diff options
Diffstat (limited to 'Master/texmf-dist/source/latex')
-rw-r--r-- | Master/texmf-dist/source/latex/unroman/unroman.dtx | 531 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/unroman/unroman.ins | 32 |
2 files changed, 563 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/unroman/unroman.dtx b/Master/texmf-dist/source/latex/unroman/unroman.dtx new file mode 100644 index 00000000000..2f408253258 --- /dev/null +++ b/Master/texmf-dist/source/latex/unroman/unroman.dtx @@ -0,0 +1,531 @@ +% \iffalse meta-comment +% +% Copyright (C) 2007 by +% Joseph Wright <joseph.wright@morningstar2.co.uk> +% +% Released under the GNU General Public License v2 +% See http://www.gnu.org/licenses/gpl.txt +% +% This work consists of the main source file unroman.dtx +% and the derived files unroman.sty and unroman.pdf +% +%<*driver> +\documentclass{ltxdoc} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +%\OnlyDescription +\usepackage[T1]{fontenc} +\usepackage[english,UKenglish]{babel} +\usepackage{mathpazo,booktabs,array,url} +\usepackage{\jobname} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \CheckSum{277} +% +% \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 \~} +% +% \GetFileInfo{\jobname.sty} +% +% \changes{v1.0}{2007/06/11}{Initial public release} +% +% \DoNotIndex{\@whilenum,\addtocounter,\DeclareRobustCommand,\def} +% \DoNotIndex{\do,\edef,\else,\end,\expandafter,\fi,\if,\ifnum} +% \DoNotIndex{\if,\let,\NeedsTeXFormat,\newcommand,\newcounter} +% \DoNotIndex{\newif,\PackageInfo,\ProvidesPackage} +% \DoNotIndex{\RequirePackage,\setcounter,\strlenstore,\the,\value} +% \DoNotIndex{\z@} +% +% \title{From Roman numerals to Arabic numbers} +% \author{Joseph Wright% +% \thanks{E-mail: joseph.wright@morningstar2.co.uk}} +% \date{\filedate} +% +% \maketitle +% +% \begin{abstract} +% +% The |unroman| package provides a number of functions to convert +% from Roman numerals to Arabic numbers. The set of functions is +% designed to cover a range of applications. +% +% \end{abstract} +% +% \section{Introduction} +% +% TeX and the LaTeX kernel provide a number of functions for +% converting Arabic numbers to Roman numerals. However, there is +% a lack of functions to go the opposite way, back to Arabic numbers +% from a given Roman numeral. The |unroman| package seeks to address +% this, providing a flexible set of macros for a variety of +% applications. +% +% \section{Usage} +% +% \subsection{Conversion from Roman numerals} +% +% \DescribeMacro{\unroman} +% \DescribeMacro{\unromanhead} +% \DescribeMacro{\unromantail} +% The main aim of the package is to allow Roman numerals to be turned +% into Arabic numbers. This is achieved using the +% |\unroman|\marg{numeral} macro, which takes a single argument +% \meta{numeral}. The case of \meta{numeral} is unimportant, but the +% string must only contain valid Roman numeral characters (i, v, x, +% c, d, l, m). If the string contains any non-valid characters, +% |\unroman| returns the value 0, and writes a message to the log. +% The macros |\unromanhead|\marg{numeral} and +% |\unromantail|\marg{numeral} extract a Roman numeral from the +% beginning and end of a string, respectively. This is illustrated +% in Table~\ref{tbl:examples}. +% \begin{table} +% \centering +% \begin{tabular}{ll} +% \toprule +% LaTeX code & Output \\ +% \midrule +% |\unroman{MCMXCII}| & \unroman{MCMXCII} \\ +% |\unroman{ii--xi}| & \unroman{ii--xi} \\ +% |\unromanhead{ii--xi}| & \unromanhead{ii--xi} \\ +% |\unromantail{ii--xi}| & \unromantail{ii--xi} \\ +% \bottomrule +% \end{tabular} +% \caption{Conversion examples} +% \label{tbl:examples} +% \end{table} +% +% \DescribeMacro{\unromanstore} +% \DescribeMacro{\unromanheadstore} +% \DescribeMacro{\unromantailstore} +% \newcounter{mycounter} +% Following the example of the |coolstr| package, versions of all +% three conversion macros are provided that do do produce any typeset +% output. Instead, they are designed to store the result in a LaTeX +% counter for further manipulation. So +% |\unromanstore|\marg{numeral}\marg{counter} will store the value +% of \meta{numeral} in counter \meta{counter}. For example, +% |\unromanstore{mcmxcii}{mycounter}| +% \unromanstore{mcmxcii}{mycounter} yields |\the\value{mycounter}| +% of \the\value{mycounter}. +% +% \subsection{The length of a Roman numeral} +% +% \DescribeMacro{\romanheadlen} +% \DescribeMacro{\romantaillen} +% \DescribeMacro{\romanheadlenstore} +% \DescribeMacro{\romantaillenstore} +% Using the core macros of |unroman|, it is easy to design methods +% for determining how many characters of a string constitute a valid +% Roman numeral. Obviously, if the entire string is expected to be +% a numeral, then the |\substr| macro from the |coolstr| package +% is applicable. The |unroman| package provides two functions to +% measure numerals at the end of strings, |\romanheadlen| and +% |\romantaillen|. For example, |\romantaillen{Figure~XI}| +% yields \romantaillen{Figure~XI}. Versions of both macros +% are provided which store the result in a counter, as +% |\romanheadlenstore| and |\romantaillenstore| +% +% \subsection{Reversing a string} +% +% \DescribeMacro{\reversestr} +% The most efficient method for converting Roman numerals to +% Arabic numbers in LaTeX first requires the string to be reversed. +% For example, the numeral MCMXCII is first changed to IICXMCM before +% processing. As a result, |unroman| contains code to reverse a +% string. This is made available as a user command +% |\reversestr|\marg{string}. A simple example is +% |\reversestr{Hello}|, yielding ``\reversestr{Hello}''. This command is +% robust. +% +% \StopEventually{} +% +% \iffalse +%<*package> +% \fi +% +% \section{Implementation} +% +% \subsection{Setup code} +% +% The first part of the package is concerned with basic +% identification and loading support packages. The only package +% needed is |coolstr|, which is used to provide a length-of-string +% function. +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{unroman}% + [2007/06/11 v1.0 From Roman numerals to Arabic numbers] +\RequirePackage{coolstr} +% \end{macrocode} +% +% \begin{macro}{urm@counta} +% \begin{macro}{urm@countb} +% \begin{macro}{urm@value} +% \begin{macro}{urm@stringlength} +% \begin{macro}{\ifurm@tailerror} +% Various internal counters are needed by the package in order to +% function. These are declared here. A single new Boolean is also +% needed. +% \begin{macrocode} +\newcounter{urm@counta} +\newcounter{urm@countb} +\newcounter{urm@value} +\newcounter{urm@stringlength} +\newif\ifurm@tailerror +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Internal macros} +% +% \begin{macro}{\urm@numtoint} +% The business-end macro of the entire package is the conversion of +% a single character to its value. Using any of the case-changing +% macros (\emph{e.g.}~|\lowercase|, |\MakeLowercase|, \emph{etc.}) +% leads to problems. So the function tests for both upper- and +% lowercase letters. See also the LaTeX kernel function +% |\@slowromancap|, which takes a similar cautious approach to +% changing case. +% \begin{macrocode} +\def\urm@numtoint#1{% + \if#1i% + 1% + \else% + \if#1v% + 5% + \else% + \if#1x% + 10% + \else% + \if#1l% + 50% + \else% + \if#1c% + 100% + \else% + \if#1d% + 500% + \else% + \if#1m% + 1000% + \else% + \if#1I% + 1% + \else + \if#1V% + 5% + \else% + \if#1X% + 10% + \else% + \if#1L% + 50% + \else% + \if#1C% + 100% + \else% + \if#1D% + 500% + \else% + \if#1M% + 1000% +% \end{macrocode} +% If the character hasn't been matched, then it is not a valid +% Roman numeral. The value $-1$ is used as an indicator of this. +% \begin{macrocode} + \else% + -1% + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\urm@calc} +% The |\urm@calc| macro is the engine-room of the whole package. +% \begin{macrocode} +\def\urm@calc#1#2\end{% +% \end{macrocode} +% First, the current lead character is converted to its integer +% equivalent. This is stored in the first working counter +% \begin{macrocode} + \setcounter{urm@counta}{\urm@numtoint{#1}}% +% \end{macrocode} +% The value returned by |\urm@numtoint| is examined to check for +% the warning value $-1$. +% \begin{macrocode} + \ifnum\the\value{urm@counta}>\z@% +% \end{macrocode} +% The character returned is a valid Roman numeral. The next step is +% to compare to the value of the previous character. The value is then +% compared to that for the previous character (stored in +% |urm@countb|). Working from right to left, the current value is +% to be taken off the running total if it is less than the previous +% value. This is handled by sign inversion. +% \begin{macrocode} + \ifnum\the\value{urm@counta}<\the\value{urm@countb}% + \setcounter{urm@counta}{-\the\value{urm@counta}}% + \fi% + \addtocounter{urm@value}{\the\value{urm@counta}}% + \setcounter{urm@countb}{\the\value{urm@counta}}% +% \end{macrocode} +% Having carried out the calculation, the string being processed +% is shortened by one character, ready for the next pass. +% \begin{macrocode} + \def\urm@string@a{#2}% +% \end{macrocode} +% The case where |urm@counta| equals $-1$ value is now handled. +% Depending on which user function is in action, processing of the +% string may just stop. The alternative is to return a value of 0 +% and also provide suitable information in the run log. +% \begin{macrocode} + \else% + \ifurm@tailerror% + \PackageInfo{unroman}% + {Invalid character in string --- returning value 0}% + \setcounter{urm@value}{0}% + \fi% + \def\urm@string@a{}% + \fi% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\urm@reverse@string} +% The core of the string-reversing algorithm is picking off the +% first character of the string and using it to build a new string, +% in the opposite direction. Here, |\urm@string@b| is used to +% store the new string, while |\urm@string@c| holds the original +% information being ``eaten'' at each step. +% \begin{macrocode} +\def\urm@reverse@string#1#2\end{% + \edef\urm@string@b{#1\urm@string@b}% + \def\urm@string@c{#2}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\urm@reversestring} +% The second internal function for reversing strings loops through +% each character of the supplied string. As this function is used +% for internal reasons, it doesn't print anything. This leads to +% the need for this to be an internal function. +% \begin{macrocode} +\def\urm@reversestring#1{% + \def\urm@string@c{#1}% + \strlenstore{#1}{urm@stringlength}% + \def\urm@string@b{}% + \@whilenum\the\value{urm@stringlength}>\z@\do% + {\expandafter\urm@reverse@string\urm@string@c\end% + \strlenstore{\urm@string@c}{urm@stringlength}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\urm@roman@length} +% The core function for finding the length of a Roman numeral +% uses |\urm@numtoint| to determine whether characters in the +% string are valid Roman numerals. Once this stops, the +% string is truncated. +% \begin{macrocode} +\def\urm@roman@length#1#2\end{% + \setcounter{urm@counta}{\urm@numtoint{#1}}% + \ifnum\the\value{urm@counta}>\z@% + \addtocounter{urm@value}{1}% + \def\urm@string@a{#2}% + \else% + \def\urm@string@a{}% + \fi% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\urm@romanlength} +% The counter for the length of a Roman numeral is set up here, and +% the same looping as used elsewhere is implemented. +% \begin{macrocode} +\def\urm@romanlength#1{% + \setcounter{urm@value}{0}% + \strlenstore{#1}{urm@stringlength}% + \def\urm@string@a{#1}% + \@whilenum\the\value{urm@stringlength}>\z@\do% + {\expandafter\urm@roman@length\urm@string@a\end% + \strlenstore{\urm@string@a}{urm@stringlength}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\urm@make@head} +% \begin{macro}{\urm@makehead} +% The functions to strip a Roman numeral at the start of a string +% are very similar to those used to count how long such a string +% is. The only difference is the construction of a new string as +% the counting occurs. +% \begin{macrocode} +\def\urm@make@head#1#2\end{% + \setcounter{urm@counta}{\urm@numtoint{#1}}% + \ifnum\the\value{urm@counta}>\z@% + \edef\urm@string@b{\urm@string@b#1}% + \def\urm@string@a{#2}% + \else% + \def\urm@string@a{}% + \fi% +} +\def\urm@makehead#1{% + \strlenstore{#1}{urm@stringlength}% + \def\urm@string@a{#1}% + \def\urm@string@b{}% + \@whilenum\the\value{urm@stringlength}>\z@\do% + {\expandafter\urm@make@head\urm@string@a\end% + \strlenstore{\urm@string@a}{urm@stringlength}% + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\urm@unroman} +% The final internal macro is the loop to convert a Roman numeral +% into a number. +% \begin{macrocode} +\newcommand*{\urm@unroman}[1]{% +% \end{macrocode} +% The counters needed are initialised. The counter |urm@value| is +% used to hold the result of the conversion, whilst |urm@countb| +% is needed to track the value of the previously-converted character. +% \begin{macrocode} + \setcounter{urm@value}{0}% + \setcounter{urm@countb}{0}% +% \end{macrocode} +% The string is reversed, as this makes it much easier to calculate +% the value of the numeral. +% \begin{macrocode} + \urm@reversestring{#1}% + \let\urm@string@a\urm@string@b% +% \end{macrocode} +% The main loop then converts the value, iterating through the string +% one character at a time. +% \begin{macrocode} + \strlenstore{\urm@string@a}{urm@stringlength}% + \@whilenum\the\value{urm@stringlength}>\z@\do% + {\expandafter\urm@calc\urm@string@a\end% + \strlenstore{\urm@string@a}{urm@stringlength}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{User space macros} +% +% \begin{macro}{\reversestr} +% The string reversing macro simply calls the internal version of +% the function, then outputs the resulting string. Due to the +% interaction of the internal macros, this ends up as +% |\urm@string@b| rather than the more obvious |\urm@string@a|. +% \begin{macrocode} +\DeclareRobustCommand*{\reversestr}[1]{% + \urm@reversestring{#1}% + \urm@string@b% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\unroman} +% \begin{macro}{\unromanstore} +% \begin{macro}{\unromantail} +% \begin{macro}{\unromantailstore} +% \begin{macro}{\unromanhead} +% \begin{macro}{\unromanheadstore} +% \begin{macro}{\unromanheadlen} +% \begin{macro}{\unromanheadlenstore} +% \begin{macro}{\unromantaillen} +% \begin{macro}{\unromantaillenstore} +% All of the user space functions to generate numbers come in two +% versions. The |store| versions are modelled on the |coolstr| +% package. All of these functions simple make appropriate calls to +% the internal functions, then deal correctly with the output. +% \begin{macrocode} +\newcommand*{\unroman}[1]{% + \urm@tailerrortrue% + \urm@unroman{#1}% + \the\value{urm@value}% +} +\newcommand*{\unromanstore}[2]{% + \urm@tailerrortrue% + \urm@unroman{#1}% + \setcounter{#2}{\the\value{urm@value}}% +} +\newcommand*{\unromantail}[1]{% + \urm@tailerrorfalse% + \urm@unroman{#1}% + \the\value{urm@value}% +} +\newcommand*{\unromantailstore}[2]{% + \urm@tailerrorfalse% + \urm@unroman{#1}% + \setcounter{#2}{\the\value{urm@value}}% +} +\newcommand*{\unromanhead}[1]{% + \urm@makehead{#1}% + \expandafter\unroman\expandafter{\urm@string@b}% +} +\newcommand*{\unromanheadstore}[2]{% + \urm@makehead{#1}% + \expandafter\unromanstore\expandafter{\urm@string@b}{#2}% +} +\newcommand*{\romanheadlen}[1]{% + \urm@romanlength{#1}% + \the\value{urm@value}% +} +\newcommand*{\romanheadlenstore}[2]{% + \urm@romanlength{#1}% + \setcounter{#2}{\the\value{urm@value}}% +} +\newcommand*{\romantaillen}[1]{% + \urm@reversestring{#1}% + \expandafter\urm@romanlength\expandafter{\urm@string@b}% + \the\value{urm@value}% +} +\newcommand*{\romantaillenstore}[2]{% + \urm@reversestring{#1}% + \expandafter\urm@romanlength\expandafter{\urm@string@b}% + \setcounter{#2}{\the\value{urm@value}}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \iffalse +%</package> +% \fi +% \PrintChanges +% \PrintIndex +% \Finale diff --git a/Master/texmf-dist/source/latex/unroman/unroman.ins b/Master/texmf-dist/source/latex/unroman/unroman.ins new file mode 100644 index 00000000000..216062f2e47 --- /dev/null +++ b/Master/texmf-dist/source/latex/unroman/unroman.ins @@ -0,0 +1,32 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% unroman is free software; you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published +% by the Free Software Foundation; either version 2, or (at your +% option) any later version. +% +% unroman is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program; if not, write to the Free Software +% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\input docstrip.tex +\askonceonly +\preamble + ---------------------------------------------------------------- + The unroman package - From Roman numerals to Arabic numbers + Maintained by Joseph Wright + E-mail: joseph.wright@morningstar2.co.uk + Released under the GNU General Public License + See http://www.gnu.org/licenses/gpl.txt + ---------------------------------------------------------------- +\endpreamble +\Msg{Generating unroman files:} +\usedir{tex/latex/contib/unroman} +\generate{\file{unroman.sty}{\from{unroman.dtx}{package}}} +\endbatchfile |