%% Macro package `fifinddo.sty' for LaTeX2e, %% FIDO, FIND! %% copyright (C) 2009-2012 Uwe L\"uck, %% http://www.contact-ednotes.sty.de.vu %% -- author-maintained in the sense of LPPL below -- %% for processing tex(t) files %% (checking, filtering, converting, substituting, expanding, ...) \def\fileversion{0.61} \def\filedate{2012/11/17} %% This file can be redistributed and/or modified under %% the terms of the LaTeX Project Public License; either %% version 1.3c of the License, or any later version. %% The latest version of this license is in %% %% http://www.latex-project.org/lppl.txt %% %% We did our best to help you, but there is NO WARRANTY. %% Please report bugs, problems, and suggestions via %% %% http://www.contact-ednotes.sty.de.vu %% %% For the full documentation, look for `fifinddo.pdf'. %% Its source starts in `fifinddo.tex'. %% %% === Format and package version === \NeedsTeXFormat{LaTeX2e}[1994/12/01] % 1994/12/01: \newcommand* etc. \ProvidesPackage{fifinddo}[\filedate\space v\fileversion\space filtering TeX(t) files by TeX (UL)] %% %% === Category codes === %% We use the ``underscore" as ``compound identifier:" \RequirePackage{stacklet} \PushCatMakeLetter\_ %% 2012/08/27 %% v0.6 moves definition of |\MakeActiveDef| to 'actcodes' %% in the 'catcodes' bundle: \RequirePackage{actcodes} %% 'fifinddo' uses \TeX's feature of delimited macro parameters %% for matching \emph{strings} of characters. %% In order to get expected results, \emph{category codes} must match as well. %% |\PatternCodes| is used in setup macros for reading patterns %% for this purpose. It defaults to |\fdPatternCodes|. %% We offer |\SetPatternCodes{}| %% for redefining `\PatternCodes' %% and |\ResetPatternCodes| for returning to `\fdPatternCodes', %% so setup scripts such as 'mdoccorr.cfg' have shorter lines. \newcommand*{\fdPatternCodes}{\MakeOther\&\MakeOther\$} \newcommand*{\SetPatternCodes}{\def\PatternCodes} \newcommand*{\ResetPatternCodes}{\let\PatternCodes\fdPatternCodes} \newcommand*{\PatternCodes}{} \ResetPatternCodes %% TODO adding/removing; `*' may be wrong 2010/03/29 %% %% It would be bad to have `\MakeOther\%' and `\MakeOther\ ' here in %% that this may have unexpected, weird effects with arguments of %% setup macros. (With `\MakeOther\ ' you must not indent within a %% setup command, and if you add `\MakeOther\%' the setup command %% must stay in one line.) %% Therefore neither `\dospecials' nor `\@sanitize' are %% used. Curly braces remain untouched as default delimiters in setup %% macros. For matching them, you must use `\MakeOther\{' and %% `\MakeOther\}' %% corr. 2010/11/09 %% in your `\PatternCodes', or |\Delimiters| to introduce %% new ones at the same time, e.g., `\Delimiters\[\]': \newcommand*{\Delimiters}[2]{% \MakeOther\{\MakeOther\}\CatCode#1\@ne \CatCode#2=\tw@} %% |\CatCode\| is introduced for v0.6. %% It should appear in a package 'manycats' of the 'catcodes' %% bundle, but that's to much for 2012/08/27---TODO. \providecommand*{\CatCode}{\catcode`} %% For replacing strings or for defining other strings of ``other" %% characters by `\edef', you can use some \LaTeX\ constructs---here %% are copies |\PercentChar| and |\BackslashChar| of them %% (do you need more?): \newcommand*{\PercentChar}{} \let\PercentChar\@percentchar \newcommand*{\BackslashChar}{} \let\BackslashChar\@backslashchar %% %% <- corr. typo 2010/11/25 %% %% |\BasicNormalCatcodes| restores Plain~\TeX's %% \textbf{macro parsing} and comment character: \newcommand*{\BasicNormalCatCodes}{% \CatCode\\\z@ \Delimiters\{\}% % \restorecr !? \CatCode\ =10 \CatCode\%=14} %% However, reading files \emph{line by line} makes parsing of %% macro parameters somewhat difficult %% when the parameter code spans code lines. %% A line must not end with a curly brace when a macro requires %% another parameter; instead, it must contain the curly left %% brace for the next parameter. %% %% `\BasicNormalCatCodes' may be reimplemented by a package %% 'normcats' in the 'catcodes' bundle---TODO~... %% %% %% rm. \MakeActiveDef 2012/08/27 %% %% == File handling == %% %% 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{}| opens (and empties) a file %% to be written into. \newcommand*{\ResultFile}[1]{% \def\result_file_name{#1}% \typeout{`fifinddo' generating `\result_file_name'}% %% 2011/10/23 \immediate\openout\result_file=#1} %% |\WriteResult{}| writes a line into %% (or more lines with `^^J'). \newcommand*{\WriteResult}[1]{% \immediate\write\result_file{#1}} %% |\WriteProvides| writes a `\ProvidesFile' command to the %% opened file. This should be used when %% is made as \LaTeXe\ input. \newcommand*{\WriteProvides}{% \WriteResult{% \string\ProvidesFile{\result_file_name}% [\the\year/\two@digits\month/\two@digits\day\space automatically generated with fifinddo.sty]}}% %% |\CloseResultFile| closes : \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[]{}{}| %% opens a file %% and runs a loop on its lines the main body of which is . %% When the starts, a new line of is stored as macro %% |\fdInputLine|. The optional argument may change %% category codes used in reading . It may be useful to %% read macros with arguments and active characters expanding %% in writing to the output file. Even these expansions may be %% defined here (local to the group like everything else %% happening here, unless ...). %% Macros |\BasicNormalCatcodes| and |\MakeActiveDef| %% have been created for this purpose (see previous section TODO). %% (It may be better to store %% these in another macro and to call %% `\ProcessFileWith[]{}{}'). %% More possible uses of some usual \TeX\ category codes may be %% (some of) %% \begin{itemize} %% \item avoiding matching substrings of control words, %% \item skipping blank spaces as \TeX\ does it usually, %% %% <- macro parsing + ...!? %% \item catching \emph{balanced} input pieces, %% \item ignoring comments, %% \item ignoring certain characters. %% \end{itemize} \newcommand*{\ProcessFileWith}[3][]{% %% 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 %% ... 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 \MakeOther\^^I% ASCII horizontal tab -- guessed!? ^^L!? %% With v0.31, we support non-ASCII: \count@=128 \loop \ifnum\count@<\@cclvi \catcode\count@=12 \advance\count@\@ne \repeat #1% \loop \ifeof\@inputcheck \else \read\@inputcheck to \fdInputLine \ignorespaces #3% %% v0.42 supports |\IfFDpreviousInputEmpty|, %% cf. section \ref{sec:tails}: \expandafter \let \expandafter \IfFDpreviousInputEmpty \ifx\fdInputLine\@empty \@firstoftwo \else \@secondoftwo \fi \repeat \endgroup \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+

+. %% % %% |\CopyFile[]{}| %% is an application of `\ProcessFileWith' %% that ``copies" the content of file %% into the file specified by %% `\ResultFile'. %% was `\WriteResult'. 2011/08/06 %% However, optional allows some %% ``modifications" while ``copying"---especially, %% conversion of text encodings by active characters %% and expanding macros for generating \acro{HTML} %% or other code. The ``starred" variant %% |\CopyFile*| copies one empty line only %% when one empty line in the input file is followed %% by more of them. \newcommand*{\CopyFile}{% \@ifstar{\let\FD@copy@style\FD@compress@voids \FD@copyfile}% {\let\FD@copy@style\CopyLine \FD@copyfile}} \newcommand*{\FD@copyfile}[2][]{% \ProcessFileWith[#1]{#2}{\FD@copy@style\message{.}}} %% % <- message 2010/11/13; 2011/08/22: %% You should find a file `copyfile.tex' providing a dialogue %% for ``compressing" files this way. As soon as you have a %% useful conversion mapping file (defining |\TextCodes|), %% you can also use it for text encoding conversions. %% %% |\CopyLine|: \newcommand*{\CopyLine}{\WriteResult\fdInputLine} %% (... added `\space' without success with macro arguments %% 2010/04/26 --- `\BlogCodes' has used a better solution %% later). \newcommand*{\FD@compress@voids}{% \IfFDinputEmpty{\IfFDpreviousInputEmpty\relax\CopyLine}% \CopyLine} %% %% === 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[]{}{}| %% % |\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 %% 2011/11/19 again %% == Basic handling of substring conditionals == %% \label{sec:theory} %% %% TODO move theory to fifinddo.tex 2009/04/12 %% === ``Substring Theory" === %% \begin{flushright}\it %% I wished I could study string theory,\\ %% but I only could study substring theory. %% \end{flushright} %% A \TeX\ macro, say, `\find' whose parameter text %% (cf. \TeX book p.~203) %% starts with `#1#2&' stops \TeX\ with an error if it does %% not find and then `&'. Otherwise we have a situation %% `\find&', and `\find' reads as %% #1 and as #2. An important point to note is that %% will not contain , but possibly has more %% occurrences in . In this sense, `\find' uses the %% \emph{first} occurrence of it finds in order to delimit #1. %% Finding the \emph{last} occurrence of therefore needs a %% special idea. %% %% In order to use `\find' for a test whether is in %% , we build a ``sandbox" |\find&|, where %% contains \emph{and additionally} ---as a %% ``dummy;" so `&' delimits the search and `\find' finds %% either in or somewhere else before `&'. %% %% Consider the simple sandbox |\find&|. %% We can test #1 and #2 on being empty by `\ifx$#1$' and `\ifx$#2$'. %% If #2 is empty, is \emph{not} in . %% If #1 is empty at the same time, is empty. %% If #1 is empty and #2 is not, \emph{starts} %% !\footnote{%% 2011/01/25: %% This is just as wrong as the next claim.} %% This can be used to implement %% Wikipedia-like lists %% TODO 2009/04/11 %% and to distinguish package code from comments in %% 'makedoc'.\footnote{%% 2011/01/25: %% Due to the special substrings to test in this %% application, this is true although the %% surrounding claims are wrong.} %% %% If #2 is \emph{not} empty, occurs in ---or this once %% was \emph{thought}, some time in developping the present package, %% as well as in the version of 'substr.sty' marked %% `2005-11-29',\footnote{\url{http://ctan.org/pkg/substr}. %% 'substr' does not change category codes %% as 'fifinddo' does %% and uses \cs{@nil} as delimiter instead of %% our &&.} try %% (if that version still is installed)\footnote{The ``feature" has %% been fixed with v1.2 as of 2009/10/20 of %% 'substr.sty'.} %% \[`\IfSubStringInString{}{}{YES}{NO}'\] %% which works \emph{verbatim} as well as considering and %% \emph{placeholders}, e.g., for %% \begin{center} %% `\IfSubStringInString{day after day}{day after }{YES}{NO}'\footnote{% %% Likewise \texttt{t\string\^ete-\string\`a-t\string\^ete} ...}\\ %% %% <- `e' was missing 2010/03/17 %% `\IfSubStringInString{AMSTERDAM}{AMSTERD}{YES}{NO}'\\ %% `\IfSubStringInString{TORONTO}{TORON}{YES}{NO}'\\ %% `\IfSubStringInString{bonbon}{bon}{YES}{NO}'\footnote{% %% Polynesian: `aku aku', `rongorongo', `wiki wiki' ...}\\ %% `\IfSubStringInString{bonobo}{bono}{YES}{NO}' %% (an ape) %% \end{center} %% or `\IfSubStringInString{ionization}{ionizat}{YES}{NO}'.\footnote{% %% Read 'substr.sty' or try ``normal" things to convince yourself %% that the syntax indeed is %% &\IfSubStringInString{}{}{}{}.} %% Same with \LaTeX's internal `\in@':\footnote{\cs{in@} has been %% fixed after my warning on Heiko Oberdiek's proposal---at %% least in the repository.---On 2009/04/21 %% I learn from Manuel P\'egouri\'e-Gonnard %% that the first versions of his 'ted' %% had a similar bug, fixed on v1.05 essentially like here; %% Steven Segletes confirms that his 'stringstrings' doesn't %% suffer the problem (returning positions of substrings and %% numbers of occurrences).} %% \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} %% has a \emph{period} $p$---less than its length---in the sense of that %% the $p$th token to the right or left of each token in %% is the \emph{same} token. %% `AMSTERDAM' has a period 7, %% was 8 2011/01/20 %% `day after day' 10, `bonbon' 3, `bonobo' 4. %% There is a counterexample of length $p$ iff %% has period $p$, namely the first substring of %% having length $p$. If the length of exceeds a multiple %% $mp$ of its period, the first $mp$ tokens of form %% a counterexample . %% %% Therefore, a sandbox must have something between and %% .\footnote{Must? Actually, I preferred this solution to %% other ideas like measuring the length of .} %% We choose |\find~$&| as standard. %% The `$' will be used as an argument delimiter to get rid of the dummy %% in , as well as to decide whether the match was %% in or in the dummy part of the sandbox. %% The `$' can be replaced by another tilde `~' in order to %% test whether \emph{ends} on a , defining a macro %% like `\findatend' whose parameter text starts with `#1~#2&'. %% %% === Plan for proceeding === %% When we check a file for several patterns, we seem to need %% \emph{two} macros for each pattern: one that has the pattern %% in its parameter text and one that stores the pattern for building %% the sandbox.\footnote{If it were for the pattern only, the parsing %% macro might suffice and the macro calling it might extract the %% pattern from a ``dummy expansion." Somewhat too much for me now; %% on the other hand the calling macro also hands some ``current" %% informations to the parsing macro---oh, even this could be %% handled by a general ``calling" macro \dots} %% %% TODO 2009/04/15 %% We use a separate \emph{``name space"} for each of %% both kinds. The parsing macro and the macro building the sandbox %% will have a common \emph{``identifier"} by which the user or %% programmer calls them. Actually, she will usually (first) call %% the sandbox box builder. The sandbox builder calls the parsing %% macro. When \emph{all} occurrences of a pattern in the target are %% looked for, the parser may call itself. %% %% Actually, the parsing macro will execute certain actions %% depending on what it finds in the sandbox, so we call it a %% \emph{``substring conditional"}. It may read additional arguments %% after the sandbox that store information gathered before. %% This is especially useful for designing \emph{``expandable"} %% chains (sequences) of conditionals where macros cannot store information in %% macros. The macro setting up the sandbox will initialize such %% extra arguments at the same time. %% %% It may be more efficient \emph{not} to use the following setup %% macros but to type the macros yourself, just using the following %% as templates. The setup macros are especially useful with patterns %% that contain ``special characters," as when you are looking for %% %% TODO repetition of single right quote not working 2010/03/19 %% lines that might be package comments. %% %% === Meta-Setup === %% %% A setup command will have the following syntax: %% \[|{}[]{}|\] %% will, in the first instance, be category code changes %% for reading overriding the settings in `\PatternCodes'. %% They are executed after the latter in a local group. %% It may be safer to redefine `\PatternCodes' instead %% of using the optional argument. %% %% A macro %% \[|\StartFDsetup{}{}[]|\] %% shared by setup commands %% may read and for . %% || will be the macro that reads (and more) %% and processes it. It must contain `\endgroup' to match %% `\begingroup' from `\FD_prepare_pattern'. %% is stored in a macro |\fdParserId|. %% The default for is \emph{nothing}. \newcommand*{\StartFDsetup}[1]{% \let\FD_do_setup#1% \afterassignment\FD_prepare_pattern \def\fdParserId} \newcommand*{\FD_prepare_pattern}[1][]{% \begingroup \PatternCodes #1\FD_do_setup} %% So should be set up about as follows: %% \begin{quote} %% `\newcommand*{}{\StartFDsetup}'\\ %% `\newcommand*{}[]{}' %% \end{quote} %% 's first argument will be the argument %% of .---With v0.5, we learn from the previous and provide %% \[|\MakeSetupCommand{}{}[]{}|\] \newcommand*{\MakeSetupCommand}[2]{\newcommand*#1{\StartFDsetup#2}% \newcommand*#2} %% %% === Setup for conditionals === %% `substr_cond' is the ``name space" for substring conditionals. %% A colon separates it from \emph{``job identifiers"} in the actual %% macro names. \def\substr_cond{substr_cond:} %% %% |\MakeSubstringConditional{}[]{}| %% starts the definition of a conditional with identifier %% and pattern . optionally add commands to %% be executed after `\PatternCodes' in a local group. %% `\begingroup' |\mk_substr_cond{}| %% TODO!? 2010/03/22 %% can be directly called by other programmer setup commands when %% `\fdParserId' and have been read. \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:' in primitive \TeX\ with `\def' in the form %% \[`\def\substr_cond:#1#2&'\] %% where `\csname' etc. render \lq`:'\rq\ part of the macro %% name.\footnote{%% 2010/11/27: %% Loosely speaking of ``the parser" around %% here somehow refers to this macro---but rather to %% its ``parameter text" only, %% according to \TeX book p.~203. Such a macro, %% however, won't ``parse" only, but it will also %% execute some job on the results of parsing. %% Or: a ``mere parsing" macro might be macro that %% transforms a ``weird" Plain \TeX\ parameter text %% into a ``simple" parameter text of another macro, %% consisting of hash marks and digits only. E.g.: %% &\def&\Foo#1#2&&{&\foo{#1}{#2}}.} %% The user or programmer macro produces the part of the definition %% until the delimiter `&' to match the sandbox. You have to add %% (maybe) #3 etc. and the `{}' %% just as with primitive \TeX. %% %% === Setup for sandboxes === %% There was a \emph{question:} will we rather see %% \emph{string macros} or \emph{strings from macro arguments}? %% The input file content always comes %% as `\fdInputLine' first, so we at least \emph{must account} for %% the possibility of string macros as input. %% %% One easy way to apply several checks and substitutions to %% `\fdInputLine' before the result is written to is %% `\let\OutputString\fdInputLine' and then let `\OutputString' %% be to what each job refers as \emph{its} %% input and output, finally `\WriteResult{\OutputString}'. %% (`\fdInputLine' might better not be touched, it could be used %% for a final test whether any change applied for some message on %% screen, even with an entirely expandable chain of actions.) %% This way each job, indeed each recursive substitution of a single %% string must start with expanding `\OutputString'. %% %% On the other hand, there is the idea of \emph{``expandable" %% chains of substitutions}. We may, e.g., define a macro, say, %% `\manysubstitutions{}', such that %% `\WriteResult{\manysubstitutions{\fdInputLine}}' %% writes to the result of applying many expandable %% substitutions to `\fdInputLine'. %% Such a macro `\manysubstitutions' may read `\fdInputLine', %% but it must not redefine any macros. %% Instead, the substitution macros it calls must read results %% of previous substitutions as \emph{arguments}. %% %% Another aspect: %% the order of substitutions should be easy to %% change. Therefore expanding of string macros should rather be %% controlled by the way a job is \emph{called}, not right here %% at the \emph{definition} of the job. For this reason, %% a variant of the sandbox builder expanding some macro was given up. %% %% <- TODO!? 2010/03/25 %% `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:} %% \begin{center} %% 2011/11/13 %% |\MakeSetupSubstringCondition{}[]{}{}| %% \end{center} %% % <- TODO allow `%' and ` ' for breaking code lines. %% ---same , , as for %% `\MakeSubstringConditional' (this is bad, there may be %% |\MakeSubstringConditional*{}|)---creates the %% % <- TODO: store args in \Make...Conditional %% corresponding sandbox, by default without tilde wrap. %% may contain `{#1}' to store the string that was tested, %% also `{}' for calling repetitions and `{}' for screen %% or log informations. \MakeSetupCommand{\MakeSetupSubstringCondition} {\mk_setup_substr_cond}[2]{% %% |\mk_setup_substr_cond{}{}| %% %% without \begingroup 2010/03/29 %% can be directly called by other programmer setup commands after %% `\fdParserId' and have been read. %% #1 pattern string %% #2 additional arguments, e.g., `{#1}' to keep tested string \endgroup \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{% \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\FD_noexpand~#1\dollar_tilde}% %% <- `\noexpand~' as before v0.5 replaced for v0.51 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 |\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} %% <- 2011/11/20 -> \def\noexpandcsname{\expandafter\noexpand\csname} %% %% === Getting rid of the tildes === %% |\let~\TildeGobbles| can be used to suppress dummy patterns %% (contained in ) %% in `\write'ing or with `\edef'. ... will probably become obsolete %% ... however, it is helpful in that you needn't care %% whether there is a dummy wrap left at all. (2009/04/13) \newcommand{\TildeGobbles}{} \def\TildeGobbles#1${} %% |\RemoveDummyPattern| is used to remove the dummy pattern %% \emph{immediately}, not waiting for `\write'ing %% or other ``total" expansion: %% 2009/04/13 \newcommand{\RemoveDummyPattern}{} \def\RemoveDummyPattern#1~#2${#1} %% |\RemoveDummyPatternArg{}| executes %% `\RemoveDummyPattern' in the next argument: \newcommand*{\RemoveDummyPatternArg}[2]{% \expandafter #1\expandafter {\RemoveDummyPattern #2}} %% |\RemoveTilde| is used to remove the tilde that separated %% the dummy pattern from . %% %% An alternative policy is to pass %% TODO 2011/01/25 %% %% (as an argument) to the parsing macro. \newcommand{\RemoveTilde}{} \def\RemoveTilde#1~{#1} %% |\RemoveTildeArg{}| executes `\RemoveTilde' %% in the next argument: \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}{% \let\FD_noexpand\noexpand %% v0.51 %% v0.5 had a modification of `~' that corrupted typesetting. \let\RemoveTilde\FD_remove_normal_tilde} \let\FD_remove_normal_tilde\RemoveTilde \FDnormalTilde \newcommand*{\FDpseudoTilde}{% \def\FD_noexpand~{\noexpand\pseudo_tilde}% %% v0.51 \let\RemoveTilde\FD_remove_pseudo_tilde} \def\FD_remove_pseudo_tilde#1\pseudo_tilde{#1} %% TODO 2012/01/20: This way outer braces of splits or the %% target token list are removed. With 'blog.sty', this has been %% relevant for displaying code only (where using source braces %% for displaying braces, instead of using `\{' and `\}', %% it was a bad habit anyway). In order to fix this, the target %% token list must be surrounded with some additional dummy things, %% and `\RemoveTildeArg' must add another trick. %% %% <- stored in "bad" directory. %% %% === Calling conditionals === %% |\ProcessStringWith{}{}| \ builds the sandbox %% to search for the associated with the %% parser-conditional that is identified by , the sandbox then %% calls the parser. %% % Finally, the command \emph{``returns"} the %% % result of applying job to ---in the sense of %% % \emph{expanding} to it. %% more precisely 2010/03/25 %% %% <- removed again, wrong 2010/03/26 \newcommand*{\ProcessStringWith}[2]{% \csname \setup_substr_cond #2\endcsname{#1}} %% |\ProcessExpandedWith{}{}| does the same but with %% %% changed, intro toks 2010/04/06: %% a \emph{macro} %% (like `\fdInputLine' or `\OutputString') %% that stores the string to be tested. %% |\ProcessExpandedWith{\the}{}| with a token list %% parameter or register may be used as well. \newcommand*{\ProcessExpandedWith}[2]{% \csname \setup_substr_cond #2\expandafter \endcsname \expandafter{#1}} %% I would have preferred the reversed order of arguments which seems %% to be more natural, but the present one is more efficient. %% Macros with reversed order are currently stored after `\endinput' %% in section~\ref{sec:pondered}, maybe they once return. %% %% <- minor corr.s 2010/11/27 %% %% Anyway, most desired will be |\ProcessInputWith{}| just %% applying to `\fdInputLine': \newcommand*{\ProcessInputWith}[1]{% % \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 may also be considered a mere \emph{hook}, %% a \emph{placeholder} for a parsing job. What function actually is %% called may depend on conditions that change while reading the %% file. %%% On a certain condition, %% |\CopyFDconditionFromTo{}{}| %% \emph{creates or redefines a sandbox builder} with identifier %% that afterwards behaves like the sandbox builder . %% So you can store a certain behaviour as in advance in order %% once to change the behaviour of into that of . \newcommand*{\CopyFDconditionFromTo}[2]{% \expandafter \let \csname \setup_substr_cond #2\expandafter \endcsname \csname \setup_substr_cond #1\endcsname} %% (Only the \emph{sandbox} is copied here---what about %% changing conditionals?) %% TODO %% %% An ``almost" example is typesetting documentation from a package %% file where the ``Legalese" header might be typeset verbatim %% although it is marked as ``comment." (The present %% 2009/04/07 %% example changes ``hand-made" macros instead.) %% %% This feature could have been placed more below as a ``programming %% tool." %% %% %% == Programming tools == %% === Tails of conditionals === %% \label{sec:tails} %% When creating complex \emph{expandable} conditionals, %% this may amount to have primitive `\if' ... `\fi' conditionals %% nested quite deeply, once perhaps too deep for \TeX's memory. %% To avoid this, you can apply the common `\expandafter' trick %% which finishes the current `\if' ... `\fi' before an inside %% macro is executed (cf. \TeX book p.~219 on ``tail recursion"). %% %% Internally tests whether certain strings are present at certain %% places will be carried out by tests on emptiness or %% %% onwards) %% !? 2009/12/28 %% on starting with `~'. E.g., %% ``#1~=~ empty" indicates that either the %% starts a line or the line is empty altogether (this must be %% decided by another test). %% %% |\IfFDempty{}{}{}| \ %% is used to test on emptyness (without expanding it): \newcommand*{\IfFDempty}[1]{% \ifx$#1$\expandafter \@firstoftwo \else \expandafter \@secondoftwo \fi} %% |\IfFDinputEmpty{}{}| is a variant of %% the previous to execute if the loop processing %% finds an empty line---otherwise . \newcommand*{\IfFDinputEmpty}{% \ifx\fdInputLine\@empty \expandafter \@firstoftwo \else \expandafter \@secondoftwo \fi} %% |\IfFDdollar{}{}{}| %% %% <- dollar<-empty %% is another variant, testing for being `$', %% main indicator of there is a match anywhere in %% (as opposed to starting or ending match): \newcommand*{\IfFDdollar}[1]{% \ifx$#1\expandafter \@firstoftwo \else \expandafter \@secondoftwo \fi} %% It is exemplified and explained in section~\ref{sec:replchain}. %% (The whole policy requires that `~' remains active in any %% testing macros here!) %% %% However, you might always just type the replacement text %% (in one line) instead of %% such an `\If'\,... (for efficiency \dots) %% %% If expandability is not desired, you can just chain macros that %% rework (so re-define) `\OutputString' or so. %% %% 2009/04/11: tending towards combining ... %% Keeping empty input and empty arguments apart is useful in that %% \emph{one} test of emptiness per input line should suffice---it %% may be left open whether this should be the first of all tests %% \dots %% %% |\IfFDpreviousInputEmpty{}{}| %% (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:input}, %% where its choice among its two arguments is determined. %% It is initialized as follows: \newcommand*{\IfFDpreviousInputEmpty}[2]{#2} %% ---which is same as \let\IfFDpreviousInputEmpty\@secondoftwo %% ... working like `false', somewhat. %% Together with `\IfFDinputEmpty', it can be used to compress %% multiple adjacent empty lines into a single one %% when copying a file. %% %% === Line counter === %% A \LaTeX\ counter |fdInputLine| may be useful for screen or log %% messages, moreover you can use it to control processing of the %% file ``from outside," not dependent on what the parsing %% macros find. The header of the file might be typeset verbatim, %% but we may be too lazy to define the ``header" in terms of %% what is in the file. We just decide that the first ... lines %% are the ``header," even without counting just trying whether %% the output is fine. It may be necessary to change that number %% manually when the header changes. %% %% You also can insert lines in %% which have no counterpart in ---if you know what you are %% doing. With 'makedoc', there is a hook `\EveryComment' that can %% be used to issue commands ``from outside" at a place where %% executing the command is safe or appropriate. \newcounter{fdInputLine} %% You then must insert \ |\CountInputLines| \ in the second argument %% of `\ProcessFileWith' (or in a macro called from there) %% so that the counter is stepped. %% TODO!? 2009/04/07 \newcommand*{\CountInputLines}{\global\advance\c@fdInputLine\@ne} %% At present %% 2009/04/07 TODO %% the counter is reset by `\ProcessFileWith', this may change. %% %% |\IfInputLine{}{}{}|, when called %% from the processing loop (second argument of `\ProcessFileWith') %% issues commands if `\value{fdInputLine}' %% is true, otherwise . is one out of %% \HardNVerb+<+, `=', `>'. %% 2010/03/24 2010/03/29 \newcommand*{\IfInputLine}[1]{% \ifnum\c@fdInputLine#1\relax \expandafter \@firstoftwo \else \expandafter \@secondoftwo \fi} %% %% === ``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}) %% and \emph{leaves} the processed string without changing it %% and without the braces enclosing it: \expandafter \let \csname \setup_substr_cond LEAVE\endcsname \@firstofone %% I.e., `\ProcessStringWith{}{LEAVE}' expands to %% ... \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 %% By the following means, you can create macros %% (`\Transform' among them) such that, e.g., %% \[`\edef\OutputString{\Transform{}}'\] renders `\OutputString' %% the result of applying a chain (sequence) of stringwise replacements %% to . %% You can even write a transformed input to a file %% without defining anything after `\read to'\,.\,.\,. %% corr. 2010/11/24 %% In this case however, you don't get any statistical message %% about what happened or not. With `\edef\OutputString' you can at %% least issue some `changed!' or `left!' (maybe `\message{!}' vs.\ %% `\message{.}'). %% There is an application in 'makedoc' for ``typographical upgrading" %% from plain text to \TeX\ input. %% %% === The backbone macro === %% |\repl_all_chain_expandable| will be the backbone of the %% replacements. It is called by some parsing macro %% and receives from the latter ~=~#1 and ~=~#2. %% #3 is the result of what happened so far. \def\repl_all_chain_expandable#1#2#3#4#5#6{% %% #1, #2 splits, #3 past, #4 substitute, %% #5 repeat parser, #6 pass to % \ifx~#2\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi %% The previous line (or something similar!?) %% add. 2010/11/24 %% would be somewhat faster, but let us exemplify %% `\IfFDdollar' from section~\ref{sec:tails} instead: \IfFDdollar{#2}% %% If #2 starts with `$'---with category code 3, ``math shift"!, %% it \emph{is} `$', due to not reading `$' %% from input with its standard category code 3 %% and the sandbox construction (where `$' appears with its standard %% category code). %% TODO might be explained earlier 2009/04/11 %% %% or refer to here. %% And this is the case \emph{exactly} when the from %% didn't match, again due to the input category codes. %% Now on \emph{no} match, the sandbox builder #6 is called %% with target string #3#1 where the last tested string is attached %% to previous results. The ending `~' is removed, #6 inserts a new %% wrap for the new dummy pattern. {\RemoveTildeArg #6{#3#1}}% %% Otherwise ... the \emph{sandbox builder} %% (that will be shown below) that called %% initialized #5 to be that itself. ( otherwise %% wouldn't know who it is.) So calls itself with another sandbox %% `#2&'. Note that #2 contains \lq`~$'\rq\ due to the initial %% building. {#5#2&{#3#1#4}{#4}#5#6}} %% #4 is the replacement string that passed to . %% The first argument after the `&' is previous stuff plus %% the recently skipped %% plus #4 replacing the string that was matched. %% %% Finally, #5 and #6 again ``recall" and the sandbox %% builder to which to change in case of no other match. %% %% % TODO move following up!? 2009/04/11 %% === The basic setup interface macro === %% |\MakeExpandableAllReplacer{}[]{}{}{}|\\ %% [\topsep] %% %% \[|\MakeExpandableAllReplacer{}[]{}{}{}|\] %% creates sandbox and parser with common identifier and search %% pattern . Each occurrence of will be replaced by %% . When is not found, the sandbox builder for %% is called. This may be another replacing macro of the %% same kind. To return the result without further transformations, %% call job `LEAVE' (section~\ref{sec:LEAVE}). %% Optional argument changes category codes locally %% for reading and . %% %% <- added , -> 2010/03/19 \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 \protected@edef\@tempa{% %% protected 2011/11/21 \noexpand\mk_setup_substr_cond{#1}{% {}{#2}% \noexpand\noexpand %% 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. \noexpandcsname \substr_cond \fdParserId \endcsname \noexpand\noexpand \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'. \begingroup \@tempa \begingroup \mk_substr_cond{#1}{% \repl_all_chain_expandable{##1}{##2}}} %% The final command is the one that we explained first. %% TODO 2009/04/11 %% %% === Automatic chaining === %% \label{sec:auto-chain} %% With v0.31, %% "Half-automatic" \Prepend... %% \[|\PrependExpandableAllReplacer{}[]{}{}|\] %% % |\PrependExpandableAllReplacer{}[]{}{}| %% % \\[\topsep] %% was hoped to be a slight relief in composing replacement chains. %% It does something like invoking `\MakeExpandableAllReplacer' %% with for the last argument %% where is the of the job that was set up most %% recently. If you have adjacent lines %% \begin{quote} %% \leavevmode\hbox to 0pt\bgroup %% `\MakeExpandableAllReplacer{}{}{}{LEAVE}'% %% \hss\egroup \\ %% `\PrependExpandableAllReplacer{}{}{}'\\ %% `\PrependExpandableAllReplacer{}{}{}' %% \end{quote} %% and call , it will call , and the latter will call %% . So you can reorder the chain by moving `\Prepend'... lines. %% %% With v0.5, %% |\PrependExpandableAllReplacer*[]{}{}| %% saves you from inventing and typing , it is automatically %% generated; or the `*' replaces the argument. \newcommand*{\PrependExpandableAllReplacer}{% \let\fdParserId_before\fdParserId \@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 %% As of 2012/11/13, `mdoccorr.cfg' uses `\do' as a shorthand %% for \[`\PrependExpandableAllReplacer*'\] `\do' sometimes has %% not been defined at that moment, then %% \[`\renewcommand*{\do}{\PrependExpandableAllReplacer*}'\] fails. %% To make it working (or superfluous): %% 2012/11/17 \gdef\do{\PrependExpandableAllReplacer*} %% |\StartPrependingChain| makes `\MakeExpandableReplacer' %% superfluous, in the sense that %% the above chain setup can be achieved as well like this: %% \begin{quote} %% `\StartPrependingChain'\\ %% `\PrependExpandableAllReplacer{}{}{}'\\ %% `\PrependExpandableAllReplacer{}{}{}'\\ %% `\PrependExpandableAllReplacer{}{}{}' %% \end{quote} %% or with v0.5: %% \begin{quote} %% `\StartPrependingChain'\\ %% `\PrependExpandableAllReplacer*{}{}'\\ %% `\PrependExpandableAllReplacer*{}{}'\\ %% `\PrependExpandableAllReplacer{}{}{}' %% \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." As to the `*' version, the example suggests %% using an explicit 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: %% |\MakeDocCorrectHook{}| belongs to 'makedoc', %% but in the meantime ('nicetext' release 0.3) %% I have proposed to use it with 'fifinddo' only as well %% (running files `fdtxttex.tpl', `fdtxttex.tex'). %% Therefore I offer some simplification |\SetCorrectHookJob{}| %% for defining `\MakeDocCorrectHook' \emph{here.} \newcommand*{\SetCorrectHookJob}[1]{% \def\MakeDocCorrectHook##1{\ProcessStringWith{##1}{#1}}} %% |\SetCorrectHookJobLast| just uses the job that was set up %% most recently. \newcommand*{\SetCorrectHookJobLast} {\SetCorrectHookJob\fdParserId} %% |\CorrectedInputLine| results from `\MakeDocCorrectHook' when the %% latter is applied to `\fdInputLine': %% reworded for breaking 2011/09/13 \newcommand*{\CorrectedInputLine}{% \expandafter \MakeDocCorrectHook \expandafter{\fdInputLine}} %% %% == Leave package mode == %% We restore the underscore `_' for math subscripts. %% (This might better depend on something \dots) %% TODO 2009/04/07 \PopLetterCat\_ %% 2012/08/27 %% \endinput %% \TeX\ ignores the rest of the file when it is \emph{input} %% ``in the sense of `\input'", as opposed to just reading %% the file line by line to a macro like `\fdInputLine'. %% %% == Pondered == %% \label{sec:pondered} %% TODO abbreviated commands (aliases) \MkSubstrCond... %% TODO \@onlypreamble!? \newcommand*{\ApplySubstringConditional}[1]{% %% #1 identifier; text to be searched expected next \csname setup_substr_cond:#1\endcsname} \newcommand*{\ApplySubstringConditionalToExpanded}[1]{% 2009/03/31+ \csname setup_substr_cond:#1\expandafter \endcsname \expandafter} \newcommand*{\ApplySubstringConditionalToInputString}[1]{% 2009/03/31+ \csname setup_substr_cond:#1\expandafter \endcsname \expandafter {\fdInputLine}} %% TODO or `\OutputString', even `\read' to `\OutputString'!? % \newcommand*{\ApplySubstringConditionalToExpanded}[2]{% % %% note: without assignments, robust! % %% BUT the `\csname ... \expandafter \endcsname' method is faster % \expandafter \reversed_apply_substr_cond % \expandafter {#2}{#1}} % \newcommand*{\reversed_apply_substr_cond}[2]{% % \ApplySubstringConditional{#2}{#1}} %% ODER: % \newcommand*{\expand_attach_arg}[2]{%% 2009/03/31 % %% #1 command with previous args, TODO cf. LaTeX3 % \expandafter \attach_arg \expandafter {#1}{#2}} % %% actually #1 may contain more than one token, % %% only first expanded % \newcommand*{\attach_arg}[2]{#2{#1}} % \newcommand*{\ApplySubstringConditionalToExpanded}[2]{% % \expandafter \attach_arg \expandafter % {#2}{\ApplySubstringConditional{#1}}} %% %% %% %% == VERSION HISTORY == %% v0.1 2009/04/03 very first version, tested on morgan.sty v0.2 2009/04/05 counter fdInputLine, \ProvidesFile moved from \ProcessFile to \ResultFile, \CopyFD..., category section first, more sectioning, suppressing empty code lines before section titles; discussion, \Delimiters 2009/04/06 more discussion 2009/04/07 more discussion, factored \WriteProvides out from \ResultFile, \ProcessExpandedWith corrected 2009/04/08 \InputString -> \fdInputline; removed \ignorespaces 2009/04/09 \WhenInputLine[2] -> \IfInputline[3], \ProcessInputWith, typos, \WriteProvides message `with' 2009/04/10 \make_not_expanding_cs DISCOVERED ``IF SUBSTRING" ALGORITHM WRONG ( in ) v0.3 2009/04/11 SOME THINGS GIVEN UP EARLIER WILL BE REMOVED, TO BE STORED IN THE COPY AS OF 2009/04/10 mainly: sandbox setup (tilde/dollar) REAL ADDITION: setup for expandable replacing 2009/04/12 played with `chain' vs. `sequence'; plain `...', `cf.', `etc.' for `mdcorr.cfg' 2009/04/13 \RemoveTilde... 2009/04/15 reworked text, same mistake \in@ v0.31 2009/04/21f. comments on ted, stringstrings 2009/12/28 "onwards)" !? "safer", not "more safe" 2010/03/10 the loop starts 2010/03/17 corr. t^ete; set up -> setup for 2010/03/18 TODO EOF, ctan.org/pkg/newfile; non-ASCII 2010/03/19 extended description of \MakeExpandableAll...; '' -> " 2010/03/20 \ctanpkgref 2010/03/22 \StartFDsetup, \Prepend... 2010/03/23 URL for `substr.sty' SENT TO CTAN v0.4 2010/03/24 removed \pagebreak before "substrings"; with \IfInputLine precisely 2010/03/25 todo \ProcessExp... more precisely, etc. 2010/03/26 ... was wrong, removed 2010/03/29 \SetPatternCodes, \ResetPatternCodes, \SetCorrectHookJob, \SetCorrectHookJobLast; with \HardNVerb; don't mention \begingroup with \mk_setup_substr_cond; renamed v0.4 belonged to nicetext RELEASE 0.4 v0.4a 2010/04/04 copyright 2010 belonged to nicetext RELEASE 0.41 v0.41 2010/04/06 more on \ProcessExpanded...; \ProcessFile... gets opt arg 2010/04/13 \ProcessFile{}... shows used by blog.sty v0.1, v0.2 v0.42 2010/11/09 typo corr. 2010/11/10 \IfFDpreviousInputEmpty 2010/11/11 \BasicNormalCatcodes from blog.sty, \CopyFile*, \CopyLine; v3. -> v0.3; LPPL v1.3c 2010/11/12 \CatCode replaced (implemented in niceverb only) 2010/11/13 \CopyFile with \message{.} 2010/11/24 reworked doc. of replacement setup; \StartPrependingChain 2010/11/25 corr. typo \@backslash...; doc. changes; \CopyLine indeed, not \fdCopyLine 2010/11/27 footnote on "parser", other doc. corr.s 2011/01/20 corr. "period" AMSTERDAM 2011/01/25 updated (C); footnotes to `substring theory'; TODO with \RemoveTilde; some manual line spacings (adding `\ ') -> r0.42 v0.43 2011/08/06 doc.: mistake \WriteResult/\ResultFile, 2011/08/22 use \acro 2011/09/12f. \CorrectedInputLine - reworded for breaking -> 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" -> r0.5 v0.51 2012/01/20 updated (C); TODO on pseudo-tilde 2012/03/17 fixed \FDnormalTilde/\FDpseudoTilde -> r0.53 v0.6 2012/08/27 using 'catcodes', introducing \CatCode -> r0.62 v0.61 2012/11/17 . \gdef\do... TODO: cleveref 2010/03/18