summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/latex/nicetext/doclog/fifinddo.doc
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/doc/latex/nicetext/doclog/fifinddo.doc')
-rw-r--r--Master/texmf-dist/doc/latex/nicetext/doclog/fifinddo.doc807
1 files changed, 807 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/nicetext/doclog/fifinddo.doc b/Master/texmf-dist/doc/latex/nicetext/doclog/fifinddo.doc
new file mode 100644
index 00000000000..7178ee20640
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/nicetext/doclog/fifinddo.doc
@@ -0,0 +1,807 @@
+\ProvidesFile{fifinddo.doc}[2009/04/16 automatically generated with makedoc.sty]
+\begin{packagecode}
+%% Macro package `fifinddo.sty' for LaTeX2e, %% FIDO, FIND!
+%% copyright (C) 2009 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.3} \def\filedate{2009/04/15}
+
+%% This file can be redistributed and/or modified under
+%% the terms of the LaTeX Project Public License; either
+%% version 1.3a 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'.
+\end{packagecode}
+
+\subsection{\hspace{1sp}\ignorespaces Format and package version \unskip }
+
+\begin{packagecode}
+\NeedsTeXFormat{LaTeX2e}[1994/12/01]
+% 1994/12/01: \newcommand* etc.
+\ProvidesPackage{fifinddo}[\filedate\space v\fileversion\space
+ filtering TeX(t) files by TeX (UL)]
+\end{packagecode}
+
+\subsection{\hspace{1sp}\ignorespaces Category codes \unskip }
+
+
+We use the ``underscore'' as ``compound identifier.''
+\begin{packagecode}
+\catcode`\_=11 %% underscore used in control words
+\end{packagecode}
+|\MakeOther| is a synonym for `\@makeother', needed for matching
+special characters from the input file. It is exemplified by
+|\fdPatternCodes| which is the default of |\PatternCodes|.
+The latter is used in setup macros for reading patterns.
+\begin{packagecode}
+\@ifundefined{MakeOther}{\let\MakeOther\@makeother}{}
+\newcommand*{\fdPatternCodes}{\MakeOther\&\MakeOther\$}
+\newcommand*{\PatternCodes}{} \let\PatternCodes\fdPatternCodes
+ %% TODO adding/removing
+\end{packagecode}
+It would be bad to have `\MakeOther\%' and `\MakeOther\ ' here in
+that this may have unexpected, weird effects with arguments of
+setup macros. 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' in your `\PatternCodes', or |\Delimiters| to introduce
+new ones at the same time, e.g., `\Delimiters\[\]':
+\begin{packagecode}
+\newcommand*{\Delimiters}[2]{%
+ \MakeOther\{\MakeOther\}\catcode`#1=1\catcode`#2=2\relax}
+\end{packagecode}
+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?):
+\begin{packagecode}
+\newcommand*{\PercentChar}{} \let\PercentChar\@percentchar
+\newcommand*{\BackslashChar}{} \let\BackslashChar\@backslashcar
+\end{packagecode}
+
+\section{\hspace{1sp}\ignorespaces File handling \unskip }
+
+\begin{packagecode}
+\newwrite\result_file %% or write to \@mainaux!?
+\end{packagecode}
+|\ResultFile{<output>}| opens (and empties) a file
+<output> to be written into.
+\begin{packagecode}
+\newcommand*{\ResultFile}[1]{%
+ \def\result_file_name{#1}%
+ \immediate\openout\result_file=#1}
+\end{packagecode}
+|\WriteResult{<balanced>}| writes a <balanced> line into
+<output> (or more lines with `^^J').
+\begin{packagecode}
+\newcommand*{\WriteResult}[1]{%
+ \immediate\write\result_file{#1}}
+\end{packagecode}
+|\WriteProvides| writes a `\ProvidesFile' command to the
+opened <output> file. This should be used when <output>
+is made as \LaTeXe\ input.
+\begin{packagecode}
+\newcommand*{\WriteProvides}{%
+ \WriteResult{%
+ \string\ProvidesFile{\result_file_name}%
+ [\the\year/\two@digits\month/\two@digits\day\space
+ automatically generated with fifinddo.sty]}}%
+\end{packagecode}
+|\ProcessFileWith{<input>}{<loop-body>}| opens a file <input>
+and runs a loop on its lines the main body of which is <loop-body>.
+When it starts, a new line of <input> is stored as macro
+|\fdInputLine|.
+\begin{packagecode}
+\newcommand*{\ProcessFileWith}[2]{%
+ \openin\@inputcheck=#1%
+% \ifeof\@inputcheck %% bad `exists?' test
+% \PackageError{fifinddo}{File `#1' not here}%
+% {Mistyped?}%
+% \else
+ \global\c@fdInputLine=\z@ %% line counter reset
+ \begingroup
+ \MakeOther\{\MakeOther\}\@sanitize
+ %% from docstrip.tex:
+ % \MakeOther\^^A\MakeOther\^^K%% irrelevant, not LaTeX
+ \endlinechar\m@ne
+ %% <- cf. TeXbook "extended keyboards" up-/downarrow
+ %% -> "math specials", cf. "space specials"
+ \MakeOther\^^I% ASCII horizontal tab -- guessed!? ^^L!?
+ \loop \ifeof\@inputcheck \else
+ \read\@inputcheck to \fdInputLine
+ \ignorespaces #2%
+ \repeat
+ \endgroup
+% \fi
+ \closein\@inputcheck}
+\end{packagecode}
+|\CloseResultFile| closes <output>.
+\begin{packagecode}
+\newcommand*{\CloseResultFile}{\immediate\closeout\result_file}
+\end{packagecode}
+Peter Wilson's 'newfile' provides more powerful file handling.
+% <- TODO relevant? 2009/04/12
+
+\pagebreak %% TODO move theory to fifinddo.tex 2009/04/12
+
+\section{\hspace{1sp}\ignorespaces Basic handling of substring conditionals \unskip }
+
+\label{sec:theory}
+
+\subsection{\hspace{1sp}\ignorespaces ``Substring Theory'' \unskip }
+
+\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<pattern>#2&' stops \TeX\ with an error if it does
+not find <pattern> and then `&'. Otherwise we have a situation
+`\find<split1><pattern><split2>&', and `\find' reads <split1> as
+#1 and <split2> as #2. An important point to note is that <split1>
+will not contain <pattern>, but possibly <pattern> has more
+occurrences in <split2>. In this sense, `\find' uses the
+\emph{first} occurrence of <pattern> it finds in order to delimit #1.
+Finding the \emph{last} occurrence of <pattern> therefore needs a
+special idea.
+
+In order to use `\find' for a test whether <pattern> is in
+<target>, we build a ``sandbox'' |\find<sand>&|, where <sand>
+contains <target> \emph{and additionally} <pattern>---as a
+``dummy;'' so `&' delimits the search and `\find' finds
+<pattern> either in <target> or somewhere else before `&'.
+
+Consider the simple sandbox |\find<target><pattern>&|.
+We can test #1 and #2 on being empty by `\ifx$#1$' and `\ifx$#2$'.
+If #2 is empty, <pattern> is \emph{not} in <target>.
+If #1 is empty at the same time, <target> is empty.
+If #1 is empty and #2 is not, <pattern> \emph{starts} <target>!
+This can be used to implement
+Wikipedia-like lists %% TODO 2009/04/11
+and to distinguish package code from comments in 'makedoc'.
+
+If #2 is \emph{not} empty, <pattern> occurs in <target>---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{\hspace{1sp}'substr' does not change
+ category codes
+ % as 'fifinddo' does
+ and uses \cs{@nil} as delimiter instead of our &&.} try
+\[`\IfSubStringInString{<str1><str2><str1>}{<str1><str2>}{YES}{NO}'\]
+which works \emph{verbatim} as well as considering <str1> and
+<str2> \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\^te} $\dots$}\\
+ `\IfSubStringInString{AMSTERDAM}{AMSTERD}{YES}{NO}'\\
+ `\IfSubStringInString{TORONTO}{TORON}{YES}{NO}'\\
+ `\IfSubStringInString{bonbon}{bon}{YES}{NO}'\footnote{%
+ Polynesian: `aku aku', `rongorongo', `wiki wiki' $\dots$}\\
+ `\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{<pattern>}{<target>}{<yes>}{<no>}.}
+Same with \LaTeX's internal `\in@':
+\[`\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}
+
+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
+the $p$th token to the right or left of each token in <pattern>
+is the \emph{same} token.
+`AMSTERDAM' has a period 8, `day after day' 10, `bonbon' 3, `bonobo' 4.
+There is a counterexample <target> of length $p$ iff
+<pattern> has period $p$, namely the first substring of <pattern>
+having length $p$. If the length of <pattern> exceeds a multiple
+$mp$ of its period, the first $mp$ tokens of <pattern> form
+a counterexample <target>.
+
+Therefore, a sandbox must have something between <target> and
+<pattern>. We choose |\find<target>~<pattern>$&| as standard.
+The `$' will be used as an argument delimiter to get rid of the dummy
+<pattern> in <split2>, as well as to decide whether the match was
+in <target> or in the dummy part of the sandbox.
+The `$' can be replaced by another tilde `~' in order to
+test whether <target> \emph{ends} on a <pattern>, defining a macro
+like `\findatend' whose parameter text starts with `#1<pattern>~#2&'.
+
+
+\subsection{\hspace{1sp}\ignorespaces Plan for proceeding \unskip }
+
+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
+lines that might be package comments.
+
+
+\subsection{\hspace{1sp}\ignorespaces Set up conditionals \unskip }
+
+`substr_cond' is the ``name space'' for substring conditionals.
+A colon separates it from \emph{``job identifiers''} in the actual
+macro names.
+\begin{packagecode}
+\def\substr_cond{substr_cond:}
+\end{packagecode}
+|\MakeSubstringConditional{<id>}[<changes>]{<pattern>}|
+starts the definition of a conditional with \emph{identifier} <id>
+and pattern <pattern>. <changes> optionally add commands to
+be executed after `\PatternCodes' in a local group.
+It may be more safe to redefine `\PatternCodes' instead.
+\begin{packagecode}
+\newcommand*{\MakeSubstringConditional}{%
+ \afterassignment\mk_substr_cond_san \def\cond_id}
+\newcommand*{\mk_substr_cond_san}[1][]{%
+ \begingroup \PatternCodes #1\mk_substr_cond}
+ %% #1 more changes
+\end{packagecode}
+`\begingroup' |\mk_substr_cond{<pattern>}|
+can be directly called by other programmer setup commands when
+`\cond_id' and <pattern> have been read.
+\begin{packagecode}
+\def\mk_substr_cond #1{%% #1 pattern string
+ \endgroup \@namedef{\substr_cond \cond_id}##1#1##2&}
+\end{packagecode}
+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&'\]
+where `\csname' etc.\ render \lq`:<id>'\rq\ part of the macro name.
+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 `{<definition text>}'
+just as with primitive \TeX.
+
+
+\subsection{\hspace{1sp}\ignorespaces Set up sandboxes \unskip }
+
+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 <output> 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{<macro-name>}', such that
+`\WriteResult{\manysubstitutions{\fdInputLine}}'
+writes to <output> 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.
+
+`setup_substr_cond' is the name space for macros that build
+sandboxes and initialize arguments for conditional macros.
+\begin{packagecode}
+\def\setup_substr_cond{setup_substr_cond:}
+\end{packagecode}
+|\MakeSetupSubstringCondition{<id>}[<changes>]{<pattern>}{<more-args>}|
+% <- TODO allow `%' and ` ' for breaking code lines.
+---same <id>, <changes>, <pattern> as for
+`\MakeSubstringConditional' (this is bad, there may be
+|\MakeSubstringConditional*{<more-args>}|)---creates the
+% <- TODO: store args in \Make$\dots$Conditional
+corresponding sandbox, by default without tilde wrap.
+<more-args> may contain `{#1}' to store the string that was tested,
+also `{<id>}' for calling repetitions and `{<pattern>}' for screen
+or log informations.
+\begin{packagecode}
+\newcommand*{\MakeSetupSubstringCondition}{%
+ \afterassignment\mk_setup_substr_cond_san \def\cond_id}
+\newcommand*{\mk_setup_substr_cond_san}[1][]{%
+ \begingroup \PatternCodes #1\mk_setup_substr_cond}
+\end{packagecode}
+`\begingroup' |\mk_setup_substr_cond{<pattern>}{<more-args>}|
+can be directly called by other programmer setup commands after
+`\cond_id' and <pattern> have been read:
+\begin{packagecode}
+\def\mk_setup_substr_cond #1#2{%% #1 pattern string,
+ %% #2 additional arguments, e.g., `{#1}' to keep tested string
+ \endgroup
+ \expandafter \edef
+ \csname \setup_substr_cond \cond_id \endcsname ##1{%
+% \expandafter \noexpand
+% \csname \substr_cond \cond_id \endcsname %% 2009/04/10:
+ \make_not_expanding_cs{\substr_cond \cond_id}%
+\end{packagecode}
+By `\edef', the name of the substring conditional is stored here
+as a single token. The rest of the sandbox follows.
+\begin{packagecode}
+ ##1\noexpand~#1\dollar_tilde&#2}%
+ \let\dollar_tilde\sandbox_dollar}
+\end{packagecode}
+If a tilde `~' has been used instead of `$', the default
+is restored.
+\begin{packagecode}
+\def\sandbox_dollar{$}
+\let\dollar_tilde\sandbox_dollar
+\end{packagecode}
+The following general tool |\make_not_expanding_cs| has been used
+(many definitions in 'latex.ltx' could have used it): %% 2009/04/10
+\begin{packagecode}
+\def\make_not_expanding_cs#1{%
+ \expandafter \noexpand \csname #1\endcsname}
+\end{packagecode}
+
+\subsection{\hspace{1sp}\ignorespaces Getting rid of the tildes \unskip }
+
+|\let~\TildeGobbles| can be used to suppress dummy patterns
+(contained in <split2>)
+in `\write'ing or with `\edef'. $\dots$ will probably become obsolete
+$\dots$ however, it is helpful in that you needn't care
+whether there is a dummy wrap left at all. (2009/04/13)
+\begin{packagecode}
+\newcommand{\TildeGobbles}{} \def\TildeGobbles#1${}
+\end{packagecode}
+|\RemoveDummyPattern| is used to remove the dummy pattern
+\emph{immediately}, not waiting for `\write'ing
+or other ``total'' expansion: %% 2009/04/13
+\begin{packagecode}
+\newcommand{\RemoveDummyPattern}{} \def\RemoveDummyPattern#1~#2${#1}
+\end{packagecode}
+|\RemoveDummyPatternArg<macro>{<arg>}| executes
+`\RemoveDummyPattern' in the next argument:
+\begin{packagecode}
+\newcommand*{\RemoveDummyPatternArg}[2]{%
+ \expandafter #1\expandafter {\RemoveDummyPattern #2}}
+\end{packagecode}
+|\RemoveTilde| is used to remove the tilde that separated
+the dummy pattern from <split1>.
+\begin{packagecode}
+% %% An alternative policy is to pass
+% %% <target> (as an argument) to the parsing macro.
+\newcommand{\RemoveTilde}{} \def\RemoveTilde#1~{#1}
+\end{packagecode}
+|\RemoveTildeArg<macro>{<arg>}| executes `\RemoveTilde'
+in the next argument:
+\begin{packagecode}
+\newcommand*{\RemoveTildeArg}[2]{%
+ \expandafter #1\expandafter {\RemoveTilde #2}}
+\end{packagecode}
+
+\subsection{\hspace{1sp}\ignorespaces Calling conditionals \unskip }
+
+|\ProcessStringWith{<target-string>}{<id>}| builds the sandbox
+to search <target-string> for the <pattern> associated with the
+parser-conditional that is identified by <id>, the sandbox then
+calls the parser.
+\begin{packagecode}
+\newcommand*{\ProcessStringWith}[2]{%
+ \csname \setup_substr_cond #2\endcsname{#1}}
+\end{packagecode}
+|\ProcessExpandedWith{<string-macro>}{<id>}| does the same but with
+a \emph{macro} (like `\fdInputLine' or `\OutputString') in which
+the string to be tested is stored.
+\begin{packagecode}
+\newcommand*{\ProcessExpandedWith}[2]{%
+ \csname \setup_substr_cond #2\expandafter \endcsname
+ \expandafter{#1}}
+\end{packagecode}
+I would have preferred the reversed order of arguments which seems
+to be more natural, but the present is more efficient.
+Macros with reversed order are currently stored after `\endinput'
+in section~\ref{sec:pondered}, may be they once return.
+
+Anyway, most desired will be |\ProcessInputWith{<id>}| just
+applying to `\fdInputLine':
+\begin{packagecode}
+\newcommand*{\ProcessInputWith}[1]{%
+ \csname \setup_substr_cond #1\expandafter \endcsname
+ \expandafter{\fdInputLine}}
+\end{packagecode}
+(Definition almost copied for efficiency.)
+\begin{packagecode}
+ %% TODO: error when undefined 2009/04/07
+\end{packagecode}
+
+\subsection{\hspace{1sp}\ignorespaces Copy jobs \unskip }
+
+A job identifier <id> 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
+<input> file. %%% On a certain condition,
+|\CopyFDconditionFromTo{<id1>}{<id2>}|
+\emph{creates or redefines a sandbox builder} with identifier <id2>
+that afterwards behaves like the sandbox builder <id1>.
+So you can store a certain behaviour as <id1> in advance in order
+once to change the behaviour of <id2> into that of <id1>.
+\begin{packagecode}
+\newcommand*{\CopyFDconditionFromTo}[2]{%
+ \expandafter \let
+ \csname \setup_substr_cond #2\expandafter \endcsname
+ \csname \setup_substr_cond #1\endcsname}
+\end{packagecode}
+(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.''
+
+
+\section{\hspace{1sp}\ignorespaces Programming tools \unskip }
+
+
+\subsection{\hspace{1sp}\ignorespaces Tails of conditionals \unskip }
+
+\label{sec:tails}
+When creating complex \emph{expandable} conditionals,
+this may amount to have primitive `\if' $\dots$ `\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' $\dots$ `\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) on starting with `~'. E.g.,
+``#1~=~<split1> empty'' indicates that either the <pattern>
+starts a line or the line is empty altogether (this must be
+decided by another test).
+
+|\IfFDempty{<arg>}{<when-empty>}{<when-not-empty>}|
+is used to test <arg> on emptyness (without expanding it):
+\begin{packagecode}
+\newcommand*{\IfFDempty}[1]{%
+ \ifx$#1$\expandafter \@firstoftwo \else
+ \expandafter \@secondoftwo \fi}
+\end{packagecode}
+|\IfFDinputEmpty{<when-empty>}{<when-not-empty>}| is a variant of
+the previous to execute <when-empty> if the loop processing <input>
+finds an empty line---otherwise <when-not-empty>.
+\begin{packagecode}
+\newcommand*{\IfFDinputEmpty}{%
+ \ifx\fdInputLine\@empty \expandafter \@firstoftwo \else
+ \expandafter \@secondoftwo \fi}
+\end{packagecode}
+|\IfFDdollar{<arg>}{<when-empty>}{<when-not-empty>}|
+is another variant, testing <split2> for being `$',
+main indicator of there is a match anywhere in <target>
+(as opposed to starting or ending match):
+\begin{packagecode}
+\newcommand*{\IfFDdollar}[1]{%
+ \ifx$#1\expandafter \@firstoftwo \else
+ \expandafter \@secondoftwo \fi}
+\end{packagecode}
+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'\,$\dots$ (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 $\dots$
+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
+
+
+\subsection{\hspace{1sp}\ignorespaces Line counter \unskip }
+
+A \LaTeX\ counter |fdInputLine| may be useful for screen or log
+messages, moreover you can use it to control processing of the
+<input> 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 $\dots$ 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 <output>
+which have no counterpart in <input>---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.
+\begin{packagecode}
+\newcounter{fdInputLine}
+\end{packagecode}
+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
+\begin{packagecode}
+\newcommand*{\CountInputLines}{\global\advance\c@fdInputLine\@ne}
+\end{packagecode}
+At present %% 2009/04/07 TODO
+the counter is reset by `\ProcessFileWith', this may change.
+
+|\IfInputLine{<relation><number>}{<true>}{<false>}|, when called
+from the processing loop (second argument of `\ProcessFileWith')
+issues <true> commands if `\value{fdInputLine}<relation><number>'
+is true, otherwise <false>. <relation> may usually be just `='.
+\begin{packagecode}
+\newcommand*{\IfInputLine}[1]{%
+ \ifnum\c@fdInputLine#1\relax \expandafter \@firstoftwo
+ \else \expandafter \@secondoftwo \fi}
+\end{packagecode}
+
+\subsection{\hspace{1sp}\ignorespaces The ``identity job'' `LEAVE' \unskip }
+
+\label{sec:LEAVE}
+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:
+\begin{packagecode}
+\expandafter \let
+ \csname \setup_substr_cond LEAVE\endcsname \@firstofone
+\end{packagecode}
+I.e., `\ProcessStringWith{<string>}{LEAVE}' expands to <string>
+$\dots$ \ProcessStringWith{(Indeed!)}{LEAVE}
+
+
+\section{\hspace{1sp}\ignorespaces Setup for expandable chains of replacements \unskip }
+
+\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{<string>}}'\] renders `\OutputString'
+the result of applying a chain (sequence) of stringwise replacements
+to <string>.
+You can even write a transformed input <string> to a file
+without defining anything anything after `\read to'\,.\,.\,.
+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.
+
+|\repl_all_chain_expandable| will be the backbone of the
+replacements. It is called by some parsing macro <parser>
+and receives from the latter <split1>~=~#1 and <split2>~=~#2.
+#3 is the result of what happened so far.
+\begin{packagecode}
+\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
+\end{packagecode}
+The previous line would be somewhat faster, but let us exemplify
+`\IfFDdollar' from section~\ref{sec:tails} instead:
+\begin{packagecode}
+ \IfFDdollar{#2}%
+\end{packagecode}
+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 <pattern> from
+<parser> 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.
+\begin{packagecode}
+ {\RemoveTildeArg #6{#3#1}}%
+\end{packagecode}
+Otherwise $\dots$ the \emph{sandbox builder} <sandbox>
+(that will be shown below) that called <parser>
+initialized #5 to be that <parser> itself. (<parser> otherwise
+wouldn't know who it is.) So <parser> calls itself with another sandbox
+`#2&'. Note that #2 contains \lq`~<pattern>$'\rq\ due to the initial
+<sandbox> building.
+\begin{packagecode}
+ {#5#2&{#3#1#4}{#4}#5#6}}
+\end{packagecode}
+#4 is the replacement string that <sandbox> passed to <parse>.
+The first argument after the `&' is previous stuff plus
+the recently skipped <split1>
+plus #4 replacing the string <pattern> that was matched.
+
+Finally, #5 and #6 again ``recall'' <parser> and the sandbox
+builder to which to change in case of no other match.
+
+% TODO move following up!? 2009/04/11
+|\MakeExpandableAllReplacer{<id>}{<pattern>}{<replace>}{<id-next>}|
+creates sandbox and parser with common identifier <id> and search
+pattern <pattern>. Each occurrence of <pattern> will be replaced by
+<replace>. When <pattern> is not found, the sandbox builder for
+<id-next> 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}).
+\begin{packagecode}
+\newcommand*{\MakeExpandableAllReplacer}{%
+ \afterassignment\mk_setup_xpdbl_all_repl_san
+ \def\cond_id}
+\end{packagecode}
+$\dots$ usual intermezzo for reading patterns with non-standard
+category codes, this time we read \emph{two} patterns \dots
+\begin{packagecode}
+\newcommand*{\mk_setup_xpdbl_all_repl_san}[1][]{%
+ \begingroup \PatternCodes #1\mk_setup_xpdbl_all_repl}
+\end{packagecode}
+Here comes the real work.
+\begin{packagecode}
+\newcommand*{\mk_setup_xpdbl_all_repl}[3]{%
+ %% #1 pattern, #2 substitute, #3 pass to
+ \endgroup
+\end{packagecode}
+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
+\begin{packagecode}
+ \edef\@tempa{%
+ \noexpand\mk_setup_substr_cond{#1}{%
+ {}{#2}%
+ \noexpand\noexpand
+\end{packagecode}
+That `\edef\@tempa' must \emph{not expand} the controll
+words after they have been computed from `\csname' etc.
+Moreover, expansion of the parser commands
+must be avoided another time, when `\@tempa' is executed.
+\begin{packagecode}
+ \make_not_expanding_cs{\substr_cond\cond_id}%
+ \noexpand\noexpand
+ \make_not_expanding_cs{\setup_substr_cond #3}}}%
+\end{packagecode}
+Those internal setup commands start with `\endgroup' to switch back
+to standard category codes. We must match them here by
+`\begingroup'.
+\begin{packagecode}
+ \begingroup \@tempa
+ \begingroup \mk_substr_cond{#1}{%
+ \repl_all_chain_expandable{##1}{##2}}}
+\end{packagecode}
+The final command is the one that we explained first. %% TODO 2009/04/11
+
+Support for dozens of replacements in one sequence
+and for screen messages
+must wait for another release, sorry! %% TODO 2009/04/11
+
+
+\section{\hspace{1sp}\ignorespaces Leave package mode \unskip }
+
+We restore the underscore `_' for math subscripts.
+(This might better depend on something \dots) %% TODO 2009/04/07
+\begin{packagecode}
+\catcode`\_=8 %% restores underscore use for subscripts
+
+\endinput
+\end{packagecode}
+\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'.
+
+
+\section{\hspace{1sp}\ignorespaces Pondered \unskip }
+
+\label{sec:pondered}
+\begin{packagecode}
+ %% 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}}}
+\end{packagecode}
+
+\section{\hspace{1sp}\ignorespaces VERSION HISTORY \unskip }
+
+
+\begin{packagecode}
+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
+ (<str1><str2><str1> in <str1><str2>)
+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@
+
+\end{packagecode}