From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/duckuments/duckuments.dtx | 1227 ++++++++++++++++++++++++ 1 file changed, 1227 insertions(+) create mode 100644 macros/latex/contrib/duckuments/duckuments.dtx (limited to 'macros/latex/contrib/duckuments/duckuments.dtx') diff --git a/macros/latex/contrib/duckuments/duckuments.dtx b/macros/latex/contrib/duckuments/duckuments.dtx new file mode 100644 index 0000000000..0460a3f1dc --- /dev/null +++ b/macros/latex/contrib/duckuments/duckuments.dtx @@ -0,0 +1,1227 @@ +% \iffalse meta-comment +% +% File: duckuments.dtx Copyright (C) 2018-2019 Jonathan P. Spratte +% +% It may be distributed and/or modified under the conditions of the LaTeX +% Project Public License (LPPL), either version 1.3c of this license or (at your +% option) any later version. The latest version of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% ------------------------------------------------------------------------------ +% +%<*driver> +\def\nameofplainTeX{plain} +\ifx\fmtname\nameofplainTeX\else + \expandafter\begingroup +\fi +\input l3docstrip.tex +\askforoverwritefalse +\preamble + +-------------------------------------------------------------- +duckuments -- minimal working duckuments +E-mail: jspratte@yahoo.de +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +-------------------------------------------------------------- + +Copyright (C) 2018-2019 Jonathan P. Spratte + +This work may be distributed and/or modified under the conditions of the +LaTeX Project Public License (LPPL), either version 1.3c of this license or +(at your option) any later version. The latest version of this license is in +the file: + + http://www.latex-project.org/lppl.txt + +This work is "maintained" (as per LPPL maintenance status) by + Jonathan P. Spratte. + +This work consists of the file duckuments.dtx +and the derived files duckuments.pdf, + duckuments.sty, + example-image-duck.tex and + example-image-duck-portrait.tex + +\endpreamble +% stop docstrip adding \endinput +\postamble +\endpostamble +\generate{\file{duckuments.sty}{\from{duckuments.dtx}{pkg}}} +\generate{\file{example-image-duck.tex}{\from{duckuments.dtx}{eid}}} +\generate{\file{example-image-duck-portrait.tex}{\from{duckuments.dtx}{eidp}}} +\ifx\fmtname\nameofplainTeX + \expandafter\endbatchfile +\else + \expandafter\endgroup +\fi +% +% +%<*driver|pkg> +\RequirePackage{xparse}[2019-05-03] +\RequirePackage{letltxmacro,l3keys2e} +\def\duckuments@version{0.4d} +\def\duckuments@date{2019/06/02} +% +% +%<*driver> +\ProvidesFile{duckuments.dtx} + [\csname duckuments@date\endcsname\space minimal working duckuments] +\documentclass{l3doc} +\usepackage{duckuments} +\usepackage{enumitem} +\newenvironment{options} + {\begin{description}[style=nextline,font=\normalfont\ttfamily]} + {\end{description}} +\begin{document} + \DocInput{duckuments.dtx} +\end{document} +% +% +%<*eid> +\documentclass[tikz,multi]{standalone} + +\usepackage{tikzducks} +\usepackage{duckuments} + +\begin{document} +\duckumentsDrawRandomDucks +\end{document} +% +% +%<*eidp> +\documentclass[tikz,multi]{standalone} + +\usepackage{tikzducks} +\usepackage{duckuments} + +\begin{document} +\duckumentsDrawRandomDucks* +\end{document} +% +% +%<*pkg> +\ProvidesExplPackage + {duckuments} {\duckuments@date} + {\duckuments@version} {minimal working duckuments} +% +% \fi +% +% \title{The \pkg{duckuments} package} +% \author{Jonathan P. Spratte\thanks{E-mail: jspratte@yahoo.de}} +% \makeatletter +% \date{version \duckuments@version, released \duckuments@date} +% \makeatother +% \maketitle +% \tableofcontents +% +% \begin{documentation}^^A>>> +% +% \section{Introducktion}^^A>>> +% +% This package was inspired by the question +% \href{https://tex.stackexchange.com/questions/419751} +% {getting ducks in example images}. +% It began on the idea to patch \cs{includegraphics} to automatically change its +% behaviour if |example-image-duck| is used, but then it turned out to be a +% simple alternative to the \pkg{blindtext} package. +% +% It is written as a docstrip file: executing |latex duckuments.dtx| generates +% the \file{duckuments.sty}, \file{example-image-duck.tex}, and +% \file{example-image-duck-portrait.tex} file and typesets this duckumentation; +% execute |tex duckuments.dtx| to only generate the files \file{duckuments.sty}, +% \file{example-image-duck.tex}, and \file{example-image-duck-portrait.tex}. +% +% For its functionality \file{example-image-duck.tex} and +% \file{example-image-duck-portrait.tex} must be compiled at least once. The +% sources are hosted on +% \href{https://github.com/Skillmon/ltx_duckuments}{github}. +% +% \textbf{The package does currently only work on \pdfTeX, \LuaTeX, and \XeTeX}. +%^^A<<< +% +% \section{Duckumentation}^^A>>> +% +% \subsection{Ducky content}^^A>>> +% +% \begin{function}{\duckument}^^A>>> +% \begin{syntax} +% \cs{duckument}\oarg{key=value} +% \end{syntax} +% Produces a duckument with one sectioning entry of each level starting at +% \cs{chapter} (if available) and two variants of the list environment +% \env{itemize}, \env{enumerate}, and \env{description}, one only at top +% level and one with 4~environments nested. The \meta{key=value}s accept every +% key as explained in \autoref{sec:keys}, but not every key has an effect. +% \end{function}^^A<<< +% +% \begin{function}{\blindduck}^^A>>> +% \begin{syntax} +% \cs{blindduck}\oarg{key=value} +% \end{syntax} +% Produces one paragraph of dummy content. The \meta{key=value}s accept every +% key as explained in \autoref{sec:keys}, but not every key has an effect. +% \end{function}^^A<<< +% +% \begin{function}{\ducklist}^^A>>> +% \begin{syntax} +% \cs{ducklist}\meta{*}\marg{environment} +% \end{syntax} +% Sets a list of the specified \meta{environment}, if \meta{*} is given +% \cs{item}\oarg{dummy} is used instead of only \cs{item}. For |description| +% the starred version is used automatically. +% \end{function}^^A<<< +% +% \begin{function}{\ducklistlist}^^A>>> +% \begin{syntax} +% \cs{ducklistlist}\meta{*}\marg{list} +% \end{syntax} +% Sets 4~levels of a nested list of the specified \meta{environment}, if +% \meta{*} is given \cs{item}\oarg{dummy} is used instead of only \cs{item}. +% For |description| the starred version is used automatically. +% \end{function}^^A<<< +% +% \begin{function}{\duckitemize}^^A>>> +% Abbreviation for \cs{ducklist}|{itemize}|. +% \end{function}^^A<<< +% +% \begin{function}{\duckenumerate}^^A>>> +% Abbreviation for \cs{ducklist}|{enumerate}|. +% \end{function}^^A<<< +% +% \begin{function}{\duckdescription}^^A>>> +% Abbreviation for \cs{ducklist}|{description}|. +% \end{function}^^A<<< +%^^A<<< +% +% \subsection{Other Macros}^^A>>> +% +% \begin{function}{\duckumentsCreateExampleFiles}^^A>>> +% Creates the files \file{example-image-duck.tex} and +% \file{example-image-duck-portrait.tex} in the current working directory. +% \end{function}^^A<<< +% +% \begin{function}{\duckumentsDrawRandomDucks}^^A>>> +% \begin{syntax} +% \cs{duckumentsDrawRandomDucks}\meta{*}\oarg{count} +% \end{syntax} +% Draws \meta{count} random \pkg{tikzducks} using +% \pkg{Ti\textit{k}Z}. \meta{count} defaults to \cs{duckuments@randoms}. +% Note that \pkg{duckuments} doesn't load \pkg{Ti\textit{k}Z}, this macro is +% for the use in \file{example-image-duck.tex} and +% \file{example-image-duck-portrait.tex}. If the optional star is given, the +% images will be drawn in portrait orientation else in landscape. +% \end{function}^^A<<< +%^^A<<< +% +% \subsection{Patches}^^A>>> +% +% The package patches \cs{includegraphics} if \pkg{graphicx} is loaded at the +% time the patch is applied (see \autoref{sec:keys}, |immediate|). The patch +% changes the behaviour if the used image file is \file{example-image-duck} or +% \file{example-image-duck-portrait}. If that is the case, a random page of that +% document is used. There shouldn't be any change in behaviour if other files +% are used. +% +% The patch is done so that one can use \pkg{tikzducks} ducks without the need +% of loading \pkg{tikz} in a minimal working duckument as example images. +%^^A<<< +% +% \subsection{Options}\label{sec:keys}^^A>>> +% +% The package and commands which take a \oarg{key=value} accept the following +% options. Some of which only make sense as package options. The +% \textbf{\texttt{bold}} printed value is the one used if you don't specify a +% value. The \textit{\texttt{italic}} printed value is the initial one. +% \begin{options} +% \item[toc=\textbf{true}$\vert$\textit{false}] +% If |true| the \cs{duckument} contains a ToC. During package load time the +% key doesn't throw errors but only warnings for values other than |true| +% and |false|. This is done for compatibility reasons with classes which +% take a non-boolean |toc| option (like those of KOMA-script). +% \item[maths=\textbf{both}$\vert$inline$\vert$display$\vert$\textit{none}] +% If |both| the \cs{blindduck} (which is also used by \cs{duckument}) +% contains both inline and displayed math. With |inline| and |display| the +% respective maths is activated. |none| disables both. +% \item[full] +% This typesets the full range of \cs{blindduck}. Don't use this as a +% package option. +% \item[all] +% synonym for |full|. +% \item[immediate=\textbf{true}$\vert$\textit{false}] +% If |true| \cs{includegraphics} is patched during package load time, else +% the patching is done \cs{AtBeginDocument}. +% \end{options} +% Additionally \cs{blindduck} and \cs{duckument} accept another key which must +% match one of the following patterns and doesn't get any value. Patterns: +% \bgroup +% \def\num#1{\texttt{\meta{num#1}}}% +% \begin{description}[style=nextline,font=\normalfont\ttfamily] +% \item[\meta{num1}] The paragraph \num{1} is printed. +% \item[\meta{num1-}] Like the above +% \item[\meta{-num2}] The paragraphs up to \num{2} are printed. +% \item[\meta{num1-num2}] The paragraphs from \num{1} up to \num{2} +% are printed. +% \item[\meta{-}] The next paragraph is printed. +% \end{description} +% If the used pattern includes a ``|-|'' a \cs{par} is used after each +% paragraph. If any pattern is used the next pattern that doesn't include a +% \num{1} starts with the paragraph after the last used paragraph, cycling back +% to the first after the last available paragraph. +% \egroup +%^^A<<< +%^^A<<< +% +% \end{documentation}^^A<<< +% +% \begin{implementation}^^A>>> +% +% \section{Implementation} +% +% \begin{macrocode} +%<*pkg> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=duckuments> +% \end{macrocode} +% +% \subsection{Check for possible problems}^^A>>> +% +% Check which engine is used. +% \begin{macrocode}^^A>>> +\bool_if:nF + { + \sys_if_engine_luatex_p: + || \sys_if_engine_pdftex_p: + || \sys_if_engine_xetex_p: + } + {%>>> + \msg_new:nnnn { duckuments } { incompatible } + { + The~duckuments~package~is~currently~only~compatible~with~pdfTeX,~ + LuaTeX,~and~XeTeX! + } + { + \ ~_____________________________\\ + \ (Quack!~Sorry~for~that.~Quack!)\\ + \ ~"""""""""""""""""""""""""""""\\ + \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ \ ~\ ~\ ~\ ~\string\ \\ + \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ \ ~\ ~\ ~\ ~\ ~>()_\\ + \ \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ \ ~\ ~\ ~\ ~\ ~\ ~(__)__ + } + \msg_error:nn { duckuments } { incompatible } + \endinput + }%<<< +% \end{macrocode}^^A<<< +% Check whether \file{example-image-duck.pdf} exists. +% \begin{macrocode}^^A>>> +\file_if_exist:nF { example-image-duck.pdf } + {%>>> +% \end{macrocode} +% If the current \cs{jobname} doesn't match \file{example-image-duck} throw an +% error. +% \begin{macrocode} + \str_if_eq:VnF \c_sys_jobname_str { example-image-duck } + { + \msg_new:nnnn { duckuments } { missing~file } + { + The~file~`#1`~can't~be~found.~Make~sure~to~create~it + \tl_if_empty:nF{#2}{~#2}. + } + { Sorry~for~the~inconvenience.~#3 } + \msg_error:nnnnn { duckuments } { missing~file } + { example-image-duck.pdf } + { + by~compiling~example-image-duck.tex~at~least~once + } + { + If~you~don't~find~the~file~on~your~machine~you~can~use~ + `\duckumentsCreateExampleFiles`~in~your~document~to~produce~a~copy~ + in~the~current~working~directory. + } + } + }%<<< +% \end{macrocode}^^A<<< +% And do the same for \file{example-image-duck-portrait.pdf}. +% \begin{macrocode}^^A>>> +\file_if_exist:nF { example-image-duck-portrait.pdf } + {%>>> + \str_if_eq:VnF \c_sys_jobname_str { example-image-duck-portrait } + { + \msg_if_exist:nnF { duckuments } { missing~file } + { + \msg_new:nnnn { duckuments } { missing~file } + { + The~file~`#1`~can't~be~found.~Make~sure~to~create~it + \tl_if_empty:nF{#2}{~#2}. + } + { Sorry~for~the~inconvenience.~#3 } + } + \msg_error:nnnnn { duckuments } { missing~file } + { example-image-duck-portrait.pdf } + { + by~compiling~example-image-duck-portrait.tex~at~least~once + } + { + If~you~don't~find~the~file~on~your~machine~you~can~use~ + `\duckumentsCreateExampleFiles`~in~your~document~to~produce~a~copy~ + in~the~current~working~directory. + } + } + }%<<< +% \end{macrocode}^^A<<< +%^^A<<< +% +% \subsection{Variables}^^A>>> +% +% \begin{variable}{\duckuments@randoms}^^A>>> +% Stores the number of random ducks in \file{example-image-duck.pdf}. +% \begin{macrocode} +\newcommand*\duckuments@randoms{128} +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\l_duckuments_immediate_bool}^^A>>> +% Stores whether the patch is to be done during package load time. +% \begin{macrocode} +\bool_new:N \l_duckuments_immediate_bool +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\l_duckuments_toc_bool}^^A>>> +% Stores whether to display a ToC in \cs{duckument}. +% \begin{macrocode} +\bool_new:N \l_duckuments_toc_bool +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\l_duckuments_math_inline_bool}^^A>>> +% Stores whether to display inline math in \cs{blindduck}. +% \begin{macrocode} +\bool_new:N \l_duckuments_math_inline_bool +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\l_duckuments_math_display_bool}^^A>>> +% Stores whether to display displayed math in \cs{blindduck}. +% \begin{macrocode} +\bool_new:N \l_duckuments_math_display_bool +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\l_duckuments_blindduck_pars_bool}^^A>>> +% Stores whether each paragraph of \cs{blindduck} should end with a \cs{par}. +% \begin{macrocode} +\bool_new:N \l_duckuments_blindduck_pars_bool +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\l_duckuments_range_seq}^^A>>> +% Stores the paragraphs range for \cs{blindduck}. +% \begin{macrocode} +\seq_new:N \l_duckuments_range_seq +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\g_duckuments_blindduck_start_int}^^A>>> +% Stores the paragraph with which \cs{blindduck} should start. +% \begin{macrocode} +\int_new:N \g_duckuments_blindduck_start_int +\int_gset:Nn \g_duckuments_blindduck_start_int { \c_one } +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\g_duckuments_blindduck_end_int}^^A>>> +% Stores the paragraph with which \cs{blindduck} should end. +% \begin{macrocode} +\int_new:N \g_duckuments_blindduck_end_int +% \end{macrocode} +% \end{variable}^^A<<< +%^^A<<< +% +% \subsection{Constants}^^A>>> +% +% \begin{variable}{\c_duckuments_example_regex}^^A>>> +% Regex against which the patch of \cs{includegraphics} is testing. +% \begin{macrocode} +\regex_const:Nn \c_duckuments_example_regex + { + example-image-duck + |example-image-duck.pdf + |example-image-duck-portrait + |example-image-duck-portrait.pdf + } +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\c_duckuments_range_regex}^^A>>> +% Regex against which the optional range in \cs{blindduck} is checked. +% \begin{macrocode} +\regex_const:Nn \c_duckuments_range_regex { (\d+|\d+-|-\d+|\d+-\d+|-) } +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\c_duckuments_blindduck_pars_int}^^A>>> +% \begin{macrocode} +\int_const:Nn \c_duckuments_blindduck_pars_int { \c_five } +% \end{macrocode} +% \end{variable}^^A<<< +% +% \begin{variable}{\c_duckuments_example_pages_int}^^A>>> +% \begin{macrocode} +\bool_if:nTF + { + \str_if_eq_p:Vn \c_sys_jobname_str { example-image-duck } + || \str_if_eq_p:Vn \c_sys_jobname_str { example-image-duck-portrait } + } + { \int_const:Nn \c_duckuments_example_pages_int { 1 } } + { + \group_begin: + \sys_if_engine_pdftex:T + { + \pdfximage{example-image-duck.pdf} + \int_set:Nn \l_tmpa_int { \the\pdflastximagepages } + \pdfximage{example-image-duck-portrait.pdf} + \int_set:Nn \l_tmpb_int { \the\pdflastximagepages } + } + \sys_if_engine_luatex:T + { + \saveimageresource{example-image-duck.pdf} + \int_set:Nn \l_tmpa_int { \lastsavedimageresourcepages } + \saveimageresource{example-image-duck-portrait.pdf} + \int_set:Nn \l_tmpb_int { \lastsavedimageresourcepages } + } + \sys_if_engine_xetex:T + { + \int_set:Nn \l_tmpa_int + { \XeTeXpdfpagecount "example-image-duck.pdf" } + \int_set:Nn \l_tmpb_int + { \XeTeXpdfpagecount "example-image-duck-portrait.pdf" } + } + \int_const:Nn \c_duckuments_example_pages_int + { \int_min:nn { \l_tmpa_int } { \l_tmpb_int } } + \group_end: + } +% \end{macrocode} +% \end{variable}^^A<<< +%^^A<<< +% +% \subsection{Messages}^^A>>> +% +% \begin{macrocode}^^A duckuments option~unknown >>> +\msg_new:nnnn { duckuments } { option~unknown } + { + Unknown~option~'#1'~for~package~duckuments. + } + { + \ ~__________________________________\\ + \ (Quack!~Nothing~here,~sorry.~Quack!)\\ + \ ~""""""""""""""""""""""""""""""""""\\ + \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\string\ \\ + \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~>()_\\ + \ \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~(__)__ + } +% \end{macrocode}^^A<<< +% \begin{macrocode}^^A duckuments non-boolean~toc >>> +\msg_new:nnnn { duckuments } { non-boolean~toc } + { + A~non-boolean~value~`#1`~was~received~for~the~`toc`~option~during~package~ + load~time.~It~is~assumed~this~was~given~to~\string\documentclass\ and~ + therefore~ignored. + } + { + \ ~__________________________________\\ + \ (Quack!~Nothing~here,~sorry.~Quack!)\\ + \ ~""""""""""""""""""""""""""""""""""\\ + \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\string\ \\ + \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~>()_\\ + \ \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~(__)__ + } +% \end{macrocode}^^A<<< +% \begin{macrocode}^^A duckuments out~of~range >>> +\msg_new:nnnn { duckuments } { out~of~range } + { + You~requested~element~#3~out~of~the~range~#1~to~#2~of~array~'#4'.\\ + I'll~just~use~element~#1~for~you. + } + { + \ ~__________________________________\\ + \ (Quack!~Nothing~here,~sorry.~Quack!)\\ + \ ~""""""""""""""""""""""""""""""""""\\ + \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\string\ \\ + \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~>()_\\ + \ \ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~\ ~(__)__ + } +% \end{macrocode}^^A<<< +% +% \begin{macro}{\duckuments_patch_see_duckumentation:}^^A>>> +% \begin{macrocode} +\cs_new:Npn \duckuments_patch_see_duckumentation: + {%>>> + \cs_set:Nn \msg_see_documentation_text:n + { + \\\\ + See~the~\str_if_eq:nnTF { ##1 } { duckuments } { duckumentation } + { + \str_if_eq:nnTF { ##1 } { LaTeX } { LaTeX3~ } { ##1~ } + documentation + }~for~further~information. + } + }%<<< +\duckuments_patch_see_duckumentation: +% \end{macrocode} +% \end{macro}^^A<<< +%^^A<<< +% +% \subsection{Options and Configurations}^^A>>> +% \begin{macrocode} +\keys_define:nn { duckuments } + {%>>> + ,immediate .bool_set:N = \l_duckuments_immediate_bool + ,immediate .default:n = true + ,full .code:n = + \duckuments_blindduck_range_test:n { 1-\c_duckuments_blindduck_pars_int } + ,all .meta:n = { full } + ,maths .choice: + ,maths / both .code:n = + { + \bool_set_true:N \l_duckuments_math_inline_bool + \bool_set_true:N \l_duckuments_math_display_bool + } + ,maths / display .code:n = \bool_set_true:N \l_duckuments_math_display_bool + ,maths / inline .code:n = \bool_set_true:N \l_duckuments_math_inline_bool + ,maths / none .code:n = + { + \bool_set_false:N \l_duckuments_math_inline_bool + \bool_set_false:N \l_duckuments_math_display_bool + } + ,maths .default:n = both + ,toc .code:n = + { + \str_case:nnF { #1 } + { + { true } { \bool_set_true:N \l_duckuments_toc_bool } + { false } { \bool_set_false:N \l_duckuments_toc_bool } + } + { + \msg_warning:nnn { duckuments } { non-boolean~toc } { #1 } + } + } + ,toc .default:n = true + ,unknown .code:n = + { \msg_error:nnx { duckuments } { option~unknown } { \l_keys_key_tl } } + }%<<< +\ProcessKeysOptions { duckuments } +\keys_define:nn { duckuments } + {%>>> + ,toc .undefine: + ,toc .bool_set:N = \l_duckuments_toc_bool + ,toc .default:n = true + ,unknown .code:n = \duckuments_blindduck_range_test:V \l_keys_key_tl + }%<<< +\bool_if:NTF \l_duckuments_immediate_bool + { \AtEndOfPackage { \duckuments_patch_includegraphics: } } + { \AtBeginDocument { \duckuments_patch_includegraphics: } } +% \end{macrocode} +%^^A<<< +% +% \subsection{Functions}^^A>>> +% +% \subsubsection{Duckument Level}^^A>>> +% +% \begin{macro}{\duckument}^^A>>> +% \begin{macrocode} +\NewDocumentCommand \duckument { O{} } + {%>>> + \group_begin: + \keys_set:nn { duckuments } { #1 } + \bool_if:NT \l_duckuments_toc_bool { \tableofcontents } + \cs_if_exist_use:NT \chapter + { {\duckuments@headings@text{0}} \blindduck } + \duckuments@headings{1} \blindduck + \duckuments@headings{2} \blindduck + \duckuments@headings{3} \blindduck + \duckuments@headings{4} \blindduck + \section {Lists} + \duckuments_list_example:n { itemize } + \duckuments_list_example:n { enumerate } + \duckuments_list_example:n { description } + \group_end: + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\blindduck}^^A>>> +% \begin{macrocode} +\NewDocumentCommand \blindduck { O{} } + {%>>> + \group_begin: + \keys_set:nn { duckuments } { #1 } + \duckuments@blindduck@text + \bool_if:NT \l_duckuments_blindduck_pars_bool { \par } + \group_end: + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\ducklist}^^A>>> +% \begin{macrocode} +\NewDocumentCommand \ducklist {s m} + {%>>> + \begin{#2} + \IfBooleanTF { #1 } + {\ducklists@content@starred} + { + \str_if_eq:nnTF { #2 } { description } + \ducklists@content@starred + \ducklists@content + } + \end{#2} + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% \begin{macro}{\ducklistlist}^^A>>> +% \begin{macrocode} +\NewDocumentCommand \ducklistlist { s m } + {%>>> + \IfBooleanTF { #1 } + { \duckuments@listlist@starred { #2 } } + { + \str_if_eq:nnTF { #2 } { description } + { \duckuments@listlist@starred { description } } + { \duckuments@listlist{#2} } + } + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckenumerate}^^A>>> +% \begin{macrocode} +\newcommand*\duckenumerate{\ducklist{enumerate}} +% \end{macrocode} +% \end{macro}^^A<<< +% \begin{macro}{\duckitemize}^^A>>> +% \begin{macrocode} +\newcommand*\duckitemize{\ducklist{itemize}} +% \end{macrocode} +% \end{macro}^^A<<< +% \begin{macro}{\duckdescription}^^A>>> +% \begin{macrocode} +\newcommand*\duckdescription{\ducklist{description}} +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckumentsCreateExampleFiles}^^A>>> +% Create example-image-duck.tex +% \begin{macrocode} +\newcommand*\duckumentsCreateExampleFiles + {%>>> + \iow_new:N \duckuments_example_file_iow + \iow_open:Nn \duckuments_example_file_iow { example-image-duck.tex } + \iow_now:Nn \duckuments_example_file_iow + { \documentclass[tikz,multi]{standalone} } + \iow_now:Nn \duckuments_example_file_iow + { \usepackage{tikzducks} } + \iow_now:Nn \duckuments_example_file_iow + { \usepackage{duckuments} } + \iow_now:Nn \duckuments_example_file_iow + { \begin{document} } + \iow_now:Nn \duckuments_example_file_iow + { \duckumentsDrawRandomDucks } + \iow_now:Nn \duckuments_example_file_iow + { \end{document} } + \iow_close:N \duckuments_example_file_iow +% \end{macrocode} +% Create example-image-duck-portrait.tex +% \begin{macrocode} + \iow_open:Nn \duckuments_example_file_iow + { example-image-duck-portrait.tex } + \iow_now:Nn \duckuments_example_file_iow + { \documentclass[tikz,multi]{standalone} } + \iow_now:Nn \duckuments_example_file_iow + { \usepackage{tikzducks} } + \iow_now:Nn \duckuments_example_file_iow + { \usepackage{duckuments} } + \iow_now:Nn \duckuments_example_file_iow + { \begin{document} } + \iow_now:Nn \duckuments_example_file_iow + { \duckumentsDrawRandomDucks* } + \iow_now:Nn \duckuments_example_file_iow + { \end{document} } + \iow_close:N \duckuments_example_file_iow + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% \begin{macro}{\duckumentsDrawRandomDucks}^^A>>> +% \begin{macrocode} +\newcommand*\duckumentsDrawRandomDucks + {%>>> + \@ifstar + {\duckumentsDrawRandomDucks@portrait} + {\duckumentsDrawRandomDucks@landscape}% + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +%^^A<<< +% +% \subsubsection{Intern}^^A>>> +% +% \begin{macro}{\duckuments@headings}^^A>>> +% \begin{macrocode} +\newcommand*\duckuments@headings[1] + {%>>> + \ifcase#1\relax + \expandafter\chapter + \or \expandafter\section + \or \expandafter\subsection + \or \expandafter\subsubsection + \or \expandafter\paragraph + \else \expandafter\@gobble + \fi + {\duckuments@headings@text{#1}} + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments@headings@level}^^A>>> +% \begin{macrocode} +\newcommand*\duckuments@headings@level[1] + {%>>> + ( + \ifcase#1 + chapter + \or section + \or subsection + \or subsubsection + \or paragraph + \fi + ) + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments@ifinline}^^A>>> +% \begin{macrocode} +\newcommand*\duckuments@ifinline[2][] + { \bool_if:NTF \l_duckuments_math_inline_bool { #2 } { #1 } } +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments@ifdisplay}^^A>>> +% \begin{macrocode} +\newcommand*\duckuments@ifdisplay[2][] + { \bool_if:NTF \l_duckuments_math_display_bool { #2 } { #1 } } +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_list_example:n}^^A>>> +% \begin{macrocode} +\cs_new_protected_nopar:Npn \duckuments_list_example:n #1 + {%>>> + \subsection{Example\ for\ ducks\ (#1)} + \ducklist { #1 } + \subsubsection{Nested\ ducks} + \ducklistlist { #1 } + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments@enquote}^^A>>> +% \begin{macrocode} +\NewDocumentCommand \duckuments@enquote { s +m } + {%>>> + \IfBooleanTF { #1 } + { + \cs_if_exist_use:NTF + \enquote { * { #2 } } + { `#2' } + } + { + \cs_if_exist_use:NTF + \enquote { { #2 } } + {``#2''} + } + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckumentsDrawRandomDucks@landscape}^^A>>> +% \begin{macrocode} +\newcommand*\duckumentsDrawRandomDucks@landscape[1][\duckuments@randoms] + {%>>> + \foreach\x in {1,2,...,#1} + {\duckumentsDrawRandomDucks@draw{6.47214}{4}{3.23607}{2}} + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckumentsDrawRandomDucks@portrait}^^A>>> +% \begin{macrocode} +\newcommand*\duckumentsDrawRandomDucks@portrait[1][\duckuments@randoms] + {%>>> + \foreach\x in {1,2,...,#1} + {\duckumentsDrawRandomDucks@draw{1.8541}{3}{.92705}{1.5}} + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckumentsDrawRandomDucks@draw}^^A>>> +% \begin{macrocode} +\newcommand*\duckumentsDrawRandomDucks@draw[4] + {%>>> + \begin{tikzpicture} + \draw[fill=gray!50,use~as~bounding~box] (0,0) rectangle (#1,#2); + \draw[gray,thin] (0,0) -- (#1,#2); + \draw[gray,thin] (0,#2) -- (#1,0); + \draw[gray,thin] (#3,0) -- (#3,#2); + \draw[gray,thin] (0,#4) -- (#1,#4); + \node at (#3,#4) {\tikz\randuck;}; + \draw[black] (0,0) rectangle (#1,#2); + \end{tikzpicture} + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_patch_includegraphics:}^^A>>> +% \begin{macrocode} +\cs_new_protected_nopar:Npn \duckuments_patch_includegraphics: + {%>>> + \@ifpackageloaded { graphicx } + { + \LetLtxMacro\duckuments@includegraphicsBAK\includegraphics + \RenewDocumentCommand \includegraphics + { >{\duckuments_starred:n}s O{} o m } + { + \IfValueTF { ##3 } + { \duckuments@includegraphicsBAK##1[##2][##3]{##4} } + { + \regex_match:NnTF \c_duckuments_example_regex { ##4 } + { + \duckuments@includegraphicsBAK##1 + [page=\duckuments_random_page:,##2] + { ##4 } + } + { + \duckuments@includegraphicsBAK##1[##2]{##4} + } + } + } + } + {} + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_blindduck_range_test:n}^^A>>> +% \begin{macrocode} +\cs_new_protected:Npn \duckuments_blindduck_range_test:n #1 + {%>>> + \regex_match:NnTF \c_duckuments_range_regex { #1 } + { + \seq_set_split:Nnn \l_duckuments_range_seq { - } { #1 } + \int_compare:nNnTF { 1 } = { \seq_count:N \l_duckuments_range_seq } + { + \cs_set:Npn \duckuments@blindduck@text + { + \duckuments_blindduck_single_par:n { #1 } + \duckuments_blindduck_set_next_start:n { #1 } + } + } + { + \bool_set_true:N \l_duckuments_blindduck_pars_bool + \exp_args:Nx + \tl_if_empty:nF { \seq_item:Nn \l_duckuments_range_seq { \c_one } } + { + \int_gset:Nn \g_duckuments_blindduck_start_int + { \seq_item:Nn \l_duckuments_range_seq { \c_one } } + } + \exp_args:Nx + \tl_if_empty:nTF { \seq_item:Nn \l_duckuments_range_seq { \c_two } } + { + \int_gset_eq:NN + \g_duckuments_blindduck_end_int + \g_duckuments_blindduck_start_int + } + { + \int_set:Nn \g_duckuments_blindduck_end_int + { \seq_item:Nn \l_duckuments_range_seq { \c_two } } + } + \duckuments_blindduck_set_text:xx + { \int_use:N \g_duckuments_blindduck_start_int } + { \int_use:N \g_duckuments_blindduck_end_int } + } + } + { + \exp_args:NnnV + \msg_error:nnn { duckuments } { option~unknown } \l_keys_key_tl + } + }%<<< +\cs_generate_variant:Nn \duckuments_blindduck_range_test:n { V } +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_blindduck_set_text:nn}^^A>>> +% \begin{macrocode} +\cs_new:Npn \duckuments_blindduck_set_text:nn #1 #2 + {%>>> + \def \duckuments@blindduck@text + { + \int_step_function:nnnN { #1 } { \c_one } { #2 } + \duckuments_blindduck_par_loop:n + \duckuments_blindduck_set_next_start:n { #2 } + } + }%<<< +\cs_generate_variant:Nn \duckuments_blindduck_set_text:nn { xx } +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_blindduck_set_next_start:n}^^A>>> +% \begin{macrocode} +\cs_new:Npn \duckuments_blindduck_set_next_start:n #1 + {%>>> + \int_gset:Nn \g_duckuments_blindduck_start_int + { \int_mod:nn { #1 } { \c_duckuments_blindduck_pars_int } + \c_one } + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_blindduck_single_par:n}^^A>>> +% \begin{macrocode} +\cs_new:Npn \duckuments_blindduck_single_par:n #1 + {%>>> + \bool_if:nTF + { + \int_compare_p:nNn { #1 } > { \c_duckuments_blindduck_pars_int } + || \int_compare_p:nNn { #1 } < { \c_one } + } + { + \msg_error:nnxxxx { duckuments } { out~of~range } + { 1 } { \int_use:N \c_duckuments_blindduck_pars_int } { #1 } + { blindduck~paragraphs } + \duckuments@blindduck@text@i + } + { + \use:c { duckuments@blindduck@text@ \int_to_roman:n { #1 } } + } + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_blindduck_par_loop:n}^^A>>> +% \begin{macrocode} +\cs_new:Npn \duckuments_blindduck_par_loop:n #1 + {%>>> + \duckuments_blindduck_single_par:n { #1 } + \par + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_starred:n}^^A>>> +% \begin{macrocode} +\cs_new_protected:Npn \duckuments_starred:n #1 + {%>>> + \IfBooleanTF { #1 } + { \def\ProcessedArgument{*} } + { \def\ProcessedArgument{} } + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments_random_page:}^^A>>> +% \begin{macrocode} +\cs_new:Npn \duckuments_random_page: + { \int_rand:n { \c_duckuments_example_pages_int } } +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \begin{macro}{\duckuments@blindduck@text}^^A>>> +% \begin{macrocode} +\newcommand*\duckuments@blindduck@text{\duckuments@blindduck@text@i} +\newcommand*\duckuments@blindduck@text@i + {%>>> + There once was a very smart but sadly blind duck. When it was still a small + duckling it was renowned for its good vision. But sadly as the duck grew + older it caught a sickness which caused its eyesight to worsen. It became so + bad, that the duck couldn't read the notes it once took containing much of + inline math\duckuments@ifinline{ just like its favoured equation: $d = u_c + \cdot k$}. Only displayed equations remained legible% + \duckuments@ifdisplay[.]{ so it could still read \begin{equation}d = r a^k + e\hbox{.}\end{equation}} That annoyed the smart duck, as it wasn't able to + do its research any longer. It called for its underduckling and said: + \duckuments@enquote{Go, find me the best eye ducktor there is. He shall + heal me from my disease!}% + }%<<< +\newcommand*\duckuments@blindduck@text@ii + {%>>> + \duckuments@enquote{But my duck, how are you supposed to manage your daily + routines without my visual guidance}, replied the underduckling. The smart + duck's face turned grim in anger. \duckuments@enquote{You dare to talk + back?} The underduckling blushed ashamed. How could he have objections + after his duck gave strict orders? The underduckling was so embarrassed + about his own behaviour he had to solve an equation.% + }%<<< +\newcommand*\duckuments@blindduck@text@iii + {%>>> + After the equation was solved and the underduckling prepared his leave for + the next day it fell asleep in a shaky mood. It did not know what the + journey had prepared for him and if he was prepared enough for it. His sleep + was restless. The dreams he had that night were not calm and bright as they + used to be for an innocent underduckling.% + }%<<< +\newcommand*\duckuments@blindduck@text@iv + {%>>> + Before dawn the underduckling woke. He didn't have the feeling of being well + rested. But nonetheless he knew that this was the day he should leave. + Except saying goodbye to his beloved ones there was nothing holding him + back. His duck had sent him on the most important mission a five weeks old + inexperienced underduckling was ever sent on. He bid farewell to his mother, + all his brothers and sisters, and finally from his duck. The bag was + shouldered, the boots were tied, the underduckling left.% + }%<<< +\newcommand*\duckuments@blindduck@text@v + {%>>> + As the underduckling went along he saw a tree. It was so tall he couldn't + even approximate its height. Oh, how small he felt. What should he, a small + duckling whose plumage was still fluffy, achieve in this vast, gigantic + world? He stuck his trembling wings under the straps of his backpack to calm + his shaking limbs. Where should he start his search? How should he survive + in the hostile nature surrounding the sheltered pond of his community? + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments@headings@text}^^A>>> +% \begin{macrocode} +\newcommand*\duckuments@headings@text[1] + {A friendly duck at level #1 \duckuments@headings@level{#1}} +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\ducklists@content}^^A>>> +% \begin{macrocode} +\newcommand*\ducklists@content + {%>>> + \item First swims father drake + \item Then floats mother duck + \item After her paddles baby duckling + \item And over there bathes uncle canard + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\ducklists@content@starred}^^A>>> +% \begin{macrocode} +\newcommand*\ducklists@content@starred + {%>>> + \item[drake] is the swimming father + \item[duck] is the floating mother + \item[duckling] is the paddling baby + \item[canard] is the bathing uncle + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments@listlist}^^A>>> +% \begin{macrocode} +\newcommand*\duckuments@listlist[1] + {%>>> + \begin{#1} + \item swimming father drake + \begin{#1} + \item swimming father drake + \begin{#1} + \item swimming father drake + \begin{#1} + \item swimming father drake + \item floating mother duck + \end{#1} + \item floating mother duck + \end{#1} + \item floating mother duck + \end{#1} + \item floating mother duck + \end{#1}% + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +% +% \begin{macro}{\duckuments@listlist@starred}^^A>>> +% \begin{macrocode} +\newcommand*\duckuments@listlist@starred[1] + {%>>> + \begin{#1} + \item[drake] is the swimming father + \begin{#1} + \item[drake] is the swimming father + \begin{#1} + \item[drake] is the swimming father + \begin{#1} + \item[drake] is the swimming father + \item[duck] is the floating mother + \end{#1} + \item[duck] is the floating mother + \end{#1} + \item[duck] is the floating mother + \end{#1} + \item[duck] is the floating mother + \end{#1}% + }%<<< +% \end{macrocode} +% \end{macro}^^A<<< +%^^A<<< +%^^A<<< +% +% \begin{macrocode} +\endinput +% \end{macrocode} +% +% \end{implementation}^^A<<< +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \clearpage +% \section{The story of the duck}^^A>>> +% +% \bgroup +% \ExplSyntaxOn +% \newcount\duckuments_count_for_duckumentation_only +% \cs_set:Nn \duckuments_blindduck_par_loop:n +% {^^A>>> +% \advance\duckuments_count_for_duckumentation_only1 +% \llap +% { +% \group_begin: +% \driver_color_gray:n { 0.5 } +% \rlap +% { +% \smash +% { +% \parbox[t]{2cm} +% { +% \scriptsize\raggedright +% paragraph~\the\duckuments_count_for_duckumentation_only +% } +% } +% } +% \hspace{\dimexpr\marginparsep+2cm\relax} +% \group_end: +% } +% \vspace{-\baselineskip} +% \duckuments_blindduck_single_par:n { #1 } +% \par +% }^^A<<< +% \ExplSyntaxOff +% \blindduck[full] +% \egroup^^A<<< +% +% +^^A vim: fdm=marker foldmarker=>>>,<<< -- cgit v1.2.3