diff options
author | Karl Berry <karl@freefriends.org> | 2012-03-29 23:20:23 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-03-29 23:20:23 +0000 |
commit | 84c2b4bf9bf9fa99638f75dd5c81041d7e8705cf (patch) | |
tree | 08001c80f59e16e691575822fde1669bf8fccc44 /Master/texmf-dist/tex/generic/bitelist | |
parent | 9fc033895f0466fc3ad09b515d588d61ea42f960 (diff) |
new generic package bitelist (29mar12)
git-svn-id: svn://tug.org/texlive/trunk@25779 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/bitelist')
-rw-r--r-- | Master/texmf-dist/tex/generic/bitelist/bitedemo.tex | 43 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/bitelist/bitelist.sty | 240 |
2 files changed, 283 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/bitelist/bitedemo.tex b/Master/texmf-dist/tex/generic/bitelist/bitedemo.tex new file mode 100644 index 00000000000..6c4f9ed1038 --- /dev/null +++ b/Master/texmf-dist/tex/generic/bitelist/bitedemo.tex @@ -0,0 +1,43 @@ +\def\filename{bitedemo.tex} \def\filedate{2012/03/29} +\def\fileinfo{demonstrating/testing bitelist.sty (UL)} +\expandafter\ifx\csname ProvidesPackage\endcsname\relax \else + \edef\bitedemolatexstart{% + \noexpand\ProvidesFile{\filename}% + [\filedate\space\fileinfo]% + \noexpand\RequirePackage{bitelist}} + \expandafter\bitedemolatexstart +\fi +\ifx\BiteMakeIf\undefined \input bitelist.sty \fi +\ifx\typeout\undefined + \def\typeout{\immediate\write17} + \newlinechar`^^J +\fi +\def\splitted #1#2#3{>>#1|#2|#3<<} +\def\unsplitted#1{>>#1<<} +\def\spacetocomma#1#2{>>#1,#2<<} +\BiteMakeIfOnly {\def}{\occursyesno}{no} +\BiteMakeIf {\def}{\noshowsplit}{no} +\BiteMakeIfBraces{\def}{\noShowSplit}{no} +\typeout{^^J + \BiteFindByIn {no}{\occursyesno} + {bonobo}{YES!}{NO!} + \BiteFindByIn {no}{\noshowsplit} + {bonobo}{bonobo}{\splitted}{\unsplitted} + \BiteFindByInIn{no}{\noshowsplit} + {bonobo}{\splitted}{\unsplitted} + ^^J + \BiteFindByIn {no}{\occursyesno} + {bobobo}{YES!}{NO!} + \BiteFindByIn {no}{\noshowsplit} + {bobobo}{bobobo}{\splitted}{\unsplitted} + \BiteFindByInIn{no}{\noshowsplit} + {bobobo}{\splitted}{\unsplitted} + ^^J + \BiteFindByInBraces{no}{\noShowSplit} + {{bo}no{bo}}{\splitted}{\unsplitted} + ^^J + \BiteGetNextWord{bo no bo}{\spacetocomma}{\unsplitted} + \BiteGetNextWord{bo nobo} {\spacetocomma}{\unsplitted} + \BiteGetNextWord{bonobo} {\spacetocomma}{\unsplitted} + ^^J} +\endinput diff --git a/Master/texmf-dist/tex/generic/bitelist/bitelist.sty b/Master/texmf-dist/tex/generic/bitelist/bitelist.sty new file mode 100644 index 00000000000..219008d6938 --- /dev/null +++ b/Master/texmf-dist/tex/generic/bitelist/bitelist.sty @@ -0,0 +1,240 @@ +\def\filename{bitelist} \def\filedate{2012/03/29} +\def\fileversion{v0.1} \def\fileinfo{split lists in TeX's mouth (UL)} +%% Copyright (C) 2012 Uwe Lueck, +%% http://www.contact-ednotes.sty.de.vu +%% -- author-maintained in the sense of LPPL below -- +%% +%% 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 +%% There is NO WARRANTY - this rather is somewhat experimental. +%% +%% Please report bugs, problems, and suggestions via +%% +%% http://www.contact-ednotes.sty.de.vu +%% +%% === Proceeding without \LaTeX === +%% Some tricks from Bernd Raichle's \CtanPkgRef{ngerman}{ngerman.sty}---I +%% need \LaTeX's `\Provides'\-`Package' for \ctanpkgref{fileinfo}, +%% my package version tools. With 'readprov.sty', it issues `\endinput', +%% close conditional before: +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname ProvidesPackage\endcsname\relax \else + \edef\fileinfo{\noexpand\ProvidesPackage{\filename}% + [\filedate\space \fileversion\space \fileinfo]} + \expandafter\fileinfo +\fi +\chardef\atcode=\catcode`\@ +\catcode`\@=11 % \makeatletter +%% Providing \LaTeX's `\@firstoftwo' and `\@secondoftwo': +\long\def\@firstoftwo #1#2{#1} +\long\def\@secondoftwo#1#2{#2} +%% +%% === Basic Parsing (No Braces) === +%% +%% |\BiteMake{<def>}{<cmd>}{<find>}| provides the parameter text +%% (\TeX book p.~203) for defining (by <def>) a macro <cmd> that will +%% search for <find>: +\def\BiteMake#1#2#3{#1#2##1#3##2\BiteSep##3\BiteStop} +%% With |\BiteFindByIn{<find>}{<cmd>}{<list>}|, +%% you can use a <cmd> (perhaps defined by &\BiteMake) +%% in order to search <find> in <list>. +%% This is expandable as promised: +\def\BiteFindByIn#1#2#3{% + #2#3\BiteSep#1\BiteCrit\BiteSep\BiteStop} +%% Preparing a possible &\edef as <def>: +\let\BiteSep\relax \let\BiteStop\relax +%% And this is important in any case for correct testing of +%% occurrence:\footnote{The idea for the ``funny `Q'" +%% is from the \ctanpkgref{ifmtarg} package.} +\catcode`\Q=7 \let\BiteCrit=Q \catcode`\Q=11 +%% Perhaps you could increase safety of tests by using something similar to the funny `Q' +%% for &\BiteSep and &\BiteStop. +%% %% 2012/03/28: +%% However, this would additionally require reimplementation of +%% the macros for keeping braces (Section~\ref{sec:braces}) using `\edef'. +%% % It appears to me, however, that expandable tests like this one +%% % never are perfectly safe; you only can say that it is safe with a +%% % source meeting certain conditions. \ctanpkgref{fifinddo} originally +%% % was made for ``plain text," to be read from files without assigning +%% % \TeX's special category codes. \emph{Here} we assume that the source +%% % (text in \cs{Provides.\empty..} arguments) will never contain such a +%% % ``funny `Q'". +%% +%% === Simple Conditionals === +%% By |\BiteMakeIfOnly{<def>}{<cmd>}{<find>}|, you can make a command <cmd> +%% that with +%% \[|\BiteFindByIn{<find>}{<cmd>}{<list>}{<yes>}{<no>}|\] +%% chooses <yes> if <find> occurs in <list> and <no> otherwise. +\def\BiteMakeIfOnly#1#2#3{\BiteMake{#1}{#2}{#3}{\BiteIfCrit{##2}}} +%% |\BiteIfCrit{<suffix>}{<yes>}{<no>}| +%% is the basic test for occurrence of <find> in <list>: +\def\BiteIfCrit#1{\ifx\BiteCrit#1\expandafter\@secondoftwo +%% If <cmd>'s second argument---same as &\BiteIfCrit's first argument---is +%% empty, &\BiteCrit is compared with &\expandafter, so <yes> is chosen. +%% That is correct, it happens when <find> is a suffix of <list>. + \else \expandafter\@firstoftwo \fi } +%% +%% === Passing Results Completely---No Braces === +%% So the previous `\BiteMakeIfOnly' generates pure tests on occurrence, +%% giving away information about prefix and suffix. +%% It may be considered a didactical step fostering understanding of the following. +%% % \medskip\noindent +%% % ** Generic Fundamental Splitter---No Braces ** +%% %% Wrong: +%% % With the above `\BiteMakeIfOnly', the user can choose on her own +%% % information about the composition of <list> to use. +%% % Perhaps it is not easy to understand. +%% % `\BiteMakeIfOnlySplit{<def>}{<cmd>}{<find>}' by contrast, +%% % should satisfy ``all needs" by providing \emph{all} the information +%% % about splitting a <list>. It may also be a template for using +%% % `\BiteMakeIfOnly'. +%% When, by contrast \[|\BiteMakeIf{<def>}{<cmd>}{<find>}|\] +%% has been issued, a later +%% $$|\BiteFindByIn{<find>}{<cmd>}{<list>}{<list>}{<yes>}{<no>}|\eqno(*)$$ +%% will expand to +%% \[`<yes>{<prefix>}{<find>}{<suffix>}'\] +%% if <list> is composed as <prefix><find><suffix> +%% and <prefix> is the shortest $\alpha$ such that there is some $\beta$ +%% with $<list>=\alpha<find>\beta$. Otherwise, $(*)$ will expand to +%% \[`<no>{<list>}'\] +%% This gives all the information available. +%% For actual applications, it may be too much, and the macro programmer +%% may do something in between of `\BiteMakeIfOnly' and `\BiteMakeIf': +\def\BiteMakeIf#1#2#3{% + \BiteMake{#1}{#2}{#3}##4##5##6{% +%% In the replacement text, we first do the same as with `\BiteMakeIfOnly': + \BiteIfCrit{##2}% +%% What follows is new. <cmd>'s third argument is ignored. +%% The fourth keeps the original <list>. +%% <yes> is <cmd>'s fifth and <no> is its sixth argument. + {##5{##1}{#3}{##2}}% %% if #3 in ##4 + {##6{##4}}% %% otherwise + }% +} +%% In $(*)$, <list> has been doubled. That was no mistake. +%% It is due to a shortcoming of `\BiteFindByIn'. +%% With +%% \[|\BiteFindByInIn{<find>}{<cmd>}{<list>}{<yes>}{<no>}|\] +%% you get the same result as with $(*)$: +\def\BiteFindByInIn#1#2#3{\BiteFindByIn{#1}{#2}{#3}{#3}} +%% TODO not sure about command names yet +%% +%% == Example Applications == +%% === Splitting at Space === +%% \label{sec:space} +%% This work actually arose from modifying `\GetFileInfo' +%% as provided by \LaTeX's \ctanpkgref{doc} package +%% so that it would deal reasonably with ``incomplete" file info---for +%% the \ctanpkgref{nicefilelist} package. +%% `\GetFileInfo' works best when the file info contains +%% at least \emph{two} blank spaces. But how many are there indeed?---And +%% I wanted to do it \emph{expandably:} while `\GetFileInfo' issues +%% \emph{definitions} of `\filedate', `\fileversion', and `\fileinfo', +%% date, version, and info should be passed as \emph{macro arguments}. +%% \medbreak\noindent +%% |\BiteIfSpace| tries splitting at the next blank space passes results: +\BiteMake{\def}{\BiteIfSpace}{ }#4#5#6{% + \BiteIfCrit{#2}{#5{#1}{#2}}{#6{#4}}} +%% The difference to the `\BiteMakeIf' construction is that we do not +%% pass <find>, the space---it's not essential. +%% (TODO names may change ...) +%% +%% Now \[|\BiteFindByInIn{ }{\BiteIfSpace}{<list>}{<yes>}{<no>}|\] +%% will pass prefix/suffix to <yes> or <list> to <no>. +%% If this is needed frequently, here is a shorthand +%% |\BiteGetNextWord{<list>}{<yes>}{<no>}|: +\def\BiteGetNextWord{\BiteFindByInIn{ }\BiteIfSpace} +%% See a test in `bitedemo.tex' (Section~\ref{sec:demo}). +%% +%% === Splitting at Comma === +%% ... left as an exercise to the reader ... +%% +%% == Keeping Braces: Reasoning == +%% \label{sec:braces} +%% Now we want to generalize task (Section~\ref{sec:task}) +%% and solution (Section~\ref{sec:trick}) for the case that +%% $\tau=<list>$ has (balanced) braces +%% (with category codes for argument delimiters), +%% while $\sigma=<find>$ still has not (does not work with our method). +%% So with $\tau=\alpha\sigma\beta$, +%% $\alpha$ (``prefix") or $\beta$ (``suffix") or both +%% may contain braces. But we consider another restriction: +%% braces must be balanced in $\alpha$ and in $\beta$, +%% we don't try parsing inside braces +%% (as opposed to the search for asterisks in Appendix~D +%% of The~\TeX book). +%% +%% According to \TeX book p.~204, when a macro <cmd> finds an argument +%% formed as `{<tokens>}', in <cmd>'s replacement text only <tokens> +%% is used, i.e., outer braces are removed. +%% So when $\alpha=`{<tokens>}'$, a parser <cmd> as defined by our +%% methods above will return <tokens> instead of `{<tokens>}'---likewise +%% for $\beta$. We are now trying to \emph{keep} outer braces in prefix/suffix +%% by a more elaborate method. +%% +%% The idea is to present $\tau=<list>$ with context\footnote{Perhaps +%% I am confusing `&\empty' and the token list containing just `&\empty' here?} +%% \[`<cmd>\empty<list><stop><sep><find><crit><sep><stop>'\] +%% or in the notation of Section~\ref{sec:trick} +%% \[`<cmd>\empty'\tau\theta\zeta\sigma\rho\zeta\theta\] +%% Then, if <find> occurs in <list>, we must remove the `\empty' +%% from the prefix that we get with the earlier method (easy) +%% and <stop> from the suffix (tricky, similar problem recurs). +%% Using old $\theta$ for a new purpose works here because +%% <cmd> will look for $\theta$ only when it has found $\zeta$ before. +%% +%% Mere testing for occurrence is not affected. +%% \[`\BiteMakeIfOnly' \quad \mbox{and} \quad `\BiteFindByIn'\] +%% still can be used. +%% We provide an improved version of +%% \[`\BiteMakeIf' \quad (`\BiteMakeIfBraces')\] and of +%% \[`\BiteFindInIn' \quad (`\BiteFindInBraces').\] +%% +%% == Implementation Part II == +%% === Keeping Braces === +%% \[|\BiteFindByInBraces{<find>}{<cmd>}{<list>}{<yes>}{<no>}|\] +%% varies `\BiteFindByInIn' according to the previous: +\def\BiteFindByInBraces#1#2#3{% + #2\empty#3\BiteStop\BiteSep#1\BiteCrit\BiteSep\BiteStop{#3}} +%% Such a <cmd> can be made by |\BiteMakeIfBraces{<def>}{<cmd>}{<find>}|: +\def\BiteMakeIfBraces#1#2#3{% + \BiteMake{#1}{#2}{#3}##4##5##6{% + \BiteIfCrit{##2}% +%% <no> works as before. For <yes>, first the `\empty' in the prefix +%% is expanded for vanishing. +%% `\BiteTidyI' and `\BiteTidyII' continue tidying. + {\expandafter \BiteTidyI %% if #3 in ##4 + \expandafter{##1}% %% prefix +%% Another `\empty' avoids that removal of `\BiteStop' in suffix +%% by `\BiteTideII' removes outer braces: + {\BiteTidyII\empty##2}% %% suffix + {#3}% %% find + {##5}}% %% yes + {##6{##4}}% %% otherwise + }% +} +%% |\BiteTidyI{<prefix>}{<suffix>}| \ first expands `\BiteTidyII' +%% for removing `\BiteStop' in <suffix>. +%% `\empty' from `\BiteFindByInBraces' remains and is expanded next +%% for vanishing. Finally, `\BiteTidied' reorders arguments +%% for operation of <yes>: +\def\BiteTidyI#1#2{% + \expandafter\expandafter\expandafter \BiteTidied + \expandafter\expandafter\expandafter {#2}{#1}} +\def\BiteTidyII#1\BiteStop{#1} +\def\BiteTidied#1#2#3#4{#4{#2}{#3}{#1}} +%% +%% === Leaving the Package File === +\catcode`\@=\atcode +\endinput +%% +%% === VERSION HISTORY === + +v0.1 2012/03/26 started + 2012/03/27 continued, restructured + 2012/03/28 continued, separate sections for "Mere Occurrence" + vs. ...; keeping braces, \BiteIfCrit + 2012/03/29 proceeding without LaTeX corrected, restructured |