diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/nicetext/fifinddo.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/nicetext/fifinddo.sty | 297 |
1 files changed, 210 insertions, 87 deletions
diff --git a/Master/texmf-dist/tex/latex/nicetext/fifinddo.sty b/Master/texmf-dist/tex/latex/nicetext/fifinddo.sty index 75681f23eb8..e25e67aed5d 100644 --- a/Master/texmf-dist/tex/latex/nicetext/fifinddo.sty +++ b/Master/texmf-dist/tex/latex/nicetext/fifinddo.sty @@ -5,7 +5,7 @@ %% for processing tex(t) files %% (checking, filtering, converting, substituting, expanding, ...) -\def\fileversion{0.44} \def\filedate{2011/10/23} +\def\fileversion{0.5} \def\filedate{2011/11/21} %% This file can be redistributed and/or modified under %% the terms of the LaTeX Project Public License; either @@ -99,14 +99,19 @@ %% %% %% == File handling == -%% \label{sec:files} %% 2010/11/10 -\newwrite\result_file %% or write to \@mainaux!? +%% %% structured 2011/11/19 +%% Peter Wilson's \ctanpkgref{newfile} +%% provides more powerful file handling. +%% % <- TODO relevant? 2009/04/12 +%% +%% === Opening, Writing to, Closing Output === +%% \label{sec:output} +\newwrite\result_file %% or write to \@mainaux!? TODO %% |\ResultFile{<output>}| opens (and empties) a file %% <output> to be written into. \newcommand*{\ResultFile}[1]{% \def\result_file_name{#1}% -%% By analogy to `\ProcessFileWith' 2011/10/23: - \typeout{`fifinddo' generating `\result_file_name'}% + \typeout{`fifinddo' generating `\result_file_name'}% %% 2011/10/23 \immediate\openout\result_file=#1} %% |\WriteResult{<balanced>}| writes a <balanced> line into %% <output> (or more lines with `^^J'). @@ -120,6 +125,15 @@ \string\ProvidesFile{\result_file_name}% [\the\year/\two@digits\month/\two@digits\day\space automatically generated with fifinddo.sty]}}% +%% |\CloseResultFile| closes <output>: +\newcommand*{\CloseResultFile}{% + \immediate\closeout\result_file + \typeout{`fifinddo' %% 2011/10/23 + \space\space\space %% 2011/10/26 + closing `\result_file_name'}} +%% +%% === Processing Input === +%% \label{sec:input} %% %% opt arg 2010/04/06: %% |\ProcessFileWith[<changes>]{<input>}{<loop-body>}| %% opens a file <input> @@ -147,20 +161,26 @@ %% \item ignoring certain characters. %% \end{itemize} \newcommand*{\ProcessFileWith}[3][]{% - \typeout{`fifinddo' processing `#2'}%% 2010/04/15 - \openin\@inputcheck=#2% -% \ifeof\@inputcheck %% bad `exists?' test -% \PackageError{fifinddo}{File `#1' not here}% -% {Mistyped?}% -% \else - \global\c@fdInputLine=\z@ %% line counter reset +%% v0.5: Variant of \LaTeX's `\IfFileExists'---failed so far +%% because I had omitted the blank space: + \openin\@inputcheck#2 % space essential! 2011/11/19 + \ifeof\@inputcheck + \PackageError{fifinddo}{File `#2' not here}% + {Mistyped?}% + \else + \typeout{`fifinddo' processing `#2'}%% 2010/04/15 +%% %% 2011/11/19: +%% ... moves into conditional with v0.5. Resetting line counter: + \global\c@fdInputLine=\z@ \begingroup \MakeOther\{\MakeOther\}\@sanitize - %% from docstrip.tex: +%% ... switching into ``plain text mode"; from `docstrip.tex': % \MakeOther\^^A\MakeOther\^^K%% irrelevant, not LaTeX +%% <- cf. \TeX book +%% pp.~43ff., 368ff., %% 2011/11/19 +%% ``extended keyboards", up-/downarrow; +%% -> ``math specials", cf. ``space specials" \endlinechar\m@ne - %% <- cf. TeXbook "extended keyboards" up-/downarrow - %% -> "math specials", cf. "space specials" \MakeOther\^^I% ASCII horizontal tab -- guessed!? ^^L!? %% With v0.31, we support non-ASCII: \count@=128 @@ -181,13 +201,25 @@ \else \@secondoftwo \fi \repeat \endgroup -% \fi - \closein\@inputcheck} -%% TODO: write EOF for debugging!?---%% 2010/03/18 -%% Peter Wilson's \ctanpkgref{newfile} -%% provides more powerful file handling. -%% % <- TODO relevant? 2009/04/12 -%% + \fi + \closein\@inputcheck +%% Added for v0.5, cf. Sec.~\ref{sec:final-input} + \ifFinalInputFile + \CloseResultFile \FinalInputFilefalse + \fi +} +%% % TODO: write EOF for debugging!?---%% 2010/03/18 +%% % Another difference to some \ctanpkgref{verbatimcopy} +%% % is that `\CopyFile' really was meant to +%% % be used for creating a \acro{HTML} file from some \emph{number} of +%% % sources, especially for shared head sections (however, +%% % I have used macros for this purpose so far), a navigation column, +%% % the main varying ``blog-like" content, and finally a shared +%% % footer section. +%% % In the meantime, however, I have chosen another variant +%% % for generating \acro{HTML} that +%% % replaces an empty line by a line consisting of \verb+<p>+. +%% % %% |\CopyFile[<changes>]{<file>}| %% is an application of `\ProcessFileWith' %% that ``copies" the content of file <file> @@ -220,25 +252,33 @@ \newcommand*{\FD@compress@voids}{% \IfFDinputEmpty{\IfFDpreviousInputEmpty\relax\CopyLine}% \CopyLine} -%% Another difference to some \ctanpkgref{verbatimcopy} -%% is that `\CopyFile' really was meant to -%% be used for creating a \acro{HTML} file from some \emph{number} of -%% sources, especially for shared head sections (however, -%% I have used macros for this purpose so far), a navigation column, -%% the main varying ``blog-like" content, and finally a shared -%% footer section. -%% In the meantime, however, I have chosen another variant -%% for generating \acro{HTML} that -%% replaces an empty line by a line consisting of \verb+<p>+. %% -%% |\CloseResultFile| closes <output>. -\newcommand*{\CloseResultFile}{% - \immediate\closeout\result_file -%% \enlargethispage{1\baselineskip} -%% Another analogy to `\ProcessFileWith' 2011/10/23: - \typeout{`\result_file_name' completed (`fifinddo')}} +%% === A Combining Shorthand === +%% \label{sec:final-input} +%% Before v0.5, the general idea was that some number of \strong{input} +%% files would be combined for creating a single \strong{output} file +%% (e.g., as opposed to \ctanpkgref{verbatimcopy}, regarding +%% `\CopyFile'). +%% According to experience, however, a \strong{single} input file +%% typically suffices for generating an output file. +%% Then |\CloseResultFile| (Sec.~\ref{sec:output}) +%% may be called ``implicitly". The flag |\ifFinalInputFile| +%% will control (and generalize!) this +%% (in `\ProcessFileWith', Sec.~\ref{sec:input}), +%% and will be reset if changed +%% (thinking of generating another file in the same \TeX\ run). +%% +%% So +%% |\ProcessFinalFileWith[<changes>]{<input>}{<loop-body>}| +%% % |\ProcessFinalFileWith| works like `\ProcessFileWith' +%% works as with `\ProcessFileWith' +%% except that `\CloseResultFile' is issued after processing, +%% so you can omit the latter. +\newif\ifFinalInputFile +\newcommand*{\ProcessFinalFileWith}{% + \FinalInputFiletrue \ProcessFileWith} %% -%% \pagebreak +%% \pagebreak %% 2011/11/19 again %% == Basic handling of substring conditionals == %% \label{sec:theory} %% %% TODO move theory to fifinddo.tex 2009/04/12 @@ -318,9 +358,13 @@ %% Steven Segletes confirms that his 'stringstrings' doesn't %% suffer the problem (returning positions of substrings and %% numbers of occurrences).} -%% \[`\makeatletter \in@{bonbon}{bon}\ifin@ YES\else NO\fi \makeatother'\] +%% \begin{center} +%% % \[ +%% `\makeatletter \in@{bonbon}{bon}\ifin@ YES\else NO\fi \makeatother' %% %% \makeatletter \in@{bonbon}{bon}\ifin@ YES\else NO\fi \makeatother %% %% \IfSubStringInString{ionization}{ionizat}{YES}{NO} +%% % \] +%% \end{center} %% %% In general, the previous approach \emph{fails if and exactly if} %% <pattern> has a \emph{period} $p$---less than its length---in the sense of that @@ -411,7 +455,10 @@ %% `\newcommand*{<do-setup>}[<args>]{<action>}' %% \end{quote} %% <do-setup>'s first argument will be the <pattern> argument -%% of <setup-cmd>. +%% of <setup-cmd>.---With v0.5, we learn from the previous and provide +%% \[|\MakeSetupCommand{<setup-cmd>}{<do-setup>}[<args>]{<action>}|\] +\newcommand*{\MakeSetupCommand}[2]{\newcommand*#1{\StartFDsetup#2}% + \newcommand*#2} %% %% === Setup for conditionals === %% `substr_cond' is the ``name space" for substring conditionals. @@ -423,16 +470,12 @@ %% starts the definition of a conditional with identifier <id> %% and pattern <pattern>. <changes> optionally add commands to %% be executed after `\PatternCodes' in a local group. -%% -\newcommand*{\MakeSubstringConditional} - {\StartFDsetup\mk_substr_cond} -%% %% `\begingroup' |\mk_substr_cond{<pattern>}| %% TODO!? 2010/03/22 %% can be directly called by other programmer setup commands when %% `\fdParserId' and <pattern> have been read. -\def\mk_substr_cond #1{%% #1 pattern string +\MakeSetupCommand{\MakeSubstringConditional}{\mk_substr_cond}[1]{% + %% #1 pattern string \endgroup \@namedef{\substr_cond \fdParserId}##1#1##2&} -%% %% This really is not \LaTeX. We are starting defining a macro %% `\substr_cond:<id>' in primitive \TeX\ with `\def' in the form %% \[`\def\substr_cond:<id>#1<pattern>#2&'\] @@ -494,8 +537,9 @@ %% `setup_substr_cond' is the name space for macros that build %% sandboxes and initialize arguments for conditional macros. \def\setup_substr_cond{setup_substr_cond:} -%% |\MakeSetupSubstringCondition{<id>}[<changes>]{<pattern>}{<more-args>}|\\ -%% [\topsep] %% 2010/11/25 +%% \begin{center} %% 2011/11/13 +%% |\MakeSetupSubstringCondition{<id>}[<changes>]{<pattern>}{<more-args>}| +%% \end{center} %% % <- TODO allow `%' and ` ' for breaking code lines. %% ---same <id>, <changes>, <pattern> as for %% `\MakeSubstringConditional' (this is bad, there may be @@ -505,30 +549,37 @@ %% <more-args> may contain `{#1}' to store the string that was tested, %% also `{<id>}' for calling repetitions and `{<pattern>}' for screen %% or log informations. -\newcommand*{\MakeSetupSubstringCondition} - {\StartFDsetup\mk_setup_substr_cond} +\MakeSetupCommand{\MakeSetupSubstringCondition} + {\mk_setup_substr_cond}[2]{% %% |\mk_setup_substr_cond{<pattern>}{<more-args>}| %% %% without \begingroup 2010/03/29 %% can be directly called by other programmer setup commands after -%% `\fdParserId' and <pattern> have been read: -\def\mk_setup_substr_cond #1#2{%% #1 pattern string, +%% `\fdParserId' and <pattern> have been read. + %% #1 pattern string %% #2 additional arguments, e.g., `{#1}' to keep tested string \endgroup - \expandafter \edef + \expandafter \protected@edef %% protected 2011/11/21 +%% ... keeps `\protect' instead of just not expanding, +%% but I cannot implement `\UseBlogLigs' otherwise right now. \csname \setup_substr_cond \fdParserId \endcsname ##1{% - \make_not_expanding_cs{\substr_cond \fdParserId}% + \noexpandcsname \substr_cond \fdParserId \endcsname %% By `\edef', the name of the substring conditional is stored here %% as a single token. The rest of the sandbox follows. - ##1\noexpand~#1\dollar_tilde}% + ##1~#1\dollar_tilde}% +%% <- `\noexpand~' replaced for v0.5 according to +%% Sec.~\ref{sec:pseudo-tilde}. \let\dollar_tilde\sandbox_dollar} %% If a tilde `~' has been used instead of `$', the default %% is restored. \def\sandbox_dollar{$} \let\dollar_tilde\sandbox_dollar -%% The following general tool |\make_not_expanding_cs| has been used +%% % The following general tool |\make_not_expanding_cs| has been used +%% The following general tool |\noexpandcsname| has been used %% (many definitions in 'latex.ltx' could have used it): %% 2009/04/10 -\def\make_not_expanding_cs#1{% - \expandafter \noexpand \csname #1\endcsname} +% \def\make_not_expanding_cs#1{% +% \expandafter \noexpand \csname #1\endcsname} +%% <- 2011/11/20 -> +\def\noexpandcsname{\expandafter\noexpand\csname} %% %% === Getting rid of the tildes === %% |\let~\TildeGobbles| can be used to suppress dummy patterns @@ -555,6 +606,21 @@ \newcommand*{\RemoveTildeArg}[2]{% \expandafter #1\expandafter {\RemoveTilde #2}} %% +%% === Alternative Setup === +%% \label{sec:pseudo-tilde} +%% 'blog.sty' v0.7---``ligatures"---has problems with the tilde. +%% We call a different setup by |\FDpseudoTilde| and go back +%% to the original one by |\FDnormalTilde| +%% (which, however, works only for new processing jobs and +%% processing another file---at present, TODO 2011/11/21): +\newcommand*{\FDnormalTilde}{\def~{\noexpand~}% + \let\RemoveTilde\FD_remove_normal_tilde} +\let\FD_remove_normal_tilde\RemoveTilde +\FDnormalTilde +\newcommand*{\FDpseudoTilde}{\def~{\noexpand\pseudo_tilde}% + \let\RemoveTilde\FD_remove_pseudo_tilde} +\def\FD_remove_pseudo_tilde#1\pseudo_tilde{#1} +%% %% === Calling conditionals === %% |\ProcessStringWith{<target-string>}{<id>}| \ builds the sandbox %% to search <target-string> for the <pattern> associated with the @@ -585,10 +651,11 @@ %% Anyway, most desired will be |\ProcessInputWith{<id>}| just %% applying to `\fdInputLine': \newcommand*{\ProcessInputWith}[1]{% - \csname \setup_substr_cond #1\expandafter \endcsname - \expandafter{\fdInputLine}} -%% (Definition almost copied for efficiency.) - %% TODO: error when undefined 2009/04/07 +% \csname \setup_substr_cond #1\expandafter \endcsname +% \expandafter{\fdInputLine}} +% %% (Definition almost copied for efficiency.) + \ProcessExpandedWith\fdInputLine{#1}} %% 2011/11/21 +%% TODO: error when undefined 2009/04/07 %% %% === Copy jobs === %% A job identifier <id> may also be considered a mere \emph{hook}, @@ -615,6 +682,7 @@ %% This feature could have been placed more below as a ``programming %% tool." %% +%% %% == Programming tools == %% === Tails of conditionals === %% \label{sec:tails} @@ -673,7 +741,7 @@ %% (v0.42) %% is a companion of `\IfFDpreviousInputEmpty' referring to %% `\fdInputLine' as of the \emph{previous} run of the loop -%% in `\ProcessFileWith', cf. section~\ref{sec:files}, +%% in `\ProcessFileWith', cf. section~\ref{sec:input}, %% where its choice among its two arguments is determined. %% It is initialized as follows: \newcommand*{\IfFDpreviousInputEmpty}[2]{#2} @@ -717,8 +785,8 @@ \ifnum\c@fdInputLine#1\relax \expandafter \@firstoftwo \else \expandafter \@secondoftwo \fi} %% -%% === The ``identity job" `LEAVE' === -%% \label{sec:LEAVE} +%% === ``Identity job" `LEAVE' and ``default job" `*' === +%% \label{sec:LEAVE}\label{sec:*} %% The job with identifier |LEAVE| %% \emph{leaves} an (expandable) chain of jobs %% (as expandable replacement in section~\ref{sec:replchain}) @@ -728,6 +796,24 @@ \csname \setup_substr_cond LEAVE\endcsname \@firstofone %% I.e., `\ProcessStringWith{<string>}{LEAVE}' expands to <string> %% ... \ProcessStringWith{(Indeed!)}{LEAVE} +%% +%% |LEAVE| is used for ``chaining" jobs---there will be a routine +%% (Sec.~\ref{sec:auto-chain}) +%% to define the action of a job, including what job to run +%% \emph{next} after the present one has been finished. +%% Using this routine, the final job will call `LEAVE'. +%% +%% |*| may be considered a ``meta-job"---it does not directly +%% set up a sandbox, it just ``redirects" to the job that has been +%% declared most recently. When job ids are assigned automatically, +%% with `*' you can call that job without knowing its actual id: +\@namedef{\setup_substr_cond*}{% + \csname \setup_substr_cond \fdParserId \endcsname} +%% As an important example, when all the jobs in the chain are +%% expandable, you can call the chain by +%% \[|\WriteResult{\ProcessInputWith{*}}|\] +%% in the body of the file processing loop (Sec.~\ref{sec:input}). +%% TODO: test! %% 2011/11/21 %% %% == Setup for expandable chains of replacements == %% \label{sec:replchain}%% TODO makedoc: provide less visible label/ref 2009/04/11 @@ -800,26 +886,26 @@ %% Optional argument <chng> changes category codes locally %% for reading <find> and <replace>. %% %% <- added <cat>, <pattern> -> <find> 2010/03/19 -\newcommand*{\MakeExpandableAllReplacer} - {\StartFDsetup\mk_setup_xpdbl_all_repl} -\newcommand*{\mk_setup_xpdbl_all_repl}[3]{% +\MakeSetupCommand{\MakeExpandableAllReplacer} + {\mk_setup_xpdbl_all_repl}[3]{% %% #1 pattern, #2 substitute, #3 pass to \endgroup %% We take pains to call next jobs by single %% command strings and store them this way, not by `\csname', %% as `\ProcessStringWith' would do it. `\edef\@tempa' %% is used for this purpose, but \dots - \edef\@tempa{% + \protected@edef\@tempa{% %% protected 2011/11/21 \noexpand\mk_setup_substr_cond{#1}{% {}{#2}% \noexpand\noexpand -%% That `\edef\@tempa' must \emph{not expand} the controll -%% words after they have been computed from `\csname' etc. +%% That `\edef\@tempa' must \emph{not expand} +%% tokens %%% the controll words after they have been %% 2011/11/20 +%% computed from `\csname' etc. %% Moreover, expansion of the parser commands -%% must be avoided another time, when `\@tempa' is executed. - \make_not_expanding_cs{\substr_cond\fdParserId}% +%% must be avoided another time when `\@tempa' is executed. + \noexpandcsname \substr_cond \fdParserId \endcsname \noexpand\noexpand - \make_not_expanding_cs{\setup_substr_cond #3}}}% + \noexpandcsname \setup_substr_cond #3\endcsname}}% %% Those internal setup commands start with `\endgroup' to switch back %% to standard category codes. We must match them here by %% `\begingroup'. @@ -828,11 +914,13 @@ \repl_all_chain_expandable{##1}{##2}}} %% The final command is the one that we explained first. %% TODO 2009/04/11 %% -%% === Half-automatic chaining === -%% |\PrependExpandableAllReplacer{<id>}[<cat>]{<find>}{<replace>}| %%\\ -%% %% [\topsep] -%% %% \[|\PrependExpandableAllReplacer{<id>}[<cat>]{<find>}{<replace>}|\] -%% is hoped to be a slight relief in composing replacement chains. +%% === Automatic chaining === +%% \label{sec:auto-chain} +%% With v0.31, %% "Half-automatic" \Prepend... +%% \[|\PrependExpandableAllReplacer{<id>}[<cat>]{<find>}{<replace>}|\] +%% % |\PrependExpandableAllReplacer{<id>}[<cat>]{<find>}{<replace>}| +%% % \\[\topsep] +%% was hoped to be a slight relief in composing replacement chains. %% It does something like invoking `\MakeExpandableAllReplacer' %% with <prev-setup-id> for the last <next-id> argument %% where <prev-setup-id> is the <id> of the job that was set up most @@ -846,11 +934,23 @@ %% \end{quote} %% and call <id-2>, it will call <id-1>, and the latter will call %% <id-0>. So you can reorder the chain by moving `\Prepend'... lines. +%% +%% With v0.5, +%% |\PrependExpandableAllReplacer*[<cat>]{<find>}{<replace>}| +%% saves you from inventing and typing <id>, it is automatically +%% generated; or the `*' replaces the <id> argument. \newcommand*{\PrependExpandableAllReplacer}{% \let\fdParserId_before\fdParserId - \StartFDsetup\prep_xpdbl_all_repl} + \@ifstar{\stepcounter{fd_line_job}% + \edef\@tempa{% + \noexpand\StartFDsetup + \noexpand\prep_xpdbl_all_repl + {\number\value{fd_line_job}}}% + \@tempa}% + {\StartFDsetup\prep_xpdbl_all_repl}} \newcommand*{\prep_xpdbl_all_repl}[2]{% \mk_setup_xpdbl_all_repl{#1}{#2}{\fdParserId_before}}% + %% #1 pattern, #2 substitute, #3 pass to %% |\StartPrependingChain| makes `\MakeExpandableReplacer' %% superfluous, in the sense that %% the above chain setup can be achieved as well like this: @@ -860,12 +960,25 @@ %% `\PrependExpandableAllReplacer{<id-1>}{<find-1>}{<subst-1>}'\\ %% `\PrependExpandableAllReplacer{<id-2>}{<find-2>}{<subst-2>}' %% \end{quote} +%% or with v0.5: +%% \begin{quote} +%% `\StartPrependingChain'\\ +%% `\PrependExpandableAllReplacer*{<find-0>}{<subst-0>}'\\ +%% `\PrependExpandableAllReplacer*{<find-1>}{<subst-1>}'\\ +%% `\PrependExpandableAllReplacer{<start>}{<find-2>}{<subst-2>}' +%% \end{quote} %% This adds a code line, but this way you can choose %% the final ``real" job more easily. So you can think of %% `\StartPrependingChain' as ``initializing a chain of -%% prependments." -\newcommand*{\StartPrependingChain}{\def\fdParserId{LEAVE}} -%% Use automatic ids another time ... TODO %% 2010/11/24 +%% prependments." As to the `*' version, the example suggests +%% using an explicit <id> argument finally if you want to invoke +%% the chain explicitly by a line job identity +%% (without counting the declaration lines---however, +%% note job `*' according to Sec.~\ref{sec:*}). +\newcommand*{\StartPrependingChain}{% + \def\fdParserId{LEAVE}% + \setcounter{fd_line_job}{0}} %% 2011/11/13; TODO \Nameprefix... +\newcounter{fd_line_job} %% %% === `CorrectHook' launching the replacement chain === %% %% 2010/03/29: @@ -889,7 +1002,7 @@ %% == Leave package mode == %% We restore the underscore `_' for math subscripts. %% (This might better depend on something \dots) %% TODO 2009/04/07 -\catcode`\_=8 %% restores underscore use for subscripts +\catcode`\_=8 %% \endinput %% \TeX\ ignores the rest of the file when it is \emph{input} @@ -1001,11 +1114,21 @@ v0.42 2010/11/09 typo corr. 2011/01/25 updated (C); footnotes to `substring theory'; TODO with \RemoveTilde; some manual line spacings (adding `\ ') -belonged to nicetext RELEASE 0.42 + -> r0.42 v0.43 2011/08/06 doc.: mistake \WriteResult/\ResultFile, 2011/08/22 use \acro 2011/09/12f. \CorrectedInputLine - reworded for breaking -belonged to nicetext RELEASE 0.44 + -> r0.44 v0.44 2011/10/23 messages from \ResultFile and \CloseResultFile + -> r0.46 +v0.45 2011/10/26 little modification of \CloseResultFile message, + "sacrificing" \pagebreak before Sec. 4 -- fine! +v0.5 2011/11/13 \PrependExpandableAllReplacer*, \MakeSetupCommand; + doc.: {center} with too long verbatim quote + 2011/11/19 input check fixed, doc. there adjusted, + \ifFinalInputFile, \ProcessFinalFileWith, job `*' + 2011/11/20 \noexpandcsname; "default job" lowercase + 2011/11/21 \ProcessInputWith "less efficient", + \protected@edef, "pseudo-tilde" TODO: cleveref 2010/03/18 |