summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-12-09 03:02:14 +0000
committerNorbert Preining <norbert@preining.info>2020-12-09 03:02:14 +0000
commit6c3488e145a5b86adaa393a1282b0af6fa355f4a (patch)
treea7d012c2f7548dfb76d383126f5007df22db0c7e /macros
parent2d234d1cf6b222448569c5e7596c7f835fd54bd2 (diff)
CTAN sync 202012090302
Diffstat (limited to 'macros')
-rw-r--r--macros/latex/contrib/decision-table/LICENSE415
-rw-r--r--macros/latex/contrib/decision-table/README12
-rw-r--r--macros/latex/contrib/decision-table/decision-table-doc.pdfbin262752 -> 0 bytes
-rw-r--r--macros/latex/contrib/decision-table/decision-table-doc.tex209
-rw-r--r--macros/latex/contrib/decision-table/decision-table.dtx474
-rw-r--r--macros/latex/contrib/decision-table/decision-table.ins47
-rw-r--r--macros/latex/contrib/decision-table/decision-table.pdfbin0 -> 112176 bytes
-rw-r--r--macros/latex/contrib/decision-table/decision-table.sty149
-rw-r--r--macros/latex/contrib/draftwatermark/README.md32
-rw-r--r--macros/latex/contrib/draftwatermark/draftwatermark.dtx583
-rw-r--r--macros/latex/contrib/draftwatermark/draftwatermark.ins52
-rw-r--r--macros/latex/contrib/draftwatermark/draftwatermark.pdfbin264619 -> 297379 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/README2
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/lecturebib-english.pdfbin85104 -> 85100 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/lecturehandout-english.pdfbin57923 -> 57920 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/lecturepresentation-english.pdfbin84606 -> 84600 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/lectureprogram-english.pdfbin56905 -> 56906 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/lecturescript-english.pdfbin34575 -> 34578 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/membertable-blank-english.pdfbin28442 -> 28442 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/membertable-filled-english.pdfbin28450 -> 28449 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/presencetable-blank-english.pdfbin27974 -> 27971 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/presencetable-filled-english.pdfbin26752 -> 26749 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/English/presentation-list-english.pdfbin25688 -> 25685 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/lecturebib.pdfbin85488 -> 85483 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/lecturehandout.pdfbin59148 -> 59144 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/lecturepresentation.pdfbin84992 -> 84982 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/lectureprogram.pdfbin57899 -> 57898 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/lecturescript.pdfbin34772 -> 34769 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/membertable-blank.pdfbin28387 -> 28386 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/membertable-filled.pdfbin28509 -> 28506 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/presencetable-blank.pdfbin27896 -> 27891 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/presencetable-filled.pdfbin26784 -> 26778 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/examples/German/presentation-list.pdfbin26864 -> 26863 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/jslectureplanner.pdfbin478838 -> 480426 bytes
-rw-r--r--macros/latex/contrib/jslectureplanner/jslectureplanner.sty33
-rw-r--r--macros/latex/contrib/jslectureplanner/jslectureplanner.tex32
-rw-r--r--macros/latex/contrib/jslectureplanner/jsmembertable.sty4
-rw-r--r--macros/latex/contrib/microtype/README.md5
-rw-r--r--macros/latex/contrib/microtype/microtype-utf.dtx7
-rw-r--r--macros/latex/contrib/microtype/microtype.dtx922
-rw-r--r--macros/latex/contrib/microtype/microtype.ins2
-rw-r--r--macros/latex/contrib/microtype/microtype.pdfbin1694528 -> 1786700 bytes
-rw-r--r--macros/latex/contrib/stringstrings/stringstrings.dtx8771
-rw-r--r--macros/latex/contrib/stringstrings/stringstrings.ins12
-rw-r--r--macros/latex/contrib/stringstrings/stringstrings.pdfbin436700 -> 425249 bytes
-rw-r--r--macros/unicodetex/latex/polyglossia/README.md2
-rw-r--r--macros/unicodetex/latex/polyglossia/polyglossia.dtx219
-rw-r--r--macros/unicodetex/latex/polyglossia/polyglossia.pdfbin279219 -> 280545 bytes
48 files changed, 6195 insertions, 5789 deletions
diff --git a/macros/latex/contrib/decision-table/LICENSE b/macros/latex/contrib/decision-table/LICENSE
deleted file mode 100644
index 4db9b5af29..0000000000
--- a/macros/latex/contrib/decision-table/LICENSE
+++ /dev/null
@@ -1,415 +0,0 @@
-The LaTeX Project Public License
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-LPPL Version 1.3c 2008-05-04
-
-Copyright 1999 2002-2008 LaTeX3 Project
- Everyone is allowed to distribute verbatim copies of this
- license document, but modification of it is not allowed.
-
-
-PREAMBLE
-========
-
-The LaTeX Project Public License (LPPL) is the primary license under
-which the LaTeX kernel and the base LaTeX packages are distributed.
-
-You may use this license for any work of which you hold the copyright
-and which you wish to distribute. This license may be particularly
-suitable if your work is TeX-related (such as a LaTeX package), but
-it is written in such a way that you can use it even if your work is
-unrelated to TeX.
-
-The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE',
-below, gives instructions, examples, and recommendations for authors
-who are considering distributing their works under this license.
-
-This license gives conditions under which a work may be distributed
-and modified, as well as conditions under which modified versions of
-that work may be distributed.
-
-We, the LaTeX3 Project, believe that the conditions below give you
-the freedom to make and distribute modified versions of your work
-that conform with whatever technical specifications you wish while
-maintaining the availability, integrity, and reliability of
-that work. If you do not see how to achieve your goal while
-meeting these conditions, then read the document `cfgguide.tex'
-and `modguide.tex' in the base LaTeX distribution for suggestions.
-
-
-DEFINITIONS
-===========
-
-In this license document the following terms are used:
-
- `Work'
- Any work being distributed under this License.
-
- `Derived Work'
- Any work that under any applicable law is derived from the Work.
-
- `Modification'
- Any procedure that produces a Derived Work under any applicable
- law -- for example, the production of a file containing an
- original file associated with the Work or a significant portion of
- such a file, either verbatim or with modifications and/or
- translated into another language.
-
- `Modify'
- To apply any procedure that produces a Derived Work under any
- applicable law.
-
- `Distribution'
- Making copies of the Work available from one person to another, in
- whole or in part. Distribution includes (but is not limited to)
- making any electronic components of the Work accessible by
- file transfer protocols such as FTP or HTTP or by shared file
- systems such as Sun's Network File System (NFS).
-
- `Compiled Work'
- A version of the Work that has been processed into a form where it
- is directly usable on a computer system. This processing may
- include using installation facilities provided by the Work,
- transformations of the Work, copying of components of the Work, or
- other activities. Note that modification of any installation
- facilities provided by the Work constitutes modification of the Work.
-
- `Current Maintainer'
- A person or persons nominated as such within the Work. If there is
- no such explicit nomination then it is the `Copyright Holder' under
- any applicable law.
-
- `Base Interpreter'
- A program or process that is normally needed for running or
- interpreting a part or the whole of the Work.
-
- A Base Interpreter may depend on external components but these
- are not considered part of the Base Interpreter provided that each
- external component clearly identifies itself whenever it is used
- interactively. Unless explicitly specified when applying the
- license to the Work, the only applicable Base Interpreter is a
- `LaTeX-Format' or in the case of files belonging to the
- `LaTeX-format' a program implementing the `TeX language'.
-
-
-
-CONDITIONS ON DISTRIBUTION AND MODIFICATION
-===========================================
-
-1. Activities other than distribution and/or modification of the Work
-are not covered by this license; they are outside its scope. In
-particular, the act of running the Work is not restricted and no
-requirements are made concerning any offers of support for the Work.
-
-2. You may distribute a complete, unmodified copy of the Work as you
-received it. Distribution of only part of the Work is considered
-modification of the Work, and no right to distribute such a Derived
-Work may be assumed under the terms of this clause.
-
-3. You may distribute a Compiled Work that has been generated from a
-complete, unmodified copy of the Work as distributed under Clause 2
-above, as long as that Compiled Work is distributed in such a way that
-the recipients may install the Compiled Work on their system exactly
-as it would have been installed if they generated a Compiled Work
-directly from the Work.
-
-4. If you are the Current Maintainer of the Work, you may, without
-restriction, modify the Work, thus creating a Derived Work. You may
-also distribute the Derived Work without restriction, including
-Compiled Works generated from the Derived Work. Derived Works
-distributed in this manner by the Current Maintainer are considered to
-be updated versions of the Work.
-
-5. If you are not the Current Maintainer of the Work, you may modify
-your copy of the Work, thus creating a Derived Work based on the Work,
-and compile this Derived Work, thus creating a Compiled Work based on
-the Derived Work.
-
-6. If you are not the Current Maintainer of the Work, you may
-distribute a Derived Work provided the following conditions are met
-for every component of the Work unless that component clearly states
-in the copyright notice that it is exempt from that condition. Only
-the Current Maintainer is allowed to add such statements of exemption
-to a component of the Work.
-
- a. If a component of this Derived Work can be a direct replacement
- for a component of the Work when that component is used with the
- Base Interpreter, then, wherever this component of the Work
- identifies itself to the user when used interactively with that
- Base Interpreter, the replacement component of this Derived Work
- clearly and unambiguously identifies itself as a modified version
- of this component to the user when used interactively with that
- Base Interpreter.
-
- b. Every component of the Derived Work contains prominent notices
- detailing the nature of the changes to that component, or a
- prominent reference to another file that is distributed as part
- of the Derived Work and that contains a complete and accurate log
- of the changes.
-
- c. No information in the Derived Work implies that any persons,
- including (but not limited to) the authors of the original version
- of the Work, provide any support, including (but not limited to)
- the reporting and handling of errors, to recipients of the
- Derived Work unless those persons have stated explicitly that
- they do provide such support for the Derived Work.
-
- d. You distribute at least one of the following with the Derived Work:
-
- 1. A complete, unmodified copy of the Work;
- if your distribution of a modified component is made by
- offering access to copy the modified component from a
- designated place, then offering equivalent access to copy
- the Work from the same or some similar place meets this
- condition, even though third parties are not compelled to
- copy the Work along with the modified component;
-
- 2. Information that is sufficient to obtain a complete,
- unmodified copy of the Work.
-
-7. If you are not the Current Maintainer of the Work, you may
-distribute a Compiled Work generated from a Derived Work, as long as
-the Derived Work is distributed to all recipients of the Compiled
-Work, and as long as the conditions of Clause 6, above, are met with
-regard to the Derived Work.
-
-8. The conditions above are not intended to prohibit, and hence do not
-apply to, the modification, by any method, of any component so that it
-becomes identical to an updated version of that component of the Work as
-it is distributed by the Current Maintainer under Clause 4, above.
-
-9. Distribution of the Work or any Derived Work in an alternative
-format, where the Work or that Derived Work (in whole or in part) is
-then produced by applying some process to that format, does not relax or
-nullify any sections of this license as they pertain to the results of
-applying that process.
-
-10. a. A Derived Work may be distributed under a different license
- provided that license itself honors the conditions listed in
- Clause 6 above, in regard to the Work, though it does not have
- to honor the rest of the conditions in this license.
-
- b. If a Derived Work is distributed under a different license, that
- Derived Work must provide sufficient documentation as part of
- itself to allow each recipient of that Derived Work to honor the
- restrictions in Clause 6 above, concerning changes from the Work.
-
-11. This license places no restrictions on works that are unrelated to
-the Work, nor does this license place any restrictions on aggregating
-such works with the Work by any means.
-
-12. Nothing in this license is intended to, or may be used to, prevent
-complete compliance by all parties with all applicable laws.
-
-
-NO WARRANTY
-===========
-
-There is no warranty for the Work. Except when otherwise stated in
-writing, the Copyright Holder provides the Work `as is', without
-warranty of any kind, either expressed or implied, including, but not
-limited to, the implied warranties of merchantability and fitness for a
-particular purpose. The entire risk as to the quality and performance
-of the Work is with you. Should the Work prove defective, you assume
-the cost of all necessary servicing, repair, or correction.
-
-In no event unless required by applicable law or agreed to in writing
-will The Copyright Holder, or any author named in the components of the
-Work, or any other party who may distribute and/or modify the Work as
-permitted above, be liable to you for damages, including any general,
-special, incidental or consequential damages arising out of any use of
-the Work or out of inability to use the Work (including, but not limited
-to, loss of data, data being rendered inaccurate, or losses sustained by
-anyone as a result of any failure of the Work to operate with any other
-programs), even if the Copyright Holder or said author or said other
-party has been advised of the possibility of such damages.
-
-
-MAINTENANCE OF THE WORK
-=======================
-
-The Work has the status `author-maintained' if the Copyright Holder
-explicitly and prominently states near the primary copyright notice in
-the Work that the Work can only be maintained by the Copyright Holder
-or simply that it is `author-maintained'.
-
-The Work has the status `maintained' if there is a Current Maintainer
-who has indicated in the Work that they are willing to receive error
-reports for the Work (for example, by supplying a valid e-mail
-address). It is not required for the Current Maintainer to acknowledge
-or act upon these error reports.
-
-The Work changes from status `maintained' to `unmaintained' if there
-is no Current Maintainer, or the person stated to be Current
-Maintainer of the work cannot be reached through the indicated means
-of communication for a period of six months, and there are no other
-significant signs of active maintenance.
-
-You can become the Current Maintainer of the Work by agreement with
-any existing Current Maintainer to take over this role.
-
-If the Work is unmaintained, you can become the Current Maintainer of
-the Work through the following steps:
-
- 1. Make a reasonable attempt to trace the Current Maintainer (and
- the Copyright Holder, if the two differ) through the means of
- an Internet or similar search.
-
- 2. If this search is successful, then enquire whether the Work
- is still maintained.
-
- a. If it is being maintained, then ask the Current Maintainer
- to update their communication data within one month.
-
- b. If the search is unsuccessful or no action to resume active
- maintenance is taken by the Current Maintainer, then announce
- within the pertinent community your intention to take over
- maintenance. (If the Work is a LaTeX work, this could be
- done, for example, by posting to comp.text.tex.)
-
- 3a. If the Current Maintainer is reachable and agrees to pass
- maintenance of the Work to you, then this takes effect
- immediately upon announcement.
-
- b. If the Current Maintainer is not reachable and the Copyright
- Holder agrees that maintenance of the Work be passed to you,
- then this takes effect immediately upon announcement.
-
- 4. If you make an `intention announcement' as described in 2b. above
- and after three months your intention is challenged neither by
- the Current Maintainer nor by the Copyright Holder nor by other
- people, then you may arrange for the Work to be changed so as
- to name you as the (new) Current Maintainer.
-
- 5. If the previously unreachable Current Maintainer becomes
- reachable once more within three months of a change completed
- under the terms of 3b) or 4), then that Current Maintainer must
- become or remain the Current Maintainer upon request provided
- they then update their communication data within one month.
-
-A change in the Current Maintainer does not, of itself, alter the fact
-that the Work is distributed under the LPPL license.
-
-If you become the Current Maintainer of the Work, you should
-immediately provide, within the Work, a prominent and unambiguous
-statement of your status as Current Maintainer. You should also
-announce your new status to the same pertinent community as
-in 2b) above.
-
-
-WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE
-======================================================
-
-This section contains important instructions, examples, and
-recommendations for authors who are considering distributing their
-works under this license. These authors are addressed as `you' in
-this section.
-
-Choosing This License or Another License
-----------------------------------------
-
-If for any part of your work you want or need to use *distribution*
-conditions that differ significantly from those in this license, then
-do not refer to this license anywhere in your work but, instead,
-distribute your work under a different license. You may use the text
-of this license as a model for your own license, but your license
-should not refer to the LPPL or otherwise give the impression that
-your work is distributed under the LPPL.
-
-The document `modguide.tex' in the base LaTeX distribution explains
-the motivation behind the conditions of this license. It explains,
-for example, why distributing LaTeX under the GNU General Public
-License (GPL) was considered inappropriate. Even if your work is
-unrelated to LaTeX, the discussion in `modguide.tex' may still be
-relevant, and authors intending to distribute their works under any
-license are encouraged to read it.
-
-A Recommendation on Modification Without Distribution
------------------------------------------------------
-
-It is wise never to modify a component of the Work, even for your own
-personal use, without also meeting the above conditions for
-distributing the modified component. While you might intend that such
-modifications will never be distributed, often this will happen by
-accident -- you may forget that you have modified that component; or
-it may not occur to you when allowing others to access the modified
-version that you are thus distributing it and violating the conditions
-of this license in ways that could have legal implications and, worse,
-cause problems for the community. It is therefore usually in your
-best interest to keep your copy of the Work identical with the public
-one. Many works provide ways to control the behavior of that work
-without altering any of its licensed components.
-
-How to Use This License
------------------------
-
-To use this license, place in each of the components of your work both
-an explicit copyright notice including your name and the year the work
-was authored and/or last substantially modified. Include also a
-statement that the distribution and/or modification of that
-component is constrained by the conditions in this license.
-
-Here is an example of such a notice and statement:
-
- %% pig.dtx
- %% Copyright 2005 M. Y. Name
- %
- % This work may be distributed and/or modified under the
- % conditions of the LaTeX Project Public License, either version 1.3
- % of this license or (at your option) any later version.
- % The latest version of this license is in
- % http://www.latex-project.org/lppl.txt
- % and version 1.3 or later is part of all distributions of LaTeX
- % version 2005/12/01 or later.
- %
- % This work has the LPPL maintenance status `maintained'.
- %
- % The Current Maintainer of this work is M. Y. Name.
- %
- % This work consists of the files pig.dtx and pig.ins
- % and the derived file pig.sty.
-
-Given such a notice and statement in a file, the conditions
-given in this license document would apply, with the `Work' referring
-to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being
-generated from `pig.dtx' using `pig.ins'), the `Base Interpreter'
-referring to any `LaTeX-Format', and both `Copyright Holder' and
-`Current Maintainer' referring to the person `M. Y. Name'.
-
-If you do not want the Maintenance section of LPPL to apply to your
-Work, change `maintained' above into `author-maintained'.
-However, we recommend that you use `maintained', as the Maintenance
-section was added in order to ensure that your Work remains useful to
-the community even when you can no longer maintain and support it
-yourself.
-
-Derived Works That Are Not Replacements
----------------------------------------
-
-Several clauses of the LPPL specify means to provide reliability and
-stability for the user community. They therefore concern themselves
-with the case that a Derived Work is intended to be used as a
-(compatible or incompatible) replacement of the original Work. If
-this is not the case (e.g., if a few lines of code are reused for a
-completely different task), then clauses 6b and 6d shall not apply.
-
-
-Important Recommendations
--------------------------
-
- Defining What Constitutes the Work
-
- The LPPL requires that distributions of the Work contain all the
- files of the Work. It is therefore important that you provide a
- way for the licensee to determine which files constitute the Work.
- This could, for example, be achieved by explicitly listing all the
- files of the Work near the copyright notice of each file or by
- using a line such as:
-
- % This work consists of all files listed in manifest.txt.
-
- in that place. In the absence of an unequivocal list it might be
- impossible for the licensee to determine what is considered by you
- to comprise the Work and, in such a case, the licensee would be
- entitled to make reasonable conjectures as to which files comprise
- the Work.
diff --git a/macros/latex/contrib/decision-table/README b/macros/latex/contrib/decision-table/README
index 48923bccbb..feb434fb75 100644
--- a/macros/latex/contrib/decision-table/README
+++ b/macros/latex/contrib/decision-table/README
@@ -1,5 +1,5 @@
-dmn.sty
-Copyright 2020 Simon Vandevelde
+decision-table.sty
+Copyright 2020 Simon Vandevelde, Francois Pantigny
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3c
@@ -11,8 +11,10 @@ version 2005/12/01 or later.
This work has the LPPL maintenance status “maintained”.
-The Current Maintainer of this work is Simon Vandevelde.
+The Current Maintainers of this work are Simon Vandevelde and Francois Pantigny.
-This work consists of the files dmn.sty.
+This work consists of the files decision-table.dtx and decision-table.ins.
+You can generate the decision-table.sty package by placing both the dtx and ins
+in the same directory, and running `latex decision-table.ins`.
-The dmn LaTeX package allows easy construction of dmn decision tables.
+The decision-table LaTeX package allows easy construction of DMN decision tables.
diff --git a/macros/latex/contrib/decision-table/decision-table-doc.pdf b/macros/latex/contrib/decision-table/decision-table-doc.pdf
deleted file mode 100644
index 54156a937c..0000000000
--- a/macros/latex/contrib/decision-table/decision-table-doc.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/decision-table/decision-table-doc.tex b/macros/latex/contrib/decision-table/decision-table-doc.tex
deleted file mode 100644
index 266e88acbf..0000000000
--- a/macros/latex/contrib/decision-table/decision-table-doc.tex
+++ /dev/null
@@ -1,209 +0,0 @@
-\documentclass{article}
-\usepackage{decision-table}
-\usepackage{hyperref}
-\usepackage{listings}
-\usepackage{float}
-
-\author{Simon Vandevelde}
-
-\title{The \texttt{decision-table} Package}
-\date{2020/08/22}
-
-\begin{document}
-
-\maketitle
-
-\section{Description}
-
-The \texttt{decision-table} package allows for an easy way to generate decision tables in the Decision Model and Notation (DMN) format. (See Fig. \ref{ex1})
-This package ensures consistency in the tables (i.e. fontsize), and is thus a better alternative to inserting tables via images.
-
-\begin{figure}[H]
- \centering
- \dmntable{Calculate BMI}{U}{Weight(kgs),Length(m)}{BMI}{
- ---,---,weight/length*length}
- \caption{Example of a DMN table}
- \label{ex1}
-\end{figure}
-\section{How to use}
-
-The \texttt{decision-table} package adds the \texttt{dmntable} command, with which tables can be created.
-This command expands into a \texttt{tabular}, so it can be used within a \texttt{table} or \texttt{figure} environment.
-Furthermore, this allows labels and captions to be added seamlessly.
-It is also possible to place multiple DMN tables in one \texttt{table}/\texttt{figure} environment.
-
-The \texttt{dmntable} command has the following inputs:
-\begin{itemize}
- \item title
- \item hit policy
- \item input column headers
- \item output column headers
- \item the table values
-\end{itemize}
-The command is used as follows:
-\begin{lstlisting}[language=tex, frame=single]
-\dmntable{title}{hitpolicy}{input}{output}{values}
-\end{lstlisting}
-
-The input, output and cell values are split by a comma.
-It is not necessary to include the row numbers for the cell values.
-For example, \ref{ex1} is generated by the following code:
-\begin{lstlisting}[language=tex, frame=single, basicstyle=\small]
-\begin{figure}[H]
- \centering
- \dmntable{Calculate BMI}{U} % Title and HP
- {Weight(kgs),Length(m)}{BMI} % Input, output
- {---,---,weight/length*length} % Cell values
- \caption{Example of a DMN table}
- \label{ex1}
-\end{figure}
-\end{lstlisting}
-
-If a cell value contains multiple values (e.g. multiple string values), then accolades should be written around them.
-See the example \ref{ex2}.
-
-
-\section{Examples}
-This section contains some example code and their resulting tables.
-
-\begin{lstlisting}[language=tex, frame=single, basicstyle=\small]
-\begin{figure}[H]
- \centering
- \dmntable{Calculate BMI}{U} % Title and HP
- {Weight(kgs),Length(m)}{BMI} % Input, output
- {---,---,weight/length*length} % Cell values
- \caption{Example of a DMN table}
-\end{figure}
-\end{lstlisting}
-\begin{figure}[H]
- \centering
- \dmntable{Calculate BMI}{U} % Title and HP
- {Weight(kgs),Length(m)}{BMI} % Input, output
- {---,---,weight/length*length} % Cell values
- \caption{Example of a DMN table}
-\end{figure}
-
-
-\begin{lstlisting}[language=tex, frame=single, basicstyle=\small]
-\begin{ligure}[H]
- \centering
- \dmntable{Decide BMI Level}{U} % Title and HP
- {BMI}{BMI Level, Risk Level} % Input, output
- {$< 18.5$, Underweight, Increased,
- $[18.5..24.9]$, Normal, Low,
- $[25..29.9]$, overweight, Increased,
- $[30..34.9]$, Obese I, High,
- $[35..39.9]$, Obese II, Very High,
- $> 39.9$, Extreme Obesity, Extremely High}
- \caption{Example of a DMN table}
-\end{figure}
-\end{lstlisting}
-\begin{figure}[H]
- \centering
- \dmntable{Decide BMI Level}{U} % Title, HP
- {BMI}{BMI Level, Risk Level} % Input, output
- {$< 18.5$, Underweight, Increased,
- $[18.5..24.9]$, Normal, Low,
- $[25..29.9]$, overweight, Increased,
- $[30..34.9]$, Obese I, High,
- $[35..39.9]$, Obese II, Very High,
- $> 39.9$, Extreme Obesity, Extremely High}
- \caption{Example of a larger DMN table}
-\end{figure}
-
-\begin{lstlisting}[language=tex, frame=single, basicstyle=\tiny]
-\begin{figure}[H]
- \centering
- \dmntable{Decide Risk Level}{U}
- {BMI level, Waist(cm)}{Risk Level}
- {Overweight, $<=88$, Increased,
- Overweight, $ > 88$, High,
- Obese I,$ <= 88$, High,
- Obese II, ---, Very High,
- Extreme Obesity, ---, Extremely High,
- {not(Overweight, Obese I, Obese II, Extreme Obesity)}, ---, Low
- }
- \caption{Example of cell with multiple values}
- \label{ex2}
-\end{figure}
-\end{lstlisting}
-
-\begin{figure}[H]
- \centering
- \dmntable{Decide Risk Level}{U}
- {BMI level, Waist(cm)}{Risk Level}
- {Overweight, $<=88$, Increased,
- Overweight, $ > 88$, High,
- Obese I,$ <= 88$, High,
- Obese II, ---, Very High,
- Extreme Obesity, ---, Extremely High,
- {not(Overweight, Obese I, Obese II, Extreme Obesity)}, ---, Low
- }
- \caption{Example of cell with multiple values}
- \label{ex2}
-\end{figure}
-
-\begin{lstlisting}[language=tex, frame=single, basicstyle=\tiny]
-\begin{figure}[H]
- \centering
- \dmntable{Rule 1}{U}
- {Age, Service Years}{Eligible1}
- {$\leq18$, ---, Yes,
- $\geq60$, ---, Yes,
- {$[18, 60]$}, $\geq 30$, Yes
- }
- \dmntable{Rule 2}{U}
- {Age, Service Years}{Eligible2}
- {---,$\geq30$, Yes,
- $\geq60$,$<30$, Yes
- }
- \dmntable{Rule 3}{U}
- {Age, Service Years}{Eligible3}
- {$< 45$, {$[15, 30)$}, Yes,
- $> 45$, ---, Yes
- }
- \dmntable{Vacation days}{C+}
- {Eligible1, Eligible2, Eligble3}{Vacation Days}
- {---, ---, ---, 22,
- Yes, ---, ---, 5,
- ---, Yes, ---, 3,
- No, ---, Yes, 2
- }
- \caption{dmn table example for the Vacation Days}
-\end{figure}
-\end{lstlisting}
-\begin{figure}[H]
- \centering
- \dmntable{Rule 1}{U}
- {Age, Service Years}{Eligible1}
- {$\leq18$, ---, Yes,
- $\geq60$, ---, Yes,
- {$[18, 60]$}, $\geq 30$, Yes
- }
- \dmntable{Rule 2}{U}
- {Age, Service Years}{Eligible2}
- {---,$\geq30$, Yes,
- $\geq60$,$<30$, Yes
- }
- \dmntable{Rule 3}{U}
- {Age, Service Years}{Eligible3}
- {$< 45$, {$[15, 30)$}, Yes,
- $> 45$, ---, Yes
- }
- \dmntable{Vacation days}{C+}
- {Eligible1, Eligible2, Eligble3}{Vacation Days}
- {---, ---, ---, 22,
- Yes, ---, ---, 5,
- ---, Yes, ---, 3,
- No, ---, Yes, 2
- }
- \caption{DMN table example for the Vacation Days}
-\end{figure}
-
-
-\section{Contributing}
-
-Contributions are always welcome.
-The project is hosted at \url{https://gitlab.com/Vadevesi/dmn-tex}
-
-\end{document}
diff --git a/macros/latex/contrib/decision-table/decision-table.dtx b/macros/latex/contrib/decision-table/decision-table.dtx
new file mode 100644
index 0000000000..ba9eada069
--- /dev/null
+++ b/macros/latex/contrib/decision-table/decision-table.dtx
@@ -0,0 +1,474 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2020 by S. Vandevelde, F. Pantigny
+% ------------------------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% \fi
+% \iffalse
+%
+\def\dmnfileversion{0.0.3}
+\def\dmnfiledate{2020/12/08}
+%
+%<*batchfile>
+\begingroup
+\input l3docstrip.tex
+\keepsilent
+\usedir{tex/latex/cascade}
+\preamble
+
+Copyright (C) 2020 by S.Vandevelde, F. Pantigny
+-----------------------------------
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in:
+
+http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+\endpreamble
+\askforoverwritefalse
+\endgroup
+%</batchfile>
+%
+%<@@=cascade>
+%<*driver>
+\documentclass[dvipsnames]{l3doc}% option dvipsnames is for xcolor (loaded by tikz)
+\usepackage{xltxtra}
+\usepackage{geometry}
+\geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}}
+\setlength{\fboxsep}{0pt}
+\usepackage{tikz}
+\usepackage{hyperref}
+\usepackage{listings}
+\usepackage{float}
+\usetikzlibrary{calc}
+\usepackage{decision-table}
+\hfuzz=5cm
+\def\interitem{\vskip 7mm plus 2 mm minus 3mm}
+\def\emphase{\bgroup\color{RoyalPurple}\let\next=}
+\fvset{commandchars=\~\#\@,formatcom={\color{gray}}}
+\parindent 0pt
+\skip\footins = 2\bigskipamount
+
+
+
+\begin{document}
+\DocInput{decision-table.dtx}
+\end{document}
+%</driver>
+% \fi
+% \title{The package \pkg{decision-table}\thanks{This document corresponds to the
+% version~\dmnfileversion\space of \pkg{decision-table}, at the date of~\dmnfiledate.}}
+% \author{S. Vandevelde, F. Pantigny \\ \texttt{s.vandevelde@kuleuven.be} \\ \texttt{fpantigny@wanadoo.fr}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% The LaTeX package \pkg{decision-table} provides a command |\dmntable|, which allows for an easy way to generate decision tables in the Decision Model and Notation (DMN) format. (See Fig. \ref{ex1})
+% This package ensures consistency in the tables (i.e. fontsize), and is thus a better alternative to inserting tables via images.
+% \end{abstract}
+%
+%
+%
+% \vspace{1cm}
+% \section{Description}
+%
+% The \texttt{decision-table} package allows for an easy way to generate decision tables in the Decision Model and Notation (DMN) format. (See Fig. \ref{ex1})
+% This package ensures consistency in the tables (i.e. fontsize), and is thus a better alternative to inserting tables via images.
+%
+% \begin{figure}[H]
+% \centering
+% \dmntable{Calculate BMI}{U}{Weight(kgs),Length(m)}{BMI}{ % ---,---,weight/length*length}
+% \caption{Example of a DMN table}
+% \label{ex1}
+% \end{figure}
+% \section{How to use}
+%
+% The \texttt{decision-table} package adds the \texttt{dmntable} command, with which tables can be created.
+% This command expands into a \texttt{tabular}, so it can be used within a \texttt{table} or \texttt{figure} environment.
+% Furthermore, this allows labels and captions to be added seamlessly.
+% It is also possible to place multiple DMN tables in one \texttt{table}/\texttt{figure} environment.
+%
+% The \texttt{dmntable} command has the following inputs:
+% \begin{itemize}
+% \item title
+% \item hit policy
+% \item input column headers
+% \item output column headers
+% \item the table values
+% \end{itemize}
+% The command is used as follows:
+% \begin{lstlisting}[language=tex, frame=single]
+% \dmntable{title}{hitpolicy}{input}{output}{values}
+% \end{lstlisting}
+%
+% The input, output and cell values are split by a comma.
+% It is not necessary to include the row numbers for the cell values.
+% For example, \ref{ex1} is generated by the following code:
+% \begin{lstlisting}[language=tex, frame=single, basicstyle=\small]
+% \begin{figure}[H]
+% \centering
+% \dmntable{Calculate BMI}{U} % Title and HP
+% {Weight(kgs),Length(m)}{BMI} % Input, output
+% {---,---,weight/length*length} % Cell values
+% \caption{Example of a DMN table}
+% \label{ex1}
+% \end{figure}
+% \end{lstlisting}
+%
+% If a cell value contains multiple values (e.g. multiple string values), then accolades should be written around them.
+% See the example \ref{ex2}.
+%
+%
+% \section{Examples}
+% This section contains some example code and their resulting tables.
+%
+% \begin{lstlisting}[language=tex, frame=single, basicstyle=\small]
+% \begin{figure}[H]
+% \centering
+% \dmntable{Calculate BMI}{U} % Title and HP
+% {Weight(kgs),Length(m)}{BMI} % Input, output
+% {---,---,weight/length*length} % Cell values
+% \caption{Example of a DMN table}
+% \end{figure}
+% \end{lstlisting}
+% \begin{figure}[H]
+% \centering
+% \dmntable{Calculate BMI}{U}
+% {Weight(kgs),Length(m)}{BMI}
+% {---,---,weight/length*length}
+% \caption{Example of a DMN table}
+% \end{figure}
+%
+%
+% \begin{lstlisting}[language=tex, frame=single, basicstyle=\small]
+% \begin{ligure}[H]
+% \centering
+% \dmntable{Decide BMI Level}{U}
+% {BMI}{BMI Level, Risk Level}
+% {$< 18.5$, Underweight, Increased,
+% $[18.5..24.9]$, Normal, Low,
+% $[25..29.9]$, overweight, Increased,
+% $[30..34.9]$, Obese I, High,
+% $[35..39.9]$, Obese II, Very High,
+% $> 39.9$, Extreme Obesity, Extremely High}
+% \caption{Example of a DMN table}
+% \end{figure}
+% \end{lstlisting}
+% \begin{figure}[H]
+% \centering
+% \dmntable{Decide BMI Level}{U}
+% {BMI}{BMI Level, Risk Level}
+% {$< 18.5$, Underweight, Increased,
+% $[18.5..24.9]$, Normal, Low,
+% $[25..29.9]$, overweight, Increased,
+% $[30..34.9]$, Obese I, High,
+% $[35..39.9]$, Obese II, Very High,
+% $> 39.9$, Extreme Obesity, Extremely High}
+% \caption{Example of a larger DMN table}
+% \end{figure}
+%
+% \begin{lstlisting}[language=tex, frame=single, basicstyle=\tiny]
+% \begin{figure}[H]
+% \centering
+% \dmntable{Decide Risk Level}{U}
+% {BMI level, Waist(cm)}{Risk Level}
+% {Overweight, $<=88$, Increased,
+% Overweight, $ > 88$, High,
+% Obese I,$ <= 88$, High,
+% Obese II, ---, Very High,
+% Extreme Obesity, ---, Extremely High,
+% {not(Overweight, Obese I, Obese II, Extreme Obesity)}, ---, Low
+% }
+% \caption{Example of cell with multiple values}
+% \label{ex2}
+% \end{figure}
+% \end{lstlisting}
+%
+% \begin{figure}[H]
+% \centering
+% \dmntable{Decide Risk Level}{U}
+% {BMI level, Waist(cm)}{Risk Level}
+% {Overweight, $<=88$, Increased,
+% Overweight, $ > 88$, High,
+% Obese I,$ <= 88$, High,
+% Obese II, ---, Very High,
+% Extreme Obesity, ---, Extremely High,
+% {not(Overweight, Obese I, Obese II, Extreme Obesity)}, ---, Low
+% }
+% \caption{Example of cell with multiple values}
+% \label{ex2}
+% \end{figure}
+%
+% \begin{lstlisting}[language=tex, frame=single, basicstyle=\tiny]
+% \begin{figure}[H]
+% \centering
+% \dmntable{Rule 1}{U}
+% {Age, Service Years}{Eligible1}
+% {$\leq18$, ---, Yes,
+% $\geq60$, ---, Yes,
+% {$[18, 60]$}, $\geq 30$, Yes
+% }
+% \dmntable{Rule 2}{U}
+% {Age, Service Years}{Eligible2}
+% {---,$\geq30$, Yes,
+% $\geq60$,$<30$, Yes
+% }
+% \dmntable{Rule 3}{U}
+% {Age, Service Years}{Eligible3}
+% {$< 45$, {$[15, 30)$}, Yes,
+% $> 45$, ---, Yes
+% }
+% \dmntable{Vacation days}{C+}
+% {Eligible1, Eligible2, Eligble3}{Vacation Days}
+% {---, ---, ---, 22,
+% Yes, ---, ---, 5,
+% ---, Yes, ---, 3,
+% No, ---, Yes, 2
+% }
+% \caption{dmn table example for the Vacation Days}
+% \end{figure}
+% \end{lstlisting}
+% \begin{figure}[H]
+% \centering
+% \dmntable{Rule 1}{U}
+% {Age, Service Years}{Eligible1}
+% {$\leq18$, ---, Yes,
+% $\geq60$, ---, Yes,
+% {$[18, 60]$}, $\geq 30$, Yes
+% }
+% \dmntable{Rule 2}{U}
+% {Age, Service Years}{Eligible2}
+% {---,$\geq30$, Yes,
+% $\geq60$,$<30$, Yes
+% }
+% \dmntable{Rule 3}{U}
+% {Age, Service Years}{Eligible3}
+% {$< 45$, {$[15, 30)$}, Yes,
+% $> 45$, ---, Yes
+% }
+% \dmntable{Vacation days}{C+}
+% {Eligible1, Eligible2, Eligble3}{Vacation Days}
+% {---, ---, ---, 22,
+% Yes, ---, ---, 5,
+% ---, Yes, ---, 3,
+% No, ---, Yes, 2
+% }
+% \caption{DMN table example for the Vacation Days}
+% \end{figure}
+%
+%
+% \section{Contributing}
+%
+% Contributions are always welcome.
+% The project is hosted at \url{https://gitlab.com/Vadevesi/dmn-tex}
+
+%
+% \newgeometry{left=4cm}
+%
+% \section{Implementation}
+%
+%<@@=dmn>
+%
+% \bigskip
+%
+%
+% We give the traditional declaration of a package written with |expl3|:
+% \begin{macrocode}
+\RequirePackage{l3keys2e}
+\ProvidesExplPackage
+ {decision-table}
+ {\dmnfiledate}
+ {\dmnfileversion}
+ {Table of decision}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\RequirePackage { nicematrix }
+% \end{macrocode}
+%
+% \bigskip
+% We define the command |\dmntable| with the tools of \pkg{xparse} (in 2020
+% October, \pkg{xparse} will be included in the LaTeX kernel).
+% \begin{macrocode}
+\NewDocumentCommand \dmntable { m m m m m }
+ {
+% \end{macrocode}
+% The clist (\emph{commad separated list}) |\l_@@_input_clist| is for the list
+% of the names of the input fields.
+% \begin{macrocode}
+ \clist_clear_new:N \l_@@_input_clist
+ \clist_set:Nn \l_@@_input_clist { #3 }
+% \end{macrocode}
+%
+% \bigskip
+% The clist |\l_@@_output_clist| is for the list of the names of the output fields.
+% \begin{macrocode}
+ \clist_clear_new:N \l_@@_output_clist
+ \clist_set:Nn \l_@@_output_clist { #4 }
+% \end{macrocode}
+%
+% \bigskip
+% The integer |\l_@@_input_int| is the number of the input fields.
+% \begin{macrocode}
+ \int_zero_new:N \l_@@_input_int
+ \int_set:Nn \l_@@_input_int { \clist_count:N \l_@@_input_clist }
+% \end{macrocode}
+%
+% \bigskip
+% The integer |\l_@@_output_int| is the number of the output fields.
+% \begin{macrocode}
+ \int_zero_new:N \l_@@_output_int
+ \int_set:Nn \l_@@_output_int { \clist_count:N \l_@@_output_clist }
+% \end{macrocode}
+%
+%
+% \bigskip
+% The sequence |\l_@@_cells_seq| is the sequence of all the cells of the
+% ``body'' of the tabular.
+% \begin{macrocode}
+ \seq_clear_new:N \l_@@_cells_seq
+ \seq_set_split:Nnn \l_@@_cells_seq { , } { #5 }
+% \end{macrocode}
+%
+%
+% \vspace{1cm}
+% Now, we will begin the construction of the tabular (a |{NiceTabular}| of
+% \pkg{nicematrix}).
+%
+% \bigskip
+% The command |\use:x| will expand its argument. Indeed, the preamble of the
+% |{NiceTabular}| (which has the same format as a preamble of |{tabular}| must
+% be computed before the execution of the |\begin{NiceTabular}|.
+% \begin{macrocode}
+ \use:x
+ {
+ \exp_not:N \begin { NiceTabular }
+% \end{macrocode}
+% Here is the preamble of the tabular. The command |\prg_replicate:nn| is
+% expandable and hence will be expanded by the |use:x|.
+% \begin{macrocode}
+ { r \prg_replicate:nn { \l_@@_input_int + \l_@@_output_int } l }
+% \end{macrocode}
+% Here is the list of options of the |{NiceTabular}| (a standard tabular of
+% |{array}| don't have such list of options. Once again, we have to compute some
+% quantities in this list of options before the execution of |\begin{NiceTabular}|.
+% \begin{macrocode}
+ [
+% \end{macrocode}
+% The key |hvlines-except-corners| will draw all the rules of the tabular,
+% excepted in the (upper right) corner.
+% \begin{macrocode}
+ hvlines-except-corners ,
+% \end{macrocode}
+% The key |code-before| of |{NiceTabular}| contains instructions to color the
+% cells \emph{before} the rules (doing so, the resulting \textsc{pdf} gives
+% better results in the \textsc{pdf} viewers).
+% \begin{macrocode}
+ code-before =
+% \end{macrocode}
+% First, a |\rectanglecolor| for the labels of the ``input'' fields. The command
+% |\int_eval:n| is expandable and, hence, will be expanded by the |\use:x|. On
+% the other side, we have to prevent the expansion of |\rectanglecolor| which,
+% in fact, at that point is not defined (it will be defined by \pkg{nicematrix}
+% after the construction of the array).
+% \begin{macrocode}
+ \exp_not:N \rectanglecolor
+ { blue!10!green!60!black!30 }
+ { 2 - 2 }
+ { 2 - \int_eval:n { \l_@@_input_int + 1 } }
+% \end{macrocode}
+% A |\rectanglecolor| for the labels of the ``output'' fields.
+% \begin{macrocode}
+ \exp_not:N \rectanglecolor
+ { green!30!blue!15 }
+ { 2 - \int_eval:n { \l_@@_input_int + 2 } }
+ { 2 - \int_eval:n { \l_@@_input_int + \l_@@_output_int + 1 } }
+ ]
+ }
+% \end{macrocode}
+% Now, we begin the body of the tabular (the environment |{NiceTabular}|).
+%
+% \medskip
+% The body begins by a |\multicolumn| for the title. However, we have to compute
+% the number of cells of that |\multicolumn|. That's why we have to expand the
+% first argument of the |\multicolumn| before executing the |\multicolumn|.
+% However, we have to do that in an expandable way in order to prevent the
+% functionnality of the |\multicolumn| (which internally give a |\omit| of TeX).
+% That's why we have to use |\exp_args:Ne| (|\exp_args:Nx| would not do the job).
+% \begin{macrocode}
+ \exp_args:Ne \multicolumn
+ { \int_eval:n { \l_@@_input_int + 1 } }
+ { l }
+ { #1 } \\
+% \end{macrocode}
+% |#2| is the \emph{hit policy}.
+% \begin{macrocode}
+ #2 &
+% \end{macrocode}
+% Now, the fields (``input fields'' and ``output fields''). By using
+% |\clist_use:Nn|, we replace the commas by ampersands (|&|).
+% \begin{macrocode}
+ \clist_use:Nn \l_@@_input_clist { & } &
+ \clist_use:Nn \l_@@_output_clist { & } \\
+% \end{macrocode}
+% Now, all the rows corresponding to the rules. We begin a loop over all the
+% cells with |\seq_map_inline:Nn|.
+% \begin{macrocode}
+ 1 &
+ \seq_map_inline:Nn \l_@@_cells_seq
+ {
+% \end{macrocode}
+% |\c@jCol| and |\c@iRow| are counters provided by |{NiceTabular}| for the
+% current column and the current row. If you are in the first column, we insert
+% the number of rule.
+% \begin{macrocode}
+ \int_compare:nT { \c@jCol = 0 } { \int_eval:n { \c@iRow - 1 } & }
+% \end{macrocode}
+% Now, we add one composante of |\l_@@_cells_seq|.
+% \begin{macrocode}
+ ##1
+% \end{macrocode}
+% Before the following cell, we have, of course, to add |\\| (if we are at the
+% end of the row) or |&| (elsewhere).
+% \begin{macrocode}
+ \int_compare:nTF { \c@jCol = \l_@@_input_int + \l_@@_output_int + 1 }
+ { \\ }
+ { & }
+ }
+ \end { NiceTabular }
+ }
+% \end{macrocode}
+%
+%
+%
+% \tableofcontents
+%
+% \end{document}
+%
+% Local Variables:
+% TeX-fold-mode: t
+% TeX-fold-preserve-comments: nil
+% flyspell-mode: nil
+% fill-column: 80
+% End:
+
+
+
+
+
+
diff --git a/macros/latex/contrib/decision-table/decision-table.ins b/macros/latex/contrib/decision-table/decision-table.ins
new file mode 100644
index 0000000000..e6e24bff6f
--- /dev/null
+++ b/macros/latex/contrib/decision-table/decision-table.ins
@@ -0,0 +1,47 @@
+%%
+%% Copyright (C) 2020 by S. Vandevelde and F. Pantigny
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3c or later is part of all distributions of
+%% LaTeX version 2005/12/01 or later.
+%%
+\input l3docstrip.tex
+\keepsilent
+\usedir{tex/latex/decision-table}
+\preamble
+
+Copyright (C) 2020 by S. Vandevelde, F. Pantigny
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2005/12/01 or later.
+
+\endpreamble
+\generate{\file{decision-table.sty}{\from{decision-table.dtx}{package}}}
+\Msg{*********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the}
+\Msg{* following file into a directory searched by TeX:}
+\Msg{*}
+\Msg{* \space\space decision-table.sty}
+\Msg{*}
+\Msg{* To produce the documentation run the file decision-table.dtx}
+\Msg{* through XeLaTeX.}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*********************************************************}
+\endbatchfile
+
diff --git a/macros/latex/contrib/decision-table/decision-table.pdf b/macros/latex/contrib/decision-table/decision-table.pdf
new file mode 100644
index 0000000000..001dea8435
--- /dev/null
+++ b/macros/latex/contrib/decision-table/decision-table.pdf
Binary files differ
diff --git a/macros/latex/contrib/decision-table/decision-table.sty b/macros/latex/contrib/decision-table/decision-table.sty
deleted file mode 100644
index 2e1bf38539..0000000000
--- a/macros/latex/contrib/decision-table/decision-table.sty
+++ /dev/null
@@ -1,149 +0,0 @@
-% The decision-table package is the easiest way to generate tables in the Decision Model and Notation (DMN) format.
-%
-%% decision-table.sty
-%% Copyright 2020 Simon Vandevelde
-%
-% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3c
-% of this license or (at your option) any later version.
-% The latest version of this license is in
-% http://www.latex-project.org/lppl.txt
-% and version 1.3c or later is part of all distributions of LaTeX
-% version 2005/12/01 or later.
-%
-% This work has the LPPL maintenance status “maintained”.
-%
-% The Current Maintainer of this work is Simon Vandevelde.
-%
-% This work consists of the file decision-table.sty
-%
-%% This package creates the \dmntable command.
-%% Requires the following input:
-%% 1: table title
-%% 2: hit policy
-%% 3: input columns, separated by commas (e.g. 'weight, length')
-%% 4: output columns, separated by commas (e.g. 'BMI')
-%% 5: cell values, separated by commas (e.g. '>80, ---, weight/length*length,
-%
-%% The package depends on two other packages: 'colortbl' and 'booktabs'.
-
-\ProvidesPackage{decision-table}[2020/08/22 v0.0.2 LaTeX package for DMN]
-
-
-\RequirePackage{colortbl} % Color in the cells.
-\RequirePackage{booktabs} % Special header format.
-
-
-\definecolor{inputgreen}{RGB}{182, 215, 168}
-\definecolor{inputblue}{RGB}{207, 226, 243}
-\definecolor{glossaryorange}{RGB}{255, 123, 89}
-\definecolor{executered}{RGB}{236, 155, 164}
-\newcommand{\inputcol}[1]{\cellcolor{inputgreen} \textbf{#1}}
-\newcommand{\outputcol}[1]{\cellcolor{inputblue} \textbf{#1}}
-\newcommand{\glossarycol}[0]{\cellcolor{glossaryorange}}
-\newcommand{\executecol}[0]{\cellcolor{executered}}
-\newcommand{\dmnfont}[0]{\fontsize{7}{9} \fontfamily{put} \selectfont \setlength{\belowrulesep}{0pt}}
-
-% Code to iterate over strings separated by comma's and executing a macro on each of them.
-\makeatletter
-
-% Functional foreach construct
-% 1 - Function to call on each comma-separated item in param 3
-% 2 - Parameter to pass to function in param 1 as first parameter
-% 3 - Comma-separated list of items to pass as second parameter to function in param 1
-\def\foreach#1#2#3{%
- \@test@foreach{#1}{#2}#3,\@end@token%
-}
-
-% Internal helper function - Eats one input
-\def\@swallow#1{}
-
-% Internal helper function - Checks the next character after param 1 and param 2 and
-% continues loop iteration if \@end@token is not found
-\def\@test@foreach#1#2{%
- \@ifnextchar\@end@token%
- {\@swallow}%
- {\@foreach{#1}{#2}}%
-}
-
-% Internal helper function - Calls 1{2}{3} and recurses
-% The magic of splitting the third parameter occurs in the pattern matching of the \def
-\def\@foreach#1#2#3,#4\@end@token{%
- #1{#2}{#3}%
- \@test@foreach{#1}{#2}#4\@end@token%
-}
-
-%%% Macro's which are used in the above iteration function.
-% Formats the inputcol as "\& \inputcol('input')".
-\def\makeinputcol#1#2{&\inputcol{#2}}
-% Formats the outputcol as "\& \outputcol('output')".
-\def\makeoutputcol#1#2{&\outputcol{#2}}
-
-\def\makecol#1#2{ % Format the cells. Needs to add in \\\hline after the right amount of cells.
- \ifnum\colcounter=\nbcols% If we're at the end of a row, reset the counter and add the \\\hline
- \global\colcounter=0\relax
- \uppercase{\\} \hline \the\rowcounter
- \global\advance\rowcounter by 1
- \else
- \fi%5
- \global\advance\colcounter by 1
- \uppercase{&} {#2}
-}
-
-% Increments the counters by one, in order to count inputs or outputs using the above loop function.
-\def\countinput#1#2{\global\advance\nbinputs by 1\relax}
-\def\countoutput#1#2{\global\advance\nboutputs by 1\relax}
-
-\makeatother
-
-% Command to create a DMN table in a tabular environment.
-% Requires the following input:
-% 1: table title
-% 2: hit policy
-% 3: input columns, separated by commas (e.g. 'weight, length')
-% 4: output columns, separated by commas (e.g. 'BMI')
-% 5: cell values, separated by commas (e.g. '>80, ---, weight/length*length,
-% <80, ---, length/weight*weight')
-\newcommand{\dmntable}[5]{
- % Create and instantiate counters.
- \newcount{\nbinputs}
- \newcount{\nboutputs}
- \newcount{\nbcols} % The width of a table.
- \newcount{\colcounter}
- \newcount{\rowcounter}
- \nbinputs=0\relax
- \nboutputs=0\relax
- \nbcols=0\relax
- \colcounter=0\relax
- \rowcounter=2\relax
-
- \newcount\X
- {
- % Set the correct font.
- \dmnfont
-
- % Count the amount of inputs and outputs.
- \foreach{\countinput}{}{#3}
- \foreach{\countoutput}{}{#4}
- % Sum them together to find the number of columns of the table.
- \advance\nbcols by \nbinputs
- \advance\nbcols by \nboutputs
-
- % X is the first index number, always 1.
- \X=1
- \advance\nbinputs by 1\relax % To make space for the index
- \begin{tabular}{|r|*{\nbcols}{l|}}
- \expandafter\cmidrule{1-\nbinputs} % Makes sure the top hline is not the full width.
- \multicolumn{\nbinputs}{|l|}{#1} & \multicolumn{\nboutputs}{c}{}\\ % Set the input and output as multicolumn.
- \hline
- #2 \foreach{\makeinputcol}{}{#3} \foreach{\makeoutputcol}{}{#4} \\ % Generate input and outputheaders.
- \hline
- \the\X \foreach{\makecol}{}{#5} \\ % Generate the cell values
- \hline
- \end{tabular}
- }
-}
-
-\endinput
-%%%
-%%% End of file 'dmn.sty'
diff --git a/macros/latex/contrib/draftwatermark/README.md b/macros/latex/contrib/draftwatermark/README.md
index 7b22c3a1fc..527bffa1ff 100644
--- a/macros/latex/contrib/draftwatermark/README.md
+++ b/macros/latex/contrib/draftwatermark/README.md
@@ -6,27 +6,37 @@ document. Typical usage may consist in writing words such as "DRAFT" or
"CONFIDENTIAL" across document pages. The package may remind in some sense
`draftcopy` by Dr. Juergen Vollmer, but its implementation is lighter (as the
reduced code footprint shows) and does not rely on postscript specials, making
-the package fully compatible with pdfLaTeX, XeLaTeX and LuaLaTeX. The package
-depends on `everypage.sty` by the same author.
+the package fully compatible with pdfLaTeX, XeLaTeX and LuaLaTeX.
The package focus is on simplicity, for complex layouts please consider
-`scrlayer.sty` in the KOMA script bundle.
+`scrlayer.sty` in the KOMA script bundle or directly employing the new
+LaTeX hooks `shiphout/background` and `shipout/foreground`.
The `draftwatermark` package is copyright 2006, 2012, 2020 by Sergio Callegari
<sergio.callegari@gmail.com>.
-This work consists of this `README.md` file, as well as files `draftwatermark.dtx`,
-`draftwatermark.ins` and the derived file `draftwatermark.sty`.
+This work consists of this `README.md` file, as well as files:
+- `draftwatermark.dtx`,
+- `draftwatermark.ins`
+and the derived files.
-To install the package, run LaTeX on the installation script
+To install the package, run TeX/LaTeX on the installation script
`draftwatermark.ins` and follow the instructions provided by the script itself.
-This work may be distributed and/or modified under the conditions of the LaTeX
-Project Public License version 1.3. This license is available at
-<https://www.latex-project.org/lppl/> and it is part of all distributions of
-LaTeX version 2005/12/01 or later.
-This work has the LPPL maintenance status "author-maintained".
+## License
+
+Package `draftwatermark` may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, version 1.3. This license is
+available at <https://www.latex-project.org/lppl/lppl-1-3c/>.
+
+
+## Maintenace status
+
+This work has the LPPL maintenance status "maintained".
+
+
+## Development and bug tracking
Development happens on github at
<https://github.com/callegar/LaTeX-draftwatermark>. Please refer to that site
diff --git a/macros/latex/contrib/draftwatermark/draftwatermark.dtx b/macros/latex/contrib/draftwatermark/draftwatermark.dtx
index b759f29eb7..216fd1072c 100644
--- a/macros/latex/contrib/draftwatermark/draftwatermark.dtx
+++ b/macros/latex/contrib/draftwatermark/draftwatermark.dtx
@@ -8,14 +8,16 @@
% a contribution to the LaTeX2e system.
% ---------------------------------------------
%
-% It may be distributed and/or modified under the conditions of the
-% LaTeX Project Public License, version 1.3. This license is at
-% https://www.latex-project.org/lppl/ and is part
-% of all distributions of LaTeX version 2005/12/01 or later.
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, version 1.3c.
+% This license is in
+% https://www.latex-project.org/lppl/lppl-1-3c/
+% and is part of all distributions of LaTeX later than
+% 2008-05-04.
%
-% This work has the LPPL maintenance status "author-maintained".
+% This work has the LPPL maintenance status "maintained".
%
-% This program consists of the files listed in the README file
+% This program consists of the files listed in the README.md file
% included in the package.
%
%<*driver>
@@ -27,40 +29,8 @@
\usepackage{textcomp}
\usepackage{url}
\EnableCrossrefs
-
-\setcounter{IndexColumns}{2}
-\setlength{\IndexMin}{3cm}
-
-\DoNotIndex{\\}
-\DoNotIndex{\begin, \end, \begingroup, \endgroup}
-\DoNotIndex{\csname, \endcsname}
-\DoNotIndex{\if, \else, \fi}
-\DoNotIndex{\ifx, \fi}
-\DoNotIndex{\ifodd, \fi}
-\DoNotIndex{\@car, \@empty, \@ifnextchar, \@nil, \@onelevel@sanitize,
- \@tempboxa, \@tempdima, \@tempdimb, \@tfor}
-\DoNotIndex{\AddEverypageHook, \AddThispageHook, \addtolength, \author}
-\DoNotIndex{\bfseries, \box}
-\DoNotIndex{\color}
-\DoNotIndex{\DeclareBoolOption, \DeclareComplementaryOption,
- \DeclareStringOption, \def, \define@key, \dimexpr, \DisableKeyvalOption,
- \do, \documentclass, \dp}
-\DoNotIndex{\edef, \expandafter}
-\DoNotIndex{\fbox, \fontsize}
-\DoNotIndex{\hbox, \hspace, \hss, \ht}
-\DoNotIndex{\let, \lipsum}
-\DoNotIndex{\maketitle, \MyWM}
-\DoNotIndex{\newcommand, \newsavebox, \NeedsTeXFormat}
-\DoNotIndex{\PackageError, \paperheight, \paperwidth,
- \ProcessKeyvalOptions, \ProvidesPackage}
-\DoNotIndex{\relax, \RequirePackage, \rotatebox}
-\DoNotIndex{\savebox, \sbox, \scalebox, \section, \selectfont, \setkeys,
- \setlength, \sffamily, \shortstack}
-\DoNotIndex{\thepage, \title}
-\DoNotIndex{\usebox, \usepackage}
-\DoNotIndex{\vbox, \vspace, \vss}
-\DoNotIndex{\wd, \wmbox}
-
+\CodelineIndex
+\RecordChanges
\CodelineIndex
%\RecordChanges
\begin{document}
@@ -70,12 +40,47 @@
%
% \fi
%
-% \CheckSum{291}
+% \CheckSum{576}
%
% \def\filename{draftwatermark.dtx}
-% \def\fileversion{2.2}
-% \def\filedate{2020/06/29}
-% \def\docdate{2020/06/29}
+% \def\fileversion{3.0}
+% \def\filedate{2020/12/08}
+% \def\docdate{2020/12/08}
+%
+% \DoNotIndex{\\}
+% \DoNotIndex{\begin, \end, \begingroup, \endgroup}
+% \DoNotIndex{\csname, \endcsname}
+% \DoNotIndex{\if, \else, \fi}
+% \DoNotIndex{\ifx, \fi}
+% \DoNotIndex{\ifodd, \fi}
+% \DoNotIndex{\@car, \@empty, \@ifnextchar, \@ifundefined, \@nil,
+% \@onelevel@sanitize, \@tempboxa, \@tempdima, \@tempdimb, \@tfor}
+% \DoNotIndex{\AddEverypageHook, \AddThispageHook, \AddToHook, \AddToHookNext,
+% \addtolength, \author}
+% \DoNotIndex{\bfseries, \box}
+% \DoNotIndex{\color}
+% \DoNotIndex{\DeclareBoolOption, \DeclareComplementaryOption,
+% \DeclareStringOption, \def, \define@key, \depth, \dimexpr,
+% \DisableKeyvalOption, \do, \documentclass, \dp}
+% \DoNotIndex{\edef, \endinput, \expandafter}
+% \DoNotIndex{\fbox, \fontsize}
+% \DoNotIndex{\hbox, \hspace, \hss, \ht}
+% \DoNotIndex{\let, \lipsum}
+% \DoNotIndex{\maketitle, \MyWM, \MessageBreak}
+% \DoNotIndex{\newcommand, \newsavebox, \NeedsTeXFormat}
+% \DoNotIndex{\PackageError, \PackageWarningNoLine, \paperheight,
+% \paperwidth, \ProcessKeyvalOptions, \ProvidesPackage, \put}
+% \DoNotIndex{\raisebox, \relax, \RequirePackage, \RequirePackageWithOptions,
+% \rotatebox}
+% \DoNotIndex{\savebox, \sbox, \scalebox, \section, \selectfont, \setkeys,
+% \SetupKeyvalOptions, \setlength, \sffamily, \shortstack}
+% \DoNotIndex{\thepage, \title}
+% \DoNotIndex{\usebox, \usepackage}
+% \DoNotIndex{\vbox, \vspace, \vss}
+% \DoNotIndex{\wd, \wmbox}
+%
+% \setcounter{IndexColumns}{2}
+% \setlength{\IndexMin}{3cm}
%
% \newcommand*{\Lpack}[1]{\textsf {#1}} ^^A typeset a package
% \newcommand*{\Lopt}[1]{\texttt {#1}} ^^A typeset an option
@@ -97,28 +102,30 @@
% \maketitle
%
% \begin{abstract}
-% The \Lpack{draftwatermark} package extends \LaTeX\ providing a means
-% to add a watermark (typically textual and light gray, but possibly
-% more sophisticated) on the pages of a document (either on every page,
-% on the first page, or on selected pages). Typical usage may consist in
-% writing words such as ``DRAFT'' or ``CONFIDENTIAL'' across the
-% pages. The package may remind in some sense \Lpack{draftcopy} by
-% Dr.~Juergen Vollmer, but its implementation is lighter (as the reduced
-% code footprint shows) and does not rely on postscript specials, making
-% the package fully compatible with \hologo{pdfLaTeX}, \hologo{XeLaTeX}
-% and \hologo{LuaLaTeX}. The \Lpack{draftwatermark} package depends on
-% \Lpack{everypage} by the same author. Its feature set is somehow
-% restricted because the emphasis is on the simplicity of the
-% interface. For complex layouts, \Lpack{scrlayer.sty} from the
-% \emph{KOMA script} bundle may represent a valuable alternative.
+% The \Lpack{draftwatermark} package extends \hologo{LaTeX} providing a
+% means to add a watermark (typically textual and light gray, but
+% possibly more sophisticated) on the pages of a document (either on
+% every page, on the first page, or on selected pages). Typical usage
+% may consist in writing words such as ``DRAFT'' or ``CONFIDENTIAL''
+% across the pages. The package may remind in some sense
+% \Lpack{draftcopy} by Dr.~Juergen Vollmer, but its implementation is
+% lighter (as the reduced code footprint shows) and does not rely on
+% postscript specials, making the package fully compatible with
+% \hologo{pdfLaTeX}, \hologo{XeLaTeX} and \hologo{LuaLaTeX}. Its feature
+% set is somehow restricted because the emphasis is on the simplicity of
+% the interface. For complex layouts, consider \Lpack{scrlayer.sty} from
+% the \emph{KOMA script} bundle or directly using the new \hologo{LaTeX}
+% shipout hooks.
% \end{abstract}
%
% \section{Introduction}
-%
-% This package extends \LaTeX\ providing a means to add a textual, usually
-% light gray (but possibly colored) watermark on every page, the first
-% page, or selected pages of a document. Typical usage may consist in
-% writing words such as ``DRAFT'' or ``CONFIDENTIAL'' across document
+%
+% \changes{R1.0}{2006/06/30}{Initial release.}%
+% \changes{R1.1}{2012/01/06}{Many small fixes in the documentation.}
+% This package extends \hologo{LaTeX} providing a means to add a textual,
+% usually light gray (but possibly colored) watermark on every page, the
+% first page, or selected pages of a document. Typical usage may consist
+% in writing words such as ``DRAFT'' or ``CONFIDENTIAL'' across document
% pages.
%
% The package may remind in some sense \Lpack{draftcopy} by Dr.~Juergen
@@ -162,11 +169,10 @@
% other packages affecting the page building, e.g., with respect to the
% stacking order of the objects on the page. For any complex layout, or
% when the Z-ordering is important, the recommendation is to look at the
-% \Lpack{scrlayer} package in the \emph{KOMA script} bundle.
+% \Lpack{scrlayer} package in the \emph{KOMA script} bundle or to rely
+% directly on the new shipout hook mechanism provided by \hologo{LaTeX}.
+%
%
-% For the actual page building \Lpack{draftwatermark} depends on the
-% \Lpack{everypage} package by the same author.
-%
% \section{User interface}
% When loaded, \Lpack{draftwatermark} sets up a number of defaults
% (detailed later and modifiable by specific commands) and immediately
@@ -185,7 +191,8 @@
% |\usepackage[<options>]{draftwatermark}|
% \end{quote}
%
-% \DescribeMacro{\DraftwatermarkOptions}
+% \DescribeMacro{\DraftwatermarkOptions}
+% \changes{R2.0}{2020/03/08}{Introduction of a keyval option mechanism.}
% The package behavior can also be dynamically changed \emph{after the
% package is loaded} by the command |\DraftwatermarkOptions{<options>}|
% that can be used anywhere in the document source. In either case,
@@ -198,11 +205,13 @@
% command is a bit quirky, hence when specifying options with the
% |<key>=<value>| syntax, some values that are accepted by
% |\DraftwatermarkOptions| may cause issues when specifying options with
-% |\usepackage|.
-% \medskip
+% |\usepackage|. \medskip
%
% The available options are:
% \begin{itemize}
+% \changes{R1.1}{2012/01/06}{Introduce the ``stamp'', ``nostamp'' and
+% ``final'' options to control whether the watermark should actually
+% be printed.}^^A
% \item \verb!firstpageonly=true|false!\\
% If no value is provided, |true| is assumed. Default is |false|.\\
% Instructs \Lpack{draftwatermark} to only apply the watermark on the
@@ -322,21 +331,21 @@
% fact, sufficiently large to get the word ``DRAFT'', rotated at
% 45\textdegree, take about half of the page width.
%
-% Nonetheless asking for a large font may not work, if \LaTeX\ has not
-% been set up to use \emph{scalable} fonts. For this reason, the
-% recommendation is to always use \Lpack{draftwatermark} on \LaTeX\ or
-% \hologo{pdfLaTeX} together with other packages that trigger the usage of
-% fully scalable fonts (practical examples may be \Lpack{newtx} or
+% Nonetheless asking for a large font may not work, if \hologo{LaTeX} has
+% not been set up to use \emph{scalable} fonts. For this reason, the
+% recommendation is to always use \Lpack{draftwatermark} on \hologo{LaTeX}
+% or \hologo{pdfLaTeX} together with other packages that trigger the usage
+% of fully scalable fonts (practical examples may be \Lpack{newtx} or
% \Lpack{mathptmx}, etc.). An even better alternative is to use modern
% \TeX\ engines, as in \hologo{XeLaTeX} or \hologo{LuaLaTeX} with
% \Lpack{fontspec}. In any case, recall that even with scalable fonts,
-% \LaTeX\ may be unable to deal with extremely large font sizes (e.g.,
-% $\gg 5\,\mathrm{cm}$). If really large letters are required for the
-% watermark, a suitable combination of |fontsize| and |scale| may be
+% \hologo{LaTeX} may be unable to deal with extremely large font sizes
+% (e.g., $\gg 5\,\mathrm{cm}$). If really large letters are required for
+% the watermark, a suitable combination of |fontsize| and |scale| may be
% needed.
%
-% One can immediately realize when \LaTeX\ is unable to deal with the
-% package default or selected |fontsize| from two things: (i) a font
+% One can immediately realize when \hologo{LaTeX} is unable to deal with
+% the package default or selected |fontsize| from two things: (i) a font
% warning from \LaTeX; and (ii) a tiny watermark text whose size seems not
% to react to the |fontsize| option. In this case, either switch to
% scalable fonts or select a small |fontsize| (e.g., |12pt|) together with
@@ -352,21 +361,21 @@
% (e.g., |\bfseries|). In fact, it is also possible to use a command to
% include an image as the text. In case line breaks are present, the text
% is left, right, center aligned according to the |alignment| option. A
-% word of caution is necessary, though. To use \LaTeX\ commands in the
-% watermark text, please configure the latter via the
+% word of caution is necessary, though. To use \hologo{LaTeX} commands in
+% the watermark text, please configure the latter via the
% |\DraftwatermarkOptions| command. Trying to do so by passing options to
% the \Lpack{draftwatermark} package via the |\usepackage| mechanism may
-% fail due to how \LaTeX\ parses option strings. Also note that the text
-% may need to be surrounded by braces.
+% fail due to how \hologo{LaTeX} parses option strings. Also note that the
+% text may need to be surrounded by braces.
%
% If the watermark text includes line breaks, \Lpack{draftwatermark} will
% use a very thin interline space, according to the fact that the
-% multi-line text is managed by surrounding the it with a \LaTeX\
+% multi-line text is managed by surrounding the it with a \hologo{LaTeX}
% |shortstack| command.
%
-% Also, note that the watermark typesetting happens inside a \TeX\
-% group, to make sure that any parameter setting you do in the |text|
-% token list can stay local.
+% Also, note that the watermark typesetting happens inside a \TeX\ group,
+% to make sure that any parameter setting you do in the |text| token list
+% can stay local.
%
% As a further remark, observe that in order to only put a watermark on
% selected pages, an alternative to changing the |stamp| configuration
@@ -391,18 +400,21 @@
% anchoring.
%
% As a final remark, observe that the specification of the positioning
-% coordinates can be based on \LaTeX\ macros. For instance, one can set
-% the horizontal position |hpos| at |0.5\paperwidth| (for centering) or at
-% |\dimexpr\paperwidth-5mm| (for placement at the right hand side of the
-% page). Interestingly, \Lpack{draftwatermark} re-evaluates the
+% coordinates can be based on \hologo{LaTeX} macros. For instance, one can
+% set the horizontal position |hpos| at |0.5\paperwidth| (for centering)
+% or at |\dimexpr\paperwidth-5mm| (for placement at the right hand side of
+% the page). Interestingly, \Lpack{draftwatermark} re-evaluates the
% positioning coordinates on every page. This means that positions based
% on |\paperwidth| or |\paperheight| should dynamically adjust if the page
-% size is changed through the document. To some extent, this is also true
+% size is changed through the document.
+% \changes{R2.1}{2020/05/11}{Let anchor directives be re-evaluated on
+% every page.}^^A
+% To some extent, this is also true
% of the anchor options. For instance, one may set the horizontal anchor
% |hanchor| at |\ifodd\thepage r\else l\fi| causing the anchor point to
% alternate between |r| and |l| at every new page. In conjunction with a
% similarly conditional |hpos| setting, for instance
-% |\ifodd\thepage \dimexpr\paperwidth-5mm\else 5mm\fi|, this enables
+% |\ifodd\thepage \dimexpr\paperwidth-5mm \else 5mm\fi|, this enables
% interesting effects, like placing the watermark close to the right side
% of the page on odd pages and to the left side of the page on even
% pages. Obviously, this kind of setting is only applicable with the
@@ -442,8 +454,33 @@
%
% \end{sloppy}
%
-% \section{Compatibility notes for package version 2.0 and later}
+% \section{Compatibility notes}
+%
+% \subsection{Compatibility notes for package version 3.0 and later}
+%
+% \changes{R3.0}{2020/12/08}{Remove dependency on package
+% \Lpack{everypage}.}^^A
+% Version 3.0 of the package takes advantage of the new functionalities
+% introduced in \hologo{LaTeX} with the Fall 2020 release and gets rid of
+% its dependency on \Lpack{everypage}. In principle, this could result in
+% behavioral differences in corner cases.
+%
+% \changes{R3.0}{2020/12/08}{Automatically load legacy code for older
+% \hologo{LaTeX} formats.}^^A
+% For users of versions of \hologo{LaTeX} before Fall 2020,
+% \Lpack{draftwatermarks} falls back to its own legacy code base, now
+% packaged as \Lpack{draftwatermark-2x}.
%
+% It is worth remarking that there is no advantage in trying to explicitly
+% load \Lpack{draftwatermark-2x} on a modern \hologo{LaTeX} to try to get
+% the past behavior. In fact, even if the old code base uses
+% \Lpack{everypage}, on modern \hologo{LaTeX} formats, the latter tries
+% itself to rely on the new \hologo{LaTeX} functionalities rather than its
+% own legacy mechanisms.
+%
+% \subsection{Compatibility notes for package version 2.0 and later}
+%
+% \changes{R2.0}{2020/03/08}{Complete package overhaul.}
% Version 2.0 of the package is an almost complete rewrite with respect to
% version 1.2. Specifically, all the configuration mechanism has been
% overhauled, by moving to an interface based on configuration keys and
@@ -465,6 +502,8 @@
% Command |\SetWatermarkAngle{<real>}| is the same as\\
% |\DraftwatermarkOptions{angle=<real>}|.
% \item \DescribeMacro{\SetWatermarkColor}^^A
+% \changes{R1.1}{2012/01/06}{Add support for specifying color
+% of textual watermark.}^^A
% Command |\SetWatermarkColor[<model>]{<color spec>}| is the same as\\
% |\DraftwatermarkOptions{color={[<model>]{<color spec>}}}|.
% \item \DescribeMacro{\SetWatermarkLightness}^^A
@@ -478,14 +517,18 @@
% Command |\SetWatermarkScale{<real>}| is the same as\\
% |\DraftwatermarkOptions{scale=<real>}|.
% \item \DescribeMacro{\SetWatermarkHorCenter}^^A
+% \changes{R1.2}{2015/02/19}{Add support for specifying the watermark
+% horizontal position.}^^A
% Command |\SetWatermarkHorCenter{<length>}| is the same as\\
% |\DraftwatermarkOptions{hpos=<length>, hanchor=c}|.
% \item \DescribeMacro{\SetWatermarkVerCenter}^^A
+% \changes{R1.2}{2015/02/19}{Add support for specifying the watermark
+% vertical position.}^^A
% Command |\SetWatermarkVerCenter{<length>}| is the same as\\
% |\DraftwatermarkOptions{vpos=<length>, vanchor=m}|.
% \item \DescribeMacro{\SetWatermarkText}^^A
% Command |\SetWatermarkText{<text>}| is the same as\\
-% |\DraftwatermarkOptions{text=<text>}|.
+% |\DraftwatermarkOptions{text={<text>}}|.
% \end{itemize}
%
% Note that the legacy interface supports only a subset of what is
@@ -503,7 +546,7 @@
% \fi
% \begin{macrocode}
\documentclass{article}
-\usepackage[named]{xcolor}
+\usepackage[svgnames]{xcolor}
\usepackage[T1]{fontenc}
\usepackage[firstpageonly, color={[gray]{0.5}},
text=DRAFT\\COPY]{draftwatermark}
@@ -526,7 +569,6 @@
% \iffalse
%</samplecode-modern>
% \fi
-% \makeatletter \c@CodelineNo\z@ \makeatother
%
% This produces a two pages document with placeholder content, putting a
% page-centered watermark on the first page only. The watermark is made a
@@ -541,7 +583,7 @@
% \fi
% \begin{macrocode}
\documentclass{article}
-\usepackage[named]{xcolor}
+\usepackage[svgnames]{xcolor}
\usepackage[T1]{fontenc}
\usepackage[firstpage]{draftwatermark}
\usepackage{mathptmx}
@@ -567,7 +609,6 @@
% \iffalse
%</samplecode-legacy>
% \fi
-% \makeatletter \c@CodelineNo\z@ \makeatother
%
% \subsection{Things that cannot be done with the legacy interface}
%
@@ -581,7 +622,7 @@
% \fi
% \begin{macrocode}
\documentclass{article}
-\usepackage[named]{xcolor}
+\usepackage[svgnames]{xcolor}
\usepackage[T1]{fontenc}
\usepackage[firstpage, anchor=tr, color=red,
pos={\dimexpr\paperwidth-5mm, 5mm},
@@ -606,7 +647,6 @@
% \iffalse
%</samplecode-anchor>
% \fi
-% \makeatletter \c@CodelineNo\z@ \makeatother
%
% Another interesting possibility of the modern interface derives from the
% fact that the positioning and anchoring options are re-evaluated for
@@ -619,7 +659,7 @@
% \fi
% \begin{macrocode}
\documentclass{article}
-\usepackage[named]{xcolor}
+\usepackage[svgnames]{xcolor}
\usepackage[T1]{fontenc}
\usepackage[color=red, fontsize=32pt]{draftwatermark}
\usepackage{mathptmx}
@@ -650,7 +690,6 @@
% \iffalse
%</samplecode-dynamic>
% \fi
-% \makeatletter \c@CodelineNo\z@ \makeatother
%
% \subsection{Maximum freedom with a custom watermarking command}
%
@@ -662,7 +701,7 @@
% \fi
% \begin{macrocode}
\documentclass{article}
-\usepackage[named]{xcolor}
+\usepackage[svgnames]{xcolor}
\usepackage[T1]{fontenc}
\usepackage{draftwatermark}
\usepackage{mathptmx}
@@ -697,7 +736,6 @@
% \iffalse
%</samplecode-custom>
% \fi
-% \makeatletter \c@CodelineNo\z@ \makeatother
%
%
% \section{Development and support}
@@ -711,23 +749,10 @@
% requests that, from the present document, would evidently require moving
% against some fundamental design decisions.
%
-% \section{Changelog}
-%
-% \begin{description}
-% \item[1.0 - 2006/06/30] Initial version.
-% \item[1.1 - 2012/01/06] Add support for colored watermarks; options to
-% disable watermarking; many small fixes in the documentation.
-% \item[1.2 - 2015/02/19] Add support for watermark position.
-% \item[2.0 - 2020/03/08] Configuration management overhaul; introduction
-% of a legacy interface for compatibility.
-% \item[2.1 - 2020/05/11] Allow anchor information to be re-evaluated on
-% every page.
-% \item[2.2 - 2020/06/29] Make line breaks in watermark text work.
-% \end{description}
-%
% \StopEventually {}
%
% \section{Implementation}
+% \subsection{Implementation of \Lpack{draftwatermark}}
%
% Announce the name and version of the package, which requires
% \LaTeXe.
@@ -737,7 +762,277 @@
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{draftwatermark}%
- [2020/06/29 2.2 Put a gray textual watermark on document pages]
+ [2020/12/08 3.0 Put a gray textual watermark on document pages]
+% \end{macrocode}
+% \changes{R3.0}{2020/12/08}{Automatically load legacy code for older
+% \hologo{LaTeX} formats.}^^A
+% Depending on the actual functionalities provided by \hologo{LaTeX}
+% consider loading \Lpack{draftwatermark-2x}. If so doing, warn about this,
+% and hand over the operation to that package.
+% \begin{macrocode}
+\@ifundefined{AddToHook}{%
+ \PackageWarningNoLine{draftwatermark}{%
+ You appear to be running a version of LaTeX\MessageBreak
+ unsupported by current draftwatermark.\MessageBreak
+ Forcing fallback to `draftwatermark-2x` that\MessageBreak
+ uses an older code base}%
+ \RequirePackageWithOptions{draftwatermark-2x}%
+ \endinput}{}
+% \end{macrocode}
+%
+% Require the needed packages.
+% \begin{macrocode}
+\RequirePackage{kvoptions}
+\RequirePackage{graphicx}
+\RequirePackage{color}
+% \end{macrocode}
+%
+% Define the configuration options and default values.
+% \begin{macrocode}
+\DeclareBoolOption[false]{firstpageonly}
+\define@key{draftwatermark}{firstpage}[true]{%
+ \csname draftwatermark@firstpageonly#1\endcsname}
+\DeclareBoolOption[true]{stamp}
+\DeclareComplementaryOption{nostamp}{stamp}
+\DeclareComplementaryOption{final}{stamp}
+\DeclareStringOption[45]{angle}
+\DeclareStringOption[1]{scale}
+\DeclareStringOption[DRAFT]{text}
+\DeclareStringOption[0.5\paperwidth]{hpos}
+\DeclareStringOption[0.5\paperheight]{vpos}
+\DeclareStringOption[0.25\paperwidth]{fontsize}
+\DeclareStringOption[gray]{colormodel}
+\DeclareStringOption[0.8]{colorspec}
+\DeclareStringOption[c]{hanchor}
+\DeclareStringOption[m]{vanchor}
+\DeclareStringOption[c]{alignment}
+\DeclareStringOption[\DraftwatermarkStdMark]{markcmd}
+\define@key{draftwatermark}{pos}{%
+ \draftwatermark@processpos #1\@nil}
+\define@key{draftwatermark}{anchor}{%
+ \draftwatermark@processanchor{#1}}
+\define@key{draftwatermark}{color}{%
+ \draftwatermark@processcolor #1\@nil}
+% \end{macrocode}
+%
+% Set up some helper marcros to process the options. These should be
+% rather self-explanatory.
+% \begin{macrocode}
+\def\draftwatermark@processpos#1,#2\@nil{%
+ \def\draftwatermark@hpos{#1}%
+ \def\draftwatermark@vpos{#2}}
+
+\def\draftwatermark@processanchor#1{%
+ \def\draftwatermark@tempa{#1}
+ \@onelevel@sanitize \draftwatermark@tempa
+ \expandafter \@tfor \expandafter \draftwatermark@tempb
+ \expandafter :\expandafter =\draftwatermark@tempa
+ \do
+ {%
+ \if \draftwatermark@tempb l%
+ \def \draftwatermark@hanchor{l}%
+ \else \if \draftwatermark@tempb c%
+ \def \draftwatermark@hanchor{c}%
+ \else \if \draftwatermark@tempb r%
+ \def \draftwatermark@hanchor{r}%
+ \else \if \draftwatermark@tempb t%
+ \def \draftwatermark@vanchor{t}%
+ \else \if \draftwatermark@tempb m%
+ \def \draftwatermark@vanchor{m}%
+ \else \if \draftwatermark@tempb b%
+ \def \draftwatermark@vanchor{b}
+ \else
+ \PackageError{draftwatermark}{%
+ Illegal anchor directive `\draftwatermark@tempb'}%
+ {Directive has been ingnored.}%
+ \fi\fi\fi\fi\fi\fi
+ }}
+
+\def\draftwatermark@processcolor{%
+ \@ifnextchar[
+ \draftwatermark@processcolor@ii\draftwatermark@processcolor@i}
+
+\def\draftwatermark@processcolor@i#1\@nil{%
+ \def\draftwatermark@colormodel{}%
+ \def\draftwatermark@colorspec{#1}}
+
+\def\draftwatermark@processcolor@ii[#1]#2\@nil{%
+ \def\draftwatermark@colormodel{#1}%
+ \def\draftwatermark@colorspec{#2}}
+
+% \end{macrocode}
+%
+% Process the package options\dots
+% \begin{macrocode}
+\ProcessKeyvalOptions*
+% \end{macrocode}
+%
+% \dots\, and then disable the |firstpageonly| and |firstpage| options,
+% that can only be used at the package loading time.
+% \begin{macrocode}
+\DisableKeyvalOption{draftwatermark}{firstpageonly}
+\DisableKeyvalOption{draftwatermark}{firstpage}
+
+% \end{macrocode}
+%
+% \begin{macro}{\DraftwatermarkOptions}
+% Set up a command to modify the configuration as needed.
+% \begin{macrocode}
+\newcommand\DraftwatermarkOptions[1]{\setkeys{draftwatermark}{#1}}
+
+% \end{macrocode}
+% \end{macro}
+%
+% Introduce the legacy interface.
+% \begin{macro}{\SetWatermarkAngle}
+% Legacy command to set the rotation angle for the standard watermark
+% \begin{macrocode}
+\newcommand\SetWatermarkAngle[1]{\DraftwatermarkOptions{angle=#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SetWatermarkFontSize}
+% Legacy command to set the font size for the standard watermark
+% \begin{macrocode}
+\newcommand\SetWatermarkFontSize[1]{\DraftwatermarkOptions{fontsize=#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SetWatermarkScale}
+% Legacy command to set the scale for the standard watermark
+% \begin{macrocode}
+\newcommand\SetWatermarkScale[1]{\DraftwatermarkOptions{scale=#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SetWatermarkHorCenter}
+% \begin{macro}{\SetWatermarkVerCenter}
+% Legacy commands to set the horizontal and vertical position for the
+% standard watermark, also forcing it to be centered there.
+% \begin{macrocode}
+\newcommand\SetWatermarkHorCenter[1]{%
+ \DraftwatermarkOptions{hpos=#1, hanchor=c}}
+\newcommand\SetWatermarkVerCenter[1]{%
+ \DraftwatermarkOptions{vpos=#1, vanchor=m}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\SetWatermarkText}
+% \changes{R2.3}{2020/12/06}{Fix legacy interface to accept
+% text including commas.}^^A
+% Legacy command to set the text of the standard watermark
+% \begin{macrocode}
+\newcommand\SetWatermarkText[1]{\DraftwatermarkOptions{text={#1}}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SetWatermarColor}
+% \begin{macro}{\SetWatermarkLightness}
+% Legacy commands to set the color for the
+% standard watermark.
+% \begin{macrocode}
+\newcommand\SetWatermarkColor[2][]{%
+ \DraftwatermarkOptions{colormodel=#1, colorspec=#2}}
+\newcommand\SetWatermarkLightness[1]{%
+ \DraftwatermarkOptions{colormodel=gray, colorspec=#1}}
+
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DraftwatermarkStdMark}
+% The command to generate the standard watermark
+% \changes{R2.2}{2020/06/29}{Wrap watermark text in a shortstack to make
+% line breaks possible.}
+% \begin{macrocode}
+\newcommand\DraftwatermarkStdMark{%
+ \rotatebox{\draftwatermark@angle}{%
+ \scalebox{\draftwatermark@scale}{%
+ \begingroup
+ \ifx\draftwatermark@colormodel\@empty
+ \color{\draftwatermark@colorspec}%
+ \else
+ \color[\draftwatermark@colormodel]{\draftwatermark@colorspec}%
+ \fi
+ \setlength{\@tempdima}{\draftwatermark@fontsize}%
+ \fontsize{\@tempdima}{1.2\@tempdima}\selectfont
+ \shortstack[\draftwatermark@alignment]{\draftwatermark@text}%
+ \endgroup}}}
+
+% \end{macrocode}
+% \end{macro}
+%
+% The code to actually print the watermark
+% \begin{macrocode}
+\newcommand\draftwatermark@printwm[1]{%
+ \sbox\@tempboxa{\raisebox{\depth}{#1}}%
+ \setlength{\@tempdima}{\draftwatermark@hpos}%
+ \setlength{\@tempdimb}{-\draftwatermark@vpos}%
+ \edef \draftwatermark@tempa{\draftwatermark@hanchor}%
+ \@onelevel@sanitize \draftwatermark@tempa
+ \expandafter\def\expandafter\draftwatermark@tempb
+ \expandafter{\expandafter\@car \draftwatermark@tempa\@nil}%
+ \if \draftwatermark@tempb r%
+ \addtolength\@tempdima{-\wd\@tempboxa}%
+ \else\if \draftwatermark@tempb c%
+ \addtolength\@tempdima{-0.5\wd\@tempboxa}%
+ \else\if \draftwatermark@tempb l%
+ \relax
+ \else
+ \PackageError{draftwatermark}{%
+ Illegal anchor directive `\draftwatermark@tempb'}%
+ {Anchoring to left side.}%
+ \fi\fi\fi
+ \edef \draftwatermark@tempa{\draftwatermark@vanchor}%
+ \@onelevel@sanitize \draftwatermark@tempa
+ \expandafter\def\expandafter\draftwatermark@tempb
+ \expandafter{\expandafter\@car \draftwatermark@tempa\@nil}%
+ \if \draftwatermark@tempb b%
+ \relax
+ \else\if \draftwatermark@tempb m%
+ \addtolength\@tempdimb{-0.5\ht\@tempboxa}%
+ \else\if \draftwatermark@tempb t%
+ \addtolength\@tempdimb{-\ht\@tempboxa}%
+ \else
+ \PackageError{draftwatermark}{%
+ Illegal anchor directive `\draftwatermark@tempb'}%
+ {Anchoring to top side.}%
+ \fi\fi\fi
+ \put(\@tempdima,\@tempdimb){\usebox\@tempboxa}%
+}
+
+% \end{macrocode}
+%
+% A wrapper to make the watermark printing conditional
+% \begin{macrocode}
+\newcommand\draftwatermark@print[1]{%
+ \ifdraftwatermark@stamp
+ \draftwatermark@printwm{#1}%
+ \fi}
+% \end{macrocode}
+%
+% \dots\, and finally the code to set up the \Lpack{everypage} hooks to
+% assure that the watermark printing commands are called when needed
+% \begin{macrocode}
+\ifdraftwatermark@firstpageonly
+ \AddToHookNext{shipout/background}{%
+ \draftwatermark@print{\draftwatermark@markcmd}}%
+\else
+ \AddToHook{shipout/background}{%
+ \draftwatermark@print{\draftwatermark@markcmd}}%
+\fi
+% \end{macrocode}
+% \iffalse
+%</draftwatermark>
+% \fi
+%
+% \subsection{Implementation of \Lpack{draftwatermark-2x}}
+%
+% Announce the name and version of the package, which requires
+% \LaTeXe.
+% \iffalse
+%<*draftwatermark-2x>
+% \fi
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{draftwatermark}%
+ [2020/12/06 2.3 Put a gray textual watermark on document pages]
% \end{macrocode}
%
@@ -749,6 +1044,11 @@
\RequirePackage{color}
% \end{macrocode}
+% Set up options and assumptions for the \Lpack{kvoptions} package
+% \begin{macrocode}
+\SetupKeyvalOptions{family=draftwatermark, prefix=draftwatermark@}
+
+% \end{macrocode}
%
% Define the configuration options and default values.
% \begin{macrocode}
@@ -879,9 +1179,11 @@
% \end{macro}
% \end{macro}
% \begin{macro}{\SetWatermarkText}
+% \changes{R2.3}{2020/12/06}{Fix legacy interface to accept
+% text including commas.}^^A
% Legacy command to set the text of the standard watermark
% \begin{macrocode}
-\newcommand\SetWatermarkText[1]{\DraftwatermarkOptions{text=#1}}
+\newcommand\SetWatermarkText[1]{\DraftwatermarkOptions{text={#1}}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\SetWatermarColor}
@@ -985,30 +1287,31 @@
\AddEverypageHook{\draftwatermark@print{\draftwatermark@markcmd}}
\fi
% \end{macrocode}
-
-
% \iffalse
-%</draftwatermark>
+%</draftwatermark-2x>
% \fi
%
+%
% \Finale
+% \PrintChanges
+% \pagebreak[1]
% \PrintIndex
%
-%% \CharacterTable
-%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
-%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
-%% Digits \0\1\2\3\4\5\6\7\8\9
-%% Exclamation \! Double quote \" Hash (number) \#
-%% Dollar \$ Percent \% Ampersand \&
-%% Acute accent \' Left paren \( Right paren \)
-%% Asterisk \* Plus \+ Comma \,
-%% Minus \- Point \. Solidus \/
-%% Colon \: Semicolon \; Less than \<
-%% Equals \= Greater than \> Question mark \?
-%% Commercial at \@ Left bracket \[ Backslash \\
-%% Right bracket \] Circumflex \^ Underscore \_
-%% Grave accent \` Left brace \{ Vertical bar \|
-%% Right brace \} Tilde \~}
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
\endinput
%%% Local Variables:
diff --git a/macros/latex/contrib/draftwatermark/draftwatermark.ins b/macros/latex/contrib/draftwatermark/draftwatermark.ins
index 1365e64ebf..151fcec0a0 100644
--- a/macros/latex/contrib/draftwatermark/draftwatermark.ins
+++ b/macros/latex/contrib/draftwatermark/draftwatermark.ins
@@ -7,12 +7,14 @@
%% a contribution to the LaTeX2e system.
%% ---------------------------------------------
%%
-%% It may be distributed and/or modified under the conditions of the LaTeX
-%% Project Public License, version 1.3. The license is at
-%% https://www.latex-project.org/lppl/ and is part of all distributions of
-%% LaTeX version 2005/12/01 or later.
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, version 1.3c.
+%% This license is in
+%% https://www.latex-project.org/lppl/lppl-1-3c/
+%% and is part of all distributions of LaTeX later than
+%% 2008-05-04.
%%
-%% This work has the LPPL maintenance status "author-maintained".
+%% This work has the LPPL maintenance status "maintained".
%%
%% This program consists of the files listed in the README.md file
%% included in the package.
@@ -43,35 +45,39 @@ a contribution to the LaTeX2e system.
This program consists of the files listed in the README.md file included
in the package.
-Any modified versions of this file must be renamed with new filenames distinct
-from draftwatermark.sty.
+Any modified versions of this file must be renamed with new filenames
+distinct from \outFileName.
For distribution of the original source see the terms for copying and
-modification in the file draftwatermark.dtx.
+modification in the file \inFileName.
-This generated file may be distributed as long as the original source files, as
-listed above, are part of the same distribution. (The sources need not
+This generated file may be distributed as long as the original source files,
+as listed above, are part of the same distribution. (The sources need not
necessarily be in the same archive or directory.)
\endpreamble
\Msg{*** Generating the LaTeX2e package files ***}
+\usedir{tex/latex/draftwatermark}
\generate{\file{draftwatermark.sty}{%
- \from{draftwatermark.dtx}{draftwatermark}}}
+ \from{draftwatermark.dtx}{draftwatermark}}}
+\generate{\file{draftwatermark-2x.sty}{%
+ \from{draftwatermark.dtx}{draftwatermark-2x}}}
\preamble
\endpreamble
\Msg{*** Generating the example files ***}
-\generate{\file{test_draftwatermark1.tex}{%
+\usedir{doc/latex/draftwatermark/examples}
+\generate{\file{test_draftwatermark-1.tex}{%
\from{draftwatermark.dtx}{samplecode-modern}}}
-\generate{\file{test_draftwatermark2.tex}{%
+\generate{\file{test_draftwatermark-2.tex}{%
\from{draftwatermark.dtx}{samplecode-legacy}}}
-\generate{\file{test_draftwatermark3.tex}{%
+\generate{\file{test_draftwatermark-3.tex}{%
\from{draftwatermark.dtx}{samplecode-anchor}}}
-\generate{\file{test_draftwatermark4.tex}{%
+\generate{\file{test_draftwatermark-4.tex}{%
\from{draftwatermark.dtx}{samplecode-dynamic}}}
-\generate{\file{test_draftwatermark5.tex}{%
+\generate{\file{test_draftwatermark-5.tex}{%
\from{draftwatermark.dtx}{samplecode-custom}}}
%\ReportTotals
@@ -84,14 +90,18 @@ necessarily be in the same archive or directory.)
\Msg{* \space\space draftwatermark.sty}
\Msg{*}
\Msg{*}
-\Msg{* To produce the documentation run draftwatermark.dtx}
-\Msg{* through LaTeX (or maybe pdfLaTeX).}
+\Msg{* To produce the documentation:
+run draftwatermark.dtx}
+\Msg{* - run draftwatermark.dtx through LaTeX}
\Msg{* Process draftwatermark.idx file by:}
\Msg{* \space\space\space\space makeindex -s gind.ist draftwatermark}
-%\Msg{* Process draftwatermark.glo file by:}
-%\Msg{* \space\space\space\space makeindex -s gglo.ist -o draftwatermark.gls
-% draftwatermark.glo}
+\Msg{* Process draftwatermark.glo file by:}
+\Msg{* \space\space\space\space makeindex -s gglo.ist -o draftwatermark.gls
+ draftwatermark.glo}
\Msg{* Re run through LaTeX the draftwatermark.dtx file as necessary}
+\Msg{* You may then want to move the test_draftwatermark*.tex files produced by}
+\Msg{* processing this ins file together with the documentation (e.g., in an}
+\Msg{* examples subdirectory}
\Msg{*}
\Msg{***********************************************************}
diff --git a/macros/latex/contrib/draftwatermark/draftwatermark.pdf b/macros/latex/contrib/draftwatermark/draftwatermark.pdf
index e872276964..9b79678161 100644
--- a/macros/latex/contrib/draftwatermark/draftwatermark.pdf
+++ b/macros/latex/contrib/draftwatermark/draftwatermark.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/README b/macros/latex/contrib/jslectureplanner/README
index 5f9da681e1..e5dae559d2 100644
--- a/macros/latex/contrib/jslectureplanner/README
+++ b/macros/latex/contrib/jslectureplanner/README
@@ -68,6 +68,8 @@ instructions; also have a look at the example files.
== CHANGES ==
+* V. 1.12 (2020-12-08): - Correctly parse staryear/endyear.
+
* V. 1.11 (2020-05-11): - Allow for customization of program and presentation lists.
- Correctly set first session in presentation list.
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/lecturebib-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/lecturebib-english.pdf
index ae0607b469..7fe67e794f 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/lecturebib-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/lecturebib-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/lecturehandout-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/lecturehandout-english.pdf
index 54a3fe2529..24941bb9b1 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/lecturehandout-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/lecturehandout-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/lecturepresentation-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/lecturepresentation-english.pdf
index 1d90d42f0c..4f8220e8e5 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/lecturepresentation-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/lecturepresentation-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/lectureprogram-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/lectureprogram-english.pdf
index ac529f1a97..0b8f229180 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/lectureprogram-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/lectureprogram-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/lecturescript-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/lecturescript-english.pdf
index f949f346aa..b756c85705 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/lecturescript-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/lecturescript-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/membertable-blank-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/membertable-blank-english.pdf
index 8618c4a994..30b972c602 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/membertable-blank-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/membertable-blank-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/membertable-filled-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/membertable-filled-english.pdf
index 619c62ce97..c844df95f2 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/membertable-filled-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/membertable-filled-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/presencetable-blank-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/presencetable-blank-english.pdf
index 826431e8b1..fbfee149f8 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/presencetable-blank-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/presencetable-blank-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/presencetable-filled-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/presencetable-filled-english.pdf
index a51da79d67..4e81e8d909 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/presencetable-filled-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/presencetable-filled-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/English/presentation-list-english.pdf b/macros/latex/contrib/jslectureplanner/examples/English/presentation-list-english.pdf
index 3effb91217..883a071f06 100644
--- a/macros/latex/contrib/jslectureplanner/examples/English/presentation-list-english.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/English/presentation-list-english.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/lecturebib.pdf b/macros/latex/contrib/jslectureplanner/examples/German/lecturebib.pdf
index a30a8d7d73..dc7be35d41 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/lecturebib.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/lecturebib.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/lecturehandout.pdf b/macros/latex/contrib/jslectureplanner/examples/German/lecturehandout.pdf
index 4df0807950..3bd76674b0 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/lecturehandout.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/lecturehandout.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/lecturepresentation.pdf b/macros/latex/contrib/jslectureplanner/examples/German/lecturepresentation.pdf
index 7494a82a67..4e02a240b8 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/lecturepresentation.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/lecturepresentation.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/lectureprogram.pdf b/macros/latex/contrib/jslectureplanner/examples/German/lectureprogram.pdf
index 326beb4f68..58cf55305f 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/lectureprogram.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/lectureprogram.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/lecturescript.pdf b/macros/latex/contrib/jslectureplanner/examples/German/lecturescript.pdf
index d353936903..1f535cb2f1 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/lecturescript.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/lecturescript.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/membertable-blank.pdf b/macros/latex/contrib/jslectureplanner/examples/German/membertable-blank.pdf
index 3ecc09846a..67df001b4c 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/membertable-blank.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/membertable-blank.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/membertable-filled.pdf b/macros/latex/contrib/jslectureplanner/examples/German/membertable-filled.pdf
index 303b1dae40..db9feda975 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/membertable-filled.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/membertable-filled.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/presencetable-blank.pdf b/macros/latex/contrib/jslectureplanner/examples/German/presencetable-blank.pdf
index 464a6c7f3b..b846ca5779 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/presencetable-blank.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/presencetable-blank.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/presencetable-filled.pdf b/macros/latex/contrib/jslectureplanner/examples/German/presencetable-filled.pdf
index d09b39386e..0cd64cb49a 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/presencetable-filled.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/presencetable-filled.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/examples/German/presentation-list.pdf b/macros/latex/contrib/jslectureplanner/examples/German/presentation-list.pdf
index 0050ea7045..62f446fa15 100644
--- a/macros/latex/contrib/jslectureplanner/examples/German/presentation-list.pdf
+++ b/macros/latex/contrib/jslectureplanner/examples/German/presentation-list.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/jslectureplanner.pdf b/macros/latex/contrib/jslectureplanner/jslectureplanner.pdf
index 7a0c357150..971a3b29bc 100644
--- a/macros/latex/contrib/jslectureplanner/jslectureplanner.pdf
+++ b/macros/latex/contrib/jslectureplanner/jslectureplanner.pdf
Binary files differ
diff --git a/macros/latex/contrib/jslectureplanner/jslectureplanner.sty b/macros/latex/contrib/jslectureplanner/jslectureplanner.sty
index 72c62b27fa..31bbfd3530 100644
--- a/macros/latex/contrib/jslectureplanner/jslectureplanner.sty
+++ b/macros/latex/contrib/jslectureplanner/jslectureplanner.sty
@@ -23,8 +23,8 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\def\filedate{2020/05/11}
-\def\fileversion{1.11}
+\def\filedate{2020/12/08}
+\def\fileversion{1.12}
\def\filename{jslectureplanner.sty}
\NeedsTeXFormat{LaTeX2e}
@@ -58,6 +58,8 @@
\def\lecnsemverb{}
\def\lecnsemny{}
\def\lecyear{}
+\def\lecendyear{}
+\def\lecendyearsep{/}
\def\lecsemester{}
\def\lecsemesterverb{}
\def\lecuniversity{}
@@ -256,6 +258,7 @@
\def\lecshorttitle{#1}%
\global\toggletrue{uniquelecshorttitle}}
\define@key{lec}{year}{\def\lecyear{#1}}
+\define@key{lec}{endyear}{\def\lecendyear{#1}}
\define@key{lec}{uni}{\def\lecuniversity{#1}}
\define@key{lec}{institute}{\def\lecinstitute{#1}}
\define@key{lec}{platform}{\def\lecplatform{#1}}
@@ -313,12 +316,31 @@
%
% ALTERNATIVE SETUP MACROS
%
+\RequirePackage{xparse}
+
+% LecYear parses and splits {...}{startyear/endyear}
+\ExplSyntaxOn
+\NewDocumentCommand \LecYear { m m }
+{
+ % #1: semester/term
+ \setkeys{lec}{lecsem=#1}
+ % split #2 at / if available (startyear/endyear)
+ \seq_set_split:Nnn \seq_jslp_lec_year { / } { #2 }
+ \seq_pop_left:NNT \seq_jslp_lec_year \tl_jslp_start_year
+ {
+ \setkeys{lec}{year=\tl_jslp_start_year}
+ }
+ \seq_get_right:NNT \seq_jslp_lec_year \tl_jslp_end_year
+ {
+ \setkeys{lec}{endyear=\tl_jslp_end_year}
+ }
+}
+\ExplSyntaxOff
\newcommand*{\LecType}[1]{\setkeys{lec}{lectype=#1}}
\newcommand*{\LecTitle}[2][]{\setkeys{lec}{shorttitle={#2},#1,title={#2}}}
\newcommand*{\LecTitleSep}[1]{\setkeys{lec}{titlesep={#1}}}
\newcommand*{\LecSubTitle}[1]{\setkeys{lec}{subtitle={#1}}}
-\newcommand*{\LecYear}[2]{\setkeys{lec}{lecsem=#1,year=#2}}
\newcommand*{\LecUni}[1]{\setkeys{lec}{uni={#1}}}
\newcommand*{\LecInstitute}[1]{\setkeys{lec}{institute={#1}}}
\newcommand*{\LecRoom}[1]{\setkeys{lec}{room={#1}}}
@@ -341,7 +363,6 @@
%
% Courtesy of Christian Hupfer at
% https://tex.stackexchange.com/a/473552/19291
-\RequirePackage{xparse}
\ExplSyntaxOn
\cs_generate_variant:Nn \int_set:Nn {NV}
@@ -384,8 +405,8 @@
%
% CONCATENATED VARIABLES
%
-\def\lecsemester{\lecsemshort~\lecyear}
-\def\lecsemesterverb{\lecsemverb\ \lecyear}
+\def\lecsemester{\lecsemshort~\lecyear\ifcsempty{lecendyear}{}{\lecendyearsep\lecendyear}}
+\def\lecsemesterverb{\lecsemverb\ \lecyear\ifcsempty{lecendyear}{}{\lecendyearsep\lecendyear}}
\def\lecfulltitle{\lectitle\lectitlesep\lecsubtitle}
\def\sesfulltitle{\sestitle\sestitlesep\sessubtitle}
\def\lecendtime{\jslp@endtime{\@lecstarttime}{\lecduration}}
diff --git a/macros/latex/contrib/jslectureplanner/jslectureplanner.tex b/macros/latex/contrib/jslectureplanner/jslectureplanner.tex
index 4792ba03bb..ecadf4b79a 100644
--- a/macros/latex/contrib/jslectureplanner/jslectureplanner.tex
+++ b/macros/latex/contrib/jslectureplanner/jslectureplanner.tex
@@ -87,7 +87,7 @@ colorlinks=false
\author{Jürgen Spitzmüller%
\thanks{Please report issues via \protect\url{https://github.com/jspitz/jslectureplanner}.}}
-\date{Version 1.11, 2020/05/11}
+\date{Version 1.12, 2020/12/08}
\maketitle
@@ -238,7 +238,8 @@ Please also cf. sec.~\ref{sec:styles} on the concept of ``styles''.
Sec.~\ref{sec:customizing-strings} explains how to customize and extend this list.
Also cf. sec.~\ref{sec:styles}.
-\item [\joption{year=\jparam{year}}] Year of the term
+\item [\joption{year=\jparam{year}}] (Start) year of the term
+\item [\joption{endyear=\jparam{year}}] End year of the term if applicable (in case of terms such as \emph{Winter Term 2020/21})
\item [\joption{uni=\jparam{university}}] Your university
\item [\joption{institute=\jparam{institute}}] Your institute/department
\item [\joption{room=\jparam{room}}] The room where the course generally takes place;
@@ -315,6 +316,10 @@ description.}
\item \joption{ss}: Summer term (\emph{Sommersemester})
\item \joption{ws}: Winter term (\emph{Wintersemester})
\end{itemize}
+%
+If the \joption{\jparam{year}} spans multiple years, always use a slash as separator (e.\,g., 2020/21)
+for parsing purposes in the input.
+The separator that is used in the output can be customized (see sec.~\ref{sec:custstrings}).
\item \jcsmacro{LecUni\{\jparam{university}\}}: Record the name of
your university
\item \jcsmacro{LecInstitute\{\jparam{institute}\}}: Record your institute's/department's name
@@ -358,7 +363,6 @@ your university
\item \jcsmacro{SessionTitleSep\{\jparam{separator}\}}: Specify a default separator between session title and subtitle (e.\,g., ``. '' or `` -- ''). This is used if no specific separator has been specified in the session entry (see sec.~\ref{sec:lecplan}); by default, no separator is defined.
\end{itemize}
-\clearpage
\section{Setting up a course schedule}\label{sec:lecplan}
@@ -512,11 +516,13 @@ there is a unique short title by the test
the term type (e.\,g., ``WS'')
\item \jcsmacro{lecsemverb}: Outputs the verbose version
of the term type (such as ``Winter\-semester'')
-\item \jcsmacro{lecyear}: Outputs the year
+\item \jcsmacro{lecyear}: Outputs the (start) year
+\item \jcsmacro{lecendyear}: Outputs the end year if available
+\item \jcsmacro{lecendyearsep}: Outputs the separator between start and end year (slash by default)
\item \jcsmacro{lecsemester}: Outputs the short version of
-the semester (e.\,g., ``WS 2014'')
+the semester (e.\,g., ``WS 2014/15'')
\item \jcsmacro{lecsemesterverb}: Outputs the verbose version
-of the semester (such as ``Winter\-semester 2014'')
+of the semester (such as ``Winter\-semester 2014/15'')
\item \jcsmacro{adjsemester}: Outputs the short version of
the semester that \emph{follows} this one (e.\,g., ``SoSe 2015'')
\item \jcsmacro{adjsemesterverb}: Outputs the verbose version
@@ -999,7 +1005,7 @@ Analogous macros for canceled session items, exam items and presentation list it
\begin{lstlisting}[language={[LaTeX]TeX},basicstyle={\small\ttfamily},
frame=single,moretexcs={[3]{ProgramListCancelItem,programdateformat,cansestitleformat}}]
\newcommand*{\ProgramListCancelItem}[4]{\item[\programdateformat{#1}]
- \cansestitleformat{#2#3#4 \leccancel}}
+ \cansestitleformat{#2#3#4\leccancel}}
\end{lstlisting}
\begin{lstlisting}[language={[LaTeX]TeX},basicstyle={\small\ttfamily},
frame=single,moretexcs={[3]{ProgramListExamItem,programdateformat,exsestitleformat}}]
@@ -1132,7 +1138,7 @@ frame=single,moretexcs={[1]{breakevent}}]
and if so, it is output followed by the separator given as second argument and the break
title (\texttt{\#2}). If not, only the break title (\texttt{\#2}) is output.
-\subsubsection{Strings}
+\subsubsection{Strings}\label{sec:custstrings}
For canceled sessions, the program outputs
``\jparam{Session title} -- keine \jparam{Session}'' (``keine''
@@ -1163,6 +1169,12 @@ an em-dash), can be redefined by changing
moretexcs={[1]{emptypressession}}]
\newcommand*\emptypressession{---}
\end{lstlisting}
+%
+The separator between start and end year of a term can be redefined by changing
+\begin{lstlisting}[language={[LaTeX]TeX},basicstyle={\small\ttfamily},frame=single,
+moretexcs={[1]{lecendyearsep}}]
+\newcommand*\lecendyearsep{/}
+\end{lstlisting}
\subsection{Using styles}\label{sec:styles}
@@ -1427,6 +1439,10 @@ the \jslp\ style files. Thanks, Dominik.
\section{Release History}
\begin{itemize}
+\item 2020/12/08 (v. 1.12):
+ \begin{itemize}
+ \item Correctly parse staryear/endyear.
+ \end{itemize}
\item 2020/05/11 (v. 1.11):
\begin{itemize}
\item Allow for customization of program and presentation lists (see sec.~\ref{sec:listcust}).
diff --git a/macros/latex/contrib/jslectureplanner/jsmembertable.sty b/macros/latex/contrib/jslectureplanner/jsmembertable.sty
index 8d8b634bba..a371a492a5 100644
--- a/macros/latex/contrib/jslectureplanner/jsmembertable.sty
+++ b/macros/latex/contrib/jslectureplanner/jsmembertable.sty
@@ -24,8 +24,8 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\def\filedate{2020/05/11}
-\def\fileversion{1.11}
+\def\filedate{2020/12/08}
+\def\fileversion{1.12}
\def\filename{jsmembertable.sty}
\NeedsTeXFormat{LaTeX2e}
diff --git a/macros/latex/contrib/microtype/README.md b/macros/latex/contrib/microtype/README.md
index 47a727711c..bef433731f 100644
--- a/macros/latex/contrib/microtype/README.md
+++ b/macros/latex/contrib/microtype/README.md
@@ -4,7 +4,7 @@ The `microtype` package
**Subliminal refinements towards typographical perfection**
- (v2.7d -- 2019/11/18)
+ (v2.8 -- 2020/12/07)
Overview
@@ -76,5 +76,4 @@ provided that: (1) the original copyright statement is not removed, and
(2) the identification string is changed.
------------------------------------------------------
-Copyright (c) 2004--2019 R Schlicht `<w.m.l@gmx.net>`
-------------------------------------------------------
+Copyright (c) 2004--2020 R Schlicht `<w.m.l@gmx.net>`
diff --git a/macros/latex/contrib/microtype/microtype-utf.dtx b/macros/latex/contrib/microtype/microtype-utf.dtx
index 36b08620a2..7bc673f3de 100644
--- a/macros/latex/contrib/microtype/microtype-utf.dtx
+++ b/macros/latex/contrib/microtype/microtype-utf.dtx
@@ -1,11 +1,11 @@
%\iffalse meta-comment
% !Mode:: "TeX:DTX:UK"
% !smartQuote:: "English"
-% !DTXversion:: "2.7d"
+% !DTXversion:: "2.8"
% ------------------------------------------------------------------------
% The `microtype' package
% Subliminal refinements towards typographical perfection
-% Copyright (c) 2004--2019 R Schlicht <w.m.l@gmx.net>
+% Copyright (c) 2004--2020 R Schlicht <w.m.l@gmx.net>
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3c of this license or (at
@@ -26,7 +26,7 @@
%
\ProvidesFile
%<*driver>
- {\jobname.dtx}[2019/11/18 v2.7d]
+ {\jobname.dtx}[2020/12/07 v2.8]
%</driver>
%<CharisSIL> {mt-CharisSIL.cfg}[2017/07/07 v1.1 microtype config. file: Charis SIL (RS)]
%<LatinModernRoman> {mt-LatinModernRoman.cfg}[2013/03/13 v1.0 microtype config. file: Latin Modern Roman (RS)]
@@ -113,6 +113,7 @@ luatexbase.add_to_callback("pre_linebreak_filter", nodeprocessor, "replace missi
% \fi
%\StopEventually{}
%
+% ^^A -------------------------------------------------------------------------
%\GeneralChanges{Documentation}
%\changes{v2.5a}{2013/05/15}{include OpenType configuration files}
%\changes{v2.6}{2015/12/07}{missing characters printed with Charis <SIL>}
diff --git a/macros/latex/contrib/microtype/microtype.dtx b/macros/latex/contrib/microtype/microtype.dtx
index 9f92e7296f..698eec0772 100644
--- a/macros/latex/contrib/microtype/microtype.dtx
+++ b/macros/latex/contrib/microtype/microtype.dtx
@@ -1,11 +1,11 @@
%\iffalse meta-comment
% !Mode:: "TeX:DTX:UK"
% !smartQuote:: "English"
-% !DTXversion:: "2.7d"
+% !DTXversion:: "2.8"
% ------------------------------------------------------------------------
% The `microtype' package
% Subliminal refinements towards typographical perfection
-% Copyright (c) 2004--2019 R Schlicht <w.m.l@gmx.net>
+% Copyright (c) 2004--2020 R Schlicht <w.m.l@gmx.net>
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3c of this license or (at
@@ -37,7 +37,7 @@
%<luatex-def> {microtype-luatex.def}
%<xetex-def> {microtype-xetex.def}
%<*package|letterspace|m-t|pdftex-def|luatex-def|xetex-def>
- [2019/11/18 v2.7d
+ [2020/12/07 v2.8
%<package> Micro-typographical refinements
%<letterspace> Robust letterspacing
%<m-t> microtype main configuration file
@@ -51,8 +51,8 @@
%<luafile>local microtype = microtype
%<luafile>microtype.module = {
%<luafile> name = "microtype",
-%<luafile> version = "2.7d",
-%<luafile> date = "2019/11/18",
+%<luafile> version = "2.8",
+%<luafile> date = "2020/12/07",
%<luafile> description = "microtype module.",
%<luafile> author = "E. Roux, R. Schlicht and P. Gesang",
%<luafile> copyright = "E. Roux, R. Schlicht and P. Gesang",
@@ -91,7 +91,7 @@
\def\SourceSansPro@scale{1.02}
\def\ttdefault{blg}
{\ttfamily\selectfont
- \DeclareFontShape{T1}{blg}{k}{n}{<-> ssub * blg/b/n}{}}
+ \DeclareFontShape{T1}{blg}{eb}{n}{<-> ssub * blg/b/n}{}}
\usepackage{textcomp}
\usepackage{iftex}
%<*!docsty>
@@ -192,11 +192,11 @@
\def\PackageFont{\sffamily}
\def\match{\textbullet}
\usepackage{amssymb} % \varnothing
- \let\OrigTeX\TeX
+ \expandafter\let\expandafter\OrigTeX\csname TeX \endcsname
\DeclareRobustCommand\TeX{\textoractual{\OrigTeX}{TeX}}
\setlength\textheight{49\baselineskip}
\else
- \def\bfdefault{b}
+ \let\bfdefault\bfdefault@previous % undo mathdesign's \def\bdefault{b}
\def\Module#1{{\color{theblue}\textoractual{$\langle$}{<}\textit{#1}\textoractual{$\rangle$}{>}}}
\DeclareRobustCommand\TeX{\textoractual{T\kern-.1em\lower.4ex\hbox{E}\kern-.075emX\@}{TeX}}
\DeclareRobustCommand\LaTeX{\textoractual{L\kern-.26em{\sbox\z@ T\vbox to\ht\z@{%
@@ -206,6 +206,7 @@
\def\match{{\large\raisebox{-.15em}{\textbullet}}}
{\catcode`\`=\active % indiscernible from ' in Bitstream Letter Gothic
\g@addto@macro\macro@code{\let`\textasciigrave}}
+ \DeclareEncodingSubset{TS1}{blg}{1} % for \textasciigrave
\linespread{1.07}\normalfont
\setlength\textheight{48\baselineskip}
\fi
@@ -217,15 +218,15 @@
\def\section{\@startsection {section}{1}{\z@}%
{-3.5ex \@plus -1ex \@minus -.2ex}%
{2.3ex \@plus.2ex}%
- {\normalfont\Large\ifcmr\fontseries{bx}\else\fontseries{k}\fi\sffamily\color{sectioning}}}
+ {\normalfont\Large\ifcmr\fontseries{bx}\else\fontseries{eb}\fi\sffamily\color{sectioning}}}
\def\subsection{\@startsection{subsection}{2}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{1.5ex \@plus .2ex}%
- {\normalfont\large\ifcmr\fontseries{bx}\else\fontseries{k}\fi\sffamily\color{sectioning}}}
+ {\normalfont\large\ifcmr\fontseries{bx}\else\fontseries{eb}\fi\sffamily\color{sectioning}}}
\def\subsubsection{\@startsection{subsubsection}{3}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{1.5ex \@plus .2ex}%
- {\normalfont\normalsize\ifcmr\fontseries{bx}\else\fontseries{k}\fi\sffamily\color{sectioning}}}
+ {\normalfont\normalsize\ifcmr\fontseries{bx}\else\fontseries{eb}\fi\sffamily\color{sectioning}}}
\def\paragraph{\@startsection{paragraph}{4}%
{0pt}{8pt plus 2pt minus 1pt}{-1em}%
{\normalfont\normalsize\itshape}}
@@ -559,7 +560,8 @@
colorlinks,linkcolor=theblue,citecolor=theblue,urlcolor=thered,
hyperindex=false,hyperfootnotes=false]
{hyperref}
- \usepackage{hyperxmp}
+ \PassOptionsToPackage{nodvi}{totpages} % remove annoying log output
+ \usepackage{hyperxmp} % (hyperxmp loads totpages)
\usepackage{attachfile}
\usepackage{pdfpages}
\hypersetup{
@@ -569,7 +571,7 @@
pdfkeywords={TeX, LaTeX, pdfTeX, LuaTeX, XeTeX, typography, micro-typography,
character protrusion, margin kerning, optical alignment, font expansion,
font scaling, hz, kerning, spacing, glue, letterspacing, tracking, ligatures},
- pdfcopyright={\textcopyright\ 2004--2019 R Schlicht\012%
+ pdfcopyright={\textcopyright\ 2004--2020 R Schlicht\012%
This work may be distributed and/or modified under the conditions
of the LaTeX Project Public License, either version 1.3c of this
license or (at your option) any later version.\012%
@@ -607,7 +609,7 @@
\href{https://www.ctan.org/pkg/#1}{\nolinkurl{pkg/#1}}}
\DeclareRobustCommand\mailto[1]{\href{mailto:#1}{\nolinkurl{#1}}}
\def\mailtoRS{\href % some PDF viewers don't like spaces:
- {mailto:<w.m.l@gmx.net>\%20Robert\%20Schlicht?subject=[microtype\%20\fileversion]}
+ {mailto:Robert\%20Schlicht\%3cw.m.l@gmx.net\%3e?subject=[microtype\%20\fileversion]}
{\texttt{w.m.l@gmx.net}}}
% the samples in the introduction, utilising nested optional content groups (aka. layers):
\ifnum\pdftexversion<140 \else
@@ -812,7 +814,7 @@
% other extensions (see section~\ref{sec:lettersp}).
%
%\bigskip\noindent
-% This package is copyright \textcopyright\ 2004\kern.09em--2019 R Schlicht.
+% This package is copyright \textcopyright\ 2004\kern.09em--2020 R Schlicht.
% It may be distributed and/or modified under the conditions of the
% \IfFileExists{lppl.tex}{\hyperref[LPPL:LPPL]}{\href{http://www.latex-project.org/lppl/}}
% {\LaTeX\ Project Public License},
@@ -823,7 +825,7 @@
%
%\newpage
%\emptypdfpageresources ^^A layers of the logo
-%{\sffamily\def\familydefault{\sfdefault}\ifcmr\else\def\bfdefault{sb}\fi
+%{\sffamily\def\familydefault{\sfdefault}\ifcmr\else\DeclareFontSeriesDefault[sf]{bf}{sb}\fi
% \tableofcontents
% \listoftables
%}
@@ -972,8 +974,8 @@
% the well-known |key=value| syntax. In the following, you will find a
% description of all \key{keys} and their possible |values|
% (`|true|' may be omitted; multiple values, where allowed, must be enclosed in
-% braces; the default value is shown on the right, preceded by an asterisk
-% if it is contingent on the \TeX\ engine, version and/or the output mode).
+% braces; the default value is shown on the right -- if preceded by an asterisk,
+% this default only applies when running an up-to-date \pdftex\ in <PDF> mode).
%
%
%\subsection{Enabling the micro-typographic features}\label{sub:options-microtype}
@@ -989,7 +991,7 @@
% output mode (see section~\ref{sub:options-misc}), or with \xetex.
% In other words, \microtype\ will try to apply as much micro-typography as
% can safely be expected to work under the respective conditions (hence, it is
-% usually not necessary to load the package with different options for <PDF>
+% usually not necessary to load the package with different options, \eg, for <PDF>
% resp. <DVI> mode).
%
% Protrusion and expansion may be enabled or disabled independently from each
@@ -1068,15 +1070,15 @@
% & $\less$ 0.14f & <DVI>/<PDF> & _ & _ & _ & _ & _ & _\\
% & $\geq$ 0.14f & <DVI>/<PDF> & ! & ? & _ & _ & _ & _\\
% & $\geq$ 1.20 & <DVI> & ! & ? & _ & _ & _ & _\\
-% & & <PDF> & ! & ! & ! & _ & _ & _\\
+% & & <PDF> & ! & ? & ! & _ & _ & _\\
% & $\geq$ 1.40 & <DVI> & ! & ? & _ & ? & ? & _\\
-% & & <PDF> & ! & ! & ! & ? & ? & ?\\^^A\,\textsuperscript{\itshape a}\\
+% & & <PDF> & ! & ? & ! & ? & ? & ?\\
%\cmidrule(r){1-3}
-% \luatex ^^A we will have to re-model kerning, spacing and tracking with \luatex
+% \luatex ^^A we will have to re-model kerning and spacing with \luatex
% & $\geq$ 0.30 & <DVI> & ! & ? & _ & _ & _ & _\\
-% & & <PDF> & ! & ! & ! & _ & _ & _\\
-% & $\geq$ 0.62 & <DVI> & ! & ? & ?\,\textsuperscript{\itshape a} & _ & _ & ?\,\textsuperscript{\itshape a}\\
-% & & <PDF> & ! & ! & ! & _ & _ & ?\\
+% & & <PDF> & ! & ? & ! & _ & _ & _\\
+% & $\geq$ 0.62 & <DVI> & ! & _ & \hskip1em\llap{(}\textcolor{theblue}{$\boxtimes$})\textsuperscript{\itshape a} & _ & _ & ?\\
+% & & <PDF> & ! & _ & ! & _ & _ & ?\\
%\cmidrule(r){1-3}
% \let\textoractual\@firstoftwo ^^A why?
% \xetex
@@ -1084,14 +1086,13 @@
%\bottomrule
%\end{tabular}^^A
%\vskip4pt\footnotesize
-%\hskip-.8em
+%\hskip-1em
% ! = enabled\quad
% ? = not enabled\quad
% _ = not available
%\hfill
-% ^^A \textit{a}\quad $\geq$ 1.40.4 recommended
-% \textit{a}\quad for legacy (<TFM>) fonts only
-%\vskip3pt
+% \textit{a}\quad by means of variable tracking\hskip1em
+%\vskip4pt
%\end{minipage}^^A
%}\kern-\dimexpr\fboxsep+\fboxrule\relax ^^A end \fcolorbox
%\end{table}
@@ -1138,7 +1139,13 @@
% instances of the fonts may be calculated automatically and at run-time instead
% of the user having to prepare them in advance. This option is true
% by default provided that you are using a \TeX\ engine with this capability
-% and the output mode is <PDF>.
+% and the output mode is <PDF>.\footnote{
+% With \pdftex, automatic font expansion does not work with bitmap fonts.
+% Therefore, if you are using the Computer Modern Roman fonts in <T1> encoding,
+% you should either install the \pkg{cm-super} package or use the Latin Modern
+% fonts (package \pkg{lmodern}).}
+%\changes{v1.9}{2005/08/27}{add remark about Type\,1 fonts required for
+% automatic font expansion}
% If \opt{auto} is set to false, the font instances for all expansion steps must exist
% (with files called \meta{font~name}\texttt{\textpm}\meta{expansion value},
% \eg, \file{cmr12+10}, as described in the \cite{pdftexman}).
@@ -1146,23 +1153,17 @@
% If expanded instances of the fonts are available, they will be used
% regardless whether \opt{auto} is true or not.
%\fi
+% With \luatex, expansion is always automatic.
%
-%\changes{v1.9}{2005/08/27}{add remark about Type\,1 fonts required for
-% automatic font expansion}
-% With \pdftex, automatic font expansion does not work with bitmap fonts. Therefore, if you
-% are using the Computer Modern Roman fonts in <T1> encoding,
-%\iffalse
-% \footnote{
-% En passant, it may be noted that Type\,1 format and <T1> encoding are in
-% no other way related than that both start with a `T' and end with a `1'.}
-%\fi
-% you should either install the \pkg{cm-super} fonts or use the Latin Modern
-% fonts (package \pkg{lmodern}).
-%\changes{v2.7}{2017/07/06}{add remark about automatic font expansion with \texttt{dvilualatex}}
-% With \luatex, expansion is always automatic, and also works in <DVI> mode
-% (|dvilualatex|), however, because postprocessing programs like |dvips|
-% or |dvipdfmx| are not (yet) capable of dealing with OpenType fonts,
-% only for legacy fonts.
+% When generating <DVI> files, font expansion has to be enabled explicitly.
+% With \pdftex, \emph{automatic} font expansion will not work because
+% the postprocessing drivers (|dvips|, |dvipdfm|, etc.) resp. the <DVI> viewer
+% are not able to generate the fonts on the fly.
+%^^A\changes{v2.7}{2017/07/06}{add remark about automatic font expansion with \texttt{dvilualatex}}
+%\changes{v2.8}{2020/02/09}{squash fake news about automatic font expansion with \texttt{dvilualatex}}^^A
+% With \luatex, on the other hand, expansion in <DVI> mode is realised by
+% modifying the inter-letter spacing (tracking) instead of the glyphs
+% themselves, which may or may not be desired.
%
%\medskip
%\Describe{Option}{stretch}{:integer}[20]
@@ -1212,36 +1213,11 @@
% to +1000.
%
%
-%\enlargethispage{\baselineskip} ^^A layout
%\subsection{Miscellaneous options}\label{sub:options-misc}
%
-%\Describe{Option}{DVIoutput}{true,*false}
-% \pdftex\ and \luatex\ are not only able to generate <PDF> output but can also
-% spit out <DVI> files.\footnote{
-% All recent \TeX\ systems are using \pdftex\ as the default engine also for
-% <DVI> output.}
-% The latter can be ordered with the option \opt{DVIoutput}, which will set
-% \cmd\pdfoutput\ to zero.
-% For \xetex, this option is not applicable.
-%
-%\changes{v1.5}{2004/12/15}{add note about \opt{DVIoutput} option}
-% Note that this will confuse packages that depend on the value of
-% \cmd\pdfoutput\ if they were loaded earlier, as they had been made believe
-% that they were called to generate <PDF> output where they actually weren't.
-% These packages are, among others: \pkg{graphics}, \pkg{color},
-% \pkg{hyperref}, \pkg{pstricks} and, obviously, \pkg{ifpdf}. Either load these
-% packages after \microtype\ or else issue the command |\pdfoutput=0| earlier
-% -- in the latter case, the \opt{DVIoutput} option is redundant.
-%
-% When generating <DVI> files, font expansion has to be enabled explicitly.
-% With \pdftex, neither letterspacing nor \emph{automatic} font expansion will work because
-% the postprocessing drivers (|dvips|, |dvipdfm|, etc.) resp. the <DVI> viewer
-% are not able to generate the fonts on the fly.
-%
%\changes{v2.0}{2006/11/28}{add remark about `\opt{draft}' option disabling \microtype\
% (noted by \contributor Michalis Miatidis <miatidis\at informatik.rwth-aachen.de>)}
% ^^A private mail, 2006/11/26
-%\medskip
%\Describe{Option}{draft}{true,!false}
%\DescribeOption{final}
% If the \opt{draft} option is passed to the package, \emph{all
@@ -1276,6 +1252,31 @@
% You can have a different configuration file loaded instead by specifying its
% name \emph{without the extension}, \eg, |config=mycrotype|.
%
+%\medskip
+%\Describe{Option}{DVIoutput}{true,*false}
+% \pdftex\ and \luatex\ are not only able to generate <PDF> output but can also
+% spit out <DVI> files. In fact, all recent \TeX\ systems are using \pdftex\ as
+% the default engine also for <DVI> output, and \luatex\ too can be called
+% in <DVI> mode. However, since changing the output mode inside the document
+% may have undesired effects, this option should be considered deprecated;
+% instead, it is recommended to just call the respective program (|latex| resp.
+% |dvilualatex|).
+%\changes{v2.8}{2020/04/02}{declare \opt{DVIoutput} option deprecated}
+% For \xetex, this option is not applicable.
+%
+%\iffalse
+%\changes{v1.5}{2004/12/15}{add note about \opt{DVIoutput} option}
+% The latter can be ordered with the option \opt{DVIoutput}, which will set
+% \cmd\pdfoutput\ to zero.
+% Note that this will confuse packages that depend on the value of
+% \cmd\pdfoutput\ if they were loaded earlier, as they had been made believe
+% that they were called to generate <PDF> output where they actually weren't.
+% These packages are, among others: \pkg{graphics}, \pkg{color},
+% \pkg{hyperref}, \pkg{pstricks} and, obviously, \pkg{ifpdf}. Either load these
+% packages after \microtype\ or else issue the command |\pdfoutput=0| earlier
+% -- in the latter case, the \opt{DVIoutput} option is redundant.
+%\fi
+%
%\iffalse ^^A ... waiting for bug reports before documenting yet another option ...
%\medskip
%\Describe{Option}{defersetup}{!true,false}
@@ -1301,7 +1302,7 @@
% expansion settings with a |context| keyword are encountered. If these
% settings are loaded after the preamble, however, it is too late, and you
% should set the \opt{copyfonts} option manually.
-% This only works with \pdftex\ 1.40.4 or later.
+% This only works with \pdftex\ 1.40.4 or later, or \luatex.
%\fi
%
%
@@ -1413,20 +1414,13 @@
% normal font. Size selection commands are possible, too, however, ranges are
% not allowed.
%
-%\medskip\noindent
-% Table~\ref{tab:predefined-font-sets} lists the eleven predefined font sets.
-% They may also be activated by passing their name to the feature options
-% \opt{protrusion}, \opt{expansion}, \opt{tracking}, \opt{kerning} and
-% \opt{spacing} when loading the package, for example:
-%\begin{verbatim}
-%\usepackage[protrusion=allmath,tracking=smallcaps]{microtype}
-%\end{verbatim}
-%
+%\newcounter{nrfontsets}
%\begin{table}\microtypesetup{protrusion=false}\small
%\caption{Predefined font sets}\label{tab:predefined-font-sets}
%\catcode`\!=13 \def!{\textcolor{thered}{$\varnothing$}}
%\catcode`\/=13 \def/#1/{\textcolor{thegreen}{#1}}
%\def<#1>{\textcolor{theblue}{\acronym{#1}}}
+%\def\s#1{|#1|\stepcounter{nrfontsets}}
%\setlength\fboxsep{4pt}
%\leavevmode\kern-\dimexpr\fboxsep+\fboxrule\relax
%\fcolorbox{theframe}{white}{^^A
@@ -1443,56 +1437,56 @@
% & \footnotesize Size\\
%\cmidrule(r){1-1}\cmidrule(r){2-2}\cmidrule(r){3-3}
%\cmidrule(r){4-4}\cmidrule(r){5-5}\cmidrule{6-6}
-% |all|
+% \s{all}
% & !
% & !
% & !
% & !
% & ! \\
%\cmidrule(r){1-1}
-% |alltext|\linebreak(|allmath|)
+% \s{alltext}\linebreak(\s{allmath})
% & Text encodings, <TS1>\linebreak (<OML>, <OMS>, <U>)
% & !
% & !
% & !
% & ! \\
%\cmidrule(r){1-1}
-% |alltext-nott|\linebreak(|allmath-nott|)
+% \s{alltext-nott}\linebreak(\s{allmath-nott})
% & Text encodings, <TS1>\linebreak (<OML>, <OMS>, <U>)
% & /\cmd\rm|*|/,\linebreak/\cmd\sf|*|/
% & !
% & !
% & ! \\
%\cmidrule(r){1-1}
-% |basictext|\linebreak(|basicmath|)
+% \s{basictext}\linebreak(\s{basicmath})
% & Text encodings \linebreak (<OML>, <OMS>)
% & /\cmd\rm|*|/,\linebreak/\cmd\sf|*|/
% & /\cmd\md|*|/
% & !
% & /\cmd\normalsize/, /\cmd\footnotesize/, /\cmd\small/, /\cmd\large/\\
%\cmidrule(r){1-1}
-% |smallcaps|
+% \s{smallcaps}
% & Text encodings
% & !
% & !
% & /\cmd\sc|*|/,/si/,/scit/
% & ! \\
%\cmidrule(r){1-1}
-% |footnotesize|
+% \s{footnotesize}
% & Text encodings, <TS1>
% & !
% & !
% & !
% & |-|/\cmd\small/\\
%\cmidrule(r){1-1}
-% |scriptsize|
+% \s{scriptsize}
% & Text encodings, <TS1>
% & !
% & !
% & !
% & |-|/\cmd\footnotesize/\\
%\cmidrule(r){1-1}
-% |normalfont|
+% \s{normalfont}
% & /\cmd\encoding|*|/
% & /\cmd\family|*|/
% & /\cmd\series|*|/
@@ -1504,11 +1498,23 @@
% `Text encodings' = <OT1>, <T1>, <T2A>, <LY1>, <OT4>, <QX>, <T5>, <EU1>, <EU2>, <TU>
%\hfill
% `/\bslash\,\dots|*|/' = `/\bslash\,\dots|default|/'
-%\vskip3pt
+%\vskip4pt
%\end{minipage}^^A
%}\kern-\dimexpr\fboxsep+\fboxrule\relax ^^A end \fcolorbox
+%\ifcase\c@nrfontsets\or\or\or\or\or\or\or\or\or\or\or
+% \def\@currentlabel{eleven}\or \def\@currentlabel{twelve}\else
+% \PackageError{\MT@MT}{I cannot count any further}{}\fi\label{nrfontsets}
%\end{table}
%
+%\medskip\noindent
+% Table~\ref{tab:predefined-font-sets} lists the \ref*{nrfontsets} predefined font sets.
+% They may also be activated by passing their name to the feature options
+% \opt{protrusion}, \opt{expansion}, \opt{tracking}, \opt{kerning} and
+% \opt{spacing} when loading the package, for example:
+%\begin{verbatim}
+%\usepackage[protrusion=allmath,tracking=smallcaps]{microtype}
+%\end{verbatim}
+%
%\ifcmr\else\pagebreak\fi ^^A layout
%\medskip
%\Describe{Macro}{\UseMicrotypeSet}{?features,set name}
@@ -1521,8 +1527,8 @@
%\Describe{Macro}{\DeclareMicrotypeSetDefault}{?features,set name}
% If a feature is enabled but no font set has been chosen explicitly, the sets
% declared by this command will be activated. By default, the `|alltext|' font
-% set will be used for character protrusion and additional kerning, the
-% `|basictext|' set for font expansion and interword spacing, and the
+% set will be activated for character protrusion and additional kerning, the
+% `|alltext-nott|' set for font expansion and interword spacing, and the
% `|smallcaps|' set for tracking.
%
%\medskip\noindent
@@ -1625,7 +1631,7 @@
% (since the value that comes last will take precedence). Font settings
% will be loaded recursively.
% The following options will affect all loaded lists, in other words,
-% any options from the loaded lists will be ignored:
+% any options from the loaded lists will be ignored:\looseness=-1 ^^A layout
%\changes{v1.8}{2005/06/23}{add example for \texttt{factor} option}
% \item[\key{factor}] This option can be used to influence all protrusion
% factors of the list, overriding any global \opt{factor} setting (see
@@ -1736,12 +1742,13 @@
% This paragraph contains a `fussy' widow.}
%\end{verbatim}
% This method of employing contexts to temporarily apply different
-% expansion parameters only works with \pdftex\ version 1.40.4 or later.^^A
+% expansion parameters only works with \pdftex\ version 1.40.4 or later,^^A
% \footnote{For older versions, a dirty trick is laid out in
% section~\ref{ssec:font-setup} on page~\pageref{exp-hack}.}
-% Also note that \pdftex\ prohibits the use of fonts with different expansion
+% or with \luatex.
+% Also note that both \pdftex\ and \luatex\ prohibit the use of fonts with different expansion
% limits or steps (even of different fonts) within one paragraph, hence
-% the |sloppy| context has to be applied to complete paragraphs.
+% the |sloppy| context would have to be applied to complete paragraphs.
% \item[\key{factor}]
% This option provides a different method to alter expansion settings for
% certain fonts, working around the restriction just mentioned. The
@@ -1936,7 +1943,7 @@
% is, whenever a particular character appears in the text, the specified
% kerning will be inserted, regardless of which character precedes resp.
% follows it.
-% (Put in another way, this feature allows to modify the left or right
+% (Put differently, this feature allows modifying the left or right
% \textit{sidebearings} of specific glyphs.)
%
%\emptypdfpageresources ^^A layers of letterspacing illustration
@@ -2116,6 +2123,7 @@
% This package ships with configuration files for a number of font families.
% Table~\ref{tab:fonts} lists them all.
%
+%\enlargethispage{\baselineskip} ^^A layout
%\begin{table}[t]\small
%\changes{v1.6a}{2005/02/02}{add table of fonts with tailored protrusion settings}
%\caption{Fonts with tailored protrusion settings}\label{tab:fonts}
@@ -2125,10 +2133,10 @@
%\begin{minipage}{\textwidth}
%\def\arraystretch{1.2}
%\long\def\@makefntext#1{%
-% \leftskip 0pt
-% \parindent 0pt
-% \everypar{\parindent 0pt}%
-% \leavevmode\hbox to 15pt{\@thefnmark\hss}#1}
+% \leftskip 1em
+% \parindent -1em
+% \everypar{\parindent -1em}%
+% \leavevmode\hbox to 1em{\@thefnmark\hss}#1}
%\let\footnoterule\relax
%\def\fnref#1{\textsuperscript{\itshape\ifpdf\ref*{#1}\else\ref{#1}\fi}}
%\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}*3l@{}}
@@ -2141,7 +2149,7 @@
% Generic
% & <OT1>, <T1>, <T2A>, <LY1>, <QX>, (<TS1>)\footnote{Incomplete\label{fn:incmpl}}
% & n, (it, sl, sc)\fnref{fn:incmpl} \\
-% Computer Modern Roman (|cmr|)\footnote{Aliases: Latin Modern (|lmr|),
+% Computer Modern Roman (|cmr|)\footnote{Aliases: Latin Modern Roman (|lmr|),
% \pkg{ae} (|aer|), \pkg{zefonts} (|zer|),
% \pkg{eco} (|cmor|), \pkg{hfoldsty} (|hfor|)}
% & <OT1>, <OT4>, <T1>, <T2A>, <T5>, <LY1>, <TS1>
@@ -2164,15 +2172,15 @@
% & n, it, (sl)\fnref{fn:it-sl}, sc, si\\
% Palatino (|ppl|, |pplx|, |pplj|)\footnote{Aliases: \pkg{pxfonts} (|pxr|),
% \pkg{qfonts}/QuasiPalatino, \TeX\ Gyre Pagella (|qpl|),
-% \pkg{newpx}, <FPL> Neu (|fp9x|, |fp9j|)}
+% \pkg{newpx}, <FPL> Neu (|fp9x|, |fp9j|), \pkg{domitian}}
% & <OT1>, <OT4>, <T1>, <LY1>, (<TS1>)\fnref{fn:incmpl}
% & n, it, (sl)\fnref{fn:it-sl}, sc \\
% Times (|ptm|, |ptmx|, |ptmj|)\footnote{Aliases: \pkg{txfonts} (|txr|),
% \pkg{qfonts}/QuasiTimes, \TeX\ Gyre Termes (|qtm|),
-% \pkg{newtx}, \pkg{tempora}}
+% \pkg{newtx}, \pkg{tempora}, \pkg{step}, \pkg{stix}/\pkg{stix2}}
% & <OT1>, <OT4>, <T1>, <LY1>, <QX>, (<TS1>)\fnref{fn:incmpl}
% & n, it, (sl)\fnref{fn:it-sl}, sc \\
-% Latin Modern Roman
+% Latin Modern Roman\footnote{Alias: New Computer Modern}
% & <EU1>/<2>, <TU> [Latin, Greek]
% & n, it, (sl)\fnref{fn:it-sl}\\
% Charis <SIL>
@@ -2183,7 +2191,7 @@
% & <EU1>/<2>, <TU> [Latin, Cyrillic, Greek]
% & n, it, sc, si\\
%\fi
-% Palatino Linotype\footnote{Aliases: \TeX\ Gyre Pagella, Palatino <LT> Std, Palatino}
+% Palatino Linotype\footnote{Aliases: \TeX\ Gyre Pagella, Palatino <LT> Std, Palatino, Domitian}
% & <EU1>/<2>, <TU> [Latin]
% & n, it, sc\\
% Computer Modern math (|cmsy|, |cmm|)\footnote{Aliases: Latin Modern (|lmsy|, |lmm|)}
@@ -2619,8 +2627,8 @@
%\end{verbatim}
% This error message will occur if you are trying to employ font expansion
% while creating <DVI> output. Remember that \emph{automatic} font expansion
-% only works when running \pdftex\ in <PDF> mode. Although expansion is also
-% possible in <DVI> mode, it requires that all instances of the expanded fonts
+% only works when running \pdftex\ or \luatex\ in <PDF> mode. Although expansion is also
+% possible in <DVI> mode with \pdftex, it requires that all instances of the expanded fonts
% exist on your \TeX\ system.
%
%\changes{v2.2}{2007/06/13}{add hint about error message with \pdftex\ 1.40}
@@ -2652,7 +2660,7 @@
% distributions, this can be changed in the file \file{updmap.cfg} by setting
% |pdftexDownloadBase14| to |true|.
%
-%\pagebreak ^^A layout
+%\ifcmr\else\pagebreak\fi ^^A layout
%\changes{v1.9a}{2005/11/15}{add explanation for error message with non-Type\,1 fonts}
% \item
%\begin{verbatim}
@@ -2871,10 +2879,14 @@
% \contributor Phelype Oleinik <phe.h.o1\at gmail.com>,
% \contributor Falk Hanisch <falk.hanisch\at tu-dresden.de>,
% \contributor Markus Kohm <komascript\at gmx.info>,
-% \contributor Paolo Polesana <@\at @>, ^^A https://tex.stackexchange.com/users/95083/paolo-polesana
-% \contributor Oliver Kopp <koppdev\at gmail.com>
+% \contributor Paolo Polesana <@\at @>, ^^A https://tex.stackexchange.com/users/95083/paolo-polesana
+% \contributor Oliver Kopp <koppdev\at gmail.com>,
+% \contributor Hironori Kitagawa <h_kitagawa2001\at yahoo.co.jp>,
+% `\contributor d909 <@\at @>', ^^A https://tex.stackexchange.com/users/176404/d909
+% \contributor Daniel Benjamin Miller <dbmiller\at dbmiller.org>,
+% \contributor Md Ayquassar <mdayq0\at lenta.ru>
% and
-% \contributor Hironori Kitagawa <h_kitagawa2001\at yahoo.co.jp>.
+% \contributor Marcel Kr\"uger <tex\at 2krueger.de>.
%
%
%\iffalse
@@ -2946,9 +2958,9 @@
% \newblock (Online at \url{http://www.tug.org/TUGboat/Articles/tb29-1/tb91thanh-fonts.pdf})
%
% \bibitem[\pdftex\ manual]{pdftexman}
-% \thanh, Sebastian Rahtz, Hans Hagen, Hartmut Henkel, Pawe\l\ Jackowski, Martin Schr\"oder,
+% \thanh, Sebastian Rahtz, Hans Hagen, Hartmut Henkel, Pawe\l\ Jackowski, Martin Schr\"oder, Karl Berry,
% \emph{The \pdftex\ user manual},
-% \newblock 2~January 2018.
+% \newblock 2~March 2020.
% \newblock (\ctanurl{systems/doc/pdftex/manual/pdftex-a.pdf})
% ^^A latest version at \url{http://sarovar.org/projects/pdftex/}
% ^^A or even \url{http://foundry.supelec.fr/scm/?group_id=23}
@@ -2960,19 +2972,19 @@
%
% \bibitem[\LaTeXe\ font selection]{fntguide}
% \LaTeX3 Project Team, \emph{\LaTeXe\ font selection},
-% \newblock July 2019.
+% \newblock July 2020.
% \newblock (\ctanurl{macros/latex/base/fntguide.pdf})
%
% \bibitem[\pkg{fontspec}]{fontspec}
% Will Robertson,
% \emph{The \pkg{fontspec} package: Font selection for \xe\LaTeX\ and Lua\LaTeX},
-% \newblock 19~October 2019.
+% \newblock 21~February 2020.
% \newblock (\ctanpkgurl{fontspec})
%
% \bibitem[\pkg{luaotfload}]{luaotfload}
% \'Elie Roux, Khaled Hosny, Philipp Gesang, Ulrike Fischer, Marcel Kr\"uger,
% \emph{The \pkg{luaotfload} package},
-% \newblock 10~November 2019.
+% \newblock 2~September 2020.
% \newblock (\ctanpkgurl{luaotfload})
%
% \bibitem[\pkg{pdfcprot}]{pdfcprot}
@@ -3023,7 +3035,11 @@
%
%\begin{History}
%
-%\VersionDate{\expandafter\@gobble\fileversion}{\filedate}
+%\Version{\expandafter\@gobble\fileversion}{\filedate}
+% \item New default font sets for expansion and spacing: `|alltext-nott|'
+% \refsection{\ref{sec:font-sets}, table~\ref{tab:predefined-font-sets}}
+%
+%\VersionDate{2.7d}{2019/11/18}
%
%\VersionDate{2.7c}{2019/10/10}
%
@@ -3277,6 +3293,7 @@
% \setlength{\linewidth}{\textwidth}
% \footnotesize
%}
+%
%\def\LPPLSettings{
%\changes{v1.9e}{2006/06/13}{include <LPPL>}
% \let\LPPLicense\empty
@@ -3353,9 +3370,9 @@
%^^A \tagcode,\letterspacefont,\pdfcopyfont,\pdffontexpand,\pdfnoligatures,
%^^A \pdfprotrudechars,\pdfadjust(interwordglue,spacing),\pdf(ap,pre)pendkern,
%^^A \pdftracingfonts} ^^A pdftex
-%\DoNotIndex{\XeTeXversion,\XeTeXrevision} ^^A xetex
-%^^A\DoNotIndex{\XeTeXcharglyph,\XeTeXcountglyphs,\XeTeXfonttype,\XeTeXglyph,
-%^^A \XeTeXglyphindex,\XeTeXglyphname,\XeTeXprotrudechars}
+%\DoNotIndex{\XeTeXversion,\XeTeXrevision,\strcmp} ^^A xetex
+%^^A\DoNotIndex{\XeTeXcharglyph,\XeTeXfonttype,\XeTeXglyph,\XeTeXglyphindex,
+%^^A \XeTeXglyphname,\XeTeXlastfontchar,\XeTeXprotrudechars}
%\DoNotIndex{\directlua,\luatexversion} ^^A luatex
%^^A\DoNotIndex{\adjustspacing,\copyfont,\expandglyphsinfont,
%^^A \ignoreligaturesinfont,\outputmode,\protrudechars,\tracingfonts}
@@ -3396,7 +3413,7 @@
%\DoNotIndex{\RequireLuaModule} ^^A luatexbase
%\DoNotIndex{\pdf@escapestring} ^^A pdftexcmds
%\DoNotIndex{\py@macron} ^^A pinyin
-%\DoNotIndex{\SOUL@,\soulregister} ^^A soul
+%\DoNotIndex{\SOUL@,\SOUL@doword,\soulregister} ^^A soul
%\DoNotIndex{\tikz@expandcount} ^^A tikz
%\DoNotIndex{\conditionally@traceoff} ^^A trace
%\DoNotIndex{\@xspace,\@xspace@firsttrue} ^^A xspace
@@ -3495,11 +3512,11 @@
\def\MT@fix@catcode#1#2{%
\edef\MT@restore@catcodes{%
\MT@restore@catcodes
- \catcode#1 \the\catcode#1\relax
+ \catcode#1=\the\catcode#1\relax
}%
- \catcode#1 #2\relax
+ \catcode#1=#2\relax
}
-%<package>\MT@fix@catcode{17}{14}% ^^Q (comment)
+\MT@fix@catcode{17}{14}% ^^Q (comment)
\MT@fix@catcode{24} {9}% ^^X (ignore)
%<package>\MT@fix@catcode{33}{12}% !
%<package>\MT@fix@catcode{34}{12}% "
@@ -3780,6 +3797,7 @@
%\end{macro}
%\changes{v2.2}{2007/05/01}{use catcode trickery for \etex\ test}
%^^A\changes{v2.3a}{2007/12/29}{removed} ^^A \MT@maybe@etex
+%\changes{v2.8}{2020/05/26}{\letterspace\ works with \etex\ only}
% For definitions that depend on \etex\ features.
% \begin{macrocode}
\ifcase 0%
@@ -3791,6 +3809,8 @@
\else
\catcode`\^^Q=9 \catcode`\^^X=14
\fi
+%<letterspace>^^Q\MT@warning@nl{This package requires the etex extensions.
+%<letterspace>^^Q \MessageBreak Exiting}\MT@restore@catcodes\endinput
%<debug>\MT@dinfo@nl{0}{this is
%<debug>^^Q not
%<debug> etex}
@@ -3850,9 +3870,11 @@
\ifnum\luatexversion < 62 \def\MT@engine@tooold{0}
\else
\def\MT@engine@tooold{1}
+ \let\MT@lua\directlua
\ifnum\luatexversion > 84
\let\pdfoutput\outputmode
\let\pdfprotrudechars\protrudechars
+ \let\pdfadjustspacing\adjustspacing
\fi
\fi
%</letterspace>
@@ -3968,7 +3990,11 @@
% \item N/A
% \item \luatex\ ($\less$~0.36)
% \item + \cmd\directlua\ without state number ($\geq$~0.36)
-% \item + \cmd\letterspacefont\ ($\geq$~0.62)
+% \item + \cmd\letterspacefont; non-automatic expansion doesn't work anymore,
+% and automatic expansion in <DVI> mode is realised by modifying the tracking,
+% not the glyphs\footnote{This may have been changed earlier, but I'm no longer able
+% to find out when (the last version that actually works for me is 0.40).}
+% ($\geq$~0.62)
% \item + almost all of the \pdftex\ primitives have been renamed ($\geq$~0.85)
% \item + default \cmd\efcode\,=\,1000;
% \cmd\protrusionboundary\ [not yet supported] ($\geq$~0.90)
@@ -3988,7 +4014,7 @@
% number.
%\changes{v2.3d}{2009/03/25}{update for \luatex\ 0.36}
% \begin{macrocode}
-\def\MT@lua{\directlua}
+\let\MT@lua\directlua
\def\MT@luatex@no{5}
\ifnum\luatexversion<90
\def\MT@luatex@no{4}
@@ -4094,6 +4120,7 @@
%\end{macro}
%\end{macro}
%\end{macro}
+% [This line intentionally left blank.]
%\begin{macro}{\MT@pr@level}
%\begin{macro}{\MT@ex@level}
%\begin{macro}{\MT@pr@factor}
@@ -4224,7 +4251,7 @@
%<pdftex-def> \MT@pdftex@no
%<luatex-def> \MT@luatex@no
<#1 \expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi}
-%<luatex-def&debug>\MT@requires@luatex4{\directlua{tex.enableprimitives('pdf',{'tracingfonts'})}}\relax
+%<luatex-def&debug>\MT@requires@luatex4{\MT@lua{tex.enableprimitives('pdf',{'tracingfonts'})}}\relax
%<pdftex-def&debug>\MT@requires@pdftex6{
%<debug>\pdftracingfonts=1
%<pdftex-def&debug>}\relax
@@ -4249,8 +4276,9 @@
% load \pkg{fontspec} before \microtype.
% There will hardly be any \luatex\ documents that don't load this package, anyway.
%\changes{v2.6}{2013/06/19}{load \pkg{luaotfload} with \luatex}
+% Since 2017/01/01, it is already loaded in the format.
% \begin{macrocode}
-\RequirePackage{luaotfload}
+\@ifl@t@r\fmtversion{2017/01/01}\relax{\RequirePackage{luaotfload}}
\MT@lua{require("microtype")}
%</luatex-def>
% \end{macrocode}
@@ -4262,6 +4290,7 @@
% \contributor Ulrike Fischer <news3\at nililand.de>)}
% ^^A private mail, 2019/02/19
% ^^A private mail, 2019/02/26
+%\changes{v2.8}{2020/05/26}{fix for \pkg{luatexbase}}
% \begin{macrocode}
%<*luafile>
@@ -4277,7 +4306,7 @@ local catpackage
if luatexbase.registernumber then
catpackage = luatexbase.registernumber("catcodetable@atletter") -- LaTeX
else
- catpackage = luatexbase.catcodetables.CatcodeTableAtletter -- luatexbase
+ catpackage = luatexbase.catcodetables.CatcodeTableLaTeXAtLetter -- luatexbase
end
function microtype.sprint (...)
tex.sprint(catpackage, ...)
@@ -4589,19 +4618,21 @@ microtype.if_dimen = if_dimen
% (found by \contributor Wiebke Petersen <petersew\at uni-duesseldorf.de>)}
% ^^A MID: <esmd6k$954$1@news1.rz.uni-duesseldorf.de>
%\changes{v2.2}{2007/05/10}{employ \luatex\ features if available}
+%\changes{v2.8}{2020/06/18}{use \xetex's \cmd\stringcmp}
% \begin{macrocode}
-%<*pdftex-def>
-\MT@requires@pdftex5{
+%<*pdftex-def|xetex-def>
+%<pdftex-def>\MT@requires@pdftex5{
\def\MT@ifstreq#1#2{%
- \ifcase\pdfstrcmp{#1}{#2}\relax
+%<pdftex-def> \ifnum\pdfstrcmp{#1}{#2}=\z@
+%<xetex-def> \ifnum\strcmp{#1}{#2}=\z@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
+%</pdftex-def|xetex-def>
+%<*pdftex-def>
}{
-%</pdftex-def>
-%<*pdftex-def|xetex-def>
\def\MT@ifstreq#1#2{%
\edef\MT@res@a{#1}%
\edef\MT@res@b{#2}%
@@ -4611,8 +4642,8 @@ microtype.if_dimen = if_dimen
\expandafter\@secondoftwo
\fi
}
-%</pdftex-def|xetex-def>
-%<pdftex-def>}
+}
+%</pdftex-def>
%<luatex-def>\def\MT@ifstreq#1#2{\csname\MT@lua{microtype.if_str_eq([[#1]],[[#2]])}\endcsname}
%<*luafile>
local function if_str_eq(s1, s2)
@@ -4842,21 +4873,45 @@ microtype.if_str_eq = if_str_eq
% \end{macrocode}
%\end{macro}
%\changes{v2.6a}{2016/05/03}{fixes for \letterspace\ package with \luatex}
+%\begin{macro}{\MT@if@luaotf@font}
+%\changes{v2.8}{2019/11/27}{use \texttt{lua} function}
+% For fonts loaded by \pkg{luaotfload} we query the font's table.
+% \begin{macrocode}
+%<letterspace>\MT@pdf@or@lua{\let\MT@if@luaotf@font\@secondoftwo}{
+%<luatex-def|letterspace>\def\MT@if@luaotf@font{\csname\MT@lua{%
+%<luatex-def> microtype.if_luaotf_font()
+%<*luafile|letterspace>
+%<luafile>local function if_luaotf_font()
+ local thefont = font.getfont(font.current())
+ if thefont and ( thefont.format == "opentype" or thefont.format == "truetype" )
+ then tex.write("@firstoftwo")
+ else tex.write("@secondoftwo")
+ end
+%<luafile>end
+%<luafile>microtype.if_luaotf_font = if_luaotf_font
+%<luafile>
+%</luafile|letterspace>
+%<luatex-def|letterspace> }\endcsname
+%<luatex-def|letterspace>}
+%<letterspace>}
+% \end{macrocode}
+%\end{macro}
%\begin{macro}{\MT@do@font}
% Execute \meta{\#1} 256 times,
% \begin{macrocode}
%<pdftex-def|letterspace>\def\MT@do@font{\MT@while@num\z@\@cclvi}
% \end{macrocode}
-% resp. for the whole font for \luatex, if loaded by \pkg{fontspec}/\pkg{luaotfload}.
+% resp. for the whole font for \luatex, if it's a Unicode font.
%\changes{v2.5}{2010/08/14}{adapt for \luatex}
%\changes{v2.6}{2013/07/14}{speed up for \luatex}
%\changes{v2.6a}{2015/05/10}{fix \texttt{lua} function
% (reported by \contributor Herbert Vo\ss{} <Herbert.Voss\at FU-Berlin.DE>)}
% ^^A private mail, 2016/05/10
+%\changes{v2.8}{2020/06/20}{simplify \texttt{lua} function}
% \begin{macrocode}
%<*luatex-def>
\def\MT@do@font#1{%
- \MT@if@fontspec@font{%
+ \MT@if@luaotf@font{%
\def\MT@dofont@function{#1}%
\MT@lua{microtype.do_font()}%
}{\MT@while@num\z@\@cclvi{#1}}%
@@ -4864,23 +4919,15 @@ microtype.if_str_eq = if_str_eq
%</luatex-def>
% \end{macrocode}
% This is the |lua| function, which is much faster than looping through all glyphs
-% in \TeX. Legacy fonts (which this function might be fed with, because \pkg{fontspec}
-% isn't always getting it right) don't contain a |v.index| field.
+% in \TeX. Legacy fonts (which this function should never work on) don't contain a |v.index| field.
% \begin{macrocode}
%<*luafile>
local function do_font()
- if fonts then
- local thefont
- if fonts.ids then --- legacy luaotfload
- thefont = fonts.ids[font.current()]
- else --- new location
- thefont = fonts.hashes.identifiers[font.current()]
- end
- if thefont then
- for i,v in next,thefont.characters do
- if v.index == nil or v.index > 0 then
- microtype.sprint([[\@tempcnta=]]..i..[[\relax\MT@dofont@function]])
- end
+ local thefont = font.getfont(font.current())
+ if thefont then
+ for i,v in next,thefont.characters do
+ if v.index == nil or v.index > 0 then
+ microtype.sprint([[\@tempcnta=]]..i..[[\relax\MT@dofont@function]])
end
end
end
@@ -4889,15 +4936,17 @@ microtype.do_font = do_font
%</luafile>
% \end{macrocode}
-% The \xetex\ variant.
+% The \xetex\ variant (it's slow~\dots!).
%\changes{v2.5}{2010/05/18}{adapt for \xetex}
+%\changes{v2.8}{2020/02/06}{fix for \xetex}
% \begin{macrocode}
%<*xetex-def>
\def\MT@do@font#1{%
\@tempcnta=\z@
- \MT@loop #1%
- \advance\@tempcnta \@ne
- \ifnum\@tempcnta < \XeTeXcountglyphs\MT@font \MT@repeat
+ \MT@loop
+ \iffontchar\MT@font\@tempcnta #1\fi
+ \advance\@tempcnta\@ne
+ \ifnum\@tempcnta < \XeTeXlastfontchar\MT@font \MT@repeat
}
%</xetex-def>
%<*package>
@@ -5219,27 +5268,8 @@ microtype.do_font = do_font
% \begin{macrocode}
\newif\ifMT@xunicode
\MT@with@package@T{xunicode}\MT@xunicodetrue
-%</package>
\newif\ifMT@fontspec
-%<letterspace>\MT@requires@latex2{
\MT@with@package@T{fontspec}\MT@fontspectrue
-%<letterspace>}{\MT@fontspecfalse}
-% \end{macrocode}
-%\end{macro}
-%\end{macro}
-%\begin{macro}{\MT@if@fontspec@font}
-%\begin{macro}{\MT@fontspec@setup}
-%\changes{v2.6}{2016/04/23}{fix \cs{MT@if@fontspec@font} ABD}
-% For fonts loaded by \pkg{fontspec} (or, rather, \pkg{luaotfload}) we can
-% use some of the features the latter package provides.
-% \begin{macrocode}
-\let\MT@if@fontspec@font\@secondoftwo
-\def\MT@fontspec@setup{%
- \@ifpackagelater{fontspec}{2013/05/23}{
- \MT@let@cn\MT@if@fontspec@font{fontspec_if_fontspec_font:TF}%
- }\relax
-}
-\ifMT@fontspec\MT@fontspec@setup\fi
% \end{macrocode}
%\end{macro}
%\end{macro}
@@ -5255,7 +5285,6 @@ microtype.do_font = do_font
% lest we disturb \pkg{tikz}. This is used in \cs{MT@afteraftergroup}, and we
% don't need it for \letterspace.
% \begin{macrocode}
-%<*package>
\let\MT@maybe@gobble@with@tikz\@firstofone
\def\MT@tikz@setup{%
\def\MT@maybe@gobble@with@tikz{%
@@ -5359,11 +5388,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
\MT@with@package@T {eledmac}\MT@ledmac@setup
\MT@with@package@T{reledmac}\MT@ledmac@setup
\MT@with@package@T{xunicode}\MT@xunicodetrue
-%</package>
-%<plain> \MT@requires@latex2{
- \MT@with@package@T{fontspec}{\MT@fontspectrue\MT@fontspec@setup}%
-%<plain> }\relax
-%<*package>
+ \MT@with@package@T{fontspec}\MT@fontspectrue
% \end{macrocode}
% We can clean up \cs{MT@setupfont@hook} now.
%\changes{v2.6}{2014/03/17}{redefine \cs{MT@setupfont@hook} globally
@@ -5426,9 +5451,9 @@ time will almost certainly lead to undesired results. Have your choice!}%
% \begin{macrocode}
\MT@with@package@T{listings}{%
\g@addto@macro\MT@cfg@catcodes{%
- \MT@while@num{"30}{"3A}{\catcode\@tempcnta 12\relax}%
- \MT@while@num{"41}{"5B}{\catcode\@tempcnta 11\relax}%
- \MT@while@num{"61}{"7B}{\catcode\@tempcnta 11\relax}%
+ \MT@while@num{"30}{"3A}{\catcode\@tempcnta=12\relax}%
+ \MT@while@num{"41}{"5B}{\catcode\@tempcnta=11\relax}%
+ \MT@while@num{"61}{"7B}{\catcode\@tempcnta=11\relax}%
}%
% \end{macrocode}
% \dots~and the backslash (which would lead to problems in \cs{MT@get@slot}).
@@ -5437,7 +5462,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
% ^^A private mail, 2006/09/15
% \begin{macrocode}
\g@addto@macro\MT@setupfont@hook{%
- \catcode`\\\z@
+ \catcode`\\=\z@
% \end{macrocode}
% Inside a listing, \cmd\space\ is redefined.
%\changes{v2.5}{2011/05/03}{restore \cmd\space\ inside \pkg{listings}
@@ -5445,7 +5470,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
% ^^A private mail, 2011/04/30
% ^^A (beta:07)
% \begin{macrocode}
- \def\space{ }%
+ \def\space{ }%
% \end{macrocode}
%\changes{v1.9b}{2005/12/23}{compatibility with the \texttt{extendedchar} option of
% the \pkg{listings} package}
@@ -5462,24 +5487,23 @@ time will almost certainly lead to undesired results. Have your choice!}%
% Of course, using both \pkg{soul}'s and \microtype's letterspacing mechanisms
% at the same time doesn't make much sense. But \pkg{soul} can do more, \eg,
% underlining. The optional argument to \cs{textls} may not be used.
+%\changes{v2.8}{2020/04/11}{compatibility with \pkg{soul}: patch for font change
+% (reported by \contributor Md Ayquassar <mdayq0\at lenta.ru>)}
+% ^^A https://github.com/latex3/babel/issues/53#issuecomment-598307655
+% Also, we have to disable expansion within \pkg{soul}'s trial run.
+%\changes{v2.3a}{2008/01/06}{fix test for \pkg{soul} under plain \TeX}
+% Under plain \TeX, \pkg{soul} doesn't register itself the \LaTeX\ way, so
+% we just test for its main command.
% \begin{macrocode}
%</package>
-%<plain> \MT@requires@latex2{
- \MT@with@package@T{soul}{%
+ \ifx\SOUL@\@undefined\else
\soulregister\lsstyle 0%
\soulregister\textls 1%
- }%
-% \end{macrocode}
-%\changes{v2.3a}{2008/01/06}{fix test for \pkg{soul} under plain \TeX}
-% Under plain \TeX, \pkg{soul} doesn't register itself the \LaTeX\ way, hence
-% we have to use a different test in this case.
-% \begin{macrocode}
-%<*plain>
- }{\ifx\SOUL@\@undefined\else
- \soulregister\lsstyle 0%
- \soulregister\textls 1%
- \fi}%
-%</plain>
+ \ifx\XeTeXrevision\@undefined
+ \let\MT@SOUL@doword\SOUL@doword
+ \def\SOUL@doword{\pdfadjustspacing=\z@ \MT@SOUL@doword}%
+ \fi
+ \fi
%<*package>
\MT@with@package@T{tikz}\MT@tikz@setup
% \end{macrocode}
@@ -5667,12 +5691,12 @@ time will almost certainly lead to undesired results. Have your choice!}%
% \end{macrocode}
%\end{macro}
% Even though \luatex\ also provides the primitive from \pdftex\ (even renamed to
-% \cmd\copyfont, that is, `promoted' as per the \luatex\ manual), it is crippled
-% in that OpenType features will be lost. ^^A see https://mailman.ntg.nl/pipermail/ntg-context/2016/087541.html
+% \cmd\copyfont, that is, `promoted' as per the \luatex\ manual), it is seriously
+% crippled in that OpenType features will be lost. ^^A see https://mailman.ntg.nl/pipermail/ntg-context/2016/087541.html seqq.
%\changes{v2.7d}{2019/11/17}{in \luatex, don't use the \cmd\copyfont\ primitive, but load the font anew
% (reported by \contributor Paolo Polesana <@\at @> and
% \contributor Oliver Kopp <koppdev\at gmail.com>)}
-% ^^A http://tex.stackexchange.com/questions/338942/cancellation-of-color-fontspec-font-settings-while-defining-microtype-context
+% ^^A https://tex.stackexchange.com/questions/338942/cancellation-of-color-fontspec-font-settings-while-defining-microtype-context
% ^^A https://tex.stackexchange.com/questions/419288/microtypecontext-with-lualatex
% Therefore, we do not copy the font but load it anew.
% \begin{macrocode}
@@ -5695,9 +5719,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
\let\font@name\MT@font@copy
% \end{macrocode}
% But we have to properly substitute the font after we're done.
-% In \luatex, for some reason, one expansion step more.
% \begin{macrocode}
-%<luatex-def> \aftergroup\MT@exp@two@c
\aftergroup\let\aftergroup\font@name\aftergroup\MT@font@copy
}
% \end{macrocode}
@@ -5751,6 +5773,39 @@ time will almost certainly lead to undesired results. Have your choice!}%
% prevent a different design size being selected.
%
%\bigskip
+%\begin{macro}{\MT@fix@fontdimen@six}
+%\changes{v1.8}{2005/05/03}{new macro: test whether \fontdim6 is defined}
+%\changes{v2.3e}{2009/08/31}{fix: gobbling settings with tracking failed
+% (reported by \contributor Leo <sdl.web\at gmail.com>)}
+% ^^A MID: <m0vdk4g8t2.fsf@cam.ac.uk>
+%\changes{v2.8}{2020/05/25}{try to fix zero \fontdim6}
+%\begin{macro}{\MT@dimen@six}
+% If \fontdim6 is zero, character protrusion, spacing, kerning and tracking
+% won't work, and we could skip the settings (for example, the \pkg{dsfont}
+% fonts don't specify this dimension; this is probably a bug -- the \pkg{fourier}
+% and \pkg{newpx}/\pkg{newtx} packages have been fixed in the meantime).
+% However, we can fix it ourselves -- only tracking still doesn't work (it seems
+% that \cmd\letterspacefont\ uses the \fontdim6 from the original font).
+% \xetex\ doesn't provide an equivalent to \cmd\pdffontsize, so we use the
+% nominal size instead.
+% \begin{macrocode}
+%<*pdftex-def|luatex-def|xetex-def>
+\def\MT@fix@fontdimen@six{%
+ \ifnum\fontdimen6\MT@font=\z@
+ \fontdimen6\MT@font=%
+%<pdftex-def> \pdffontsize\MT@font
+%<luatex-def> \MT@requires@luatex4{\pdffeedback fontsize}{\pdffontsize}\MT@font
+%<xetex-def> \MT@size pt
+ \MT@info{Fixing zero \string\fontdimen 6 for font `\MT@@font'\MessageBreak
+ (new value: \the\fontdimen6\MT@font)}%
+ \MT@glet@nc{\MT@@font-fake6}\@empty
+ \fi
+ \edef\MT@dimen@six{\number\fontdimen6\MT@font}%
+}
+%</pdftex-def|luatex-def|xetex-def>
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
%\begin{macro}{\MT@split@name}
%\changes{v1.7}{2005/02/27}{don't define \cs{MT@encoding} \&c. \cmd\global ly}
%\changes{v2.0}{2006/12/19}{adjust to possible letterspacing}
@@ -5774,6 +5829,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
\def\MT@series {#3}%
\def\MT@shape {#4}%
\def\MT@size {#5}%
+ \MT@fix@fontdimen@six
% \end{macrocode}
%\begin{macro}{\MT@familyalias}
% Alias family?
@@ -6035,57 +6091,30 @@ time will almost certainly lead to undesired results. Have your choice!}%
\MT@glet@nc{\MT@encoding-\MT@family-settings}\@empty
}%
\fi
- \MT@get@font@dimen@six{%
- \MT@get@opt
- \MT@reset@pr@codes
+ \MT@get@opt
+ \MT@reset@pr@codes
% \end{macrocode}
% Get the name of the inheritance list and parse it.
% \begin{macrocode}
- \MT@get@inh@list
+ \MT@get@inh@list
% \end{macrocode}
% Set an input encoding?
% \begin{macrocode}
- \MT@set@inputenc{c}%
+ \MT@set@inputenc{c}%
% \end{macrocode}
% Load additional lists?
% \begin{macrocode}
- \MT@load@list\MT@pr@c@name
- \MT@set@listname
+ \MT@load@list\MT@pr@c@name
+ \MT@set@listname
% \end{macrocode}
% Load the main list.
% \begin{macrocode}
- \MT@let@cn\@tempc{MT@pr@c@\MT@pr@c@name}%
- \expandafter\MT@set@codes\@tempc,\relax,}%
+ \MT@let@cn\@tempc{MT@pr@c@\MT@pr@c@name}%
+ \expandafter\MT@set@codes\@tempc,\relax,%
}\MT@reset@pr@codes
}
% \end{macrocode}
%\end{macro}
-%\begin{macro}{\MT@get@font@dimen@six}
-%\changes{v1.8}{2005/05/03}{new macro: test whether \fontdim6 is defined}
-%\changes{v2.3e}{2009/08/31}{fix: gobbling settings with tracking failed
-% (reported by \contributor Leo <sdl.web\at gmail.com>)}
-% ^^A MID: <m0vdk4g8t2.fsf@cam.ac.uk>
-%\begin{macro}{\MT@dimen@six}
-% If \fontdim6 is zero, character protrusion, spacing, kerning and tracking
-% won't work, and we can skip the settings (for example, the \pkg{dsfont} and
-% \pkg{fourier} fonts don't specify this dimension; this is probably a bug in
-% the fonts).
-% \begin{macrocode}
-\def\MT@get@font@dimen@six{%
- \ifnum\fontdimen6\MT@font=\z@
- \MT@warning@nl{%
- Font `\MT@@font' does not specify its\MessageBreak
- \@backslashchar fontdimen 6 (width of an `em')! Therefore,\MessageBreak
- \@nameuse{MT@abbr@\MT@feat} will not work with this font}%
- \expandafter\@gobble
- \else
- \edef\MT@dimen@six{\number\fontdimen6\MT@font}%
- \expandafter\@firstofone
- \fi
-}
-% \end{macrocode}
-%\end{macro}
-%\end{macro}
%\begin{macro}{\MT@set@all@pr}
%\changes{v2.2}{2007/06/16}{(et al.) allow empty values}
% Set all protrusion codes of the font.
@@ -6372,7 +6401,8 @@ time will almost certainly lead to undesired results. Have your choice!}%
%\end{macro}
%\begin{macro}{\MT@get@opt}
% The optional argument to the configuration commands (except for
-% \cs{SetExpansion}, which is being dealt with in \cs{MT@get@ex@opt}).
+% \cs{SetExpansion} and \cs{SetTracking}, which are being dealt with
+% in \cs{MT@get@ex@opt} and \cs{MT@get@tr@opt}, resp.).
% \begin{macrocode}
\def\MT@get@opt{%
\MT@set@listname
@@ -6554,8 +6584,8 @@ time will almost certainly lead to undesired results. Have your choice!}%
% \begin{macrocode}
%<*pdftex-def|xetex-def|luatex-def>
\def\MT@set@pr@heirs#1{%
- \lpcode\MT@font #1 =\lpcode\MT@font\MT@char\relax
- \rpcode\MT@font #1 =\rpcode\MT@font\MT@char\relax
+ \lpcode\MT@font #1=\lpcode\MT@font\MT@char\relax
+ \rpcode\MT@font #1=\rpcode\MT@font\MT@char\relax
%<debug>\MT@dinfo@nl{2}{-- heir of \MT@char: #1}%
%<debug>\MT@dinfo@nl{4}{;;; lp/rp (#1): \number\lpcode\MT@font\MT@char\space/%
%<debug> \number\rpcode\MT@font\MT@char\space}%
@@ -6671,7 +6701,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
\let\MT@stretch@ \MT@stretch
\let\MT@shrink@ \MT@shrink
\let\MT@step@ \MT@step
-%<pdftex-def> \let\MT@auto@ \MT@auto
+ \let\MT@auto@ \MT@auto
\let\MT@ex@factor@\MT@ex@factor
}%
\MT@reset@ef@codes
@@ -6690,30 +6720,33 @@ time will almost certainly lead to undesired results. Have your choice!}%
% \end{macrocode}
%\end{macro}
%\begin{macro}{\MT@expandfont}
-% Expand the font.
+% Expand the font. For some reason, older \luatex\ versions freeze if
+% the |autoexpand| modifier is missing. Can't be bothered to find out why.
+% For newer versions, we could also use the function |font.setexpansion|,
+% or, in the future, \pkg{luaotfload}'s expansion font feature. ^^A https://github.com/latex3/luaotfload/commit/4907e23407c52437cca56966d11d3b4548bba585
+%\iffalse
% In \luatex, we try to go the |lua| way, if the |font.setexpansion| function exists.
%\changes{v2.7d}{2019/11/17}{use \luatex\ function \texttt{font.}\penalty\exhyphenpenalty\texttt{setexpansion} if available}
+%\fi
% \begin{macrocode}
%<*luatex-def>
-\directlua{\detokenize{
- if font.setexpansion == nil then
- tex.print("\\@firstoftwo")
- else
- tex.print("\\@secondoftwo")
- end
-}}{
+\MT@requires@luatex3{
\MT@requires@luatex4{\let\pdffontexpand\expandglyphsinfont}\relax
-%</luatex-def>
+\ifnum\luatexversion<79
\def\MT@expandfont{%
- \pdffontexpand\MT@font \MT@stretch@ \MT@shrink@ \MT@step@ \MT@auto@\relax
+ \pdffontexpand\MT@font \MT@stretch@ \MT@shrink@ \MT@step@ autoexpand\relax
}
-%<*luatex-def>
-}{
+\else
\def\MT@expandfont{%
- \directlua{font.setexpansion(font.current(),\MT@stretch@,\MT@shrink@,\MT@step@)}%
-}
+ \pdffontexpand\MT@font \MT@stretch@ \MT@shrink@ \MT@step@\relax
}
+\fi
+}{
%</luatex-def>
+\def\MT@expandfont{%
+ \pdffontexpand\MT@font \MT@stretch@ \MT@shrink@ \MT@step@ \MT@auto@\relax
+}
+%<luatex-def>}
% \end{macrocode}
%\end{macro}
%\begin{macro}{\MT@set@all@ex}
@@ -6809,8 +6842,9 @@ time will almost certainly lead to undesired results. Have your choice!}%
\MT@get@ex@opt@{stretch}{Setting stretch limit to \number\MT@stretch@}%
\MT@get@ex@opt@{shrink} {Setting shrink limit to \number\MT@shrink@}%
\MT@get@ex@opt@{step} {Setting expansion step to \number\MT@step@}%
-%<pdftex-def> \def\@tempa{autoexpand}%
-%<pdftex-def> \MT@get@ex@opt@{auto}{\ifx\@tempa\MT@auto@ En\else Dis\fi abling automatic expansion}%
+%<luatex-def> \MT@requires@luatex3\relax{%
+ \MT@get@ex@opt@{auto}{\MT@ifstreq{\MT@auto@}{autoexpand}{En}{Dis}abling automatic expansion}%
+%<luatex-def> }%
\MT@ifdefined@n@T{MT@ex@c@\MT@ex@c@name @preset}{%
\MT@preset@ex
\let\MT@reset@ef@codes\relax
@@ -6870,15 +6904,14 @@ time will almost certainly lead to undesired results. Have your choice!}%
% \begin{macrocode}
\def\MT@set@sp@codes{%
\MT@if@list@exists{%
- \MT@get@font@dimen@six{%
- \MT@get@opt
- \MT@reset@sp@codes
- \MT@get@inh@list
- \MT@set@inputenc{c}%
- \MT@load@list\MT@sp@c@name
- \MT@set@listname
- \MT@let@cn\@tempc{MT@sp@c@\MT@sp@c@name}%
- \expandafter\MT@set@codes\@tempc,\relax,}%
+ \MT@get@opt
+ \MT@reset@sp@codes
+ \MT@get@inh@list
+ \MT@set@inputenc{c}%
+ \MT@load@list\MT@sp@c@name
+ \MT@set@listname
+ \MT@let@cn\@tempc{MT@sp@c@\MT@sp@c@name}%
+ \expandafter\MT@set@codes\@tempc,\relax,%
}\MT@reset@sp@codes
}
% \end{macrocode}
@@ -6987,15 +7020,14 @@ time will almost certainly lead to undesired results. Have your choice!}%
% \begin{macrocode}
\def\MT@set@kn@codes{%
\MT@if@list@exists{%
- \MT@get@font@dimen@six{%
- \MT@get@opt
- \MT@reset@kn@codes
- \MT@get@inh@list
- \MT@set@inputenc{c}%
- \MT@load@list\MT@kn@c@name
- \MT@set@listname
- \MT@let@cn\@tempc{MT@kn@c@\MT@kn@c@name}%
- \expandafter\MT@set@codes\@tempc,\relax,}%
+ \MT@get@opt
+ \MT@reset@kn@codes
+ \MT@get@inh@list
+ \MT@set@inputenc{c}%
+ \MT@load@list\MT@kn@c@name
+ \MT@set@listname
+ \MT@let@cn\@tempc{MT@kn@c@\MT@kn@c@name}%
+ \expandafter\MT@set@codes\@tempc,\relax,%
}\MT@reset@kn@codes
}
% \end{macrocode}
@@ -7120,12 +7152,23 @@ time will almost certainly lead to undesired results. Have your choice!}%
% The tracking amount is determined by the optional argument to \cs{textls},
% settings from \cs{SetTracking}, or the global \opt{letterspace} option, in
% this order.
+%
+% Tracking won't work if the original font's \fontdim6 is zero, in which
+% case we issue a warning (once for every font).
% \begin{macrocode}
%<*pdftex-def|luatex-def|letterspace>
\def\MT@set@tr@codes{%
%<*pdftex-def|luatex-def>
\MT@vinfo{Tracking font `\MT@@font'\on@line}%
- \MT@get@font@dimen@six{%
+ \MT@ifdefined@n@TF{\MT@@font-fake6}{%
+ \expandafter\ifx\csname\MT@@font-fake6\endcsname\@empty
+ \MT@warning@nl{%
+ Font `\MT@@font' does not specify its\MessageBreak
+ \@backslashchar fontdimen 6 (width of an `em')! Therefore,\MessageBreak
+ \@nameuse{MT@abbr@\MT@feat} will not work with this font}%
+ \MT@glet@nc{\MT@@font-fake6}\relax
+ \fi
+ }{%
\MT@if@list@exists
\MT@get@tr@opt
\relax
@@ -7170,8 +7213,8 @@ time will almost certainly lead to undesired results. Have your choice!}%
% than the \pdftex\ primitive \cmd\letterspacefont.
% \begin{macrocode}
%<*luatex-def|letterspace>
- \MT@if@fontspec@font{%
-%<luatex-def&debug>\MT@dinfo@nl{1}{... fontspec font: \MessageBreak
+ \MT@if@luaotf@font{%
+%<luatex-def&debug>\MT@dinfo@nl{1}{... luaotf font: \MessageBreak
%<luatex-def&debug> \expandafter\fontname\font@name}%
\ifnum\MT@letterspace@<\z@\def\MT@minus{-}\else\let\MT@minus\@empty\fi
\global\expandafter\font\MT@lsfont=%
@@ -7231,7 +7274,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
% (reported by \contributor Wolfram Schaalo <schaalo\at gmx.net>)}
% ^^A private mail, 2008/05/12
% \begin{macrocode}
-%<luatex-def|letterspace> \MT@if@fontspec@font\relax{%
+%<luatex-def|letterspace> \MT@if@luaotf@font\relax{%
%<debug>\MT@dinfo@nl{2}{... compensating for tracking (\number\MT@letterspace@)}%
\MT@do@font{\lpcode\MT@lsfont\@tempcnta=\numexpr\MT@letterspace@/2\relax
\rpcode\MT@lsfont\@tempcnta=\numexpr\MT@letterspace@/2\relax}%
@@ -7245,7 +7288,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
% \begin{macrocode}
\aftergroup\MT@set@lsfont
%<pdftex-def|luatex-def> \let\MT@font\MT@lsfont
-%<luatex-def> \MT@if@fontspec@font\MT@font\relax
+%<luatex-def> \MT@if@luaotf@font\MT@font\relax
% \end{macrocode}
%\begin{macro}{\MT@set@curr@ls}
%\begin{macro}{\MT@curr@ls}
@@ -7367,23 +7410,26 @@ time will almost certainly lead to undesired results. Have your choice!}%
%<*pdftex-def|luatex-def>
\def\MT@get@tr@opt{%
\MT@set@listname
- \MT@ifdefined@n@T{MT@tr@c@\MT@tr@c@name}{%
- \MT@let@cn\MT@letterspace{MT@tr@c@\MT@tr@c@name}%
+ \let\MT@tr@factor@\@m
% \end{macrocode}
%\begin{macro}{\MT@tr@unit@}
-% Different unit?
+% Different unit (for |letterspace| and/or |(outer)spacing|)?
+%\changes{v2.8}{2020/11/22}{fix: allow unit regardless whether letterspacing is set}
% \begin{macrocode}
- \MT@ifdefined@n@T{MT@tr@c@\MT@tr@c@name @unit}{%
- \MT@let@cn\MT@tr@unit@{MT@tr@c@\MT@tr@c@name @unit}%
- \ifdim\MT@tr@unit@=1em
- \let\MT@tr@unit@\@undefined
- \else
- \MT@let@cn\@tempb{MT@tr@c@\MT@tr@c@name}%
- \MT@get@unit\MT@tr@unit@
- \let\MT@tr@factor@\@m
- \MT@scale@to@em
- \edef\MT@letterspace{\number\@tempcntb}%
- \fi
+ \MT@ifdefined@n@T{MT@tr@c@\MT@tr@c@name @unit}{%
+ \MT@let@cn\MT@tr@unit@{MT@tr@c@\MT@tr@c@name @unit}%
+ \ifdim\MT@tr@unit@=1em
+ \let\MT@tr@unit@\@undefined
+ \else
+ \MT@get@unit\MT@tr@unit@
+ \fi
+ }%
+ \MT@ifdefined@n@T{MT@tr@c@\MT@tr@c@name}{%
+ \MT@let@cn\MT@letterspace{MT@tr@c@\MT@tr@c@name}%
+ \MT@ifdefined@c@T\MT@tr@unit@{%
+ \let\@tempb\MT@letterspace
+ \MT@scale@to@em
+ \edef\MT@letterspace{\number\@tempcntb}%
}%
}%
% \end{macrocode}
@@ -7448,12 +7494,18 @@ time will almost certainly lead to undesired results. Have your choice!}%
%\changes{v2.7}{2016/08/03}{fix: prevent infinite loop with \pkg{psnfss} and \pkg{exscale} packages
% (reported by \contributor user11126 <@\at @>,
% solution by \contributor Ulrike Fischer <fischer\at troubleshooting-tex.de>)}
-% Setting \cmd\glb@currsize\ to \cmd\@empty\ (our previous solution) could
+% ^^A https://tex.stackexchange.com/questions/316231/microtype-and-exscale-crashing-in-texlive-2016#comment771828_316252
+% Setting \cmd\glb@currsize\ globally to \cmd\@empty\ (our previous solution) could
% throw us into an infinite loop (\eg, with the \pkg{psnfss} packages,
% via \cmd\every@math@size), so we issue \cmd\glb@settings\ instead.
+%\changes{v2.8}{2020/05/26}{fix: enforce math setup, again}
+% However, in certain situations, we may still miss some math fonts, so
+% let's try to also enforce it by emptying \cmd\glb@currsize, fingers crossed.
+% The overhead seems small.
% \begin{macrocode}
\DeclareRobustCommand\lsstyle{%
\not@math@alphabet\lsstyle\textls
+ \let\glb@currsize\@empty
%<pdftex-def|luatex-def> \MT@maybe@gobble@with@tikz{\aftergroup\glb@settings}%
%<pdftex-def|luatex-def> \def\MT@feat{tr}%
\let\MT@tracking\MT@set@tr@codes
@@ -7598,16 +7650,15 @@ time will almost certainly lead to undesired results. Have your choice!}%
%\begin{macro}{\MT@tr@set@space@}
% If settings for outer spacing \meta{\#2} don't exist, they will be inherited
% from the inner spacing settings \meta{\#1}.
+%\changes{v2.8}{2020/11/24}{simplified}
% \begin{macrocode}
\def\MT@tr@set@space@#1#2#3#4{%
\MT@ifempty{#2}{%
- \MT@ifempty{#1}{%
- \edef\MT@temp{\MT@temp#4\the\fontdimen#3\MT@lsfont}%
- }{%
+ \MT@ifempty{#1}\relax{%
\MT@tr@set@space@@{#1}{#3}{1000}%
- \edef\MT@temp{\MT@temp#4\the\@tempdima}%
\fontdimen#3\MT@lsfont=\@tempdima
}%
+ \edef\MT@temp{\MT@temp#4\the\fontdimen#3\MT@lsfont}%
}{%
\MT@tr@set@space@@{#2}{#3}{2000}%
\edef\MT@temp{\MT@temp#4\the\@tempdima}%
@@ -7629,8 +7680,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
\MT@ifdefined@c@TF\MT@tr@unit@
{\edef\@tempb{#1}\MT@scale@to@em}
{\@tempcntb=#1\relax}%
- \@tempdima=\dimexpr \dimexpr\@tempcntb sp*\MT@dimen@six/1000\relax
- -\fontdimen#2\MT@lsfont\relax
+ \@tempdima=\dimexpr\@tempcntb sp*\MT@dimen@six/1000\relax
% \end{macrocode}
% For \fontdim2, we also have to subtract the kerning that letterspacing adds
% to each side of the characters (only half if it's for outer spacing).
@@ -7638,7 +7688,6 @@ time will almost certainly lead to undesired results. Have your choice!}%
\ifnum#2=\tw@
\advance\@tempdima -\dimexpr\MT@letterspace@ sp*\MT@dimen@six/#3\relax
\fi
- \@tempdima=\dimexpr \fontdimen#2\MT@lsfont+\@tempdima\relax
}{%
\MT@ifempty\@tempa{\let\@tempa\MT@letterspace@}\relax
\@tempdima=\dimexpr \numexpr1000+\@tempa sp *\fontdimen#2\MT@lsfont/1000\relax
@@ -8061,7 +8110,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
% in a table (used by the \pkg{luaotfload} function |keepligature|).
%\changes{v2.6}{2016/04/20}{use \pkg{luaotfload} function to keep\slash inhibit ligatures}
% \begin{macrocode}
-%<luatex-def> \MT@if@fontspec@font
+%<luatex-def> \MT@if@luaotf@font
%<luatex-def> {\MT@lua{microtype.noligatures([[#1]],[[\MT@char]])}}\relax
\fi
}%
@@ -8074,7 +8123,7 @@ time will almost certainly lead to undesired results. Have your choice!}%
}%
}{%
\pdfnoligatures#1%
-%<luatex-def> \MT@if@fontspec@font
+%<luatex-def> \MT@if@luaotf@font
%<luatex-def> {\MT@lua{microtype.noligatures([[#1]],"_all_")}}\relax
\MT@vinfo{... Disabling all ligatures}%
}%
@@ -8739,17 +8788,17 @@ else
local function name_to_slot(name, unsafe)
if fonts then
local unicodes
- if fonts.ids then --- legacy luaotfload
+ if fonts.ids then -- legacy luaotfload
local tfmdata = fonts.ids[font.current()]
if not tfmdata then return end
unicodes = tfmdata.shared.otfdata.luatex.unicodes
- else --- new location
+ else -- new location
local tfmdata = fonts.hashes.identifiers[font.current()]
if not tfmdata then return end
unicodes = tfmdata.resources.unicodes
end
local unicode = unicodes[name]
- if unicode then --- does the 'or' branch actually exist?
+ if unicode then -- does the 'or' branch actually exist?
return type(unicode) == "number" and unicode or unicode[1]
end
end
@@ -9067,10 +9116,12 @@ end
%\end{macro}
%\end{macro}
%\begin{macro}{\MT@is@tlig}
-% This might have to change again with the next \LaTeX\ release. ^^A see https://github.com/latex3/latex2e/issues/165
+% This might have to change again with the next \LaTeX\ release, ^^A see https://github.com/latex3/latex2e/issues/165
+% \dots\ or so I feared, but it still seems to be fine.
% \begin{macrocode}
\def\MT@is@tlig#1#2{%
\ifx#1\remove@tlig
+%<debug> \MT@dinfo@nl{3}{> `\the\MT@toks' (removing remove@tlig)}%
\MT@is@number #2\relax\relax
\fi
}
@@ -9619,15 +9670,24 @@ end
% ^^A MID: <46ab4fbb$0$31632$9b4e6d93@newsspool3.arcor-online.net>
%\changes{v2.6}{2014/03/26}{allow \texttt{activate} shortcut (reported by \contributor Karl Berry <karl\at freefriends.org>)}
% ^^A private mail, 2014/03/21
+%\changes{v2.8}{2019/11/25}{fix \texttt{activate} shortcut}
+%\changes{v2.8}{2019/12/12}{ignore spaces}
+%\begin{macro}{\MT@microtypecontext}
% The user may change the context, so that different setups are possible. This
% is especially useful for multi-lingual documents.
%
-% Inside the preamble, it shouldn't actually do anything but remember it for
+% Inside the preamble, this command shouldn't actually do anything but remember itself for
% later.
% \begin{macrocode}
-\def\microtypecontext#1{\MT@addto@setup{\microtypecontext{#1}}}
+\def\microtypecontext{\MT@begin@catcodes\MT@microtypecontext}
+\def\MT@microtypecontext#1{\MT@end@catcodes\MT@addto@setup{\microtypecontext{#1}}}
\MT@addto@setup{%
- \DeclareRobustCommand\microtypecontext[1]{%
+ \DeclareRobustCommand\microtypecontext{%
+ \MT@begin@catcodes
+ \MT@microtypecontext
+ }%
+ \def\MT@microtypecontext#1{%
+ \MT@end@catcodes
\MT@setup@contexts
\let\MT@reset@context\relax
% \end{macrocode}
@@ -9643,13 +9703,21 @@ end
}
% \end{macrocode}
%\end{macro}
+%\end{macro}
%\begin{macro}{\textmicrotypecontext}
%\changes{v2.2}{2007/07/03}{new command: wrapper around \cs{microtypecontext}}
+%\changes{v2.8}{2019/12/12}{ignore spaces}
+%\begin{macro}{\MT@textmicrotypecontext}
+%\begin{macro}{\MT@text@microtypecontext}
% This is just a wrapper around \cs{microtypecontext}.
% \begin{macrocode}
-\DeclareRobustCommand\textmicrotypecontext[2]{{\microtypecontext{#1}#2}}
+\DeclareRobustCommand\textmicrotypecontext{\MT@begin@catcodes\MT@textmicrotypecontext}
+\def\MT@textmicrotypecontext#1{\MT@end@catcodes\MT@text@microtypecontext{#1}}
+\def\MT@text@microtypecontext#1#2{{\microtypecontext{#1}#2}}
% \end{macrocode}
%\end{macro}
+%\end{macro}
+%\end{macro}
%\begin{macro}{\MT@reset@context}
%\changes{v1.9f}{2006/08/03}{only reset context if it has actually been changed}
%\begin{macro}{\MT@reset@context@}
@@ -9701,6 +9769,7 @@ end
\def\MT@reset@context{\aftergroup\MT@reset@context@}%
% \end{macrocode}
% The next time we see the font, we have to reset \emph{all} factors.
+%^^A TODO: only for pdftex? or why at all?
% \begin{macrocode}
\MT@glet@nn{MT@reset@\@tempb @codes}{MT@reset@\@tempb @codes@}%
% \end{macrocode}
@@ -9721,8 +9790,8 @@ end
% We also allow the |activate| shortcut.
% \begin{macrocode}
\define@key{MTC}{activate}[]{%
- \setkeys{MT}{protrusion={#1}}%
- \setkeys{MT}{expansion={#1}}%
+ \setkeys{MTC}{protrusion={#1}}%
+ \setkeys{MTC}{expansion={#1}}%
}
% \end{macrocode}
%\begin{macro}{\MT@pr@context}
@@ -9888,7 +9957,7 @@ end
Ignoring `#1 = {\@tempa*}' in font set\MessageBreak`\MT@curr@set@name'}%
\let\MT@val\@empty}%
% \end{macrocode}
-% In contrast to earlier version, these values will not be expanded immediately
+% In contrast to earlier versions, these values will not be expanded immediately,
% but at the end of the preamble.
%\changes{v1.2}{2004/09/26}{check whether defaults have changed}
%\changes{v1.5}{2004/12/02}{don't test defaults if called after begin document}
@@ -10978,23 +11047,19 @@ end
%\changes{v1.7}{2005/03/07}{disallow automatic expansion if \pdftex\ too old}
%\changes{v2.7a}{2017/08/08}{disallow non-automatic expansion with \luatex}
% \begin{macrocode}
-%<*pdftex-def>
- \MT@requires@pdftex4{%
- \MT@gdef@n{MT@ex@c@\MT@curr@set@name @auto}{autoexpand}%
- }{%
- \MT@warning{pdftex too old for automatic font expansion}%
- }
-%</pdftex-def>
+%<pdftex-def> \MT@requires@pdftex4%
+%<luatex-def> \MT@requires@luatex3\relax
+ {\MT@gdef@n{MT@ex@c@\MT@curr@set@name @auto}{autoexpand}}%
+%<pdftex-def> {\MT@warning{pdftex too old for automatic font expansion}}%
\else
-%<*pdftex-def>
- \MT@requires@pdftex4{%
- \MT@glet@nc{MT@ex@c@\MT@curr@set@name @auto}\@empty
- }\relax
-%</pdftex-def>
+%<pdftex-def> \MT@requires@pdftex4%
%<*luatex-def>
- \MT@warning{Non-automatic font expansion doesn't work with\MessageBreak
- luatex}%
+ \MT@requires@luatex3{%
+ \MT@warning{Non-automatic font expansion doesn't work with\MessageBreak
+ luatex}}%
%</luatex-def>
+ {\MT@glet@nc{MT@ex@c@\MT@curr@set@name @auto}\@empty}%
+%<pdftex-def> \relax
\fi
}
% \end{macrocode}
@@ -12238,11 +12303,30 @@ end
% For <DVI> output, the user must have explicitly passed the \opt{expansion}
% option to the package.
%\changes{v1.5}{2004/12/02}{defaults: turn off expansion for <DVI> output}
+% Under \luatex, expansion works quite differently: the glyphs will be
+% positioned as if they were transformed, without actually being transformed.
+% Since this could still be considered a viable option, we don't disable
+% the feature completely, but issue a warning.
+%\changes{v2.8}{2020/02/09}{warning when expanding in <DVI> mode with \luatex\
+% (reported by \contributor d909 <@\at @>)}
+% ^^A https://tex.stackexchange.com/questions/531413/dvipdfmx-and-dvips-do-not-expand-fonts-properly-with-lualatex-in-dvi-mode
% \begin{macrocode}
%<*pdftex-def|luatex-def>
\def\MT@setup@expansion{%
\ifnum\pdfoutput<\@ne
- \ifMT@opt@expansion \else
+ \ifMT@opt@expansion
+%<*luatex-def>
+ \ifMT@expansion
+ \MT@requires@luatex3{%
+ \MT@warning@nl{Font expansion doesn't work properly with luatex in\MessageBreak
+ DVI mode: the glyphs won't be actually transformed,\MessageBreak
+ but will only be shifted. You might want to use\MessageBreak
+ pdflatex instead. I'll continue anyway ..}%
+ %\MT@expansionfalse
+ }\relax
+ \fi
+%</luatex-def>
+ \else
\MT@expansionfalse
\fi
\fi
@@ -12316,14 +12400,13 @@ end
% (reported by \contributor Ulrike Fischer <news3\at nililand.de>)}
% ^^A private mail, 2017/10/29
% In \luatex\ 1.0.6, the `|autoexpand|' option seems to have been removed altogether
-% and would trigger an error.
+% and would trigger a warning.
% \begin{macrocode}
-%<luatex-def> \let\MT@auto@\@empty
-%<pdftex-def> \let\MT@auto\@empty
+ \let\MT@auto\@empty
\ifMT@auto
% \end{macrocode}
%\end{macro}
-% We turn off automatic expansion if output mode is <DVI> and we're running \pdftex.
+% We turn off automatic expansion if output mode is <DVI>.
%\changes{v1.5}{2004/12/02}{disable automatic expansion for <DVI> output}
%\changes{v2.7}{2017/07/02}{don't disable automatic expansion for <DVI> output with \luatex}
% \begin{macrocode}
@@ -12359,6 +12442,7 @@ end
\def\MT@auto{1000 }%
}%
%</pdftex-def>
+%<luatex-def> \MT@requires@luatex3\relax{\def\MT@auto{autoexpand}}%
\else
%<*pdftex-def>
% \end{macrocode}
@@ -12369,10 +12453,13 @@ end
}%
%</pdftex-def>
%<*luatex-def>
- \ifMT@opt@auto
- \MT@error{Non-automatic font expansion does not work with\MessageBreak
- luatex}{Remove `auto=false' from the package options, or use pdftex.}%
- \fi
+ \MT@requires@luatex3{%
+ \ifMT@opt@auto
+ \MT@error{Non-automatic font expansion does not work with\MessageBreak
+ luatex}{Remove `auto=false' from the package options, or use pdftex.}%
+ \MT@autotrue
+ \fi
+ }\relax
%</luatex-def>
\fi
% \end{macrocode}
@@ -12917,13 +13004,15 @@ end
% \end{macrocode}
% The default sets.
%\changes{v2.2}{2007/04/15}{default set for tracking: \texttt{smallcaps}}
+%\changes{v2.8}{2019/12/04}{default set for expansion: \texttt{alltext-nott}}
+%\changes{v2.8}{2019/12/04}{default set for spacing: \texttt{alltext-nott}}
% \begin{macrocode}
%%% -----------------------------------------------------------------------
%%% DEFAULT SETS
\DeclareMicrotypeSetDefault[protrusion]{alltext}
-\DeclareMicrotypeSetDefault[expansion] {basictext}
-\DeclareMicrotypeSetDefault[spacing] {basictext}
+\DeclareMicrotypeSetDefault[expansion] {alltext-nott}
+\DeclareMicrotypeSetDefault[spacing] {alltext-nott}
\DeclareMicrotypeSetDefault[kerning] {alltext}
\DeclareMicrotypeSetDefault[tracking] {smallcaps}
@@ -12932,13 +13021,11 @@ end
%\subsection{Font variants and aliases}
%\GeneralChanges{Font aliases}
%
-% \begin{macrocode}
-%%% -----------------------------------------------------------------------
-%%% FONT VARIANTS AND ALIASES
-% \end{macrocode}
% These are the variants I happen to be using (expert encoding, oldstyle
% numerals, swashes, alternative, display, inferior and superior numerals):
% \begin{macrocode}
+%%% -----------------------------------------------------------------------
+%%% FONT VARIANTS AND ALIASES
\DeclareMicrotypeVariants{x,j,w,a,d,0,1}
% \end{macrocode}
@@ -12968,9 +13055,10 @@ end
\fi
\ifMT@fontspec\MT@if@true\fi
\ifMT@if@
+%% -- Computer/Latin Modern Roman
\DeclareMicrotypeAlias{lmr}{Latin Modern Roman}
\else
-\DeclareMicrotypeAlias{lmr}{cmr} % lmodern
+\DeclareMicrotypeAlias{lmr}{cmr} % lmodern
\fi
% \end{macrocode}
% The Latin Modern fonts, the virtual fonts from the
@@ -12986,12 +13074,17 @@ end
% (reported by \contributor Jonas Hogstrom <hjb981\at gmail.com>)}
% ^^A https://tex.stackexchange.com/questions/63558/how-to-get-microtype-to-work-with-mathematical-minus-sign-and-package-lmodern
% \begin{macrocode}
-\DeclareMicrotypeAlias{lmsy}{cmsy}
-\DeclareMicrotypeAlias{lmm} {cmm}
-\DeclareMicrotypeAlias{aer} {cmr} % ae
-\DeclareMicrotypeAlias{zer} {cmr} % zefonts
-\DeclareMicrotypeAlias{cmor}{cmr} % eco
-\DeclareMicrotypeAlias{hfor}{cmr} % hfoldsty
+\DeclareMicrotypeAlias{lmsy}{cmsy} % "
+\DeclareMicrotypeAlias{lmm} {cmm} % "
+\DeclareMicrotypeAlias{aer} {cmr} % ae
+\DeclareMicrotypeAlias{zer} {cmr} % zefonts
+\DeclareMicrotypeAlias{cmor}{cmr} % eco
+\DeclareMicrotypeAlias{hfor}{cmr} % hfoldsty
+% \end{macrocode}
+% Another, new Computer Modern extension.
+%\changes{v2.8}{2019/11/22}{declare New Computer Modern as an alias of Latin Modern Roman}
+% \begin{macrocode}
+\DeclareMicrotypeAlias{New Computer Modern}{Latin Modern Roman}
% \end{macrocode}
% The packages \pkg{pxfonts} and \pkg{txfonts} fonts inherit Palatino and Times
% settings respectively,
@@ -13001,67 +13094,84 @@ end
%\changes{v1.9}{2005/08/16}{declare \texttt{qpl} and \texttt{qtm} (\pkg{qfonts}, \TeX\ Gyre)
% as aliases of \texttt{ppl} resp. \texttt{ptm}}
% \begin{macrocode}
-\DeclareMicrotypeAlias{pxr} {ppl} % pxfonts
-\DeclareMicrotypeAlias{qpl} {ppl} % TeX Gyre Pagella (formerly: qfonts/QuasiPalatino)
+%% -- Palatino
+\DeclareMicrotypeAlias{pxr} {ppl} % pxfonts
+\DeclareMicrotypeAlias{qpl} {ppl} % TeX Gyre Pagella (formerly: qfonts/QuasiPalatino)
% \end{macrocode}
% The `<FPL> Neu' fonts, a `re-implementation' of Palatino.
%\changes{v2.2}{2007/05/27}{declare \texttt{fp9x}, \texttt{fp9j} (<FPL> Neu) as aliases of \texttt{ppl[xj]}}
% \begin{macrocode}
-\DeclareMicrotypeAlias{fp9x}{pplx} % FPL Neu
-\DeclareMicrotypeAlias{fp9j}{pplj} % "
+\DeclareMicrotypeAlias{fp9x}{pplx} % FPL Neu
+\DeclareMicrotypeAlias{fp9j}{pplj} % "
% \end{macrocode}
% The \pkg{newpx} package, a replacement for \pkg{pxfonts}.
%\changes{v2.7}{2017/03/13}{declare aliases for \pkg{newpx}}
% \begin{macrocode}
-\DeclareMicrotypeAlias{zpllf}{ppl} % newpxtext
-\DeclareMicrotypeAlias{zplosf}{ppl} % "
-\DeclareMicrotypeAlias{zpltlf}{ppl} % "
-\DeclareMicrotypeAlias{zpltosf}{ppl} % "
-\DeclareMicrotypeAlias{txr} {ptm} % txfonts
-% \end{macrocode}
-% The \pkg{newtx} package, a replacement for \pkg{txfonts}.
-%\changes{v2.7}{2017/02/25}{declare aliases for \pkg{newtx}}
-% \begin{macrocode}
-\DeclareMicrotypeAlias{ntxlf}{ptm} % newtxtext
-\DeclareMicrotypeAlias{ntxosf}{ptm} % "
-\DeclareMicrotypeAlias{ntxtlf}{ptm} % "
-\DeclareMicrotypeAlias{ntxtosf}{ptm} % "
+\DeclareMicrotypeAlias{zpllf}{pplx} % newpxtext
+\DeclareMicrotypeAlias{zplosf}{pplj} % "
+\DeclareMicrotypeAlias{zpltlf}{pplx} % "
+\DeclareMicrotypeAlias{zpltosf}{pplj} % "
% \end{macrocode}
-% The \pkg{tempora} package.
-%\changes{v2.7}{2017/02/25}{declare aliases for \pkg{tempora}}
+% The \pkg{domitian} package.
+%\changes{v2.8}{2020/03/07}{declare aliases for \pkg{step} and \pkg{domitian}
+% (notified by \contributor Daniel Benjamin Miller <dbmiller\at dbmiller.org>)}
+% ^^A private mail, 2020/02/27
% \begin{macrocode}
-\DeclareMicrotypeAlias{Tempora-TLF}{ptm} % tempora
-\DeclareMicrotypeAlias{Tempora-TOsF}{ptm}% "
-\DeclareMicrotypeAlias{qtm} {ptm} % TeX Gyre Termes (formerly: qfonts/QuasiTimes)
+\DeclareMicrotypeAlias{Domitian-TLF} {pplx}% domitian
+\DeclareMicrotypeAlias{Domitian-TOsF}{pplj}% "
% \end{macrocode}
% The OpenType versions:
%
%\changes{v2.5}{2012/03/29}{declare TeX Gyre Pagella, Asana Math, Palatino <LT> Std, and Palatino
% as aliases of Palatino Linotype (OpenType version)}
% \begin{macrocode}
+\DeclareMicrotypeAlias{Domitian} {Palatino Linotype}
\DeclareMicrotypeAlias{TeX Gyre Pagella}{Palatino Linotype}
\DeclareMicrotypeAlias{Palatino LT Std} {Palatino Linotype}
\DeclareMicrotypeAlias{Palatino} {Palatino Linotype}
\DeclareMicrotypeAlias{Asana Math} {Palatino Linotype}
+%% -- Times New Roman
+\DeclareMicrotypeAlias{txr}{ptm} % txfonts
+% \end{macrocode}
+% The \pkg{newtx} package, a replacement for \pkg{txfonts}.
+%\changes{v2.7}{2017/02/25}{declare aliases for \pkg{newtx}}
+% \begin{macrocode}
+\DeclareMicrotypeAlias{ntxlf}{ptmx} % newtxtext
+\DeclareMicrotypeAlias{ntxosf}{ptmj} % "
+\DeclareMicrotypeAlias{ntxtlf}{ptmx} % "
+\DeclareMicrotypeAlias{ntxtosf}{ptmj} % "
+% \end{macrocode}
+% The \pkg{tempora} package.
+%\changes{v2.7}{2017/02/25}{declare aliases for \pkg{tempora}}
+% \begin{macrocode}
+\DeclareMicrotypeAlias{Tempora-TLF}{ptmx} % tempora
+\DeclareMicrotypeAlias{Tempora-TOsF}{ptmj} % "
+\DeclareMicrotypeAlias{qtm}{ptm} % TeX Gyre Termes (formerly: qfonts/QuasiTimes)
+% \end{macrocode}
+% The \pkg{step} package.
+% \begin{macrocode}
+\DeclareMicrotypeAlias{STEP-TLF}{ptmx} % step
+\DeclareMicrotypeAlias{STEP-TOsF}{ptmj} % "
+% \end{macrocode}
+% The \pkg{stix} and \pkg{stix2} packages (the latter has departed a bit from being
+% a Times clone, but still seems close enough).
+%\changes{v2.8}{2020/05/31}{declare aliases for \pkg{stix} and \pkg{stix2} fonts}
+% \begin{macrocode}
+\DeclareMicrotypeAlias{stix} {ptm} % stix
+\DeclareMicrotypeAlias{stix2}{ptm} % stix2
% \end{macrocode}
%\todo{check Times variants}
% More Times variants, to be checked: |pns|, |mns| (TimesNewRomanPS); |mnt|
% (Times\-NewRomanMT, TimesNRSevenMT), |mtm| (TimesSmallTextMT); |pte|
% (TimesEuropa); |ptt| (TimesTen); TimesEighteen; TimesModernEF.
%
-% The \pkg{eulervm} package virtually extends the Euler fonts.
-%\changes{v1.9e}{2006/07/28}{declare \texttt{zeur} and \texttt{zeus} (\pkg{eulervm})
-% as aliases of \texttt{eur} resp. \texttt{eus} (\pkg{euler})}
-% \begin{macrocode}
-\DeclareMicrotypeAlias{zeur}{eur} % Euler VM
-\DeclareMicrotypeAlias{zeus}{eus} % "
-% \end{macrocode}
% MicroPress's Charter version (\pkg{chmath}).
%\changes{v2.2}{2007/06/08}{declare \texttt{chr} (\pkg{chmath}) as an alias of \texttt{bch}
% (reported by \contributor Geoff Vallis <gkv\at Princeton.EDU>)}
% ^^A private mail, 2007/06/07
% \begin{macrocode}
-\DeclareMicrotypeAlias{chr} {bch} % CH Math
+%% -- Charter
+\DeclareMicrotypeAlias{chr}{bch} % CH Math
% \end{macrocode}
%\changes{v2.7}{2017/03/13}{declare aliases for \pkg{XCharter}}
% The \pkg{XCharter} package extends the Charter fonts.
@@ -13074,29 +13184,38 @@ end
% as an alias of \texttt{bch}}
% and <URW> Garamond.
% \begin{macrocode}
-\DeclareMicrotypeAlias{mdbch}{bch} % mathdesign/Charter
-\DeclareMicrotypeAlias{mdugm}{ugm} % mathdesign/URW Garamond
+\DeclareMicrotypeAlias{mdbch}{bch} % mathdesign/Charter
+%% -- Garamond
+\DeclareMicrotypeAlias{mdugm}{ugm} % mathdesign/URW Garamond
% \end{macrocode}
% The \pkg{garamondx} package, an extension of <URW> Garamond, providing
% small caps and oldstyle figures.
%\changes{v2.5}{2013/02/20}{declare \texttt{zgmx} etc. (\pkg{garamondx})
% as aliases of \texttt{ugm}}
% \begin{macrocode}
-\DeclareMicrotypeAlias{zgmx}{ugm} % garamondx
-\DeclareMicrotypeAlias{zgmj}{ugm} % "
-\DeclareMicrotypeAlias{zgmI}{ugm} % "
-\DeclareMicrotypeAlias{zgmq}{ugm} % "
+\DeclareMicrotypeAlias{zgmx}{ugm} % garamondx
+\DeclareMicrotypeAlias{zgmj}{ugm} % "
+\DeclareMicrotypeAlias{zgmI}{ugm} % "
+\DeclareMicrotypeAlias{zgmq}{ugm} % "
+%% --
% \end{macrocode}
% <URW> Letter Gothic is similar enough to Bitstream Letter Gothic to share the
% configuration.
% \begin{macrocode}
-\DeclareMicrotypeAlias{ulg} {blg} % URW LetterGothic -> Bitstream LetterGothic12Pitch
+\DeclareMicrotypeAlias{ulg}{blg} % URW LetterGothic -> Bitstream LetterGothic12Pitch
+% \end{macrocode}
+% The \pkg{eulervm} package virtually extends the Euler fonts.
+%\changes{v1.9e}{2006/07/28}{declare \texttt{zeur} and \texttt{zeus} (\pkg{eulervm})
+% as aliases of \texttt{eur} resp. \texttt{eus} (\pkg{euler})}
+% \begin{macrocode}
+\DeclareMicrotypeAlias{zeur}{eur} % Euler VM
+\DeclareMicrotypeAlias{zeus}{eus} % "
% \end{macrocode}
% Euro symbol fonts, to save some files.
% \begin{macrocode}
-\DeclareMicrotypeAlias{zpeus} {zpeu} % Adobe Euro sans -> serif
-\DeclareMicrotypeAlias{eurosans}{zpeu} % Adobe Euro sans -> serif
-\DeclareMicrotypeAlias{euroitcs}{euroitc}% ITC Euro sans -> serif
+\DeclareMicrotypeAlias{zpeus} {zpeu} % Adobe Euro sans -> serif
+\DeclareMicrotypeAlias{eurosans}{zpeu} % Adobe Euro sans -> serif
+\DeclareMicrotypeAlias{euroitcs}{euroitc} % ITC Euro sans -> serif
% \end{macrocode}
%
@@ -13145,7 +13264,7 @@ end
% encoding with \cmd\DeclareTextSymbol\ or \cmd\DeclareTextComposite.
% Characters defined via \cmd\chardef\ are also possible.
%
-% Ligatures and \cmd\mathchardef ed symbols have to be specified numerically.
+% Ligatures and \cmd\mathchardef'ed symbols have to be specified numerically.
% Of course, numerical identification is possible in any other case, too.
%
%\changes{v1.1}{2004/09/14}{remove 8-bit characters from the configuration files
@@ -13157,7 +13276,8 @@ end
% combination with the `|inputenc|' key.
%
% With \xetex\ or \luatex, in contrast, it is advisable to use the proper
-% Unicode characters.
+% Unicode characters, or the font-specific glyph names prefixed with `|/|'
+% (cf. section \ref{sec:OpenType}).
%
%\subsection{Character inheritance}
%\GeneralChanges{Inheritance}
@@ -16971,9 +17091,9 @@ end
%
%\IfFileExists{microtype-utf.pdf}
% {\includepdf[pages=-,
-% addtotoc={1,section,1,OpenType configuration files,section.\thesection,
-% \utfsectioni,subsection,2,Character inheritance,subsection.\thesection.1,
-% \utfsectionii,subsection,2,Character protrusion,subsection.\thesection.2}]
+% addtotoc={1,section,1,OpenType configuration files,sec:OpenType,
+% \utfsectioni,subsection,2,Character inheritance,sub:OT-inheritance,
+% \utfsectionii,subsection,2,Character protrusion,sub:OT-protrusion}]
% {microtype-utf.pdf}}
% {\section{OpenType configuration settings}
% To view the OpenType configuration settings, first typeset
@@ -17134,7 +17254,7 @@ normal, and shrunk by 5\%:
% Grave accent \` Left brace \{ Vertical bar \|
% Right brace \} Tilde \~}
%
-% \CheckSum{10666}
+% \CheckSum{10748}
%
% \Finale
%
diff --git a/macros/latex/contrib/microtype/microtype.ins b/macros/latex/contrib/microtype/microtype.ins
index 7fa515b865..e26326e802 100644
--- a/macros/latex/contrib/microtype/microtype.ins
+++ b/macros/latex/contrib/microtype/microtype.ins
@@ -10,7 +10,7 @@
The `microtype' package
Subliminal refinements towards typographical perfection
- Copyright (c) 2004--2019 R Schlicht <w.m.l@gmx.net>
+ Copyright (c) 2004--2020 R Schlicht <w.m.l@gmx.net>
This work may be distributed and/or modified under the conditions of the
LaTeX Project Public License, either version 1.3c of this license or (at
diff --git a/macros/latex/contrib/microtype/microtype.pdf b/macros/latex/contrib/microtype/microtype.pdf
index 6c2810a2c9..9a628fbca3 100644
--- a/macros/latex/contrib/microtype/microtype.pdf
+++ b/macros/latex/contrib/microtype/microtype.pdf
Binary files differ
diff --git a/macros/latex/contrib/stringstrings/stringstrings.dtx b/macros/latex/contrib/stringstrings/stringstrings.dtx
index 24baeeda9c..9f0effbb27 100644
--- a/macros/latex/contrib/stringstrings/stringstrings.dtx
+++ b/macros/latex/contrib/stringstrings/stringstrings.dtx
@@ -1,4385 +1,4386 @@
-% \iffalse
-%<package>\ProvidesPackage{stringstrings}
-%<package>[2015/02/02 v1.23
-%<package> Extensive array of string manipulation routines for
-%<package> cosmetic and programming application]
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<*driver>
-% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
-% of this license or (at your option) any later version.
-% The latest version of this license is in
-% http://www.latex-project.org/lppl.txt
-% and version 1.3c or later is part of all distributions of LaTeX
-% version 2005/12/01 or later.
-%
-% This work has the LPPL maintenance status `maintained'.
-%
-% The Current Maintainer of this work is Steven B. Segletes.
-%
-% v1.00 -Initial Release
-% v1.01 -Included support for & character, though it loses catcode 4
-% status
-% v1.02 -Bug fix. Needed some % chars in \convertchar to avoid extra spaces
-% v1.03 -Documentation fix; notably removed 's' from \narg in \getargs
-% v1.04 -Removed \rotate command, as it conflicts with environment in
-% \usepackage{rotating}
-% v1.10 -Fixed bug in convertword by adding @@@stringsize definition to
-% \whereisword
-% -Added suite of routines to support \capitalizetitle functionality
-% v1.20 -Added ability to encode/decode arbitrary tokens
-% v1.21 -Added %, removing extra space (bug) from \whereisword
-% v1.22 -Added %, removing extra space (bug) from \getargs
-% v1.23 -Changed {~} to {\ } in \retokenizechar
-% -Forced all stringtest commands to function outside of math mode
-% which will give correct result, when invoked within math mode.
-\documentclass{ltxdoc}
-\usepackage{stringstrings}
-\DisableCrossrefs
-\CodelineNumbered
-% DEFINE SOME CAMMANDS THAT ARE EASIER HERE THAN IN DocInput ENVIRONMENT
-\newcommand\stringstrings{\textsf{stringstrings}~}
-\newcommand\coolstr{\textsf{coolstr}~}
-% ITALICIZED i.e.,
-\newcommand{\ie}{\textit{i.e.},~}%
-% ITALICIZED e.g.,
-\newcommand{\eg}{\textit{e.g.},~}%
-% ITALICIZED etc.
-\newcommand{\etc}{\textit{etc}.}%
-\def\modetablelayout{|l|c|c|c|}
-\def\mylayout{@{}c|c|l@{}}
-\stringencode{\|}
-\stringdecode[q]{\thestring}
-\edef\mypipe{\thestring}
-\stringencode{\carat}
-\stringdecode[q]{\thestring}
-\edef\mycarat{\thestring}
-
-\GetFileInfo{stringstrings.sty}
-\begin{document}
- \title{The \stringstrings Package\\
- \rule{0em}{0.7em}\small\fileinfo}
- \author{Steven B. Segletes\\
- steven.b.segletes.civ@mail.mil}
- \date{\filedate\\
- \fileversion}
- \maketitle
- \DocInput{stringstrings.dtx}
-\end{document}
-%</driver>
-%\fi
-% \parskip 1ex
-% \begin{abstract}
-% The \stringstrings package provides a large and sundry array of routines
-% for the manipulation of strings. The routines are developed not only
-% for cosmetic application, such as the changing of letter
-% cases, selective removal of character classes, and string
-% substitution,
-% but also for programming application, such as character look-ahead
-% applications, argument parsing, |\if|-tests for various string
-% conditions, etc. A key tenet employed during the
-% development of this package (unlike, for comparison, the |\uppercase|
-% and |\lowercase| routines) was to have resultant strings be
-% ``expanded'' (\ie the product of an |\edef|), so that the
-% \stringstrings routines could be strung together sequentially and
-% nested (after a fashion) to achieve very complex manipulations.
-%
-% \end{abstract}
-%
-% \vspace{-.55em}
-% \tableofcontents\rule[.2em]{4.5in}{.3mm}\vspace{-1.5em}
-%
-% \section {Motivation}
-%
-% There were two seminal moments that brought about my motivation to
-% develop this package. The first was the realization of the oft
-% cited and infamous \LaTeX{} limitation concerning the inability to
-% nest letter-case changes with \LaTeX{}'s intrinsic |\uppercase| and
-% |\lowercase| routines. The second,
-% though not diminishing its utility in many useful applications, was
-% the inherent limitations of the \coolstr package, which is otherwise
-% a useful tool for extracting substrings and measuring string lengths.
-%
-% The former is well documented and need not be delved into in great
-% detail. Basically, as it was explained to me, |\uppercase| and
-% |\lowercase| are expanded by \LaTeX{} at the last possible moment, and
-% thus attempts to capture their result for subsequent use are doomed to
-% failure. One is forced to adopt the left-to-right (rather than
-% nested) approach to case changes.
-%
-% In the case of the \coolstr package, I again want to express
-% my admiration for the utility of this package. I briefly considered
-% building the \stringstrings package around it, but it proved
-% unworkable, because of some intrinsic limitations.
-% First, \coolstr operates on
-% strings, not tokens, and so in order to fool it into working on
-% tokenized inputs, one must use the cumbersome nomenclature of
-%
-% |\expandafter\substr\expandafter{\TokenizedString}{...}{...}|
-% \vspace{1ex}\\%
-% in order to, for example grab a substring of |\TokenizedString|. One
-% may |\def| the result of this subroutine, and use it elsewhere in an
-% unaltered state. However, one may not expand, via |\edef|, the
-% result of |\substr| in order to use it as input to a subsequent string
-% manipulation. And thus, the desire to engage in successive string
-% manipulations of different natures (\eg capitalization of leading
-% characters, extraction of words, reversal of character sequence,
-% removal of character classes, etc., etc.) are not achievable in the
-% context of \textsf{coolstr}.
-%
-% It was this state of affairs that brought me to hunger for routines
-% that could thoroughly manipulate strings, and yet produce their result
-% ``in the clear'' (\ie in an untokenized form) which could be used as
-% input for the next manipulation. It turns out the heart of the
-% \stringstrings package which achieves this goal is based on the simple
-% (if much maligned) |\if| construct of \LaTeX{}, by using successive
-% iterations of the following construct:
-%
-% |\if <|\textit{test char.}|><|\textit{string}|><|\textit{manipulated
-% test char.}|>\else ...\fi|
-% \vspace{1ex}\\%
-% in which a character at the begining of a string is tested. If a
-% match is found,
-% the manipulated test character is replaced at the end of the string,
-% while the original test character is lopped off from the beginning of
-% the string. A false result is used to proceed to a different test
-% character. In this manner, the string may be rotated through,
-% character by character, performing the desired manipulations. And,
-% most importantly, the product of this operation may be placed into an
-% |\edef|.
-%
-% It turns out there was one glitch to this process (which has been
-% successfully remedied in the \stringstrings package). And that is that
-% there are several tokenized \LaTeX{} symbols (\eg |\$|, |\{|, |\}|,
-% |\AE|, |\oe|, etc.) which expand to more than a single byte. If
-% I was more savvy on \LaTeX{} constructs, I would probably have known
-% how to handle this better. But my solution was to develop my own
-% encoding scheme wherein these problematic characters were re-encoded
-% in my intermediate calculations as a 2-byte (escape character-escape code)
-% combination, and only converted back into \LaTeX{} symbols at the last
-% moment, as the finalized strings were handed back to the user.
-%
-% There are also several tokens, like |\dag|, |\ddag|, |\P|, |\d|, |\t|,
-% |\b|, and |\copyright| which
-% can not be put into an |\edef| construct. The solution developed for
-% strings containing these such characters was to convert the encoded
-% string not into an expanded |\edef| construct, but rather back into a
-% tokenized form amenable to |\def|. The |\retokenize| command
-% accomplishes this task and several others.
-%
-% There was also one glitch that I have not yet been able to resolve
-% to my full satisfaction, though I have provided a workaround.
-% And that is the occurance of \LaTeX{} grouping characters, |{| and
-% |}|, that might typically occur in math mode. The problem is that the
-% character-rotate technique that is the core of \stringstrings breaks
-% when rotating these group characters. Why?? Because a string
-% comprised of |...{...}...|, during the rotation process, will
-% eventually become |...}......{| during an intermediate stage of
-% character rotation. This
-% latter string breaks \LaTeX{} because it is not a properly constructed
-% grouping, even if subsequent rotations would intend to bring it back
-% into a proper construction.
-%
-% And so, while \stringstrings can handle certain math-mode
-% constructs (\eg |$|, |^|, and |_|), it is unable to {\it directly}
-% handle groupings that are brought about by the use of curly braces.
-% Note that |\{| and |\}| are handled just fine, but not |{| and |}|.
-% As a result of this limitation regarding the use of grouping braces
-% within strings, \stringstrings support for various math symbols
-% remains quite limited.
-%
-% While it is also common to use curly braces to
-% delimit the arguments of diacritcal marks in words like
-% |m\"{u}de| \etc, the same result can be achieved without the
-% use of braces as |m\"ude|, with the proper result obtained: m\"ude.
-% For diacritical marks that have an alphabetic token such as the breve,
-% given by |\u|, the curly braces can also be omitted, with the only
-% change being a space required after the |\u| to delimit the token.
-% Thus, |c\u at| becomes c\u at. Therefore, when manipulating strings
-% containing diacritical marks, it is best to formulate them, if
-% possible, without the use of curly braces.
-%
-% The workaround fix I have developed, to provide grouping functions
-% within \stringstrings arguments, involves the use of newly defined
-% tokens |\LB| and |\RB| (to be used in lieu of |{| and |}|),
-% along with a command |\retokenize|. This
-% workaround will be described subsequently, in the Disclaimers section.
-%
-% \section{Philosophy of Operation}
-%
-% There are several classes of commands that have been developed as part
-% of the \stringstrings package. In addition to {\bf Configuration
-% Commands}, which set parameters for subsequent string operations,
-% there are the following command classes:
-% \begin{itemize}
-% \item {\bf Commands to Manipulate Strings} -- these commands take an
-% input string or token and perform a specific manipulation on the
-% string;
-% \item {\bf Commands to Extract String Information} -- these commands
-% take an input string or token, and ascertain a particular
-% characteristic of the string; and
-% \item {\bf Commands to Test Strings} -- these commands take an input
-% string or token and test for a particular alphanumeric condition.
-% \end{itemize}
-% Of course, there are also {\bf Support Commands} which are low-level
-% routines which provide functionality to the package, which are
-% generally not accessible to the user.
-%
-% To support the intended philosophy that the user may achieve a complex
-% string manipulation though a series of simpler manipulations (which
-% is otherwise known as nesting), a mechanism had to be developed. True
-% command nesting of the form |\commandA{\commandB{\commandC{string}}}|
-% is {\bf not} supported by the \stringstrings package, since many of
-% the manipulation commands make use of (and would thus inadvertantly
-% overwrite) the same sets of variables used by other routines.
-% Furthermore, there is that 'ol left-to-right philosophy of \LaTeX{} to
-% contend with.
-%
-% Instead, for the case of commands that manipulate strings, the expanded
-% (\ie |\edef|'ed) result of the manipulation is placed into a string
-% called |\thestring|\DescribeMacro{\thestring}. Then, |\thestring|
-% may either be directly used
-% as the input to a subsequent operation, or |\edef|'ed into another
-% variable to save it for future use.
-%
-% String manipulation commands use an optional first argument to specify
-% what to do with the manipulated string (in addition to putting it in
-% |\thestring|). Most string manipulation
-% commands default to verbose mode |[v]|\DescribeMacro{[v]}, and print
-% out their result immediately on the assumption that a simple string
-% manipulation is, many times, all that is required. If the user wishes
-% to use the manipulated result as is, but needs to use it later in the
-% document, a quiet mode |[q]| \DescribeMacro{[q]} is provided which
-% suppresses the immediate output of |\thestring|.
-%
-% In the absence of symbol tokens (\eg |\$|, |\&|, |\oe|, |\^|, \etc),
-% the verbose and quiet modes would prove sufficient. However, when a
-% tokenized symbol is |\edef|'ed, the token is expanded to the actual
-% symbolic representation of the character. If this expanded symbol is
-% used as part of an input string to a
-% subsequent \stringstrings manipulation
-% routine, it gets confused, because the means to detect the token are
-% characteristically different than the means to detect the expanded
-% symbol. Thus, if one wishes to use |\thestring| as an input to a
-% subsequent manipulation routine, \stringstrings provides an encoded
-% mode |[e]| \DescribeMacro{[e]} which places an encoded version of the
-% resulting manipulation into
-% |\thestring|. The encoded mode is also a quiet mode, since it leaves
-% |\thestring| in a visually unappealing state that is intended for
-% subsequent manipulation.
-%
-% The encoded mode is not a \LaTeX{} standard,
-% but was developed for this application. And therefore, if the result
-% of a \stringstrings manipulation is needed as input for a routine
-% outside of the \stringstrings package, the encoded mode will be of no
-% use. For this reason (and others),
-% the |\retokenize| \DescribeMacro{\retokenize}
-% command is provided. Its use is one of only three times that a
-% \stringstrings command
-% returns a tokenized |\def|'ed string in |\thestring|, rather than an
-% expanded, |\edef|'ed string. And in the other two cases, both
-% call upon |\retokenize|.
-%
-% In addition to providing tokenized strings that can be passed to other
-% \LaTeX{} packages, |\retokenize| can also remedy \stringstrings problems
-% associated with inadequate character encodings (OT1) and the use of
-% grouping characters |{| and |}| within \stringstrings arguments. This
-% issue is discussed more fully in the Disclaimers section, and in the
-% actual |\retokenize| command description.
-%
-% Therefore, for complex multistage string manipulations, the
-% recommended procedure
-% is to perform each stage of the manipulation in encoded |[e]| mode,
-% passing along |\thestring| to each subsequent stage of the
-% manipulation, until the very last manipulation, which should be,
-% at the last, performed in verbose |[v]| or quiet |[q]| modes. If
-% the resulting manipulation is to be passed to a command outside of the
-% \stringstrings package for further manipulation (or if the string
-% contains characters which cannot be placed into an |\edef|),
-% |\thestring| may
-% need to be |\retokenize|'ed. If concatenations of two (or more) different
-% manipulations are to be used as input to a third manipulation,
-% |\thestring| from the first manipulation will need to be immediately
-% |\edef|'ed into a different variable, since |\thestring| will be
-% overwritten by the second manipulation (see Table~\ref{tbl:modes}
-% for summary).
-% \begin{table}[h]
-% \begin{center}
-% \caption{\bf Execution Modes of \stringstrings Commands
-% \label{tbl:modes}}\vspace{0.5em}
-% \small
-% \begin{tabular}\modetablelayout
-% \hline
-% Mode & Coding & Use when result is & |\thestring| is\\
-% \hline
-% \hline
-% |[v]| verbose & decoded or retokenized & final & echoed \\
-% |[q]| quiet & decoded or retokenized & final & not echoed \\
-% |[e]| encoded & encoded & intermediate & not echoed \\
-% \hline
-% \end{tabular}
-% \end{center}
-% \end{table}
-%
-% Moving on to commands that extract string information, this class of
-% commands (unless otherwise noted) output their result into a token
-% which is given the name |\theresult|\DescribeMacro{\theresult}.
-% This token does not contain a manipulated form of the string, but
-% rather a piece of information about the string, such as ``how many
-% characters are in the string?'', ``how many words are in the string?'',
-% ``how many letter `e's are in the string?'', \etc
-%
-% The final class of \stringstrings commands are the string-test
-% commands. While some of this class of commands also store their
-% test result in |\theresult|, most of these commands use the
-% |\test|{\it condition}|{|{\it string}|}| |\if|{\it
-% condition} constructs (see {\sf ifthen} package) to answer true/false
-% questions like ``is the string composed entirely of lowercase
-% characters?'', ``is the string's first letter capitalized?'' \etc
-%
-% \section {Configuration Commands}
-%
-% \noindent%
-% |\Treatments{|{\it U-mode}|}{|{\it l-mode}|}{|{\it p-mode}|}{|{\it%
-% n-mode}|}{|{\it s-mode}|}{|{\it b-mode}|}|\\
-% |\defaultTreatments|\\
-% |\encodetoken[|{\it index}|]{|{\it token}|}|\\
-% |\decodetoken[|{\it index}|]{|{\it token}|}|\\
-% |\+|\\
-% |\?|
-%
-% The command |\Treatments| \DescribeMacro{\Treatments}
-% is used to define how different classes of
-% characters are to be treated by the command |\substring|, which is the
-% brains of the \stringstrings package. As will be explained in the
-% next section, most string manipulation routines end up calling
-% |\substring|, the difference between them being a matter of how these
-% character treatments are set prior to the call.
-% Because most string manipulation
-% commands will set the treatments as necessary to perform their given
-% task, and reset them to the default upon conclusion, one should set
-% the |\Treatments| immediately prior to the call upon |\substring|.
-%
-% |\Treatments| has six arguments, that define the mode of treatment
-% for the six classes of characters that \stringstrings has designated.
-% All modes are one-digit integers. They are described below:
-% \begin{itemize}
-% \item{\it U-mode---} This mode defines the
-% treatment for the upper-case characters (A--Z, \OE, \AE, \AA, \O, and
-% \L).
-% A mode of 0 tells |\substring| to remove upper-case characters, a
-% mode of 1 indicates to leave upper-case characters alone, and
-% a mode of 2 indicates to change the case of upper-case
-% characters to lower case.
-%
-% \item {\it l-mode---} This mode defines the
-% treatment for the lower-case characters (a--z, \oe, \ae, \aa, \o, \l,
-% and \ss).
-% A mode of 0 tells |\substring| to remove lower-case characters, a
-% mode of 1 indicates to leave lower-case characters alone, and
-% a mode of 2 indicates to change the case of lower-case
-% characters to upper case. In the case of the eszett character (\ss),
-% there is no uppercase equivalent, and so an {\it l-mode} of 2 will
-% leave the eszett unchanged.
-%
-% \item {\it p-mode---} This mode defines the
-% treatment for the punctuation characters. \stringstrings
-% defines the punctuation characters as ; : ' " , . ? ` and ! A mode of
-% 0 tells |\substring| to remove punctuation characters, while a mode of
-% 1 indicates to leave punctuation characters as is.
-%
-% \item {\it n-mode---} This mode defines the
-% treatment for the numerals (0--9). A mode of
-% 0 tells |\substring| to remove numerals, while a mode of
-% 1 indicates to leave numerals as is.
-%
-% \item {\it s-mode---} This mode defines the
-% treatment for the symbols. \stringstrings
-% defines symbols as the following characters and diacritical marks:
-% \substring{/ * ( ) - = + [ ] $<$ $>$}{1}{$} \& |\& \% \# \{ \} \_ \$|
-% \dag~\ddag~\S~\P~\L~\pounds~\copyright~\v x \^x \~x \"x \`x \'x \=x
-% \.x \u x \v x
-% \H x \c x \d x \t{xx} \b x as well as |@|, math and text carats,
-% and the pipe symbol. A mode of
-% 0 tells |\substring| to remove symbols, while a mode of
-% 1 indicates to leave symbols as is. Note that the \$ symbol, when
-% used for entering and exiting math mode, is left intact, regardless of
-% {\it s-mode}.
-%
-% % \item {\it b-mode---} This mode defines the
-% treatment for blankspaces. A mode of
-% 0 tells |\substring| to remove blankspaces, while a mode of
-% 1 indicates to leave blankspaces as is. The treatment apples to both
-% soft (~) as well as hard (|~|) spaces.
-% \end{itemize}
-%
-% The command |\defaultTreatments| \DescribeMacro{\defaultTreatments}
-% resets all treatment modes to their default settings, which are to
-% leave individual characters unaltered by a string manipulation.
-%
-% The commands |\encodetoken| \DescribeMacro{\encodetoken} and
-% |\decodetoken| \DescribeMacro{\decodetoken} have been introduced in
-% \stringstrings v1.20. Prior to this version, the ability of
-% \stringstrings to handle a particular token was dependent on whether
-% provisions for encoding that token had been explicitly hardwired into
-% the \stringstrings package. A large number of alphabetic and
-% diacritical marks had reserved encodings set aside in \stringstrings
-% for their treatment (see next paragraph or Table 2 for their enumeration).
-% However, requests would invariable come in for treating yet another
-% token, which required a new \stringstrings release for each revision.
-% The command |\encodetoken| allows the user to specify an arbitrary
-% token, to be assigned to the reserved encoding slot associated with the
-% index (permissible indices are in the range 1--3, 1 being the default).
-% Once assigned an encoding slot, a token may be successfully manipulated in
-% \stringstrings routines. Once \stringstrings manipulation is
-% complete, the token must undergo a |\decodetoken| operation in order
-% for that token to be reset to a normal \LaTeX{} token again (lest it
-% display in its encoded \stringstrings form).
-%
-% The commands |\+| and |\?| \DescribeMacro{\+}\DescribeMacro{\?}
-% are a pair that work in tandem to turn on \stringstrings encoding and
-% turn off \stringstrings encoding, respectively. Generally, the user
-% will not need these commands unless he is writing his own routines to
-% take advantage of the \stringstrings library. After |\+| is called,
-% tokens which would otherwise expand to multi-byte sequences are
-% instead encoded according to the \stringstrings methodology. The
-% affected tokens
-% include
-% |\$ \^ \" \{ \} \_ \dag \ddag \P \S \ss \AA \aa \O \o \AE \ae|
-% |\OE|, |\oe|, |\~|, |\`|, |\'|, |\=|, |\.|, |\u|, |\v|, |\H|, |\c|,
-% |\d|, |\t|, |\b|, |\copyright|, |\pounds|, |\L|, |\l|, and |\ss|. In
-% addition, pipes, text carats, and hard spaces (|~|) are encoded
-% as well. The command |\?| restores the
-% standard \LaTeX{} encoding for these tokens.
-%
-% \section {Commands to Manipulate Strings}
-%
-% These commands take an
-% input string or token and perform a specific manipulation on the
-% string. They include:
-%
-% \noindent|\substring[|{\it mode}|]{|{\it
-% string}|}{|{\it min}|}{|{\it max}|}|\\
-% |\caseupper[|{\it mode}|]{|{\it string}|}|\\
-% |\caselower[|{\it mode}|]{|{\it string}|}|\\
-% |\solelyuppercase[|{\it mode}|]{|{\it string}|}|\\
-% |\solelylowercase[|{\it mode}|]{|{\it string}|}|\\
-% |\changecase[|{\it mode}|]{|{\it string}|}|\\
-% |\noblanks[|{\it mode}|]{|{\it string}|}|\\
-% |\nosymbolsnumerals[|{\it mode}|]{|{\it string}|}|\\
-% |\alphabetic[|{\it mode}|]{|{\it string}|}|\\
-% |\capitalize[|{\it mode}|]{|{\it string}|}|\\
-% |\capitalizewords[|{\it mode}|]{|{\it string}|}|\\
-% |\capitalizetitle[|{\it mode}|]{|{\it string}|}|\\
-% |\addlcword{|{\it word}|}|\\
-% |\addlcwords{|{\it word1 word2 word3 \ldots}|}|\\
-% |\resetlcwords|\\
-% |\reversestring[|{\it mode}|]{|{\it string}|}|\\
-% |\convertchar[|{\it mode}|]{|{\it
-% string}|}{|{\it from-char}|}{|{\it to-string}|}|\\
-% |\convertword[|{\it mode}|]{|{\it
-% string}|}{|{\it from-string}|}{|{\it to-string}|}|\\
-% |\rotateword[|{\it mode}|]{|{\it string}|}|\\
-% |\removeword[|{\it mode}|]{|{\it string}|}|\\
-% |\getnextword[|{\it mode}|]{|{\it string}|}|\\
-% |\getaword[|{\it mode}|]{|{\it string}|}{|{\it n}|}|\\
-% |\rotateleadingspaces[|{\it mode}|]{|{\it string}|}|\\
-% |\removeleadingspaces[|{\it mode}|]{|{\it string}|}|\\
-% |\stringencode[|{\it mode}|]{|{\it string}|}|\\
-% |\stringdecode[|{\it mode}|]{|{\it string}|}|\\
-% |\gobblechar[|{\it mode}|]{|{\it string}|}|\\
-% |\gobblechars[|{\it mode}|]{|{\it string}|}{|{\it n}|}|\\
-% |\retokenize[|{\it mode}|]{|{\it string}|}|
-%
-% \noindent
-% Unless otherwise noted, the {\it mode} may take one of three values:
-% |[v]| for verbose mode (generally, the default), |[q]| for quiet mode,
-% and |[e]| for encoded mode. In all cases, the result of
-% the operation is stored in |\thestring|. In verbose mode, it is also
-% output immediately (and may be captured by an |\edef|). In quiet mode,
-% no string is output, though the result still resides in |\thestring|.
-% Encoded mode is also a quiet mode. However, the encoded mode saves
-% the string with its \stringstrings encodings. Encoded mode indicates
-% that the result is an intermediate result which will be subsequently
-% used as input to another \stringstrings manipulation.
-%
-% The command |\substring| \DescribeMacro{\substring} is the brains of
-% the \stringstrings package, in that most of the commands in this
-% section call upon |\substring| in one form or another. Nominally, the
-% routine returns a substring of {\it string} between the characters
-% defined by the integers {\it min} and {\it max}, inclusive.
-% However, the returned substring is
-% affected by the designated |\Treatments| which have been defined
-% for various classes of characters. Additionally, a shorthand of \$
-% may be used in {\it min} and {\it max} to define END-OF-STRING, and
-% the shorthand \$--{\it integer} may be used to define an offset of
-% {\it integer} relative to the END-OF-STRING.
-%
-% Regardless of how many bytes a \LaTeX{} token otherwise expands
-% to, or how many characters are in the token name, each \LaTeX{}
-% symbol token
-% counts as a single character for the purposes of defining the
-% substring limits, {\it min} and {\it max}.
-%
-% While the combination of |\Treatments| and |\substring| are sufficient
-% to achieve a wide array of character manipulations, many of those
-% possibilities are useful enough that separate commands have been
-% created to describe them, for convenience. Several of the commands
-% that follow fall into this category.
-%
-% The command |\caseupper| \DescribeMacro{\caseupper} takes the input
-% string or token, and converts all lowercase characters in the string
-% to uppercase. All other character classes are left untouched.
-% Default mode is |[v]|.
-%
-% The command |\caselower| \DescribeMacro{\caselower} takes the input
-% string or token, and converts all uppercase characters in the string
-% to lowercase. All other character classes are left untouched.
-% Default mode is |[v]|.
-%
-% The command |\solelyuppercase| \DescribeMacro{\solelyuppercase} is
-% similar to |\caseupper|, except that all punctuation, numerals, and
-% symbols are discarded from the string. Blankspaces are left alone,
-% and lowercase characters are converted to uppercase.
-% Default mode is |[v]|.
-%
-% The command |\solelylowercase| \DescribeMacro{\solelylowercase} is
-% similar to |\caselower|, except that all punctuation, numerals, and
-% symbols are discarded from the string. Blankspaces are left alone,
-% and uppercase characters are converted to lowercase.
-% Default mode is |[v]|.
-%
-% The command |\changecase| \DescribeMacro{\changecase} switches lower
-% case to upper case and upper case to lower case. All other characters
-% are left unchanged.
-% Default mode is |[v]|.
-%
-% The command |\noblanks| \DescribeMacro{\noblanks} removes blankspaces
-% (both hard and soft) from
-% a string, while leaving other characters unchanged.
-% Default mode is |[v]|.
-%
-% The command |\nosymbolsnumerals| \DescribeMacro{\nosymbolsnumerals}
-% removes symbols and numerals from
-% a string, while leaving other characters unchanged.
-% Default mode is |[v]|.
-%
-% The command |\alphabetic| \DescribeMacro{\alphabetic} discards
-% punctuation, symbols, and numerals, while retaining alphabetic
-% characters and blankspaces.
-% Default mode is |[v]|.
-%
-% The command |\capitalize| \DescribeMacro{\capitalize} turns the first
-% character of {\it string} into its upper case, if it is alphabetic.
-% Otherwise, that character will remain unaltered.
-% Default mode is |[v]|.
-%
-% The command |\capitalizewords| \DescribeMacro{\capitalizewords} turns
-% the first character of every word in {\it string} into its upper
-% case, if it is alphabetic.
-% Otherwise, that character will remain unaltered. For the purposes of
-% this command, ``the first character of a word'' is defined as either
-% the first character of the string, or the first non-blank
-% character that follows one or more blankspaces.
-% Default mode is |[v]|.
-%
-% The command |\capitalizetitle| \DescribeMacro{\capitalizetitle} is a
-% command similar to |\capitalizewords|, except that words which have
-% been previously designated as ``lower-case words'' are not
-% capitalized (\eg prepositions, conjunctions, \etc). In all cases,
-% the first word of the string is
-% capitalized, even if it is on the lower-case word list. Words are
-% added to the lower-case word list with the commands
-% |\addlcword|\DescribeMacro{\addlcword}, in the case of a single word,
-% or with |\addlcwords|\DescribeMacro{\addlcwords}, in the case of
-% multiple (space-separated) words. Because the addition of many words
-% to the lower-case list can substantially slow-down the execution of
-% the |\capitalizetitle| command, the command
-% |\resetlcwords| \DescribeMacro{\resetlcwords} has been added to
-% allow the user to zero out the lower-case word list.
-% (See newer \textsf{titlecaps} package as an alternative to this
-% command.)
-%
-% The command |\reversestring| \DescribeMacro{\reversestring} reverses
-% the sequence of characters in a string, such that what started as
-% the first character becomes the last character in the manipulated
-% string, and what started as the last character becomes the
-% first character.
-% Default mode is |[v]|.
-%
-% The command |\convertchar| \DescribeMacro{\convertchar} is a substitution
-% command in which a specified match character in the original string
-% ({\it from-char}) is substituted with a different string ({\it
-% to-string}). All occurances of {\it from-char} in the original
-% string are replaced. The {\it from-char} can only be a single
-% character (or tokenized symbol), whereas {\it to-string} can range
-% from the null-string (\ie character removal) to a single character
-% (\ie character substitution)
-% to a complete multi-character string.
-% Default mode is |[v]|.
-%
-% The command |\convertword| \DescribeMacro{\convertword} is a substitution
-% command in which a specified match string in the original string
-% ({\it from-string}) is substituted with a different string ({\it
-% to-string}). All occurances of {\it from-string} in the original
-% string are replaced. If {\it from-string} includes spaces, use
-% hard-space |(~)| characters instead of blanks.
-% Default mode is |[v]|.
-%
-% The command |\rotateword| \DescribeMacro{\rotateword} takes the first
-% word of {\it string} (and its leading and trailing spaces)
-% and rotates them to the end of the string.
-% Care must be taken to have a blankspace at the beginning or end
-% of {\it string} if one wishes to retain a blankspace word
-% separator between the original last word of the string and the
-% original first word which has been rotated to the end of the string.
-% Default mode is |[v]|.
-%
-% The command |\removeword| \DescribeMacro{\removeword} removes the
-% first word of {\it string}, along with any of its leading and trailing
-% spaces.
-% Default mode is |[v]|.
-%
-% The command |\getnextword| \DescribeMacro{\getnextword} returns the
-% next word of {\it string}. In this case, ``word'' is a sequence of
-% characters delimited either by spaces or by the beginning or end
-% of the string.
-% Default mode is |[v]|.
-%
-% The command |\getaword| \DescribeMacro{\getaword} returns a
-% word of {\it string} defined by the index, {\it n}.
-% In this case, ``word'' is a sequence of
-% characters delimited either by spaces or by the first or last
-% characters of the string. If the index, {\it n}, requested exceeds the
-% number of words available in the string, the index wraps around back
-% to the first argument of the string, such that asking for the tenth word
-% of an eight word string will return the second word of the string.
-% Default mode is |[v]|.
-%
-% The command |\rotateleadingspaces|
-% \DescribeMacro{\rotateleadingspaces} takes any leading spaces of the
-% string and rotates them to the end of the string.
-% Default mode is |[v]|.
-%
-% The command |\removeleadingspaces|
-% \DescribeMacro{\removeleadingspaces} removes any leading spaces of the
-% string.
-% Default mode is |[v]|.
-%
-% The command |\stringencode| \DescribeMacro{\stringencode} returns a
-% copy of the string that has been encoded according to the
-% \stringstrings encoding scheme. Because an encoded string is an
-% intermediate result, the default mode for this command is |[e]|.
-%
-% The command |\stringdecode| \DescribeMacro{\stringdecode} returns a
-% copy of the string that has been decoded.
-% Default mode is |[v]|.
-%
-% The command |\gobblechar| \DescribeMacro{\gobblechar} returns a string
-% in which the first character of {\it string} has been removed. Unlike
-% the \LaTeX{} system command |\@gobble| which removes the next {\bf
-% byte} in
-% the input stream, |\gobblechar| not only takes an argument as the
-% target of its gobble, but also removes one {\bf character}, regardless
-% of whether that character is a single-byte or multi-byte character.
-% Because this command may have utility outside of the \stringstrings
-% environment, the result of this command is retokenized (\ie |def|'ed)
-% rather than expanded (\ie |edef|'ed).
-% Default mode is |[q]|. Mode |[e]| is not recognized.
-%
-% The command |\gobblechars| \DescribeMacro{\gobblechars} returns a string
-% in which the first {\it n} characters of {\it string} have been removed.
-% Like |\gobblechar|, |\gobblechars| removes characters, regardless
-% of whether those characters are single-byte or multi-byte characters.
-% Likewise, the result of this command is retokenized (\ie |def|'ed)
-% rather than expanded (\ie |edef|'ed).
-% Default mode is |[q]|. Mode |[e]| is not recognized.
-%
-% The command |\retokenize| \DescribeMacro{\retokenize} takes a string
-% that is encoded according to the \stringstrings encoding scheme, and
-% repopulates the encoded characters with their \LaTeX{} tokens. This
-% command is particularly useful for exporting a string to a routine
-% outside of the \stringstrings library or if the string includes
-% the following
-% characters: |\{|, |\}|, \verb,\|,, |\dag|, |\ddag|, |\d|, |\t|, |\b|,
-% |\copyright|, and |\P|.
-% Default mode is |[q]|. Mode |[e]| is not recognized.
-%
-% \section {Commands to Extract String Information}
-%
-% These commands
-% take an input string or token, and ascertain a particular
-% characteristic of the string. They include:
-%
-% \noindent|\stringlength[|{\it mode}|]{|{\it string}|}|\\
-% |\findchars[|{\it mode}|]{|{\it string}|}{|{\it match-char}|}|\\
-% |\findwords[|{\it mode}|]{|{\it string}|}{|{\it match-string}|}|\\
-% |\whereischar[|{\it mode}|]{|{\it string}|}{|{\it match-char}|}|\\
-% |\whereisword[|{\it mode}|]{|{\it string}|}{|{\it match-string}|}|\\
-% |\wordcount[|{\it mode}|]{|{\it string}|}|\\
-% |\getargs[|{\it mode}|]{|{\it string}|}|
-%
-% \noindent Commands in this section return their result in the string
-% |\theresult|, unless otherwise specified.
-% Unless otherwise noted, the {\it mode} may take one of two values:
-% |[v]| for verbose mode (generally, the default), and |[q]| for quiet
-% mode. In both cases, the result of
-% the operation is stored in |\theresult|. In verbose mode, it is also
-% output immediately (and may be captured by an |\edef|). In quiet mode,
-% no string is output, though the result still resides in |\theresult|.
-%
-% The command |\stringlength| \DescribeMacro{\stringlength} returns the
-% length of {\it string} in characters (not bytes).
-% Default mode is |[v]|.
-%
-% The command |\findchars| \DescribeMacro{\findchars} checks to see if
-% the character {\it match-char} occurs anywhere in {\it string}. The
-% number of occurances is stored in |\theresult| and, if in verbose
-% mode, printed. If it is desired to find blankspaces, {\it match-char}
-% should be set to |{~}| and not |{ }|.
-% Default mode is |[v]|.
-%
-% The command |\findwords| \DescribeMacro{\findwords} checks to see if
-% the string {\it match-string} occurs anywhere in {\it string}. The
-% number of occurances is stored in |\theresult| and, if in verbose
-% mode, printed. If it is desired to find blankspaces, those
-% characters in {\it match-string}
-% should be set to hardspaces (\ie tildes) and not softspaces (\ie
-% blanks), regardless of how they are defined in {\it string}.
-% Default mode is |[v]|.
-%
-% The command |\whereischar| \DescribeMacro{\whereischar} checks to see
-% where
-% the character {\it match-char} first occurs in {\it string}. The
-% location of that occurance is stored in |\theresult| and, if in verbose
-% mode, printed. If the character is not found, |\theresult| is set to
-% a value of 0. If it is desired to find blankspaces, {\it match-char}
-% should be set to |{~}| and not |{ }|.
-% Default mode is |[v]|.
-%
-% The command |\whereisword| \DescribeMacro{\whereisword} checks to see
-% where
-% the string {\it match-string} first occurs in {\it string}. The
-% location of that occurance is stored in |\theresult| and, if in verbose
-% mode, printed. If {\it match-string} is not found, |\theresult| is set to
-% a value of 0. If it is desired to find blankspaces, those characters
-% in {\it match-string}
-% should be set to hardspaces (\ie tildes) and not softspaces (\ie
-% blanks), regardless of how they are defined in {\it string}.
-% Default mode is |[v]|.
-%
-% The command |\wordcount| \DescribeMacro{\wordcount} counts the number
-% of space-separated words that occur in {\it string}.
-% Default mode is |[v]|.
-%
-% The command |\getargs| \DescribeMacro{\getargs} mimics the Unix
-% command of the same name, in that it parses {\it string} to determine
-% how many arguments (\ie words) are in {\it string}, and extracts
-% each word into a separate variable. The number of arguments is placed
-% in |\narg| and the individual arguments are placed in variables of
-% the name |\argi|, |\argii|, |\argiii|, |\argiv|, etc. This command
-% may be used to facilitate simply the use of multiple optional
-% arguments in a \LaTeX{} command, for example
-% |\mycommand[|{\it option1 option2 option3}|]{|{\it argument}|}|.
-% In this case,
-% |\mycommand| should exercise |\getargs{#1}|, with the result being
-% that {\it option1} is stored in |\argi|, \etc~The command |\mycommand|
-% may then proceed to parse the optional arguments and branch
-% accordingly.
-% Default mode is |[q]|; |[e]| mode is permitted, while |[v]| mode
-% is disabled.
-%
-% \section {Commands to Test Strings}
-%
-% These commands take an input
-% string or token and test for a particular alphanumeric condition.
-% They include:
-%
-% \noindent%
-% |\isnextbyte[|{\it mode}|]{|{\it match-byte}|}{|{\it string}|}|\\
-% |\testmatchingchar{|{\it
-% string}|}{|{\it n}|}{|{\it match-char}|}|\\
-% |\testcapitalized{|{\it string}|}|\\
-% |\testuncapitalized{|{\it string}|}|\\
-% |\testleadingalpha{|{\it string}|}|\\
-% |\testuppercase{|{\it string}|}|\\
-% |\testsolelyuppercase{|{\it string}|}|\\
-% |\testlowercase{|{\it string}|}|\\
-% |\testsolelylowercase{|{\it string}|}|\\
-% |\testalphabetic{|{\it string}|}|
-%
-% The command |\isnextbyte| \DescribeMacro{\isnextbyte} tests to see if
-% the first byte of {\it string} equals {\it match-byte}. It
-% is the only string-testing command in
-% this section which does not use the {\sf ifthen} test structure for
-% its result. Rather, |\isnextbyte| returns the result of its test as
-% a |T| or |F| in the string |\theresult|. More importantly, and
-% unlike other \stringstrings commands, |\isnextbyte| is a {\it byte} test
-% and not a {\it character} test. This means that, while |\isnextbyte|
-% operates very efficiently, it cannot
-% be used to directly detect multi-byte characters like |\$|,
-% |\^|, |\{|, |\}|, |\_|, |\dag|, |\ddag|, |\AE|, |\ae|, |\OE|,
-% |\oe|, \etc~(|\isnextbyte| will give false positives or negatives
-% when testing for these multi-byte characters).
-% The default mode of |\isnextbyte| is |[v]|.
-%
-% If a character needs to be tested, rather than a byte,
-% \DescribeMacro{\testmatchingchar} |\testmatchingchar| should be used.
-% The command |\testmatchingchar| is
-% used to ascertain whether character {\it n} of {\it string} equals
-% {\it match-char} or not. Whereas |\isnextbyte| checks only a {\it
-% byte}, |\testmatchingchar| tests for a {\it character} (single- or
-% multi-byte character). After the test is called, the action(s) may be
-% called out with |\ifmatchingchar| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% The command |\testcapitalized| \DescribeMacro{\testcapitalized} is
-% used to ascertain whether the first character of {\it string} is
-% capitalized or not. If the first character is non-alphabetic, the
-% test will return FALSE. After the test is called, the action(s) may be
-% called out with |\ifcapitalized| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% The command |\testuncapitalized| \DescribeMacro{\testuncapitalized} is
-% used to ascertain whether the first character of {\it string} is
-% uncapitalized. If the first character is non-alphabetic, the
-% test will return FALSE. After the test is called, the action(s) may be
-% called out with |\ifuncapitalized| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% The command |\testleadingalpha| \DescribeMacro{\testleadingalpha} is
-% used to ascertain whether the first character of {\it string} is
-% alphabetic. After the test is called, the action(s) may be
-% called out with |\ifleadingalpha| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% The command |\testuppercase| \DescribeMacro{\testuppercase} is
-% used to ascertain whether all the alphabetic characters in {\it
-% string} are uppercase or not. The presence of non-alphabetic
-% characters in {\it string} does not falsify the test,
-% but are merely ignored. However, a string completely void of
-% alphabetic characters will always test FALSE.
-% After the test is called, the action(s) may be
-% called out with |\ifuppercase| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% The command |\testsolelyuppercase|
-% \DescribeMacro{\testsolelyuppercase} is
-% used to ascertain whether {\it all} the characters in {\it
-% string} are uppercase or not. The presence of non-alphabetic
-% characters in {\it string} other than blankspaces will automatically
-% falsify the test. Blankspaces are ignored. However, a null string or
-% a string composed solely of blankspaces will also test FALSE.
-% After the test is called, the action(s) may be
-% called out with |\ifsolelyuppercase| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% The command |\testlowercase| \DescribeMacro{\testlowercase} is
-% used to ascertain whether all the alphabetic characters in {\it
-% string} are lowercase or not. The presence of non-alphabetic
-% characters in {\it string} does not falsify the test,
-% but are merely ignored. However, a string completely void of
-% alphabetic characters will always test FALSE.
-% After the test is called, the action(s) may be
-% called out with |\iflowercase| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% The command |\testsolelylowercase|
-% \DescribeMacro{\testsolelylowercase} is
-% used to ascertain whether {\it all} the characters in {\it
-% string} are lowercase or not. The presence of non-alphabetic
-% characters in {\it string} other than blankspaces will automatically
-% falsify the test. Blankspaces are ignored. However, a null string or
-% a string composed solely of blankspaces will also test FALSE.
-% After the test is called, the action(s) may be
-% called out with |\ifsolelylowercase| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% The command |\testalphabetic|
-% \DescribeMacro{\testalphabetic} is
-% used to ascertain whether {\it all} the characters in {\it
-% string} are alphabetic or not. The presence of non-alphabetic
-% characters in {\it string} other than blankspaces will automatically
-% falsify the test. Blankspaces are ignored. However, a null string or
-% a string composed solely of blankspaces will also test FALSE.
-% After the test is called, the action(s) may be
-% called out with |\ifalphabetic| {\it true-code} |\else| {\it
-% false-code} |\fi|.
-%
-% \section{Disclaimers}
-%
-% Now that we have described the commands available in the
-% \stringstrings package, it is appropriate to lay out the quirks and
-% warnings associated with the use of the package.
-%
-% First, \stringstrings is currently set to handle a string no larger
-% than 500 characters. A user could circumvent this, presumably, by
-% editing the style package to increase the value of
-% |\@MAXSTRINGSIZE| \DescribeMacro{\@MAXSTRINGSIZE}.
-%
-% It is important to remember that \stringstrings follows the underlying
-% rules of \LaTeX{}. Therefore, a passed string could not contain a raw
-% |%| as part of it, because it would, in fact, comment out the
-% remainder of the line. Naturally, the string may freely contain
-% instances of |\%|.
-%
-% Tokens that take two or more characters to express
-% (\eg |\#|, |\oe|, |\ddag|, \etc) are {\bf counted as
-% a single character} within the string.
-% The rule applies if you wanted to know the length
-% of a string that was populated with such tokens, or wanted to extract
-% a substring from a such a string. Of course, the exception that makes
-% the rule is that of diacritical marks, which count as separate symbols
-% from the characters they mark. For example,
-% |\^a| counts as two characters, because the |a| is
-% really just the operand of the |\^| token, even though the net result
-% looks like a single character (\^a).
-%
-% Consistent with
-% \LaTeX{} convention, groups of spaces are treated as a single
-% blankspace, unless encoded with |~| characters. And finally, again
-% consistent with the way \LaTeX{} operates, the space
-% that follows an alphabetic token is not actually a space in the
-% string, but serves as the delimiter to the token. Therefore,
-% |\OE dipus| (\OE dipus) has a length of six characters,
-% one for the |\OE| and five
-% for the |dipus|. The intervening space merely closes out the |\OE|
-% token, and does not represent a space in the middle of the string.
-%
-% One quirk worthy of particular note concerns the tabbing character,
-% meaning \&
-% as opposed to |\&| (which is handled without problem).
-% As of version 1.01, \stringstrings has the
-% capability to operate on arguments containg the ampersand \&,
-% normally reserved as the \LaTeX{} tabbing character. However, one
-% adverse by-product is that \& characters returned in |\thestring|
-% lose their catcode-4 value, and thus lose their ability to function as
-% tabbing characters. In the following example,\\
-% | |\\
-% | \caseupper[q]{a & b & c & d}|\\
-% | \begin{tabular}{|\verb,|l|c|c|c|,|}|\\
-% | \hline|\\
-% | \thestring\\|\\
-% | \hline|\\
-% | \end{tabular}|\\
-% | |\\
-% will produce \caseupper[q]{a & b & c & d}
-% \begin{tabular}{\modetablelayout}
-% \hline
-% \thestring\\
-% \hline
-% \end{tabular}
-% instead of the desired
-% \begin{tabular}{\modetablelayout}
-% \hline
-% A & B & C & D\\
-% \hline
-% \end{tabular}
-% .
-%
-% In the |\substring| command, no tests are performed to guarantee that
-% the lower limit, {\it min}, is less than the upper limit, {\it max},
-% or that {\it min} is even positive. However, the upper limit,
-% {\it max}, is corrected, if set larger than the string length. Also,
-% the use of the `\$' symbol to signify the last character of the string
-% and `\$--{\it n}' to denote an offset of {\it n} characters from the
-% end of the string can be helpful in avoiding the misindexing of strings.
-%
-% \begin{table}[p]
-% \caption{\bf Problematic Characters/Tokens and \stringstrings Solutions%
-% \label{tbl:prob}}\vspace{.5em}
-% \small
-% \begin{tabular}{\mylayout}
-% \LaTeX{} & Symbol/Name & Problem/Solution\\
-% \hline
-% \hline
-% |{| & begin group & Cannot use |{| and |}| in \stringstrings
-% arguments.\\
-% |}| & end group & However, use |\LB|\ldots|\RB| in lieu of |{|\ldots|}|;\\
-% & & manipulate string in |[e]| mode \& |\retokenize| \\
-% \hline
-% |\dag| & \dag~~Dagger & Cannot |\edef| these tokens; Thus, |[v]| mode\\
-% |\ddag| & \ddag~~Double Dagger & fails with both OT1 and T1 encoding; \\
-% |\P| & \P~~Pilcrow & manipulate string in |[e]| mode \& |\retokenize| \\
-% |\d| & \d x~~Underdot & \\
-% |\t| & \t xx~~Joining Arch & \\
-% |\b| & \b x~~Letter Underline & \\
-% |\copyright| & \copyright~Copyright & \\
-% \hline
-% \hline
-% |\_| & \_~~Underscore & Cannot |\edef| with OT1 encoding; either\\
-% |\{| & \{~~Left Curly Brace & |\renewcommand\encodingdefault{T1}|, or \\
-% |\}| & \}~~Right Curly Brace &
-% manipulate string in |[e]| mode \& |\retokenize|. \\
-% |\S| & \S~~Section Symbol & With OT1, |\S|, |\c| and |\pounds| break\\
-% |\c| & \c x~~Cedilla & \stringstrings |[v]| mode.\\
-% |\pounds| & \pounds~~Pounds & \\
-% \hline
-% \verb,\|,& \stringstrings Pipe Char. & Distinct from \verb,|,,
-% the \stringstrings encoded-\\
-% & \verb,|, (T1) ~~~\stringdecode{\|} (OT1) & escape character\\
-% \hline
-% \hline
-% |\$| & \$~~Dollar & Either cannot |\edef|, or\\
-% |\carat| & \mycarat~~(text mode) &
-% cannot identify uniquely with |\if| construct, or \\
-% |\^| & \^x~~Circumflex & expanded character is more than one byte. \\
-% |\'| & \'x~~Acute & \\
-% |\"| & \"x~~Umlaut & {\it However},\\
-% |\~| & \~x~~Tilde &
-% Use these characters freely, \stringstrings\\
-% |\`| & \`x~~Grave &
-% encoding functions transparently with them.\\
-% |\.| & \.x~~Overdot & \\
-% |\=| & \=x~~Macron & |\retokenize| also works\\
-% |\u| & \u x~~Breve & \\
-% |\v| & \v x~~Caron & \\
-% |\H| & \H x~~Double Acute & \\
-% |\ss| & \ss~~Eszett & \\
-% |\AE \ae| & \AE~\ae~~\ae sc & \\
-% |\OE \oe| & \OE~\oe~~\oe thel & \\
-% |\AA \aa| & \AA~\aa~~angstrom & \\
-% |\O \o| & \O~\o~~slashed O & \\
-% |\L \l| & \L~\l~~barred L & \\
-% |~| & Hardspace &\\
-% \hline
-% |$| & begin/end math mode & These characters pose no difficulties;\\
-% |^| & math superscript & However, cannot extract substring that \\
-% |_| & math subscript & breaks in middle of math mode.\\
-% & & Other math mode symbols NOT supported.\\
-% \hline
-% \& & ampersand & Version 1.01 \stringstrings can manipulate the\\
-% & & ampersand. However, returned strings\\
-% & & containing the \& character lose their\\
-% & & catcode-4 status, making them unfit\\
-% & & for use as tabbing characters.\\
-% \hline
-% \hline
-% \end{tabular}
-% \end{table}
-% Table~\ref{tbl:prob} shows a variety of characters and tokens, some of
-% which pose a challenge to \stringstrings manipulations. In all cases,
-% a solution or workaround is provided. For symbols in the top two
-% categories, the workaround
-% solution includes the use of retokenized strings instead of expanded
-% strings. For symbols in the next two categories, use of T1 encoding
-% or retokenizing provides a satisfactory solution. In the bottom three
-% categories, because of \stringstrings encoded |[e]| mode,
-% there is nothing to impede the use of these characters in
-% \stringstrings arguments, if encoded |[e]| mode is employed for
-% intermediate calculations. Some of the
-% details of these problematic cases is described below.
-%
-% Not surprisingly, you are not allowed to extract a substring of a
-% string, if it breaks in the middle of math mode, because a substring
-% with only one |$| in it cannot be |\edef|'ed.
-%
-% There are a few potential quirks when using \LaTeX{}'s native OT1
-% character encoding, most of which can be circumvented by using the
-% more modern
-% T1 encoding (accessed via |\renewcommand\encodingdefault{T1}| in the
-% document preamble). The quirks arise because there are
-% several characters that, while displayable in \LaTeX{}, are not part
-% of the OT1 character encoding. The characters include |\{|, |\}|, and
-% the \verb,|, symbol (accessed in \stringstrings via \verb,\|,).
-% When using \stringstrings to manipulate strings containing
-% these characters in the presence of OT1 encoding,
-% they come out looking like \stringdecode{\{}, \stringdecode{\}},
-% and \stringdecode{\|}, respectively. However, if the T1 encoding fix
-% is not an option for you, you can also work around this problem by
-% |\retokenize|'ing the affected string (the |\retokenize| command is
-% provided to convert encoded, expanded strings back into tokenized
-% form, if need be).
-%
-% Likewise, for both OT1 and T1 encoding, the characters \dag~(|\dag|),
-% \ddag~(|\ddag|), \P~(|\P|), \d~~(|\d|), \t~~~(|\t|), \b~~~(|\b|),
-% and \copyright~(|\copyright|)
-% cannot be in the argument of an |\edef| expression. For
-% manipulated strings including these characters, |\retokenize| is the
-% only option available to retain the integrity of the string.
-%
-% As discussed thoroughly in the previous section, an ``encoded'' form of
-% the string manipulation routines is provided to prevent the
-% undesirable circumstance of passing an |\edef|'ed symbol as input
-% to a subsequent manipulation. Likewise, never try to ``decode''
-% an already ``decoded'' string.
-%
-% When \stringstrings doesn't understand a token, it is supposed to
-% replace it with a period. However, some undecipherable characters may
-% inadvertantly be replaced with a space, instead. Of course, neither
-% of these possibilities is any comfort to the user.
-%
-% As mentioned already, \stringstrings cannot handle curly braces that
-% are used for grouping purposes, a circumstance which often arises in
-% math mode. Nonetheless, |\LB| and |\RB| may be used within
-% \stringstrings arguments in lieu of grouping braces, {\it if the final
-% result is to be retokenized}. Thus, |\caselower[e]{$X^\LB Y + Z\RB$}|
-% followed by |\convertchar[e]{\thestring}{x}{(1+x)}|, when finished up
-% with the following command,
-% |\retokenize[v]{\thestring}| yields as its result:\\
-% \caselower[e]{$X^\LB Y + Z\RB$}\convertchar[e]{\thestring}{x}{(1+x)}
-% \retokenize[v]{\thestring}.
-%
-% One might ask, ``why not retokenize everything, instead of using the
-% |[v]| mode of the \stringstrings routines?'' While one {\it could}
-% do this, the answer is simply
-% that |\retokenize| is a computationally intensive command, and that
-% it is best used, therefore, only when the more efficient methods
-% will not suffice. In many, if not most cases, strings to be
-% manipulated will be solely composed of alphanumeric characters which
-% don't require the use of |\retokenize|, T1 encoding, or even
-% \stringstrings encoding.
-%
-% Despite these several disclaimers and workarounds required when
-% dealing with problematic characters, I hope you find the \stringstrings
-% architecture and feel to be straightforward and useful. There is only
-% one thing left, and that is to dissect the code\ldots and so here we
-% go.
-%
-%% \CharacterTable
-%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
-%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
-%% Digits \0\1\2\3\4\5\6\7\8\9
-%% Exclamation \! Double quote \" Hash (number) \#
-%% Dollar \$ Percent \% Ampersand \&
-%% Acute accent \' Left paren \( Right paren \)
-%% Asterisk \* Plus \+ Comma \,
-%% Minus \- Point \. Solidus \/
-%% Colon \: Semicolon \; Less than \<
-%% Equals \= Greater than \> Question mark \?
-%% Commercial at \@ Left bracket \[ Backslash \\
-%% Right bracket \] Circumflex \^ Underscore \_
-%% Grave accent \` Left brace \{ Vertical bar \|
-%% Right brace \} Tilde \~}
-% \StopEventually{}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \vspace{-0.8em}
-% \begin{macro}{stringstrings.sty}
-% \section{Code Listing}
-% I'll try to lay out herein
-% the workings of the \stringstrings style package.
-% \begin{macrocode}
-%<*package>
-
-%%%%% INITIALIZATIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\catcode`\&=12
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{ifthen}
-% This package makes wide use of the {\sf ifthen} style package.
-% \begin{macrocode}
-\usepackage{ifthen}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@MAXSTRINGSIZE}
-% The parameter |\@MAXSTRINGSIZE| defines the maximum allowable string
-% size that \stringstrings can operate upon.
-% \begin{macrocode}
-\def\@MAXSTRINGSIZE{500}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macrocode}
-\def\endofstring{@E@o@S@}%
-\def\undecipherable{.}% UNDECIPHERABLE TOKENS TO BE REPLACED BY PERIOD
-\def\@blankaction{\BlankSpace}
-% \end{macrocode}
-% Save the symbols which will get redefined \stringstrings encoding.
-
-% \begin{macrocode}
-\let\SaveDollar\$
-\let\SaveHardspace~
-\let\SaveCircumflex\^
-\let\SaveTilde\~
-\let\SaveUmlaut\"
-\let\SaveGrave\`
-\let\SaveAcute\'
-\let\SaveMacron\=
-\let\SaveOverdot\.
-\let\SaveBreve\u
-\let\SaveCaron\v
-\let\SaveDoubleAcute\H
-\let\SaveCedilla\c
-\let\SaveUnderdot\d
-\let\SaveArchJoin\t
-\let\SaveLineUnder\b
-\let\SaveCopyright\copyright
-\let\SavePounds\pounds
-\let\SaveLeftBrace\{
-\let\SaveRightBrace\}
-\let\SaveUnderscore\_
-\let\SaveDagger\dag
-\let\SaveDoubleDagger\ddag
-\let\SaveSectionSymbol\S
-\let\SavePilcrow\P
-\let\SaveAEsc\AE
-\let\Saveaesc\ae
-\let\SaveOEthel\OE
-\let\Saveoethel\oe
-\let\SaveAngstrom\AA
-\let\Saveangstrom\aa
-\let\SaveSlashedO\O
-\let\SaveSlashedo\o
-\let\SaveBarredL\L
-\let\SaveBarredl\l
-\let\SaveEszett\ss
-\let\SaveLB{
-\let\SaveRB}
-% \end{macrocode}
-
-% The BlankSpace character is the only character which is reencoded
-% with a 1-byte re-encoding\ldots in this case the \OE~character.
-% \begin{macrocode}
-\def\EncodedBlankSpace{\SaveOEthel}
-\edef\BlankSpace{ }
-% \end{macrocode}
-% All other reencoded symbols consist of 2 bytes: an escape character
-% plus a unique code. The escape character is a pipe symbol. the
-% unique code comprises either a single number, letter, or symbol.
-
-% \begin{macrocode}
-\def\EscapeChar{|}
-
-% |0 IS AN ENCODED |, ACCESSED VIA \|
-\def\PipeCode{0}
-\def\EncodedPipe{\EscapeChar\PipeCode}
-\def\Pipe{|}
-\let\|\EncodedPipe
-
-% |1 IS AN ENCODED \$
-\def\DollarCode{1}
-\def\EncodedDollar{\EscapeChar\DollarCode}
-% THE FOLLOWING IS NEEDED TO KEEP OT1 ENCODING FROM BREAKING;
-% IT PROVIDES AN ADEQUATE BUT NOT IDEAL ENVIRONMENT FOR T1 ENCODING
-\def\Dollar{\symbol{36}}
-% THE FOLLOWING IS BETTER FOR T1 ENCODING, BUT BREAKS OT1 ENCODING
-%\def\Dollar{\SaveDollar}
-
-% |W IS RESERVED TO BE ASSIGNED TO AN ARBITRARY TOKEN
-\def\UvariCode{W}
-\def\EncodedUvari{\EscapeChar\UvariCode}
-\def\Uvari{Uvari}
-\let\uvari\EncodedUvari
-
-% |X IS RESERVED TO BE ASSIGNED TO AN ARBITRARY TOKEN
-\def\UvariiCode{X}
-\def\EncodedUvarii{\EscapeChar\UvariiCode}
-\def\Uvarii{Uvarii}
-\let\uvarii\EncodedUvarii
-
-% |Y IS RESERVED TO BE ASSIGNED TO AN ARBITRARY TOKEN
-\def\UvariiiCode{Y}
-\def\EncodedUvariii{\EscapeChar\UvariiiCode}
-\def\Uvariii{Uvariii}
-\let\uvariii\EncodedUvariii
-
-% |2 IS AN ENCODED ^ FOR USE IN TEXT MODE, ACCESSED VIA \carat
-\def\CaratCode{2}
-\def\EncodedCarat{\EscapeChar\CaratCode}
-\def\Carat{\symbol{94}}
-\let\carat\EncodedCarat
-
-% |4 IS AN ENCODED \{
-\def\LeftBraceCode{4}
-\def\EncodedLeftBrace{\EscapeChar\LeftBraceCode}
-% THE FOLLOWING IS NEEDED TO KEEP OT1 ENCODING FROM BREAKING;
-% IT PROVIDES AN ADEQUATE BUT NOT IDEAL ENVIRONMENT FOR T1 ENCODING
-\def\LeftBrace{\symbol{123}}
-% THE FOLLOWING IS BETTER FOR T1 ENCODING, BUT BREAKS OT1 ENCODING
-%\def\LeftBrace{\SaveLeftBrace}
-
-% |5 IS AN ENCODED \}
-\def\RightBraceCode{5}
-\def\EncodedRightBrace{\EscapeChar\RightBraceCode}
-% THE FOLLOWING IS NEEDED TO KEEP OT1 ENCODING FROM BREAKING;
-% IT PROVIDES AN ADEQUATE BUT NOT IDEAL ENVIRONMENT FOR T1 ENCODING
-\def\RightBrace{\symbol{125}}
-% THE FOLLOWING IS BETTER FOR T1 ENCODING, BUT BREAKS OT1 ENCODING
-%\def\RightBrace{\SaveRightBrace}
-
-% |6 IS AN ENCODED \_
-\def\UnderscoreCode{6}
-\def\EncodedUnderscore{\EscapeChar\UnderscoreCode}
-\def\Underscore{\symbol{95}}
-%\def\Underscore{\SaveUnderscore}
-
-% |7 IS AN ENCODED \^
-\def\CircumflexCode{7}
-\def\EncodedCircumflex{\EscapeChar\CircumflexCode}
-\def\Circumflex{\noexpand\SaveCircumflex}
-
-% |8 IS AN ENCODED \~
-\def\TildeCode{8}
-\def\EncodedTilde{\EscapeChar\TildeCode}
-\def\Tilde{\noexpand\SaveTilde}
-
-% |" IS AN ENCODED \"
-\def\UmlautCode{"}
-\def\EncodedUmlaut{\EscapeChar\UmlautCode}
-\def\Umlaut{\noexpand\SaveUmlaut}
-
-% |` IS AN ENCODED \`
-\def\GraveCode{`}
-\def\EncodedGrave{\EscapeChar\GraveCode}
-\def\Grave{\noexpand\SaveGrave}
-
-% |' IS AN ENCODED \'
-\def\AcuteCode{'}
-\def\EncodedAcute{\EscapeChar\AcuteCode}
-\def\Acute{\noexpand\SaveAcute}
-
-% |= IS AN ENCODED \=
-\def\MacronCode{=}
-\def\EncodedMacron{\EscapeChar\MacronCode}
-\def\Macron{\noexpand\SaveMacron}
-
-% |. IS AN ENCODED \.
-\def\OverdotCode{.}
-\def\EncodedOverdot{\EscapeChar\OverdotCode}
-\def\Overdot{\noexpand\SaveOverdot}
-
-% |u IS AN ENCODED \u
-\def\BreveCode{u}
-\def\EncodedBreve{\EscapeChar\BreveCode}
-\def\Breve{\noexpand\SaveBreve}
-
-% |v IS AN ENCODED \v
-\def\CaronCode{v}
-\def\EncodedCaron{\EscapeChar\CaronCode}
-\def\Caron{\noexpand\SaveCaron}
-
-% |H IS AN ENCODED \H
-\def\DoubleAcuteCode{H}
-\def\EncodedDoubleAcute{\EscapeChar\DoubleAcuteCode}
-\def\DoubleAcute{\noexpand\SaveDoubleAcute}
-
-% |c IS AN ENCODED \c
-\def\CedillaCode{c}
-\def\EncodedCedilla{\EscapeChar\CedillaCode}
-\def\Cedilla{\noexpand\SaveCedilla}
-
-% |d IS AN ENCODED \d
-\def\UnderdotCode{d}
-\def\EncodedUnderdot{\EscapeChar\UnderdotCode}
-\def\Underdot{.}% CANNOT \edef \d
-
-% |t IS AN ENCODED \t
-\def\ArchJoinCode{t}
-\def\EncodedArchJoin{\EscapeChar\ArchJoinCode}
-\def\ArchJoin{.}% CANNOT \edef \t
-
-% |b IS AN ENCODED \b
-\def\LineUnderCode{b}
-\def\EncodedLineUnder{\EscapeChar\LineUnderCode}
-\def\LineUnder{.}% CANNOT \edef \b
-
-% |C IS AN ENCODED \copyright
-\def\CopyrightCode{C}
-\def\EncodedCopyright{\EscapeChar\CopyrightCode}
-\def\Copyright{.}% CANNOT \edef \copyright
-
-% |p IS AN ENCODED \pounds
-\def\PoundsCode{p}
-\def\EncodedPounds{\EscapeChar\PoundsCode}
-\def\Pounds{\SavePounds}
-
-% |[ IS AN ENCODED {
-\def\LBCode{[}
-\def\EncodedLB{\EscapeChar\LBCode}
-\def\UnencodedLB{.}
-\def\LB{\EncodedLB}
-
-% |] IS AN ENCODED }
-\def\RBCode{]}
-\def\EncodedRB{\EscapeChar\RBCode}
-\def\UnencodedRB{.}
-\def\RB{\EncodedRB}
-
-% |z IS AN ENCODED \dag
-\def\DaggerCode{z}
-\def\EncodedDagger{\EscapeChar\DaggerCode}
-\def\Dagger{.}% CANNOT \edef \dag
-
-% |Z IS AN ENCODED \ddag
-\def\DoubleDaggerCode{Z}
-\def\EncodedDoubleDagger{\EscapeChar\DoubleDaggerCode}
-\def\DoubleDagger{.}% CANNOT \edef \ddag
-
-% |S IS AN ENCODED \S
-\def\SectionSymbolCode{S}
-\def\EncodedSectionSymbol{\EscapeChar\SectionSymbolCode}
-\def\SectionSymbol{\SaveSectionSymbol}
-
-% |P IS AN ENCODED \P
-\def\PilcrowCode{P}
-\def\EncodedPilcrow{\EscapeChar\PilcrowCode}
-\def\Pilcrow{.}% CANNOT \edef \P
-
-% |E IS AN ENCODED \AE
-\def\AEscCode{E}
-\def\EncodedAEsc{\EscapeChar\AEscCode}
-\def\AEsc{\SaveAEsc}
-
-% |e IS AN ENCODED \ae
-\def\aescCode{e}
-\def\Encodedaesc{\EscapeChar\aescCode}
-\def\aesc{\Saveaesc}
-
-% |O IS AN ENCODED \OE
-\def\OEthelCode{O}
-\def\EncodedOEthel{\EscapeChar\OEthelCode}
-\def\OEthel{\SaveOEthel}
-
-% |o IS AN ENCODED \oe
-\def\oethelCode{o}
-\def\Encodedoethel{\EscapeChar\oethelCode}
-\def\oethel{\Saveoethel}
-
-% |A IS AN ENCODED \AA
-\def\AngstromCode{A}
-\def\EncodedAngstrom{\EscapeChar\AngstromCode}
-\def\Angstrom{\SaveAngstrom}
-
-% |a IS AN ENCODED \aa
-\def\angstromCode{a}
-\def\Encodedangstrom{\EscapeChar\angstromCode}
-\def\angstrom{\Saveangstrom}
-
-% |Q IS AN ENCODED \O
-\def\SlashedOCode{Q}
-\def\EncodedSlashedO{\EscapeChar\SlashedOCode}
-\def\SlashedO{\SaveSlashedO}
-
-% |q IS AN ENCODED \o
-\def\SlashedoCode{q}
-\def\EncodedSlashedo{\EscapeChar\SlashedoCode}
-\def\Slashedo{\SaveSlashedo}
-
-% |L IS AN ENCODED \L
-\def\BarredLCode{L}
-\def\EncodedBarredL{\EscapeChar\BarredLCode}
-\def\BarredL{\SaveBarredL}
-
-% |l IS AN ENCODED \l
-\def\BarredlCode{l}
-\def\EncodedBarredl{\EscapeChar\BarredlCode}
-\def\Barredl{\SaveBarredl}
-
-% |s IS AN ENCODED \ss
-\def\EszettCode{s}
-\def\EncodedEszett{\EscapeChar\EszettCode}
-\def\Eszett{\SaveEszett}
-
-\newcounter{@letterindex}
-\newcounter{@@letterindex}
-\newcounter{@@@letterindex}
-\newcounter{@wordindex}
-\newcounter{@iargc}
-\newcounter{@gobblesize}
-\newcounter{@maxrotation}
-\newcounter{@stringsize}
-\newcounter{@@stringsize}
-\newcounter{@@@stringsize}
-\newcounter{@revisedstringsize}
-\newcounter{@gobbleindex}
-\newcounter{@charsfound}
-\newcounter{@alph}
-\newcounter{@alphaindex}
-\newcounter{@capstrigger}
-\newcounter{@fromindex}
-\newcounter{@toindex}
-\newcounter{@previousindex}
-\newcounter{@flag}
-\newcounter{@matchloc}
-\newcounter{@matchend}
-\newcounter{@matchsize}
-\newcounter{@matchmax}
-\newcounter{@skipped}
-\newcounter{@lcwords}
-% \end{macrocode}
-% \begin{macrocode}
-%%%%% CONFIGURATION COMMANDS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \end{macrocode}
-
-% \begin{macro}{\defaultTreatments}
-% This command can be used to restore the default string treatments,
-% prior to calling |\substring|. The default treatments leave all
-% symbol types intact and unaltered.
-% \begin{macrocode}
-\newcommand\defaultTreatments{%
- \def\EncodingTreatment{v}% <--Set=v to decode special chars (vs. q,e)
- \def\AlphaCapsTreatment{1}% <--Set=1 to retain uppercase (vs. 0,2)
- \def\AlphaTreatment{1}% <--Set=1 to retain lowercase (vs. 0,2)
- \def\PunctuationTreatment{1}% <--Set=1 to retain punctuation (vs. 0)
- \def\NumeralTreatment{1}% <--Set=1 to retain numerals (vs. 0)
- \def\SymbolTreatment{1}% <--Set=1 to retain special chars (vs. 0)
- \def\BlankTreatment{1}% <--Set=1 to retain blanks (vs. 0)
- \def\CapitalizeString{0}% <--Set=0 for no special action (vs. 1,2)
- \def\SeekBlankSpace{0}% <--Set=0 for no special action (vs. 1,2)
-}
-\defaultTreatments
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\Treatments}
-% This command allows the user to specify the desired character class
-% treatments, prior to a call to |\substring|. Unfortunately for the
-% user, I have specified which character class each symbol belongs to.
-% Therefore, it is not easy if the user decides that he wants a cedilla,
-% for example, to be treated like an alphabetic character rather than
-% a symbol.
-% \begin{macrocode}
-% QUICK WAY TO SET UP TREATMENTS BY WHICH \@rotate HANDLES VARIOUS
-% CHARACTERS
-\newcommand\Treatments[6]{%
- \def\AlphaCapsTreatment{#1}% <--Set=0 to remove uppercase
-% =1 to retain uppercase
-% =2 to change UC to lc
- \def\AlphaTreatment{#2}% <--Set=0 to remove lowercase
-% =1 to retain lowercase
-% =2 to change lc to UC
- \def\PunctuationTreatment{#3}%<--Set=0 to remove punctuation
-% =1 to retain punctuation
- \def\NumeralTreatment{#4}% <--Set=0 to remove numerals
-% =1 to retain numerals
- \def\SymbolTreatment{#5}% <--Set=0 to remove special chars
-% =1 to retain special chars
- \def\BlankTreatment{#6}% <--Set=0 to remove blanks
-% =1 to retain blanks
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\+}
-% This command (|\+|) is used to enact the \stringstrings encoding.
-% Key symbols are redefined, and any |\edef| which occurs while this
-% command is active will adopt these new definitions.
-% \begin{macrocode}
-% REENCODE MULTIBYTE SYMBOLS USING THE stringstrings ENCODING METHOD
-\newcommand\+{%
- \def\${\EncodedDollar}%
- \def~{\EncodedBlankSpace}%
- \def\^{\EncodedCircumflex}%
- \def\~{\EncodedTilde}%
- \def\"{\EncodedUmlaut}%
- \def\`{\EncodedGrave}%
- \def\'{\EncodedAcute}%
- \def\={\EncodedMacron}%
- \def\.{\EncodedOverdot}%
- \def\u{\EncodedBreve}%
- \def\v{\EncodedCaron}%
- \def\H{\EncodedDoubleAcute}%
- \def\c{\EncodedCedilla}%
- \def\d{\EncodedUnderdot}%
- \def\t{\EncodedArchJoin}%
- \def\b{\EncodedLineUnder}%
- \def\copyright{\EncodedCopyright}%
- \def\pounds{\EncodedPounds}%
- \def\{{\EncodedLeftBrace}%
- \def\}{\EncodedRightBrace}%
- \def\_{\EncodedUnderscore}%
- \def\dag{\EncodedDagger}%
- \def\ddag{\EncodedDoubleDagger}%
- \def\S{\EncodedSectionSymbol}%
- \def\P{\EncodedPilcrow}%
- \def\AE{\EncodedAEsc}%
- \def\ae{\Encodedaesc}%
- \def\OE{\EncodedOEthel}%
- \def\oe{\Encodedoethel}%
- \def\AA{\EncodedAngstrom}%
- \def\aa{\Encodedangstrom}%
- \def\O{\EncodedSlashedO}%
- \def\o{\EncodedSlashedo}%
- \def\L{\EncodedBarredL}%
- \def\l{\EncodedBarredl}%
- \def\ss{\EncodedEszett}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\?}
-% The command |\?| reverts the character encodings back to the standard
-% \LaTeX{} definitions. The command effectively undoes a previously
-% enacted |\+|.
-% \begin{macrocode}
-% WHEN TASK IS DONE, REVERT ENCODING TO STANDARD ENCODING METHOD
-\newcommand\?{%
- \let\$\SaveDollar%
- \let~\SaveHardspace%
- \let\^\SaveCircumflex%
- \let\~\SaveTilde%
- \let\"\SaveUmlaut%
- \let\`\SaveGrave%
- \let\'\SaveAcute%
- \let\=\SaveMacron%
- \let\.\SaveOverdot%
- \let\u\SaveBreve%
- \let\v\SaveCaron%
- \let\H\SaveDoubleAcute%
- \let\c\SaveCedilla%
- \let\d\SaveUnderdot%
- \let\t\SaveArchJoin%
- \let\b\SaveLineUnder%
- \let\copyright\SaveCopyright%
- \let\pounds\SavePounds%
- \let\{\SaveLeftBrace%
- \let\}\SaveRightBrace%
- \let\_\SaveUnderscore%
- \let\dag\SaveDagger%
- \let\ddag\SaveDoubleDagger%
- \let\S\SaveSectionSymbol%
- \let\P\SavePilcrow%
- \let\AE\SaveAEsc%
- \let\ae\Saveaesc%
- \let\OE\SaveOEthel%
- \let\oe\Saveoethel%
- \let\AA\SaveAngstrom%
- \let\aa\Saveangstrom%
- \let\O\SaveSlashedO%
- \let\o\SaveSlashedo%
- \let\L\SaveBarredL%
- \let\l\SaveBarredl%
- \let\ss\SaveEszett%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\encodetoken}
-% The command |\encodetoken| assigns the supplied token to one of three
-% reserved \stringstrings user variables (the optional argument dictates
-% which user variable). Once encoded, the supplied token cannot be used
-% in the normal way, but only in stringstrings routines, unless and
-% until it is decoded.
-% \begin{macrocode}
-\newcommand\encodetoken[2][1]{%
- \if 1#1%
- \let\Uvari#2%
- \let#2\uvari\else
- \if 2#1%
- \let\Uvarii#2%
- \let#2\uvarii\else
- \if 3#1%
- \let\Uvariii#2%
- \let#2\uvariii%
- \fi
- \fi
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\decodetoken}
-% The command |\decodetoken| deassigns the supplied token from the
-% reserved \stringstrings user variables (the optional argument dictates
-% which user variable), so that the token may be used in the normal way
-% again.
-% \begin{macrocode}
-\newcommand\decodetoken[2][1]{%
- \if 1#1%
- \let#2\Uvari%
- \def\Uvari{Uvari}\else
- \if 2#1%
- \let#2\Uvarii%
- \def\Uvarii{Uvarii}\else
- \if 3#1%
- \let#2\Uvariii%
- \def\Uvariii{Uvariii}%
- \fi
- \fi
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macrocode}
-%%%%% COMMANDS TO MANIPULATE STRINGS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \end{macrocode}
-
-% In the next group of commands, the result is always stored in an
-% expandable string, |\thestring|. Expandable means that |\thestring| can
-% be put into a subsequent |\edef{}| command. Additionally, the
-% optional first argument can be used to cause three actions (verbose,
-% encoded, or quiet):
-% \begin{enumerate}
-% \item [|=v|] |\thestring| is decoded (final result);
-% print it immediately (default)
-% \item [|=e|] |\thestring| is encoded (intermediate result);
-% don't print it
-% \item [|=q|] |\thestring| is decoded (final result),
-% but don't print it
-% \end{enumerate}
-% \begin{macro}{\substring}
-% The command |\substring| is the brains of this package\ldots
-% It is used to acquire a substring from a given string, along with
-% performing specified character manipulations along the way.
-% Its strategy is fundamental to the \stringstrings
-% package: sequentially rotate the 1st character of the
-% string to the end of the string, until the desired substring resides
-% at end of rotated string. Then, gobble up the leading part of
-% string until only the desired substring is left.
-% \begin{macrocode}
-\newcommand\substring[4][v]{\+%
-% \end{macrocode}
-% Obtain the string length of the string to be manipulated and store
-% it in |@stringsize|.
-% \begin{macrocode}
- \@getstringlength{#2}{@stringsize}%
-% \end{macrocode}
-% First,
-% |\@decodepointer| is used to convert indirect references like |$|
-% and |$-3| into integers.
-% \begin{macrocode}
- \@decodepointer{#3}%
- \setcounter{@fromindex}{\@fromtoindex}%
- \@decodepointer{#4}%
- \setcounter{@toindex}{\@fromtoindex}%
-% \end{macrocode}
-% Determine the number of characters to rotate to the end of the string
-% and the number of characters to then gobble from it, in order to leave
-% the desired substring.
-% \begin{macrocode}
- \setcounter{@gobblesize}{\value{@stringsize}}%
- \ifthenelse{\value{@toindex} > \value{@stringsize}}%
- {\setcounter{@maxrotation}{\value{@stringsize}}}%
- {\setcounter{@maxrotation}{\value{@toindex}}}%
- \addtocounter{@gobblesize}{-\value{@maxrotation}}%
- \addtocounter{@gobblesize}{\value{@fromindex}}%
- \addtocounter{@gobblesize}{-1}%
-% \end{macrocode}
-% Prepare for the string rotation by initializing counters, setting the
-% targeted string into the working variable, |\rotatingword|, and set
-% the encoding treatment specified.
-% \begin{macrocode}
- \setcounter{@letterindex}{0}%
- \edef\rotatingword{#2}%
- \def\EncodingTreatment{#1}%
-% \end{macrocode}
-% If capitalization (first character of string or of each word)
-% was specified, the
-% trigger for 1st-character capitalization will be set. However,
-% the treatments for the alphabetic characters for the remainder of the
-% string must be saved and reinstituted after the first character is
-% capitalized.
-% \begin{macrocode}
- \if 0\CapitalizeString%
-% DO NOT SET CAPITALIZE TRIGGER FOR FIRST CHARACTER
- \setcounter{@capstrigger}{0}%
- \else
-% SAVE CERTAIN TREATMENTS FOR LATER RESTORATION
- \let\SaveAlphaTreatment\AlphaTreatment%
- \let\SaveAlphaCapsTreatment\AlphaCapsTreatment%
-% SET CAPITALIZE TRIGGER FOR FIRST CHARACTER
- \setcounter{@capstrigger}{1}%
- \@forcecapson%
- \fi
-% \end{macrocode}
-% The command |\@defineactions| looks at the defined treatments
-% and specifies how each of the \stringstrings encoded
-% characters should be handled (\ie left alone, removed, modified,
-% \etc).
-% \begin{macrocode}
-\@defineactions%
-% \end{macrocode}
-% Here begins the primary loop of |\substring| in which characters of
-% |\rotatingword| are successively moved (and possibly manipulated)
-% from the first character of the string to the last. |@letterindex| is
-% the running index defining how many characters have been operated on.
-% \begin{macrocode}
- \whiledo{\value{@letterindex} < \value{@maxrotation}}{%
- \addtocounter{@letterindex}{1}%
-% \end{macrocode}
-% When |\CapitalizeString| equals 1, only the first character of the
-% string is capitalized. When it equals 2, every word in the string
-% is capitalized. When equal to 2, this bit of code looks for the
-% blankspace that follows the end of a word, and uses it to reset the
-% capitalization trigger for the next non-blank character.
-% \begin{macrocode}
-% IF NEXT CHARACTER BLANK WHILE \CapitalizeString=2,
-% SET OR KEEP ALIVE TRIGGER.
- \if 2\CapitalizeString%
- \isnextbyte[q]{\EncodedBlankSpace}{\rotatingword}%
- \if F\theresult\isnextbyte[q]{\BlankSpace}{\rotatingword}\fi%
- \if T\theresult%
- \if 0\arabic{@capstrigger}%
- \@forcecapson%
- \@defineactions%
- \fi
- \setcounter{@capstrigger}{2}%
- \fi
- \fi
-% \end{macrocode}
-% Is the next character an encoded symbol? If it is a normal character,
-% simply rotate it to the end of the string.
-% If it is an encoded symbol however, its
-% treatment will depend on whether it will be gobbled away or end up
-% in the final substring. If it will be gobbled away, leave it encoded,
-% because the gobbling routine knows how to gobble encoded characters.
-% If it will end up in the substring, manipulate it according to the
-% encoding rules set in |\@defineactions| and rotate it.
-% \begin{macrocode}
-% CHECK IF NEXT CHARACTER IS A SYMBOL
- \isnextbyte[q]{\EscapeChar}{\rotatingword}%
- \ifthenelse{\value{@letterindex} < \value{@fromindex}}%
- {%
-% THIS CHARACTER WILL EVENTUALLY BE GOBBLED
- \if T\theresult%
-% ROTATE THE ESCAPE CHARACTER, WHICH WILL LEAVE THE SYMBOL ENCODED
-% FOR PROPER GOBBLING (ESCAPE CHARACTER DOESN'T COUNT AS A LETTER)
- \edef\rotatingword{\@rotate{\rotatingword}}%
- \addtocounter{@letterindex}{-1}%
- \else
-% NORMAL CHARACTER OR SYMBOL CODE... ROTATE IT
- \edef\rotatingword{\@rotate{\rotatingword}}%
- \fi
- }%
- {%
-% THIS CHARACTER WILL EVENTUALLY MAKE IT INTO SUBSTRING
- \if T\theresult%
-% ROTATE THE SYMBOL USING DEFINED TREATMENT RULES
- \edef\rotatingword{\ESCrotate{\expandafter\@gobble\rotatingword}}%
- \else
-% NORMAL CHARACTER... ROTATE IT
- \edef\rotatingword{\@rotate{\rotatingword}}%
- \fi
- }%
-% \end{macrocode}
-% Here, the capitalization trigger persistently tries to turn
-% itself off with each loop
-% through the string rotation. Only if the earlier code found the
-% rotation to be pointing to the blank character(s) between words while
-% |\CapitalizeString| equals 2 will the trigger be prevented from
-% extinguishing itself.
-% \begin{macrocode}
-% DECREMENT CAPITALIZATION TRIGGER TOWARDS 0, EVERY TIME THROUGH LOOP
- \if 0\arabic{@capstrigger}%
- \else
- \addtocounter{@capstrigger}{-1}%
- \if 0\arabic{@capstrigger}\@relaxcapson\fi
- \fi
-% \end{macrocode}
-% In addition to the standard |\substring| calls in which fixed
-% substring limits are specified (which in turn fixes the number of
-% character rotations to be executed), some \stringstrings commands
-% want the rotations to continue until a blankspace is located.
-% This bit of code looks for that blank space, if that was the option
-% requested. Once found, the rotation will stop. However, depending
-% on the value of |\SeekBlankSpace|, the remainder of the string may
-% either be retained or discarded.
-% \begin{macrocode}
-% IF SOUGHT SPACE IS FOUND, END ROTATION OF STRING
- \if 0\SeekBlankSpace\else
- \isnextbyte[q]{\EncodedBlankSpace}{\rotatingword}%
- \if F\theresult\isnextbyte[q]{\BlankSpace}{\rotatingword}\fi%
- \if T\theresult%
- \if 1\SeekBlankSpace%
-% STOP ROTATION, KEEP REMAINDER OF STRING
- \setcounter{@maxrotation}{\value{@letterindex}}%
- \else
-% STOP ROTATION, THROW AWAY REMAINDER OF STRING
- \addtocounter{@gobblesize}{\value{@maxrotation}}%
- \setcounter{@maxrotation}{\value{@letterindex}}%
- \addtocounter{@gobblesize}{-\value{@maxrotation}}%
- \fi
- \fi
- \fi
- }%
-% \end{macrocode}
-% The loop has ended.\\
-% Gobble up the first |@gobblesize| characters (not bytes!)~of the string,
-% which should leave the desired substring as the remainder. If the
-% mode is verbose, print out the resulting substring.
-% \begin{macrocode}
-% GOBBLE AWAY THAT PART OF STRING THAT ISN'T PART OF REQUESTED SUBSTRING
- \@gobblearg{\rotatingword}{\arabic{@gobblesize}}%
- \edef\thestring{\gobbledword}%
- \if v#1\thestring\fi%
-\?}
-% \end{macrocode}
-% \end{macro}
-
-% Many of the following commands are self-expanatory. The recipe they
-% follow is to use |\Treatments| to specify how different character
-% classes are to be manipulated, and then to call upon |\substring| to
-% effect the desired manipulation. Treatments are typically
-% re-defaulted at the conclusion of the command, which is why the user,
-% if desiring special treatments, should specify those treatments
-% immediately before a call to |\substring|.
-% \begin{macro}{\caseupper}
-% \begin{macrocode}
-% Convert Lower to Uppercase; retain all symbols, numerals,
-% punctuation, and blanks.
-\newcommand\caseupper[2][v]{%
- \Treatments{1}{2}{1}{1}{1}{1}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\caselower}
-% \begin{macrocode}
-% Convert Upper to Lowercase; retain all symbols, numerals,
-% punctuation, and blanks.
-\newcommand\caselower[2][v]{%
- \Treatments{2}{1}{1}{1}{1}{1}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\solelyuppercase}
-% \begin{macrocode}
-% Convert Lower to Uppercase; discard symbols, numerals, and
-% punctuation, but keep blanks.
-\newcommand\solelyuppercase[2][v]{%
- \Treatments{1}{2}{0}{0}{0}{1}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\solelylowercase}
-% \begin{macrocode}
-% Convert Upper to Lowercase; discard symbols, numerals, and
-% punctuation, but keep blanks.
-\newcommand\solelylowercase[2][v]{%
- \Treatments{2}{1}{0}{0}{0}{1}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\changecase}
-% \begin{macrocode}
-% Convert Lower to Uppercase & Upper to Lower; retain all symbols, numerals,
-% punctuation, and blanks.
-\newcommand\changecase[2][v]{%
- \Treatments{2}{2}{1}{1}{1}{1}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\noblanks}
-% \begin{macrocode}
-% Remove blanks; retain all else.
-\newcommand\noblanks[2][v]{%
- \Treatments{1}{1}{1}{1}{1}{0}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\nosymbolsnumerals}
-% \begin{macrocode}
-% Retain case; discard symbols & numerals; retain
-% punctuation & blanks.
-\newcommand\nosymbolsnumerals[2][v]{%
- \Treatments{1}{1}{1}{0}{0}{1}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\alphabetic}
-% \begin{macrocode}
-% Retain case; discard symbols, numerals &
-% punctuation; retain blanks.
-\newcommand\alphabetic[2][v]{%
- \Treatments{1}{1}{0}{0}{0}{1}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\capitalize}
-% The command |\CapitalizeString| is not set by |\Treatments|, but
-% only in |\capitalize| or in |\capitalizewords|.
-% \begin{macrocode}
-% Capitalize first character of string,
-\newcommand\capitalize[2][v]{%
- \defaultTreatments%
- \def\CapitalizeString{1}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \def\CapitalizeString{0}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\capitalizewords}
-% \begin{macrocode}
-% Capitalize first character of each word in string,
-\newcommand\capitalizewords[2][v]{%
- \defaultTreatments%
- \def\CapitalizeString{2}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \def\CapitalizeString{0}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\reversestring}
-% Reverses a string from back to front. To do this, a loop is set
-% up in which characters are grabbed one at a time from the end of the
-% given string, working towards the beginning of the string. The
-% grabbed characters are concatenated onto the end of the working
-% string, |\@reversedstring|. By the time the loop is complete
-% |\@reversedstring| fully represents the reversed string. The result
-% is placed into |\thestring|.
-% \begin{macrocode}
-% REVERSES SEQUENCE OF CHARACTERS IN STRING
-\newcommand\reversestring[2][v]{%
- \def\@reversedstring{}%
- \+\@getstringlength{#2}{@@stringsize}\?%
- \setcounter{@@@letterindex}{\the@@stringsize}%
- \whiledo{\the@@@letterindex > 0}{%
- \if e#1%
- \substring[e]{#2}{\the@@@letterindex}{\the@@@letterindex}%
- \else
- \substring[q]{#2}{\the@@@letterindex}{\the@@@letterindex}%
- \fi
- \edef\@reversedstring{\@reversedstring\thestring}%
- \addtocounter{@@@letterindex}{-1}%
- }%
- \edef\thestring{\@reversedstring}%
- \if v#1\thestring\fi%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\convertchar}
-% Takes a string, and replaces each occurance of a specified character
-% with a replacement string. The only complexity in the logic is that
-% a separate replacement algorithm exists depending on whether the
-% specified character to be replaced is a normal character or an
-% encoded character.
-% \begin{macrocode}
-% TAKES A STARTING STRING #2 AND SUBSTITUTES A SPECIFIED STRING #4
-% FOR EVERY OCCURANCE OF A PARTICULAR GIVEN CHARACTER #3. THE
-% CHARACTER TO BE CONVERTED MAY BE EITHER A PLAIN CHARACTER OR
-% AN ENCODABLE SYMBOL.
-\newcommand\convertchar[4][v]{%
- \+%
- \edef\encodedstring{#2}%
- \edef\encodedfromarg{#3}%
- \edef\encodedtoarg{#4}%
- \?%
- \isnextbyte[q]{\EscapeChar}{\encodedfromarg}%
- \if F\theresult%
-% PLAIN "FROM" ARGUMENT
- \@convertbytetostring[#1]{\encodedstring}{#3}{\encodedtoarg}%
- \else
-% ENCODABLE "FROM" ARGUMENT
- \@convertsymboltostring[#1]{\encodedstring}%
- {\expandafter\@gobble\encodedfromarg}{\encodedtoarg}%
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\convertword}
-% Takes a string, a replaces each occurance of a specified string
-% with a replacement string.
-% \begin{macrocode}
-\newcounter{@@matchloc}
-% LIKE \convertchar, EXCEPT FOR WORDS
-\newcommand\convertword[4][v]{%
- \+\edef\@@teststring{#2}%
- \edef\@fromstring{#3}%
- \edef\@tostring{#4}\?%
- \edef\@@@teststring{\@@teststring}%
- \def\@buildfront{}%
- \edef\@buildstring{\@@teststring}%
- \setcounter{@charsfound}{0}%
- \whiledo{\the@charsfound > -1}{%
-% \end{macrocode}
-% Seek occurance of |\@fromstring| in larger |\@@teststring|
-% \begin{macrocode}
- \whereisword[q]{\@@teststring}{\@fromstring}%
- \setcounter{@matchloc}{\theresult}%
- \ifthenelse{\the@matchloc = 0}%
- {%
-% \end{macrocode}
-% Not found. Done.
-% \begin{macrocode}
- \setcounter{@charsfound}{-1}%
- }%
- {%
-% \end{macrocode}
-% Potential matchstring.
-% \begin{macrocode}
- \addtocounter{@charsfound}{1}%
-% \end{macrocode}
-% Grab current test string from beginning to point just prior
-% to potential match.
-% \begin{macrocode}
- \addtocounter{@matchloc}{-1}%
- \substring[e]{\@@@teststring}{1}{\the@matchloc}%
-% \end{macrocode}
-% The string |\@buildfront| is the total original string, with
-% string substitutions, from character 1 to current potential match.
-% \begin{macrocode}
- \edef\@buildfront{\@buildfront\thestring}%
-% \end{macrocode}
-% See if potential matchstring takes us to end-of-string\ldots
-% \begin{macrocode}
- \addtocounter{@matchloc}{1}%
- \addtocounter{@matchloc}{\the@matchsize}%
- \ifthenelse{\the@matchloc > \the@@@stringsize}%
- {%
-% \end{macrocode}
-% \ldots if so, then match is last one in string. Tack on replacement
-% string to |\@buildfront| to create final string. Exit.
-% \begin{macrocode}
- \setcounter{@charsfound}{-1}%
- \edef\@buildstring{\@buildfront\@tostring}%
- }%
- {%
-% \end{macrocode}
-% \ldots if not, redefine current teststring to begin at point following
-% the current substitution. Make substitutions to current
-% |\@buildstring| and |\@buildfront|. Loop through logic again on new
-% teststring.
-% \begin{macrocode}
- \substring[e]{\@@@teststring}{\the@matchloc}{\@MAXSTRINGSIZE}%
- \edef\@@teststring{\thestring}%
- \edef\@@@teststring{\@@teststring}%
- \edef\@buildstring{\@buildfront\@tostring\@@@teststring}%
- \edef\@buildfront{\@buildfront\@tostring}%
- }%
- }%
- }%
- \substring[#1]{\@buildstring}{1}{\@MAXSTRINGSIZE}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\resetlcwords}
-% Removes all words from designated ``lower-case words'' list. This can
-% be useful because large lists of lower-case words can significantly
-% slow-down the function of |\capitalizetitle|.
-% \begin{macrocode}
-\setcounter{@lcwords}{0}
-% RESET LOWER-CASE WORD COUNT; START OVER
-\newcommand\resetlcwords[0]{%
- \setcounter{@lcwords}{0}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\addlcwords}
-% Add words to the list of designated ``lower-case words'' which will
-% not be capitalized by |\capitalizetitle|. The input should consist of
-% space-separated words, which are, in turn, passed on to |\addlcword|.
-% \begin{macrocode}
-% PROVIDE LIST OF SPACE-SEPARATED WORDS TO REMAIN LOWERCASE IN TITLES
-\newcommand\addlcwords[1]{%
- \getargs{#1}%
- \setcounter{@wordindex}{0}%
- \whiledo{\value{@wordindex} < \narg}{%
- \addtocounter{@wordindex}{1}%
- \addlcword{\csname arg\roman{@wordindex}\endcsname}%
- }
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\addlcword}
-% Add a word to the list of designated ``lower-case words'' which will
-% not be capitalized by |\capitalizetitle|.
-% \begin{macrocode}
-% PROVIDE A SINGLE WORD TO REMAIN LOWERCASE IN TITLES
-\newcommand\addlcword[1]{%
- \addtocounter{@lcwords}{1}%
- \expandafter\edef\csname lcword\roman{@lcwords}\endcsname{#1}
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\capitalizetitle}
-% Makes every word of a multi-word input string capitalized, except for
-% specifically noted ``lower-case words'' (examples might include
-% prepositions, conjunctions, \etc). The first word of the input string
-% is capitalized, while lower-case words, previously designated with
-% |\addlcword| and |\addlcwords|, are left in lower case.
-% \begin{macrocode}
-% CAPITALIZE TITLE, EXCEPT FOR DESIGNATED "LOWER-CASE" WORDS
-\newcommand\capitalizetitle[2][v]{%
-% First, capitalize every word (save in encoded form, not printed)
- \capitalizewords[e]{#2}%
-% Then lowercase words that shouldn't be capitalized, like articles,
-% prepositions, etc. (save in encoded form, not printed)
- \setcounter{@wordindex}{0}%
- \whiledo{\value{@wordindex} < \value{@lcwords}}{%
- \addtocounter{@wordindex}{1}%
- \edef\mystring{\thestring}%
- \edef\lcword{\csname lcword\roman{@wordindex}\endcsname}%
- \capitalize[e]{\lcword}%
- \edef\ucword{\thestring}%
- \convertword[e]{\mystring}{\ucword~}{\lcword~}%
- }
-% Finally, recapitalize the first word of the Title, and print it.
- \capitalize[#1]{\thestring}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\rotateword}
-% Moves first word of given string |#2| to end of string, including
-% leading and trailing blank spaces.
-% \begin{macrocode}
-\newcommand\rotateword[2][v]{%
- \+\edef\thestring{#2}\?%
-% \end{macrocode}
-% Rotate leading blank spaces to end of string
-% \begin{macrocode}
- \@treatleadingspaces[e]{\thestring}{}%
-% \end{macrocode}
-% Define end-of-rotate condition for |\substring| as next blank space
-% \begin{macrocode}
- \def\SeekBlankSpace{1}%
-% \end{macrocode}
-% Leave rotated characters alone
-% \begin{macrocode}
- \Treatments{1}{1}{1}{1}{1}{1}%
-% \end{macrocode}
-% Rotate to the next blank space or the end of string, whichever comes
-% first.
-% \begin{macrocode}
- \substring[e]{\thestring}{1}{\@MAXSTRINGSIZE}%
-% \end{macrocode}
-% Rotate trailing spaces.
-% \begin{macrocode}
- \@treatleadingspaces[#1]{\thestring}{}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\removeword}
-% Remove the first word of given string |#2|, including leading and
-% trailing spaces. Note that logic is identical to |\rotateword|,
-% except that affected spaces and characters are removed instead of
-% being rotated.
-% \begin{macrocode}
-\newcommand\removeword[2][v]{%
- \+\edef\thestring{#2}\?%
-% \end{macrocode}
-% The |{x}| final argument indicates to delete leading spaces.
-% \begin{macrocode}
- \@treatleadingspaces[e]{\thestring}{x}%
- \def\SeekBlankSpace{1}%
-% \end{macrocode}
-% The Treatments are specified to remove all characters.
-% \begin{macrocode}
- \Treatments{0}{0}{0}{0}{0}{0}%
- \substring[e]{\thestring}{1}{\@MAXSTRINGSIZE}%
-% \end{macrocode}
-% Trailing spaces are also deleted.
-% \begin{macrocode}
- \@treatleadingspaces[#1]{\thestring}{x}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\getnextword}
-% A special case of |\getaword|, where word-to-get is specified as
-% ``1''.
-% \begin{macrocode}
-% GETS NEXT WORD FROM STRING #2.
-% NOTE: ROTATES BACK TO BEGINNING, AFTER STRING OTHERWISE EXHAUSTED
-\newcommand\getnextword[2][v]{%
- \getaword[#1]{#2}{1}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\getaword}
-% Obtain a specified word number (|#3|) from string |#2|. Logic: rotate
-% leading spaces to end of string; then loop |#3|~--~1 times through
-% |\rotateword|. Finally, get next word.
-% \begin{macrocode}
-% GETS WORD #3 FROM STRING #2.
-% NOTE: ROTATES BACK TO BEGINNING, AFTER STRING OTHERWISE EXHAUSTED
-\newcommand\getaword[3][v]{%
- \setcounter{@wordindex}{1}%
- \+\edef\thestring{#2}\?%
- \@treatleadingspaces[e]{\thestring}{}%
- \whiledo{\value{@wordindex} < #3}{%
- \rotateword[e]{\thestring}%
- \addtocounter{@wordindex}{1}%
- }%
- \@getnextword[#1]{\thestring}%
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\rotateleadingspaces}
-% Rotate leading spaces of string |#2| to the end of string.
-% \begin{macrocode}
-\newcommand\rotateleadingspaces[2][v]{%
- \@treatleadingspaces[#1]{#2}{}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\removeleadingspaces}
-% Remove leading spaces from string |#2|.
-% \begin{macrocode}
-\newcommand\removeleadingspaces[2][v]{%
- \@treatleadingspaces[#1]{#2}{x}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\stringencode}
-% \begin{macrocode}
-% ENCODE STRING; UNLIKE OTHER COMMANDS, DEFAULT IS NO PRINT
-\newcommand\stringencode[2][e]{%
- \defaultTreatments%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\stringdecode}
-% \begin{macrocode}
-% DECODE STRING
-\newcommand\stringdecode[2][v]{%
- \defaultTreatments%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\gobblechar}
-% Remove first character (not byte!) from string |#2|. Unlike just about
-% all other \stringstrings commands, result is retokenized and not
-% expanded.
-% \begin{macrocode}
-% SINGLE-CHARACTER VERSION OF \gobblechars. IN THIS CASE, TWO-BYTE
-% ESCAPE SEQUENCES, WHEN ENCOUNTERED, COUNT AS A SINGLE GOBBLE.
-\newcommand\gobblechar[2][q]{\+%
- \@gobblearg{#2}{1}%
- \?\retokenize[#1]{\gobbledword}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\gobblechars}
-% Remove first |#3| characters (not bytes!) from string |#2|.
-% Unlike just about all other \stringstrings commands, result is
-% retokenized and not expanded.
-% \begin{macrocode}
-% USER CALLABLE VERSION OF \@gobblearg. TURNS ON REENCODING.
-% GOBBLE FIRST #3 CHARACTERS FROM STRING #2. TWO-BYTE
-% ESCAPE SEQUENCES, WHEN ENCOUNTERED, COUNT AS A SINGLE GOBBLE.
-\newcommand\gobblechars[3][q]{\+%
- \@gobblearg{#2}{#3}%
- \?\retokenize[#1]{\gobbledword}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\retokenize}
-% One of the key \stringstrings routines that provides several
-% indispensible functions. Its function is to take an encoded string
-% |#2| that has been given, and repopulate the string with its \LaTeX{}
-% tokens in a |\def| form (not an expanded |\edef| form). It is
-% useful if required to operate on a string outside of the
-% \stringstrings library routines, following a \stringstrings
-% manipulation. It is also useful to display certain tokens which
-% cannot be manipulated in expanded form. See
-% Table~\ref{tbl:prob} for a list of tokens that will only work when the
-% resulting string is retokenized (and not expanded).
-%
-% Logic: Loop through each character of given string |#2|. Each
-% successive character of the string is retokenized as |\inexttoken|,
-% |\iinexttoken|, |\iiinexttoken|, |\ivnexttoken|, \etc, respectively.
-% Then a series of strings are formed as\\
-% \\
-% |\def\buildtoken{}|\\
-% |\def\buildtokeni{\builtoken\inexttoken}|\\
-% |\def\buildtokenii{\builtokeni\iinexttoken}|\\
-% |\def\buildtokeniii{\builtokenii\iiinexttoken}|\\
-% |\def\buildtokeniv{\builtokeniii\ivnexttoken}|\\
-% \\
-% The last in the sequence of |\builtoken...| strings (renamed
-% |\buildtokenq|) is the retokenized
-% version of string |#2|.
-% \begin{macrocode}
-% CONVERTS ENCODED STRING BACK INTO TOKENIZED FORM (i.e., def'ED).
-\newcommand\retokenize[2][q]{\+%
- \edef\@svstring{#2}%
- \edef\buildtoken{}%
- \@getstringlength{#2}{@@stringsize}\?%
- \setcounter{@@letterindex}{0}%
- \whiledo{\the@@letterindex < \the@@stringsize}{%
- \setcounter{@previousindex}{\the@@letterindex}%
- \addtocounter{@@letterindex}{1}%
- \substring[e]{\@svstring}{\the@@letterindex}{\the@@letterindex}%
- \@retokenizechar{\thestring}{\roman{@@letterindex}nexttoken}%
- \expandafter\def\csname buildtoken\roman{@@letterindex}%
- \expandafter\endcsname\expandafter%
- {\csname buildtoken\roman{@previousindex}\expandafter\endcsname%
- \csname\roman{@@letterindex}nexttoken\endcsname}%
- }%
- \expandafter\def\expandafter\buildtokenq\expandafter{%
- \csname buildtoken\roman{@@letterindex}\endcsname}%
- \def\thestring{\buildtokenq}%
- \if v#1\thestring\fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macrocode}
-% %%%%% COMMANDS TO EXTRACT STRING INFORMATION %%%%%%%%%%%%%%%%%%%%%%%%%%
-% \end{macrocode}
-
-% The following group of commands extract information about a string,
-% and store the result in a string called |\theresult|. Since the
-% result is not a substring, a \textit{mode} of |[e]| carries no
-% meaning. Only |[v]| and |[q]| modes apply here.
-% \begin{macro}{\stringlength}
-% Returns the length of the given string in \textit{characters}, not
-% \textit{bytes}.
-% \begin{macrocode}
-% USER CALLABLE VERSION of \@getstringlength:
-% GET'S STRING LENGTH OF [#2], PUTS RESULT IN \theresult. PRINTS RESULT
-% UNLESS IN QUIET [q] MODE.
-\newcommand\stringlength[2][v]{\+%
- \@getstringlength{#2}{@@stringsize}%
- \edef\theresult{\arabic{@@stringsize}}%
- \if v#1\theresult\fi%
-\?}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\findchars}
-% Find number of occurances of character |#3| in string |#2|.
-% \begin{macrocode}
-% CHECKS TO SEE IF THE CHARACTER [#3] APPEARS ANYWHERE IN STRING [#2].
-% THE NUMBER OF OCCURANCES IS PRINTED OUT, EXCEPT WHEN [#1]=q, QUIET
-% MODE. RESULT IS ALSO STORED IN \theresult . TO FIND SPACES, ARG3
-% SHOULD BE SET TO {~}, NOT { }.
-\newcommand\findchars[3][v]{\+%
- \@getstringlength{#2}{@@stringsize}%
- \setcounter{@charsfound}{0}%
- \setcounter{@@letterindex}{0}%
-% \end{macrocode}
-% Loop through each character of |#2|.
-% \begin{macrocode}
- \whiledo{\value{@@letterindex} < \value{@@stringsize}}{%
- \addtocounter{@@letterindex}{1}%
-% \end{macrocode}
-% Test if the |@@letterindex| character of string |#2| equals |#3|.
-% If so, add to tally.
-% \begin{macrocode}
- \testmatchingchar{#2}{\arabic{@@letterindex}}{#3}%
- \ifmatchingchar\addtocounter{@charsfound}{1}\fi
- }%
- \edef\theresult{\arabic{@charsfound}}%
- \if q#1\else\theresult\fi%
-\?}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\whereischar}
-% Similar to |\findchars|, but instead finds first occurance of match
-% character |#3| within |#2| and returns its location within |#2|.
-% \begin{macrocode}
-% CHECKS TO FIND LOCATION OF FIRST OCCURANCE OF [#3] IN STRING [#2].
-% THE LOCATION IS PRINTED OUT, EXCEPT WHEN [#1]=q, QUIET
-% MODE. RESULT IS ALSO STORED IN \theresult . TO FIND SPACES, ARG3
-% SHOULD BE SET TO {~}, NOT { }.
-\newcommand\whereischar[3][v]{\+%
- \@getstringlength{#2}{@@stringsize}%
- \edef\@theresult{0}%
- \setcounter{@@letterindex}{0}%
-% \end{macrocode}
-% Loop through characters of |#2| sequentially.
-% \begin{macrocode}
- \whiledo{\value{@@letterindex} < \value{@@stringsize}}{%
- \addtocounter{@@letterindex}{1}%
-% \end{macrocode}
-% Look for match. If found, save character-location index,
-% and reset loop index to break from loop.
-% \begin{macrocode}
- \testmatchingchar{#2}{\arabic{@@letterindex}}{#3}%
- \ifmatchingchar%
- \edef\@theresult{\the@@letterindex}%
- \setcounter{@@letterindex}{\the@@stringsize}%
- \fi
- }%
- \edef\theresult{\@theresult}%
- \if q#1\else\theresult\fi%
-\?}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\whereisword}
-% Finds location of specified word (|#3|) in string |#2|.
-% \begin{macrocode}
-% LIKE \whereischar, EXCEPT FOR WORDS
-\newcommand\whereisword[3][v]{\+%
- \setcounter{@skipped}{0}%
-% \end{macrocode}
-% |\@@@@teststring| initially contains |#2|. As false alarms are
-% located, the string will be redefined to lop off initial characters
-% of string.
-% \begin{macrocode}
- \edef\@@@@teststring{#2}%
- \edef\@matchstring{#3}%
- \@getstringlength{#2}{@@stringsize}%
- \setcounter{@@@stringsize}{\value{@@stringsize}}%
- \@getstringlength{#3}{@matchsize}%
- \setcounter{@matchmax}{\the@@stringsize}%
- \addtocounter{@matchmax}{-\the@matchsize}%
- \addtocounter{@matchmax}{1}%
- \setcounter{@flag}{0}%
-% \end{macrocode}
-% Define |\matchchar| as the first character of the match string (|#3|).
-% \begin{macrocode}
- \substring[e]{#3}{1}{1}%
- \edef\matchchar{\thestring}%
- \whiledo{\the@flag = 0}{%
-% \end{macrocode}
-% Look for first character of match string within |\@@@@teststring|.
-% \begin{macrocode}
- \whereischar[q]{\@@@@teststring}{\matchchar}%
- \setcounter{@matchloc}{\theresult}%
- \ifthenelse{\equal{0}{\value{@matchloc}}}%
-% \end{macrocode}
-% If none found, we are done.
-% \begin{macrocode}
- {%
- \setcounter{@flag}{1}%
- }%
-% \end{macrocode}
-% If |\matchchar| is found, must determine if it is the beginning
-% of the match string, or just an extraneous match (\ie false alarm).
-% Extract substring
-% of |\@@@@teststring|, of a size equal to the match string.
-% Compare this extracted string with the match string.
-% \begin{macrocode}
- {%
- \setcounter{@matchend}{\theresult}%
- \addtocounter{@matchend}{\value{@matchsize}}%
- \addtocounter{@matchend}{-1}%
- \substring[e]{\@@@@teststring}{\the@matchloc}{\the@matchend}%
- \ifthenelse{\equal{\thestring}{\@matchstring}}%
-% \end{macrocode}
-% Found a match! Save the match location
-% \begin{macrocode}
- {%
- \setcounter{@flag}{1}%
- \addtocounter{@matchloc}{\the@skipped}%
- \edef\theresult{\the@matchloc}%
- }%
-% \end{macrocode}
-% False alarm. Determine if lopping off the leading characters of
-% |\@@@@teststring| (to discard the false-alarm occurance) is feasible.
-% If lopping would take one past the end of the string,
-% then no match is possible. If lopping permissible, redefine the
-% string |\@@@@teststring|, keeping track of the total number of
-% lopped-off characters in the counter |@skipped|.
-% \begin{macrocode}
- {%
- \addtocounter{@skipped}{\the@matchloc}%
- \addtocounter{@matchloc}{1}%
- \ifthenelse{\value{@matchloc} > \value{@matchmax}}%
- {%
- \setcounter{@flag}{1}%
- \edef\theresult{0}%
- }%
- {%
- \substring[e]{\@@@@teststring}{\the@matchloc}{\@MAXSTRINGSIZE}%
- \edef\@@@@teststring{\thestring}%
- }%
- }%
- }%
- }%
- \if q#1\else\theresult\fi%
-\?}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\findwords}
-% Finds the number of occurances of a word within the provided string
-% \begin{macrocode}
-% LIKE \findchar, EXCEPT FOR WORDS
-\newcommand\findwords[3][v]{%
- \+\edef\@@teststring{#2}\?%
- \edef\@@@teststring{\@@teststring}%
- \setcounter{@charsfound}{0}%
- \whiledo{\the@charsfound > -1}{%
-% \end{macrocode}
-% Seek occurance of |#3| in the string to be tested
-% \begin{macrocode}
- \whereisword[q]{\@@teststring}{#3}%
- \setcounter{@matchloc}{\theresult}%
- \ifthenelse{\the@matchloc = 0}%
- {%
-% \end{macrocode}
-% None found. Break from loop.
-% \begin{macrocode}
- \edef\theresult{\the@charsfound}%
- \setcounter{@charsfound}{-1}%
- }%
- {%
-% \end{macrocode}
-% Found. Increment count.
-% \begin{macrocode}
- \addtocounter{@charsfound}{1}%
- \addtocounter{@matchloc}{\the@matchsize}%
- \ifthenelse{\the@matchloc > \the@@stringsize}%
- {%
-% \end{macrocode}
-% This "find" takes us to the end-of-string. Break from loop now.
-% \begin{macrocode}
- \edef\theresult{\the@charsfound}%
- \setcounter{@charsfound}{-1}%
- }%
- {%
-% \end{macrocode}
-% More string to search. Lop off what has been searched from string to
-% be tested, and re-loop for next search.
-% \begin{macrocode}
- \substring[e]{\@@@teststring}{\the@matchloc}{\@MAXSTRINGSIZE}%
- \edef\@@teststring{\thestring}%
- \edef\@@@teststring{\@@teststring}%
- }%
- }%
- }%
- \if q#1\else\theresult\fi%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\wordcount}
-% Counts words (space-separated text) in a string. Simply removes one
-% word at a time, counting the words as it goes. With each removal,
-% checks for non-zero string size remaining.
-% \begin{macrocode}
-% WORD COUNT
-\newcommand\wordcount[2][v]{\+%
- \edef\@argv{#2}
- \@getstringlength{\@argv}{@stringsize}
- \setcounter{@iargc}{0}
- \whiledo{\value{@stringsize} > 0}{%
- \addtocounter{@iargc}{1}%
- \removeword[e]{\@argv}%
- \edef\@argv{\thestring}%
- \@getstringlength{\@argv}{@stringsize}%
- }
- \edef\theresult{\arabic{@iargc}}%
- \if v#1\theresult\fi%
-\?}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\getargs}
-% Parse a string of arguments in Unix-like manner. Define |\argv| as |#2|.
-% Grabs leading word from |\argv| and puts it in |\argi|. Increment
-% argument count; remove leading word from |\argv|. Repeat this process,
-% with each new argument being placed in |\argii|, |\argiii|, |\argiv|,
-% \etc~ Continue until size of |\argv| is exhausted.
-% \begin{macrocode}
-% OBTAINS ARGUMENTS (WORDS) IN #1 ALA UNIX getarg COMMAND
-% narg CONTAINS NUMBER OF ARGUMENTS. ARGUMENTS CONTAINED IN
-% argi, argii, argiii, argiv, ETC.
-% v mode disabled
-\newcommand\getargs[2][q]{\+%
- \if v#1\def\@mode{q}\else\def\@mode{#1}\fi%
- \edef\@argv{#2}%
- \@getstringlength{\@argv}{@stringsize}%
- \setcounter{@iargc}{0}%
- \whiledo{\value{@stringsize} > 0}{%
- \addtocounter{@iargc}{1}%
- \getaword[\@mode]{\@argv}{1}%
- \expandafter\edef\csname arg\roman{@iargc}\endcsname{\thestring}%
- \removeword[e]{\@argv}%
- \edef\@argv{\thestring}%
- \@getstringlength{\@argv}{@stringsize}%
- }%
- \edef\narg{\arabic{@iargc}}%
-\?}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macrocode}
-%%%%% COMMANDS TO TEST STRINGS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \end{macrocode}
-
-% The following group of commands test for various alphanumeric
-% string conditions.
-% \begin{macro}{\isnextbyte}
-% This routine performs a simple test to determine if the first byte of
-% string |#3| matches the byte given by |#2|. The only problem is that
-% the test can produce a false negative if the first byte of the test
-% string equals the match byte and the second byte of the test string
-% equals the |SignalChar| (defined below).
-%
-% To resolve this possibility, the test is performed twice with two
-% different values for |\SignalChar|, only one of which can produce
-% a false negative for a given test string. If the two results match,
-% then that result gives the correct answer to the question of whether
-% the first byte of |#3| equals |#2|. If, however, the two results fail
-% to match, then one can assume that one of the results is a false
-% negative, and so a ``true'' condition results.
-% \begin{macrocode}
-% \end{macrocode}
-% The following two ``signal characters,'' used for the two tests,
-% can be any two distinct characters. They are used solely
-% by |\isnextbyte|.
-% \begin{macrocode}
-\def\PrimarySignalChar{@}
-\def\SecondarySignalChar{`}
-
-% \isnextbyte NEEDS TO OPERATE IN RAW (SINGLE BYTE) MODE SO AS TO
-% PERFORM TESTS FOR PRESENCE OF \EscapeChar
-% \end{macrocode}
-% Incidentally,
-% |\isnextbyte| can and is used by \stringstrings to detect
-% multi-byte characters in a manner which may also be employed by the
-% user. To do this:
-% First, the string to be tested should be encoded. Then, |\isnextbyte|
-% may be used to check for |\EscapeChar| which is how every multi-byte
-% character will begin its encoding by the \stringstrings package.
-% If |\EscapeChar| is detected as the next character, then the string to
-% test may have its leading byte gobbled and the next character (called
-% the Escape Code) may be tested, and compared against the known
-% \stringstrings escape codes. The combination of
-% Escape-Character/Escape-Code is how all multi-byte characters are
-% encoded by the \stringstrings package.
-% \begin{macrocode}
-\newcommand\isnextbyte[3][v]{%
-% \end{macrocode}
-% Here's the first test\ldots
-% \begin{macrocode}
- \let\SignalChar\PrimarySignalChar%
- \edef\@x{\if #2#3\else\SignalChar\fi}%
- \edef\@x{\if \SignalChar\@x F\else T\fi}%
-% \end{macrocode}
-% \ldots and the second
-% \begin{macrocode}
- \let\SignalChar\SecondarySignalChar%
- \edef\@y{\if #2#3\else\SignalChar\fi}%
- \edef\@y{\if \SignalChar\@y F\else T\fi}%
-% \end{macrocode}
-% If the two tests produced the same result, then a comparison of |\@x\@y|
-% and |\@y\@x| will show it.
-% \begin{macrocode}
-% BECAUSE THE METHOD ONLY PRODUCES FALSE NEGATIVES, IF RESULTS DON'T
-% AGREE FROM USING TWO DIFFERENT SIGNAL CHARACTERS, RESULT MUST BE TRUE.
- \ifthenelse{\equal{\@x\@y}{\@y\@x}}
- {\edef\theresult{\@x}}%
-% CORRECT THE FALSE NEGATIVE
- {\edef\theresult{T}}%
- \if q#1\else\theresult\fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\testmatchingchar}
-% This routine checks for a specified match-character within a target
-% string. Unlike |\isnextbyte|, this
-% routine checks for characters (single- or multi-byte) and not just
-% individual bytes. Additionally, rather than testing the
-% match-character against the first byte of the test-string, the user
-% specifies (through |#2|) which byte of the test-string should be
-% compared to the match-character.
-%
-% This routine is not as efficient as |\isnextbyte|, but much more
-% versatile.
-% \begin{macrocode}
-% CHECKS TO SEE IF [#2]'th CHARACTER IN STRING [#1] EQUALS [#3]
-% RESULT STORED IN BOOLEAN \ifmatchingchar
-\newif\ifmatchingchar
-\newcommand\testmatchingchar[3]{%
- \setbox0=\hbox{%
-% \end{macrocode}
-% Extract desired character from test string
-% \begin{macrocode}
- \substring[e]{#1}{#2}{#2}\+%
-% \end{macrocode}
-% Determine if the match-character is a multi-byte symbol.
-% \begin{macrocode}
- \isnextbyte[q]{\EscapeChar}{#3}%
- \if T\theresult%
-% \end{macrocode}
-% Is the tested character also a multi-byte symbol?
-% \begin{macrocode}
- \isnextbyte[q]{\EscapeChar}{\thestring}%
- \if T\theresult%
-% \end{macrocode}
-% Yes it is\ldots Therefore, compare codes following the escape character
-% \begin{macrocode}
- \edef\@testcode{\expandafter\@DiscardNextChar\expandafter{#3}}%
- \edef\@teststring{\@DiscardNextChar{\thestring}}%
- \if \@teststring\@testcode\matchingchartrue\else\matchingcharfalse\fi
- \else
-% \end{macrocode}
-% No, we are comparing a normal character against a multi-byte symbol
-% (apples and oranges), a false comparison.
-% \begin{macrocode}
- \global\matchingcharfalse%
- \fi
- \else
-% \end{macrocode}
-% No, we are comparing two normal one-byte characters, not a mult-byte
-% character.
-% \begin{macrocode}
- \if \thestring#3\global\matchingchartrue\else\global\matchingcharfalse\fi
- \fi}
-\?}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\testcapitalized}
-% This routine checks to see if first character of string is
-% capitalized. The only quirk is that the routine must ascertain
-% whether that character is a single-byte character or a multi-byte
-% character.
-% \begin{macrocode}
-\newif\ifcapitalized
-\newcommand\testcapitalized[1]{\+%
- \setbox0=\hbox{%
- \isnextbyte[q]{\EscapeChar}{#1}%
- \if T\theresult%
- \def\EncodingTreatment{e}%
- \edef\rotatingword{#1}%
-% \end{macrocode}
-% Rotate the first [multi-byte] character of the string to the end
-% of the string, lowering its case. Store as |\@stringA|.
-% \begin{macrocode}
- \def\AlphaCapsTreatment{2}%
- \@defineactions%
- \edef\@stringA{\ESCrotate{\expandafter\@gobble\rotatingword}}%
-% \end{macrocode}
-% Rotate the first [multi-byte] character of the string to the end
-% of the string, retaining its case. Store as |\@stringB|.
-% \begin{macrocode}
- \def\AlphaCapsTreatment{1}%
- \@defineactions%
- \edef\@stringB{\ESCrotate{\expandafter\@gobble\rotatingword}}%
- \else
-% \end{macrocode}
-% \ldots or, if the first character is a normal one-byte character\ldots
-% Rotate the first [normal] character of the string to the end
-% of the string, lowering its case. Store as |\@stringA|.
-% \begin{macrocode}
- \def\AlphaCapsTreatment{2}%
- \edef\@stringA{\@rotate{#1}}%
-% \end{macrocode}
-% Rotate the first [normal] character of the string to the end
-% of the string, retaining its case. Store as |\@stringB|.
-% \begin{macrocode}
- \def\AlphaCapsTreatment{1}%
- \edef\@stringB{\@rotate{#1}}%
- \fi
-% \end{macrocode}
-% Compare strings A and B, to see if changing the case of first letter
-% altered the string
-% \begin{macrocode}
- \ifthenelse{\equal{\@stringA}{\@stringB}}%
- {\global\capitalizedfalse}{\global\capitalizedtrue}}\?%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\testuncapitalized}
-% This routine is the complement of |\testcapitalized|. The only
-% difference is that the |\@stringA| has its case made upper for the
-% comparison, instead of lowered.
-% \begin{macrocode}
-\newif\ifuncapitalized
-\newcommand\testuncapitalized[1]{\+%
- \setbox0=\hbox{%
- \isnextbyte[q]{\EscapeChar}{#1}%
- \if T\theresult%
- \def\EncodingTreatment{e}%
- \edef\rotatingword{#1}%
- \def\AlphaTreatment{2}%
- \@defineactions%
- \edef\@stringA{\ESCrotate{\expandafter\@gobble\rotatingword}}%
- \def\AlphaTreatment{1}%
- \@defineactions%
- \edef\@stringB{\ESCrotate{\expandafter\@gobble\rotatingword}}%
- \else
- \def\AlphaTreatment{2}%
- \edef\@stringA{\@rotate{#1}}%
- \def\AlphaTreatment{1}%
- \edef\@stringB{\@rotate{#1}}%
- \fi
- \ifthenelse{\equal{\@stringA}{\@stringB}}%
- {\global\uncapitalizedfalse}{\global\uncapitalizedtrue}}\?%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\testleadingalpha}
-% Test if the leading character of the string is alphabetic. This is
-% simply accomplished by checking whether the string is either
-% capitalized or uncapitalized. If non-alphabetic, it will show
-% up as false for both those tests.
-% \begin{macrocode}
-\newif\ifleadingalpha
-\newcommand\testleadingalpha[1]{%
- \testcapitalized{#1}%
- \ifcapitalized
- \leadingalphatrue%
- \else
- \testuncapitalized{#1}%
- \ifuncapitalized
- \leadingalphatrue%
- \else
- \leadingalphafalse%
- \fi
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\testuppercase}
-% Checks to see if all alphabetic characters in a string are uppercase.
-% Non-alphabetic characters don't affect the result, unless the string
-% is composed solely of nonalphabetic characters, in which case the test
-% results is false.
-% \begin{macrocode}
-\newif\ifuppercase
-\newcommand\testuppercase[1]{%
- \setbox0=\hbox{%
-% \end{macrocode}
-% Strip all non-alphabetic characters. Save as |\@stringA|.
-% \begin{macrocode}
- \Treatments{1}{1}{0}{0}{0}{0}%
- \substring[e]{#1}{1}{\@MAXSTRINGSIZE}%
- \edef\@stringA{\thestring}%
-% \end{macrocode}
-% Lower the case of all uppercase characters in |\@stringA|. Save as
-% |\@stringB|. Compare these two strings.
-% \begin{macrocode}
- \def\AlphaTreatment{2}%
- \substring[e]{#1}{1}{\@MAXSTRINGSIZE}%
- \edef\@stringB{\thestring}%
- \ifthenelse{\equal{\@stringA}{\@stringB}}%
- {%
-% \end{macrocode}
-% If the strings are equal, then all the alphabetic characters in the
-% original string were uppercase. Need only check to make sure at
-% least one alphabetic character was present in the original string.
-% \begin{macrocode}
- \@getstringlength{\@stringA}{@stringsize}%
- \ifthenelse{\value{@stringsize} = 0}%
- {\global\uppercasefalse}{\global\uppercasetrue}%
- }%
-% \end{macrocode}
-% If strings are not equal, then the alphabetic characters of the
-% original string were not all uppercase. Test false.
-% \begin{macrocode}
- {\global\uppercasefalse}}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\ifsolelyuppercase}
-% Compare the original string to one made solely uppercase. If they are
-% equal (and not composed solely of blankspaces), then the original
-% string was solely uppercase to begin with.
-% \begin{macrocode}
-\newif\ifsolelyuppercase
-\newcommand\testsolelyuppercase[1]{%
- \setbox0=\hbox{%
- \stringencode{#1}%
- \edef\@stringA{\thestring}%
- \solelyuppercase[e]{#1}%
- \edef\@stringB{\thestring}%
- \ifthenelse{\equal{\@stringA}{\@stringB}}%
- {%
- \noblanks[q]{\@stringA}%
- \@getstringlength{\thestring}{@stringsize}%
- \ifthenelse{\value{@stringsize} = 0}%
- {\global\solelyuppercasefalse}{\global\solelyuppercasetrue}%
- }%
- {\global\solelyuppercasefalse}}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\testlowercase}
-% This routine is the complement to |\testuppercase|, with corresponding
-% logic.
-% \begin{macrocode}
-\newif\iflowercase
-\newcommand\testlowercase[1]{%
- \setbox0=\hbox{%
- \Treatments{1}{1}{0}{0}{0}{0}%
- \substring[e]{#1}{1}{\@MAXSTRINGSIZE}%
- \edef\@stringA{\thestring}%
- \def\AlphaCapsTreatment{2}%
- \substring[e]{#1}{1}{\@MAXSTRINGSIZE}%
- \edef\@stringB{\thestring}%
- \ifthenelse{\equal{\@stringA}{\@stringB}}%
- {%
- \@getstringlength{\@stringA}{@stringsize}%
- \ifnum\value{@stringsize}= 0\relax%
- \global\lowercasefalse\else\global\lowercasetrue\fi%
- }%
- {\global\lowercasefalse}}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\testsolelylowercase}
-% This routine is the complement to |\testsolelyuppercase|, with
-% corresponding logic.
-% \begin{macrocode}
-\newif\ifsolelylowercase
-\newcommand\testsolelylowercase[1]{%
- \setbox0=\hbox{%
- \stringencode{#1}%
- \edef\@stringA{\thestring}%
- \solelylowercase[e]{#1}%
- \edef\@stringB{\thestring}%
- \ifthenelse{\equal{\@stringA}{\@stringB}}%
- {%
- \noblanks[q]{\@stringA}%
- \@getstringlength{\thestring}{@stringsize}%
- \ifthenelse{\value{@stringsize} = 0}%
- {\global\solelylowercasefalse}{\global\solelylowercasetrue}%
- }%
- {\global\solelylowercasefalse}}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\testalphabetic}
-% Comparable to |\testsolelyuppercase| and
-% |\testsolelylowercase| in its logic, this routine tests whether
-% the string is purely alphabetic or not.
-% \begin{macrocode}
-\newif\ifalphabetic
-\newcommand\testalphabetic[1]{%
- \setbox0=\hbox{%
- \stringencode{#1}%
- \edef\@stringA{\thestring}%
- \alphabetic[e]{#1}%
- \edef\@stringB{\thestring}%
- \ifthenelse{\equal{\@stringA}{\@stringB}}%
- {%
- \noblanks[q]{\@stringA}%
- \@getstringlength{\thestring}{@stringsize}%
- \ifthenelse{\value{@stringsize} = 0}%
- {\global\alphabeticfalse}{\global\alphabetictrue}%
- }%
- {\global\alphabeticfalse}}%
- \defaultTreatments%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macrocode}
-%
-%%%%% SUPPORT ROUTINES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% \end{macrocode}
-% The following routines support the execution of the \stringstrings
-% package.
-
-% \begin{macro}{\ESCrotate}
-% After the escape character has been ascertained as the next character,
-% this routine operates on the subsequent escape code to rotate the
-% symbol to end of string, in the fashion of macro |\@rotate|.
-% \begin{macrocode}
-\newcommand\ESCrotate[1]{%
- \if\UvariCode#1\@uvariaction\else
- \if\UvariiCode#1\@uvariiaction\else
- \if\UvariiiCode#1\@uvariiiaction\else
- \if\@fromcode#1\@tostring\else
- \if\PipeCode#1\@pipeaction\else
- \if\DollarCode#1\@dollaraction\else
- \if\CaratCode#1\@carataction\else
- \if\CircumflexCode#1\@circumflexaction\else
- \if\TildeCode#1\@tildeaction\else
- \if\UmlautCode#1\@umlautaction\else
- \if\GraveCode#1\@graveaction\else
- \if\AcuteCode#1\@acuteaction\else
- \if\MacronCode#1\@macronaction\else
- \if\OverdotCode#1\@overdotaction\else
- \if\LeftBraceCode#1\@leftbraceaction\else
- \if\RightBraceCode#1\@rightbraceaction\else
- \if\UnderscoreCode#1\@underscoreaction\else
- \if\DaggerCode#1\@daggeraction\else
- \if\DoubleDaggerCode#1\@doubledaggeraction\else
- \if\SectionSymbolCode#1\@sectionsymbolaction\else
- \if\PilcrowCode#1\@pilcrowaction\else
- \if\LBCode#1\@lbaction\else
- \if\RBCode#1\@rbaction\else
- \if\BreveCode#1\@breveaction\else
- \if\CaronCode#1\@caronaction\else
- \if\DoubleAcuteCode#1\@doubleacuteaction\else
- \if\CedillaCode#1\@cedillaaction\else
- \if\UnderdotCode#1\@underdotaction\else
- \if\ArchJoinCode#1\@archjoinaction\else
- \if\LineUnderCode#1\@lineunderaction\else
- \if\CopyrightCode#1\@copyrightaction\else
- \if\PoundsCode#1\@poundsaction\else
- \if\AEscCode#1\@AEscaction\else
- \if\aescCode#1\@aescaction\else
- \if\OEthelCode#1\@OEthelaction\else
- \if\oethelCode#1\@oethelaction\else
- \if\AngstromCode#1\@Angstromaction\else
- \if\angstromCode#1\@angstromaction\else
- \if\SlashedOCode#1\@slashedOaction\else
- \if\SlashedoCode#1\@slashedoaction\else
- \if\BarredlCode#1\@barredlaction\else
- \if\BarredLCode#1\@barredLaction\else
- \if\EszettCode#1\@eszettaction\else
- \expandafter\@gobble#1\undecipherable%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@getnextword}
-% A low-level routine designed to extract the next [space-delimited]
-% word of the primary
-% argument. It has several quirks: if the passed string has one leading
-% space, it is included as part of next word. If it has two leading
-% [hard]spaces, the 2$^\mathrm{nd}$ hard space \textit{is} the next word.
-% Using the higher-level |\getnextword| deals automatically with
-% these abberant possibilities.
-% \begin{macrocode}
-\newcommand\@getnextword[2][v]{%
- \defaultTreatments%
- \def\SeekBlankSpace{2}%
- \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
- \def\SeekBlankSpace{0}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@retokenizechar}
-% This command is the guts of the retokenize command. It grabs the
-% character provided in string |#1| and assigns it to a unique token
-% whose name is created from the string |#2|. The command has two
-% primary |\if| branches. The first branch is taken if the
-% character is a special two-byte-encoded escape-sequence, while
-% the second branch is taken if the character is a |&|, |%|, |#|,
-% a blankspace, or any simple one-byte character.
-% \begin{macrocode}
-\newcommand\@retokenizechar[2]{%
- \isnextbyte[q]{\EscapeChar}{#1}%
- \if T\theresult%
- \edef\@ESCcode{\expandafter\@gobble#1}%
- \if\UvariCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\Uvari}\else
- \if\UvariiCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\Uvarii}\else
- \if\UvariiiCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\Uvariii}\else
- \if\PipeCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\Pipe}\else
- \if\DollarCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\$}\else
- \if\CaratCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\Carat}\else
- \if\CircumflexCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\^}\else
- \if\TildeCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\~}\else
- \if\UmlautCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\"}\else
- \if\GraveCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\`}\else
- \if\AcuteCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\'}\else
- \if\MacronCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\=}\else
- \if\OverdotCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\.}\else
- \if\LeftBraceCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\{}\else
- \if\RightBraceCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\}}\else
- \if\UnderscoreCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\_}\else
- \if\DaggerCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\dag}\else
- \if\DoubleDaggerCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\ddag}\else
- \if\SectionSymbolCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\S}\else
- \if\PilcrowCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\P}\else
- \if\LBCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\SaveLB}\else
- \if\RBCode\@ESCcode%
- \expandafter\def\csname#2\endcsname{\SaveRB}\else
- \if\BreveCode\@ESCcode\expandafter\def\csname#2\endcsname{\u}\else
- \if\CaronCode\@ESCcode\expandafter\def\csname#2\endcsname{\v}\else
- \if\DoubleAcuteCode\@ESCcode\expandafter\def\csname#2\endcsname{\H}\else
- \if\CedillaCode\@ESCcode\expandafter\def\csname#2\endcsname{\c}\else
- \if\UnderdotCode\@ESCcode\expandafter\def\csname#2\endcsname{\d}\else
- \if\ArchJoinCode\@ESCcode\expandafter\def\csname#2\endcsname{\t}\else
- \if\LineUnderCode\@ESCcode\expandafter\def\csname#2\endcsname{\b}\else
- \if\CopyrightCode\@ESCcode\expandafter\def\csname#2\endcsname{\copyright}\else
- \if\PoundsCode\@ESCcode\expandafter\def\csname#2\endcsname{\pounds}\else
- \if\AEscCode\@ESCcode\expandafter\def\csname#2\endcsname{\AE}\else
- \if\aescCode\@ESCcode\expandafter\def\csname#2\endcsname{\ae}\else
- \if\OEthelCode\@ESCcode\expandafter\def\csname#2\endcsname{\OE}\else
- \if\oethelCode\@ESCcode\expandafter\def\csname#2\endcsname{\oe}\else
- \if\AngstromCode\@ESCcode\expandafter\def\csname#2\endcsname{\AA}\else
- \if\angstromCode\@ESCcode\expandafter\def\csname#2\endcsname{\aa}\else
- \if\SlashedOCode\@ESCcode\expandafter\def\csname#2\endcsname{\O}\else
- \if\SlashedoCode\@ESCcode\expandafter\def\csname#2\endcsname{\o}\else
- \if\BarredlCode\@ESCcode\expandafter\def\csname#2\endcsname{\l}\else
- \if\BarredLCode\@ESCcode\expandafter\def\csname#2\endcsname{\L}\else
- \if\EszettCode\@ESCcode\expandafter\def\csname#2\endcsname{\ss}\else
- \expandafter\def\csname#2\endcsname{\undecipherable}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \else
- \expandafter\ifx\expandafter\&#1%
- \expandafter\def\csname#2\endcsname{\&}\else
- \expandafter\ifx\expandafter\%#1%
- \expandafter\def\csname#2\endcsname{\%}\else
- \expandafter\ifx\expandafter\##1%
- \expandafter\def\csname#2\endcsname{\#}\else
- \if\EncodedBlankSpace#1\expandafter\def\csname#2\endcsname{\ }\else
- \expandafter\edef\csname#2\endcsname{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@defineactions}
-% This routine defines how encoded characters are to be treated by the
-% |\ESCrotate| routine, depending on the [encoding, capitalization,
-% blank, symbol, \textit{etc.}] treatments that have
-% been \textit{a priori} specified.
-% \begin{macrocode}
-% \@blankaction AND OTHER ...action'S ARE SET, DEPENDING ON VALUES OF
-% TREATMENT FLAGS. CHARS ARE EITHER ENCODED, DECODED, OR REMOVED.
-\newcommand\@defineactions{%
-% SET UP TREATMENT FOR SPACES, ENCODED SPACES, AND [REENCODED] SYMBOLS
- \if e\EncodingTreatment%
-% ENCODE SPACES, KEEP ENCODED SPACES ENCODED, ENCODE SYMBOLS.
- \edef\@blankaction{\EncodedBlankSpace}%
- \def\@dollaraction{\EncodedDollar}%
- \def\@pipeaction{\EncodedPipe}%
- \def\@uvariaction{\EncodedUvari}%
- \def\@uvariiaction{\EncodedUvarii}%
- \def\@uvariiiaction{\EncodedUvariii}%
- \def\@carataction{\EncodedCarat}%
- \def\@circumflexaction{\EncodedCircumflex}%
- \def\@tildeaction{\EncodedTilde}%
- \def\@umlautaction{\EncodedUmlaut}%
- \def\@graveaction{\EncodedGrave}%
- \def\@acuteaction{\EncodedAcute}%
- \def\@macronaction{\EncodedMacron}%
- \def\@overdotaction{\EncodedOverdot}%
- \def\@breveaction{\EncodedBreve}%
- \def\@caronaction{\EncodedCaron}%
- \def\@doubleacuteaction{\EncodedDoubleAcute}%
- \def\@cedillaaction{\EncodedCedilla}%
- \def\@underdotaction{\EncodedUnderdot}%
- \def\@archjoinaction{\EncodedArchJoin}%
- \def\@lineunderaction{\EncodedLineUnder}%
- \def\@copyrightaction{\EncodedCopyright}%
- \def\@poundsaction{\EncodedPounds}%
- \def\@leftbraceaction{\EncodedLeftBrace}%
- \def\@rightbraceaction{\EncodedRightBrace}%
- \def\@underscoreaction{\EncodedUnderscore}%
- \def\@daggeraction{\EncodedDagger}%
- \def\@doubledaggeraction{\EncodedDoubleDagger}%
- \def\@sectionsymbolaction{\EncodedSectionSymbol}%
- \def\@pilcrowaction{\EncodedPilcrow}%
- \def\@eszettaction{\EncodedEszett}%
- \def\@lbaction{\EncodedLB}%
- \def\@rbaction{\EncodedRB}%
- \if 2\AlphaCapsTreatment%
- \def\@AEscaction{\Encodedaesc}%
- \def\@OEthelaction{\Encodedoethel}%
- \def\@Angstromaction{\Encodedangstrom}%
- \def\@slashedOaction{\EncodedSlashedo}%
- \def\@barredLaction{\EncodedBarredl}%
- \else
- \def\@AEscaction{\EncodedAEsc}%
- \def\@OEthelaction{\EncodedOEthel}%
- \def\@Angstromaction{\EncodedAngstrom}%
- \def\@slashedOaction{\EncodedSlashedO}%
- \def\@barredLaction{\EncodedBarredL}%
- \fi
- \if 2\AlphaTreatment%
- \def\@aescaction{\EncodedAEsc}%
- \def\@oethelaction{\EncodedOEthel}%
- \def\@angstromaction{\EncodedAngstrom}%
- \def\@slashedoaction{\EncodedSlashedO}%
- \def\@barredlaction{\EncodedBarredL}%
- \else
- \def\@aescaction{\Encodedaesc}%
- \def\@oethelaction{\Encodedoethel}%
- \def\@angstromaction{\Encodedangstrom}%
- \def\@slashedoaction{\EncodedSlashedo}%
- \def\@barredlaction{\EncodedBarredl}%
- \fi
- \else
-% EncodingTreatment=v or q:
-% LEAVE SPACES ALONE; RESTORE ENCODED SPACES AND SYMBOLS
- \def\@blankaction{\BlankSpace}%
- \def\@dollaraction{\Dollar}%
- \def\@pipeaction{\Pipe}%
- \def\@uvariaction{\Uvari}%
- \def\@uvariiaction{\Uvarii}%
- \def\@uvariiiaction{\Uvariii}%
- \def\@carataction{\Carat}%
- \def\@circumflexaction{\Circumflex}%
- \def\@tildeaction{\Tilde}%
- \def\@umlautaction{\Umlaut}%
- \def\@graveaction{\Grave}%
- \def\@acuteaction{\Acute}%
- \def\@macronaction{\Macron}%
- \def\@overdotaction{\Overdot}%
- \def\@breveaction{\Breve}%
- \def\@caronaction{\Caron}%
- \def\@doubleacuteaction{\DoubleAcute}%
- \def\@cedillaaction{\Cedilla}%
- \def\@underdotaction{\Underdot}%
- \def\@archjoinaction{\ArchJoin}%
- \def\@lineunderaction{\LineUnder}%
- \def\@copyrightaction{\Copyright}%
- \def\@poundsaction{\Pounds}%
- \def\@leftbraceaction{\LeftBrace}%
- \def\@rightbraceaction{\RightBrace}%
- \def\@underscoreaction{\Underscore}%
- \def\@daggeraction{\Dagger}%
- \def\@doubledaggeraction{\DoubleDagger}%
- \def\@sectionsymbolaction{\SectionSymbol}%
- \def\@pilcrowaction{\Pilcrow}%
- \def\@eszettaction{\Eszett}%
- \def\@lbaction{\UnencodedLB}%
- \def\@rbaction{\UnencodedRB}%
- \if 2\AlphaCapsTreatment%
- \def\@AEscaction{\aesc}%
- \def\@OEthelaction{\oethel}%
- \def\@Angstromaction{\angstrom}%
- \def\@slashedOaction{\Slashedo}%
- \def\@barredLaction{\Barredl}%
- \else
- \def\@AEscaction{\AEsc}%
- \def\@OEthelaction{\OEthel}%
- \def\@Angstromaction{\Angstrom}%
- \def\@slashedOaction{\SlashedO}%
- \def\@barredLaction{\BarredL}%
- \fi
- \if 2\AlphaTreatment%
- \def\@aescaction{\AEsc}%
- \def\@oethelaction{\OEthel}%
- \def\@angstromaction{\Angstrom}%
- \def\@slashedoaction{\SlashedO}%
- \def\@barredlaction{\BarredL}%
- \else
- \def\@aescaction{\aesc}%
- \def\@oethelaction{\oethel}%
- \def\@angstromaction{\angstrom}%
- \def\@slashedoaction{\Slashedo}%
- \def\@barredlaction{\Barredl}%
- \fi
- \fi
-% REMOVE SPACES AND ENCODED SPACES?
- \if 0\BlankTreatment%
- \edef\@blankaction{}%
- \fi
-% REMOVE ENCODED SYMBOLS?
- \if 0\SymbolTreatment%
- \def\@dollaraction{}%
- \def\@pipeaction{}%
- \def\@carataction{}%
- \def\@circumflexaction{}%
- \def\@tildeaction{}%
- \def\@umlautaction{}%
- \def\@graveaction{}%
- \def\@acuteaction{}%
- \def\@macronaction{}%
- \def\@overdotaction{}%
- \def\@breveaction{}%
- \def\@caronaction{}%
- \def\@doubleacuteaction{}%
- \def\@cedillaaction{}%
- \def\@underdotaction{}%
- \def\@archjoinaction{}%
- \def\@lineunderaction{}%
- \def\@copyrightaction{}%
- \def\@poundsaction{}%
- \def\@leftbraceaction{}%
- \def\@rightbraceaction{}%
- \def\@underscoreaction{}%
- \def\@daggeraction{}%
- \def\@doubledaggeraction{}%
- \def\@sectionsymbolaction{}%
- \def\@pilcrowaction{}%
- \def\@lbaction{}%
- \def\@rbaction{}%
- \fi
-% REMOVE ENCODED ALPHACAPS?
- \if 0\AlphaCapsTreatment%
- \def\@AEscaction{}%
- \def\@OEthelaction{}%
- \def\@Angstromaction{}%
- \def\@slashedOaction{}%
- \def\@barredLaction{}%
- \fi
-% REMOVE ENCODED ALPHA?
- \if 0\AlphaTreatment%
- \def\@aescaction{}%
- \def\@oethelaction{}%
- \def\@angstromaction{}%
- \def\@slashedoaction{}%
- \def\@barredlaction{}%
- \def\@eszettaction{}%
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@forcecapson}
-% Force capitalization of strings processed by |\substring| for the
-% time being.
-% \begin{macrocode}
-\newcommand\@forcecapson{%
- \def\AlphaTreatment{2}%
- \def\AlphaCapsTreatment{1}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@relaxcapson}
-% Restore prior treatments following a period of enforced capitalization.
-% \begin{macrocode}
-\newcommand\@relaxcapson{%
- \let\AlphaTreatment\SaveAlphaTreatment%
- \let\AlphaCapsTreatment\SaveAlphaCapsTreatment%
- \@defineactions%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@decodepointer}
-% As pertains to arguments 3 and 4 of |\substring|, this routine
-% implements use of the |$| character to mean END-OF-STRING,
-% and |$-{|\textit{integer}|}| for addressing relative to the
-% END-OF-STRING.
-% \begin{macrocode}
-\newcommand\@decodepointer[2][\value{@stringsize}]{%
- \isnextbyte[q]{$}{#2}%
- \if T\theresult%
- \isnextbyte[q]{-}{\expandafter\@gobble#2}%
- \if T\theresult%
- \setcounter{@@@letterindex}{#1}%
- \@gobblearg{#2}{2}%
- \addtocounter{@@@letterindex}{-\gobbledword}%
- \edef\@fromtoindex{\value{@@@letterindex}}%
- \else
- \edef\@fromtoindex{#1}%
- \fi
- \else
- \edef\@fromtoindex{#2}%
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@getstringlength}
-% Get's string length of |#1|, puts result in counter |#2|.
-% \begin{macrocode}
-\newcommand\@getstringlength[2]{%
- \edef\@@teststring{#1\endofstring}%
- \ifthenelse{\equal{\@@teststring}{\endofstring}}%
- {\setcounter{#2}{0}}%
- {%
- \setcounter{@gobblesize}{1}%
- \whiledo{\value{@gobblesize} < \@MAXSTRINGSIZE}{%
-%
- \@gobblearg{\@@teststring}{1}%
- \edef\@@teststring{\gobbledword}%
- \ifthenelse{\equal{\@@teststring}{\endofstring}}%
- {\setcounter{#2}{\value{@gobblesize}}%
- \setcounter{@gobblesize}{\@MAXSTRINGSIZE}}%
- {\addtocounter{@gobblesize}{1}}%
- }%
- }%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@gobblearg}
-% Gobble first |#2| characters from string |#1|. The
-% result is stored in |\gobbledword|. Two-byte escape sequences,
-% when encountered, count as a single gobble.
-% \begin{macrocode}
-\newcommand\@gobblearg[2]{%
- \setcounter{@letterindex}{0}%
- \setcounter{@gobbleindex}{#2}%
- \edef\gobbledword{#1}%
- \whiledo{\value{@letterindex} < \value{@gobbleindex}}{%
- \isnextbyte[q]{\EscapeChar}{\gobbledword}%
- \if T\theresult%
-% GOBBLE ESCAPE CHARACTER
- \edef\gobbledword{\@DiscardNextChar{\gobbledword}}%
- \fi
-% GOBBLE NORMAL CHARACTER OR ESCAPE CODE
- \edef\gobbledword{\@DiscardNextChar{\gobbledword}}%
- \addtocounter{@letterindex}{1}%
- }%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@DiscardNextChar}
-% Remove the next character from the argument string. Since
-% |\@gobble| skips spaces, the routine must first look for the case of
-% a leading blankspace. If none is found, proceed with a normal
-% |\@gobble|. Note: as per \LaTeX{} convention, |\@DiscardNextChar|
-% treats double/multi-softspaces as single space.
-% \begin{macrocode}
-\newcommand\@DiscardNextChar[1]{%
- \expandafter\if\expandafter\BlankSpace#1\else
- \expandafter\@gobble#1%
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@convertsymboltostring}
-% Routine for converting an encodable symbol (|#3|) into string (|#4|),
-% for every occurance in the given string |#2|.
-% \begin{macrocode}
-\newcommand\@convertsymboltostring[4][v]{%
- \def\@fromcode{#3}%
- \def\@tostring{#4}%
- \def\EncodingTreatment{e}%
- \substring[e]{#2}{1}{\@MAXSTRINGSIZE}%
- \@convertoff%
- \if e#1\else\substring[#1]{\thestring}{1}{\@MAXSTRINGSIZE}\fi%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@convertbytetostring}
-% Routine for converting an plain byte (|#3|) into string (|#4|),
-% for every occurance in the given string |#2|.
-% \begin{macrocode}
-\newcommand\@convertbytetostring[4][v]{%
- \def\@frombyte{#3}%
- \def\@tostring{#4}%
- \def\EncodingTreatment{e}%
- \substring[e]{#2}{1}{\@MAXSTRINGSIZE}%
- \@convertoff%
- \if e#1\else\substring[#1]{\thestring}{1}{\@MAXSTRINGSIZE}\fi%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@treatleadingspaces}
-% This routine will address the leading spaces of string |#2|. If
-% argument |#3| is an 'x' character, those leading spaces will be
-% deleted from the string. Otherwise, those leading spaces will be
-% rotated to the end of the string.
-% \begin{macrocode}
-\newcommand\@treatleadingspaces[3][v]{\+%
- \defaultTreatments%
- \edef\thestring{#2}%
- \@getstringlength{\thestring}{@stringsize}%
- \setcounter{@maxrotation}{\value{@stringsize}}%
- \setcounter{@letterindex}{0}%
- \whiledo{\value{@letterindex} < \value{@maxrotation}}{%
- \addtocounter{@letterindex}{1}%
- \isnextbyte[q]{\EncodedBlankSpace}{\thestring}%
- \if F\theresult\isnextbyte[q]{\BlankSpace}{\thestring}\fi%
- \if T\theresult%
- \isnextbyte[q]{#3}{x}%
- \if F\theresult%
-% NORMAL OR ENCODED BLANK... ROTATE IT
- \edef\thestring{\@rotate{\thestring}}%
- \else
-% NORMAL OR ENCODED BLANK... DELETE IT (IF 3rd ARG=X)
- \@gobblearg{\thestring}{1}%
- \edef\thestring{\gobbledword}%
- \fi
- \else
- \setcounter{@maxrotation}{\value{@letterindex}}%
- \fi
- }\?%
- \substring[#1]{\thestring}{1}{\@MAXSTRINGSIZE}%
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@convertoff}
-% This routine is an initialization routine to
-% guarantee that there is no conversion of |\@frombyte| to |\@tostring|,
-% until further notice. It accomplishes this
-% by setting up such that subsequent |\if\@frombyte| and
-% |\if\@fromcode| clauses will automatically fail.
-% \begin{macrocode}
-\newcommand\@convertoff{\def\@frombyte{xy}\def\@tostring{}%
- \def\@fromcode{xy}}
-\@convertoff
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macro}{\@rotate}
-% The following code is the engine of the string manipulation routine.
-% It is a tree of successive \LaTeX{} commands (each of which is
-% composed of an |\if...| cascade) which have the net
-% effect of rotating the first letter of the string into the last
-% position. Depending on modes set by |\@defineactions| and
-% |\defaultTreatments|, the leading character is either encoded,
-% decoded, or removed in the process.
-% Note: |\@rotate| loses track of double/multi-spaces, per \LaTeX{}
-% convention, unless encoded blanks (|~|) are used.
-% \begin{macrocode}
-\newcommand\@rotate[1]{%
-% CHECK BYTE CONVERSION TEST FIRST
- \if \@frombyte#1\@tostring\else
-% MUST CHECK FOR MULTI-BYTE CHARACTERS NEXT, SO THAT ENCODING CHARACTER
-% ISN'T MISTAKEN FOR A NORMAL CHARACTER LATER IN MACRO.
- \if 0\SymbolTreatment%
- \@removeExpandableSymbols{#1}%
- \else
- \@rotateExpandableSymbols{#1}%
- \fi
- \fi
-}
-
-\newcommand\@rotateExpandableSymbols[1]{%
-% INDIRECT (EXPANDABLE) SYMBOLS
- \expandafter\ifx\expandafter\&#1\&\else
- \expandafter\ifx\expandafter\%#1\%\else
- \expandafter\ifx\expandafter\##1\#\else
- \@rotateBlankSpaces{#1}%
- \fi
- \fi
- \fi
-}
-
-\newcommand\@removeExpandableSymbols[1]{%
-% INDIRECT (EXPANDABLE) SYMBOLS
- \expandafter\ifx\expandafter\&#1\else
- \expandafter\ifx\expandafter\%#1\else
- \expandafter\ifx\expandafter\##1\else
- \@rotateBlankSpaces{#1}%
- \fi
- \fi
- \fi
-}
-
-\newcommand\@rotateBlankSpaces[1]{%
- \expandafter\ifx\expandafter$#1$\else% <---RETAIN GOING INTO/FROM MATH MODE
-% THE FOLLOWING FINDS TILDES, BUT MUST COME AFTER EXPANDABLE SYMBOL
-% SEARCH, OR ELSE IT FINDS THEM TOO, BY MISTAKE.
- \if \EncodedBlankSpace#1\@blankaction\else% <--- FINDS REENCODED TILDE
-% THE FOLLOWING SHOULD FIND TILDES, BUT DOESN'T... THUS, COMMENTED OUT.
-% \expandafter\ifx\expandafter\EncodedBlankSpace#1\@blankaction\else
- \if \BlankSpace#1\@blankaction\else
- \if 2\AlphaTreatment%
- \@chcaseAlpha{#1}%
- \else
- \if 0\AlphaTreatment%
- \@removeAlpha{#1}%
- \else
- \@rotateAlpha{#1}%
- \fi
- \fi
- \fi
-% \fi
- \fi
- \fi
-}
-
-\newcommand\@rotateAlpha[1]{%
-% LOWERCASE
- \if a#1a\else
- \if b#1b\else
- \if c#1c\else
- \if d#1d\else
- \if e#1e\else
- \if f#1f\else
- \if g#1g\else
- \if h#1h\else
- \if i#1i\else
- \if j#1j\else
- \if k#1k\else
- \if l#1l\else
- \if m#1m\else
- \if n#1n\else
- \if o#1o\else
- \if p#1p\else
- \if q#1q\else
- \if r#1r\else
- \if s#1s\else
- \if t#1t\else
- \if u#1u\else
- \if v#1v\else
- \if w#1w\else
- \if x#1x\else
- \if y#1y\else
- \if z#1z\else
- \if 2\AlphaCapsTreatment%
- \@chcaseAlphaCaps{#1}%
- \else
- \if 0\AlphaCapsTreatment%
- \@removeAlphaCaps{#1}%
- \else
- \@rotateAlphaCaps{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@removeAlpha[1]{%
-% LOWERCASE
- \if a#1\else
- \if b#1\else
- \if c#1\else
- \if d#1\else
- \if e#1\else
- \if f#1\else
- \if g#1\else
- \if h#1\else
- \if i#1\else
- \if j#1\else
- \if k#1\else
- \if l#1\else
- \if m#1\else
- \if n#1\else
- \if o#1\else
- \if p#1\else
- \if q#1\else
- \if r#1\else
- \if s#1\else
- \if t#1\else
- \if u#1\else
- \if v#1\else
- \if w#1\else
- \if x#1\else
- \if y#1\else
- \if z#1\else
- \if 2\AlphaCapsTreatment%
- \@chcaseAlphaCaps{#1}%
- \else
- \if 0\AlphaCapsTreatment%
- \@removeAlphaCaps{#1}%
- \else
- \@rotateAlphaCaps{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@chcaseAlpha[1]{%
-% LOWERCASE TO UPPERCASE
- \if a#1A\else
- \if b#1B\else
- \if c#1C\else
- \if d#1D\else
- \if e#1E\else
- \if f#1F\else
- \if g#1G\else
- \if h#1H\else
- \if i#1I\else
- \if j#1J\else
- \if k#1K\else
- \if l#1L\else
- \if m#1M\else
- \if n#1N\else
- \if o#1O\else
- \if p#1P\else
- \if q#1Q\else
- \if r#1R\else
- \if s#1S\else
- \if t#1T\else
- \if u#1U\else
- \if v#1V\else
- \if w#1W\else
- \if x#1X\else
- \if y#1Y\else
- \if z#1Z\else
- \if 2\AlphaCapsTreatment%
- \@chcaseAlphaCaps{#1}%
- \else
- \if 0\AlphaCapsTreatment%
- \@removeAlphaCaps{#1}%
- \else
- \@rotateAlphaCaps{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@rotateAlphaCaps[1]{%
-% UPPERCASE
- \if A#1A\else
- \if B#1B\else
- \if C#1C\else
- \if D#1D\else
- \if E#1E\else
- \if F#1F\else
- \if G#1G\else
- \if H#1H\else
- \if I#1I\else
- \if J#1J\else
- \if K#1K\else
- \if L#1L\else
- \if M#1M\else
- \if N#1N\else
- \if O#1O\else
- \if P#1P\else
- \if Q#1Q\else
- \if R#1R\else
- \if S#1S\else
- \if T#1T\else
- \if U#1U\else
- \if V#1V\else
- \if W#1W\else
- \if X#1X\else
- \if Y#1Y\else
- \if Z#1Z\else
- \if 0\NumeralTreatment%
- \@removeNumerals{#1}%
- \else
- \@rotateNumerals{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@removeAlphaCaps[1]{%
-% UPPERCASE
- \if A#1\else
- \if B#1\else
- \if C#1\else
- \if D#1\else
- \if E#1\else
- \if F#1\else
- \if G#1\else
- \if H#1\else
- \if I#1\else
- \if J#1\else
- \if K#1\else
- \if L#1\else
- \if M#1\else
- \if N#1\else
- \if O#1\else
- \if P#1\else
- \if Q#1\else
- \if R#1\else
- \if S#1\else
- \if T#1\else
- \if U#1\else
- \if V#1\else
- \if W#1\else
- \if X#1\else
- \if Y#1\else
- \if Z#1\else
- \if 0\NumeralTreatment%
- \@removeNumerals{#1}%
- \else
- \@rotateNumerals{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@chcaseAlphaCaps[1]{%
-% UPPERCASE TO LOWERCASE
- \if A#1a\else
- \if B#1b\else
- \if C#1c\else
- \if D#1d\else
- \if E#1e\else
- \if F#1f\else
- \if G#1g\else
- \if H#1h\else
- \if I#1i\else
- \if J#1j\else
- \if K#1k\else
- \if L#1l\else
- \if M#1m\else
- \if N#1n\else
- \if O#1o\else
- \if P#1p\else
- \if Q#1q\else
- \if R#1r\else
- \if S#1s\else
- \if T#1t\else
- \if U#1u\else
- \if V#1v\else
- \if W#1w\else
- \if X#1x\else
- \if Y#1y\else
- \if Z#1z\else
- \if 0\NumeralTreatment%
- \@removeNumerals{#1}%
- \else
- \@rotateNumerals{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@rotateNumerals[1]{%
-% NUMERALS
- \if 1#11\else
- \if 2#12\else
- \if 3#13\else
- \if 4#14\else
- \if 5#15\else
- \if 6#16\else
- \if 7#17\else
- \if 8#18\else
- \if 9#19\else
- \if 0#10\else
- \if 0\PunctuationTreatment%
- \@removePunctuation{#1}%
- \else
- \@rotatePunctuation{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@removeNumerals[1]{%
-% NUMERALS
- \if 1#1\else
- \if 2#1\else
- \if 3#1\else
- \if 4#1\else
- \if 5#1\else
- \if 6#1\else
- \if 7#1\else
- \if 8#1\else
- \if 9#1\else
- \if 0#1\else
- \if 0\PunctuationTreatment%
- \@removePunctuation{#1}%
- \else
- \@rotatePunctuation{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@rotatePunctuation[1]{%
-% PUNCTUATION
- \if ;#1;\else
- \if :#1:\else
- \if '#1'\else
- \if "#1"\else
- \if ,#1,\else
- \if .#1.\else
- \if ?#1?\else
- \if `#1`\else
- \if !#1!\else
- \if 0\SymbolTreatment%
- \@removeDirectSymbols{#1}%
- \else
- \@rotateDirectSymbols{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@removePunctuation[1]{%
-% PUNCTUATION
- \if ;#1\else
- \if :#1\else
- \if '#1\else
- \if "#1\else
- \if ,#1\else
- \if .#1\else
- \if ?#1\else
- \if `#1\else
- \if !#1\else
- \if 0\SymbolTreatment%
- \@removeDirectSymbols{#1}%
- \else
- \@rotateDirectSymbols{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@rotateDirectSymbols[1]{%
-% DIRECT SYMBOLS
- \if /#1/\else
- \if @#1@\else
- \if *#1*\else
- \if (#1(\else
- \if )#1)\else
- \if -#1-\else
- \if _#1_\else
- \if =#1=\else
- \if +#1+\else
- \if [#1[\else
- \if ]#1]\else
- \if ^#1^\else% <--FOR SUPERSCRIPTS, NOT \^
- \if <#1<\else
- \if >#1>\else
- \if |#1|\else
- \if &#1&\else
- \@rotateUndecipherable{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@removeDirectSymbols[1]{%
-% DIRECT SYMBOLS
- \if /#1\else
- \if @#1\else
- \if *#1\else
- \if (#1\else
- \if )#1\else
- \if -#1\else
- \if _#1\else
- \if =#1\else
- \if +#1\else
- \if [#1\else
- \if ]#1\else
- \if ^#1\else% <--FOR SUPERSCRIPTS, NOT \^
- \if <#1\else
- \if >#1\else
- \if |#1\else
- \if &#1\else
- \@rotateUndecipherable{#1}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
-}
-
-\newcommand\@rotateUndecipherable[1]{%
-% REPLACE UNDECIPHERABLE SYMBOL WITH A TOKEN CHARACTER (DEFAULT .)
- \expandafter\@gobble#1\undecipherable%
-% DONE... CLOSE UP SHOP
-}
-% \end{macrocode}
-% \end{macro}
-
-% \begin{macrocode}
-\catcode`\&=4
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%</package>
-% \end{macrocode}
-%
-% \Finale
-\endinput
-%
-% End of file `stringstrings.dtx'.
+% \iffalse
+%<package>\ProvidesPackage{stringstrings}
+%<package>[2020/12/08 v1.24
+%<package> Extensive array of string manipulation routines for
+%<package> cosmetic and programming application]
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<*driver>
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Steven B. Segletes.
+%
+% v1.00 -Initial Release
+% v1.01 -Included support for & character, though it loses catcode 4
+% status
+% v1.02 -Bug fix. Needed some % chars in \convertchar to avoid extra spaces
+% v1.03 -Documentation fix; notably removed 's' from \narg in \getargs
+% v1.04 -Removed \rotate command, as it conflicts with environment in
+% \usepackage{rotating}
+% v1.10 -Fixed bug in convertword by adding @@@stringsize definition to
+% \whereisword
+% -Added suite of routines to support \capitalizetitle functionality
+% v1.20 -Added ability to encode/decode arbitrary tokens
+% v1.21 -Added %, removing extra space (bug) from \whereisword
+% v1.22 -Added %, removing extra space (bug) from \getargs
+% v1.23 -Changed {~} to {\ } in \retokenizechar
+% -Forced all stringtest commands to function outside of math mode
+% which will give correct result, when invoked within math mode.
+% V1.24 -Added %, removing extra space (bug) from \testmatchingchar
+\documentclass{ltxdoc}
+\usepackage{stringstrings}
+\DisableCrossrefs
+\CodelineNumbered
+% DEFINE SOME CAMMANDS THAT ARE EASIER HERE THAN IN DocInput ENVIRONMENT
+\newcommand\stringstrings{\textsf{stringstrings}~}
+\newcommand\coolstr{\textsf{coolstr}~}
+% ITALICIZED i.e.,
+\newcommand{\ie}{\textit{i.e.},~}%
+% ITALICIZED e.g.,
+\newcommand{\eg}{\textit{e.g.},~}%
+% ITALICIZED etc.
+\newcommand{\etc}{\textit{etc}.}%
+\def\modetablelayout{|l|c|c|c|}
+\def\mylayout{@{}c|c|l@{}}
+\stringencode{\|}
+\stringdecode[q]{\thestring}
+\edef\mypipe{\thestring}
+\stringencode{\carat}
+\stringdecode[q]{\thestring}
+\edef\mycarat{\thestring}
+
+\GetFileInfo{stringstrings.sty}
+\begin{document}
+ \title{The \stringstrings Package\\
+ \rule{0em}{0.7em}\small\fileinfo}
+ \author{Steven B. Segletes\\
+ steven.b.segletes.civ@mail.mil}
+ \date{\filedate\\
+ \fileversion}
+ \maketitle
+ \DocInput{stringstrings.dtx}
+\end{document}
+%</driver>
+%\fi
+% \parskip 1ex
+% \begin{abstract}
+% The \stringstrings package provides a large and sundry array of routines
+% for the manipulation of strings. The routines are developed not only
+% for cosmetic application, such as the changing of letter
+% cases, selective removal of character classes, and string
+% substitution,
+% but also for programming application, such as character look-ahead
+% applications, argument parsing, |\if|-tests for various string
+% conditions, etc. A key tenet employed during the
+% development of this package (unlike, for comparison, the |\uppercase|
+% and |\lowercase| routines) was to have resultant strings be
+% ``expanded'' (\ie the product of an |\edef|), so that the
+% \stringstrings routines could be strung together sequentially and
+% nested (after a fashion) to achieve very complex manipulations.
+%
+% \end{abstract}
+%
+% \vspace{-.55em}
+% \tableofcontents\rule[.2em]{4.5in}{.3mm}\vspace{-1.5em}
+%
+% \section {Motivation}
+%
+% There were two seminal moments that brought about my motivation to
+% develop this package. The first was the realization of the oft
+% cited and infamous \LaTeX{} limitation concerning the inability to
+% nest letter-case changes with \LaTeX{}'s intrinsic |\uppercase| and
+% |\lowercase| routines. The second,
+% though not diminishing its utility in many useful applications, was
+% the inherent limitations of the \coolstr package, which is otherwise
+% a useful tool for extracting substrings and measuring string lengths.
+%
+% The former is well documented and need not be delved into in great
+% detail. Basically, as it was explained to me, |\uppercase| and
+% |\lowercase| are expanded by \LaTeX{} at the last possible moment, and
+% thus attempts to capture their result for subsequent use are doomed to
+% failure. One is forced to adopt the left-to-right (rather than
+% nested) approach to case changes.
+%
+% In the case of the \coolstr package, I again want to express
+% my admiration for the utility of this package. I briefly considered
+% building the \stringstrings package around it, but it proved
+% unworkable, because of some intrinsic limitations.
+% First, \coolstr operates on
+% strings, not tokens, and so in order to fool it into working on
+% tokenized inputs, one must use the cumbersome nomenclature of
+%
+% |\expandafter\substr\expandafter{\TokenizedString}{...}{...}|
+% \vspace{1ex}\\%
+% in order to, for example grab a substring of |\TokenizedString|. One
+% may |\def| the result of this subroutine, and use it elsewhere in an
+% unaltered state. However, one may not expand, via |\edef|, the
+% result of |\substr| in order to use it as input to a subsequent string
+% manipulation. And thus, the desire to engage in successive string
+% manipulations of different natures (\eg capitalization of leading
+% characters, extraction of words, reversal of character sequence,
+% removal of character classes, etc., etc.) are not achievable in the
+% context of \textsf{coolstr}.
+%
+% It was this state of affairs that brought me to hunger for routines
+% that could thoroughly manipulate strings, and yet produce their result
+% ``in the clear'' (\ie in an untokenized form) which could be used as
+% input for the next manipulation. It turns out the heart of the
+% \stringstrings package which achieves this goal is based on the simple
+% (if much maligned) |\if| construct of \LaTeX{}, by using successive
+% iterations of the following construct:
+%
+% |\if <|\textit{test char.}|><|\textit{string}|><|\textit{manipulated
+% test char.}|>\else ...\fi|
+% \vspace{1ex}\\%
+% in which a character at the begining of a string is tested. If a
+% match is found,
+% the manipulated test character is replaced at the end of the string,
+% while the original test character is lopped off from the beginning of
+% the string. A false result is used to proceed to a different test
+% character. In this manner, the string may be rotated through,
+% character by character, performing the desired manipulations. And,
+% most importantly, the product of this operation may be placed into an
+% |\edef|.
+%
+% It turns out there was one glitch to this process (which has been
+% successfully remedied in the \stringstrings package). And that is that
+% there are several tokenized \LaTeX{} symbols (\eg |\$|, |\{|, |\}|,
+% |\AE|, |\oe|, etc.) which expand to more than a single byte. If
+% I was more savvy on \LaTeX{} constructs, I would probably have known
+% how to handle this better. But my solution was to develop my own
+% encoding scheme wherein these problematic characters were re-encoded
+% in my intermediate calculations as a 2-byte (escape character-escape code)
+% combination, and only converted back into \LaTeX{} symbols at the last
+% moment, as the finalized strings were handed back to the user.
+%
+% There are also several tokens, like |\dag|, |\ddag|, |\P|, |\d|, |\t|,
+% |\b|, and |\copyright| which
+% can not be put into an |\edef| construct. The solution developed for
+% strings containing these such characters was to convert the encoded
+% string not into an expanded |\edef| construct, but rather back into a
+% tokenized form amenable to |\def|. The |\retokenize| command
+% accomplishes this task and several others.
+%
+% There was also one glitch that I have not yet been able to resolve
+% to my full satisfaction, though I have provided a workaround.
+% And that is the occurance of \LaTeX{} grouping characters, |{| and
+% |}|, that might typically occur in math mode. The problem is that the
+% character-rotate technique that is the core of \stringstrings breaks
+% when rotating these group characters. Why?? Because a string
+% comprised of |...{...}...|, during the rotation process, will
+% eventually become |...}......{| during an intermediate stage of
+% character rotation. This
+% latter string breaks \LaTeX{} because it is not a properly constructed
+% grouping, even if subsequent rotations would intend to bring it back
+% into a proper construction.
+%
+% And so, while \stringstrings can handle certain math-mode
+% constructs (\eg |$|, |^|, and |_|), it is unable to {\it directly}
+% handle groupings that are brought about by the use of curly braces.
+% Note that |\{| and |\}| are handled just fine, but not |{| and |}|.
+% As a result of this limitation regarding the use of grouping braces
+% within strings, \stringstrings support for various math symbols
+% remains quite limited.
+%
+% While it is also common to use curly braces to
+% delimit the arguments of diacritcal marks in words like
+% |m\"{u}de| \etc, the same result can be achieved without the
+% use of braces as |m\"ude|, with the proper result obtained: m\"ude.
+% For diacritical marks that have an alphabetic token such as the breve,
+% given by |\u|, the curly braces can also be omitted, with the only
+% change being a space required after the |\u| to delimit the token.
+% Thus, |c\u at| becomes c\u at. Therefore, when manipulating strings
+% containing diacritical marks, it is best to formulate them, if
+% possible, without the use of curly braces.
+%
+% The workaround fix I have developed, to provide grouping functions
+% within \stringstrings arguments, involves the use of newly defined
+% tokens |\LB| and |\RB| (to be used in lieu of |{| and |}|),
+% along with a command |\retokenize|. This
+% workaround will be described subsequently, in the Disclaimers section.
+%
+% \section{Philosophy of Operation}
+%
+% There are several classes of commands that have been developed as part
+% of the \stringstrings package. In addition to {\bf Configuration
+% Commands}, which set parameters for subsequent string operations,
+% there are the following command classes:
+% \begin{itemize}
+% \item {\bf Commands to Manipulate Strings} -- these commands take an
+% input string or token and perform a specific manipulation on the
+% string;
+% \item {\bf Commands to Extract String Information} -- these commands
+% take an input string or token, and ascertain a particular
+% characteristic of the string; and
+% \item {\bf Commands to Test Strings} -- these commands take an input
+% string or token and test for a particular alphanumeric condition.
+% \end{itemize}
+% Of course, there are also {\bf Support Commands} which are low-level
+% routines which provide functionality to the package, which are
+% generally not accessible to the user.
+%
+% To support the intended philosophy that the user may achieve a complex
+% string manipulation though a series of simpler manipulations (which
+% is otherwise known as nesting), a mechanism had to be developed. True
+% command nesting of the form |\commandA{\commandB{\commandC{string}}}|
+% is {\bf not} supported by the \stringstrings package, since many of
+% the manipulation commands make use of (and would thus inadvertantly
+% overwrite) the same sets of variables used by other routines.
+% Furthermore, there is that 'ol left-to-right philosophy of \LaTeX{} to
+% contend with.
+%
+% Instead, for the case of commands that manipulate strings, the expanded
+% (\ie |\edef|'ed) result of the manipulation is placed into a string
+% called |\thestring|\DescribeMacro{\thestring}. Then, |\thestring|
+% may either be directly used
+% as the input to a subsequent operation, or |\edef|'ed into another
+% variable to save it for future use.
+%
+% String manipulation commands use an optional first argument to specify
+% what to do with the manipulated string (in addition to putting it in
+% |\thestring|). Most string manipulation
+% commands default to verbose mode |[v]|\DescribeMacro{[v]}, and print
+% out their result immediately on the assumption that a simple string
+% manipulation is, many times, all that is required. If the user wishes
+% to use the manipulated result as is, but needs to use it later in the
+% document, a quiet mode |[q]| \DescribeMacro{[q]} is provided which
+% suppresses the immediate output of |\thestring|.
+%
+% In the absence of symbol tokens (\eg |\$|, |\&|, |\oe|, |\^|, \etc),
+% the verbose and quiet modes would prove sufficient. However, when a
+% tokenized symbol is |\edef|'ed, the token is expanded to the actual
+% symbolic representation of the character. If this expanded symbol is
+% used as part of an input string to a
+% subsequent \stringstrings manipulation
+% routine, it gets confused, because the means to detect the token are
+% characteristically different than the means to detect the expanded
+% symbol. Thus, if one wishes to use |\thestring| as an input to a
+% subsequent manipulation routine, \stringstrings provides an encoded
+% mode |[e]| \DescribeMacro{[e]} which places an encoded version of the
+% resulting manipulation into
+% |\thestring|. The encoded mode is also a quiet mode, since it leaves
+% |\thestring| in a visually unappealing state that is intended for
+% subsequent manipulation.
+%
+% The encoded mode is not a \LaTeX{} standard,
+% but was developed for this application. And therefore, if the result
+% of a \stringstrings manipulation is needed as input for a routine
+% outside of the \stringstrings package, the encoded mode will be of no
+% use. For this reason (and others),
+% the |\retokenize| \DescribeMacro{\retokenize}
+% command is provided. Its use is one of only three times that a
+% \stringstrings command
+% returns a tokenized |\def|'ed string in |\thestring|, rather than an
+% expanded, |\edef|'ed string. And in the other two cases, both
+% call upon |\retokenize|.
+%
+% In addition to providing tokenized strings that can be passed to other
+% \LaTeX{} packages, |\retokenize| can also remedy \stringstrings problems
+% associated with inadequate character encodings (OT1) and the use of
+% grouping characters |{| and |}| within \stringstrings arguments. This
+% issue is discussed more fully in the Disclaimers section, and in the
+% actual |\retokenize| command description.
+%
+% Therefore, for complex multistage string manipulations, the
+% recommended procedure
+% is to perform each stage of the manipulation in encoded |[e]| mode,
+% passing along |\thestring| to each subsequent stage of the
+% manipulation, until the very last manipulation, which should be,
+% at the last, performed in verbose |[v]| or quiet |[q]| modes. If
+% the resulting manipulation is to be passed to a command outside of the
+% \stringstrings package for further manipulation (or if the string
+% contains characters which cannot be placed into an |\edef|),
+% |\thestring| may
+% need to be |\retokenize|'ed. If concatenations of two (or more) different
+% manipulations are to be used as input to a third manipulation,
+% |\thestring| from the first manipulation will need to be immediately
+% |\edef|'ed into a different variable, since |\thestring| will be
+% overwritten by the second manipulation (see Table~\ref{tbl:modes}
+% for summary).
+% \begin{table}[h]
+% \begin{center}
+% \caption{\bf Execution Modes of \stringstrings Commands
+% \label{tbl:modes}}\vspace{0.5em}
+% \small
+% \begin{tabular}\modetablelayout
+% \hline
+% Mode & Coding & Use when result is & |\thestring| is\\
+% \hline
+% \hline
+% |[v]| verbose & decoded or retokenized & final & echoed \\
+% |[q]| quiet & decoded or retokenized & final & not echoed \\
+% |[e]| encoded & encoded & intermediate & not echoed \\
+% \hline
+% \end{tabular}
+% \end{center}
+% \end{table}
+%
+% Moving on to commands that extract string information, this class of
+% commands (unless otherwise noted) output their result into a token
+% which is given the name |\theresult|\DescribeMacro{\theresult}.
+% This token does not contain a manipulated form of the string, but
+% rather a piece of information about the string, such as ``how many
+% characters are in the string?'', ``how many words are in the string?'',
+% ``how many letter `e's are in the string?'', \etc
+%
+% The final class of \stringstrings commands are the string-test
+% commands. While some of this class of commands also store their
+% test result in |\theresult|, most of these commands use the
+% |\test|{\it condition}|{|{\it string}|}| |\if|{\it
+% condition} constructs (see {\sf ifthen} package) to answer true/false
+% questions like ``is the string composed entirely of lowercase
+% characters?'', ``is the string's first letter capitalized?'' \etc
+%
+% \section {Configuration Commands}
+%
+% \noindent%
+% |\Treatments{|{\it U-mode}|}{|{\it l-mode}|}{|{\it p-mode}|}{|{\it%
+% n-mode}|}{|{\it s-mode}|}{|{\it b-mode}|}|\\
+% |\defaultTreatments|\\
+% |\encodetoken[|{\it index}|]{|{\it token}|}|\\
+% |\decodetoken[|{\it index}|]{|{\it token}|}|\\
+% |\+|\\
+% |\?|
+%
+% The command |\Treatments| \DescribeMacro{\Treatments}
+% is used to define how different classes of
+% characters are to be treated by the command |\substring|, which is the
+% brains of the \stringstrings package. As will be explained in the
+% next section, most string manipulation routines end up calling
+% |\substring|, the difference between them being a matter of how these
+% character treatments are set prior to the call.
+% Because most string manipulation
+% commands will set the treatments as necessary to perform their given
+% task, and reset them to the default upon conclusion, one should set
+% the |\Treatments| immediately prior to the call upon |\substring|.
+%
+% |\Treatments| has six arguments, that define the mode of treatment
+% for the six classes of characters that \stringstrings has designated.
+% All modes are one-digit integers. They are described below:
+% \begin{itemize}
+% \item{\it U-mode---} This mode defines the
+% treatment for the upper-case characters (A--Z, \OE, \AE, \AA, \O, and
+% \L).
+% A mode of 0 tells |\substring| to remove upper-case characters, a
+% mode of 1 indicates to leave upper-case characters alone, and
+% a mode of 2 indicates to change the case of upper-case
+% characters to lower case.
+%
+% \item {\it l-mode---} This mode defines the
+% treatment for the lower-case characters (a--z, \oe, \ae, \aa, \o, \l,
+% and \ss).
+% A mode of 0 tells |\substring| to remove lower-case characters, a
+% mode of 1 indicates to leave lower-case characters alone, and
+% a mode of 2 indicates to change the case of lower-case
+% characters to upper case. In the case of the eszett character (\ss),
+% there is no uppercase equivalent, and so an {\it l-mode} of 2 will
+% leave the eszett unchanged.
+%
+% \item {\it p-mode---} This mode defines the
+% treatment for the punctuation characters. \stringstrings
+% defines the punctuation characters as ; : ' " , . ? ` and ! A mode of
+% 0 tells |\substring| to remove punctuation characters, while a mode of
+% 1 indicates to leave punctuation characters as is.
+%
+% \item {\it n-mode---} This mode defines the
+% treatment for the numerals (0--9). A mode of
+% 0 tells |\substring| to remove numerals, while a mode of
+% 1 indicates to leave numerals as is.
+%
+% \item {\it s-mode---} This mode defines the
+% treatment for the symbols. \stringstrings
+% defines symbols as the following characters and diacritical marks:
+% \substring{/ * ( ) - = + [ ] $<$ $>$}{1}{$} \& |\& \% \# \{ \} \_ \$|
+% \dag~\ddag~\S~\P~\L~\pounds~\copyright~\v x \^x \~x \"x \`x \'x \=x
+% \.x \u x \v x
+% \H x \c x \d x \t{xx} \b x as well as |@|, math and text carats,
+% and the pipe symbol. A mode of
+% 0 tells |\substring| to remove symbols, while a mode of
+% 1 indicates to leave symbols as is. Note that the \$ symbol, when
+% used for entering and exiting math mode, is left intact, regardless of
+% {\it s-mode}.
+%
+% % \item {\it b-mode---} This mode defines the
+% treatment for blankspaces. A mode of
+% 0 tells |\substring| to remove blankspaces, while a mode of
+% 1 indicates to leave blankspaces as is. The treatment apples to both
+% soft (~) as well as hard (|~|) spaces.
+% \end{itemize}
+%
+% The command |\defaultTreatments| \DescribeMacro{\defaultTreatments}
+% resets all treatment modes to their default settings, which are to
+% leave individual characters unaltered by a string manipulation.
+%
+% The commands |\encodetoken| \DescribeMacro{\encodetoken} and
+% |\decodetoken| \DescribeMacro{\decodetoken} have been introduced in
+% \stringstrings v1.20. Prior to this version, the ability of
+% \stringstrings to handle a particular token was dependent on whether
+% provisions for encoding that token had been explicitly hardwired into
+% the \stringstrings package. A large number of alphabetic and
+% diacritical marks had reserved encodings set aside in \stringstrings
+% for their treatment (see next paragraph or Table 2 for their enumeration).
+% However, requests would invariable come in for treating yet another
+% token, which required a new \stringstrings release for each revision.
+% The command |\encodetoken| allows the user to specify an arbitrary
+% token, to be assigned to the reserved encoding slot associated with the
+% index (permissible indices are in the range 1--3, 1 being the default).
+% Once assigned an encoding slot, a token may be successfully manipulated in
+% \stringstrings routines. Once \stringstrings manipulation is
+% complete, the token must undergo a |\decodetoken| operation in order
+% for that token to be reset to a normal \LaTeX{} token again (lest it
+% display in its encoded \stringstrings form).
+%
+% The commands |\+| and |\?| \DescribeMacro{\+}\DescribeMacro{\?}
+% are a pair that work in tandem to turn on \stringstrings encoding and
+% turn off \stringstrings encoding, respectively. Generally, the user
+% will not need these commands unless he is writing his own routines to
+% take advantage of the \stringstrings library. After |\+| is called,
+% tokens which would otherwise expand to multi-byte sequences are
+% instead encoded according to the \stringstrings methodology. The
+% affected tokens
+% include
+% |\$ \^ \" \{ \} \_ \dag \ddag \P \S \ss \AA \aa \O \o \AE \ae|
+% |\OE|, |\oe|, |\~|, |\`|, |\'|, |\=|, |\.|, |\u|, |\v|, |\H|, |\c|,
+% |\d|, |\t|, |\b|, |\copyright|, |\pounds|, |\L|, |\l|, and |\ss|. In
+% addition, pipes, text carats, and hard spaces (|~|) are encoded
+% as well. The command |\?| restores the
+% standard \LaTeX{} encoding for these tokens.
+%
+% \section {Commands to Manipulate Strings}
+%
+% These commands take an
+% input string or token and perform a specific manipulation on the
+% string. They include:
+%
+% \noindent|\substring[|{\it mode}|]{|{\it
+% string}|}{|{\it min}|}{|{\it max}|}|\\
+% |\caseupper[|{\it mode}|]{|{\it string}|}|\\
+% |\caselower[|{\it mode}|]{|{\it string}|}|\\
+% |\solelyuppercase[|{\it mode}|]{|{\it string}|}|\\
+% |\solelylowercase[|{\it mode}|]{|{\it string}|}|\\
+% |\changecase[|{\it mode}|]{|{\it string}|}|\\
+% |\noblanks[|{\it mode}|]{|{\it string}|}|\\
+% |\nosymbolsnumerals[|{\it mode}|]{|{\it string}|}|\\
+% |\alphabetic[|{\it mode}|]{|{\it string}|}|\\
+% |\capitalize[|{\it mode}|]{|{\it string}|}|\\
+% |\capitalizewords[|{\it mode}|]{|{\it string}|}|\\
+% |\capitalizetitle[|{\it mode}|]{|{\it string}|}|\\
+% |\addlcword{|{\it word}|}|\\
+% |\addlcwords{|{\it word1 word2 word3 \ldots}|}|\\
+% |\resetlcwords|\\
+% |\reversestring[|{\it mode}|]{|{\it string}|}|\\
+% |\convertchar[|{\it mode}|]{|{\it
+% string}|}{|{\it from-char}|}{|{\it to-string}|}|\\
+% |\convertword[|{\it mode}|]{|{\it
+% string}|}{|{\it from-string}|}{|{\it to-string}|}|\\
+% |\rotateword[|{\it mode}|]{|{\it string}|}|\\
+% |\removeword[|{\it mode}|]{|{\it string}|}|\\
+% |\getnextword[|{\it mode}|]{|{\it string}|}|\\
+% |\getaword[|{\it mode}|]{|{\it string}|}{|{\it n}|}|\\
+% |\rotateleadingspaces[|{\it mode}|]{|{\it string}|}|\\
+% |\removeleadingspaces[|{\it mode}|]{|{\it string}|}|\\
+% |\stringencode[|{\it mode}|]{|{\it string}|}|\\
+% |\stringdecode[|{\it mode}|]{|{\it string}|}|\\
+% |\gobblechar[|{\it mode}|]{|{\it string}|}|\\
+% |\gobblechars[|{\it mode}|]{|{\it string}|}{|{\it n}|}|\\
+% |\retokenize[|{\it mode}|]{|{\it string}|}|
+%
+% \noindent
+% Unless otherwise noted, the {\it mode} may take one of three values:
+% |[v]| for verbose mode (generally, the default), |[q]| for quiet mode,
+% and |[e]| for encoded mode. In all cases, the result of
+% the operation is stored in |\thestring|. In verbose mode, it is also
+% output immediately (and may be captured by an |\edef|). In quiet mode,
+% no string is output, though the result still resides in |\thestring|.
+% Encoded mode is also a quiet mode. However, the encoded mode saves
+% the string with its \stringstrings encodings. Encoded mode indicates
+% that the result is an intermediate result which will be subsequently
+% used as input to another \stringstrings manipulation.
+%
+% The command |\substring| \DescribeMacro{\substring} is the brains of
+% the \stringstrings package, in that most of the commands in this
+% section call upon |\substring| in one form or another. Nominally, the
+% routine returns a substring of {\it string} between the characters
+% defined by the integers {\it min} and {\it max}, inclusive.
+% However, the returned substring is
+% affected by the designated |\Treatments| which have been defined
+% for various classes of characters. Additionally, a shorthand of \$
+% may be used in {\it min} and {\it max} to define END-OF-STRING, and
+% the shorthand \$--{\it integer} may be used to define an offset of
+% {\it integer} relative to the END-OF-STRING.
+%
+% Regardless of how many bytes a \LaTeX{} token otherwise expands
+% to, or how many characters are in the token name, each \LaTeX{}
+% symbol token
+% counts as a single character for the purposes of defining the
+% substring limits, {\it min} and {\it max}.
+%
+% While the combination of |\Treatments| and |\substring| are sufficient
+% to achieve a wide array of character manipulations, many of those
+% possibilities are useful enough that separate commands have been
+% created to describe them, for convenience. Several of the commands
+% that follow fall into this category.
+%
+% The command |\caseupper| \DescribeMacro{\caseupper} takes the input
+% string or token, and converts all lowercase characters in the string
+% to uppercase. All other character classes are left untouched.
+% Default mode is |[v]|.
+%
+% The command |\caselower| \DescribeMacro{\caselower} takes the input
+% string or token, and converts all uppercase characters in the string
+% to lowercase. All other character classes are left untouched.
+% Default mode is |[v]|.
+%
+% The command |\solelyuppercase| \DescribeMacro{\solelyuppercase} is
+% similar to |\caseupper|, except that all punctuation, numerals, and
+% symbols are discarded from the string. Blankspaces are left alone,
+% and lowercase characters are converted to uppercase.
+% Default mode is |[v]|.
+%
+% The command |\solelylowercase| \DescribeMacro{\solelylowercase} is
+% similar to |\caselower|, except that all punctuation, numerals, and
+% symbols are discarded from the string. Blankspaces are left alone,
+% and uppercase characters are converted to lowercase.
+% Default mode is |[v]|.
+%
+% The command |\changecase| \DescribeMacro{\changecase} switches lower
+% case to upper case and upper case to lower case. All other characters
+% are left unchanged.
+% Default mode is |[v]|.
+%
+% The command |\noblanks| \DescribeMacro{\noblanks} removes blankspaces
+% (both hard and soft) from
+% a string, while leaving other characters unchanged.
+% Default mode is |[v]|.
+%
+% The command |\nosymbolsnumerals| \DescribeMacro{\nosymbolsnumerals}
+% removes symbols and numerals from
+% a string, while leaving other characters unchanged.
+% Default mode is |[v]|.
+%
+% The command |\alphabetic| \DescribeMacro{\alphabetic} discards
+% punctuation, symbols, and numerals, while retaining alphabetic
+% characters and blankspaces.
+% Default mode is |[v]|.
+%
+% The command |\capitalize| \DescribeMacro{\capitalize} turns the first
+% character of {\it string} into its upper case, if it is alphabetic.
+% Otherwise, that character will remain unaltered.
+% Default mode is |[v]|.
+%
+% The command |\capitalizewords| \DescribeMacro{\capitalizewords} turns
+% the first character of every word in {\it string} into its upper
+% case, if it is alphabetic.
+% Otherwise, that character will remain unaltered. For the purposes of
+% this command, ``the first character of a word'' is defined as either
+% the first character of the string, or the first non-blank
+% character that follows one or more blankspaces.
+% Default mode is |[v]|.
+%
+% The command |\capitalizetitle| \DescribeMacro{\capitalizetitle} is a
+% command similar to |\capitalizewords|, except that words which have
+% been previously designated as ``lower-case words'' are not
+% capitalized (\eg prepositions, conjunctions, \etc). In all cases,
+% the first word of the string is
+% capitalized, even if it is on the lower-case word list. Words are
+% added to the lower-case word list with the commands
+% |\addlcword|\DescribeMacro{\addlcword}, in the case of a single word,
+% or with |\addlcwords|\DescribeMacro{\addlcwords}, in the case of
+% multiple (space-separated) words. Because the addition of many words
+% to the lower-case list can substantially slow-down the execution of
+% the |\capitalizetitle| command, the command
+% |\resetlcwords| \DescribeMacro{\resetlcwords} has been added to
+% allow the user to zero out the lower-case word list.
+% (See newer \textsf{titlecaps} package as an alternative to this
+% command.)
+%
+% The command |\reversestring| \DescribeMacro{\reversestring} reverses
+% the sequence of characters in a string, such that what started as
+% the first character becomes the last character in the manipulated
+% string, and what started as the last character becomes the
+% first character.
+% Default mode is |[v]|.
+%
+% The command |\convertchar| \DescribeMacro{\convertchar} is a substitution
+% command in which a specified match character in the original string
+% ({\it from-char}) is substituted with a different string ({\it
+% to-string}). All occurances of {\it from-char} in the original
+% string are replaced. The {\it from-char} can only be a single
+% character (or tokenized symbol), whereas {\it to-string} can range
+% from the null-string (\ie character removal) to a single character
+% (\ie character substitution)
+% to a complete multi-character string.
+% Default mode is |[v]|.
+%
+% The command |\convertword| \DescribeMacro{\convertword} is a substitution
+% command in which a specified match string in the original string
+% ({\it from-string}) is substituted with a different string ({\it
+% to-string}). All occurances of {\it from-string} in the original
+% string are replaced. If {\it from-string} includes spaces, use
+% hard-space |(~)| characters instead of blanks.
+% Default mode is |[v]|.
+%
+% The command |\rotateword| \DescribeMacro{\rotateword} takes the first
+% word of {\it string} (and its leading and trailing spaces)
+% and rotates them to the end of the string.
+% Care must be taken to have a blankspace at the beginning or end
+% of {\it string} if one wishes to retain a blankspace word
+% separator between the original last word of the string and the
+% original first word which has been rotated to the end of the string.
+% Default mode is |[v]|.
+%
+% The command |\removeword| \DescribeMacro{\removeword} removes the
+% first word of {\it string}, along with any of its leading and trailing
+% spaces.
+% Default mode is |[v]|.
+%
+% The command |\getnextword| \DescribeMacro{\getnextword} returns the
+% next word of {\it string}. In this case, ``word'' is a sequence of
+% characters delimited either by spaces or by the beginning or end
+% of the string.
+% Default mode is |[v]|.
+%
+% The command |\getaword| \DescribeMacro{\getaword} returns a
+% word of {\it string} defined by the index, {\it n}.
+% In this case, ``word'' is a sequence of
+% characters delimited either by spaces or by the first or last
+% characters of the string. If the index, {\it n}, requested exceeds the
+% number of words available in the string, the index wraps around back
+% to the first argument of the string, such that asking for the tenth word
+% of an eight word string will return the second word of the string.
+% Default mode is |[v]|.
+%
+% The command |\rotateleadingspaces|
+% \DescribeMacro{\rotateleadingspaces} takes any leading spaces of the
+% string and rotates them to the end of the string.
+% Default mode is |[v]|.
+%
+% The command |\removeleadingspaces|
+% \DescribeMacro{\removeleadingspaces} removes any leading spaces of the
+% string.
+% Default mode is |[v]|.
+%
+% The command |\stringencode| \DescribeMacro{\stringencode} returns a
+% copy of the string that has been encoded according to the
+% \stringstrings encoding scheme. Because an encoded string is an
+% intermediate result, the default mode for this command is |[e]|.
+%
+% The command |\stringdecode| \DescribeMacro{\stringdecode} returns a
+% copy of the string that has been decoded.
+% Default mode is |[v]|.
+%
+% The command |\gobblechar| \DescribeMacro{\gobblechar} returns a string
+% in which the first character of {\it string} has been removed. Unlike
+% the \LaTeX{} system command |\@gobble| which removes the next {\bf
+% byte} in
+% the input stream, |\gobblechar| not only takes an argument as the
+% target of its gobble, but also removes one {\bf character}, regardless
+% of whether that character is a single-byte or multi-byte character.
+% Because this command may have utility outside of the \stringstrings
+% environment, the result of this command is retokenized (\ie |def|'ed)
+% rather than expanded (\ie |edef|'ed).
+% Default mode is |[q]|. Mode |[e]| is not recognized.
+%
+% The command |\gobblechars| \DescribeMacro{\gobblechars} returns a string
+% in which the first {\it n} characters of {\it string} have been removed.
+% Like |\gobblechar|, |\gobblechars| removes characters, regardless
+% of whether those characters are single-byte or multi-byte characters.
+% Likewise, the result of this command is retokenized (\ie |def|'ed)
+% rather than expanded (\ie |edef|'ed).
+% Default mode is |[q]|. Mode |[e]| is not recognized.
+%
+% The command |\retokenize| \DescribeMacro{\retokenize} takes a string
+% that is encoded according to the \stringstrings encoding scheme, and
+% repopulates the encoded characters with their \LaTeX{} tokens. This
+% command is particularly useful for exporting a string to a routine
+% outside of the \stringstrings library or if the string includes
+% the following
+% characters: |\{|, |\}|, \verb,\|,, |\dag|, |\ddag|, |\d|, |\t|, |\b|,
+% |\copyright|, and |\P|.
+% Default mode is |[q]|. Mode |[e]| is not recognized.
+%
+% \section {Commands to Extract String Information}
+%
+% These commands
+% take an input string or token, and ascertain a particular
+% characteristic of the string. They include:
+%
+% \noindent|\stringlength[|{\it mode}|]{|{\it string}|}|\\
+% |\findchars[|{\it mode}|]{|{\it string}|}{|{\it match-char}|}|\\
+% |\findwords[|{\it mode}|]{|{\it string}|}{|{\it match-string}|}|\\
+% |\whereischar[|{\it mode}|]{|{\it string}|}{|{\it match-char}|}|\\
+% |\whereisword[|{\it mode}|]{|{\it string}|}{|{\it match-string}|}|\\
+% |\wordcount[|{\it mode}|]{|{\it string}|}|\\
+% |\getargs[|{\it mode}|]{|{\it string}|}|
+%
+% \noindent Commands in this section return their result in the string
+% |\theresult|, unless otherwise specified.
+% Unless otherwise noted, the {\it mode} may take one of two values:
+% |[v]| for verbose mode (generally, the default), and |[q]| for quiet
+% mode. In both cases, the result of
+% the operation is stored in |\theresult|. In verbose mode, it is also
+% output immediately (and may be captured by an |\edef|). In quiet mode,
+% no string is output, though the result still resides in |\theresult|.
+%
+% The command |\stringlength| \DescribeMacro{\stringlength} returns the
+% length of {\it string} in characters (not bytes).
+% Default mode is |[v]|.
+%
+% The command |\findchars| \DescribeMacro{\findchars} checks to see if
+% the character {\it match-char} occurs anywhere in {\it string}. The
+% number of occurances is stored in |\theresult| and, if in verbose
+% mode, printed. If it is desired to find blankspaces, {\it match-char}
+% should be set to |{~}| and not |{ }|.
+% Default mode is |[v]|.
+%
+% The command |\findwords| \DescribeMacro{\findwords} checks to see if
+% the string {\it match-string} occurs anywhere in {\it string}. The
+% number of occurances is stored in |\theresult| and, if in verbose
+% mode, printed. If it is desired to find blankspaces, those
+% characters in {\it match-string}
+% should be set to hardspaces (\ie tildes) and not softspaces (\ie
+% blanks), regardless of how they are defined in {\it string}.
+% Default mode is |[v]|.
+%
+% The command |\whereischar| \DescribeMacro{\whereischar} checks to see
+% where
+% the character {\it match-char} first occurs in {\it string}. The
+% location of that occurance is stored in |\theresult| and, if in verbose
+% mode, printed. If the character is not found, |\theresult| is set to
+% a value of 0. If it is desired to find blankspaces, {\it match-char}
+% should be set to |{~}| and not |{ }|.
+% Default mode is |[v]|.
+%
+% The command |\whereisword| \DescribeMacro{\whereisword} checks to see
+% where
+% the string {\it match-string} first occurs in {\it string}. The
+% location of that occurance is stored in |\theresult| and, if in verbose
+% mode, printed. If {\it match-string} is not found, |\theresult| is set to
+% a value of 0. If it is desired to find blankspaces, those characters
+% in {\it match-string}
+% should be set to hardspaces (\ie tildes) and not softspaces (\ie
+% blanks), regardless of how they are defined in {\it string}.
+% Default mode is |[v]|.
+%
+% The command |\wordcount| \DescribeMacro{\wordcount} counts the number
+% of space-separated words that occur in {\it string}.
+% Default mode is |[v]|.
+%
+% The command |\getargs| \DescribeMacro{\getargs} mimics the Unix
+% command of the same name, in that it parses {\it string} to determine
+% how many arguments (\ie words) are in {\it string}, and extracts
+% each word into a separate variable. The number of arguments is placed
+% in |\narg| and the individual arguments are placed in variables of
+% the name |\argi|, |\argii|, |\argiii|, |\argiv|, etc. This command
+% may be used to facilitate simply the use of multiple optional
+% arguments in a \LaTeX{} command, for example
+% |\mycommand[|{\it option1 option2 option3}|]{|{\it argument}|}|.
+% In this case,
+% |\mycommand| should exercise |\getargs{#1}|, with the result being
+% that {\it option1} is stored in |\argi|, \etc~The command |\mycommand|
+% may then proceed to parse the optional arguments and branch
+% accordingly.
+% Default mode is |[q]|; |[e]| mode is permitted, while |[v]| mode
+% is disabled.
+%
+% \section {Commands to Test Strings}
+%
+% These commands take an input
+% string or token and test for a particular alphanumeric condition.
+% They include:
+%
+% \noindent%
+% |\isnextbyte[|{\it mode}|]{|{\it match-byte}|}{|{\it string}|}|\\
+% |\testmatchingchar{|{\it
+% string}|}{|{\it n}|}{|{\it match-char}|}|\\
+% |\testcapitalized{|{\it string}|}|\\
+% |\testuncapitalized{|{\it string}|}|\\
+% |\testleadingalpha{|{\it string}|}|\\
+% |\testuppercase{|{\it string}|}|\\
+% |\testsolelyuppercase{|{\it string}|}|\\
+% |\testlowercase{|{\it string}|}|\\
+% |\testsolelylowercase{|{\it string}|}|\\
+% |\testalphabetic{|{\it string}|}|
+%
+% The command |\isnextbyte| \DescribeMacro{\isnextbyte} tests to see if
+% the first byte of {\it string} equals {\it match-byte}. It
+% is the only string-testing command in
+% this section which does not use the {\sf ifthen} test structure for
+% its result. Rather, |\isnextbyte| returns the result of its test as
+% a |T| or |F| in the string |\theresult|. More importantly, and
+% unlike other \stringstrings commands, |\isnextbyte| is a {\it byte} test
+% and not a {\it character} test. This means that, while |\isnextbyte|
+% operates very efficiently, it cannot
+% be used to directly detect multi-byte characters like |\$|,
+% |\^|, |\{|, |\}|, |\_|, |\dag|, |\ddag|, |\AE|, |\ae|, |\OE|,
+% |\oe|, \etc~(|\isnextbyte| will give false positives or negatives
+% when testing for these multi-byte characters).
+% The default mode of |\isnextbyte| is |[v]|.
+%
+% If a character needs to be tested, rather than a byte,
+% \DescribeMacro{\testmatchingchar} |\testmatchingchar| should be used.
+% The command |\testmatchingchar| is
+% used to ascertain whether character {\it n} of {\it string} equals
+% {\it match-char} or not. Whereas |\isnextbyte| checks only a {\it
+% byte}, |\testmatchingchar| tests for a {\it character} (single- or
+% multi-byte character). After the test is called, the action(s) may be
+% called out with |\ifmatchingchar| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% The command |\testcapitalized| \DescribeMacro{\testcapitalized} is
+% used to ascertain whether the first character of {\it string} is
+% capitalized or not. If the first character is non-alphabetic, the
+% test will return FALSE. After the test is called, the action(s) may be
+% called out with |\ifcapitalized| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% The command |\testuncapitalized| \DescribeMacro{\testuncapitalized} is
+% used to ascertain whether the first character of {\it string} is
+% uncapitalized. If the first character is non-alphabetic, the
+% test will return FALSE. After the test is called, the action(s) may be
+% called out with |\ifuncapitalized| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% The command |\testleadingalpha| \DescribeMacro{\testleadingalpha} is
+% used to ascertain whether the first character of {\it string} is
+% alphabetic. After the test is called, the action(s) may be
+% called out with |\ifleadingalpha| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% The command |\testuppercase| \DescribeMacro{\testuppercase} is
+% used to ascertain whether all the alphabetic characters in {\it
+% string} are uppercase or not. The presence of non-alphabetic
+% characters in {\it string} does not falsify the test,
+% but are merely ignored. However, a string completely void of
+% alphabetic characters will always test FALSE.
+% After the test is called, the action(s) may be
+% called out with |\ifuppercase| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% The command |\testsolelyuppercase|
+% \DescribeMacro{\testsolelyuppercase} is
+% used to ascertain whether {\it all} the characters in {\it
+% string} are uppercase or not. The presence of non-alphabetic
+% characters in {\it string} other than blankspaces will automatically
+% falsify the test. Blankspaces are ignored. However, a null string or
+% a string composed solely of blankspaces will also test FALSE.
+% After the test is called, the action(s) may be
+% called out with |\ifsolelyuppercase| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% The command |\testlowercase| \DescribeMacro{\testlowercase} is
+% used to ascertain whether all the alphabetic characters in {\it
+% string} are lowercase or not. The presence of non-alphabetic
+% characters in {\it string} does not falsify the test,
+% but are merely ignored. However, a string completely void of
+% alphabetic characters will always test FALSE.
+% After the test is called, the action(s) may be
+% called out with |\iflowercase| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% The command |\testsolelylowercase|
+% \DescribeMacro{\testsolelylowercase} is
+% used to ascertain whether {\it all} the characters in {\it
+% string} are lowercase or not. The presence of non-alphabetic
+% characters in {\it string} other than blankspaces will automatically
+% falsify the test. Blankspaces are ignored. However, a null string or
+% a string composed solely of blankspaces will also test FALSE.
+% After the test is called, the action(s) may be
+% called out with |\ifsolelylowercase| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% The command |\testalphabetic|
+% \DescribeMacro{\testalphabetic} is
+% used to ascertain whether {\it all} the characters in {\it
+% string} are alphabetic or not. The presence of non-alphabetic
+% characters in {\it string} other than blankspaces will automatically
+% falsify the test. Blankspaces are ignored. However, a null string or
+% a string composed solely of blankspaces will also test FALSE.
+% After the test is called, the action(s) may be
+% called out with |\ifalphabetic| {\it true-code} |\else| {\it
+% false-code} |\fi|.
+%
+% \section{Disclaimers}
+%
+% Now that we have described the commands available in the
+% \stringstrings package, it is appropriate to lay out the quirks and
+% warnings associated with the use of the package.
+%
+% First, \stringstrings is currently set to handle a string no larger
+% than 500 characters. A user could circumvent this, presumably, by
+% editing the style package to increase the value of
+% |\@MAXSTRINGSIZE| \DescribeMacro{\@MAXSTRINGSIZE}.
+%
+% It is important to remember that \stringstrings follows the underlying
+% rules of \LaTeX{}. Therefore, a passed string could not contain a raw
+% |%| as part of it, because it would, in fact, comment out the
+% remainder of the line. Naturally, the string may freely contain
+% instances of |\%|.
+%
+% Tokens that take two or more characters to express
+% (\eg |\#|, |\oe|, |\ddag|, \etc) are {\bf counted as
+% a single character} within the string.
+% The rule applies if you wanted to know the length
+% of a string that was populated with such tokens, or wanted to extract
+% a substring from a such a string. Of course, the exception that makes
+% the rule is that of diacritical marks, which count as separate symbols
+% from the characters they mark. For example,
+% |\^a| counts as two characters, because the |a| is
+% really just the operand of the |\^| token, even though the net result
+% looks like a single character (\^a).
+%
+% Consistent with
+% \LaTeX{} convention, groups of spaces are treated as a single
+% blankspace, unless encoded with |~| characters. And finally, again
+% consistent with the way \LaTeX{} operates, the space
+% that follows an alphabetic token is not actually a space in the
+% string, but serves as the delimiter to the token. Therefore,
+% |\OE dipus| (\OE dipus) has a length of six characters,
+% one for the |\OE| and five
+% for the |dipus|. The intervening space merely closes out the |\OE|
+% token, and does not represent a space in the middle of the string.
+%
+% One quirk worthy of particular note concerns the tabbing character,
+% meaning \&
+% as opposed to |\&| (which is handled without problem).
+% As of version 1.01, \stringstrings has the
+% capability to operate on arguments containg the ampersand \&,
+% normally reserved as the \LaTeX{} tabbing character. However, one
+% adverse by-product is that \& characters returned in |\thestring|
+% lose their catcode-4 value, and thus lose their ability to function as
+% tabbing characters. In the following example,\\
+% | |\\
+% | \caseupper[q]{a & b & c & d}|\\
+% | \begin{tabular}{|\verb,|l|c|c|c|,|}|\\
+% | \hline|\\
+% | \thestring\\|\\
+% | \hline|\\
+% | \end{tabular}|\\
+% | |\\
+% will produce \caseupper[q]{a & b & c & d}
+% \begin{tabular}{\modetablelayout}
+% \hline
+% \thestring\\
+% \hline
+% \end{tabular}
+% instead of the desired
+% \begin{tabular}{\modetablelayout}
+% \hline
+% A & B & C & D\\
+% \hline
+% \end{tabular}
+% .
+%
+% In the |\substring| command, no tests are performed to guarantee that
+% the lower limit, {\it min}, is less than the upper limit, {\it max},
+% or that {\it min} is even positive. However, the upper limit,
+% {\it max}, is corrected, if set larger than the string length. Also,
+% the use of the `\$' symbol to signify the last character of the string
+% and `\$--{\it n}' to denote an offset of {\it n} characters from the
+% end of the string can be helpful in avoiding the misindexing of strings.
+%
+% \begin{table}[p]
+% \caption{\bf Problematic Characters/Tokens and \stringstrings Solutions%
+% \label{tbl:prob}}\vspace{.5em}
+% \small
+% \begin{tabular}{\mylayout}
+% \LaTeX{} & Symbol/Name & Problem/Solution\\
+% \hline
+% \hline
+% |{| & begin group & Cannot use |{| and |}| in \stringstrings
+% arguments.\\
+% |}| & end group & However, use |\LB|\ldots|\RB| in lieu of |{|\ldots|}|;\\
+% & & manipulate string in |[e]| mode \& |\retokenize| \\
+% \hline
+% |\dag| & \dag~~Dagger & Cannot |\edef| these tokens; Thus, |[v]| mode\\
+% |\ddag| & \ddag~~Double Dagger & fails with both OT1 and T1 encoding; \\
+% |\P| & \P~~Pilcrow & manipulate string in |[e]| mode \& |\retokenize| \\
+% |\d| & \d x~~Underdot & \\
+% |\t| & \t xx~~Joining Arch & \\
+% |\b| & \b x~~Letter Underline & \\
+% |\copyright| & \copyright~Copyright & \\
+% \hline
+% \hline
+% |\_| & \_~~Underscore & Cannot |\edef| with OT1 encoding; either\\
+% |\{| & \{~~Left Curly Brace & |\renewcommand\encodingdefault{T1}|, or \\
+% |\}| & \}~~Right Curly Brace &
+% manipulate string in |[e]| mode \& |\retokenize|. \\
+% |\S| & \S~~Section Symbol & With OT1, |\S|, |\c| and |\pounds| break\\
+% |\c| & \c x~~Cedilla & \stringstrings |[v]| mode.\\
+% |\pounds| & \pounds~~Pounds & \\
+% \hline
+% \verb,\|,& \stringstrings Pipe Char. & Distinct from \verb,|,,
+% the \stringstrings encoded-\\
+% & \verb,|, (T1) ~~~\stringdecode{\|} (OT1) & escape character\\
+% \hline
+% \hline
+% |\$| & \$~~Dollar & Either cannot |\edef|, or\\
+% |\carat| & \mycarat~~(text mode) &
+% cannot identify uniquely with |\if| construct, or \\
+% |\^| & \^x~~Circumflex & expanded character is more than one byte. \\
+% |\'| & \'x~~Acute & \\
+% |\"| & \"x~~Umlaut & {\it However},\\
+% |\~| & \~x~~Tilde &
+% Use these characters freely, \stringstrings\\
+% |\`| & \`x~~Grave &
+% encoding functions transparently with them.\\
+% |\.| & \.x~~Overdot & \\
+% |\=| & \=x~~Macron & |\retokenize| also works\\
+% |\u| & \u x~~Breve & \\
+% |\v| & \v x~~Caron & \\
+% |\H| & \H x~~Double Acute & \\
+% |\ss| & \ss~~Eszett & \\
+% |\AE \ae| & \AE~\ae~~\ae sc & \\
+% |\OE \oe| & \OE~\oe~~\oe thel & \\
+% |\AA \aa| & \AA~\aa~~angstrom & \\
+% |\O \o| & \O~\o~~slashed O & \\
+% |\L \l| & \L~\l~~barred L & \\
+% |~| & Hardspace &\\
+% \hline
+% |$| & begin/end math mode & These characters pose no difficulties;\\
+% |^| & math superscript & However, cannot extract substring that \\
+% |_| & math subscript & breaks in middle of math mode.\\
+% & & Other math mode symbols NOT supported.\\
+% \hline
+% \& & ampersand & Version 1.01 \stringstrings can manipulate the\\
+% & & ampersand. However, returned strings\\
+% & & containing the \& character lose their\\
+% & & catcode-4 status, making them unfit\\
+% & & for use as tabbing characters.\\
+% \hline
+% \hline
+% \end{tabular}
+% \end{table}
+% Table~\ref{tbl:prob} shows a variety of characters and tokens, some of
+% which pose a challenge to \stringstrings manipulations. In all cases,
+% a solution or workaround is provided. For symbols in the top two
+% categories, the workaround
+% solution includes the use of retokenized strings instead of expanded
+% strings. For symbols in the next two categories, use of T1 encoding
+% or retokenizing provides a satisfactory solution. In the bottom three
+% categories, because of \stringstrings encoded |[e]| mode,
+% there is nothing to impede the use of these characters in
+% \stringstrings arguments, if encoded |[e]| mode is employed for
+% intermediate calculations. Some of the
+% details of these problematic cases is described below.
+%
+% Not surprisingly, you are not allowed to extract a substring of a
+% string, if it breaks in the middle of math mode, because a substring
+% with only one |$| in it cannot be |\edef|'ed.
+%
+% There are a few potential quirks when using \LaTeX{}'s native OT1
+% character encoding, most of which can be circumvented by using the
+% more modern
+% T1 encoding (accessed via |\renewcommand\encodingdefault{T1}| in the
+% document preamble). The quirks arise because there are
+% several characters that, while displayable in \LaTeX{}, are not part
+% of the OT1 character encoding. The characters include |\{|, |\}|, and
+% the \verb,|, symbol (accessed in \stringstrings via \verb,\|,).
+% When using \stringstrings to manipulate strings containing
+% these characters in the presence of OT1 encoding,
+% they come out looking like \stringdecode{\{}, \stringdecode{\}},
+% and \stringdecode{\|}, respectively. However, if the T1 encoding fix
+% is not an option for you, you can also work around this problem by
+% |\retokenize|'ing the affected string (the |\retokenize| command is
+% provided to convert encoded, expanded strings back into tokenized
+% form, if need be).
+%
+% Likewise, for both OT1 and T1 encoding, the characters \dag~(|\dag|),
+% \ddag~(|\ddag|), \P~(|\P|), \d~~(|\d|), \t~~~(|\t|), \b~~~(|\b|),
+% and \copyright~(|\copyright|)
+% cannot be in the argument of an |\edef| expression. For
+% manipulated strings including these characters, |\retokenize| is the
+% only option available to retain the integrity of the string.
+%
+% As discussed thoroughly in the previous section, an ``encoded'' form of
+% the string manipulation routines is provided to prevent the
+% undesirable circumstance of passing an |\edef|'ed symbol as input
+% to a subsequent manipulation. Likewise, never try to ``decode''
+% an already ``decoded'' string.
+%
+% When \stringstrings doesn't understand a token, it is supposed to
+% replace it with a period. However, some undecipherable characters may
+% inadvertantly be replaced with a space, instead. Of course, neither
+% of these possibilities is any comfort to the user.
+%
+% As mentioned already, \stringstrings cannot handle curly braces that
+% are used for grouping purposes, a circumstance which often arises in
+% math mode. Nonetheless, |\LB| and |\RB| may be used within
+% \stringstrings arguments in lieu of grouping braces, {\it if the final
+% result is to be retokenized}. Thus, |\caselower[e]{$X^\LB Y + Z\RB$}|
+% followed by |\convertchar[e]{\thestring}{x}{(1+x)}|, when finished up
+% with the following command,
+% |\retokenize[v]{\thestring}| yields as its result:\\
+% \caselower[e]{$X^\LB Y + Z\RB$}\convertchar[e]{\thestring}{x}{(1+x)}
+% \retokenize[v]{\thestring}.
+%
+% One might ask, ``why not retokenize everything, instead of using the
+% |[v]| mode of the \stringstrings routines?'' While one {\it could}
+% do this, the answer is simply
+% that |\retokenize| is a computationally intensive command, and that
+% it is best used, therefore, only when the more efficient methods
+% will not suffice. In many, if not most cases, strings to be
+% manipulated will be solely composed of alphanumeric characters which
+% don't require the use of |\retokenize|, T1 encoding, or even
+% \stringstrings encoding.
+%
+% Despite these several disclaimers and workarounds required when
+% dealing with problematic characters, I hope you find the \stringstrings
+% architecture and feel to be straightforward and useful. There is only
+% one thing left, and that is to dissect the code\ldots and so here we
+% go.
+%
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+% \StopEventually{}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \vspace{-0.8em}
+% \begin{macro}{stringstrings.sty}
+% \section{Code Listing}
+% I'll try to lay out herein
+% the workings of the \stringstrings style package.
+% \begin{macrocode}
+%<*package>
+
+%%%%% INITIALIZATIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\catcode`\&=12
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ifthen}
+% This package makes wide use of the {\sf ifthen} style package.
+% \begin{macrocode}
+\usepackage{ifthen}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@MAXSTRINGSIZE}
+% The parameter |\@MAXSTRINGSIZE| defines the maximum allowable string
+% size that \stringstrings can operate upon.
+% \begin{macrocode}
+\def\@MAXSTRINGSIZE{500}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macrocode}
+\def\endofstring{@E@o@S@}%
+\def\undecipherable{.}% UNDECIPHERABLE TOKENS TO BE REPLACED BY PERIOD
+\def\@blankaction{\BlankSpace}
+% \end{macrocode}
+% Save the symbols which will get redefined \stringstrings encoding.
+
+% \begin{macrocode}
+\let\SaveDollar\$
+\let\SaveHardspace~
+\let\SaveCircumflex\^
+\let\SaveTilde\~
+\let\SaveUmlaut\"
+\let\SaveGrave\`
+\let\SaveAcute\'
+\let\SaveMacron\=
+\let\SaveOverdot\.
+\let\SaveBreve\u
+\let\SaveCaron\v
+\let\SaveDoubleAcute\H
+\let\SaveCedilla\c
+\let\SaveUnderdot\d
+\let\SaveArchJoin\t
+\let\SaveLineUnder\b
+\let\SaveCopyright\copyright
+\let\SavePounds\pounds
+\let\SaveLeftBrace\{
+\let\SaveRightBrace\}
+\let\SaveUnderscore\_
+\let\SaveDagger\dag
+\let\SaveDoubleDagger\ddag
+\let\SaveSectionSymbol\S
+\let\SavePilcrow\P
+\let\SaveAEsc\AE
+\let\Saveaesc\ae
+\let\SaveOEthel\OE
+\let\Saveoethel\oe
+\let\SaveAngstrom\AA
+\let\Saveangstrom\aa
+\let\SaveSlashedO\O
+\let\SaveSlashedo\o
+\let\SaveBarredL\L
+\let\SaveBarredl\l
+\let\SaveEszett\ss
+\let\SaveLB{
+\let\SaveRB}
+% \end{macrocode}
+
+% The BlankSpace character is the only character which is reencoded
+% with a 1-byte re-encoding\ldots in this case the \OE~character.
+% \begin{macrocode}
+\def\EncodedBlankSpace{\SaveOEthel}
+\edef\BlankSpace{ }
+% \end{macrocode}
+% All other reencoded symbols consist of 2 bytes: an escape character
+% plus a unique code. The escape character is a pipe symbol. the
+% unique code comprises either a single number, letter, or symbol.
+
+% \begin{macrocode}
+\def\EscapeChar{|}
+
+% |0 IS AN ENCODED |, ACCESSED VIA \|
+\def\PipeCode{0}
+\def\EncodedPipe{\EscapeChar\PipeCode}
+\def\Pipe{|}
+\let\|\EncodedPipe
+
+% |1 IS AN ENCODED \$
+\def\DollarCode{1}
+\def\EncodedDollar{\EscapeChar\DollarCode}
+% THE FOLLOWING IS NEEDED TO KEEP OT1 ENCODING FROM BREAKING;
+% IT PROVIDES AN ADEQUATE BUT NOT IDEAL ENVIRONMENT FOR T1 ENCODING
+\def\Dollar{\symbol{36}}
+% THE FOLLOWING IS BETTER FOR T1 ENCODING, BUT BREAKS OT1 ENCODING
+%\def\Dollar{\SaveDollar}
+
+% |W IS RESERVED TO BE ASSIGNED TO AN ARBITRARY TOKEN
+\def\UvariCode{W}
+\def\EncodedUvari{\EscapeChar\UvariCode}
+\def\Uvari{Uvari}
+\let\uvari\EncodedUvari
+
+% |X IS RESERVED TO BE ASSIGNED TO AN ARBITRARY TOKEN
+\def\UvariiCode{X}
+\def\EncodedUvarii{\EscapeChar\UvariiCode}
+\def\Uvarii{Uvarii}
+\let\uvarii\EncodedUvarii
+
+% |Y IS RESERVED TO BE ASSIGNED TO AN ARBITRARY TOKEN
+\def\UvariiiCode{Y}
+\def\EncodedUvariii{\EscapeChar\UvariiiCode}
+\def\Uvariii{Uvariii}
+\let\uvariii\EncodedUvariii
+
+% |2 IS AN ENCODED ^ FOR USE IN TEXT MODE, ACCESSED VIA \carat
+\def\CaratCode{2}
+\def\EncodedCarat{\EscapeChar\CaratCode}
+\def\Carat{\symbol{94}}
+\let\carat\EncodedCarat
+
+% |4 IS AN ENCODED \{
+\def\LeftBraceCode{4}
+\def\EncodedLeftBrace{\EscapeChar\LeftBraceCode}
+% THE FOLLOWING IS NEEDED TO KEEP OT1 ENCODING FROM BREAKING;
+% IT PROVIDES AN ADEQUATE BUT NOT IDEAL ENVIRONMENT FOR T1 ENCODING
+\def\LeftBrace{\symbol{123}}
+% THE FOLLOWING IS BETTER FOR T1 ENCODING, BUT BREAKS OT1 ENCODING
+%\def\LeftBrace{\SaveLeftBrace}
+
+% |5 IS AN ENCODED \}
+\def\RightBraceCode{5}
+\def\EncodedRightBrace{\EscapeChar\RightBraceCode}
+% THE FOLLOWING IS NEEDED TO KEEP OT1 ENCODING FROM BREAKING;
+% IT PROVIDES AN ADEQUATE BUT NOT IDEAL ENVIRONMENT FOR T1 ENCODING
+\def\RightBrace{\symbol{125}}
+% THE FOLLOWING IS BETTER FOR T1 ENCODING, BUT BREAKS OT1 ENCODING
+%\def\RightBrace{\SaveRightBrace}
+
+% |6 IS AN ENCODED \_
+\def\UnderscoreCode{6}
+\def\EncodedUnderscore{\EscapeChar\UnderscoreCode}
+\def\Underscore{\symbol{95}}
+%\def\Underscore{\SaveUnderscore}
+
+% |7 IS AN ENCODED \^
+\def\CircumflexCode{7}
+\def\EncodedCircumflex{\EscapeChar\CircumflexCode}
+\def\Circumflex{\noexpand\SaveCircumflex}
+
+% |8 IS AN ENCODED \~
+\def\TildeCode{8}
+\def\EncodedTilde{\EscapeChar\TildeCode}
+\def\Tilde{\noexpand\SaveTilde}
+
+% |" IS AN ENCODED \"
+\def\UmlautCode{"}
+\def\EncodedUmlaut{\EscapeChar\UmlautCode}
+\def\Umlaut{\noexpand\SaveUmlaut}
+
+% |` IS AN ENCODED \`
+\def\GraveCode{`}
+\def\EncodedGrave{\EscapeChar\GraveCode}
+\def\Grave{\noexpand\SaveGrave}
+
+% |' IS AN ENCODED \'
+\def\AcuteCode{'}
+\def\EncodedAcute{\EscapeChar\AcuteCode}
+\def\Acute{\noexpand\SaveAcute}
+
+% |= IS AN ENCODED \=
+\def\MacronCode{=}
+\def\EncodedMacron{\EscapeChar\MacronCode}
+\def\Macron{\noexpand\SaveMacron}
+
+% |. IS AN ENCODED \.
+\def\OverdotCode{.}
+\def\EncodedOverdot{\EscapeChar\OverdotCode}
+\def\Overdot{\noexpand\SaveOverdot}
+
+% |u IS AN ENCODED \u
+\def\BreveCode{u}
+\def\EncodedBreve{\EscapeChar\BreveCode}
+\def\Breve{\noexpand\SaveBreve}
+
+% |v IS AN ENCODED \v
+\def\CaronCode{v}
+\def\EncodedCaron{\EscapeChar\CaronCode}
+\def\Caron{\noexpand\SaveCaron}
+
+% |H IS AN ENCODED \H
+\def\DoubleAcuteCode{H}
+\def\EncodedDoubleAcute{\EscapeChar\DoubleAcuteCode}
+\def\DoubleAcute{\noexpand\SaveDoubleAcute}
+
+% |c IS AN ENCODED \c
+\def\CedillaCode{c}
+\def\EncodedCedilla{\EscapeChar\CedillaCode}
+\def\Cedilla{\noexpand\SaveCedilla}
+
+% |d IS AN ENCODED \d
+\def\UnderdotCode{d}
+\def\EncodedUnderdot{\EscapeChar\UnderdotCode}
+\def\Underdot{.}% CANNOT \edef \d
+
+% |t IS AN ENCODED \t
+\def\ArchJoinCode{t}
+\def\EncodedArchJoin{\EscapeChar\ArchJoinCode}
+\def\ArchJoin{.}% CANNOT \edef \t
+
+% |b IS AN ENCODED \b
+\def\LineUnderCode{b}
+\def\EncodedLineUnder{\EscapeChar\LineUnderCode}
+\def\LineUnder{.}% CANNOT \edef \b
+
+% |C IS AN ENCODED \copyright
+\def\CopyrightCode{C}
+\def\EncodedCopyright{\EscapeChar\CopyrightCode}
+\def\Copyright{.}% CANNOT \edef \copyright
+
+% |p IS AN ENCODED \pounds
+\def\PoundsCode{p}
+\def\EncodedPounds{\EscapeChar\PoundsCode}
+\def\Pounds{\SavePounds}
+
+% |[ IS AN ENCODED {
+\def\LBCode{[}
+\def\EncodedLB{\EscapeChar\LBCode}
+\def\UnencodedLB{.}
+\def\LB{\EncodedLB}
+
+% |] IS AN ENCODED }
+\def\RBCode{]}
+\def\EncodedRB{\EscapeChar\RBCode}
+\def\UnencodedRB{.}
+\def\RB{\EncodedRB}
+
+% |z IS AN ENCODED \dag
+\def\DaggerCode{z}
+\def\EncodedDagger{\EscapeChar\DaggerCode}
+\def\Dagger{.}% CANNOT \edef \dag
+
+% |Z IS AN ENCODED \ddag
+\def\DoubleDaggerCode{Z}
+\def\EncodedDoubleDagger{\EscapeChar\DoubleDaggerCode}
+\def\DoubleDagger{.}% CANNOT \edef \ddag
+
+% |S IS AN ENCODED \S
+\def\SectionSymbolCode{S}
+\def\EncodedSectionSymbol{\EscapeChar\SectionSymbolCode}
+\def\SectionSymbol{\SaveSectionSymbol}
+
+% |P IS AN ENCODED \P
+\def\PilcrowCode{P}
+\def\EncodedPilcrow{\EscapeChar\PilcrowCode}
+\def\Pilcrow{.}% CANNOT \edef \P
+
+% |E IS AN ENCODED \AE
+\def\AEscCode{E}
+\def\EncodedAEsc{\EscapeChar\AEscCode}
+\def\AEsc{\SaveAEsc}
+
+% |e IS AN ENCODED \ae
+\def\aescCode{e}
+\def\Encodedaesc{\EscapeChar\aescCode}
+\def\aesc{\Saveaesc}
+
+% |O IS AN ENCODED \OE
+\def\OEthelCode{O}
+\def\EncodedOEthel{\EscapeChar\OEthelCode}
+\def\OEthel{\SaveOEthel}
+
+% |o IS AN ENCODED \oe
+\def\oethelCode{o}
+\def\Encodedoethel{\EscapeChar\oethelCode}
+\def\oethel{\Saveoethel}
+
+% |A IS AN ENCODED \AA
+\def\AngstromCode{A}
+\def\EncodedAngstrom{\EscapeChar\AngstromCode}
+\def\Angstrom{\SaveAngstrom}
+
+% |a IS AN ENCODED \aa
+\def\angstromCode{a}
+\def\Encodedangstrom{\EscapeChar\angstromCode}
+\def\angstrom{\Saveangstrom}
+
+% |Q IS AN ENCODED \O
+\def\SlashedOCode{Q}
+\def\EncodedSlashedO{\EscapeChar\SlashedOCode}
+\def\SlashedO{\SaveSlashedO}
+
+% |q IS AN ENCODED \o
+\def\SlashedoCode{q}
+\def\EncodedSlashedo{\EscapeChar\SlashedoCode}
+\def\Slashedo{\SaveSlashedo}
+
+% |L IS AN ENCODED \L
+\def\BarredLCode{L}
+\def\EncodedBarredL{\EscapeChar\BarredLCode}
+\def\BarredL{\SaveBarredL}
+
+% |l IS AN ENCODED \l
+\def\BarredlCode{l}
+\def\EncodedBarredl{\EscapeChar\BarredlCode}
+\def\Barredl{\SaveBarredl}
+
+% |s IS AN ENCODED \ss
+\def\EszettCode{s}
+\def\EncodedEszett{\EscapeChar\EszettCode}
+\def\Eszett{\SaveEszett}
+
+\newcounter{@letterindex}
+\newcounter{@@letterindex}
+\newcounter{@@@letterindex}
+\newcounter{@wordindex}
+\newcounter{@iargc}
+\newcounter{@gobblesize}
+\newcounter{@maxrotation}
+\newcounter{@stringsize}
+\newcounter{@@stringsize}
+\newcounter{@@@stringsize}
+\newcounter{@revisedstringsize}
+\newcounter{@gobbleindex}
+\newcounter{@charsfound}
+\newcounter{@alph}
+\newcounter{@alphaindex}
+\newcounter{@capstrigger}
+\newcounter{@fromindex}
+\newcounter{@toindex}
+\newcounter{@previousindex}
+\newcounter{@flag}
+\newcounter{@matchloc}
+\newcounter{@matchend}
+\newcounter{@matchsize}
+\newcounter{@matchmax}
+\newcounter{@skipped}
+\newcounter{@lcwords}
+% \end{macrocode}
+% \begin{macrocode}
+%%%%% CONFIGURATION COMMANDS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \end{macrocode}
+
+% \begin{macro}{\defaultTreatments}
+% This command can be used to restore the default string treatments,
+% prior to calling |\substring|. The default treatments leave all
+% symbol types intact and unaltered.
+% \begin{macrocode}
+\newcommand\defaultTreatments{%
+ \def\EncodingTreatment{v}% <--Set=v to decode special chars (vs. q,e)
+ \def\AlphaCapsTreatment{1}% <--Set=1 to retain uppercase (vs. 0,2)
+ \def\AlphaTreatment{1}% <--Set=1 to retain lowercase (vs. 0,2)
+ \def\PunctuationTreatment{1}% <--Set=1 to retain punctuation (vs. 0)
+ \def\NumeralTreatment{1}% <--Set=1 to retain numerals (vs. 0)
+ \def\SymbolTreatment{1}% <--Set=1 to retain special chars (vs. 0)
+ \def\BlankTreatment{1}% <--Set=1 to retain blanks (vs. 0)
+ \def\CapitalizeString{0}% <--Set=0 for no special action (vs. 1,2)
+ \def\SeekBlankSpace{0}% <--Set=0 for no special action (vs. 1,2)
+}
+\defaultTreatments
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\Treatments}
+% This command allows the user to specify the desired character class
+% treatments, prior to a call to |\substring|. Unfortunately for the
+% user, I have specified which character class each symbol belongs to.
+% Therefore, it is not easy if the user decides that he wants a cedilla,
+% for example, to be treated like an alphabetic character rather than
+% a symbol.
+% \begin{macrocode}
+% QUICK WAY TO SET UP TREATMENTS BY WHICH \@rotate HANDLES VARIOUS
+% CHARACTERS
+\newcommand\Treatments[6]{%
+ \def\AlphaCapsTreatment{#1}% <--Set=0 to remove uppercase
+% =1 to retain uppercase
+% =2 to change UC to lc
+ \def\AlphaTreatment{#2}% <--Set=0 to remove lowercase
+% =1 to retain lowercase
+% =2 to change lc to UC
+ \def\PunctuationTreatment{#3}%<--Set=0 to remove punctuation
+% =1 to retain punctuation
+ \def\NumeralTreatment{#4}% <--Set=0 to remove numerals
+% =1 to retain numerals
+ \def\SymbolTreatment{#5}% <--Set=0 to remove special chars
+% =1 to retain special chars
+ \def\BlankTreatment{#6}% <--Set=0 to remove blanks
+% =1 to retain blanks
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\+}
+% This command (|\+|) is used to enact the \stringstrings encoding.
+% Key symbols are redefined, and any |\edef| which occurs while this
+% command is active will adopt these new definitions.
+% \begin{macrocode}
+% REENCODE MULTIBYTE SYMBOLS USING THE stringstrings ENCODING METHOD
+\newcommand\+{%
+ \def\${\EncodedDollar}%
+ \def~{\EncodedBlankSpace}%
+ \def\^{\EncodedCircumflex}%
+ \def\~{\EncodedTilde}%
+ \def\"{\EncodedUmlaut}%
+ \def\`{\EncodedGrave}%
+ \def\'{\EncodedAcute}%
+ \def\={\EncodedMacron}%
+ \def\.{\EncodedOverdot}%
+ \def\u{\EncodedBreve}%
+ \def\v{\EncodedCaron}%
+ \def\H{\EncodedDoubleAcute}%
+ \def\c{\EncodedCedilla}%
+ \def\d{\EncodedUnderdot}%
+ \def\t{\EncodedArchJoin}%
+ \def\b{\EncodedLineUnder}%
+ \def\copyright{\EncodedCopyright}%
+ \def\pounds{\EncodedPounds}%
+ \def\{{\EncodedLeftBrace}%
+ \def\}{\EncodedRightBrace}%
+ \def\_{\EncodedUnderscore}%
+ \def\dag{\EncodedDagger}%
+ \def\ddag{\EncodedDoubleDagger}%
+ \def\S{\EncodedSectionSymbol}%
+ \def\P{\EncodedPilcrow}%
+ \def\AE{\EncodedAEsc}%
+ \def\ae{\Encodedaesc}%
+ \def\OE{\EncodedOEthel}%
+ \def\oe{\Encodedoethel}%
+ \def\AA{\EncodedAngstrom}%
+ \def\aa{\Encodedangstrom}%
+ \def\O{\EncodedSlashedO}%
+ \def\o{\EncodedSlashedo}%
+ \def\L{\EncodedBarredL}%
+ \def\l{\EncodedBarredl}%
+ \def\ss{\EncodedEszett}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\?}
+% The command |\?| reverts the character encodings back to the standard
+% \LaTeX{} definitions. The command effectively undoes a previously
+% enacted |\+|.
+% \begin{macrocode}
+% WHEN TASK IS DONE, REVERT ENCODING TO STANDARD ENCODING METHOD
+\newcommand\?{%
+ \let\$\SaveDollar%
+ \let~\SaveHardspace%
+ \let\^\SaveCircumflex%
+ \let\~\SaveTilde%
+ \let\"\SaveUmlaut%
+ \let\`\SaveGrave%
+ \let\'\SaveAcute%
+ \let\=\SaveMacron%
+ \let\.\SaveOverdot%
+ \let\u\SaveBreve%
+ \let\v\SaveCaron%
+ \let\H\SaveDoubleAcute%
+ \let\c\SaveCedilla%
+ \let\d\SaveUnderdot%
+ \let\t\SaveArchJoin%
+ \let\b\SaveLineUnder%
+ \let\copyright\SaveCopyright%
+ \let\pounds\SavePounds%
+ \let\{\SaveLeftBrace%
+ \let\}\SaveRightBrace%
+ \let\_\SaveUnderscore%
+ \let\dag\SaveDagger%
+ \let\ddag\SaveDoubleDagger%
+ \let\S\SaveSectionSymbol%
+ \let\P\SavePilcrow%
+ \let\AE\SaveAEsc%
+ \let\ae\Saveaesc%
+ \let\OE\SaveOEthel%
+ \let\oe\Saveoethel%
+ \let\AA\SaveAngstrom%
+ \let\aa\Saveangstrom%
+ \let\O\SaveSlashedO%
+ \let\o\SaveSlashedo%
+ \let\L\SaveBarredL%
+ \let\l\SaveBarredl%
+ \let\ss\SaveEszett%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\encodetoken}
+% The command |\encodetoken| assigns the supplied token to one of three
+% reserved \stringstrings user variables (the optional argument dictates
+% which user variable). Once encoded, the supplied token cannot be used
+% in the normal way, but only in stringstrings routines, unless and
+% until it is decoded.
+% \begin{macrocode}
+\newcommand\encodetoken[2][1]{%
+ \if 1#1%
+ \let\Uvari#2%
+ \let#2\uvari\else
+ \if 2#1%
+ \let\Uvarii#2%
+ \let#2\uvarii\else
+ \if 3#1%
+ \let\Uvariii#2%
+ \let#2\uvariii%
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\decodetoken}
+% The command |\decodetoken| deassigns the supplied token from the
+% reserved \stringstrings user variables (the optional argument dictates
+% which user variable), so that the token may be used in the normal way
+% again.
+% \begin{macrocode}
+\newcommand\decodetoken[2][1]{%
+ \if 1#1%
+ \let#2\Uvari%
+ \def\Uvari{Uvari}\else
+ \if 2#1%
+ \let#2\Uvarii%
+ \def\Uvarii{Uvarii}\else
+ \if 3#1%
+ \let#2\Uvariii%
+ \def\Uvariii{Uvariii}%
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macrocode}
+%%%%% COMMANDS TO MANIPULATE STRINGS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \end{macrocode}
+
+% In the next group of commands, the result is always stored in an
+% expandable string, |\thestring|. Expandable means that |\thestring| can
+% be put into a subsequent |\edef{}| command. Additionally, the
+% optional first argument can be used to cause three actions (verbose,
+% encoded, or quiet):
+% \begin{enumerate}
+% \item [|=v|] |\thestring| is decoded (final result);
+% print it immediately (default)
+% \item [|=e|] |\thestring| is encoded (intermediate result);
+% don't print it
+% \item [|=q|] |\thestring| is decoded (final result),
+% but don't print it
+% \end{enumerate}
+% \begin{macro}{\substring}
+% The command |\substring| is the brains of this package\ldots
+% It is used to acquire a substring from a given string, along with
+% performing specified character manipulations along the way.
+% Its strategy is fundamental to the \stringstrings
+% package: sequentially rotate the 1st character of the
+% string to the end of the string, until the desired substring resides
+% at end of rotated string. Then, gobble up the leading part of
+% string until only the desired substring is left.
+% \begin{macrocode}
+\newcommand\substring[4][v]{\+%
+% \end{macrocode}
+% Obtain the string length of the string to be manipulated and store
+% it in |@stringsize|.
+% \begin{macrocode}
+ \@getstringlength{#2}{@stringsize}%
+% \end{macrocode}
+% First,
+% |\@decodepointer| is used to convert indirect references like |$|
+% and |$-3| into integers.
+% \begin{macrocode}
+ \@decodepointer{#3}%
+ \setcounter{@fromindex}{\@fromtoindex}%
+ \@decodepointer{#4}%
+ \setcounter{@toindex}{\@fromtoindex}%
+% \end{macrocode}
+% Determine the number of characters to rotate to the end of the string
+% and the number of characters to then gobble from it, in order to leave
+% the desired substring.
+% \begin{macrocode}
+ \setcounter{@gobblesize}{\value{@stringsize}}%
+ \ifthenelse{\value{@toindex} > \value{@stringsize}}%
+ {\setcounter{@maxrotation}{\value{@stringsize}}}%
+ {\setcounter{@maxrotation}{\value{@toindex}}}%
+ \addtocounter{@gobblesize}{-\value{@maxrotation}}%
+ \addtocounter{@gobblesize}{\value{@fromindex}}%
+ \addtocounter{@gobblesize}{-1}%
+% \end{macrocode}
+% Prepare for the string rotation by initializing counters, setting the
+% targeted string into the working variable, |\rotatingword|, and set
+% the encoding treatment specified.
+% \begin{macrocode}
+ \setcounter{@letterindex}{0}%
+ \edef\rotatingword{#2}%
+ \def\EncodingTreatment{#1}%
+% \end{macrocode}
+% If capitalization (first character of string or of each word)
+% was specified, the
+% trigger for 1st-character capitalization will be set. However,
+% the treatments for the alphabetic characters for the remainder of the
+% string must be saved and reinstituted after the first character is
+% capitalized.
+% \begin{macrocode}
+ \if 0\CapitalizeString%
+% DO NOT SET CAPITALIZE TRIGGER FOR FIRST CHARACTER
+ \setcounter{@capstrigger}{0}%
+ \else
+% SAVE CERTAIN TREATMENTS FOR LATER RESTORATION
+ \let\SaveAlphaTreatment\AlphaTreatment%
+ \let\SaveAlphaCapsTreatment\AlphaCapsTreatment%
+% SET CAPITALIZE TRIGGER FOR FIRST CHARACTER
+ \setcounter{@capstrigger}{1}%
+ \@forcecapson%
+ \fi
+% \end{macrocode}
+% The command |\@defineactions| looks at the defined treatments
+% and specifies how each of the \stringstrings encoded
+% characters should be handled (\ie left alone, removed, modified,
+% \etc).
+% \begin{macrocode}
+\@defineactions%
+% \end{macrocode}
+% Here begins the primary loop of |\substring| in which characters of
+% |\rotatingword| are successively moved (and possibly manipulated)
+% from the first character of the string to the last. |@letterindex| is
+% the running index defining how many characters have been operated on.
+% \begin{macrocode}
+ \whiledo{\value{@letterindex} < \value{@maxrotation}}{%
+ \addtocounter{@letterindex}{1}%
+% \end{macrocode}
+% When |\CapitalizeString| equals 1, only the first character of the
+% string is capitalized. When it equals 2, every word in the string
+% is capitalized. When equal to 2, this bit of code looks for the
+% blankspace that follows the end of a word, and uses it to reset the
+% capitalization trigger for the next non-blank character.
+% \begin{macrocode}
+% IF NEXT CHARACTER BLANK WHILE \CapitalizeString=2,
+% SET OR KEEP ALIVE TRIGGER.
+ \if 2\CapitalizeString%
+ \isnextbyte[q]{\EncodedBlankSpace}{\rotatingword}%
+ \if F\theresult\isnextbyte[q]{\BlankSpace}{\rotatingword}\fi%
+ \if T\theresult%
+ \if 0\arabic{@capstrigger}%
+ \@forcecapson%
+ \@defineactions%
+ \fi
+ \setcounter{@capstrigger}{2}%
+ \fi
+ \fi
+% \end{macrocode}
+% Is the next character an encoded symbol? If it is a normal character,
+% simply rotate it to the end of the string.
+% If it is an encoded symbol however, its
+% treatment will depend on whether it will be gobbled away or end up
+% in the final substring. If it will be gobbled away, leave it encoded,
+% because the gobbling routine knows how to gobble encoded characters.
+% If it will end up in the substring, manipulate it according to the
+% encoding rules set in |\@defineactions| and rotate it.
+% \begin{macrocode}
+% CHECK IF NEXT CHARACTER IS A SYMBOL
+ \isnextbyte[q]{\EscapeChar}{\rotatingword}%
+ \ifthenelse{\value{@letterindex} < \value{@fromindex}}%
+ {%
+% THIS CHARACTER WILL EVENTUALLY BE GOBBLED
+ \if T\theresult%
+% ROTATE THE ESCAPE CHARACTER, WHICH WILL LEAVE THE SYMBOL ENCODED
+% FOR PROPER GOBBLING (ESCAPE CHARACTER DOESN'T COUNT AS A LETTER)
+ \edef\rotatingword{\@rotate{\rotatingword}}%
+ \addtocounter{@letterindex}{-1}%
+ \else
+% NORMAL CHARACTER OR SYMBOL CODE... ROTATE IT
+ \edef\rotatingword{\@rotate{\rotatingword}}%
+ \fi
+ }%
+ {%
+% THIS CHARACTER WILL EVENTUALLY MAKE IT INTO SUBSTRING
+ \if T\theresult%
+% ROTATE THE SYMBOL USING DEFINED TREATMENT RULES
+ \edef\rotatingword{\ESCrotate{\expandafter\@gobble\rotatingword}}%
+ \else
+% NORMAL CHARACTER... ROTATE IT
+ \edef\rotatingword{\@rotate{\rotatingword}}%
+ \fi
+ }%
+% \end{macrocode}
+% Here, the capitalization trigger persistently tries to turn
+% itself off with each loop
+% through the string rotation. Only if the earlier code found the
+% rotation to be pointing to the blank character(s) between words while
+% |\CapitalizeString| equals 2 will the trigger be prevented from
+% extinguishing itself.
+% \begin{macrocode}
+% DECREMENT CAPITALIZATION TRIGGER TOWARDS 0, EVERY TIME THROUGH LOOP
+ \if 0\arabic{@capstrigger}%
+ \else
+ \addtocounter{@capstrigger}{-1}%
+ \if 0\arabic{@capstrigger}\@relaxcapson\fi
+ \fi
+% \end{macrocode}
+% In addition to the standard |\substring| calls in which fixed
+% substring limits are specified (which in turn fixes the number of
+% character rotations to be executed), some \stringstrings commands
+% want the rotations to continue until a blankspace is located.
+% This bit of code looks for that blank space, if that was the option
+% requested. Once found, the rotation will stop. However, depending
+% on the value of |\SeekBlankSpace|, the remainder of the string may
+% either be retained or discarded.
+% \begin{macrocode}
+% IF SOUGHT SPACE IS FOUND, END ROTATION OF STRING
+ \if 0\SeekBlankSpace\else
+ \isnextbyte[q]{\EncodedBlankSpace}{\rotatingword}%
+ \if F\theresult\isnextbyte[q]{\BlankSpace}{\rotatingword}\fi%
+ \if T\theresult%
+ \if 1\SeekBlankSpace%
+% STOP ROTATION, KEEP REMAINDER OF STRING
+ \setcounter{@maxrotation}{\value{@letterindex}}%
+ \else
+% STOP ROTATION, THROW AWAY REMAINDER OF STRING
+ \addtocounter{@gobblesize}{\value{@maxrotation}}%
+ \setcounter{@maxrotation}{\value{@letterindex}}%
+ \addtocounter{@gobblesize}{-\value{@maxrotation}}%
+ \fi
+ \fi
+ \fi
+ }%
+% \end{macrocode}
+% The loop has ended.\\
+% Gobble up the first |@gobblesize| characters (not bytes!)~of the string,
+% which should leave the desired substring as the remainder. If the
+% mode is verbose, print out the resulting substring.
+% \begin{macrocode}
+% GOBBLE AWAY THAT PART OF STRING THAT ISN'T PART OF REQUESTED SUBSTRING
+ \@gobblearg{\rotatingword}{\arabic{@gobblesize}}%
+ \edef\thestring{\gobbledword}%
+ \if v#1\thestring\fi%
+\?}
+% \end{macrocode}
+% \end{macro}
+
+% Many of the following commands are self-expanatory. The recipe they
+% follow is to use |\Treatments| to specify how different character
+% classes are to be manipulated, and then to call upon |\substring| to
+% effect the desired manipulation. Treatments are typically
+% re-defaulted at the conclusion of the command, which is why the user,
+% if desiring special treatments, should specify those treatments
+% immediately before a call to |\substring|.
+% \begin{macro}{\caseupper}
+% \begin{macrocode}
+% Convert Lower to Uppercase; retain all symbols, numerals,
+% punctuation, and blanks.
+\newcommand\caseupper[2][v]{%
+ \Treatments{1}{2}{1}{1}{1}{1}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\caselower}
+% \begin{macrocode}
+% Convert Upper to Lowercase; retain all symbols, numerals,
+% punctuation, and blanks.
+\newcommand\caselower[2][v]{%
+ \Treatments{2}{1}{1}{1}{1}{1}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\solelyuppercase}
+% \begin{macrocode}
+% Convert Lower to Uppercase; discard symbols, numerals, and
+% punctuation, but keep blanks.
+\newcommand\solelyuppercase[2][v]{%
+ \Treatments{1}{2}{0}{0}{0}{1}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\solelylowercase}
+% \begin{macrocode}
+% Convert Upper to Lowercase; discard symbols, numerals, and
+% punctuation, but keep blanks.
+\newcommand\solelylowercase[2][v]{%
+ \Treatments{2}{1}{0}{0}{0}{1}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\changecase}
+% \begin{macrocode}
+% Convert Lower to Uppercase & Upper to Lower; retain all symbols, numerals,
+% punctuation, and blanks.
+\newcommand\changecase[2][v]{%
+ \Treatments{2}{2}{1}{1}{1}{1}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\noblanks}
+% \begin{macrocode}
+% Remove blanks; retain all else.
+\newcommand\noblanks[2][v]{%
+ \Treatments{1}{1}{1}{1}{1}{0}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\nosymbolsnumerals}
+% \begin{macrocode}
+% Retain case; discard symbols & numerals; retain
+% punctuation & blanks.
+\newcommand\nosymbolsnumerals[2][v]{%
+ \Treatments{1}{1}{1}{0}{0}{1}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\alphabetic}
+% \begin{macrocode}
+% Retain case; discard symbols, numerals &
+% punctuation; retain blanks.
+\newcommand\alphabetic[2][v]{%
+ \Treatments{1}{1}{0}{0}{0}{1}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\capitalize}
+% The command |\CapitalizeString| is not set by |\Treatments|, but
+% only in |\capitalize| or in |\capitalizewords|.
+% \begin{macrocode}
+% Capitalize first character of string,
+\newcommand\capitalize[2][v]{%
+ \defaultTreatments%
+ \def\CapitalizeString{1}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \def\CapitalizeString{0}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\capitalizewords}
+% \begin{macrocode}
+% Capitalize first character of each word in string,
+\newcommand\capitalizewords[2][v]{%
+ \defaultTreatments%
+ \def\CapitalizeString{2}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \def\CapitalizeString{0}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\reversestring}
+% Reverses a string from back to front. To do this, a loop is set
+% up in which characters are grabbed one at a time from the end of the
+% given string, working towards the beginning of the string. The
+% grabbed characters are concatenated onto the end of the working
+% string, |\@reversedstring|. By the time the loop is complete
+% |\@reversedstring| fully represents the reversed string. The result
+% is placed into |\thestring|.
+% \begin{macrocode}
+% REVERSES SEQUENCE OF CHARACTERS IN STRING
+\newcommand\reversestring[2][v]{%
+ \def\@reversedstring{}%
+ \+\@getstringlength{#2}{@@stringsize}\?%
+ \setcounter{@@@letterindex}{\the@@stringsize}%
+ \whiledo{\the@@@letterindex > 0}{%
+ \if e#1%
+ \substring[e]{#2}{\the@@@letterindex}{\the@@@letterindex}%
+ \else
+ \substring[q]{#2}{\the@@@letterindex}{\the@@@letterindex}%
+ \fi
+ \edef\@reversedstring{\@reversedstring\thestring}%
+ \addtocounter{@@@letterindex}{-1}%
+ }%
+ \edef\thestring{\@reversedstring}%
+ \if v#1\thestring\fi%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\convertchar}
+% Takes a string, and replaces each occurance of a specified character
+% with a replacement string. The only complexity in the logic is that
+% a separate replacement algorithm exists depending on whether the
+% specified character to be replaced is a normal character or an
+% encoded character.
+% \begin{macrocode}
+% TAKES A STARTING STRING #2 AND SUBSTITUTES A SPECIFIED STRING #4
+% FOR EVERY OCCURANCE OF A PARTICULAR GIVEN CHARACTER #3. THE
+% CHARACTER TO BE CONVERTED MAY BE EITHER A PLAIN CHARACTER OR
+% AN ENCODABLE SYMBOL.
+\newcommand\convertchar[4][v]{%
+ \+%
+ \edef\encodedstring{#2}%
+ \edef\encodedfromarg{#3}%
+ \edef\encodedtoarg{#4}%
+ \?%
+ \isnextbyte[q]{\EscapeChar}{\encodedfromarg}%
+ \if F\theresult%
+% PLAIN "FROM" ARGUMENT
+ \@convertbytetostring[#1]{\encodedstring}{#3}{\encodedtoarg}%
+ \else
+% ENCODABLE "FROM" ARGUMENT
+ \@convertsymboltostring[#1]{\encodedstring}%
+ {\expandafter\@gobble\encodedfromarg}{\encodedtoarg}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\convertword}
+% Takes a string, a replaces each occurance of a specified string
+% with a replacement string.
+% \begin{macrocode}
+\newcounter{@@matchloc}
+% LIKE \convertchar, EXCEPT FOR WORDS
+\newcommand\convertword[4][v]{%
+ \+\edef\@@teststring{#2}%
+ \edef\@fromstring{#3}%
+ \edef\@tostring{#4}\?%
+ \edef\@@@teststring{\@@teststring}%
+ \def\@buildfront{}%
+ \edef\@buildstring{\@@teststring}%
+ \setcounter{@charsfound}{0}%
+ \whiledo{\the@charsfound > -1}{%
+% \end{macrocode}
+% Seek occurance of |\@fromstring| in larger |\@@teststring|
+% \begin{macrocode}
+ \whereisword[q]{\@@teststring}{\@fromstring}%
+ \setcounter{@matchloc}{\theresult}%
+ \ifthenelse{\the@matchloc = 0}%
+ {%
+% \end{macrocode}
+% Not found. Done.
+% \begin{macrocode}
+ \setcounter{@charsfound}{-1}%
+ }%
+ {%
+% \end{macrocode}
+% Potential matchstring.
+% \begin{macrocode}
+ \addtocounter{@charsfound}{1}%
+% \end{macrocode}
+% Grab current test string from beginning to point just prior
+% to potential match.
+% \begin{macrocode}
+ \addtocounter{@matchloc}{-1}%
+ \substring[e]{\@@@teststring}{1}{\the@matchloc}%
+% \end{macrocode}
+% The string |\@buildfront| is the total original string, with
+% string substitutions, from character 1 to current potential match.
+% \begin{macrocode}
+ \edef\@buildfront{\@buildfront\thestring}%
+% \end{macrocode}
+% See if potential matchstring takes us to end-of-string\ldots
+% \begin{macrocode}
+ \addtocounter{@matchloc}{1}%
+ \addtocounter{@matchloc}{\the@matchsize}%
+ \ifthenelse{\the@matchloc > \the@@@stringsize}%
+ {%
+% \end{macrocode}
+% \ldots if so, then match is last one in string. Tack on replacement
+% string to |\@buildfront| to create final string. Exit.
+% \begin{macrocode}
+ \setcounter{@charsfound}{-1}%
+ \edef\@buildstring{\@buildfront\@tostring}%
+ }%
+ {%
+% \end{macrocode}
+% \ldots if not, redefine current teststring to begin at point following
+% the current substitution. Make substitutions to current
+% |\@buildstring| and |\@buildfront|. Loop through logic again on new
+% teststring.
+% \begin{macrocode}
+ \substring[e]{\@@@teststring}{\the@matchloc}{\@MAXSTRINGSIZE}%
+ \edef\@@teststring{\thestring}%
+ \edef\@@@teststring{\@@teststring}%
+ \edef\@buildstring{\@buildfront\@tostring\@@@teststring}%
+ \edef\@buildfront{\@buildfront\@tostring}%
+ }%
+ }%
+ }%
+ \substring[#1]{\@buildstring}{1}{\@MAXSTRINGSIZE}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\resetlcwords}
+% Removes all words from designated ``lower-case words'' list. This can
+% be useful because large lists of lower-case words can significantly
+% slow-down the function of |\capitalizetitle|.
+% \begin{macrocode}
+\setcounter{@lcwords}{0}
+% RESET LOWER-CASE WORD COUNT; START OVER
+\newcommand\resetlcwords[0]{%
+ \setcounter{@lcwords}{0}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\addlcwords}
+% Add words to the list of designated ``lower-case words'' which will
+% not be capitalized by |\capitalizetitle|. The input should consist of
+% space-separated words, which are, in turn, passed on to |\addlcword|.
+% \begin{macrocode}
+% PROVIDE LIST OF SPACE-SEPARATED WORDS TO REMAIN LOWERCASE IN TITLES
+\newcommand\addlcwords[1]{%
+ \getargs{#1}%
+ \setcounter{@wordindex}{0}%
+ \whiledo{\value{@wordindex} < \narg}{%
+ \addtocounter{@wordindex}{1}%
+ \addlcword{\csname arg\roman{@wordindex}\endcsname}%
+ }
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\addlcword}
+% Add a word to the list of designated ``lower-case words'' which will
+% not be capitalized by |\capitalizetitle|.
+% \begin{macrocode}
+% PROVIDE A SINGLE WORD TO REMAIN LOWERCASE IN TITLES
+\newcommand\addlcword[1]{%
+ \addtocounter{@lcwords}{1}%
+ \expandafter\edef\csname lcword\roman{@lcwords}\endcsname{#1}
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\capitalizetitle}
+% Makes every word of a multi-word input string capitalized, except for
+% specifically noted ``lower-case words'' (examples might include
+% prepositions, conjunctions, \etc). The first word of the input string
+% is capitalized, while lower-case words, previously designated with
+% |\addlcword| and |\addlcwords|, are left in lower case.
+% \begin{macrocode}
+% CAPITALIZE TITLE, EXCEPT FOR DESIGNATED "LOWER-CASE" WORDS
+\newcommand\capitalizetitle[2][v]{%
+% First, capitalize every word (save in encoded form, not printed)
+ \capitalizewords[e]{#2}%
+% Then lowercase words that shouldn't be capitalized, like articles,
+% prepositions, etc. (save in encoded form, not printed)
+ \setcounter{@wordindex}{0}%
+ \whiledo{\value{@wordindex} < \value{@lcwords}}{%
+ \addtocounter{@wordindex}{1}%
+ \edef\mystring{\thestring}%
+ \edef\lcword{\csname lcword\roman{@wordindex}\endcsname}%
+ \capitalize[e]{\lcword}%
+ \edef\ucword{\thestring}%
+ \convertword[e]{\mystring}{\ucword~}{\lcword~}%
+ }
+% Finally, recapitalize the first word of the Title, and print it.
+ \capitalize[#1]{\thestring}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\rotateword}
+% Moves first word of given string |#2| to end of string, including
+% leading and trailing blank spaces.
+% \begin{macrocode}
+\newcommand\rotateword[2][v]{%
+ \+\edef\thestring{#2}\?%
+% \end{macrocode}
+% Rotate leading blank spaces to end of string
+% \begin{macrocode}
+ \@treatleadingspaces[e]{\thestring}{}%
+% \end{macrocode}
+% Define end-of-rotate condition for |\substring| as next blank space
+% \begin{macrocode}
+ \def\SeekBlankSpace{1}%
+% \end{macrocode}
+% Leave rotated characters alone
+% \begin{macrocode}
+ \Treatments{1}{1}{1}{1}{1}{1}%
+% \end{macrocode}
+% Rotate to the next blank space or the end of string, whichever comes
+% first.
+% \begin{macrocode}
+ \substring[e]{\thestring}{1}{\@MAXSTRINGSIZE}%
+% \end{macrocode}
+% Rotate trailing spaces.
+% \begin{macrocode}
+ \@treatleadingspaces[#1]{\thestring}{}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\removeword}
+% Remove the first word of given string |#2|, including leading and
+% trailing spaces. Note that logic is identical to |\rotateword|,
+% except that affected spaces and characters are removed instead of
+% being rotated.
+% \begin{macrocode}
+\newcommand\removeword[2][v]{%
+ \+\edef\thestring{#2}\?%
+% \end{macrocode}
+% The |{x}| final argument indicates to delete leading spaces.
+% \begin{macrocode}
+ \@treatleadingspaces[e]{\thestring}{x}%
+ \def\SeekBlankSpace{1}%
+% \end{macrocode}
+% The Treatments are specified to remove all characters.
+% \begin{macrocode}
+ \Treatments{0}{0}{0}{0}{0}{0}%
+ \substring[e]{\thestring}{1}{\@MAXSTRINGSIZE}%
+% \end{macrocode}
+% Trailing spaces are also deleted.
+% \begin{macrocode}
+ \@treatleadingspaces[#1]{\thestring}{x}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\getnextword}
+% A special case of |\getaword|, where word-to-get is specified as
+% ``1''.
+% \begin{macrocode}
+% GETS NEXT WORD FROM STRING #2.
+% NOTE: ROTATES BACK TO BEGINNING, AFTER STRING OTHERWISE EXHAUSTED
+\newcommand\getnextword[2][v]{%
+ \getaword[#1]{#2}{1}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\getaword}
+% Obtain a specified word number (|#3|) from string |#2|. Logic: rotate
+% leading spaces to end of string; then loop |#3|~--~1 times through
+% |\rotateword|. Finally, get next word.
+% \begin{macrocode}
+% GETS WORD #3 FROM STRING #2.
+% NOTE: ROTATES BACK TO BEGINNING, AFTER STRING OTHERWISE EXHAUSTED
+\newcommand\getaword[3][v]{%
+ \setcounter{@wordindex}{1}%
+ \+\edef\thestring{#2}\?%
+ \@treatleadingspaces[e]{\thestring}{}%
+ \whiledo{\value{@wordindex} < #3}{%
+ \rotateword[e]{\thestring}%
+ \addtocounter{@wordindex}{1}%
+ }%
+ \@getnextword[#1]{\thestring}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\rotateleadingspaces}
+% Rotate leading spaces of string |#2| to the end of string.
+% \begin{macrocode}
+\newcommand\rotateleadingspaces[2][v]{%
+ \@treatleadingspaces[#1]{#2}{}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\removeleadingspaces}
+% Remove leading spaces from string |#2|.
+% \begin{macrocode}
+\newcommand\removeleadingspaces[2][v]{%
+ \@treatleadingspaces[#1]{#2}{x}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\stringencode}
+% \begin{macrocode}
+% ENCODE STRING; UNLIKE OTHER COMMANDS, DEFAULT IS NO PRINT
+\newcommand\stringencode[2][e]{%
+ \defaultTreatments%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\stringdecode}
+% \begin{macrocode}
+% DECODE STRING
+\newcommand\stringdecode[2][v]{%
+ \defaultTreatments%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\gobblechar}
+% Remove first character (not byte!) from string |#2|. Unlike just about
+% all other \stringstrings commands, result is retokenized and not
+% expanded.
+% \begin{macrocode}
+% SINGLE-CHARACTER VERSION OF \gobblechars. IN THIS CASE, TWO-BYTE
+% ESCAPE SEQUENCES, WHEN ENCOUNTERED, COUNT AS A SINGLE GOBBLE.
+\newcommand\gobblechar[2][q]{\+%
+ \@gobblearg{#2}{1}%
+ \?\retokenize[#1]{\gobbledword}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\gobblechars}
+% Remove first |#3| characters (not bytes!) from string |#2|.
+% Unlike just about all other \stringstrings commands, result is
+% retokenized and not expanded.
+% \begin{macrocode}
+% USER CALLABLE VERSION OF \@gobblearg. TURNS ON REENCODING.
+% GOBBLE FIRST #3 CHARACTERS FROM STRING #2. TWO-BYTE
+% ESCAPE SEQUENCES, WHEN ENCOUNTERED, COUNT AS A SINGLE GOBBLE.
+\newcommand\gobblechars[3][q]{\+%
+ \@gobblearg{#2}{#3}%
+ \?\retokenize[#1]{\gobbledword}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\retokenize}
+% One of the key \stringstrings routines that provides several
+% indispensible functions. Its function is to take an encoded string
+% |#2| that has been given, and repopulate the string with its \LaTeX{}
+% tokens in a |\def| form (not an expanded |\edef| form). It is
+% useful if required to operate on a string outside of the
+% \stringstrings library routines, following a \stringstrings
+% manipulation. It is also useful to display certain tokens which
+% cannot be manipulated in expanded form. See
+% Table~\ref{tbl:prob} for a list of tokens that will only work when the
+% resulting string is retokenized (and not expanded).
+%
+% Logic: Loop through each character of given string |#2|. Each
+% successive character of the string is retokenized as |\inexttoken|,
+% |\iinexttoken|, |\iiinexttoken|, |\ivnexttoken|, \etc, respectively.
+% Then a series of strings are formed as\\
+% \\
+% |\def\buildtoken{}|\\
+% |\def\buildtokeni{\builtoken\inexttoken}|\\
+% |\def\buildtokenii{\builtokeni\iinexttoken}|\\
+% |\def\buildtokeniii{\builtokenii\iiinexttoken}|\\
+% |\def\buildtokeniv{\builtokeniii\ivnexttoken}|\\
+% \\
+% The last in the sequence of |\builtoken...| strings (renamed
+% |\buildtokenq|) is the retokenized
+% version of string |#2|.
+% \begin{macrocode}
+% CONVERTS ENCODED STRING BACK INTO TOKENIZED FORM (i.e., def'ED).
+\newcommand\retokenize[2][q]{\+%
+ \edef\@svstring{#2}%
+ \edef\buildtoken{}%
+ \@getstringlength{#2}{@@stringsize}\?%
+ \setcounter{@@letterindex}{0}%
+ \whiledo{\the@@letterindex < \the@@stringsize}{%
+ \setcounter{@previousindex}{\the@@letterindex}%
+ \addtocounter{@@letterindex}{1}%
+ \substring[e]{\@svstring}{\the@@letterindex}{\the@@letterindex}%
+ \@retokenizechar{\thestring}{\roman{@@letterindex}nexttoken}%
+ \expandafter\def\csname buildtoken\roman{@@letterindex}%
+ \expandafter\endcsname\expandafter%
+ {\csname buildtoken\roman{@previousindex}\expandafter\endcsname%
+ \csname\roman{@@letterindex}nexttoken\endcsname}%
+ }%
+ \expandafter\def\expandafter\buildtokenq\expandafter{%
+ \csname buildtoken\roman{@@letterindex}\endcsname}%
+ \def\thestring{\buildtokenq}%
+ \if v#1\thestring\fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macrocode}
+% %%%%% COMMANDS TO EXTRACT STRING INFORMATION %%%%%%%%%%%%%%%%%%%%%%%%%%
+% \end{macrocode}
+
+% The following group of commands extract information about a string,
+% and store the result in a string called |\theresult|. Since the
+% result is not a substring, a \textit{mode} of |[e]| carries no
+% meaning. Only |[v]| and |[q]| modes apply here.
+% \begin{macro}{\stringlength}
+% Returns the length of the given string in \textit{characters}, not
+% \textit{bytes}.
+% \begin{macrocode}
+% USER CALLABLE VERSION of \@getstringlength:
+% GET'S STRING LENGTH OF [#2], PUTS RESULT IN \theresult. PRINTS RESULT
+% UNLESS IN QUIET [q] MODE.
+\newcommand\stringlength[2][v]{\+%
+ \@getstringlength{#2}{@@stringsize}%
+ \edef\theresult{\arabic{@@stringsize}}%
+ \if v#1\theresult\fi%
+\?}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\findchars}
+% Find number of occurances of character |#3| in string |#2|.
+% \begin{macrocode}
+% CHECKS TO SEE IF THE CHARACTER [#3] APPEARS ANYWHERE IN STRING [#2].
+% THE NUMBER OF OCCURANCES IS PRINTED OUT, EXCEPT WHEN [#1]=q, QUIET
+% MODE. RESULT IS ALSO STORED IN \theresult . TO FIND SPACES, ARG3
+% SHOULD BE SET TO {~}, NOT { }.
+\newcommand\findchars[3][v]{\+%
+ \@getstringlength{#2}{@@stringsize}%
+ \setcounter{@charsfound}{0}%
+ \setcounter{@@letterindex}{0}%
+% \end{macrocode}
+% Loop through each character of |#2|.
+% \begin{macrocode}
+ \whiledo{\value{@@letterindex} < \value{@@stringsize}}{%
+ \addtocounter{@@letterindex}{1}%
+% \end{macrocode}
+% Test if the |@@letterindex| character of string |#2| equals |#3|.
+% If so, add to tally.
+% \begin{macrocode}
+ \testmatchingchar{#2}{\arabic{@@letterindex}}{#3}%
+ \ifmatchingchar\addtocounter{@charsfound}{1}\fi
+ }%
+ \edef\theresult{\arabic{@charsfound}}%
+ \if q#1\else\theresult\fi%
+\?}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\whereischar}
+% Similar to |\findchars|, but instead finds first occurance of match
+% character |#3| within |#2| and returns its location within |#2|.
+% \begin{macrocode}
+% CHECKS TO FIND LOCATION OF FIRST OCCURANCE OF [#3] IN STRING [#2].
+% THE LOCATION IS PRINTED OUT, EXCEPT WHEN [#1]=q, QUIET
+% MODE. RESULT IS ALSO STORED IN \theresult . TO FIND SPACES, ARG3
+% SHOULD BE SET TO {~}, NOT { }.
+\newcommand\whereischar[3][v]{\+%
+ \@getstringlength{#2}{@@stringsize}%
+ \edef\@theresult{0}%
+ \setcounter{@@letterindex}{0}%
+% \end{macrocode}
+% Loop through characters of |#2| sequentially.
+% \begin{macrocode}
+ \whiledo{\value{@@letterindex} < \value{@@stringsize}}{%
+ \addtocounter{@@letterindex}{1}%
+% \end{macrocode}
+% Look for match. If found, save character-location index,
+% and reset loop index to break from loop.
+% \begin{macrocode}
+ \testmatchingchar{#2}{\arabic{@@letterindex}}{#3}%
+ \ifmatchingchar%
+ \edef\@theresult{\the@@letterindex}%
+ \setcounter{@@letterindex}{\the@@stringsize}%
+ \fi
+ }%
+ \edef\theresult{\@theresult}%
+ \if q#1\else\theresult\fi%
+\?}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\whereisword}
+% Finds location of specified word (|#3|) in string |#2|.
+% \begin{macrocode}
+% LIKE \whereischar, EXCEPT FOR WORDS
+\newcommand\whereisword[3][v]{\+%
+ \setcounter{@skipped}{0}%
+% \end{macrocode}
+% |\@@@@teststring| initially contains |#2|. As false alarms are
+% located, the string will be redefined to lop off initial characters
+% of string.
+% \begin{macrocode}
+ \edef\@@@@teststring{#2}%
+ \edef\@matchstring{#3}%
+ \@getstringlength{#2}{@@stringsize}%
+ \setcounter{@@@stringsize}{\value{@@stringsize}}%
+ \@getstringlength{#3}{@matchsize}%
+ \setcounter{@matchmax}{\the@@stringsize}%
+ \addtocounter{@matchmax}{-\the@matchsize}%
+ \addtocounter{@matchmax}{1}%
+ \setcounter{@flag}{0}%
+% \end{macrocode}
+% Define |\matchchar| as the first character of the match string (|#3|).
+% \begin{macrocode}
+ \substring[e]{#3}{1}{1}%
+ \edef\matchchar{\thestring}%
+ \whiledo{\the@flag = 0}{%
+% \end{macrocode}
+% Look for first character of match string within |\@@@@teststring|.
+% \begin{macrocode}
+ \whereischar[q]{\@@@@teststring}{\matchchar}%
+ \setcounter{@matchloc}{\theresult}%
+ \ifthenelse{\equal{0}{\value{@matchloc}}}%
+% \end{macrocode}
+% If none found, we are done.
+% \begin{macrocode}
+ {%
+ \setcounter{@flag}{1}%
+ }%
+% \end{macrocode}
+% If |\matchchar| is found, must determine if it is the beginning
+% of the match string, or just an extraneous match (\ie false alarm).
+% Extract substring
+% of |\@@@@teststring|, of a size equal to the match string.
+% Compare this extracted string with the match string.
+% \begin{macrocode}
+ {%
+ \setcounter{@matchend}{\theresult}%
+ \addtocounter{@matchend}{\value{@matchsize}}%
+ \addtocounter{@matchend}{-1}%
+ \substring[e]{\@@@@teststring}{\the@matchloc}{\the@matchend}%
+ \ifthenelse{\equal{\thestring}{\@matchstring}}%
+% \end{macrocode}
+% Found a match! Save the match location
+% \begin{macrocode}
+ {%
+ \setcounter{@flag}{1}%
+ \addtocounter{@matchloc}{\the@skipped}%
+ \edef\theresult{\the@matchloc}%
+ }%
+% \end{macrocode}
+% False alarm. Determine if lopping off the leading characters of
+% |\@@@@teststring| (to discard the false-alarm occurance) is feasible.
+% If lopping would take one past the end of the string,
+% then no match is possible. If lopping permissible, redefine the
+% string |\@@@@teststring|, keeping track of the total number of
+% lopped-off characters in the counter |@skipped|.
+% \begin{macrocode}
+ {%
+ \addtocounter{@skipped}{\the@matchloc}%
+ \addtocounter{@matchloc}{1}%
+ \ifthenelse{\value{@matchloc} > \value{@matchmax}}%
+ {%
+ \setcounter{@flag}{1}%
+ \edef\theresult{0}%
+ }%
+ {%
+ \substring[e]{\@@@@teststring}{\the@matchloc}{\@MAXSTRINGSIZE}%
+ \edef\@@@@teststring{\thestring}%
+ }%
+ }%
+ }%
+ }%
+ \if q#1\else\theresult\fi%
+\?}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\findwords}
+% Finds the number of occurances of a word within the provided string
+% \begin{macrocode}
+% LIKE \findchar, EXCEPT FOR WORDS
+\newcommand\findwords[3][v]{%
+ \+\edef\@@teststring{#2}\?%
+ \edef\@@@teststring{\@@teststring}%
+ \setcounter{@charsfound}{0}%
+ \whiledo{\the@charsfound > -1}{%
+% \end{macrocode}
+% Seek occurance of |#3| in the string to be tested
+% \begin{macrocode}
+ \whereisword[q]{\@@teststring}{#3}%
+ \setcounter{@matchloc}{\theresult}%
+ \ifthenelse{\the@matchloc = 0}%
+ {%
+% \end{macrocode}
+% None found. Break from loop.
+% \begin{macrocode}
+ \edef\theresult{\the@charsfound}%
+ \setcounter{@charsfound}{-1}%
+ }%
+ {%
+% \end{macrocode}
+% Found. Increment count.
+% \begin{macrocode}
+ \addtocounter{@charsfound}{1}%
+ \addtocounter{@matchloc}{\the@matchsize}%
+ \ifthenelse{\the@matchloc > \the@@stringsize}%
+ {%
+% \end{macrocode}
+% This "find" takes us to the end-of-string. Break from loop now.
+% \begin{macrocode}
+ \edef\theresult{\the@charsfound}%
+ \setcounter{@charsfound}{-1}%
+ }%
+ {%
+% \end{macrocode}
+% More string to search. Lop off what has been searched from string to
+% be tested, and re-loop for next search.
+% \begin{macrocode}
+ \substring[e]{\@@@teststring}{\the@matchloc}{\@MAXSTRINGSIZE}%
+ \edef\@@teststring{\thestring}%
+ \edef\@@@teststring{\@@teststring}%
+ }%
+ }%
+ }%
+ \if q#1\else\theresult\fi%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\wordcount}
+% Counts words (space-separated text) in a string. Simply removes one
+% word at a time, counting the words as it goes. With each removal,
+% checks for non-zero string size remaining.
+% \begin{macrocode}
+% WORD COUNT
+\newcommand\wordcount[2][v]{\+%
+ \edef\@argv{#2}
+ \@getstringlength{\@argv}{@stringsize}
+ \setcounter{@iargc}{0}
+ \whiledo{\value{@stringsize} > 0}{%
+ \addtocounter{@iargc}{1}%
+ \removeword[e]{\@argv}%
+ \edef\@argv{\thestring}%
+ \@getstringlength{\@argv}{@stringsize}%
+ }
+ \edef\theresult{\arabic{@iargc}}%
+ \if v#1\theresult\fi%
+\?}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\getargs}
+% Parse a string of arguments in Unix-like manner. Define |\argv| as |#2|.
+% Grabs leading word from |\argv| and puts it in |\argi|. Increment
+% argument count; remove leading word from |\argv|. Repeat this process,
+% with each new argument being placed in |\argii|, |\argiii|, |\argiv|,
+% \etc~ Continue until size of |\argv| is exhausted.
+% \begin{macrocode}
+% OBTAINS ARGUMENTS (WORDS) IN #1 ALA UNIX getarg COMMAND
+% narg CONTAINS NUMBER OF ARGUMENTS. ARGUMENTS CONTAINED IN
+% argi, argii, argiii, argiv, ETC.
+% v mode disabled
+\newcommand\getargs[2][q]{\+%
+ \if v#1\def\@mode{q}\else\def\@mode{#1}\fi%
+ \edef\@argv{#2}%
+ \@getstringlength{\@argv}{@stringsize}%
+ \setcounter{@iargc}{0}%
+ \whiledo{\value{@stringsize} > 0}{%
+ \addtocounter{@iargc}{1}%
+ \getaword[\@mode]{\@argv}{1}%
+ \expandafter\edef\csname arg\roman{@iargc}\endcsname{\thestring}%
+ \removeword[e]{\@argv}%
+ \edef\@argv{\thestring}%
+ \@getstringlength{\@argv}{@stringsize}%
+ }%
+ \edef\narg{\arabic{@iargc}}%
+\?}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macrocode}
+%%%%% COMMANDS TO TEST STRINGS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \end{macrocode}
+
+% The following group of commands test for various alphanumeric
+% string conditions.
+% \begin{macro}{\isnextbyte}
+% This routine performs a simple test to determine if the first byte of
+% string |#3| matches the byte given by |#2|. The only problem is that
+% the test can produce a false negative if the first byte of the test
+% string equals the match byte and the second byte of the test string
+% equals the |SignalChar| (defined below).
+%
+% To resolve this possibility, the test is performed twice with two
+% different values for |\SignalChar|, only one of which can produce
+% a false negative for a given test string. If the two results match,
+% then that result gives the correct answer to the question of whether
+% the first byte of |#3| equals |#2|. If, however, the two results fail
+% to match, then one can assume that one of the results is a false
+% negative, and so a ``true'' condition results.
+% \begin{macrocode}
+% \end{macrocode}
+% The following two ``signal characters,'' used for the two tests,
+% can be any two distinct characters. They are used solely
+% by |\isnextbyte|.
+% \begin{macrocode}
+\def\PrimarySignalChar{@}
+\def\SecondarySignalChar{`}
+
+% \isnextbyte NEEDS TO OPERATE IN RAW (SINGLE BYTE) MODE SO AS TO
+% PERFORM TESTS FOR PRESENCE OF \EscapeChar
+% \end{macrocode}
+% Incidentally,
+% |\isnextbyte| can and is used by \stringstrings to detect
+% multi-byte characters in a manner which may also be employed by the
+% user. To do this:
+% First, the string to be tested should be encoded. Then, |\isnextbyte|
+% may be used to check for |\EscapeChar| which is how every multi-byte
+% character will begin its encoding by the \stringstrings package.
+% If |\EscapeChar| is detected as the next character, then the string to
+% test may have its leading byte gobbled and the next character (called
+% the Escape Code) may be tested, and compared against the known
+% \stringstrings escape codes. The combination of
+% Escape-Character/Escape-Code is how all multi-byte characters are
+% encoded by the \stringstrings package.
+% \begin{macrocode}
+\newcommand\isnextbyte[3][v]{%
+% \end{macrocode}
+% Here's the first test\ldots
+% \begin{macrocode}
+ \let\SignalChar\PrimarySignalChar%
+ \edef\@x{\if #2#3\else\SignalChar\fi}%
+ \edef\@x{\if \SignalChar\@x F\else T\fi}%
+% \end{macrocode}
+% \ldots and the second
+% \begin{macrocode}
+ \let\SignalChar\SecondarySignalChar%
+ \edef\@y{\if #2#3\else\SignalChar\fi}%
+ \edef\@y{\if \SignalChar\@y F\else T\fi}%
+% \end{macrocode}
+% If the two tests produced the same result, then a comparison of |\@x\@y|
+% and |\@y\@x| will show it.
+% \begin{macrocode}
+% BECAUSE THE METHOD ONLY PRODUCES FALSE NEGATIVES, IF RESULTS DON'T
+% AGREE FROM USING TWO DIFFERENT SIGNAL CHARACTERS, RESULT MUST BE TRUE.
+ \ifthenelse{\equal{\@x\@y}{\@y\@x}}
+ {\edef\theresult{\@x}}%
+% CORRECT THE FALSE NEGATIVE
+ {\edef\theresult{T}}%
+ \if q#1\else\theresult\fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\testmatchingchar}
+% This routine checks for a specified match-character within a target
+% string. Unlike |\isnextbyte|, this
+% routine checks for characters (single- or multi-byte) and not just
+% individual bytes. Additionally, rather than testing the
+% match-character against the first byte of the test-string, the user
+% specifies (through |#2|) which byte of the test-string should be
+% compared to the match-character.
+%
+% This routine is not as efficient as |\isnextbyte|, but much more
+% versatile.
+% \begin{macrocode}
+% CHECKS TO SEE IF [#2]'th CHARACTER IN STRING [#1] EQUALS [#3]
+% RESULT STORED IN BOOLEAN \ifmatchingchar
+\newif\ifmatchingchar
+\newcommand\testmatchingchar[3]{%
+ \setbox0=\hbox{%
+% \end{macrocode}
+% Extract desired character from test string
+% \begin{macrocode}
+ \substring[e]{#1}{#2}{#2}\+%
+% \end{macrocode}
+% Determine if the match-character is a multi-byte symbol.
+% \begin{macrocode}
+ \isnextbyte[q]{\EscapeChar}{#3}%
+ \if T\theresult%
+% \end{macrocode}
+% Is the tested character also a multi-byte symbol?
+% \begin{macrocode}
+ \isnextbyte[q]{\EscapeChar}{\thestring}%
+ \if T\theresult%
+% \end{macrocode}
+% Yes it is\ldots Therefore, compare codes following the escape character
+% \begin{macrocode}
+ \edef\@testcode{\expandafter\@DiscardNextChar\expandafter{#3}}%
+ \edef\@teststring{\@DiscardNextChar{\thestring}}%
+ \if \@teststring\@testcode\matchingchartrue\else\matchingcharfalse\fi
+ \else
+% \end{macrocode}
+% No, we are comparing a normal character against a multi-byte symbol
+% (apples and oranges), a false comparison.
+% \begin{macrocode}
+ \global\matchingcharfalse%
+ \fi
+ \else
+% \end{macrocode}
+% No, we are comparing two normal one-byte characters, not a mult-byte
+% character.
+% \begin{macrocode}
+ \if \thestring#3\global\matchingchartrue\else\global\matchingcharfalse\fi
+ \fi}%
+\?}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\testcapitalized}
+% This routine checks to see if first character of string is
+% capitalized. The only quirk is that the routine must ascertain
+% whether that character is a single-byte character or a multi-byte
+% character.
+% \begin{macrocode}
+\newif\ifcapitalized
+\newcommand\testcapitalized[1]{\+%
+ \setbox0=\hbox{%
+ \isnextbyte[q]{\EscapeChar}{#1}%
+ \if T\theresult%
+ \def\EncodingTreatment{e}%
+ \edef\rotatingword{#1}%
+% \end{macrocode}
+% Rotate the first [multi-byte] character of the string to the end
+% of the string, lowering its case. Store as |\@stringA|.
+% \begin{macrocode}
+ \def\AlphaCapsTreatment{2}%
+ \@defineactions%
+ \edef\@stringA{\ESCrotate{\expandafter\@gobble\rotatingword}}%
+% \end{macrocode}
+% Rotate the first [multi-byte] character of the string to the end
+% of the string, retaining its case. Store as |\@stringB|.
+% \begin{macrocode}
+ \def\AlphaCapsTreatment{1}%
+ \@defineactions%
+ \edef\@stringB{\ESCrotate{\expandafter\@gobble\rotatingword}}%
+ \else
+% \end{macrocode}
+% \ldots or, if the first character is a normal one-byte character\ldots
+% Rotate the first [normal] character of the string to the end
+% of the string, lowering its case. Store as |\@stringA|.
+% \begin{macrocode}
+ \def\AlphaCapsTreatment{2}%
+ \edef\@stringA{\@rotate{#1}}%
+% \end{macrocode}
+% Rotate the first [normal] character of the string to the end
+% of the string, retaining its case. Store as |\@stringB|.
+% \begin{macrocode}
+ \def\AlphaCapsTreatment{1}%
+ \edef\@stringB{\@rotate{#1}}%
+ \fi
+% \end{macrocode}
+% Compare strings A and B, to see if changing the case of first letter
+% altered the string
+% \begin{macrocode}
+ \ifthenelse{\equal{\@stringA}{\@stringB}}%
+ {\global\capitalizedfalse}{\global\capitalizedtrue}}\?%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\testuncapitalized}
+% This routine is the complement of |\testcapitalized|. The only
+% difference is that the |\@stringA| has its case made upper for the
+% comparison, instead of lowered.
+% \begin{macrocode}
+\newif\ifuncapitalized
+\newcommand\testuncapitalized[1]{\+%
+ \setbox0=\hbox{%
+ \isnextbyte[q]{\EscapeChar}{#1}%
+ \if T\theresult%
+ \def\EncodingTreatment{e}%
+ \edef\rotatingword{#1}%
+ \def\AlphaTreatment{2}%
+ \@defineactions%
+ \edef\@stringA{\ESCrotate{\expandafter\@gobble\rotatingword}}%
+ \def\AlphaTreatment{1}%
+ \@defineactions%
+ \edef\@stringB{\ESCrotate{\expandafter\@gobble\rotatingword}}%
+ \else
+ \def\AlphaTreatment{2}%
+ \edef\@stringA{\@rotate{#1}}%
+ \def\AlphaTreatment{1}%
+ \edef\@stringB{\@rotate{#1}}%
+ \fi
+ \ifthenelse{\equal{\@stringA}{\@stringB}}%
+ {\global\uncapitalizedfalse}{\global\uncapitalizedtrue}}\?%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\testleadingalpha}
+% Test if the leading character of the string is alphabetic. This is
+% simply accomplished by checking whether the string is either
+% capitalized or uncapitalized. If non-alphabetic, it will show
+% up as false for both those tests.
+% \begin{macrocode}
+\newif\ifleadingalpha
+\newcommand\testleadingalpha[1]{%
+ \testcapitalized{#1}%
+ \ifcapitalized
+ \leadingalphatrue%
+ \else
+ \testuncapitalized{#1}%
+ \ifuncapitalized
+ \leadingalphatrue%
+ \else
+ \leadingalphafalse%
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\testuppercase}
+% Checks to see if all alphabetic characters in a string are uppercase.
+% Non-alphabetic characters don't affect the result, unless the string
+% is composed solely of nonalphabetic characters, in which case the test
+% results is false.
+% \begin{macrocode}
+\newif\ifuppercase
+\newcommand\testuppercase[1]{%
+ \setbox0=\hbox{%
+% \end{macrocode}
+% Strip all non-alphabetic characters. Save as |\@stringA|.
+% \begin{macrocode}
+ \Treatments{1}{1}{0}{0}{0}{0}%
+ \substring[e]{#1}{1}{\@MAXSTRINGSIZE}%
+ \edef\@stringA{\thestring}%
+% \end{macrocode}
+% Lower the case of all uppercase characters in |\@stringA|. Save as
+% |\@stringB|. Compare these two strings.
+% \begin{macrocode}
+ \def\AlphaTreatment{2}%
+ \substring[e]{#1}{1}{\@MAXSTRINGSIZE}%
+ \edef\@stringB{\thestring}%
+ \ifthenelse{\equal{\@stringA}{\@stringB}}%
+ {%
+% \end{macrocode}
+% If the strings are equal, then all the alphabetic characters in the
+% original string were uppercase. Need only check to make sure at
+% least one alphabetic character was present in the original string.
+% \begin{macrocode}
+ \@getstringlength{\@stringA}{@stringsize}%
+ \ifthenelse{\value{@stringsize} = 0}%
+ {\global\uppercasefalse}{\global\uppercasetrue}%
+ }%
+% \end{macrocode}
+% If strings are not equal, then the alphabetic characters of the
+% original string were not all uppercase. Test false.
+% \begin{macrocode}
+ {\global\uppercasefalse}}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\ifsolelyuppercase}
+% Compare the original string to one made solely uppercase. If they are
+% equal (and not composed solely of blankspaces), then the original
+% string was solely uppercase to begin with.
+% \begin{macrocode}
+\newif\ifsolelyuppercase
+\newcommand\testsolelyuppercase[1]{%
+ \setbox0=\hbox{%
+ \stringencode{#1}%
+ \edef\@stringA{\thestring}%
+ \solelyuppercase[e]{#1}%
+ \edef\@stringB{\thestring}%
+ \ifthenelse{\equal{\@stringA}{\@stringB}}%
+ {%
+ \noblanks[q]{\@stringA}%
+ \@getstringlength{\thestring}{@stringsize}%
+ \ifthenelse{\value{@stringsize} = 0}%
+ {\global\solelyuppercasefalse}{\global\solelyuppercasetrue}%
+ }%
+ {\global\solelyuppercasefalse}}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\testlowercase}
+% This routine is the complement to |\testuppercase|, with corresponding
+% logic.
+% \begin{macrocode}
+\newif\iflowercase
+\newcommand\testlowercase[1]{%
+ \setbox0=\hbox{%
+ \Treatments{1}{1}{0}{0}{0}{0}%
+ \substring[e]{#1}{1}{\@MAXSTRINGSIZE}%
+ \edef\@stringA{\thestring}%
+ \def\AlphaCapsTreatment{2}%
+ \substring[e]{#1}{1}{\@MAXSTRINGSIZE}%
+ \edef\@stringB{\thestring}%
+ \ifthenelse{\equal{\@stringA}{\@stringB}}%
+ {%
+ \@getstringlength{\@stringA}{@stringsize}%
+ \ifnum\value{@stringsize}= 0\relax%
+ \global\lowercasefalse\else\global\lowercasetrue\fi%
+ }%
+ {\global\lowercasefalse}}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\testsolelylowercase}
+% This routine is the complement to |\testsolelyuppercase|, with
+% corresponding logic.
+% \begin{macrocode}
+\newif\ifsolelylowercase
+\newcommand\testsolelylowercase[1]{%
+ \setbox0=\hbox{%
+ \stringencode{#1}%
+ \edef\@stringA{\thestring}%
+ \solelylowercase[e]{#1}%
+ \edef\@stringB{\thestring}%
+ \ifthenelse{\equal{\@stringA}{\@stringB}}%
+ {%
+ \noblanks[q]{\@stringA}%
+ \@getstringlength{\thestring}{@stringsize}%
+ \ifthenelse{\value{@stringsize} = 0}%
+ {\global\solelylowercasefalse}{\global\solelylowercasetrue}%
+ }%
+ {\global\solelylowercasefalse}}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\testalphabetic}
+% Comparable to |\testsolelyuppercase| and
+% |\testsolelylowercase| in its logic, this routine tests whether
+% the string is purely alphabetic or not.
+% \begin{macrocode}
+\newif\ifalphabetic
+\newcommand\testalphabetic[1]{%
+ \setbox0=\hbox{%
+ \stringencode{#1}%
+ \edef\@stringA{\thestring}%
+ \alphabetic[e]{#1}%
+ \edef\@stringB{\thestring}%
+ \ifthenelse{\equal{\@stringA}{\@stringB}}%
+ {%
+ \noblanks[q]{\@stringA}%
+ \@getstringlength{\thestring}{@stringsize}%
+ \ifthenelse{\value{@stringsize} = 0}%
+ {\global\alphabeticfalse}{\global\alphabetictrue}%
+ }%
+ {\global\alphabeticfalse}}%
+ \defaultTreatments%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macrocode}
+%
+%%%%% SUPPORT ROUTINES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \end{macrocode}
+% The following routines support the execution of the \stringstrings
+% package.
+
+% \begin{macro}{\ESCrotate}
+% After the escape character has been ascertained as the next character,
+% this routine operates on the subsequent escape code to rotate the
+% symbol to end of string, in the fashion of macro |\@rotate|.
+% \begin{macrocode}
+\newcommand\ESCrotate[1]{%
+ \if\UvariCode#1\@uvariaction\else
+ \if\UvariiCode#1\@uvariiaction\else
+ \if\UvariiiCode#1\@uvariiiaction\else
+ \if\@fromcode#1\@tostring\else
+ \if\PipeCode#1\@pipeaction\else
+ \if\DollarCode#1\@dollaraction\else
+ \if\CaratCode#1\@carataction\else
+ \if\CircumflexCode#1\@circumflexaction\else
+ \if\TildeCode#1\@tildeaction\else
+ \if\UmlautCode#1\@umlautaction\else
+ \if\GraveCode#1\@graveaction\else
+ \if\AcuteCode#1\@acuteaction\else
+ \if\MacronCode#1\@macronaction\else
+ \if\OverdotCode#1\@overdotaction\else
+ \if\LeftBraceCode#1\@leftbraceaction\else
+ \if\RightBraceCode#1\@rightbraceaction\else
+ \if\UnderscoreCode#1\@underscoreaction\else
+ \if\DaggerCode#1\@daggeraction\else
+ \if\DoubleDaggerCode#1\@doubledaggeraction\else
+ \if\SectionSymbolCode#1\@sectionsymbolaction\else
+ \if\PilcrowCode#1\@pilcrowaction\else
+ \if\LBCode#1\@lbaction\else
+ \if\RBCode#1\@rbaction\else
+ \if\BreveCode#1\@breveaction\else
+ \if\CaronCode#1\@caronaction\else
+ \if\DoubleAcuteCode#1\@doubleacuteaction\else
+ \if\CedillaCode#1\@cedillaaction\else
+ \if\UnderdotCode#1\@underdotaction\else
+ \if\ArchJoinCode#1\@archjoinaction\else
+ \if\LineUnderCode#1\@lineunderaction\else
+ \if\CopyrightCode#1\@copyrightaction\else
+ \if\PoundsCode#1\@poundsaction\else
+ \if\AEscCode#1\@AEscaction\else
+ \if\aescCode#1\@aescaction\else
+ \if\OEthelCode#1\@OEthelaction\else
+ \if\oethelCode#1\@oethelaction\else
+ \if\AngstromCode#1\@Angstromaction\else
+ \if\angstromCode#1\@angstromaction\else
+ \if\SlashedOCode#1\@slashedOaction\else
+ \if\SlashedoCode#1\@slashedoaction\else
+ \if\BarredlCode#1\@barredlaction\else
+ \if\BarredLCode#1\@barredLaction\else
+ \if\EszettCode#1\@eszettaction\else
+ \expandafter\@gobble#1\undecipherable%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@getnextword}
+% A low-level routine designed to extract the next [space-delimited]
+% word of the primary
+% argument. It has several quirks: if the passed string has one leading
+% space, it is included as part of next word. If it has two leading
+% [hard]spaces, the 2$^\mathrm{nd}$ hard space \textit{is} the next word.
+% Using the higher-level |\getnextword| deals automatically with
+% these abberant possibilities.
+% \begin{macrocode}
+\newcommand\@getnextword[2][v]{%
+ \defaultTreatments%
+ \def\SeekBlankSpace{2}%
+ \substring[#1]{#2}{1}{\@MAXSTRINGSIZE}%
+ \def\SeekBlankSpace{0}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@retokenizechar}
+% This command is the guts of the retokenize command. It grabs the
+% character provided in string |#1| and assigns it to a unique token
+% whose name is created from the string |#2|. The command has two
+% primary |\if| branches. The first branch is taken if the
+% character is a special two-byte-encoded escape-sequence, while
+% the second branch is taken if the character is a |&|, |%|, |#|,
+% a blankspace, or any simple one-byte character.
+% \begin{macrocode}
+\newcommand\@retokenizechar[2]{%
+ \isnextbyte[q]{\EscapeChar}{#1}%
+ \if T\theresult%
+ \edef\@ESCcode{\expandafter\@gobble#1}%
+ \if\UvariCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\Uvari}\else
+ \if\UvariiCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\Uvarii}\else
+ \if\UvariiiCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\Uvariii}\else
+ \if\PipeCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\Pipe}\else
+ \if\DollarCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\$}\else
+ \if\CaratCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\Carat}\else
+ \if\CircumflexCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\^}\else
+ \if\TildeCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\~}\else
+ \if\UmlautCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\"}\else
+ \if\GraveCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\`}\else
+ \if\AcuteCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\'}\else
+ \if\MacronCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\=}\else
+ \if\OverdotCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\.}\else
+ \if\LeftBraceCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\{}\else
+ \if\RightBraceCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\}}\else
+ \if\UnderscoreCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\_}\else
+ \if\DaggerCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\dag}\else
+ \if\DoubleDaggerCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\ddag}\else
+ \if\SectionSymbolCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\S}\else
+ \if\PilcrowCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\P}\else
+ \if\LBCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\SaveLB}\else
+ \if\RBCode\@ESCcode%
+ \expandafter\def\csname#2\endcsname{\SaveRB}\else
+ \if\BreveCode\@ESCcode\expandafter\def\csname#2\endcsname{\u}\else
+ \if\CaronCode\@ESCcode\expandafter\def\csname#2\endcsname{\v}\else
+ \if\DoubleAcuteCode\@ESCcode\expandafter\def\csname#2\endcsname{\H}\else
+ \if\CedillaCode\@ESCcode\expandafter\def\csname#2\endcsname{\c}\else
+ \if\UnderdotCode\@ESCcode\expandafter\def\csname#2\endcsname{\d}\else
+ \if\ArchJoinCode\@ESCcode\expandafter\def\csname#2\endcsname{\t}\else
+ \if\LineUnderCode\@ESCcode\expandafter\def\csname#2\endcsname{\b}\else
+ \if\CopyrightCode\@ESCcode\expandafter\def\csname#2\endcsname{\copyright}\else
+ \if\PoundsCode\@ESCcode\expandafter\def\csname#2\endcsname{\pounds}\else
+ \if\AEscCode\@ESCcode\expandafter\def\csname#2\endcsname{\AE}\else
+ \if\aescCode\@ESCcode\expandafter\def\csname#2\endcsname{\ae}\else
+ \if\OEthelCode\@ESCcode\expandafter\def\csname#2\endcsname{\OE}\else
+ \if\oethelCode\@ESCcode\expandafter\def\csname#2\endcsname{\oe}\else
+ \if\AngstromCode\@ESCcode\expandafter\def\csname#2\endcsname{\AA}\else
+ \if\angstromCode\@ESCcode\expandafter\def\csname#2\endcsname{\aa}\else
+ \if\SlashedOCode\@ESCcode\expandafter\def\csname#2\endcsname{\O}\else
+ \if\SlashedoCode\@ESCcode\expandafter\def\csname#2\endcsname{\o}\else
+ \if\BarredlCode\@ESCcode\expandafter\def\csname#2\endcsname{\l}\else
+ \if\BarredLCode\@ESCcode\expandafter\def\csname#2\endcsname{\L}\else
+ \if\EszettCode\@ESCcode\expandafter\def\csname#2\endcsname{\ss}\else
+ \expandafter\def\csname#2\endcsname{\undecipherable}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \else
+ \expandafter\ifx\expandafter\&#1%
+ \expandafter\def\csname#2\endcsname{\&}\else
+ \expandafter\ifx\expandafter\%#1%
+ \expandafter\def\csname#2\endcsname{\%}\else
+ \expandafter\ifx\expandafter\##1%
+ \expandafter\def\csname#2\endcsname{\#}\else
+ \if\EncodedBlankSpace#1\expandafter\def\csname#2\endcsname{\ }\else
+ \expandafter\edef\csname#2\endcsname{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@defineactions}
+% This routine defines how encoded characters are to be treated by the
+% |\ESCrotate| routine, depending on the [encoding, capitalization,
+% blank, symbol, \textit{etc.}] treatments that have
+% been \textit{a priori} specified.
+% \begin{macrocode}
+% \@blankaction AND OTHER ...action'S ARE SET, DEPENDING ON VALUES OF
+% TREATMENT FLAGS. CHARS ARE EITHER ENCODED, DECODED, OR REMOVED.
+\newcommand\@defineactions{%
+% SET UP TREATMENT FOR SPACES, ENCODED SPACES, AND [REENCODED] SYMBOLS
+ \if e\EncodingTreatment%
+% ENCODE SPACES, KEEP ENCODED SPACES ENCODED, ENCODE SYMBOLS.
+ \edef\@blankaction{\EncodedBlankSpace}%
+ \def\@dollaraction{\EncodedDollar}%
+ \def\@pipeaction{\EncodedPipe}%
+ \def\@uvariaction{\EncodedUvari}%
+ \def\@uvariiaction{\EncodedUvarii}%
+ \def\@uvariiiaction{\EncodedUvariii}%
+ \def\@carataction{\EncodedCarat}%
+ \def\@circumflexaction{\EncodedCircumflex}%
+ \def\@tildeaction{\EncodedTilde}%
+ \def\@umlautaction{\EncodedUmlaut}%
+ \def\@graveaction{\EncodedGrave}%
+ \def\@acuteaction{\EncodedAcute}%
+ \def\@macronaction{\EncodedMacron}%
+ \def\@overdotaction{\EncodedOverdot}%
+ \def\@breveaction{\EncodedBreve}%
+ \def\@caronaction{\EncodedCaron}%
+ \def\@doubleacuteaction{\EncodedDoubleAcute}%
+ \def\@cedillaaction{\EncodedCedilla}%
+ \def\@underdotaction{\EncodedUnderdot}%
+ \def\@archjoinaction{\EncodedArchJoin}%
+ \def\@lineunderaction{\EncodedLineUnder}%
+ \def\@copyrightaction{\EncodedCopyright}%
+ \def\@poundsaction{\EncodedPounds}%
+ \def\@leftbraceaction{\EncodedLeftBrace}%
+ \def\@rightbraceaction{\EncodedRightBrace}%
+ \def\@underscoreaction{\EncodedUnderscore}%
+ \def\@daggeraction{\EncodedDagger}%
+ \def\@doubledaggeraction{\EncodedDoubleDagger}%
+ \def\@sectionsymbolaction{\EncodedSectionSymbol}%
+ \def\@pilcrowaction{\EncodedPilcrow}%
+ \def\@eszettaction{\EncodedEszett}%
+ \def\@lbaction{\EncodedLB}%
+ \def\@rbaction{\EncodedRB}%
+ \if 2\AlphaCapsTreatment%
+ \def\@AEscaction{\Encodedaesc}%
+ \def\@OEthelaction{\Encodedoethel}%
+ \def\@Angstromaction{\Encodedangstrom}%
+ \def\@slashedOaction{\EncodedSlashedo}%
+ \def\@barredLaction{\EncodedBarredl}%
+ \else
+ \def\@AEscaction{\EncodedAEsc}%
+ \def\@OEthelaction{\EncodedOEthel}%
+ \def\@Angstromaction{\EncodedAngstrom}%
+ \def\@slashedOaction{\EncodedSlashedO}%
+ \def\@barredLaction{\EncodedBarredL}%
+ \fi
+ \if 2\AlphaTreatment%
+ \def\@aescaction{\EncodedAEsc}%
+ \def\@oethelaction{\EncodedOEthel}%
+ \def\@angstromaction{\EncodedAngstrom}%
+ \def\@slashedoaction{\EncodedSlashedO}%
+ \def\@barredlaction{\EncodedBarredL}%
+ \else
+ \def\@aescaction{\Encodedaesc}%
+ \def\@oethelaction{\Encodedoethel}%
+ \def\@angstromaction{\Encodedangstrom}%
+ \def\@slashedoaction{\EncodedSlashedo}%
+ \def\@barredlaction{\EncodedBarredl}%
+ \fi
+ \else
+% EncodingTreatment=v or q:
+% LEAVE SPACES ALONE; RESTORE ENCODED SPACES AND SYMBOLS
+ \def\@blankaction{\BlankSpace}%
+ \def\@dollaraction{\Dollar}%
+ \def\@pipeaction{\Pipe}%
+ \def\@uvariaction{\Uvari}%
+ \def\@uvariiaction{\Uvarii}%
+ \def\@uvariiiaction{\Uvariii}%
+ \def\@carataction{\Carat}%
+ \def\@circumflexaction{\Circumflex}%
+ \def\@tildeaction{\Tilde}%
+ \def\@umlautaction{\Umlaut}%
+ \def\@graveaction{\Grave}%
+ \def\@acuteaction{\Acute}%
+ \def\@macronaction{\Macron}%
+ \def\@overdotaction{\Overdot}%
+ \def\@breveaction{\Breve}%
+ \def\@caronaction{\Caron}%
+ \def\@doubleacuteaction{\DoubleAcute}%
+ \def\@cedillaaction{\Cedilla}%
+ \def\@underdotaction{\Underdot}%
+ \def\@archjoinaction{\ArchJoin}%
+ \def\@lineunderaction{\LineUnder}%
+ \def\@copyrightaction{\Copyright}%
+ \def\@poundsaction{\Pounds}%
+ \def\@leftbraceaction{\LeftBrace}%
+ \def\@rightbraceaction{\RightBrace}%
+ \def\@underscoreaction{\Underscore}%
+ \def\@daggeraction{\Dagger}%
+ \def\@doubledaggeraction{\DoubleDagger}%
+ \def\@sectionsymbolaction{\SectionSymbol}%
+ \def\@pilcrowaction{\Pilcrow}%
+ \def\@eszettaction{\Eszett}%
+ \def\@lbaction{\UnencodedLB}%
+ \def\@rbaction{\UnencodedRB}%
+ \if 2\AlphaCapsTreatment%
+ \def\@AEscaction{\aesc}%
+ \def\@OEthelaction{\oethel}%
+ \def\@Angstromaction{\angstrom}%
+ \def\@slashedOaction{\Slashedo}%
+ \def\@barredLaction{\Barredl}%
+ \else
+ \def\@AEscaction{\AEsc}%
+ \def\@OEthelaction{\OEthel}%
+ \def\@Angstromaction{\Angstrom}%
+ \def\@slashedOaction{\SlashedO}%
+ \def\@barredLaction{\BarredL}%
+ \fi
+ \if 2\AlphaTreatment%
+ \def\@aescaction{\AEsc}%
+ \def\@oethelaction{\OEthel}%
+ \def\@angstromaction{\Angstrom}%
+ \def\@slashedoaction{\SlashedO}%
+ \def\@barredlaction{\BarredL}%
+ \else
+ \def\@aescaction{\aesc}%
+ \def\@oethelaction{\oethel}%
+ \def\@angstromaction{\angstrom}%
+ \def\@slashedoaction{\Slashedo}%
+ \def\@barredlaction{\Barredl}%
+ \fi
+ \fi
+% REMOVE SPACES AND ENCODED SPACES?
+ \if 0\BlankTreatment%
+ \edef\@blankaction{}%
+ \fi
+% REMOVE ENCODED SYMBOLS?
+ \if 0\SymbolTreatment%
+ \def\@dollaraction{}%
+ \def\@pipeaction{}%
+ \def\@carataction{}%
+ \def\@circumflexaction{}%
+ \def\@tildeaction{}%
+ \def\@umlautaction{}%
+ \def\@graveaction{}%
+ \def\@acuteaction{}%
+ \def\@macronaction{}%
+ \def\@overdotaction{}%
+ \def\@breveaction{}%
+ \def\@caronaction{}%
+ \def\@doubleacuteaction{}%
+ \def\@cedillaaction{}%
+ \def\@underdotaction{}%
+ \def\@archjoinaction{}%
+ \def\@lineunderaction{}%
+ \def\@copyrightaction{}%
+ \def\@poundsaction{}%
+ \def\@leftbraceaction{}%
+ \def\@rightbraceaction{}%
+ \def\@underscoreaction{}%
+ \def\@daggeraction{}%
+ \def\@doubledaggeraction{}%
+ \def\@sectionsymbolaction{}%
+ \def\@pilcrowaction{}%
+ \def\@lbaction{}%
+ \def\@rbaction{}%
+ \fi
+% REMOVE ENCODED ALPHACAPS?
+ \if 0\AlphaCapsTreatment%
+ \def\@AEscaction{}%
+ \def\@OEthelaction{}%
+ \def\@Angstromaction{}%
+ \def\@slashedOaction{}%
+ \def\@barredLaction{}%
+ \fi
+% REMOVE ENCODED ALPHA?
+ \if 0\AlphaTreatment%
+ \def\@aescaction{}%
+ \def\@oethelaction{}%
+ \def\@angstromaction{}%
+ \def\@slashedoaction{}%
+ \def\@barredlaction{}%
+ \def\@eszettaction{}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@forcecapson}
+% Force capitalization of strings processed by |\substring| for the
+% time being.
+% \begin{macrocode}
+\newcommand\@forcecapson{%
+ \def\AlphaTreatment{2}%
+ \def\AlphaCapsTreatment{1}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@relaxcapson}
+% Restore prior treatments following a period of enforced capitalization.
+% \begin{macrocode}
+\newcommand\@relaxcapson{%
+ \let\AlphaTreatment\SaveAlphaTreatment%
+ \let\AlphaCapsTreatment\SaveAlphaCapsTreatment%
+ \@defineactions%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@decodepointer}
+% As pertains to arguments 3 and 4 of |\substring|, this routine
+% implements use of the |$| character to mean END-OF-STRING,
+% and |$-{|\textit{integer}|}| for addressing relative to the
+% END-OF-STRING.
+% \begin{macrocode}
+\newcommand\@decodepointer[2][\value{@stringsize}]{%
+ \isnextbyte[q]{$}{#2}%
+ \if T\theresult%
+ \isnextbyte[q]{-}{\expandafter\@gobble#2}%
+ \if T\theresult%
+ \setcounter{@@@letterindex}{#1}%
+ \@gobblearg{#2}{2}%
+ \addtocounter{@@@letterindex}{-\gobbledword}%
+ \edef\@fromtoindex{\value{@@@letterindex}}%
+ \else
+ \edef\@fromtoindex{#1}%
+ \fi
+ \else
+ \edef\@fromtoindex{#2}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@getstringlength}
+% Get's string length of |#1|, puts result in counter |#2|.
+% \begin{macrocode}
+\newcommand\@getstringlength[2]{%
+ \edef\@@teststring{#1\endofstring}%
+ \ifthenelse{\equal{\@@teststring}{\endofstring}}%
+ {\setcounter{#2}{0}}%
+ {%
+ \setcounter{@gobblesize}{1}%
+ \whiledo{\value{@gobblesize} < \@MAXSTRINGSIZE}{%
+%
+ \@gobblearg{\@@teststring}{1}%
+ \edef\@@teststring{\gobbledword}%
+ \ifthenelse{\equal{\@@teststring}{\endofstring}}%
+ {\setcounter{#2}{\value{@gobblesize}}%
+ \setcounter{@gobblesize}{\@MAXSTRINGSIZE}}%
+ {\addtocounter{@gobblesize}{1}}%
+ }%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@gobblearg}
+% Gobble first |#2| characters from string |#1|. The
+% result is stored in |\gobbledword|. Two-byte escape sequences,
+% when encountered, count as a single gobble.
+% \begin{macrocode}
+\newcommand\@gobblearg[2]{%
+ \setcounter{@letterindex}{0}%
+ \setcounter{@gobbleindex}{#2}%
+ \edef\gobbledword{#1}%
+ \whiledo{\value{@letterindex} < \value{@gobbleindex}}{%
+ \isnextbyte[q]{\EscapeChar}{\gobbledword}%
+ \if T\theresult%
+% GOBBLE ESCAPE CHARACTER
+ \edef\gobbledword{\@DiscardNextChar{\gobbledword}}%
+ \fi
+% GOBBLE NORMAL CHARACTER OR ESCAPE CODE
+ \edef\gobbledword{\@DiscardNextChar{\gobbledword}}%
+ \addtocounter{@letterindex}{1}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@DiscardNextChar}
+% Remove the next character from the argument string. Since
+% |\@gobble| skips spaces, the routine must first look for the case of
+% a leading blankspace. If none is found, proceed with a normal
+% |\@gobble|. Note: as per \LaTeX{} convention, |\@DiscardNextChar|
+% treats double/multi-softspaces as single space.
+% \begin{macrocode}
+\newcommand\@DiscardNextChar[1]{%
+ \expandafter\if\expandafter\BlankSpace#1\else
+ \expandafter\@gobble#1%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@convertsymboltostring}
+% Routine for converting an encodable symbol (|#3|) into string (|#4|),
+% for every occurance in the given string |#2|.
+% \begin{macrocode}
+\newcommand\@convertsymboltostring[4][v]{%
+ \def\@fromcode{#3}%
+ \def\@tostring{#4}%
+ \def\EncodingTreatment{e}%
+ \substring[e]{#2}{1}{\@MAXSTRINGSIZE}%
+ \@convertoff%
+ \if e#1\else\substring[#1]{\thestring}{1}{\@MAXSTRINGSIZE}\fi%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@convertbytetostring}
+% Routine for converting an plain byte (|#3|) into string (|#4|),
+% for every occurance in the given string |#2|.
+% \begin{macrocode}
+\newcommand\@convertbytetostring[4][v]{%
+ \def\@frombyte{#3}%
+ \def\@tostring{#4}%
+ \def\EncodingTreatment{e}%
+ \substring[e]{#2}{1}{\@MAXSTRINGSIZE}%
+ \@convertoff%
+ \if e#1\else\substring[#1]{\thestring}{1}{\@MAXSTRINGSIZE}\fi%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@treatleadingspaces}
+% This routine will address the leading spaces of string |#2|. If
+% argument |#3| is an 'x' character, those leading spaces will be
+% deleted from the string. Otherwise, those leading spaces will be
+% rotated to the end of the string.
+% \begin{macrocode}
+\newcommand\@treatleadingspaces[3][v]{\+%
+ \defaultTreatments%
+ \edef\thestring{#2}%
+ \@getstringlength{\thestring}{@stringsize}%
+ \setcounter{@maxrotation}{\value{@stringsize}}%
+ \setcounter{@letterindex}{0}%
+ \whiledo{\value{@letterindex} < \value{@maxrotation}}{%
+ \addtocounter{@letterindex}{1}%
+ \isnextbyte[q]{\EncodedBlankSpace}{\thestring}%
+ \if F\theresult\isnextbyte[q]{\BlankSpace}{\thestring}\fi%
+ \if T\theresult%
+ \isnextbyte[q]{#3}{x}%
+ \if F\theresult%
+% NORMAL OR ENCODED BLANK... ROTATE IT
+ \edef\thestring{\@rotate{\thestring}}%
+ \else
+% NORMAL OR ENCODED BLANK... DELETE IT (IF 3rd ARG=X)
+ \@gobblearg{\thestring}{1}%
+ \edef\thestring{\gobbledword}%
+ \fi
+ \else
+ \setcounter{@maxrotation}{\value{@letterindex}}%
+ \fi
+ }\?%
+ \substring[#1]{\thestring}{1}{\@MAXSTRINGSIZE}%
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@convertoff}
+% This routine is an initialization routine to
+% guarantee that there is no conversion of |\@frombyte| to |\@tostring|,
+% until further notice. It accomplishes this
+% by setting up such that subsequent |\if\@frombyte| and
+% |\if\@fromcode| clauses will automatically fail.
+% \begin{macrocode}
+\newcommand\@convertoff{\def\@frombyte{xy}\def\@tostring{}%
+ \def\@fromcode{xy}}
+\@convertoff
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@rotate}
+% The following code is the engine of the string manipulation routine.
+% It is a tree of successive \LaTeX{} commands (each of which is
+% composed of an |\if...| cascade) which have the net
+% effect of rotating the first letter of the string into the last
+% position. Depending on modes set by |\@defineactions| and
+% |\defaultTreatments|, the leading character is either encoded,
+% decoded, or removed in the process.
+% Note: |\@rotate| loses track of double/multi-spaces, per \LaTeX{}
+% convention, unless encoded blanks (|~|) are used.
+% \begin{macrocode}
+\newcommand\@rotate[1]{%
+% CHECK BYTE CONVERSION TEST FIRST
+ \if \@frombyte#1\@tostring\else
+% MUST CHECK FOR MULTI-BYTE CHARACTERS NEXT, SO THAT ENCODING CHARACTER
+% ISN'T MISTAKEN FOR A NORMAL CHARACTER LATER IN MACRO.
+ \if 0\SymbolTreatment%
+ \@removeExpandableSymbols{#1}%
+ \else
+ \@rotateExpandableSymbols{#1}%
+ \fi
+ \fi
+}
+
+\newcommand\@rotateExpandableSymbols[1]{%
+% INDIRECT (EXPANDABLE) SYMBOLS
+ \expandafter\ifx\expandafter\&#1\&\else
+ \expandafter\ifx\expandafter\%#1\%\else
+ \expandafter\ifx\expandafter\##1\#\else
+ \@rotateBlankSpaces{#1}%
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@removeExpandableSymbols[1]{%
+% INDIRECT (EXPANDABLE) SYMBOLS
+ \expandafter\ifx\expandafter\&#1\else
+ \expandafter\ifx\expandafter\%#1\else
+ \expandafter\ifx\expandafter\##1\else
+ \@rotateBlankSpaces{#1}%
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@rotateBlankSpaces[1]{%
+ \expandafter\ifx\expandafter$#1$\else% <---RETAIN GOING INTO/FROM MATH MODE
+% THE FOLLOWING FINDS TILDES, BUT MUST COME AFTER EXPANDABLE SYMBOL
+% SEARCH, OR ELSE IT FINDS THEM TOO, BY MISTAKE.
+ \if \EncodedBlankSpace#1\@blankaction\else% <--- FINDS REENCODED TILDE
+% THE FOLLOWING SHOULD FIND TILDES, BUT DOESN'T... THUS, COMMENTED OUT.
+% \expandafter\ifx\expandafter\EncodedBlankSpace#1\@blankaction\else
+ \if \BlankSpace#1\@blankaction\else
+ \if 2\AlphaTreatment%
+ \@chcaseAlpha{#1}%
+ \else
+ \if 0\AlphaTreatment%
+ \@removeAlpha{#1}%
+ \else
+ \@rotateAlpha{#1}%
+ \fi
+ \fi
+ \fi
+% \fi
+ \fi
+ \fi
+}
+
+\newcommand\@rotateAlpha[1]{%
+% LOWERCASE
+ \if a#1a\else
+ \if b#1b\else
+ \if c#1c\else
+ \if d#1d\else
+ \if e#1e\else
+ \if f#1f\else
+ \if g#1g\else
+ \if h#1h\else
+ \if i#1i\else
+ \if j#1j\else
+ \if k#1k\else
+ \if l#1l\else
+ \if m#1m\else
+ \if n#1n\else
+ \if o#1o\else
+ \if p#1p\else
+ \if q#1q\else
+ \if r#1r\else
+ \if s#1s\else
+ \if t#1t\else
+ \if u#1u\else
+ \if v#1v\else
+ \if w#1w\else
+ \if x#1x\else
+ \if y#1y\else
+ \if z#1z\else
+ \if 2\AlphaCapsTreatment%
+ \@chcaseAlphaCaps{#1}%
+ \else
+ \if 0\AlphaCapsTreatment%
+ \@removeAlphaCaps{#1}%
+ \else
+ \@rotateAlphaCaps{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@removeAlpha[1]{%
+% LOWERCASE
+ \if a#1\else
+ \if b#1\else
+ \if c#1\else
+ \if d#1\else
+ \if e#1\else
+ \if f#1\else
+ \if g#1\else
+ \if h#1\else
+ \if i#1\else
+ \if j#1\else
+ \if k#1\else
+ \if l#1\else
+ \if m#1\else
+ \if n#1\else
+ \if o#1\else
+ \if p#1\else
+ \if q#1\else
+ \if r#1\else
+ \if s#1\else
+ \if t#1\else
+ \if u#1\else
+ \if v#1\else
+ \if w#1\else
+ \if x#1\else
+ \if y#1\else
+ \if z#1\else
+ \if 2\AlphaCapsTreatment%
+ \@chcaseAlphaCaps{#1}%
+ \else
+ \if 0\AlphaCapsTreatment%
+ \@removeAlphaCaps{#1}%
+ \else
+ \@rotateAlphaCaps{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@chcaseAlpha[1]{%
+% LOWERCASE TO UPPERCASE
+ \if a#1A\else
+ \if b#1B\else
+ \if c#1C\else
+ \if d#1D\else
+ \if e#1E\else
+ \if f#1F\else
+ \if g#1G\else
+ \if h#1H\else
+ \if i#1I\else
+ \if j#1J\else
+ \if k#1K\else
+ \if l#1L\else
+ \if m#1M\else
+ \if n#1N\else
+ \if o#1O\else
+ \if p#1P\else
+ \if q#1Q\else
+ \if r#1R\else
+ \if s#1S\else
+ \if t#1T\else
+ \if u#1U\else
+ \if v#1V\else
+ \if w#1W\else
+ \if x#1X\else
+ \if y#1Y\else
+ \if z#1Z\else
+ \if 2\AlphaCapsTreatment%
+ \@chcaseAlphaCaps{#1}%
+ \else
+ \if 0\AlphaCapsTreatment%
+ \@removeAlphaCaps{#1}%
+ \else
+ \@rotateAlphaCaps{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@rotateAlphaCaps[1]{%
+% UPPERCASE
+ \if A#1A\else
+ \if B#1B\else
+ \if C#1C\else
+ \if D#1D\else
+ \if E#1E\else
+ \if F#1F\else
+ \if G#1G\else
+ \if H#1H\else
+ \if I#1I\else
+ \if J#1J\else
+ \if K#1K\else
+ \if L#1L\else
+ \if M#1M\else
+ \if N#1N\else
+ \if O#1O\else
+ \if P#1P\else
+ \if Q#1Q\else
+ \if R#1R\else
+ \if S#1S\else
+ \if T#1T\else
+ \if U#1U\else
+ \if V#1V\else
+ \if W#1W\else
+ \if X#1X\else
+ \if Y#1Y\else
+ \if Z#1Z\else
+ \if 0\NumeralTreatment%
+ \@removeNumerals{#1}%
+ \else
+ \@rotateNumerals{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@removeAlphaCaps[1]{%
+% UPPERCASE
+ \if A#1\else
+ \if B#1\else
+ \if C#1\else
+ \if D#1\else
+ \if E#1\else
+ \if F#1\else
+ \if G#1\else
+ \if H#1\else
+ \if I#1\else
+ \if J#1\else
+ \if K#1\else
+ \if L#1\else
+ \if M#1\else
+ \if N#1\else
+ \if O#1\else
+ \if P#1\else
+ \if Q#1\else
+ \if R#1\else
+ \if S#1\else
+ \if T#1\else
+ \if U#1\else
+ \if V#1\else
+ \if W#1\else
+ \if X#1\else
+ \if Y#1\else
+ \if Z#1\else
+ \if 0\NumeralTreatment%
+ \@removeNumerals{#1}%
+ \else
+ \@rotateNumerals{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@chcaseAlphaCaps[1]{%
+% UPPERCASE TO LOWERCASE
+ \if A#1a\else
+ \if B#1b\else
+ \if C#1c\else
+ \if D#1d\else
+ \if E#1e\else
+ \if F#1f\else
+ \if G#1g\else
+ \if H#1h\else
+ \if I#1i\else
+ \if J#1j\else
+ \if K#1k\else
+ \if L#1l\else
+ \if M#1m\else
+ \if N#1n\else
+ \if O#1o\else
+ \if P#1p\else
+ \if Q#1q\else
+ \if R#1r\else
+ \if S#1s\else
+ \if T#1t\else
+ \if U#1u\else
+ \if V#1v\else
+ \if W#1w\else
+ \if X#1x\else
+ \if Y#1y\else
+ \if Z#1z\else
+ \if 0\NumeralTreatment%
+ \@removeNumerals{#1}%
+ \else
+ \@rotateNumerals{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@rotateNumerals[1]{%
+% NUMERALS
+ \if 1#11\else
+ \if 2#12\else
+ \if 3#13\else
+ \if 4#14\else
+ \if 5#15\else
+ \if 6#16\else
+ \if 7#17\else
+ \if 8#18\else
+ \if 9#19\else
+ \if 0#10\else
+ \if 0\PunctuationTreatment%
+ \@removePunctuation{#1}%
+ \else
+ \@rotatePunctuation{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@removeNumerals[1]{%
+% NUMERALS
+ \if 1#1\else
+ \if 2#1\else
+ \if 3#1\else
+ \if 4#1\else
+ \if 5#1\else
+ \if 6#1\else
+ \if 7#1\else
+ \if 8#1\else
+ \if 9#1\else
+ \if 0#1\else
+ \if 0\PunctuationTreatment%
+ \@removePunctuation{#1}%
+ \else
+ \@rotatePunctuation{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@rotatePunctuation[1]{%
+% PUNCTUATION
+ \if ;#1;\else
+ \if :#1:\else
+ \if '#1'\else
+ \if "#1"\else
+ \if ,#1,\else
+ \if .#1.\else
+ \if ?#1?\else
+ \if `#1`\else
+ \if !#1!\else
+ \if 0\SymbolTreatment%
+ \@removeDirectSymbols{#1}%
+ \else
+ \@rotateDirectSymbols{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@removePunctuation[1]{%
+% PUNCTUATION
+ \if ;#1\else
+ \if :#1\else
+ \if '#1\else
+ \if "#1\else
+ \if ,#1\else
+ \if .#1\else
+ \if ?#1\else
+ \if `#1\else
+ \if !#1\else
+ \if 0\SymbolTreatment%
+ \@removeDirectSymbols{#1}%
+ \else
+ \@rotateDirectSymbols{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@rotateDirectSymbols[1]{%
+% DIRECT SYMBOLS
+ \if /#1/\else
+ \if @#1@\else
+ \if *#1*\else
+ \if (#1(\else
+ \if )#1)\else
+ \if -#1-\else
+ \if _#1_\else
+ \if =#1=\else
+ \if +#1+\else
+ \if [#1[\else
+ \if ]#1]\else
+ \if ^#1^\else% <--FOR SUPERSCRIPTS, NOT \^
+ \if <#1<\else
+ \if >#1>\else
+ \if |#1|\else
+ \if &#1&\else
+ \@rotateUndecipherable{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@removeDirectSymbols[1]{%
+% DIRECT SYMBOLS
+ \if /#1\else
+ \if @#1\else
+ \if *#1\else
+ \if (#1\else
+ \if )#1\else
+ \if -#1\else
+ \if _#1\else
+ \if =#1\else
+ \if +#1\else
+ \if [#1\else
+ \if ]#1\else
+ \if ^#1\else% <--FOR SUPERSCRIPTS, NOT \^
+ \if <#1\else
+ \if >#1\else
+ \if |#1\else
+ \if &#1\else
+ \@rotateUndecipherable{#1}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+
+\newcommand\@rotateUndecipherable[1]{%
+% REPLACE UNDECIPHERABLE SYMBOL WITH A TOKEN CHARACTER (DEFAULT .)
+ \expandafter\@gobble#1\undecipherable%
+% DONE... CLOSE UP SHOP
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macrocode}
+\catcode`\&=4
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</package>
+% \end{macrocode}
+%
+% \Finale
+\endinput
+%
+% End of file `stringstrings.dtx'.
diff --git a/macros/latex/contrib/stringstrings/stringstrings.ins b/macros/latex/contrib/stringstrings/stringstrings.ins
index 3564603d75..a99e147f5b 100644
--- a/macros/latex/contrib/stringstrings/stringstrings.ins
+++ b/macros/latex/contrib/stringstrings/stringstrings.ins
@@ -1,6 +1,6 @@
-% LaTeX this .ins file in order to generate the .sty file from the .dtx file
-\input docstrip
-\askforoverwritefalse
-\generate{\file{stringstrings.sty}{\from{stringstrings.dtx}{package}}
- }
-\endbatchfile
+% LaTeX this .ins file in order to generate the .sty file from the .dtx file
+\input docstrip
+\askforoverwritefalse
+\generate{\file{stringstrings.sty}{\from{stringstrings.dtx}{package}}
+ }
+\endbatchfile
diff --git a/macros/latex/contrib/stringstrings/stringstrings.pdf b/macros/latex/contrib/stringstrings/stringstrings.pdf
index 13684086f6..9a61441db4 100644
--- a/macros/latex/contrib/stringstrings/stringstrings.pdf
+++ b/macros/latex/contrib/stringstrings/stringstrings.pdf
Binary files differ
diff --git a/macros/unicodetex/latex/polyglossia/README.md b/macros/unicodetex/latex/polyglossia/README.md
index 3510cd2d61..4f4afbf5d7 100644
--- a/macros/unicodetex/latex/polyglossia/README.md
+++ b/macros/unicodetex/latex/polyglossia/README.md
@@ -1,4 +1,4 @@
-# THE POLYGLOSSIA PACKAGE v1.50a
+# THE POLYGLOSSIA PACKAGE v1.51
## Multilingual typesetting with XeLaTeX and LuaLaTeX
This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX.
diff --git a/macros/unicodetex/latex/polyglossia/polyglossia.dtx b/macros/unicodetex/latex/polyglossia/polyglossia.dtx
index bcc694b3bc..12ab0b4ce0 100644
--- a/macros/unicodetex/latex/polyglossia/polyglossia.dtx
+++ b/macros/unicodetex/latex/polyglossia/polyglossia.dtx
@@ -8,7 +8,7 @@
\iffalse
%</internal>
%<*README>
-# THE POLYGLOSSIA PACKAGE v1.50a
+# THE POLYGLOSSIA PACKAGE v1.51
## Multilingual typesetting with XeLaTeX and LuaLaTeX
This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX.
@@ -1350,6 +1350,13 @@ to track the issues and follow progress.
% \charifavailable{01C6}{dž}) will be replaced by single characters. This can
% be useful if the ligatures on your font are broken (if the font does not
% have them, they are automatically replaced).
+% \item \xpgboolkeytrue[1.51]{splithyphens}
+% According to Croatian typesetting conventions, if a word with a hard hyphen (such as \emph{je-li})
+% is hyphenated at this hyphen, a second hyphenation character is to be inserted at the beginning
+% of the line that follows the hyphenation (\emph{je-/-li}).
+% By default, this is done automatically (if you are using \LuaTeX, the \pkg{luavlna} package is
+% loaded to achieve this).
+% Set this option to ¦false¦ to disable the feature.
% \end{itemize}
%
% \subsection{czech}\label{czech}
@@ -1467,7 +1474,7 @@ to track the issues and follow progress.
% enabled, spacing in typewriter context is the same as with roman and sans
% serif font, depending on the \xpgvalue{autospacing} and
% \xpgvalue{autospaceguillemets} settings (note that this was the default up
-% to v.~1.44).
+% to v.~1.44).
% \item \xpgboolkeyfalse{frenchfootnote}
% If \xpgvalue{true}, footnotes start with a non-superscripted number
% followed by a dot, as common in French typography. Note that this might
@@ -1479,6 +1486,14 @@ to track the issues and follow progress.
% in French typography. Note that this option is only functional (by
% design) if French is the main language. Also, it might interfere with
% list packages such as \pkg{enumitem}.
+% \item \xpgboolkeytrue[1.51]{frenchpart}
+% By default, \pkg{polyglossia} modifies part headings to match French conventions
+% (\emph{Première partie} rather than \emph{Partie I}). Next to the standard classes,
+% specifics of \pkg{KOMA-script}, \pkg{memoir} and the \pkg{titlesec} package are
+% taken into account. With other classes or packages, redefinition might fail if these
+% have particular part settings.
+% In such case, or if you don't want the redefinition, you can switch off the feature
+% by passing \textit{false} to this option.
% \item \xpgcodekey[1.46]{itemlabels}¦\textemdash¦
% If \emph{frenchitemlabels} is true, you can customize here the used item
% label of all levels.
@@ -2686,7 +2701,7 @@ to track the issues and follow progress.
% \subsection{polyglossia.sty}
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{polyglossia}[2020/10/15 v1.50a
+\ProvidesPackage{polyglossia}[2020/12/08 v1.51
Modern multilingual typesetting with XeLaTeX and LuaLaTeX]
\RequirePackage{etoolbox}
\RequirePackage{makecmds}
@@ -2697,19 +2712,23 @@ to track the issues and follow progress.
\RequirePackage{expl3}
\RequirePackage{l3keys2e}
\RequirePackage{xparse}
-\RequirePackage{filehook}
+
+% fontspec now uses LaTeX3 packages such as expl3, so we need this:
+\ExplSyntaxOn
+
+% Execute code #3 if package #1 has been loaded already, else
+% add to package hook #2
+\newcommand\xpg@at@package[3]{%
+ \@ifpackageloaded{#1}{#3}{\AddToHook{#2}{#3}}%
+}
% correct a bug in tracklang
-\AtBeginOfPackageFile*{tracklang}{
+\xpg@at@package{tracklang}{file/after/tracklang.sty}{%
\@ifpackagelater{tracklang}{2019/08/30}{}{\global\def\AddTrackedLangage{\AddTrackedLanguage}}
}
-% fontspec now uses LaTeX3 packages such as expl3, so we need this:
-\ExplSyntaxOn
-
%% This is for compatibility with Babel-aware package:
-\cslet{ver@babel.sty}{\@empty} % this "fakes" babel
\def\languageshorthands#1{\relax} %this is for scrlttr2 class
\def\bbl@cs#1{\csname bbl@#1\endcsname}%
\AtEndPreamble{\let\bbl@set@language\xpg@set@language@aux} %for biblatex
@@ -2855,7 +2874,7 @@ to track the issues and follow progress.
{}%
{\xpg@error{Unknown~ language~ direction~ #1 ~(base~ wrapper)}}%
}
-\AtEndOfPackageFile*{bidi}{%
+\xpg@at@package{bidi}{package/after/bidi}{%
\ExplSyntaxOn%
\cs_gset_nopar:Nn{\polyglossia@setpardirection:n}{%
\str_case_e:nnTF{#1}{%
@@ -2875,7 +2894,7 @@ to track the issues and follow progress.
}%
\ExplSyntaxOff%
}
-\AtEndOfPackageFile*{luabidi}{%
+\xpg@at@package{luabidi}{package/after/luabidi}{%
\ExplSyntaxOn%
\cs_gset_nopar:Nn{\polyglossia@setpardirection:n}{%
\str_case_e:nnTF{#1}{%
@@ -3840,6 +3859,16 @@ to track the issues and follow progress.
\newcommand{\setdefaultlanguage}[2][]{%
+ % latex is an internal language, so do not record
+ \ifstrequal{#2}{latex}{}{%
+ % register polyglossia language name
+ \ifcsundef{#2@registered}{%
+ \global\edef\xpg@loaded{%
+ \ifx\xpg@loaded\@empty\else\xpg@loaded,\fi #2%
+ }%
+ }{}%
+ \csgdef{#2@registered}{}%
+ }%
\ifcsundef{#2@loaded}%
{
\polyglossia_load_lang_definition:nn{#1}{#2}
@@ -8408,7 +8437,7 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
\def\prefacename{Parathenia}%
\def\chaptername{Kapitulli}%
\def\appendixname{Shtesa}%
- \def\contentsname{Përmbajta}%
+ \def\contentsname{Përmbajtja}%
\def\listfigurename{Figurat}%
\def\listtablename{Tabelat}%
\def\indexname{Indeksi}%
@@ -10720,12 +10749,18 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
% BCP-47 compliant aliases
\setlanguagealias*{croatian}{hr}
+\ifluatex
+ \RequirePackage{luavlna}
+\fi
+
\define@boolkey{croatian}[croatian@]{babelshorthands}[true]{}
\define@boolkey{croatian}[croatian@]{disableligatures}[true]{}
+\define@boolkey{croatian}[croatian@]{splithyphens}[true]{}
+
% Register default options
-\xpg@initialize@gloss@options{croatian}{babelshorthands=false,disableligatures=false}
+\xpg@initialize@gloss@options{croatian}{babelshorthands=false,disableligatures=false,splithyphens=true}
\ifsystem@babelshorthands
\setkeys{croatian}{babelshorthands=true}
@@ -10739,6 +10774,19 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
\shorthandoff{"}%
}{}
+\def\croatian@@splhyphen#1{%
+ \ifnum\hyphenchar \font>0%
+ \kern\z@\discretionary{-}{\char\hyphenchar\the\font}{#1}%
+ \nobreak\hskip\z@%
+ \else%
+ #1%
+ \fi%
+}
+
+\def\croatian@splhyphen{%
+ \croatian@@splhyphen{-}%
+}
+
\def\croatian@shorthands{%
\bbl@activate{"}%
\def\language@group{croatian}%
@@ -10768,6 +10816,32 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
\@ifundefined{initiate@active@char}{}{\bbl@deactivate{"}}%
}
+\ifxetex
+ % splithyphens
+ \newXeTeXintercharclass\croatian@hyphen % -
+ \newXeTeXintercharclass\croatian@nonsyllabicpreposition%
+\fi
+
+\def\croatian@hyphens{%
+ \ifluatex
+ \AfterPreamble{\enablesplithyphens{croatian}}%
+ \else
+ \XeTeXinterchartokenstate=1
+ \XeTeXcharclass `\- \croatian@hyphen
+ \XeTeXinterchartoks \z@ \croatian@hyphen = {\croatian@@splhyphen}% "-" -> "\croatian@@splhyphen-"
+ % necessary if used together with vlna:
+ \XeTeXinterchartoks \croatian@nonsyllabicpreposition \croatian@hyphen = {\croatian@@splhyphen}% "-" -> "\croatian@@splhyphen-"
+ \fi%
+}
+
+\def\nocroatian@hyphens{%
+ \ifluatex
+ \AfterPreamble{\disablesplithyphens{croatian}}%
+ \else
+ \XeTeXcharclass `\- \z@
+ \fi%
+}
+
\newcommand*\hr@charifavailable[2]{%
\ifcroatian@disableligatures
\bgroup#2\egroup%
@@ -10872,14 +10946,17 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
\def\noextras@croatian{%
\ifcroatian@babelshorthands\nocroatian@shorthands\fi%
+ \nocroatian@hyphens%
}
\def\blockextras@croatian{%
\ifcroatian@babelshorthands\croatian@shorthands\fi%
+ \ifcroatian@splithyphens\croatian@hyphens\else\nocroatian@hyphens\fi%
}
\def\inlineextras@croatian{%
\ifcroatian@babelshorthands\croatian@shorthands\fi%
+ \ifcroatian@splithyphens\croatian@hyphens\else\nocroatian@hyphens\fi%
}
% \end{macrocode}
@@ -12595,6 +12672,9 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
\define@boolkey{french}[french@]{autospacing}[true]{}
\french@autospacingtrue
+\define@boolkey{french}[french@]{frenchpart}[true]{}
+\french@frenchparttrue
+
\newif\iffrench@autospaceguillemets
\define@boolkey{french}[french@]{autospaceguillemets}[true]{}
\french@autospaceguillemetstrue
@@ -12694,7 +12774,7 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
\let\ttfamily\french@ttfamilyORI
}
-\def\xpg@french@thinsp{\kern 0.5\fontdimen2\font}
+\def\xpg@french@thinsp{\kern 0.5\fontdimen2\font\nobreak\hskip\z@skip}
\def\french@punctuation{%
\lccode"2019="2019
@@ -12817,14 +12897,11 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
\def\indexname{Index}%
\def\figurename{\textsc{Fig.}}%
\def\tablename{\textsc{Tab.}}%
- \def\@Fpt{\ifcase\value{part}\or Première\or Deuxième\or
- Troisième\or Quatrième\or Cinquième\or Sixième\or
- Septième\or Huitième\or Neuvième\or Dixième\or Onzième\or
- Douzième\or Treizième\or Quatorzième\or Quinzième\or
- Seizième\or Dix-septième\or Dix-huitième\or Dix-neuvième\or
- Vingtième\fi\space}%
- \def\thepart{\@Fpt partie}%
- \def\partname{}%
+ \iffrench@frenchpart
+ \def\partname{partie}%
+ \else
+ \def\partname{Partie}%
+ \fi%
\def\pagename{page}%
\def\seename{\emph{voir}}%
\def\alsoname{\emph{voir aussi}}%
@@ -12844,9 +12921,83 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
décembre\fi
\space \number\year}}
+\def\xpg@french@part{\ifcase\value{part}\or Première\or Deuxième\or%
+ Troisième\or Quatrième\or Cinquième\or Sixième\or%
+ Septième\or Huitième\or Neuvième\or Dixième\or Onzième\or%
+ Douzième\or Treizième\or Quatorzième\or Quinzième\or%
+ Seizième\or Dix-septième\or Dix-huitième\or Dix-neuvième\or%
+ Vingtième\fi}%
+
+\def\french@capsformat{%
+ % Change part heading
+ % With titlesec
+ \ifcsdef{titleformat}{%
+ \ifcsdef{@part}{%
+ \let\xpg@save@part@format\@part%
+ \patchcmd{\@part}%
+ {\partname\nobreakspace\thepart}%
+ {\xpg@french@part\nobreakspace\partname}%
+ {}%
+ {\xpg@warning{Failed to patch part for French}}%
+ }{}%
+ }{% (not \ifdefined\titleformat)
+ % With KOMA
+ \ifcsdef{sectionformat}{%
+ \ifcsdef{partformat}{%
+ \let\xpg@save@part@format\partformat%
+ \renewcommand{\partformat}{\xpg@french@part~\partname}%
+ }{}%
+ }{% (not \ifdefined\sectionformat)
+ % With memoir
+ \ifcsdef{@memptsize}{%
+ \ifcsdef{@part}{%
+ \let\xpg@save@part@format\@part%
+ \patchcmd{\@part}{\printpartname \partnamenum \printpartnum}%
+ {\partnamefont\xpg@french@part\partnamenum\printpartname}%
+ {}%
+ {\xpg@warning{Failed to patch part for French}}%
+ }{}%
+ }{% (not \ifdefined\@memptsize)
+ % With standard classes
+ \ifcsdef{@part}{%
+ \let\xpg@save@part@format\@part%
+ \patchcmd{\@part}%
+ {\partname\nobreakspace\thepart}%
+ {\xpg@french@part\nobreakspace\partname}%
+ {}%
+ {\xpg@warning{Failed to patch part for French}}%
+ }{}% (end \ifdefined\@part)
+ }% (end \ifdefined\@memptsize)
+ }% (end \ifdefined\sectionformat)
+ }% (end \ifdefined\titleformat)
+}
+
+\def\nofrench@capsformat{%
+ % Reset chapter and part heading
+ \ifcsdef{titleformat}{%
+ % With titlesec
+ \ifcsdef{xpg@save@part@format}{%
+ \let\@part\xpg@save@part@format
+ }{}%
+ }{% (not \ifdefined\titleformat)
+ \ifcsdef{sectionformat}{%
+ % With KOMA
+ \ifcsdef{xpg@save@part@format}{%
+ \let\partformat\xpg@save@part@format
+ }{}%
+ }{%
+ % With memoir and standard classes
+ \ifcsdef{xpg@save@part@format}{%
+ \let\@part\xpg@save@part@format
+ }{}%
+ }% (end \ifdefined\sectionformat)
+ }% (end \ifdefined\titleformat)
+}
+
\def\noextras@french{%
\nofrench@punctuation%
\nofrench@fontsetup%
+ \nofrench@capsformat%
}
\def\blockextras@french{%
@@ -12854,6 +13005,9 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
\french@punctuation%
\fi
\french@fontsetup%
+ \iffrench@frenchpart
+ \french@capsformat%
+ \fi%
}
\def\inlineextras@french{%
@@ -14383,7 +14537,7 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
% Bidi inserts an RTL mark (0x200f) between number and number separator (- .),
% forcing numbers to RTL. This is wrong for Hebrew.
% So we defunc the respective command.
- \renewcommand*{\DigitsDotDashInterCharToks}{}
+ \renewcommand*{\DigitsDotDashInterCharToks}{}%
\fi%
}
@@ -24997,6 +25151,25 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
%
% \iffalse
%<*Changelog>
+1.51 (08-12-2020)
+
+New features:
+ * New option "frenchpart" for French (#458).
+ * New option "splithyphens" for Croatian (#454).
+
+Bug fixes:
+
+ * Use new LaTeX core hooks rather than filehook package. This fixes
+ a recent breakage of filehook with other external packages (#453).
+ * Remove very old code that pretends polyglossia is babel (#455).
+ * Fix spelling of Albanian contentsname (#456).
+ * Fix part heading modification in French (#458).
+ * Fix extra space in Hebrew (#459).
+ * Register main polyglossia language earlier (#461).
+ * Allow for hyphenations in words following opening guillemet in French
+ with XeTeX (#462).
+
+
1.50a (15-10-2020)
Bug fixes:
diff --git a/macros/unicodetex/latex/polyglossia/polyglossia.pdf b/macros/unicodetex/latex/polyglossia/polyglossia.pdf
index 9477b7f13d..c7ef99de2e 100644
--- a/macros/unicodetex/latex/polyglossia/polyglossia.pdf
+++ b/macros/unicodetex/latex/polyglossia/polyglossia.pdf
Binary files differ