diff options
author | Karl Berry <karl@freefriends.org> | 2017-10-30 20:40:11 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-10-30 20:40:11 +0000 |
commit | d1742894869da9494417216646bc5627ef3f3352 (patch) | |
tree | 72f25c524fd78ea0bce5cbfe612902388b71319a | |
parent | 518143fa6ebbdfe93702cf0184bd96964a09b09d (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.md | 12 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/ducksay/ducksay.tex | 240 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/ducksay/ducksay.sty | 172 |
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=>>>,<<< |