summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-01-13 23:31:16 +0000
committerKarl Berry <karl@freefriends.org>2019-01-13 23:31:16 +0000
commit231f2bfbc6deb5f053659c5062e9b5be2ed8e5c8 (patch)
tree4aefb4a44dffac03ea25bdc1ead9ccbbf787da31
parent45703352bcad374f3e88099a40425df3ba5c3395 (diff)
ducksay (13jan19)
git-svn-id: svn://tug.org/texlive/trunk@49691 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/ducksay/ducksay.pdfbin483844 -> 513927 bytes
-rw-r--r--Master/texmf-dist/source/latex/ducksay/ducksay.dtx710
-rw-r--r--Master/texmf-dist/tex/latex/ducksay/ducksay.animals.tex63
-rw-r--r--Master/texmf-dist/tex/latex/ducksay/ducksay.code.v1.tex27
-rw-r--r--Master/texmf-dist/tex/latex/ducksay/ducksay.code.v2.tex218
-rw-r--r--Master/texmf-dist/tex/latex/ducksay/ducksay.sty150
6 files changed, 707 insertions, 461 deletions
diff --git a/Master/texmf-dist/doc/latex/ducksay/ducksay.pdf b/Master/texmf-dist/doc/latex/ducksay/ducksay.pdf
index 940be196f80..96e483a2dc8 100644
--- a/Master/texmf-dist/doc/latex/ducksay/ducksay.pdf
+++ b/Master/texmf-dist/doc/latex/ducksay/ducksay.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/ducksay/ducksay.dtx b/Master/texmf-dist/source/latex/ducksay/ducksay.dtx
index ec0e0cf52d2..48643bd6b35 100644
--- a/Master/texmf-dist/source/latex/ducksay/ducksay.dtx
+++ b/Master/texmf-dist/source/latex/ducksay/ducksay.dtx
@@ -63,7 +63,12 @@ and the derived files ducksay.pdf
\ProvidesFile{ducksay.dtx}
[\csname ducksay@date\endcsname\ cowsay for LaTeX]
\documentclass{l3doc}
+% silence the false positives about internal control sequences in the animals
+\csname msg_redirect_name:nnn\endcsname{l3doc}{foreign-internal}{none}
\usepackage[version=2]{ducksay}
+\usepackage{marginnote}
+\newcommand\sinceversion[1]
+ {\marginnote{\footnotesize\textsf{v#1}\kern-\marginparsep}}
\let\metaORIG\meta
\protected\def\meta #1{\texttt{\metaORIG{#1}}}
\DucksayOptions{arg=tab,msg-align=l,vpad=1}
@@ -102,6 +107,16 @@ and the derived files ducksay.pdf
}
{\end{description}}
\makeatletter
+\renewcommand*\paragraph
+ {%
+ \@startsection
+ {paragraph}
+ {4}
+ {\z@}
+ {-3.25ex \@plus -1ex \@minus -.2ex}
+ {1ex \@plus .2ex}
+ {\normalfont\normalsize\bfseries}%
+ }
\newcommand*\availableAnimal[1]
{%
\@for\cs:=#1\do
@@ -152,7 +167,7 @@ and the derived files ducksay.pdf
\hfil
\makebox[.\marginparwidth][l]
{%
- \ducksay[head-in,MSG=\footnotesize,msg-align=c,align=t]
+ \ducksay[head-in,MSG=\footnotesize,msg-align=c]
{It's always\\good to\\keep the\\overview!}%
}%
}%
@@ -173,7 +188,7 @@ and the derived files ducksay.pdf
\smash
{%
\footnotesize
- \ducksay[small-yoda,wd=39,ht=3,msg-align=c,rel-align=r]
+ \ducksay[small-yoda,wd=39,ht=3,msg-align=c,body-align=r]
{Hosted at\\\url{https://github.com/Skillmon/ltx_ducksay}\\it is.}%
}
\egroup
@@ -187,8 +202,8 @@ and the derived files ducksay.pdf
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{xparse,l3keys2e}
-\def\ducksay@version{2.2.1}
-\def\ducksay@date{2019-01-08}
+\def\ducksay@version{2.3}
+\def\ducksay@date{2019-01-13}
\ProvidesExplPackage
{ducksay} {\ducksay@date}
@@ -231,31 +246,43 @@ and the derived files ducksay.pdf
%
% \section{Documentation}\def\DocImp{Documentation}%
%
-% \subsection{Downward Compatibility Issues}
+% \subsection{Downward Compatibility Issues}\label{sec:down}^^A>>>
% \marginpar^^A>>>
% {
% \tiny
-% \ducksay[snail,MSG=\footnotesize,align=t]{Yep, I screwed up!}
+% \ducksay[snail,MSG=\footnotesize]{Yep, I screwed up!}
% }^^A<<<
%
% \begin{itemize}
-% \item Versions prior to v2.0 did use a regular expression for the option
+% \item
+% \sinceversion{2.0}
+% Versions prior to v2.0 did use a regular expression for the option
% |ligatures|, see \autoref{sec:options} for more on this issue. With v2.0
% I do refer to the package's version, not the code variant which can be
% selected with the |version| option.
% \item In a document created with package versions prior to v2.0 you'll have
% to specify the option |version=1| in newer versions to make those old
% documents behave like they used to.
-% \end{itemize}
+% \item
+% \sinceversion{2.3}
+% Since v2.3 \cs{AddAnimal} and \cs{AddColoredAnimal} behave
+% differently. You no longer have to make sure that in the first three lines
+% every backslash which is only preceded by spaces is the bubble's tail.
+% Instead you can specify which symbol should be the tail and how many of
+% such symbols there are. See \autoref{sec:macros} for more about the
+% current behaviour.
+% \item The |add-think| key is deprecated and will throw an error starting
+% with v2.3. In future versions it will be removed.
+% \end{itemize}^^A<<<
%
-% \subsection{Shared between versions}
+% \subsection{Shared between versions}^^A>>>
%
-% \subsubsection{Macros}^^A>>>
+% \subsubsection{Macros}\label{sec:macros}^^A>>>
% \marginpar^^A>>>
% {
% \tiny
% \hfill
-% \ducksay[bunny,MSG=\footnotesize,align=t,body-mirrored]
+% \ducksay[bunny,MSG=\footnotesize,body-mirrored]
% {Macros for everyone!}
% }^^A<<<
%
@@ -284,34 +311,33 @@ and the derived files ducksay.pdf
%
% \begin{function}{\AddAnimal}^^A>>>
% \begin{syntax}
-% \cs{AddAnimal}\meta{*}\marg{animal}\meta{ascii-art}
+% \cs{AddAnimal}\meta{*}\oarg{options}\marg{animal}\meta{ascii-art}
% \end{syntax}
% adds \anml\ to the known animals. \meta{ascii-art} is multi-line verbatim
% and therefore should be delimited either by matching braces or by anything
% that works for \cs{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]
+% The symbols signalizing the speech bubble's tail (in the |hedgehog| example
+% below the two |s|) can be set using the |tail-symbol| option and only the
+% first |tail-count| occurrences will be substituted (see
+% \autoref{sec:addoptions} for more about these options). For example,
+% |hedgehog| is added with:\\[1ex]
% \begin{minipage}{\linewidth}
%\begin{verbatim}
-% \AddAnimal{snowman}
-% { \
-% \ _[_]_
-% (")
-% >-( : )-<
-% (__:__)}
+% \AddAnimal[tail-symbol=s]{hedgehog}
+% { s .\|//||\||.
+% s |/\/||/|//|/|
+% /. `|/\\|/||/||
+% o__,_|//|/||\||'}
%\end{verbatim}
-% \end{minipage}
+% \end{minipage}\\[1ex]
% It is not checked whether the animal already exists, you could therefore
-% redefine existing animals with this macro.\\
-% The symbols signalizing the speech (in the |snowman| example above the two
-% backslashes) should at most be used in the first three lines, as they get
-% replaced by |O| and |o| for \cs{duckthink}. They also shouldn't be preceded
-% by anything other than a space in that line.
+% redefine existing animals with this macro.
% \end{function}^^A<<<
%
% \begin{function}{\AddColoredAnimal}^^A>>>
% \begin{syntax}
-% \cs{AddColoredAnimal}\meta{*}\marg{animal}\meta{ascii-art}
+% \cs{AddColoredAnimal}\meta{*}\oarg{options}\marg{animal}\meta{ascii-art}
% \end{syntax}
% It does the same as \cs{AddAnimal} but allows three different colouring
% syntaxes. You can use \cs{textcolor} in the \meta{ascii-art} with the syntax
@@ -324,7 +350,7 @@ and the derived files ducksay.pdf
% |\bgroup\color{red}RedText\egroupOtherText| is valid syntax). You can't nest
% delimited \cs{color}s.\\
% Also you can use an undelimited \cs{color}. It affects anything until the
-% end of the current line (or, if used inside of the \meta{text} of an
+% end of the current line (or, if used inside of the \meta{text} of a
% delimited \cs{color}, anything until the end of that delimited \cs{color}'s
% \meta{text}). The syntax would be \cs{color}\marg{color}.\\
% The package doesn't load anything providing those colouring commands for you
@@ -333,13 +359,26 @@ and the derived files ducksay.pdf
% normal \cs{AddAnimal}.
% \end{function}^^A<<<
%
+% \begin{function}{\AnimalOptions}^^A>>>
+% \begin{syntax}
+% \cs{AnimalOptions}\meta{*}\marg{animal}\marg{options}
+% \end{syntax}
+% With this macro you can set \anml\ specific \meta{options}. If the star is
+% given any currently set options for this \anml\ are dropped and only the
+% ones specified in \meta{options} will be applied, else \meta{options} will
+% be added to the set options for this \anml. The set \meta{options} can
+% set the |tail-1| and |tail-2| options and therefore overwrite the effects of
+% \cs{duckthink}, as \cs{duckthink} really is just \cs{ducksay} with the
+% |think| option.
+% \end{function}^^A<<<
+%
%^^A<<<
%
% \subsubsection{Options}\label{sec:options}^^A>>>
% \marginpar
% {%
% \vspace*{-2em}\tiny
-% \ducksay[pig,MSG=\footnotesize,align=t]{Options.\\For every occasion}%
+% \ducksay[pig,MSG=\footnotesize]{Options.\\For every occasion}%
% }
% The following options are available independent on the used code variant (the
% value of the |version| key). They might be used as package options -- unless
@@ -369,33 +408,58 @@ and the derived files ducksay.pdf
% |}| so that they can't form ligatures. Giving no argument (or an empty
% one) might enhance compilation speed by disabling this replacement. The
% formation of ligatures was only observed in combination with
-% \verb|\usepackage[T1]{fontenc}| by the author of this package. Therefore
-% giving the option |ligatures| without an argument might enhance the
-% compilation speed for you without any drawbacks. Initially this is set to
+% |\usepackage[T1]{fontenc}| by the author of this package. Therefore giving
+% the option |ligatures| without an argument might enhance the compilation
+% speed for you without any drawbacks. Initially this is set to
% \texttt{\csuse{\detokenize{l_ducksay_ligatures_tl}}}.\\
% \textbf{Note:} In earlier releases this option's expected argument was a
% regular expression. This means that this option is not fully
% downward compatible with older versions. The speed gain however seems
% worth it (and I hope the affected documents are few).
-% \item[add-think=\meta{bool}]
-% by default the animals for \cs{duckthink} are not created during package
-% load time, but only when they are really used -- but then they are created
-% globally so it just has to be done once. This is done because they rely on
-% a rather slow regular expression. If you set this key to |true| each
-% \cs{AddAnimal} will also create the corresponding \cs{duckthink} variant
-% immediately.
+% \item[no-tail]
+% Sets |tail-1| and |tail-2| to be a space.
+% \item[say]
+% Sets |tail-1| and |tail-2| as backslashes.
+% \item[tail-1=\meta{token list}]
+% Sets the first tail symbol in the output to be \meta{token list}. If set
+% outside of \cs{ducksay} and \cs{duckthink} it will be overwritten inside
+% of \cs{duckthink} to be |O|.
+% \item[tail-2=\meta{token list}]
+% Sets every other tail symbol except the first one in the output to be
+% \meta{token list}. If set outside of \cs{ducksay} and \cs{duckthink} it
+% will be overwritten inside of \cs{duckthink} to be |o|.
+% \item[think]
+% Sets |tail-1=O| and |tail-2=o|.
+% \end{options}
+%
+% \paragraph{Options for \cs{AddAnimal}}\label{sec:addoptions}
+% The options described here are only available in \cs{AddAnimal} and
+% \cs{AddColoredAnimal}.
+% \begin{options}
+% \item[tail-count=\meta{int}]
+% sets the number of tail symbols to be replaced in \cs{AddAnimal} and
+% \cs{AddColoredAnimal}. Initial value is 2. If the value is negative every
+% occurrence of |tail-symbol| will be replaced.
+% \item[tail-symbol=\meta{str}]
+% the symbol used in \cs{AddAnimal} and \cs{AddColoredAnimal} to mark the
+% bubble's tail. The argument gets \cs{detokenize}d. Initially a single
+% backslash.
% \end{options}
%^^A<<<
%
+%^^A<<<
+%
% \SetVersion{1}%
-% \subsection{Version 1}\label{sec:v1}
+% \subsection{Version 1}\label{sec:v1}^^A>>>
%
-% \subsubsection{Introduction}
+% \subsubsection{Introduction}^^A>>>
%
% This version is included for legacy support (old documents should behave the
% same without any change to them -- except the usage of |version=1| as an
-% option). For the bleeding edge version of \pkg{ducksay} skip this subsection
-% and read \autoref{sec:v2}.
+% option, for a more or less complete list of downward compatibility related
+% problems see \autoref{sec:down}). For the bleeding edge version of
+% \pkg{ducksay} skip this subsection and read \autoref{sec:v2}.
+%^^A<<<
%
% \subsubsection{Macros}\label{sec:macros1}^^A>>>
% \marginpar
@@ -403,7 +467,7 @@ and the derived files ducksay.pdf
% \rlap
% {%
% \tiny
-% \ducksay[yoda,MSG=\footnotesize,align=t]{Use those, you might}%
+% \ducksay[yoda,MSG=\footnotesize]{Use those, you might}%
% }%
% }
% The following is the description of macros which differ in behaviour from
@@ -426,11 +490,9 @@ and the derived files ducksay.pdf
% \end{syntax}
% options might include any of the options described in \autoref{sec:options}
% and \autoref{sec:options1} if not otherwise specified. Prints an \anml\
-% thinking \msg. \msg\ is not read in verbatim. It is implemented using
-% regular expressions replacing a |\| which is only preceded by |\s*| in the
-% first three lines with |O| and |o|. It is therefore slower than
-% \cs{ducksay}. Multi-line \msg s are possible using |\\|. |\\| should not be
-% contained in a macro definition but at toplevel. Else use the option |ht|.
+% thinking \msg. \msg\ is not read in verbatim. Multi-line \msg s are possible
+% using |\\|. |\\| should not be contained in a macro definition but at
+% toplevel. Else use the option |ht|.
% \end{function}^^A<<<
%^^A<<<
%
@@ -439,7 +501,7 @@ and the derived files ducksay.pdf
% {%
% \vspace*{-2em}\tiny
% \hfill
-% \ducksay[hedgehog,MSG=\footnotesize,align=t]{Everyone likes\\options}%
+% \ducksay[hedgehog,MSG=\footnotesize]{Everyone likes\\options}%
% }
% The following options are available to \cs{ducksay}, \cs{duckthink}, and
% \cs{DucksayOptions} and if not otherwise specified also as package options:
@@ -452,7 +514,7 @@ and the derived files ducksay.pdf
% use \meta{code} 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|.
+% |body=\hfill|.
% \item[align=\meta{valign}]
% use \meta{valign} as the vertical alignment specifier given to the
% \env{tabular} which is around the contents of \cs{ducksay} and
@@ -480,31 +542,35 @@ and the derived files ducksay.pdf
% \begingroup
% \reversemarginpar
% \marginpar
-% {\tiny\hfill\ducksay[frog,MSG=\footnotesize,align=t]{Ohh, no!}}
+% {\tiny\hfill\ducksay[frog,MSG=\footnotesize,t]{Ohh, no!}}
% \endgroup
% \begin{itemize}
% \item no automatic line wrapping
% \end{itemize}^^A<<<
%
+%^^A<<<
+%
% \SetVersion{2}%
-% \subsection{Version 2}\label{sec:v2}
+% \subsection{Version 2}\label{sec:v2}^^A>>>
% \marginpar^^A>>>
% {
% \fontsize{3.5pt}{3.5pt}\selectfont
-% \ducksay[unicorn,MSG=\footnotesize,align=t]{Here's all the good stuff!}
+% \makebox[\marginparwidth]
+% {\ducksay[unicorn,MSG=\footnotesize]{Here's all the good stuff!}}%
% }^^A<<<
%
% \subsubsection{Introduction}^^A>>>
%
-% Version 2 is the current version of \pkg{ducksay}. It features automatic line
+% Version~2 is the current version of \pkg{ducksay}. It features automatic line
% wrapping (if you specify a fixed width) and in general more options (with some
% nasty argument parsing).
%
-% If you're already used to version 1 you should note one important thing: You
-% should only specify the |version|, the |ligatures| and |add-think| during
-% package load time as arguments to \cs{usepackage}. The other keys might not
-% work or do unintended things and only don't throw errors or warnings because
-% of the legacy support of version 1.
+% If you're already used to version~1 you should note one important thing: You
+% should only specify the |version| and the |ligatures| during package load time
+% as arguments to \cs{usepackage}. The other keys might not work or do
+% unintended things and only don't throw errors or warnings because of the
+% legacy support of version~1. After the package is loaded, keys only used for
+% version~1 will throw an error.
%
%^^A<<<
%
@@ -512,7 +578,7 @@ and the derived files ducksay.pdf
% \marginpar^^A>>>
% {
% \tiny
-% \ducksay[duck-family,MSG=\footnotesize,align=t,body-mirrored]
+% \ducksay[duck-family,MSG=\footnotesize,t,body-mirrored]
% {Look at those, kids!}
% }^^A<<<
%
@@ -543,11 +609,6 @@ and the derived files ducksay.pdf
% \end{syntax}
% The only difference to \cs{ducksay} is that in \cs{duckthink} the \anml s
% think the \msg\ and don't say it.\\
-% It is implemented using regular expressions replacing a |\| which is only
-% preceded by |\s*| (any number of space tokens) in the first three lines with
-% |O| and |o|. It's first use per \anml\ might therefore be slower than
-% \cs{ducksay} depending on the |add-think| key (see its description in
-% \autoref{sec:options}).
% \end{function}^^A<<<
%
%^^A<<<
@@ -556,7 +617,7 @@ and the derived files ducksay.pdf
% \marginpar^^A>>>
% {
% \tiny
-% \hfill\ducksay[small-rabbit,MSG=\footnotesize,align=t]
+% \hfill\ducksay[small-rabbit,MSG=\footnotesize]
% {Fast, use options!}
% }^^A<<<
% In version 2 the following options are available. Keep in mind that you
@@ -728,9 +789,12 @@ and the derived files ducksay.pdf
% \pkg{array} is used afterwards. The package default is |\raggedleft|. It
% might be useful if you want to use \pkg{ragged2e}'s \cs{RaggedLeft} for
% example.
-% \item[msg-to-bubble=\meta{pole}]
+% \item[msg-to-body=\meta{pole}]
% defines the horizontal coffin \meta{pole} to be used as the reference
% point for the placement of the \anml\ beneath the \msg. See \PolesInfo.
+% \item[no-bubble=\meta{bool}]
+% If |true| the \msg\ will not be surrounded by a bubble. Package default is
+% of course |false|.
% \item[none=\meta{bool}]
% One could say this is a special animal. If |true| no animal body will be
% used (resulting in just the speech bubble). Package default is of course
@@ -778,6 +842,8 @@ and the derived files ducksay.pdf
%
%^^A<<<
%
+%^^A<<<
+%
% \SetVersion{}%
% \subsection{Dependencies}^^A>>>
% \marginpar
@@ -787,7 +853,7 @@ and the derived files ducksay.pdf
% {%
% \ducksay
% [
-% kangaroo,MSG=\footnotesize,align=t
+% kangaroo,MSG=\footnotesize
% ,body-mirrored,body-to-msg=r,msg-to-body=hc
% ]
% {We rely on you}%
@@ -805,10 +871,12 @@ and the derived files ducksay.pdf
% \hfill
% \makebox[8em][r]
% {%
-% \ducksay[whale,MSG=\footnotesize,align=t]
-% {I'm the\\new one.}%
+% \ducksay[knight,MSG=\footnotesize,t]
+% {I'm the\\new one.}\\
+% \ducksay[crusader,MSG=\footnotesize,body=\normalsize,t]
+% {Deus\\vult!\rlap{\footnotemark}}%
% }%
-% }
+% }\footnotetext{Latin; ``I'm new, too.''}
% The following animals are provided by this package. I did not create them (but
% altered some), they belong to their original creators.
% \bgroup
@@ -837,7 +905,9 @@ and the derived files ducksay.pdf
% ,rabbit^^A
% ,snail^^A
% ,whale^^A
+% ,crusader^^A
% ,unicorn^^A
+% ,knight^^A
% }\end{multicols}\begin{multicols}{2}
% \availableAnimal{^^A
% ,r2d2^^A
@@ -856,7 +926,7 @@ and the derived files ducksay.pdf
% \rlap
% {%
% \tiny
-% \ducksay[squirrel,MSG=\footnotesize,align=t]
+% \ducksay[squirrel,MSG=\footnotesize,t]
% {WTFPL would be a\\better license.}%
% }%
% }
@@ -884,7 +954,7 @@ and the derived files ducksay.pdf
% {%
% \tiny
% \ducksay
-% [vader,MSG=\footnotesize,align=t,arg=tab,msg-align=c]
+% [vader,MSG=\footnotesize,arg=tab,msg-align=c,body-align=c]
% {%
% Only rebel scum reads\\documentation!\\
% Join the dark side,\\read the implementation.%
@@ -904,6 +974,7 @@ and the derived files ducksay.pdf
% \begin{macrocode}
\int_new:N \l_ducksay_msg_width_int
\int_new:N \l_ducksay_msg_height_int
+\int_new:N \l_ducksay_tail_symbol_count_int
% \end{macrocode}
% \paragraph{Sequences}
% \begin{macrocode}
@@ -911,17 +982,18 @@ and the derived files ducksay.pdf
% \end{macrocode}
% \paragraph{Token lists}
% \begin{macrocode}
-\tl_new:N \l_ducksay_say_or_think_tl
\tl_new:N \l_ducksay_align_tl
\tl_new:N \l_ducksay_msg_align_tl
\tl_new:N \l_ducksay_animal_tl
\tl_new:N \l_ducksay_body_tl
\tl_new:N \l_ducksay_bubble_tl
\tl_new:N \l_ducksay_tmpa_tl
+\tl_new:N \l_ducksay_tail_symbol_out_one_tl
+\tl_new:N \l_ducksay_tail_symbol_out_two_tl
+\tl_new:N \l_ducksay_tail_symbol_in_tl
% \end{macrocode}
% \paragraph{Boolean}
% \begin{macrocode}
-\bool_new:N \l_ducksay_also_add_think_bool
\bool_new:N \l_ducksay_version_one_bool
\bool_new:N \l_ducksay_version_two_bool
% \end{macrocode}
@@ -933,14 +1005,7 @@ and the derived files ducksay.pdf
%^^A<<<
%
% \subsubsection{Regular Expressions}^^A>>>
-% Regular expressions for \cs{duckthink}
-% \begin{macrocode}
-\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*)\\ }
-% \end{macrocode}
-% And for \cs{AddColoredAnimal}
+% Regular expressions for \cs{AddColoredAnimal}
% \begin{macrocode}
\regex_const:Nn \c_ducksay_textcolor_regex
{ \cO(?:\\textcolor\{(.*?)\}\{(.*?)\}) }
@@ -955,6 +1020,8 @@ and the derived files ducksay.pdf
% \begin{macrocode}
\msg_new:nnn { ducksay } { load-time-only }
{ The~`#1`~key~is~to~be~used~only~during~package~load~time. }
+\msg_new:nnn { ducksay } { deprecated-key }
+ { The~`\l_keys_key_tl`~key~is~deprecated.~Sorry~for~the~inconvenience. }
% \end{macrocode}
%^^A<<<
%
@@ -983,7 +1050,17 @@ and the derived files ducksay.pdf
,rel-align .value_required:n = true
,ligatures .tl_set:N = \l_ducksay_ligatures_tl
,ligatures .initial:n = { `<>,'- }
- ,add-think .bool_set:N = \l_ducksay_also_add_think_bool
+ ,tail-1 .tl_set:N = \l_ducksay_tail_symbol_out_one_tl
+ ,tail-1 .initial:x = \c_backslash_str
+ ,tail-2 .tl_set:N = \l_ducksay_tail_symbol_out_two_tl
+ ,tail-2 .initial:x = \c_backslash_str
+ ,no-tail .meta:n = { tail-1 = { ~ }, tail-2 = { ~ } }
+ ,think .meta:n = { tail-1 = { O }, tail-2 = { o } }
+ ,say .code:n =
+ {
+ \exp_args:Nx \DucksayOptions
+ { tail-1 = { \c_backslash_str }, tail-2 = { \c_backslash_str } }
+ }
,version .choice:
,version / 1 .code:n =
{
@@ -996,6 +1073,7 @@ and the derived files ducksay.pdf
\bool_set_true:N \l_ducksay_version_two_bool
}
,version .initial:n = 2
+ ,add-think .code:n = \msg_error:nn { ducksay } { deprecated-key }
}
% \end{macrocode}
%
@@ -1011,6 +1089,22 @@ and the derived files ducksay.pdf
}
% \end{macrocode}
%
+% \paragraph{Keys for \cs{AddAnimal}}^^A>>>
+% Define keys meant for \cs{AddAnimal} and \cs{AddColoredAnimal} only in their
+% own regime:
+% \begin{macrocode}
+\keys_define:nn { ducksay / add-animal }
+ {
+ ,tail-symbol .code:n =
+ \tl_set:Nx \l_ducksay_tail_symbol_in_tl { \tl_to_str:n { #1 } }
+ ,tail-symbol .initial:o = \c_backslash_str
+ ,tail-count .int_set:N = \l_ducksay_tail_symbol_count_int
+ ,tail-count .initial:n = 2
+ }
+% \end{macrocode}
+%
+%^^A<<<
+%
%^^A<<<
%
% \subsubsection{Functions}^^A>>>
@@ -1018,27 +1112,13 @@ and the derived files ducksay.pdf
% \paragraph{Generating Variants of External Functions}^^A>>>
%
% \begin{macrocode}
-\cs_generate_variant:Nn \tl_if_eq:nnT { VnT }
+\cs_generate_variant:Nn \tl_replace_once:Nnn { NVn }
+\cs_generate_variant:Nn \tl_replace_all:Nnn { NVn }
% \end{macrocode}
%^^A<<<
%
% \paragraph{Internal}^^A>>>
%
-% \begin{macro}{\ducksay_create_think_animal:n}^^A>>>
-% \begin{macrocode}
-\cs_new_protected:Npn \ducksay_create_think_animal:n #1
- {
- \group_begin:
- \tl_set_eq:Nc \l_ducksay_tmpa_tl { g_ducksay_animal_say_#1_tl }
- \regex_replace_once:NnN \c_ducksay_first_regex { \1O } \l_ducksay_tmpa_tl
- \regex_replace_once:NnN \c_ducksay_second_regex { \1o } \l_ducksay_tmpa_tl
- \regex_replace_once:NnN \c_ducksay_third_regex { \1o } \l_ducksay_tmpa_tl
- \tl_gset_eq:cN { g_ducksay_animal_think_#1_tl } \l_ducksay_tmpa_tl
- \group_end:
- }
-% \end{macrocode}
-% \end{macro}^^A<<<
-%
% \begin{macro}{\ducksay_replace_verb_newline:Nn}^^A>>>
% \begin{macrocode}
\cs_new_protected:Npx \ducksay_replace_verb_newline:Nn #1 #2
@@ -1069,27 +1149,65 @@ and the derived files ducksay.pdf
% \end{macrocode}
% \end{macro}^^A<<<
%
-% \begin{macro}{\ducksay_add_animal_inner:nn}^^A>>>
+% \begin{macro}{\ducksay_add_animal_inner:nnnn}^^A>>>
% \begin{macrocode}
-\cs_new_protected:Npn \ducksay_add_animal_inner:nn #1 #2
+\cs_new_protected:Npn \ducksay_add_animal_inner:nnnn #1 #2 #3 #4
{
- \tl_set:Nn \l_ducksay_tmpa_tl { \ #2 }
- \tl_map_inline:Nn \l_ducksay_ligatures_tl
- { \tl_replace_all:Nnn \l_ducksay_tmpa_tl { ##1 } { { ##1 } } }
- \ducksay_replace_verb_newline:Nn \l_ducksay_tmpa_tl { \tabularnewline\null }
- \tl_gset_eq:cN { g_ducksay_animal_say_#1_tl } \l_ducksay_tmpa_tl
- \keys_define:nn { ducksay }
+ \group_begin:
+ \keys_set:nn { ducksay / add-animal } { #1 }
+ \tl_set:Nn \l_ducksay_tmpa_tl { \ #3 }
+ \int_compare:nNnTF { \l_ducksay_tail_symbol_count_int } < { \c_zero_int }
+ {
+ \tl_replace_once:NVn
+ \l_ducksay_tmpa_tl
+ \l_ducksay_tail_symbol_in_tl
+ \l_ducksay_tail_symbol_out_one_tl
+ \tl_replace_all:NVn
+ \l_ducksay_tmpa_tl
+ \l_ducksay_tail_symbol_in_tl
+ \l_ducksay_tail_symbol_out_two_tl
+ }
+ {
+ \int_compare:nNnT { \l_ducksay_tail_symbol_count_int } >
+ { \c_zero_int }
+ {
+ \tl_replace_once:NVn
+ \l_ducksay_tmpa_tl
+ \l_ducksay_tail_symbol_in_tl
+ \l_ducksay_tail_symbol_out_one_tl
+ \int_step_inline:nnn { 2 } { \l_ducksay_tail_symbol_count_int }
+ {
+ \tl_replace_once:NVn
+ \l_ducksay_tmpa_tl
+ \l_ducksay_tail_symbol_in_tl
+ \l_ducksay_tail_symbol_out_two_tl
+ }
+ }
+ }
+ \tl_map_inline:Nn \l_ducksay_ligatures_tl
+ { \tl_replace_all:Nnn \l_ducksay_tmpa_tl { ##1 } { { ##1 } } }
+ \ducksay_replace_verb_newline:Nn \l_ducksay_tmpa_tl
+ { \tabularnewline\null }
+ \exp_args:NNnV
+ \group_end:
+ \tl_set:cn { l_ducksay_animal_#2_tl } \l_ducksay_tmpa_tl
+ \exp_args:Nnx \keys_define:nn { ducksay }
{
- #1 .code:n =
+ #2 .code:n =
{
- \tl_if_exist:cF
- { g_ducksay_animal_ \l_ducksay_say_or_think_tl _#1_tl }
- { \ducksay_create_think_animal:n { #1 } }
- \tl_set_eq:Nc \l_ducksay_animal_tl
- { g_ducksay_animal_ \l_ducksay_say_or_think_tl _#1_tl }
+ \exp_not:n { \tl_set_eq:NN \l_ducksay_animal_tl }
+ \exp_after:wN \exp_not:N \cs:w l_ducksay_animal_#2_tl \cs_end:
+ \exp_not:n { \exp_args:NV \DucksayOptions }
+ \exp_after:wN
+ \exp_not:N \cs:w l_ducksay_animal_#2_options_tl \cs_end:
}
}
+ \tl_if_exist:cF { l_ducksay_animal_#2_options_tl }
+ { \tl_new:c { l_ducksay_animal_#2_options_tl } }
+ \IfBooleanT { #4 }
+ { \keys_define:nn { ducksay } { default_animal .meta:n = { #2 } } }
}
+\cs_generate_variant:Nn \ducksay_add_animal_inner:nnnn { nnVn }
% \end{macrocode}
% \end{macro}^^A<<<
%
@@ -1117,35 +1235,44 @@ and the derived files ducksay.pdf
%
% \begin{macro}{\AddAnimal}^^A>>>
% \begin{macrocode}
-\NewDocumentCommand \AddAnimal { s m +v }
+\NewDocumentCommand \AddAnimal { s O{} m +v }
{
- \ducksay_add_animal_inner:nn { #2 } { #3 }
- \bool_if:NT \l_ducksay_also_add_think_bool
- { \ducksay_create_think_animal:n { #2 } }
- \IfBooleanT{#1}
- { \keys_define:nn { ducksay } { default_animal .meta:n = { #2 } } }
+ \ducksay_add_animal_inner:nnnn { #2 } { #3 } { #4 } { #1 }
}
% \end{macrocode}
% \end{macro}^^A<<<
%
% \begin{macro}{\AddColoredAnimal}^^A>>>
% \begin{macrocode}
-\NewDocumentCommand \AddColoredAnimal { s m +v }
+\NewDocumentCommand \AddColoredAnimal { s O{} m +v }
{
- \ducksay_add_animal_inner:nn { #2 } { #3 }
- \regex_replace_all:Nnc \c_ducksay_color_delim_regex
+ \tl_set:Nn \l_ducksay_tmpa_tl { #4 }
+ \regex_replace_all:NnN \c_ducksay_color_delim_regex
{ \c{bgroup}\c{color}\cB\{\1\cE\}\2\c{egroup} }
- { g_ducksay_animal_say_#2_tl }
- \regex_replace_all:Nnc \c_ducksay_color_regex
+ \l_ducksay_tmpa_tl
+ \regex_replace_all:NnN \c_ducksay_color_regex
{ \c{color}\cB\{\1\cE\} }
- { g_ducksay_animal_say_#2_tl }
- \regex_replace_all:Nnc \c_ducksay_textcolor_regex
+ \l_ducksay_tmpa_tl
+ \regex_replace_all:NnN \c_ducksay_textcolor_regex
{ \c{textcolor}\cB\{\1\cE\}\cB\{\2\cE\} }
- { g_ducksay_animal_say_#2_tl }
- \bool_if:NT \l_ducksay_also_add_think_bool
- { \ducksay_create_think_animal:n { #2 } }
- \IfBooleanT{#1}
- { \keys_define:nn { ducksay } { default_animal .meta:n = { #2 } } }
+ \l_ducksay_tmpa_tl
+ \ducksay_add_animal_inner:nnVn { #2 } { #3 } \l_ducksay_tmpa_tl { #1 }
+ }
+% \end{macrocode}
+% \end{macro}^^A<<<
+%
+% \begin{macro}{\AnimalOptions}^^A>>>
+% \begin{macrocode}
+\NewDocumentCommand \AnimalOptions { s m m }
+ {
+ \tl_if_exist:cTF { l_ducksay_animal_#2_options_tl }
+ {
+ \IfBooleanTF { #1 }
+ { \tl_set:cn }
+ { \tl_put_right:cn }
+ }
+ { \tl_set:cn }
+ { l_ducksay_animal_#2_options_tl } { #3, }
}
% \end{macrocode}
% \end{macro}^^A<<<
@@ -1308,16 +1435,19 @@ and the derived files ducksay.pdf
% \end{macrocode}
% \end{macro}^^A<<<
%
-% \begin{macro}{\ducksay_prepare_say_and_think:n}^^A>>>
+% \begin{macro}{\ducksay_say_and_think:nn}^^A>>>
% Reset some variables
% \begin{macrocode}
-\cs_new:Npn \ducksay_prepare_say_and_think:n #1
+\cs_new:Npn \ducksay_say_and_think:nn #1 #2
{
- \int_set:Nn \l_ducksay_msg_width_int { -\c_max_int }
- \int_set:Nn \l_ducksay_msg_height_int { -\c_max_int }
- \keys_set:nn { ducksay } { #1 }
- \tl_if_empty:NT \l_ducksay_animal_tl
- { \keys_set:nn { ducksay } { default_animal } }
+ \group_begin:
+ \int_set:Nn \l_ducksay_msg_width_int { -\c_max_int }
+ \int_set:Nn \l_ducksay_msg_height_int { -\c_max_int }
+ \keys_set:nn { ducksay } { #1 }
+ \tl_if_empty:NT \l_ducksay_animal_tl
+ { \keys_set:nn { ducksay } { default_animal } }
+ \ducksay_print:nV { #2 } \l_ducksay_rel_align_tl
+ \group_end:
}
% \end{macrocode}
% \end{macro}^^A<<<
@@ -1329,11 +1459,7 @@ and the derived files ducksay.pdf
% \begin{macrocode}
\NewDocumentCommand \ducksay { O{} m }
{
- \group_begin:
- \tl_set:Nn \l_ducksay_say_or_think_tl { say }
- \ducksay_prepare_say_and_think:n { #1 }
- \ducksay_print:nV { #2 } \l_ducksay_rel_align_tl
- \group_end:
+ \ducksay_say_and_think:nn { #1 } { #2 }
}
% \end{macrocode}
% \end{macro}^^A<<<
@@ -1342,11 +1468,7 @@ and the derived files ducksay.pdf
% \begin{macrocode}
\NewDocumentCommand \duckthink { O{} m }
{
- \group_begin:
- \tl_set:Nn \l_ducksay_say_or_think_tl { think }
- \ducksay_prepare_say_and_think:n { #1 }
- \ducksay_print:nV { #2 } \l_ducksay_rel_align_tl
- \group_end:
+ \ducksay_say_and_think:nn { think, #1 } { #2 }
}
% \end{macrocode}
% \end{macro}^^A<<<
@@ -1381,6 +1503,8 @@ and the derived files ducksay.pdf
The~specified~message~alignment~`\exp_not:n { #1 }`~is~unknown.~
`l`~is~used~as~fallback.
}
+\msg_new:nnn { ducksay } { v1-key-only }
+ { The~`\l_keys_key_tl`~key~is~only~available~for~`version=1`. }
% \end{macrocode}
%^^A<<<
%
@@ -1444,6 +1568,7 @@ and the derived files ducksay.pdf
,wd* .initial:n = -\c_max_dim
,wd* .value_required:n = true
,none .bool_set:N = \l_ducksay_no_body_bool
+ ,no-bubble .bool_set:N = \l_ducksay_no_bubble_bool
,body-mirrored .bool_set:N = \l_ducksay_mirrored_body_bool
,ignore-body .bool_set:N = \l_ducksay_ignored_body_bool
,body-x .dim_set:N = \l_ducksay_body_x_offset_dim
@@ -1505,7 +1630,7 @@ and the derived files ducksay.pdf
,bubble-bot-kern .initial:n = { .2ex }
,bubble-bot-kern .value_required:n = true
,bubble-side-kern .tl_set:N = \l_ducksay_bubble_side_kern_tl
- ,bubble-side-kern .initial:n = { 0.2em }
+ ,bubble-side-kern .initial:n = { .2em }
,bubble-side-kern .value_required:n = true
,bubble-delim-top .tl_set:N = \l_ducksay_bubble_delim_top_tl
,bubble-delim-left-1 .tl_set:N = \l_ducksay_bubble_delim_left_a_tl
@@ -1529,6 +1654,18 @@ and the derived files ducksay.pdf
}
% \end{macrocode}
%
+% Redefine keys only intended for version~1 to throw an error:
+%
+% \begin{macrocode}
+\clist_map_inline:nn
+ { align, rel-align }
+ {
+ \keys_define:nn { ducksay }
+ { #1 .code:n = \msg_error:nn { ducksay } { v1-key-only } }
+ }
+% \end{macrocode}
+%
+%
%^^A<<<
%
% \subsubsection{Functions}^^A>>>
@@ -1618,6 +1755,7 @@ and the derived files ducksay.pdf
% \begin{macrocode}
\cs_new:Npn \ducksay_digest_options:n #1
{
+ \group_begin:
\keys_set:nn { ducksay } { #1 }
\tl_if_empty:NT \l_ducksay_animal_tl
{ \keys_set:nn { ducksay } { default_animal } }
@@ -1672,6 +1810,7 @@ and the derived files ducksay.pdf
}
\cs_set_eq:NN \ducksay_eat_argument:w \ducksay_eat_argument_tabular:w
}
+ \ducksay_eat_argument:w
}
% \end{macrocode}
% \end{macro}^^A<<<
@@ -1708,88 +1847,119 @@ and the derived files ducksay.pdf
% \begin{macrocode}
\cs_new_protected:Npn \ducksay_shipout:
{
- \hbox_set:Nn \l_ducksay_tmpa_box
- { \l_ducksay_bubble_fount_tl \l_ducksay_bubble_delim_top_tl }
- \int_set:Nn \l_ducksay_msg_width_int
- {
- \fp_eval:n
- {
- ceil
- ( \box_wd:N \l_ducksay_msg_box / \box_wd:N \l_ducksay_tmpa_box )
- }
- }
- \group_begin:
- \l_ducksay_bubble_fount_tl
- \exp_args:NNNx
- \group_end:
- \int_set:Nn \l_ducksay_msg_height_int
+ \hcoffin_set:Nn \l_ducksay_msg_coffin { \box_use:N \l_ducksay_msg_box }
+ \bool_if:NF \l_ducksay_no_bubble_bool
{
- \int_max:nn
+ \hbox_set:Nn \l_ducksay_tmpa_box
+ { \l_ducksay_bubble_fount_tl \l_ducksay_bubble_delim_top_tl }
+ \int_set:Nn \l_ducksay_msg_width_int
{
\fp_eval:n
{
- ceil
+ ceil
(
- (
- \box_ht:N \l_ducksay_msg_box
- + \box_dp:N \l_ducksay_msg_box
- )
- / ( \arraystretch * \baselineskip )
+ \box_wd:N \l_ducksay_msg_box / \box_wd:N \l_ducksay_tmpa_box
)
}
- + \l_ducksay_vpad_int
}
- { \l_ducksay_msg_height_int }
- }
- \hcoffin_set:Nn \l_ducksay_bubble_open_coffin
- {
+ \group_begin:
\l_ducksay_bubble_fount_tl
- \begin{tabular}{@{}l@{}}
- \int_compare:nNnTF { \l_ducksay_msg_height_int } = { \c_one_int }
- {
- \l_ducksay_bubble_delim_left_a_tl
- }
- {
- \l_ducksay_bubble_delim_left_b_tl\\
- \int_step_inline:nnn
- { 3 } { \l_ducksay_msg_height_int }
+ \exp_args:NNNx
+ \group_end:
+ \int_set:Nn \l_ducksay_msg_height_int
+ {
+ \int_max:nn
+ {
+ \fp_eval:n
+ {
+ ceil
+ (
+ (
+ \box_ht:N \l_ducksay_msg_box
+ + \box_dp:N \l_ducksay_msg_box
+ )
+ / ( \arraystretch * \baselineskip )
+ )
+ }
+ + \l_ducksay_vpad_int
+ }
+ { \l_ducksay_msg_height_int }
+ }
+ \hcoffin_set:Nn \l_ducksay_bubble_open_coffin
+ {
+ \l_ducksay_bubble_fount_tl
+ \begin{tabular}{@{}l@{}}
+ \int_compare:nNnTF { \l_ducksay_msg_height_int } = { \c_one_int }
{
- \kern-\l_ducksay_bubble_side_kern_tl
- \l_ducksay_bubble_delim_left_c_tl
- \\
+ \l_ducksay_bubble_delim_left_a_tl
}
- \l_ducksay_bubble_delim_left_d_tl
- }
- \end{tabular}
- }
- \hcoffin_set:Nn \l_ducksay_bubble_close_coffin
- {
- \l_ducksay_bubble_fount_tl
- \begin{tabular}{@{}r@{}}
- \int_compare:nNnTF { \l_ducksay_msg_height_int } = { \c_one_int }
- {
- \l_ducksay_bubble_delim_right_a_tl
- }
- {
- \l_ducksay_bubble_delim_right_b_tl \\
- \int_step_inline:nnn
- { 3 } { \l_ducksay_msg_height_int }
{
- \l_ducksay_bubble_delim_right_c_tl
- \kern-\l_ducksay_bubble_side_kern_tl
- \\
+ \l_ducksay_bubble_delim_left_b_tl\\
+ \int_step_inline:nnn
+ { 3 } { \l_ducksay_msg_height_int }
+ {
+ \kern-\l_ducksay_bubble_side_kern_tl
+ \l_ducksay_bubble_delim_left_c_tl
+ \\
+ }
+ \l_ducksay_bubble_delim_left_d_tl
}
- \l_ducksay_bubble_delim_right_d_tl
- }
- \end{tabular}
- }
- \hcoffin_set:Nn \l_ducksay_bubble_top_coffin
- {
- \l_ducksay_bubble_fount_tl
- \int_step_inline:nn { \l_ducksay_msg_width_int + \l_ducksay_hpad_int }
- { \l_ducksay_bubble_delim_top_tl }
+ \end{tabular}
+ }
+ \hcoffin_set:Nn \l_ducksay_bubble_close_coffin
+ {
+ \l_ducksay_bubble_fount_tl
+ \begin{tabular}{@{}r@{}}
+ \int_compare:nNnTF { \l_ducksay_msg_height_int } = { \c_one_int }
+ {
+ \l_ducksay_bubble_delim_right_a_tl
+ }
+ {
+ \l_ducksay_bubble_delim_right_b_tl \\
+ \int_step_inline:nnn
+ { 3 } { \l_ducksay_msg_height_int }
+ {
+ \l_ducksay_bubble_delim_right_c_tl
+ \kern-\l_ducksay_bubble_side_kern_tl
+ \\
+ }
+ \l_ducksay_bubble_delim_right_d_tl
+ }
+ \end{tabular}
+ }
+ \hcoffin_set:Nn \l_ducksay_bubble_top_coffin
+ {
+ \l_ducksay_bubble_fount_tl
+ \int_step_inline:nn
+ { \l_ducksay_msg_width_int + \l_ducksay_hpad_int }
+ { \l_ducksay_bubble_delim_top_tl }
+ }
+ \dim_set:Nn \l_ducksay_hpad_dim
+ {
+ (
+ \coffin_wd:N \l_ducksay_bubble_top_coffin
+ - \coffin_wd:N \l_ducksay_msg_coffin
+ ) / 2
+ }
+ \coffin_join:NnnNnnnn
+ \l_ducksay_msg_coffin { l } { vc }
+ \l_ducksay_bubble_open_coffin { r } { vc }
+ { - \l_ducksay_hpad_dim } { \c_zero_dim }
+ \coffin_join:NnnNnnnn
+ \l_ducksay_msg_coffin { r } { vc }
+ \l_ducksay_bubble_close_coffin { l } { vc }
+ { \l_ducksay_hpad_dim } { \c_zero_dim }
+ \ducksay_set_bubble_top_kern:
+ \ducksay_set_bubble_bottom_kern:
+ \coffin_join:NnnNnnnn
+ \l_ducksay_msg_coffin { hc } { t }
+ \l_ducksay_bubble_top_coffin { hc } { b }
+ { \c_zero_dim } { \l_ducksay_bubble_top_kern_dim }
+ \coffin_join:NnnNnnnn
+ \l_ducksay_msg_coffin { hc } { b }
+ \l_ducksay_bubble_top_coffin { hc } { t }
+ { \c_zero_dim } { \l_ducksay_bubble_bottom_kern_dim }
}
- \hcoffin_set:Nn \l_ducksay_msg_coffin { \box_use:N \l_ducksay_msg_box }
\bool_if:NF \l_ducksay_no_body_bool
{
\hcoffin_set:Nn \l_ducksay_body_coffin
@@ -1810,34 +1980,6 @@ and the derived files ducksay.pdf
{ r } { \tl_set:Nn \l_ducksay_body_to_msg_align_body_tl { l } }
}
}
- }
- \dim_set:Nn \l_ducksay_hpad_dim
- {
- (
- \coffin_wd:N \l_ducksay_bubble_top_coffin
- - \coffin_wd:N \l_ducksay_msg_coffin
- ) / 2
- }
- \coffin_join:NnnNnnnn
- \l_ducksay_msg_coffin { l } { vc }
- \l_ducksay_bubble_open_coffin { r } { vc }
- { - \l_ducksay_hpad_dim } { \c_zero_dim }
- \coffin_join:NnnNnnnn
- \l_ducksay_msg_coffin { r } { vc }
- \l_ducksay_bubble_close_coffin { l } { vc }
- { \l_ducksay_hpad_dim } { \c_zero_dim }
- \ducksay_set_bubble_top_kern:
- \ducksay_set_bubble_bottom_kern:
- \coffin_join:NnnNnnnn
- \l_ducksay_msg_coffin { hc } { t }
- \l_ducksay_bubble_top_coffin { hc } { b }
- { \c_zero_dim } { \l_ducksay_bubble_top_kern_dim }
- \coffin_join:NnnNnnnn
- \l_ducksay_msg_coffin { hc } { b }
- \l_ducksay_bubble_top_coffin { hc } { t }
- { \c_zero_dim } { \l_ducksay_bubble_bottom_kern_dim }
- \bool_if:NF \l_ducksay_no_body_bool
- {
\bool_if:NTF \l_ducksay_ignored_body_bool
{ \coffin_attach:NVnNVnnn }
{ \coffin_join:NVnNVnnn }
@@ -1956,9 +2098,7 @@ and the derived files ducksay.pdf
\cs_generate_variant:Nn \coffin_join:NnnNnnnn { NVnNVnnn }
\cs_generate_variant:Nn \coffin_attach:NnnNnnnn { NVnNVnnn }
\cs_generate_variant:Nn \coffin_typeset:Nnnnn { NVVnn }
-\cs_generate_variant:Nn \tl_if_eq:nnT { VnT }
\cs_generate_variant:Nn \str_case:nn { Vn }
-\cs_generate_variant:Nn \regex_replace_all:NnN { Nnc }
% \end{macrocode}
%
%^^A<<<
@@ -1971,10 +2111,7 @@ and the derived files ducksay.pdf
% \begin{macrocode}
\NewDocumentCommand \ducksay { O{} }
{
- \group_begin:
- \tl_set:Nn \l_ducksay_say_or_think_tl { say }
- \ducksay_digest_options:n { #1 }
- \ducksay_eat_argument:w
+ \ducksay_digest_options:n { #1 }
}
% \end{macrocode}
% \end{macro}^^A<<<
@@ -1983,10 +2120,7 @@ and the derived files ducksay.pdf
% \begin{macrocode}
\NewDocumentCommand \duckthink { O{} }
{
- \group_begin:
- \tl_set:Nn \l_ducksay_say_or_think_tl { think }
- \ducksay_digest_options:n { #1 }
- \ducksay_eat_argument:w
+ \ducksay_digest_options:n { think, #1 }
}
% \end{macrocode}
% \end{macro}^^A<<<
@@ -2077,9 +2211,9 @@ and the derived files ducksay.pdf
(")
>-( : )-<
(__:__)}%<<<
-\AddAnimal{hedgehog}%>>>
-{ \ .\|//||\||.
- \ |/\/||/|//|/|
+\AddAnimal[tail-symbol=s]{hedgehog}%>>>
+{ s .\|//||\||.
+ s |/\/||/|//|/|
/. `|/\\|/||/||
o__,_|//|/||\||'}%<<<
\AddAnimal{kangaroo}%>>>
@@ -2091,10 +2225,10 @@ and the derived files ducksay.pdf
// \\
,/' `\_,}%<<<
%^^A http://chris.com/ascii/index.php?art=animals/rabbits
-\AddAnimal{rabbit}%>>>
-{ \ / \`\ __
- \ | \ `\ /`/ \
- \ \_/`\ \-"-/` /\ \
+\AddAnimal[tail-symbol=s,tail-count=3]{rabbit}%>>>
+{ s / \`\ __
+ s | \ `\ /`/ \
+ s \_/`\ \-"-/` /\ \
| | \ |
(d b) \_/
/ \
@@ -2117,10 +2251,10 @@ and the derived files ducksay.pdf
\ _//
(')---.
_/-_( )o}%<<<
-\AddAnimal{dragon}%>>>
-{ \ / \ //\
- \ |\___/| / \// \\
- \ /0 0 \__ / // | \ \
+\AddAnimal[tail-symbol=s,tail-count=3]{dragon}%>>>
+{ s / \ //\
+ s |\___/| / \// \\
+ s /0 0 \__ / // | \ \
/ / \/_/ // | \ \
@_^_@'/ \/_ // | \ \
//_^_/ \/_ // | \ \
@@ -2179,15 +2313,15 @@ and the derived files ducksay.pdf
_// _//
/_| /_|}%<<<
%^^A https://asciiart.website//index.php?art=animals/other%20(water)
-\AddAnimal{whale}%>>>
-{ \ |-.
- \ .-""-._ \ \.--|
- \ / `-..__) ,-'
+\AddAnimal[tail-count=3,tail-symbol=s]{whale}%>>>
+{ s |-.
+ s .-""-._ \ \.--|
+ s / `-..__) ,-'
| . /
\--.__, .__.,'
`-.___'._\_.'}%<<<
%^^A from http://www.ascii-art.de/ascii/s/starwars.txt :
-\AddAnimal{yoda}%>>>
+\AddAnimal[tail-count=3]{yoda}%>>>
{ \
\ ____
\ _.' : `._
@@ -2224,7 +2358,7 @@ and the derived files ducksay.pdf
:-""-.`./-.' / `.___.'
\ `t ._ /
"-.t-._:'}%<<<
-\AddAnimal{yoda-head}%>>>
+\AddAnimal[tail-count=3]{yoda-head}%>>>
{ \
\ ____
\ _.' : `._
@@ -2279,6 +2413,36 @@ and the derived files ducksay.pdf
/_ \O========O/ _\
`--...__|`-._ _.-'|__...--'
| `' |}%<<<
+\AddAnimal[tail-symbol=|,tail-count=1]{crusader}%>>>
+{ |
+\[T]/}
+\csname bool_if:cT\endcsname {l_ducksay_version_one_bool}
+ {\AnimalOptions{crusader}{tail-1=|,rel-align=c}}
+\csname bool_if:cT\endcsname {l_ducksay_version_two_bool}
+ {\AnimalOptions{crusader}{tail-1=|,body-align=c}}%<<<
+%^^A http://ascii.co.uk/art/knights
+\AddAnimal[tail-count=3]{knight}%>>>
+{ \
+ \ ,-"""-.
+ \ | === |
+ ) | (
+ .=='\" "/`==.
+ .'\ (`:') /`.
+ _/_ |_.-' : `-._|__\_
+ <___>'\ : / `<___>
+ / / >=======< / /
+ _/ .' / ,-:-. \/=,'
+/ _/ |__/v^v^v\__) \
+\(\) |V^V^V^V^V|\_/
+ (\\ \`---|---'/
+ \\ \-._|_,-/
+ \\ |__|__|
+ \\ <___X___>
+ \\ \..|../
+ \\ \ | /
+ \\ /V|V\
+ \|/ | \
+ '--' `--`}%<<<
%</animals>
% \end{macrocode}^^A<<<
%
diff --git a/Master/texmf-dist/tex/latex/ducksay/ducksay.animals.tex b/Master/texmf-dist/tex/latex/ducksay/ducksay.animals.tex
index 32f8df1aa2d..e0077f6f47b 100644
--- a/Master/texmf-dist/tex/latex/ducksay/ducksay.animals.tex
+++ b/Master/texmf-dist/tex/latex/ducksay/ducksay.animals.tex
@@ -104,9 +104,9 @@
(")
>-( : )-<
(__:__)}%<<<
-\AddAnimal{hedgehog}%>>>
-{ \ .\|//||\||.
- \ |/\/||/|//|/|
+\AddAnimal[tail-symbol=s]{hedgehog}%>>>
+{ s .\|//||\||.
+ s |/\/||/|//|/|
/. `|/\\|/||/||
o__,_|//|/||\||'}%<<<
\AddAnimal{kangaroo}%>>>
@@ -117,10 +117,10 @@
\,\ / \\
// \\
,/' `\_,}%<<<
-\AddAnimal{rabbit}%>>>
-{ \ / \`\ __
- \ | \ `\ /`/ \
- \ \_/`\ \-"-/` /\ \
+\AddAnimal[tail-symbol=s,tail-count=3]{rabbit}%>>>
+{ s / \`\ __
+ s | \ `\ /`/ \
+ s \_/`\ \-"-/` /\ \
| | \ |
(d b) \_/
/ \
@@ -143,10 +143,10 @@
\ _//
(')---.
_/-_( )o}%<<<
-\AddAnimal{dragon}%>>>
-{ \ / \ //\
- \ |\___/| / \// \\
- \ /0 0 \__ / // | \ \
+\AddAnimal[tail-symbol=s,tail-count=3]{dragon}%>>>
+{ s / \ //\
+ s |\___/| / \// \\
+ s /0 0 \__ / // | \ \
/ / \/_/ // | \ \
@_^_@'/ \/_ // | \ \
//_^_/ \/_ // | \ \
@@ -201,14 +201,14 @@
\_| / / / /
_// _//
/_| /_|}%<<<
-\AddAnimal{whale}%>>>
-{ \ |-.
- \ .-""-._ \ \.--|
- \ / `-..__) ,-'
+\AddAnimal[tail-count=3,tail-symbol=s]{whale}%>>>
+{ s |-.
+ s .-""-._ \ \.--|
+ s / `-..__) ,-'
| . /
\--.__, .__.,'
`-.___'._\_.'}%<<<
-\AddAnimal{yoda}%>>>
+\AddAnimal[tail-count=3]{yoda}%>>>
{ \
\ ____
\ _.' : `._
@@ -245,7 +245,7 @@
:-""-.`./-.' / `.___.'
\ `t ._ /
"-.t-._:'}%<<<
-\AddAnimal{yoda-head}%>>>
+\AddAnimal[tail-count=3]{yoda-head}%>>>
{ \
\ ____
\ _.' : `._
@@ -299,6 +299,35 @@
/_ \O========O/ _\
`--...__|`-._ _.-'|__...--'
| `' |}%<<<
+\AddAnimal[tail-symbol=|,tail-count=1]{crusader}%>>>
+{ |
+\[T]/}
+\csname bool_if:cT\endcsname {l_ducksay_version_one_bool}
+ {\AnimalOptions{crusader}{tail-1=|,rel-align=c}}
+\csname bool_if:cT\endcsname {l_ducksay_version_two_bool}
+ {\AnimalOptions{crusader}{tail-1=|,body-align=c}}%<<<
+\AddAnimal[tail-count=3]{knight}%>>>
+{ \
+ \ ,-"""-.
+ \ | === |
+ ) | (
+ .=='\" "/`==.
+ .'\ (`:') /`.
+ _/_ |_.-' : `-._|__\_
+ <___>'\ : / `<___>
+ / / >=======< / /
+ _/ .' / ,-:-. \/=,'
+/ _/ |__/v^v^v\__) \
+\(\) |V^V^V^V^V|\_/
+ (\\ \`---|---'/
+ \\ \-._|_,-/
+ \\ |__|__|
+ \\ <___X___>
+ \\ \..|../
+ \\ \ | /
+ \\ /V|V\
+ \|/ | \
+ '--' `--`}%<<<
%%
%%
%% End of file `ducksay.animals.tex'.
diff --git a/Master/texmf-dist/tex/latex/ducksay/ducksay.code.v1.tex b/Master/texmf-dist/tex/latex/ducksay/ducksay.code.v1.tex
index a5a1bab3414..1d6487c7674 100644
--- a/Master/texmf-dist/tex/latex/ducksay/ducksay.code.v1.tex
+++ b/Master/texmf-dist/tex/latex/ducksay/ducksay.code.v1.tex
@@ -125,29 +125,24 @@
\group_end:
}
\cs_generate_variant:Nn \ducksay_print:nn { nV }
-\cs_new:Npn \ducksay_prepare_say_and_think:n #1
- {
- \int_set:Nn \l_ducksay_msg_width_int { -\c_max_int }
- \int_set:Nn \l_ducksay_msg_height_int { -\c_max_int }
- \keys_set:nn { ducksay } { #1 }
- \tl_if_empty:NT \l_ducksay_animal_tl
- { \keys_set:nn { ducksay } { default_animal } }
- }
-\NewDocumentCommand \ducksay { O{} m }
+\cs_new:Npn \ducksay_say_and_think:nn #1 #2
{
\group_begin:
- \tl_set:Nn \l_ducksay_say_or_think_tl { say }
- \ducksay_prepare_say_and_think:n { #1 }
+ \int_set:Nn \l_ducksay_msg_width_int { -\c_max_int }
+ \int_set:Nn \l_ducksay_msg_height_int { -\c_max_int }
+ \keys_set:nn { ducksay } { #1 }
+ \tl_if_empty:NT \l_ducksay_animal_tl
+ { \keys_set:nn { ducksay } { default_animal } }
\ducksay_print:nV { #2 } \l_ducksay_rel_align_tl
\group_end:
}
+\NewDocumentCommand \ducksay { O{} m }
+ {
+ \ducksay_say_and_think:nn { #1 } { #2 }
+ }
\NewDocumentCommand \duckthink { O{} m }
{
- \group_begin:
- \tl_set:Nn \l_ducksay_say_or_think_tl { think }
- \ducksay_prepare_say_and_think:n { #1 }
- \ducksay_print:nV { #2 } \l_ducksay_rel_align_tl
- \group_end:
+ \ducksay_say_and_think:nn { think, #1 } { #2 }
}
%%
%%
diff --git a/Master/texmf-dist/tex/latex/ducksay/ducksay.code.v2.tex b/Master/texmf-dist/tex/latex/ducksay/ducksay.code.v2.tex
index fbd1143b637..413e221bbaa 100644
--- a/Master/texmf-dist/tex/latex/ducksay/ducksay.code.v2.tex
+++ b/Master/texmf-dist/tex/latex/ducksay/ducksay.code.v2.tex
@@ -43,6 +43,8 @@
The~specified~message~alignment~`\exp_not:n { #1 }`~is~unknown.~
`l`~is~used~as~fallback.
}
+\msg_new:nnn { ducksay } { v1-key-only }
+ { The~`\l_keys_key_tl`~key~is~only~available~for~`version=1`. }
\tl_new:N \l_ducksay_msg_align_vbox_tl
\box_new:N \l_ducksay_msg_box
\bool_new:N \l_ducksay_eat_arg_box_bool
@@ -76,6 +78,7 @@
,wd* .initial:n = -\c_max_dim
,wd* .value_required:n = true
,none .bool_set:N = \l_ducksay_no_body_bool
+ ,no-bubble .bool_set:N = \l_ducksay_no_bubble_bool
,body-mirrored .bool_set:N = \l_ducksay_mirrored_body_bool
,ignore-body .bool_set:N = \l_ducksay_ignored_body_bool
,body-x .dim_set:N = \l_ducksay_body_x_offset_dim
@@ -137,7 +140,7 @@
,bubble-bot-kern .initial:n = { .2ex }
,bubble-bot-kern .value_required:n = true
,bubble-side-kern .tl_set:N = \l_ducksay_bubble_side_kern_tl
- ,bubble-side-kern .initial:n = { 0.2em }
+ ,bubble-side-kern .initial:n = { .2em }
,bubble-side-kern .value_required:n = true
,bubble-delim-top .tl_set:N = \l_ducksay_bubble_delim_top_tl
,bubble-delim-left-1 .tl_set:N = \l_ducksay_bubble_delim_left_a_tl
@@ -159,6 +162,12 @@
,bubble-delim-right-4 .initial:n = /
,strip-spaces .bool_set:N = \l_ducksay_msg_strip_spaces_bool
}
+\clist_map_inline:nn
+ { align, rel-align }
+ {
+ \keys_define:nn { ducksay }
+ { #1 .code:n = \msg_error:nn { ducksay } { v1-key-only } }
+ }
\cs_new:Npn \ducksay_evaluate_message_alignment_fixed_width_common:
{
\str_case:Vn \l_ducksay_msg_align_tl
@@ -210,6 +219,7 @@
}
\cs_new:Npn \ducksay_digest_options:n #1
{
+ \group_begin:
\keys_set:nn { ducksay } { #1 }
\tl_if_empty:NT \l_ducksay_animal_tl
{ \keys_set:nn { ducksay } { default_animal } }
@@ -264,6 +274,7 @@
}
\cs_set_eq:NN \ducksay_eat_argument:w \ducksay_eat_argument_tabular:w
}
+ \ducksay_eat_argument:w
}
\cs_new:Npn \ducksay_set_bubble_top_kern:
{
@@ -285,88 +296,119 @@
}
\cs_new_protected:Npn \ducksay_shipout:
{
- \hbox_set:Nn \l_ducksay_tmpa_box
- { \l_ducksay_bubble_fount_tl \l_ducksay_bubble_delim_top_tl }
- \int_set:Nn \l_ducksay_msg_width_int
- {
- \fp_eval:n
- {
- ceil
- ( \box_wd:N \l_ducksay_msg_box / \box_wd:N \l_ducksay_tmpa_box )
- }
- }
- \group_begin:
- \l_ducksay_bubble_fount_tl
- \exp_args:NNNx
- \group_end:
- \int_set:Nn \l_ducksay_msg_height_int
+ \hcoffin_set:Nn \l_ducksay_msg_coffin { \box_use:N \l_ducksay_msg_box }
+ \bool_if:NF \l_ducksay_no_bubble_bool
{
- \int_max:nn
+ \hbox_set:Nn \l_ducksay_tmpa_box
+ { \l_ducksay_bubble_fount_tl \l_ducksay_bubble_delim_top_tl }
+ \int_set:Nn \l_ducksay_msg_width_int
{
\fp_eval:n
{
ceil
(
- (
- \box_ht:N \l_ducksay_msg_box
- + \box_dp:N \l_ducksay_msg_box
- )
- / ( \arraystretch * \baselineskip )
+ \box_wd:N \l_ducksay_msg_box / \box_wd:N \l_ducksay_tmpa_box
)
}
- + \l_ducksay_vpad_int
}
- { \l_ducksay_msg_height_int }
- }
- \hcoffin_set:Nn \l_ducksay_bubble_open_coffin
- {
+ \group_begin:
\l_ducksay_bubble_fount_tl
- \begin{tabular}{@{}l@{}}
- \int_compare:nNnTF { \l_ducksay_msg_height_int } = { \c_one_int }
- {
- \l_ducksay_bubble_delim_left_a_tl
- }
- {
- \l_ducksay_bubble_delim_left_b_tl\\
- \int_step_inline:nnn
- { 3 } { \l_ducksay_msg_height_int }
+ \exp_args:NNNx
+ \group_end:
+ \int_set:Nn \l_ducksay_msg_height_int
+ {
+ \int_max:nn
+ {
+ \fp_eval:n
+ {
+ ceil
+ (
+ (
+ \box_ht:N \l_ducksay_msg_box
+ + \box_dp:N \l_ducksay_msg_box
+ )
+ / ( \arraystretch * \baselineskip )
+ )
+ }
+ + \l_ducksay_vpad_int
+ }
+ { \l_ducksay_msg_height_int }
+ }
+ \hcoffin_set:Nn \l_ducksay_bubble_open_coffin
+ {
+ \l_ducksay_bubble_fount_tl
+ \begin{tabular}{@{}l@{}}
+ \int_compare:nNnTF { \l_ducksay_msg_height_int } = { \c_one_int }
{
- \kern-\l_ducksay_bubble_side_kern_tl
- \l_ducksay_bubble_delim_left_c_tl
- \\
+ \l_ducksay_bubble_delim_left_a_tl
}
- \l_ducksay_bubble_delim_left_d_tl
- }
- \end{tabular}
- }
- \hcoffin_set:Nn \l_ducksay_bubble_close_coffin
- {
- \l_ducksay_bubble_fount_tl
- \begin{tabular}{@{}r@{}}
- \int_compare:nNnTF { \l_ducksay_msg_height_int } = { \c_one_int }
- {
- \l_ducksay_bubble_delim_right_a_tl
- }
- {
- \l_ducksay_bubble_delim_right_b_tl \\
- \int_step_inline:nnn
- { 3 } { \l_ducksay_msg_height_int }
{
- \l_ducksay_bubble_delim_right_c_tl
- \kern-\l_ducksay_bubble_side_kern_tl
- \\
+ \l_ducksay_bubble_delim_left_b_tl\\
+ \int_step_inline:nnn
+ { 3 } { \l_ducksay_msg_height_int }
+ {
+ \kern-\l_ducksay_bubble_side_kern_tl
+ \l_ducksay_bubble_delim_left_c_tl
+ \\
+ }
+ \l_ducksay_bubble_delim_left_d_tl
}
- \l_ducksay_bubble_delim_right_d_tl
- }
- \end{tabular}
- }
- \hcoffin_set:Nn \l_ducksay_bubble_top_coffin
- {
- \l_ducksay_bubble_fount_tl
- \int_step_inline:nn { \l_ducksay_msg_width_int + \l_ducksay_hpad_int }
- { \l_ducksay_bubble_delim_top_tl }
+ \end{tabular}
+ }
+ \hcoffin_set:Nn \l_ducksay_bubble_close_coffin
+ {
+ \l_ducksay_bubble_fount_tl
+ \begin{tabular}{@{}r@{}}
+ \int_compare:nNnTF { \l_ducksay_msg_height_int } = { \c_one_int }
+ {
+ \l_ducksay_bubble_delim_right_a_tl
+ }
+ {
+ \l_ducksay_bubble_delim_right_b_tl \\
+ \int_step_inline:nnn
+ { 3 } { \l_ducksay_msg_height_int }
+ {
+ \l_ducksay_bubble_delim_right_c_tl
+ \kern-\l_ducksay_bubble_side_kern_tl
+ \\
+ }
+ \l_ducksay_bubble_delim_right_d_tl
+ }
+ \end{tabular}
+ }
+ \hcoffin_set:Nn \l_ducksay_bubble_top_coffin
+ {
+ \l_ducksay_bubble_fount_tl
+ \int_step_inline:nn
+ { \l_ducksay_msg_width_int + \l_ducksay_hpad_int }
+ { \l_ducksay_bubble_delim_top_tl }
+ }
+ \dim_set:Nn \l_ducksay_hpad_dim
+ {
+ (
+ \coffin_wd:N \l_ducksay_bubble_top_coffin
+ - \coffin_wd:N \l_ducksay_msg_coffin
+ ) / 2
+ }
+ \coffin_join:NnnNnnnn
+ \l_ducksay_msg_coffin { l } { vc }
+ \l_ducksay_bubble_open_coffin { r } { vc }
+ { - \l_ducksay_hpad_dim } { \c_zero_dim }
+ \coffin_join:NnnNnnnn
+ \l_ducksay_msg_coffin { r } { vc }
+ \l_ducksay_bubble_close_coffin { l } { vc }
+ { \l_ducksay_hpad_dim } { \c_zero_dim }
+ \ducksay_set_bubble_top_kern:
+ \ducksay_set_bubble_bottom_kern:
+ \coffin_join:NnnNnnnn
+ \l_ducksay_msg_coffin { hc } { t }
+ \l_ducksay_bubble_top_coffin { hc } { b }
+ { \c_zero_dim } { \l_ducksay_bubble_top_kern_dim }
+ \coffin_join:NnnNnnnn
+ \l_ducksay_msg_coffin { hc } { b }
+ \l_ducksay_bubble_top_coffin { hc } { t }
+ { \c_zero_dim } { \l_ducksay_bubble_bottom_kern_dim }
}
- \hcoffin_set:Nn \l_ducksay_msg_coffin { \box_use:N \l_ducksay_msg_box }
\bool_if:NF \l_ducksay_no_body_bool
{
\hcoffin_set:Nn \l_ducksay_body_coffin
@@ -387,34 +429,6 @@
{ r } { \tl_set:Nn \l_ducksay_body_to_msg_align_body_tl { l } }
}
}
- }
- \dim_set:Nn \l_ducksay_hpad_dim
- {
- (
- \coffin_wd:N \l_ducksay_bubble_top_coffin
- - \coffin_wd:N \l_ducksay_msg_coffin
- ) / 2
- }
- \coffin_join:NnnNnnnn
- \l_ducksay_msg_coffin { l } { vc }
- \l_ducksay_bubble_open_coffin { r } { vc }
- { - \l_ducksay_hpad_dim } { \c_zero_dim }
- \coffin_join:NnnNnnnn
- \l_ducksay_msg_coffin { r } { vc }
- \l_ducksay_bubble_close_coffin { l } { vc }
- { \l_ducksay_hpad_dim } { \c_zero_dim }
- \ducksay_set_bubble_top_kern:
- \ducksay_set_bubble_bottom_kern:
- \coffin_join:NnnNnnnn
- \l_ducksay_msg_coffin { hc } { t }
- \l_ducksay_bubble_top_coffin { hc } { b }
- { \c_zero_dim } { \l_ducksay_bubble_top_kern_dim }
- \coffin_join:NnnNnnnn
- \l_ducksay_msg_coffin { hc } { b }
- \l_ducksay_bubble_top_coffin { hc } { t }
- { \c_zero_dim } { \l_ducksay_bubble_bottom_kern_dim }
- \bool_if:NF \l_ducksay_no_body_bool
- {
\bool_if:NTF \l_ducksay_ignored_body_bool
{ \coffin_attach:NVnNVnnn }
{ \coffin_join:NVnNVnnn }
@@ -485,22 +499,14 @@
\cs_generate_variant:Nn \coffin_join:NnnNnnnn { NVnNVnnn }
\cs_generate_variant:Nn \coffin_attach:NnnNnnnn { NVnNVnnn }
\cs_generate_variant:Nn \coffin_typeset:Nnnnn { NVVnn }
-\cs_generate_variant:Nn \tl_if_eq:nnT { VnT }
\cs_generate_variant:Nn \str_case:nn { Vn }
-\cs_generate_variant:Nn \regex_replace_all:NnN { Nnc }
\NewDocumentCommand \ducksay { O{} }
{
- \group_begin:
- \tl_set:Nn \l_ducksay_say_or_think_tl { say }
- \ducksay_digest_options:n { #1 }
- \ducksay_eat_argument:w
+ \ducksay_digest_options:n { #1 }
}
\NewDocumentCommand \duckthink { O{} }
{
- \group_begin:
- \tl_set:Nn \l_ducksay_say_or_think_tl { think }
- \ducksay_digest_options:n { #1 }
- \ducksay_eat_argument:w
+ \ducksay_digest_options:n { think, #1 }
}
%%
%%
diff --git a/Master/texmf-dist/tex/latex/ducksay/ducksay.sty b/Master/texmf-dist/tex/latex/ducksay/ducksay.sty
index 6d140038d95..98d096c4175 100644
--- a/Master/texmf-dist/tex/latex/ducksay/ducksay.sty
+++ b/Master/texmf-dist/tex/latex/ducksay/ducksay.sty
@@ -35,8 +35,8 @@
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{xparse,l3keys2e}
-\def\ducksay@version{2.2.1}
-\def\ducksay@date{2019-01-08}
+\def\ducksay@version{2.3}
+\def\ducksay@date{2019-01-13}
\ProvidesExplPackage
{ducksay} {\ducksay@date}
@@ -44,22 +44,20 @@
\int_new:N \l_ducksay_msg_width_int
\int_new:N \l_ducksay_msg_height_int
+\int_new:N \l_ducksay_tail_symbol_count_int
\seq_new:N \l_ducksay_msg_lines_seq
-\tl_new:N \l_ducksay_say_or_think_tl
\tl_new:N \l_ducksay_align_tl
\tl_new:N \l_ducksay_msg_align_tl
\tl_new:N \l_ducksay_animal_tl
\tl_new:N \l_ducksay_body_tl
\tl_new:N \l_ducksay_bubble_tl
\tl_new:N \l_ducksay_tmpa_tl
-\bool_new:N \l_ducksay_also_add_think_bool
+\tl_new:N \l_ducksay_tail_symbol_out_one_tl
+\tl_new:N \l_ducksay_tail_symbol_out_two_tl
+\tl_new:N \l_ducksay_tail_symbol_in_tl
\bool_new:N \l_ducksay_version_one_bool
\bool_new:N \l_ducksay_version_two_bool
\box_new:N \l_ducksay_tmpa_box
-\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*)\\ }
\regex_const:Nn \c_ducksay_textcolor_regex
{ \cO(?:\\textcolor\{(.*?)\}\{(.*?)\}) }
\regex_const:Nn \c_ducksay_color_delim_regex
@@ -68,6 +66,8 @@
{ \cO(?:\\color\{(.*?)\}) }
\msg_new:nnn { ducksay } { load-time-only }
{ The~`#1`~key~is~to~be~used~only~during~package~load~time. }
+\msg_new:nnn { ducksay } { deprecated-key }
+ { The~`\l_keys_key_tl`~key~is~deprecated.~Sorry~for~the~inconvenience. }
\keys_define:nn { ducksay }
{
,bubble .tl_set:N = \l_ducksay_bubble_tl
@@ -91,7 +91,17 @@
,rel-align .value_required:n = true
,ligatures .tl_set:N = \l_ducksay_ligatures_tl
,ligatures .initial:n = { `<>,'- }
- ,add-think .bool_set:N = \l_ducksay_also_add_think_bool
+ ,tail-1 .tl_set:N = \l_ducksay_tail_symbol_out_one_tl
+ ,tail-1 .initial:x = \c_backslash_str
+ ,tail-2 .tl_set:N = \l_ducksay_tail_symbol_out_two_tl
+ ,tail-2 .initial:x = \c_backslash_str
+ ,no-tail .meta:n = { tail-1 = { ~ }, tail-2 = { ~ } }
+ ,think .meta:n = { tail-1 = { O }, tail-2 = { o } }
+ ,say .code:n =
+ {
+ \exp_args:Nx \DucksayOptions
+ { tail-1 = { \c_backslash_str }, tail-2 = { \c_backslash_str } }
+ }
,version .choice:
,version / 1 .code:n =
{
@@ -104,23 +114,23 @@
\bool_set_true:N \l_ducksay_version_two_bool
}
,version .initial:n = 2
+ ,add-think .code:n = \msg_error:nn { ducksay } { deprecated-key }
}
\ProcessKeysOptions { ducksay }
\keys_define:nn { ducksay }
{
version .code:n = \msg_error:nnn { ducksay } { load-time-only } { version }
}
-\cs_generate_variant:Nn \tl_if_eq:nnT { VnT }
-\cs_new_protected:Npn \ducksay_create_think_animal:n #1
+\keys_define:nn { ducksay / add-animal }
{
- \group_begin:
- \tl_set_eq:Nc \l_ducksay_tmpa_tl { g_ducksay_animal_say_#1_tl }
- \regex_replace_once:NnN \c_ducksay_first_regex { \1O } \l_ducksay_tmpa_tl
- \regex_replace_once:NnN \c_ducksay_second_regex { \1o } \l_ducksay_tmpa_tl
- \regex_replace_once:NnN \c_ducksay_third_regex { \1o } \l_ducksay_tmpa_tl
- \tl_gset_eq:cN { g_ducksay_animal_think_#1_tl } \l_ducksay_tmpa_tl
- \group_end:
+ ,tail-symbol .code:n =
+ \tl_set:Nx \l_ducksay_tail_symbol_in_tl { \tl_to_str:n { #1 } }
+ ,tail-symbol .initial:o = \c_backslash_str
+ ,tail-count .int_set:N = \l_ducksay_tail_symbol_count_int
+ ,tail-count .initial:n = 2
}
+\cs_generate_variant:Nn \tl_replace_once:Nnn { NVn }
+\cs_generate_variant:Nn \tl_replace_all:Nnn { NVn }
\cs_new_protected:Npx \ducksay_replace_verb_newline:Nn #1 #2
{
\tl_replace_all:Nnn #1 { \char_generate:nn { 13 } { 12 } } { #2 }
@@ -136,25 +146,63 @@
\ducksay_replace_verb_newline_newline:Nn \ProcessedArgument { #2 }
\ducksay_replace_verb_newline:Nn \ProcessedArgument { #1 }
}
-\cs_new_protected:Npn \ducksay_add_animal_inner:nn #1 #2
+\cs_new_protected:Npn \ducksay_add_animal_inner:nnnn #1 #2 #3 #4
{
- \tl_set:Nn \l_ducksay_tmpa_tl { \ #2 }
- \tl_map_inline:Nn \l_ducksay_ligatures_tl
- { \tl_replace_all:Nnn \l_ducksay_tmpa_tl { ##1 } { { ##1 } } }
- \ducksay_replace_verb_newline:Nn \l_ducksay_tmpa_tl { \tabularnewline\null }
- \tl_gset_eq:cN { g_ducksay_animal_say_#1_tl } \l_ducksay_tmpa_tl
- \keys_define:nn { ducksay }
+ \group_begin:
+ \keys_set:nn { ducksay / add-animal } { #1 }
+ \tl_set:Nn \l_ducksay_tmpa_tl { \ #3 }
+ \int_compare:nNnTF { \l_ducksay_tail_symbol_count_int } < { \c_zero_int }
+ {
+ \tl_replace_once:NVn
+ \l_ducksay_tmpa_tl
+ \l_ducksay_tail_symbol_in_tl
+ \l_ducksay_tail_symbol_out_one_tl
+ \tl_replace_all:NVn
+ \l_ducksay_tmpa_tl
+ \l_ducksay_tail_symbol_in_tl
+ \l_ducksay_tail_symbol_out_two_tl
+ }
+ {
+ \int_compare:nNnT { \l_ducksay_tail_symbol_count_int } >
+ { \c_zero_int }
+ {
+ \tl_replace_once:NVn
+ \l_ducksay_tmpa_tl
+ \l_ducksay_tail_symbol_in_tl
+ \l_ducksay_tail_symbol_out_one_tl
+ \int_step_inline:nnn { 2 } { \l_ducksay_tail_symbol_count_int }
+ {
+ \tl_replace_once:NVn
+ \l_ducksay_tmpa_tl
+ \l_ducksay_tail_symbol_in_tl
+ \l_ducksay_tail_symbol_out_two_tl
+ }
+ }
+ }
+ \tl_map_inline:Nn \l_ducksay_ligatures_tl
+ { \tl_replace_all:Nnn \l_ducksay_tmpa_tl { ##1 } { { ##1 } } }
+ \ducksay_replace_verb_newline:Nn \l_ducksay_tmpa_tl
+ { \tabularnewline\null }
+ \exp_args:NNnV
+ \group_end:
+ \tl_set:cn { l_ducksay_animal_#2_tl } \l_ducksay_tmpa_tl
+ \exp_args:Nnx \keys_define:nn { ducksay }
{
- #1 .code:n =
+ #2 .code:n =
{
- \tl_if_exist:cF
- { g_ducksay_animal_ \l_ducksay_say_or_think_tl _#1_tl }
- { \ducksay_create_think_animal:n { #1 } }
- \tl_set_eq:Nc \l_ducksay_animal_tl
- { g_ducksay_animal_ \l_ducksay_say_or_think_tl _#1_tl }
+ \exp_not:n { \tl_set_eq:NN \l_ducksay_animal_tl }
+ \exp_after:wN \exp_not:N \cs:w l_ducksay_animal_#2_tl \cs_end:
+ \exp_not:n { \exp_args:NV \DucksayOptions }
+ \exp_after:wN
+ \exp_not:N \cs:w l_ducksay_animal_#2_options_tl \cs_end:
}
}
+ \tl_if_exist:cF { l_ducksay_animal_#2_options_tl }
+ { \tl_new:c { l_ducksay_animal_#2_options_tl } }
+ \IfBooleanT { #4 }
+ { \keys_define:nn { ducksay } { default_animal .meta:n = { #2 } } }
}
+\cs_generate_variant:Nn \ducksay_add_animal_inner:nnnn { nnVn }
\NewDocumentCommand \DefaultAnimal { m }
{
\keys_define:nn { ducksay } { default_animal .meta:n = { #1 } }
@@ -163,30 +211,34 @@
{
\keys_set:nn { ducksay } { #1 }
}
-\NewDocumentCommand \AddAnimal { s m +v }
+\NewDocumentCommand \AddAnimal { s O{} m +v }
{
- \ducksay_add_animal_inner:nn { #2 } { #3 }
- \bool_if:NT \l_ducksay_also_add_think_bool
- { \ducksay_create_think_animal:n { #2 } }
- \IfBooleanT{#1}
- { \keys_define:nn { ducksay } { default_animal .meta:n = { #2 } } }
+ \ducksay_add_animal_inner:nnnn { #2 } { #3 } { #4 } { #1 }
}
-\NewDocumentCommand \AddColoredAnimal { s m +v }
+\NewDocumentCommand \AddColoredAnimal { s O{} m +v }
{
- \ducksay_add_animal_inner:nn { #2 } { #3 }
- \regex_replace_all:Nnc \c_ducksay_color_delim_regex
+ \tl_set:Nn \l_ducksay_tmpa_tl { #4 }
+ \regex_replace_all:NnN \c_ducksay_color_delim_regex
{ \c{bgroup}\c{color}\cB\{\1\cE\}\2\c{egroup} }
- { g_ducksay_animal_say_#2_tl }
- \regex_replace_all:Nnc \c_ducksay_color_regex
+ \l_ducksay_tmpa_tl
+ \regex_replace_all:NnN \c_ducksay_color_regex
{ \c{color}\cB\{\1\cE\} }
- { g_ducksay_animal_say_#2_tl }
- \regex_replace_all:Nnc \c_ducksay_textcolor_regex
+ \l_ducksay_tmpa_tl
+ \regex_replace_all:NnN \c_ducksay_textcolor_regex
{ \c{textcolor}\cB\{\1\cE\}\cB\{\2\cE\} }
- { g_ducksay_animal_say_#2_tl }
- \bool_if:NT \l_ducksay_also_add_think_bool
- { \ducksay_create_think_animal:n { #2 } }
- \IfBooleanT{#1}
- { \keys_define:nn { ducksay } { default_animal .meta:n = { #2 } } }
+ \l_ducksay_tmpa_tl
+ \ducksay_add_animal_inner:nnVn { #2 } { #3 } \l_ducksay_tmpa_tl { #1 }
+ }
+\NewDocumentCommand \AnimalOptions { s m m }
+ {
+ \tl_if_exist:cTF { l_ducksay_animal_#2_options_tl }
+ {
+ \IfBooleanTF { #1 }
+ { \tl_set:cn }
+ { \tl_put_right:cn }
+ }
+ { \tl_set:cn }
+ { l_ducksay_animal_#2_options_tl } { #3, }
}
\bool_if:NT \l_ducksay_version_one_bool
{ \file_input:n { ducksay.code.v1.tex } }