summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2017-10-30 20:40:11 +0000
committerKarl Berry <karl@freefriends.org>2017-10-30 20:40:11 +0000
commitd1742894869da9494417216646bc5627ef3f3352 (patch)
tree72f25c524fd78ea0bce5cbfe612902388b71319a
parent518143fa6ebbdfe93702cf0184bd96964a09b09d (diff)
ducksay (30oct17)
git-svn-id: svn://tug.org/texlive/trunk@45647 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/ducksay/README.md12
-rw-r--r--Master/texmf-dist/doc/latex/ducksay/ducksay.tex240
-rw-r--r--Master/texmf-dist/tex/latex/ducksay/ducksay.sty172
3 files changed, 358 insertions, 66 deletions
diff --git a/Master/texmf-dist/doc/latex/ducksay/README.md b/Master/texmf-dist/doc/latex/ducksay/README.md
index 2c1eaf2706d..f1b338ddfc8 100644
--- a/Master/texmf-dist/doc/latex/ducksay/README.md
+++ b/Master/texmf-dist/doc/latex/ducksay/README.md
@@ -8,9 +8,13 @@ Copyright (C) 2017 by Jonathan P. Spratte
The package draws ASCII art of animals saying a specified message. The following
macros are available:
-\ducksay[<options>]{<message>}
-\duckthink[<options>]{<message>}
-\DefaultAnimal{<animal>}
-\AddAnimal(*){<name>}<ascii-art>
+ - `\ducksay[<options>]{<message>}`
+ - `\duckthink[<options>]{<message>}`
+ - `\DefaultAnimal{<animal>}`
+ - `\DucksayOptions{<options>}`
+ - `\AddAnimal(*){<name>}<ascii-art>`
+
+`<ascii-art>` should be delimited either by matching braces or by the same
+symbol and is read verbatim.
Multi-line messages are supported but need to be manually created using `\\`.
diff --git a/Master/texmf-dist/doc/latex/ducksay/ducksay.tex b/Master/texmf-dist/doc/latex/ducksay/ducksay.tex
new file mode 100644
index 00000000000..b03db19e2c0
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/ducksay/ducksay.tex
@@ -0,0 +1,240 @@
+%% This package is distributed under the terms of the GPLv3 or later, or the
+%% LPPL 1.3c or later, which ever license fits your needs the best.
+%%
+%% Copyright (C) 2017 by Jonathan P. Spratte
+%%
+%% This file is for documentation only
+\documentclass[a4paper,10pt]{article}
+
+%\usepackage[utf8]{inputenc}
+%\usepackage[T1]{fontenc}
+\usepackage[ligatures]{ducksay}
+\usepackage{multicol}
+\usepackage[colorlinks]{hyperref}
+\usepackage{lmodern}
+
+\makeatletter
+\newcommand*{\availableAnimal}[1]{\@for\cs:=#1\do{%
+ \ifx\cs\@empty\else%
+ \rlap{\expandafter\ducksay\expandafter[\cs]{\cs}}\hfill\mbox{}\\[1ex]%
+ \fi%
+}}
+\makeatother
+\newcommand*{\anml}{\texttt{<animal>}}
+\newcommand*{\msg}{\texttt{<message>}}
+\newenvironment{codedescription}{%
+ \parindent=-3em%
+ \parskip=1em%
+ \par%
+}{}
+
+\begin{document}
+\begin{titlepage}%>>>
+ \makeatletter
+ \centering
+ %\mbox{}\vfill
+ \Large
+ \ducksay[duck,bubble=\huge,msg-align=c,wd=8]{This is\\ducksay!}\\
+ \vfill
+ \normalsize
+ \hspace*{-2cm}
+ \ducksay[cow,bubble=\large]{\ducksay@version}\\
+ \small
+ \vspace*{-5cm}\hspace*{5cm}
+ \ducksay[small-duck,bubble=\normalsize]{But which Version?}
+ \mbox{}\hfil
+ \vspace{2cm}
+ \vfill
+ \vfill
+ \hspace*{-0cm}
+ \large
+ \smash{%
+ \ducksay[r2d2,bubble=\large]{by Jonathan P. Spratte}}
+ \small
+ \ducksay[hedgehog,bubble=\normalsize]{Today is \ducksay@date}
+ \makeatother
+\end{titlepage}%<<<
+\tableofcontents
+\section{Macros}%>>>
+\marginpar{%
+ \rlap{%
+ \tiny\ducksay[yoda,bubble=\footnotesize,align=t]{Use those, you might}}}
+The following macros are available:
+
+\begin{codedescription}
+\verb|\ducksay[<options>]{<message>}|\\
+ options might include any of the options described in
+ \autoref{sec:options}. Prints an \anml\ saying \msg. \msg\ is not read in
+ verbatim. Multi-line \msg s are possible using \verb|\\|. \verb|\\| should not
+ be inside a macro but at toplevel. Else use the option \texttt{ht}.
+
+\verb|\duckthink[<options>]{<message>}|\\
+ options might include any of the options described in
+ \autoref{sec:options}. Prints an \anml\ thinking \msg. \msg\ is not read in
+ verbatim. It is implemented using regular expressions replacing a \verb|\|
+ which is only preceded by \verb|\s*| in the first three lines with \verb|O|
+ and \verb|o|. It is therefore slower than \verb|\ducksay|. Multi-line \msg s
+ are possible using \verb|\\|. \verb|\\| should not be inside a macro but at
+ toplevel. Else use the option \texttt{ht}.
+
+\verb|\DefaultAnimal{<animal>}|\\
+ use the \anml\ if none is given in the optional argument to \verb|\ducksay| or
+ \verb|\duckthink|. Package default is \texttt{duck}.
+
+\verb|\DucksayOptions{<options>}|\\
+ set the defaults to the keys described in \autoref{sec:options}. Don't use an
+ \anml\ here, it has no effect.
+
+\verb|\AddAnimal(*){<animal>}<ascii-art>|\\
+ adds \anml\ to the known animals. \texttt{<ascii-art>} is multi-line verbatim
+ and therefore should be delimited either by matching braces or by anything
+ that works for \verb|\verb|. If the star is given \anml\ is the new default.
+ One space is added to the begin of \anml\ (compensating the opening symbol).
+ For example, snowman is added with:\\[1ex]
+ \begin{minipage}{\linewidth}
+\begin{verbatim}
+\AddAnimal{snowman}
+{ \
+ \_[_]_
+ (")
+ >-( : )-<
+ (__:__)}
+\end{verbatim}
+ \end{minipage}
+\end{codedescription}
+%<<<
+\section{Options}\label{sec:options}%>>>
+{\reversemarginpar\marginpar{%
+ \vspace*{-2em}\hspace*{-4em}%
+ \tiny%
+ \ducksay[hedgehog,bubble=\footnotesize,align=t]{Everyone likes\\options}}}
+The following options are available to \verb|\ducksay|, \verb|\duckthink|, and
+\verb|\DucksayOptions| and if not otherwise specified also as package options:
+
+\begin{codedescription}
+\anml\\
+ One of the animals listed in \autoref{sec:animals} or any of the ones added
+ with \verb|\AddAnimal|. Not useable as package option.
+
+\texttt{animal=\anml}\\
+ a longer alternative to the use of \anml\ if used in \verb|\ducksay| or
+ \verb|\duckthink|. If it is used as a package option or in
+ \verb|\DucksayOptions| it changes the default animal to \anml.
+
+\texttt{bubble=\#1}\\
+ use \texttt{\#1} in a group right before the bubble (for font switches). Might
+ be used as a package option but not all control sequences work out of the box
+ there.
+
+\texttt{body=\#1}\\
+ use \texttt{\#1} in a group right before the body (meaning the \anml). Might
+ be used as a package option but not all control sequences work out of the box
+ there. E.g., to right-align the \anml\ to the bubble, use \verb|body=\hfill|.
+
+\texttt{align=\#1}\\
+ use \texttt{\#1} as the vertical alignment specifier given to the
+ \texttt{tabular} which is around the contents of \verb|\ducksay| and
+ \verb|\duckthink|.
+
+\texttt{msg-align=\#1}\\
+ use \texttt{\#1} for alignment of the rows of multi-line \msg s. It should
+ match a \texttt{tabular} column specifier. Default is \texttt{l}. It only
+ affects the contents of the speech bubble not the bubble.
+
+\texttt{wd=\#1}\\
+ in order to detect the width the \msg\ is expanded. This might not work out
+ for some commands (e.g. \verb|\url| from \texttt{hyperref}). If you specify
+ the width using \texttt{wd} the \msg\ is not expanded and therefore the
+ command \emph{might} work out. \texttt{\#1} should be the character count.
+
+\texttt{ht=\#1}\\
+ you might explicitly set the height (the row count) of the \msg. This only has
+ an effect if you also specify \texttt{wd}.
+
+\texttt{ligatures=\#1}\\
+ this is a \LaTeX3 regular expression which should match every character you
+ don't want to form ligatures during \verb|\AddAnimal|. The default expression
+ is \verb|[\-<>`]|. Giving no argument (or an empty one) disables the
+ replacement, which enhances compilation speed. The formation of ligatures was
+ only observed in combination with \verb|\usepackage[T1]{fontenc}| by the
+ author of this package. Therefore giving the option \texttt{ligatures} without
+ an argument might enhance the compilation speed for you without any
+ drawbacks.
+\end{codedescription}
+ %<<<
+\section{Defects}%>>>
+{\reversemarginpar\marginpar{%
+ \tiny\rlap{\ducksay[frog,bubble=\footnotesize,align=t]{Ohh, no!}}}}
+\begin{itemize}
+ \item no automatic line wrapping
+\end{itemize}
+%<<<
+\section{Dependencies}%>>>
+\marginpar{%
+ \tiny\rlap{\ducksay[kangaroo,bubble=\footnotesize,align=t]{We rely on you}}}
+The package depends on the two packages \texttt{xparse} and \texttt{l3keys2e}
+and all of their dependencies.
+%<<<
+%\clearpage
+\section{Available Animals}\label{sec:animals}%>>>
+The following animals are provided by this package. I did not create them (but
+altered some), they belong to their original creators.
+\bgroup
+\footnotesize
+\begin{multicols}{2}
+\availableAnimal{%>>>
+ ,duck%
+ ,small-duck%
+ ,duck-family%
+ ,small-rabbit%
+ ,squirrel%
+ ,cow%
+ ,tux%
+ ,head-in%
+ ,pig%
+ ,frog%
+ ,snowman%
+ ,bunny%
+ ,dragon%
+ ,sodomized%
+ ,hedgehog%
+ ,kangaroo%
+ ,dog%
+ ,rabbit%
+ ,unicorn%
+}\end{multicols}\begin{multicols}{2}
+\availableAnimal{%
+ ,r2d2%
+ ,vader%
+ ,yoda-head%
+ ,small-yoda%
+ ,yoda%
+}%<<<
+\end{multicols}
+\egroup
+%<<<
+\section{Miscellaneous}%>>>
+\marginpar{%
+ \rlap{\tiny\ducksay[squirrel,bubble=\footnotesize,align=t]{I'd choose WTFPL}}}
+This package is distributed under the terms of the GPLv3 or later, or the LPPL
+1.3c or later, choose which ever license fits your needs the best.
+
+The package is hosted on \url{https://github.com/Skillmon/ltx_ducksay}, you
+might report bugs there.
+%<<<
+\clearpage
+% closing page>>>
+\thispagestyle{empty}
+\bgroup
+\Huge
+\mbox{}\vfill
+\centering
+\makebox[0pt]{\duckthink{Who's gonna use it anyway?}}
+\vfill
+\hfill\smash{\footnotesize\ducksay[small-yoda,wd=49]{hosted at
+ \url{https://github.com/Skillmon/ltx_ducksay}}}
+\egroup
+%<<<
+\end{document}
+
+% vim: fdm=marker foldmarker=>>>,<<<
diff --git a/Master/texmf-dist/tex/latex/ducksay/ducksay.sty b/Master/texmf-dist/tex/latex/ducksay/ducksay.sty
index bb4a9fe3e5e..8282a35791c 100644
--- a/Master/texmf-dist/tex/latex/ducksay/ducksay.sty
+++ b/Master/texmf-dist/tex/latex/ducksay/ducksay.sty
@@ -5,8 +5,8 @@
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{xparse,l3keys2e}
-\def\ducksay@version{v1.1}
-\def\ducksay@date{2017/09/25}
+\def\ducksay@version{v1.2}
+\def\ducksay@date{2017/10/30}
\ProvidesExplPackage
{ducksay} {\ducksay@date}
@@ -14,11 +14,57 @@
\ExplSyntaxOn
+% variables>>>
\int_new:N \l_ducksay_strlen_int
\int_new:N \l_ducksay_lines_int
\seq_new:N \l_ducksay_msg_lines_seq
+\tl_new:N \l_ducksay_align_tl
+\tl_new:N \l_ducksay_msg_align_tl
+\tl_new:N \l_ducksay_animal_tl
+\bool_new:N \l_ducksay_empty_ligatures_bool
+\cs_new:Nn \ducksay_bubble: {}
+\cs_new:Nn \ducksay_body: {}
+\regex_new:N \l_ducksay_ligatures_regex
+%<<<
+
+% predefined regexes>>>
+% regexes for \duckthink >>>
+\regex_const:Nn \c_ducksay_first_regex { \A(.\s*)\\ }
+\regex_const:Nn \c_ducksay_second_regex { \A(.[^\c{null}]*\c{null}\s*)\\ }
+\regex_const:Nn \c_ducksay_third_regex {
+ \A(.[^\c{null}]*\c{null}[^\c{null}]*\c{null}\s*)\\ }
+%<<<
+% regexes for \AddAnimal >>>
+\regex_const:Nn \c_ducksay_newline_regex { \r }
+\regex_set:Nn \l_ducksay_ligatures_regex { [\-<>`] }
+%<<<
+%<<<
+
+\keys_define:nn { ducksay } {%>>>
+ ,bubble .code:n = \cs_set:Nn \ducksay_bubble: {#1}
+ ,body .code:n = \cs_set:Nn \ducksay_body: {#1}
+ ,align .tl_set:N = \l_ducksay_align_tl
+ ,align .value_required:n = true
+ ,wd .int_set:N = \l_ducksay_strlen_int
+ ,wd .value_required:n = true
+ ,ht .int_set:N = \l_ducksay_lines_int
+ ,ht .value_required:n = true
+ ,animal .code:n = {
+ \keys_define:nn { ducksay } { default_animal .meta:n = {#1} }}
+ ,animal .initial:n = duck
+ ,msg-align .tl_set:N = \l_ducksay_msg_align_tl
+ ,msg-align .initial:n = l
+ ,msg-align .value_required:n = true
+ ,ligatures .code:n = {
+ \tl_if_empty:nTF { #1 }
+ { \bool_set_true:N \l_ducksay_empty_ligatures_bool }
+ { \regex_set:Nn \l_ducksay_ligatures_regex { #1 } }
+ }
+}%<<<
+
+\ProcessKeysOptions { ducksay }
-\cs_new:Npn \ducksay_longest_line:n #1 {%>>>
+\cs_new:Nn \ducksay_longest_line:n {%>>>
\int_incr:N \l_ducksay_lines_int
\exp_args:NNx \tl_set:Nn \l_tmpa_tl { #1 }
\regex_replace_all:nnN { \s } { \c{space} } \l_tmpa_tl
@@ -26,7 +72,7 @@
\int_max:nn { \l_ducksay_strlen_int } { \tl_count:N \l_tmpa_tl } }
}%<<<
-\cs_new:Npn \ducksay_open_bubble: {%>>>
+\cs_new:Nn \ducksay_open_bubble: {%>>>
\begin{tabular}{@{}l@{}}
\mbox{}\\
\int_compare:nNnTF {\l_ducksay_lines_int} = {1} {
@@ -41,11 +87,11 @@
\begin{tabular}{@{}l@{}}
_\\
\int_step_inline:nnnn{2}{1}{\l_ducksay_lines_int}{\\}\\[-1ex]
- {-}
+ \mbox{-}
\end{tabular}
}%<<<
-\cs_new:Npn \ducksay_close_bubble: {%>>>
+\cs_new:Nn \ducksay_close_bubble: {%>>>
\begin{tabular}{@{}l@{}}
_\\
\int_step_inline:nnnn{2}{1}{\l_ducksay_lines_int}{\\}\\[-1ex]
@@ -64,7 +110,7 @@
\end{tabular}
}%<<<
-\cs_new:Npn \ducksay_print_msg:n #1 #2 {%>>>
+\cs_new:Nn \ducksay_print_msg:nn {%>>>
\begin{tabular}{@{} #2 @{}}
\int_step_inline:nnnn{1}{1}{\l_ducksay_strlen_int}{_}\\
#1\\[-1ex]
@@ -72,7 +118,9 @@
\end{tabular}
}%<<<
-\cs_new:Npn \ducksay_print:n #1 {%>>>
+\cs_generate_variant:Nn \ducksay_print_msg:nn { nV }
+
+\cs_new:Nn \ducksay_print:n {%>>>
\int_case:nnF { \l_ducksay_strlen_int }
{ { 0 } {
\seq_set_split:Nnn \l_ducksay_msg_lines_seq {\\} { #1 }
@@ -85,14 +133,16 @@
\int_incr:N \l_ducksay_lines_int
}}
}
- \frenchspacing
\group_begin:
+ \frenchspacing
\ttfamily
+ \verbatim@font
+ \@noligs
\begin{tabular}[\l_ducksay_align_tl]{@{}l@{}}
\ducksay_bubble:
\begin{tabular}{@{}l@{}}
\ducksay_open_bubble:
- \exp_args:Nno \ducksay_print_msg:n {#1} { \l_ducksay_msg_align_tl }
+ \ducksay_print_msg:nV {#1} \l_ducksay_msg_align_tl
\ducksay_close_bubble:
\end{tabular}\\
\ducksay_body:
@@ -103,63 +153,50 @@
\group_end:
}%<<<
+\cs_new:Nn \ducksay_prepare_say_and_think:n {%>>>
+ \int_zero:N \l_ducksay_strlen_int
+ \int_zero:N \l_ducksay_lines_int
+ \keys_define:nn { ducksay } { animal .meta:n = { ##1 } }
+ \keys_set:nn { ducksay } { default_animal,#1 }
+}%<<<
+
+\cs_new:Nn \ducksay_to_duckthink: {%>>>
+ \regex_replace_once:NnN \c_ducksay_first_regex { \1O } \l_ducksay_animal_tl
+ \regex_replace_once:NnN \c_ducksay_second_regex { \1o } \l_ducksay_animal_tl
+ \regex_replace_once:NnN \c_ducksay_third_regex { \1o } \l_ducksay_animal_tl
+}%<<<
+
\NewDocumentCommand{\ducksay}{ O{} m }{%>>>
\group_begin:
- \int_zero:N \l_ducksay_strlen_int
- \int_zero:N \l_ducksay_lines_int
- \keys_set:nn { ducksay } { default_animal,#1 }
+ \ducksay_prepare_say_and_think:n { #1 }
\ducksay_print:n { #2 }
\group_end:
}%<<<
-% regexes for \duckthink >>>
-\regex_const:Nn \c_ducksay_first_regex { \A(.\s*)\\ }
-\regex_const:Nn \c_ducksay_second_regex { \A(.[^\c{null}]*\c{null}\s*)\\ }
-\regex_const:Nn \c_ducksay_third_regex {
- \A(.[^\c{null}]*\c{null}[^\c{null}]*\c{null}\s*)\\ }
-%<<<
-
\NewDocumentCommand{\duckthink}{ O{} m }{%>>>
\group_begin:
- \int_zero:N \l_ducksay_strlen_int
- \int_zero:N \l_ducksay_lines_int
- \keys_set:nn { ducksay } { default_animal,#1 }
- \regex_replace_once:NnN \c_ducksay_first_regex { \1O } \l_ducksay_animal_tl
- \regex_replace_once:NnN \c_ducksay_second_regex { \1o } \l_ducksay_animal_tl
- \regex_replace_once:NnN \c_ducksay_third_regex { \1o } \l_ducksay_animal_tl
+ \ducksay_prepare_say_and_think:n { #1 }
+ \ducksay_to_duckthink:
\ducksay_print:n { #2 }
\group_end:
}%<<<
-\keys_define:nn { ducksay } {%>>>
- ,bubble .code:n = \cs_set:Nn \ducksay_bubble: {#1}
- ,bubble .initial:n = \relax
- ,body .code:n = \cs_set:Nn \ducksay_body: {#1}
- ,body .initial:n = \relax
- ,align .tl_set:N = \l_ducksay_align_tl
- ,align .initial:n = {}
- ,align .value_required:n = true
- ,wd .int_set:N = \l_ducksay_strlen_int
- ,wd .value_required:n = true
- ,ht .int_set:N = \l_ducksay_lines_int
- ,ht .value_required:n = true
- ,animal .code:n = {
- \keys_define:nn { ducksay } { default_animal .meta:n = {#1} }}
- ,animal .initial:n = duck
- ,msg-align .tl_set:N = \l_ducksay_msg_align_tl
- ,msg-align .initial:n = l
- ,msg-align .value_required:n = true
-}%<<<
-
\NewDocumentCommand{\DefaultAnimal}{ m }{%>>>
\keys_define:nn { ducksay } { default_animal .meta:n = {#1} }}%<<<
+\NewDocumentCommand{\DucksayOptions}{ m }{%>>>
+ \keys_set:nn { ducksay } { #1 }}%<<<
+
\NewDocumentCommand{\AddAnimal}{ s m +v }{%>>>
\tl_set:Nn \l_tmpa_tl { \ #3 }
- \regex_replace_all:nnN { \r } { \c{tabularnewline}\c{null} } \l_tmpa_tl
- \cs_gset_eq:cN { g_ducksay_animal_#2_tl } \l_tmpa_tl
+ \bool_if:NF \l_ducksay_empty_ligatures_bool {
+ \regex_replace_all:NnN \l_ducksay_ligatures_regex { \c{mbox}\0 } \l_tmpa_tl
+ }
+ \regex_replace_all:NnN \c_ducksay_newline_regex { \c{tabularnewline}\c{null} }
+ \l_tmpa_tl
+ \tl_gset_eq:cN { g_ducksay_animal_#2_tl } \l_tmpa_tl
\keys_define:nn { ducksay } {
- #2 .code:n = \cs_set_eq:Nc \l_ducksay_animal_tl { g_ducksay_animal_#2_tl }
+ #2 .code:n = \tl_set_eq:Nc \l_ducksay_animal_tl { g_ducksay_animal_#2_tl }
}
\IfBooleanT{#1}{
\keys_define:nn { ducksay } {
@@ -272,8 +309,8 @@
`""`""`}%<<<
\AddAnimal{bunny}%>>>
{ \
- \ \
- \ /\
+ \ /
+ /\ /
( )
.( o ).}%<<<
\AddAnimal{small-rabbit}%>>>
@@ -313,7 +350,28 @@
_(\.= ;:;;'
`"_( _/="`
`"'``}%<<<
-
+% from http://www.ascii-art.de/ascii/uvw/unicorn.txt
+\AddAnimal{unicorn}
+{ \
+ \ /((((((\\\\
+ ---====((((((((((\\\\\
+ (( \\\\\\\
+ ( (* _/ \\\\\\\
+ \ / \ \\\\\\_ __,,__
+ | | | </ "------"" ((\\\\
+ o_| / / \ \\\\ \\\\\\\
+ | ._ ( \ \\\\\\\\\\\\\\\\
+ | / / / \\\\\\\ \\
+ .______/\/ / / / \\\
+ / __.____/ _/ ___----( /\
+ / / / ________/:______,---' \ / \_
+ / / \ \ \ \ \_ \
+ ( < \ \ > / \ \
+ \/ \\_ / / > )
+ \_| / / / /
+ _// _//
+ /_| /_|}
+
% from http://www.ascii-art.de/ascii/s/starwars.txt :
\AddAnimal{yoda}%>>>
{ \
@@ -409,15 +467,5 @@
| `' |}%<<<
%<<<
-\ExplSyntaxOn
-
-\ProcessKeysOptions { ducksay }
-
-\keys_define:nn { ducksay } {
- ,animal .undefine:
-}
-
-\ExplSyntaxOff
-
\endinput
% vim: fdm=marker foldmarker=>>>,<<<