% \iffalse meta-comment % % Copyright (C) 2005 by Scott Pakin % ------------------------------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.2 % 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.2 or later is part of all distributions of LaTeX % version 1999/12/01 or later. % % \fi % % \iffalse %<*driver> \ProvidesFile{mftinc.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{mftinc} %<*package> [2005/01/31 v1.0a Include pretty-printed Metafont listings in LaTeX] % % %<*driver> \documentclass{ltxdoc} \usepackage{mftinc}[2005/01/31] \EnableCrossrefs \CodelineIndex \RecordChanges % Unfortunately, we need to input mftmac.tex in the driver section. Its % lines don't start with "%", which causes doc to complain. Even worse, % mftmac steps on a few LaTeX things, which we have to correct here % and/or every time we show MFT examples in this document. \newlength{\oldparindent} \setlength{\oldparindent}{\parindent} \input mftmac \setlength{\parindent}{\oldparindent} % Define a \MFT command to typeset "MFT" in the same font that Knuth % uses to typeset "Metafont". If the font doesn't exist, just use the % current sans-serif font as an approximation. \IfFileExists{mflogo.sty} {\let\MF=\relax \RequirePackage{mflogo} \newcommand{\MFT}{\textlogo{MFT}}} {\newcommand{\MFT}{{\tenlogo MFT}}} % Use booktabs if we have it, otherwise fake its macros. \IfFileExists{booktabs.sty} {\RequirePackage{booktabs}} {\let\toprule=\hline \let\midrule=\hline \let\bottomrule=\hline } \begin{document} \DocInput{mftinc.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{525} % % \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 \~} % % % \changes{v1.0}{2001/05/15}{Initial version} % \changes{v1.0a}{2005/01/31}{Restructured the \texttt{.dtx} file} % % \GetFileInfo{mftinc.dtx} % % \DoNotIndex{\%, \', \/, \:, \\, \9} % \DoNotIndex{\@height, \@minus, \@plus, \@tempdima} % \DoNotIndex{\addtolength, \advance, \begin, \begingroup, \bgroup} % \DoNotIndex{\box, \char, \chardef, \cr, \DeclareRobustCommand, \def} % \DoNotIndex{\divide, \dp, \egroup, \else, \empty, \end, \endgroup} % \DoNotIndex{\expandafter, \fi, \gdef, \global, \halign, \hbox, \hfil} % \DoNotIndex{\hrule, \hrulefill, \hsize, \hspace} % \DoNotIndex{\ht, \ifdim, \if, \ifnum, \ifx, \ignorespaces, \it} % \DoNotIndex{\kern, \lastpenalty, \let, \loop, \linewidth, \long, \lower} % \DoNotIndex{\meaning, \medskip, \MessageBreak, \multiply, \multispan} % \DoNotIndex{\newcount, \newdimen, \newenvironment, \newfam, \newif} % \DoNotIndex{\newlength, \next} % \DoNotIndex{\noalign, \nobreak, \noindent, \nointerlineskip, \null, \par} % \DoNotIndex{\penalty, \quad, \raise, \renewcommand, \renewenvironment} % \DoNotIndex{\repeat, \rlap, \rm, \setbox, \setlength, \settowidth} % \DoNotIndex{\smash, \space, \tabskip, \the, \tt, \unskip, \vbox, \vcenter} % \DoNotIndex{\vrule, \vskip, \vspace, \xdef} % % ^^A Give LaTeX some more leeway in placing floats % ^^A (suggested by Donald Arseneau ). % \renewcommand{\topfraction}{0.85} % \renewcommand{\bottomfraction}{0.7} % \renewcommand{\textfraction}{0.15} % \renewcommand{\floatpagefraction}{0.66} % \renewcommand{\dbltopfraction}{0.66} % \renewcommand{\dblfloatpagefraction}{0.66} % \setcounter{topnumber}{9} % \setcounter{bottomnumber}{9} % \setcounter{totalnumber}{20} % \setcounter{dbltopnumber}{9} % % ^^A We caption tables at the top, so make sure we have sufficient spacing. % \setlength{\belowcaptionskip}{\abovecaptionskip} % % % \title{The \textsf{mftinc} package\thanks{This document % corresponds to \textsf{mftinc}~\fileversion, dated \filedate.}} % \author{Scott Pakin \\ \texttt{scott+mft@pakin.org}} % % \maketitle % % \begin{abstract} % The \MFT\ program pretty-prints \MF\ source code into a \TeX\ file. % The \textsf{mftinc} package facilitates incorporating such files % into a \LaTeXe\ document. In addition, \textsf{mftinc} provides % routines for improved comment formatting and for typesetting font % tables. % \end{abstract} % % \section{Introduction} % % \MF~\cite{mft:MFB} is Donald Knuth's system for creating fonts---and % entire families of fonts---by describing the characters % mathematically in a specialized programming language. As with any % programming language, it is important for a programmer to document his % code, to make it easier to extend and modify in the future. \MFT\ is % a stand-alone utility that makes \MF\ programs more readable by % typesetting different language constructs (keywords, variables, etc.)\ % in different fonts and styles. For example, the following is the font % program for Computer Modern Roman's plus-sign character (taken % from |punct.mf|): % % \begin{verbatim} % cmchar "Plus sign"; % beginarithchar("+"); pickup rule.nib; % x1=x2=good.x .5w; top y1=h+eps; .5[y1,y2]=math_axis; % lft x3=hround u-eps; x4=w-x3; y3=y4=math_axis; % draw z1--z2; % stem % draw z3--z4; % crossbar % labels(1,2,3,4); endchar; % \end{verbatim} % \unskip % % \noindent % and this is how \MFT\ formats it: % % \bigskip % \noindent| |^^A % \begin{minipage}{0.9\linewidth} % \let\\=\textit \parindent=0pt % $\2{cmchar}\7"Plus sign";$\par % $\2{beginarithchar}(\7"+");\ \2{pickup}\\{rule}.\\{nib};$\par % $x_{1}=x_{2}=\\{good}.x\,.5w;\ \\{top}\,y_{1}=h+\\{eps};\ .5[y_{1},y_{2}]=^^A % \\{math\_axis};$\par % $\\{lft}\,x_{3}=\1{hround}u-\\{eps};\ x_{4}=w-x_{3};\ y_{3}=y_{4}=\\{math^^A % \_axis};$\par % $\2{draw}z_{1}\8{--}z_{2};\ \9 stem\par % $\2{draw}z_{3}\8{--}z_{4};\ \9 crossbar\par % $\2{labels}(1,2,3,4);\3{endchar};$\par % \end{minipage} % \bigskip % % The formatted version draws attention to language features. It shows % keywords in bold, variables in italics, subscripts as subscripts, and % comments right-justified. The problem, though, is that \MFT\ produces % Plain \TeX\ documents, which can't readily be included into a \LaTeXe\ % document. What's the advantage of including formatted font programs % in \LaTeX? The answer is that it lets you take advantage of \LaTeX's % formatting and structuring capabilities to produce clear font % documentation with comparatively little effort. Because a \MF\ % program is like any other program, good documentation is important, as % it makes it easier to extend and modify the font in the future. Using % \LaTeX, you can, for instance, put majuscules in one chapter, % miniscules in another, and punctuation in a third; you can include % graphics produced by \MF's smoke or proof modes to show what the % resulting glyphs should look like; and you could add hyperlinks, a % table of contents, a bibliography, font samples, and anything else % that can clarify how the various character programs operate. % % The \textsf{mftinc} packages's initial purpose was somewhat % unambitious: simply include an \MFT-produced |.tex| file within a % \LaTeXe\ document. But it evolved from that to support the following % additional features: % % \begin{itemize} % \item Comments describing large, top-level blocks of code, such % as the character programs themselves % % \item Stanza-level comments within a block of code % % \item Font tables, \`a la Knuth's |textfont.tex| utility % \end{itemize} % % Figure~\ref{mft:annotated-plus} shows an example of how one might % format Computer Modern Roman's plus-sign program, using % \textsf{mftinc}'s comment environments. Notice how \textsf{mftinc} % makes the introductory paragraph stand out from the character program % by placing it between a pair of horizontal rules and the final paragraph % stand out from the surrounding code by prefixing each line with a percent % sign (\MF's comment character). % % \begin{figure}[tp] % \centering % \begin{minipage}{0.9\linewidth} % \let\\=\textit \parindent=0pt % \begin{explaincode} % \sloppy % The following is the definition of the plus sign character (``+''). % Admittedly, the glyph is so simple that it doesn't really need the % depth of commentary that's I'm providing here. I mainly wanted to % show how \textsf{mftinc} formats comments. Speaking of which, this is % a block-level comment, created with \textsf{mftinc}'s % \texttt{explaincode} environment. % \end{explaincode} % $\\{cmchar}\7"Plus sign";$\par % $\2{beginarithchar}(\7"+");$\par % \quad\quad$\9 This is an ordinary \MFT\ comment, entered with % \verb+%+. Notice how only the first line starts with a percent sign, % and the text isn't even properly indented. Yuck! \]\par % \quad\quad$\2{pickup}\\{rule}_{nib};$\par % \BL % \quad\quad$\9 This is another ordinary \MFT, \verb+%+-prefixed comment. % I had to \]\par % \quad\quad$\9 break the lines manually and end each line with a % \verb+\]+. While \]\par % \quad\quad$\9 that's okay for one-liners, it's an immense bother for % longer \]\par % \quad\quad$\9 comments (like this one). \]\par % \quad\quad$x_{1}=x_{2}=\\{good}.x\,.5w;$\par % \quad\quad$\\{top}\,y_{1}=h+\\{eps};$\par % \quad\quad$.5[y_{1},y_{2}]=\\{math\_axis};$\par % \quad\quad$\\{lft}\,x_{3}=\1{hround}u-\\{eps};$\par % \quad\quad$x_{4}=w-x_{3};$\par % \quad\quad$y_{3}=y_{4}=\\{math\_axis};$\par % \BL % \quad\quad \begin{wrapcomment} % \quad\quad Ah, much better! This comment was entered within one of % \quad\quad \textsf{mftinc}'s \texttt{wrapcomment} % \quad\quad environments. Notice how it's indented the correct amount, every % line % \quad\quad starts with a~\verb+%+, and the lines are fully justified---and % none % \quad\quad of this required any manual formatting. \textsf{mftinc} did all % the % \quad\quad work for us. % \quad\quad \end{wrapcomment} % \quad\quad$\2{draw}z_{1}\8{--}z_{2};\ \9 stem\par % \quad\quad$\2{draw}z_{3}\8{--}z_{4};\ \9 crossbar\par % \quad\quad$\2{labels}(1,2,3,4);$\par % $\!\3{endchar};$\par % \end{minipage} % \caption{Computer Modern Roman's ``+'', formatted with \textsf{mftinc}} % \label{mft:annotated-plus} % \end{figure} % % % \section{Usage} % % ^^A The following was swiped verbatim from ltxguide.cls. % \DeleteShortVerb\| % \newenvironment{decl}[1][]% % {\par\small\addvspace{4.5ex plus 1ex}% % \vskip -\parskip % \ifx\relax#1\relax % \def\@decl@date{}% % \else % \def\@decl@date{\NEWfeature{#1}}% % \fi % \noindent\hspace{-\leftmargini}% % \begin{tabular}{|l|}\hline\ignorespaces}% % {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak % \vspace{2.3ex}\vskip -\parskip} % \MakeShortVerb\| % % I hope the previous section and Figure~\ref{mft:annotated-plus} piqued % your interest in \textsf{mftinc}. We'll now look at how to use all of % \textsf{mftinc}'s features. Remember, the idea is that you use % \textsf{mftinc}'s commands and environments within a |.mf| file % (generally on lines beginning with |%%|, as \MFT\ passes such lines % unmodified to the resulting |.tex| file). You then format the |.mf| % file using \MFT\@. And finally, you include the resulting |.tex| file % into your main \LaTeX\ document (which contains a % |\usepackage{mftinc}| in its prologue to enable \textsf{mftinc}'s % features). % % \begin{center} % \begin{picture}(243,60)(54,0) % \put(73,40){\texttt{.mf}} % \put(89,42){\vector(1,0){34}} % \put(123,24){\framebox(54,36){\texttt{mft}}} % \put(177,42){\vector(1,0){36}} % \put(182,46){\texttt{.tex}} % \put(213,24){\framebox(54,36){\texttt{latex}}} % \put(267,42){\vector(1,0){30}} % \put(54,11){\parbox{63\unitlength}{^^A % \raggedright(with \textsf{mftinc} macros and environments)}} % \put(213,0){\makebox(54,3){\texttt{mftinc.sty}}} % \put(240,7){\vector(0,1){17}} % \end{picture} % \end{center} % % \noindent % Note that \textsf{mftinc}'s macros and environments do, in fact, % work in the main \LaTeX\ document. It's just that some of them % aren't particularly interesting outside of a \MF\ file. % % % \subsection{File inclusion} % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "\mftinput" \marg{filename} % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % \DescribeMacro{\mftinput} % |\mftinput| is used within the main \LaTeX\ document to incorporate % an \MFT-produced |.tex| file. If a file extension is not supplied, % |.tex| is assumed. % % % \subsection{Improved comment handling} % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "\begin{explaincode}" \oarg{options} \\ % \meta{comment text} \\ % "\end{explaincode}" % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % \DescribeEnv{explaincode} % \MF\ programs define one character program for each glyph in the font. % It's good style to start each of these---and other top-level blocks of % code---with a comment describing the code and its particular nuances. % The |explaincode| environment typesets such comments between % horizontal rules, so that the comments are more easily distinguishable % from the code they describe. |explaincode| also adds a little % stretchable space above the first rule to separate the comment from % whatever precedes it. For example, the following lines in a |.mf| file: % % \begin{verbatim} % %% \begin{explaincode} % %% This text is set within an \texttt{explaincode} environment. % %% \texttt{explaincode} is intended to be used before a character % %% program or other large block of code. % %% \end{explaincode} % \end{verbatim} % \unskip % \noindent % will look like this when run through |latex|: % % \begin{center} % \begin{minipage}{0.85\textwidth} % \begin{explaincode} % This text is set within an \texttt{explaincode} environment. % \texttt{explaincode} is intended to be used before a character % program or other large block of code. % \end{explaincode} % \end{minipage} % \end{center} % \bigskip % % The optional argument to |\begin{explaincode}| provides control % over the thickness of the two rules. This is discussed in % Section~\ref{mft:options}. % % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "\begin{wrapcomment}" \\ % \meta{comment text} \\ % "\end{wrapcomment}" % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % \DescribeEnv{wrapcomment} % The |wrapcomment| environment is used for comments that describe a % stanza---a logical chunk of code---within a character program or macro. % The important features of comments that are typeset with |wrapcomment| % are the following: % % \begin{itemize} % \item They can be multiple lines long. % \item They wrap text like any other piece of \LaTeX\ code. % \item Each line of output begins with a percent line. % \item The comments use the same indentation as the block of \MF\ % code they describe. % \end{itemize} % % Here's an example of a |wrapcomment| that's indented within a \MF\ % \textbf{for} loop and the way that \textsf{mftinc} tells \LaTeX\ % to format it: % % \begin{verbatim} % for i = 0 upto length cpath: % %% \begin{wrapcomment} % %% See how comments typeset within a \texttt{wrapcomment} % %% environment are indented? They line up with the first % %% \verb+%%+ within the environment. Just remember to use two % %% percent signs instead of one, or bad things will happen. % %% \end{wrapcomment} % draw z[i]--z.c; % endfor; % \end{verbatim} % % \begin{center} % \begin{minipage}{0.85\linewidth} % \let\\=\textit \parindent=0pt % $\2{for}i=0\4{upto}\1{length}\\{cpath}\?:$\par % \quad\quad \begin{wrapcomment} % \quad\quad See how comments typeset within a \texttt{wrapcomment} % \quad\quad environment are indented? They line up with the first % \quad\quad \verb+%%+ within the environment. Just remember to use two % \quad\quad percent signs instead of one, or bad things will happen. % \quad\quad \end{wrapcomment}\par % \quad\quad$\2{draw}z[i]\8{--}z_{c};$\par % $\!\3{endfor};$\par % \end{minipage} % \end{center} % % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "\mfcomment" % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % \DescribeMacro{\mfcomment} % One advantage that \MFT's |%| comments have over |%%| comments is that % they format anything that's set between vertical bars as it if it were % \MF\ code. For example, \verb+|draw z1--z2|+ is typeset as % ``$\2{draw}z_{1}\8{--}z_{2}$''. The problem is that the |explaincode| % and |wrapcomment| environments need to be typeset with~|%%|, so their % contents gets passed directly to \LaTeX. To embed \MF\ code within % |explaincode| or |wrapcomment|, one need only end the previous line with % |\mfcomment| and put the \MF\ code on the next line, preceded by a~|%|: % % \begin{verbatim} % %% \begin{wrapcomment} % %% The reason we set \mfcomment % % |x4 = w - x3| % %% below is to ensure that when we later \mfcomment % % do a ``|draw x4{up}..x1..{down}x3|'', the character % %% will have equal left and right sidebearings. % %% \end{wrapcomment} % \end{verbatim} % % \begin{center} % \begin{minipage}{0.9\linewidth} % \let\\=\textit \parindent=0pt % \quad \begin{wrapcomment} % \quad The reason we set \mfcomment % \quad$\9 $x_{4}=w-x_{3}$\par % \quad below is to ensure that when we later \mfcomment % \quad$\9 do a ``$\2{draw}x_{4}\{\\{up}\}\8{..}x_{1}\8{..}\{\\{down}% % \}x_{3}$'', the character\par % \quad will have equal left and right sidebearings. % \quad \end{wrapcomment} % \end{minipage} % \end{center} % % % \subsection{Font tables} % % Most \TeX\ distributions come with a program of Knuth's called % |testfont.tex|, which can produce a variety of font samples. One of % |testfont|'s more useful features is the ability to produce a table of % all the characters in a given font: % % \begin{verbatim} % % tex testfont % This is TeX, Version 3.14159 (Web2C 7.3.2) % (/usr/share/texmf/tex/plain/base/testfont.tex % % Name of the font to test = cmr10.mf % Now type a test command (\help for help):) % *\table % % *\bye % [1] % Output written on testfont.dvi (1 page, 5812 bytes). % Transcript written on testfont.log. % \end{verbatim} % \unskip % % \def\oct#1{\hbox{\rm\'{}\kern-.2em\it#1\/\kern.05em}}% % \def\hex#1{\hbox{\rm\H{}\tt#1}}% % % \noindent % Table~\ref{mft:cmr10-full} depicts the table that this produces. % Characters are numbered in both octal (\oct{000}--\oct{177}) and % hexadecimal (\hex{00}--\hex{7F}). Empty rows---of which there aren't % any in this example---are automatically omitted. % % \begin{table}[htbp] % \caption{Complete \texttt{cmr10} character set} % \label{mft:cmr10-full} % \fonttable{cmr10} % \end{table} % % % \DescribeMacro{\fonttable} % The problem is that |testfont.tex| was designed to be used % interactively and stand-alone. But wouldn't it be nice to be able to % include a font table in the same document that contains the annotated % font source code? With \textsf{mftinc}, you can do just that. % \textsf{mftinc} includes a |\fonttable| command, based on the one in % |testfont.tex|---in fact, much of |\fonttable|'s code was taken verbatim % from |testfont.tex|---but extended to provide more features and to % interact better with \LaTeX. % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "\fonttable" \oarg{options} \marg{font name} % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % The mandatory argument, \meta{font name}, is the name of the font to % chart. Note that this must be the \TeX, as opposed to \LaTeXe, font % name. For example, to draw a font table of 11\,pt.\ Computer Modern % Typewriter Text, one would have to write ``|\fonttable{cmtt10| % \texttt{at 11pt}|}|'', because there is no 11\,pt.\ version of the % font, only a 10\,pt.\ version scaled up to~11\,pt. The optional % argument to |\fonttable|, \meta{options}, provides control over the % width of the table and the range of characters included within it. % This is discussed in Section~\ref{mft:options}. % % % \subsection{Options} % \label{mft:options} % % The |explaincode| environment and the |\fonttable| macro each take an % optional argument containing zero or more comma-separated, % \meta{key}=\meta{value} pairs. These allow for finer control over % \textsf{mftinc}'s behavior. % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "toprule="\meta{dimen} \\ % "bottomrule="\meta{dimen} % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % The horizontal rules drawn above and below an |explaincode| comment % are normally 1\,pt.\ thick. The |toprule| and |bottomrule| options % enable you to change this default. For example: % % \begin{verbatim} % %% \begin{explaincode}[toprule=3mm,bottomrule=5pt] % %% The rule above this sentence is 3\,mm.\ thick, and the rule % %% below this sentence is 5\,pt.\ thick. % %% \end{explaincode} % \end{verbatim} % \unskip % % \begin{center} % \begin{minipage}{0.85\textwidth} % \begin{explaincode}[toprule=3mm,bottomrule=5pt] % The rule above this sentence is 3\,mm.\ thick, and the rule % below this sentence is 5\,pt.\ thick. % \end{explaincode} % \end{minipage} % \end{center} % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "tablewidth="\meta{dimen} % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % The tables drawn by |\fonttable| normally expand to fill the width of % the text. The |tablewidth| option lets you choose an arbitrary table % width. For example: % % \begin{verbatim} % \fonttable[tablewidth=0.5\linewidth]{logo10} % \end{verbatim} % \unskip % % \begin{center} % \fonttable[tablewidth=0.5\linewidth]{logo10} % \end{center} % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "charrange="\meta{range} % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % Knuth's original table code shows every character in a given font, and % that's what |\fonttable| does by default. However, the |charrange| % option lets you limit the range of characters that are output to a % subset of the characters available in the font. \meta{range} is the % range of character codes to output, specified as % ``\meta{first}|-|\meta{last}''. \meta{first} and \meta{last} are both % inclusive and can be specified in any number format that \TeX\ % accepts---decimal (|123|), hexadecimal (|"7B|), or octal (|'173|). If % \meta{first} is omitted (|-123|), it defaults to the first character % in the font. If \meta{last} is omitted (|123-|), it defaults to the % last character in the font. Single numbers (|123|) are acceptable, as % are comma-separated ranges of numbers % (|65-96,|\linebreak[0]|123-127|). In the last case, the ranges must % be specified within curly braces so that \textsf{mftinc} knows they % are all part of |charrange|'s argument, and not the argument to a % subsequent option. % % |charrange| is useful when typesetting font documentation, because a % section can begin by showing a table of all the glyphs that will be % defined in that section. For example |punct.mf| defines the % following subset of the Computer Modern fonts, according to Knuth's % comments at the top of that file: % % \begin{verbatim} % \fonttable[tablewidth=0.75\linewidth, % charrange={'41,'43,'45,'47-'54,'56-'57,'72-'73,'75, % '100,'133,'135,'140}]{cmss10 at 11pt} % \end{verbatim} % \unskip % \noindent % Table~\ref{mft:punct-chars} shows the result of that |\fonttable| % invocation. Note how only the specified characters are shown, and % empty rows (more precisely, empty double-rows) are omitted from the % table. Hence, the table ranges from hexadecimal \hex{20}--\hex{6F} % instead of from \hex{00}--\hex{7F}. % % \begin{table}[htbp] % \centering % \caption{\texttt{cmss10} characters defined in \texttt{punct.mf}} % \label{mft:punct-chars} % \fonttable[tablewidth=0.75\linewidth, % charrange={'41,'43,'45,'47-'54,'56,'57,'72,'73,'75, % '100,'133,'135,'140}]{cmss10 at 11pt} % \end{table} % % % \DeleteShortVerb{\|}\MakeShortVerb{\"} % \begin{decl} % "\setmftdefaults" \marg{options} % \end{decl} % \DeleteShortVerb{\"}\MakeShortVerb{\|} % % \noindent % \DescribeMacro{\setmftdefaults} % It can be cumbersome to repeatedly pass the same arguments to % |charexplain| or |\fonttable|. Hence, \textsf{mftinc} exports a % |\setmftdefaults| macro. |\setmftdefaults| takes the same % \meta{key}=\meta{value} pairs as |charexplain| and |\fonttable|, but % uses them to change the default value of each option for all future % invocations of |charexplain| and |\fonttable|: % % \begin{verbatim} % \setmftdefaults{charrange=65-67,toprule=3pt,bottomrule=3pt} % \begin{explaincode} % \textsf{mftinc}'s default parameters have been altered. % However, it's still possible to override those defaults % on a case-by-case basis. % \begin{center} % \fonttable{cmsy10 at 17pt} % \fonttable[charrange=68-70]{cmsy10 at 17pt} % \fonttable{cmsy10 at 17pt} % \end{center} % \end{explaincode} % \end{verbatim} % \unskip % \noindent % The result is shown in Figure~\ref{mft:setmftdefaults}. % % \begin{figure}[htbp] % \centering % \begin{minipage}{0.85\textwidth} % \setmftdefaults{charrange=65-67,toprule=3pt,bottomrule=3pt} % \begin{explaincode} % \textsf{mftinc}'s default parameters have been altered. % However, it's still possible to override those defaults % on a case-by-case basis. % \begin{center} % \fonttable{cmsy10 at 17pt} % \fonttable[charrange=68-70]{cmsy10 at 17pt} % \fonttable{cmsy10 at 17pt} % \end{center} % \end{explaincode} % \end{minipage} % \caption{Example of changing and overriding \textsf{mftinc}'s defaults} % \label{mft:setmftdefaults} % \end{figure} % % % \section{Other information} % % This section contains miscellaneous commentary on \textsf{mftinc}, % \MFT, and other things that don't fit into any of the other sections. % % \subsection{\textsf{mftinc} copyright and license} % % Copyright \textcopyright\ 2005 Scott Pakin \texttt{}. % \bigskip % % This package may be distributed and/or modified under the % conditions of the \LaTeX\ Project Public License, either version~1.2 % of this license or (at your option) any later version. % The latest version of this license is in % \begin{center} % |http://www.latex-project.org/lppl.txt| % \end{center} % \noindent % and version~1.2 or later is part of all distributions of \LaTeX\ % version~1999/12/01 or later. % % % \subsection{Package dependencies} % % \textsf{mftinc} requires the \textsf{rawfonts} and \textsf{keyval} % packages, both of which are included with virtually every \LaTeXe\ % distribution. The |wrapcomment| environment additionally requires % \textsf{chngpage} and \textsf{lineno}, which are nonstandard but % freely available from CTAN (\texttt{http://www.ctan.org/}). If % \textsf{mftinc} can't find \textsf{chngpage} or \textsf{lineno}, it % will issue a \emph{warning} message, which turns into an error message at % the first |\begin{wrapcomment}|. Hence, if you merely want to include % \MFT\ output, font tables, and character-level comments and are willing % to sacrifice stanza-level comments, you can avoid the bother of % downloading and installing two additional packages. % % % \subsection{Including proof and smoke images} % % Knuth's \textit{Computer Modern Typefaces}~\cite{mft:CMT} shows % proof-mode versions of each character next to the corresponding % character program. One way to do this yourself for your own fonts is % to use MetaPost, which can produce an Encapsulated PostScript (EPS) % image of each character in a font. The exact details may differ % slightly from system to system, but here's the basic approach: First, % assuming you don't already have it, you have to produce a % |mfplain.mem| file. The command to do this on a Unix-based system is % usually: % % \bigskip % \noindent % | mpost -ini '\input mfplain; dump'| % \bigskip % % \noindent % On Windows, you'll probably need to use double quotes instead of single % quotes. On other systems, you're on your own. % % The |mfplain.mem| files enables MetaPost to accept (most) \MF\ commands. % The next step is to use MetaPost plus |mfplain.mem| to produce a proof-mode % version of your font: % % \bigskip % \noindent % | mpost -mem mfplain '\mode:=proof; prologues:=2; input |\meta{filename}|'| % \bigskip % % \noindent % \dots or a smoke-mode version: % % \bigskip % \noindent % | mpost -mem mfplain '\mode:=smoke; prologues:=2; input |\meta{filename}|'| % \bigskip % % In either case, MetaPost will produce a separate EPS file for each % character in the font. These will be named % \meta{filename}|.|\meta{character code}. For example, the EPS file % for |cmr10.mf|'s letter ``A'' will be called |cmr10.65|, because ``A'' % is at position~65 in that font. You may want to give these files a % |.eps| extension, so that \LaTeX\ and other programs realize that the % files are EPS\@. The good news is that even pdf\LaTeX, which can't read % arbitrary EPS files, can read MetaPost's EPS output. (By default, % pdf\LaTeX\ expects the files to have a |.mps| extension, however.) % % % \subsection{Known bugs} % % The first |%%| after a |\begin{wrapcomment}| must be indented at least % one space. Otherwise, \LaTeX\ will abort with ``\texttt{! LaTeX Error:} % |\begin{wrapcomment}| \texttt{on input line}~\meta{line} \texttt{ended % by} |\end{linenumbers}|''. % % % \subsection{A brief \MFT\ reference} % % \MFT\ processes comments beginning with one to four percent signs in % different ways, as shown in Table~\ref{mft:mft-comments}. The \MFT\ % documentation says that comments starting with more than four percent % signs are verboten. \textsf{mftinc} is normally used within % double-percent comments, because those are passed directly to \LaTeX\ % with no additional processing on \MFT's part. % % \begin{table}[htbp] % \centering % \caption{\MFT\ comment types} % \label{mft:mft-comments} % \renewcommand{\arraystretch}{1.5} % \begin{tabular}{@{}lp{0.7\textwidth}@{}} \toprule % \multicolumn{1}{@{}c}{Type} & % \multicolumn{1}{c@{}}{Description} \\ \midrule % % |%| & % Format a comment using \TeX\ (or with \textsf{mftinc}, \LaTeX), with % the addition that text within vertical bars is formatted as if it were % outside of the comment (i.e., as if it were \MF\ code). Single-|%| % comments are output right-justified with a leading percent sign. % Ending a line with |\]| makes it left-justified, though. \\ % % |%%| & % Format a comment using \TeX\ (or with \textsf{mftinc}, \LaTeX), with % none of single-|%|'s bells and whistles---no leading percent sign, no % right-justification, and no support for embedded \MF\ code. % \textsf{mftinc}'s |explaincode| and |wrapcomment| environments % belong within double-|%| comments. \\ % % |%%%| & % Given a list of space-separated \MF\ tokens, make \MFT\ format all % of them like the first one in the list. Hence ``|%%%| % \texttt{addto mymacro}'' says to format the token |mymacro| just % like \MF's |addto| primitive. \\ % % |%%%%| & % \MFT\ discards lines beginning with quadruple-|%| comments. \\ % \bottomrule % \end{tabular} % \end{table} % % |mftmac.tex|, which is |\input| by every |.tex| file that \MFT\ % produces, defines a number of macros for typesetting \MF\ % (Table~\ref{mft:additional-macros}). These may be used within a |%%| % comment when doing so is more convenient than \textsf{mftinc}'s % |\mfcomment| macro (e.g., if only a single symbol need be typeset). % The following are the important things to note about these macros: % % \begin{itemize} % \item They're defined to be used in math mode, so be sure to use % them within |$|\dots|$|. % % \item The different boldfaced operators have different surrounding % spacing (not always obvious from % Table~\ref{mft:additional-macros}). To select the right operator, % I usually look at the |.tex| file to see how it formats the % operator in the font program listing. % % \item |\\| doesn't mean ``line break'', as it normally does in \LaTeX; % use |\newline| instead. % \end{itemize} % % \begin{table}[htbp] % \centering % \caption{Additional \MFT\ macros} % \label{mft:additional-macros} % \begin{tabular}{@{}ll@{}} \toprule % \multicolumn{1}{@{}c}{Macro} & % \multicolumn{1}{c@{}}{Example} \\ \midrule % % |\\|\marg{identifier} & \textit{i}, \textit{eps} \\ % |\1|\marg{operator} & $\1{length}$, $\1{hround}$ \\ % |\2|\marg{operator} & $\2{beginchar}$, $\2{for}$ \\ % |\3|\marg{closing operator} & $\3{fi}$, $\3{endgroup}$ \\ % |\4|\marg{binary operator} & $\4{step}$, $\4{at}$ \\ % |\5|\marg{constant} & $\5{true}$, $\5{nullpicture}$ \\ % |\6|\marg{binary operator} & $\6{++}$, $\6{scaled}$ \\ % |\7"|\meta{string}|"| & $\7"Hello, world!"$ \\ % |\8|\marg{relation} & $\8{..}$, $\8{--}$ \\ % |\?|\marg{relation} & \DeleteShortVerb{\|} % $\?{::}$, $\?{||:}$ % \MakeShortVerb{\|} \\ % |\PS| & $\PS$ \\ % |\SH| & $\SH$ \\ % |\frac|\marg{num}|/|\marg{den} & $\frac{17}/{23}$ \\ % \bottomrule % \end{tabular} % \end{table} % % % \StopEventually{^^A % \begin{thebibliography}{1} % \bibitem{mft:MFB} % Donald~E. Knuth. % \newblock {\em The \MF{}book}, volume~C of {\em Computers and Typesetting}. % \newblock Addison-Wesley, Reading, Massachusetts, 1986. % % \bibitem{mft:CMT} % Donald~E. Knuth. % \newblock {\em Computer Modern Typefaces}, volume~E of {\em Computers and % Typesetting}. % \newblock Addison-Wesley, Reading, Massachusetts, 1986. % \end{thebibliography} % } % % % \section{Implementation} % % Most users can stop reading at this point. The Implementation section % contains the annotated source code for the \textsf{mftinc} package % itself, which is useful only to people who want a detailed and precise % explanation of how \textsf{mftinc} works. If you're planning on % extending or customizing (or debugging!) the package, this is the % section for you. (Note that \textsf{mftinc} is released under the % \LaTeX\ Project Public License, which gives your the right to make % whatever modifications you want, provided you don't call the result % ``\textsf{mftinc}''.) % % \subsection{Including \MFT-formatted files} % % The following code provides the minimal amount of functionality % that \textsf{mftinc} needs to be useful: the ability to include an % \MFT-produced \TeX\ file in a \LaTeXe\ document. Because % \textsf{mftmac} uses \TeX\ (and \LaTeX~2.09) font names, such % as |\tenbf|, we have to load the \textsf{rawfonts} compatibility % package to make it work. In addition, \textsf{mftmac} assumes that % the |\bffam| and |\itfam| font families are predefined, which they % aren't in \LaTeXe, so we have to define those, too. % % \begin{macrocode} \RequirePackage{rawfonts} \newfam\bffam \newfam\itfam % \end{macrocode} % % \begin{macro}{\mftinput} % Fortunately, most of \textsf{mftmac}'s screwy macro definitions are % defined in the local scope (i.e., with |\def| instead of |\gdef|). % Hence, we can simply |\input| an \MFT-formatted file within a group, % and most things will go back to normal at the |\endgroup|. % \begin{macrocode} \DeclareRobustCommand{\mftinput}[1]{\begingroup\input #1\endgroup} % \end{macrocode} % \end{macro} % % % \subsection{Argument processing} % % The |explainchar| environment and the |\fonttable| command each take a % few optional arguments. We use the \textsf{keyval} package to help % process these arguments. Table~\ref{mft:supported-args} lists the % arguments that are currently supported. % % \begin{table}[htbp] % \centering % \caption{Options supported by \textsf{mftinc}'s macros and environments} % \label{mft:supported-args} % \renewcommand{\arraystretch}{1.5} % \begin{tabular}{@{}lllp{3cm}@{}} \toprule % \multicolumn{1}{@{}c}{Key} & % \multicolumn{1}{c}{Applies to} & % \multicolumn{1}{c}{Affects} & % \multicolumn{1}{c@{}}{Meaning} \\ \midrule % % |toprule| & |explainchar| & |\mft@top@rule| & % Width of the rule above |explainchar| comments \\ % % |bottomrule| & |explainchar| & |\mft@bot@rule| & % Width of the rule below |explainchar| comments \\ % % |tablewidth| & |\fonttable| & |\mft@table@width| & % Width of the font table \\ % % |charrange| & |\fonttable| & % \multicolumn{1}{p{12em}}{\raggedright\texttt{\string\mft@ranges} and % \texttt{\string\mft@expanded@ranges}} & % Comma-delimited, hyphenated ranges of characters to include in % the font table \\ \bottomrule % \end{tabular} % \end{table} % % \begin{macrocode} \RequirePackage{keyval} \define@key{mft}{toprule}{\setlength{\mft@top@rule}{#1}} \define@key{mft}{bottomrule}{\setlength{\mft@bot@rule}{#1}} \define@key{mft}{tablewidth}{\setlength{\mft@table@width}{#1}}% \define@key{mft}{charrange}{% \def\mft@ranges{}% \def\mft@expanded@ranges{}% \mft@parse@ranges#1,,% {\let\@elt=\mft@expand@range\mft@ranges}% } % \end{macrocode} % % \begin{macro}{\setmftdefaults} % Rather than repeatedly specify the same optional arguments, one can % use |\setmftdefaults| to specify default values for all % \textsf{mftinc} macros and environments that take optional arguments. % |\setmftdefaults| takes one mandatory argument, which has the same % effect globally as the various macros' and environments' optional % arguments have locally. % \begin{macrocode} \DeclareRobustCommand{\setmftdefaults}[1]{\setkeys{mft}{#1}} % \end{macrocode} % \end{macro} % % % \subsection{Improved comment formatting} % % There are three main places a font designer might want to insert % code comments: % % \begin{enumerate} % \item Before a character program or macro, % \item Before a stanza of a code within a character program or macro, and % \item On the same line as some \MF\ code. % \end{enumerate} % % \noindent % % \MFT\ has weak support for the first two of those. While \MFT\ passes % lines starting with ``|%%|'' directly to \TeX\ (or, when % \textsf{mftinc} is used, \LaTeX), text formatted this way doesn't % sufficiently stand stand out from the formatted \MF\ code, in my % opinion. Comments starting with~|%| are normally right-justified and % work well when used for brief phrases that share a line with \MF\ % code, but they are cumbersome to use for longer, non-right-justified, % stanza-level comments. In order to make each output line start with a % |%| (to make it clear that the text is a comment and not code), the % author must manually break lines and, in addition, end each line with % |\]| to inhibit right-justification. % % The macros that will be introduced in this section solve all of these % problems. % % % \subsubsection{Character-level comments} % % To clearly separate commentary from the program text that follows, we % define a simple, |explaincode| environment that draws a horizontal % rule above and below the contained text. % % \begin{macro}{\mft@top@rule} % Specify the thickness of the rule above the |explaincode| text. % \begin{macrocode} \newlength{\mft@top@rule} \setlength{\mft@top@rule}{1pt} % \end{macrocode} % \end{macro} % % \begin{macro}{\mft@bot@rule} % Specify the thickness of the rule below the |explaincode| text. % \begin{macrocode} \newlength{\mft@bot@rule} \setlength{\mft@bot@rule}{1pt} % \end{macrocode} % \end{macro} % % \begin{environment}{explaincode} % Draw a rule above and below any text contained within % |\begin{explaincode}|\dots\linebreak[0]|\end{explaincode}|. For % \ae{}sethetics, we add a little stretchable glue above the first rule % and a little shrinkable glue below the bottom rule. We also prohibit % page breaks between the rules and the text. % \begin{macrocode} \newenvironment{explaincode}[1][]{% \setkeys{mft}{#1}% \par\vskip 4ex \@plus 2ex \hrule\@height\mft@top@rule \nobreak\medskip\nobreak\noindent\ignorespaces }{% \nobreak\medskip\nobreak \hrule\@height\mft@bot@rule \vskip 2ex \@minus 1ex } % \end{macrocode} % \end{environment} % % % \subsubsection{Stanza-level comments} % % We define a new environment for formatting stanza-level comments that % honors the following properties: % % \begin{itemize} % \item The comments can be multiple lines long. % \item They wrap text like an ordinary block of \LaTeX\ code. % \item Each line of output begins with a percent line. % \item The comments use the same indentation as the block of \MF\ % code they describe. % \end{itemize} % % \begin{macro}{\mft@wc@indent} % This \meta{dimen} stores the indentation of a |wrapcomment| % environment, excluding the space occupied by the initial percent % signs. % \begin{macrocode} \newlength{\mft@wc@indent} % \end{macrocode} % \end{macro} % % \begin{macro}{\mft@eat@quads} % To figure out the correct indentation for the entire comment block, we % (tail-recursively) count the number of |\quad|s in the first line, % adding |1em| of space to |\mft@wc@indent| for each one encountered and % discarding the |\quad| as we go. At the end, we make |\quad| a no-op, % to prevent |\quad|s on subsequent lines from contributing unwanted % space, indent by |\mft@wc@indent| plus the width of a percent sign, % and use \textsf{lineno} to ``number'' the lines using percent signs. % \begin{macrocode} \def\mft@eat@quads#1{% \ifx#1\quad \global\addtolength{\mft@wc@indent}{1em}% \expandafter\mft@eat@quads \else \def\quad{}% \settowidth{\@tempdima}{\%~}% \advance\@tempdima by \mft@wc@indent \vspace{-2ex}% \begin{adjustwidth}{\@tempdima}{}% \begin{linenumbers}% \internallinenumbers \renewcommand{\makeLineNumber}{% \rlap{\hspace*{\mft@wc@indent}\%}}% \expandafter#1% \fi } % \end{macrocode} % \end{macro} % % \begin{environment}{wrapcomment} % Display a block of text that is indented to the same position as the % first text after the |\begin{wrapcomment}|. |\mft@eat@quads| does % most of the work. |wrapcomment| merely resets the indentation counter % and makes the first |\quad| consume the rest (via |\mft@eat@quads|). % The |\end{wrapcomment}| closes the |linenumbers| and |adjustwidth| % environments opened by |\mft@eat@quads|. % \begin{macrocode} \newenvironment{wrapcomment}{% \global\setlength{\mft@wc@indent}{0pt}% \def\quad{% \global\addtolength{\mft@wc@indent}{1em}% \mft@eat@quads }% }{% \end{linenumbers}% \end{adjustwidth}% } % \end{macrocode} % \end{environment} % % \begin{macro}{\mft@missing} % If we can't load one or both of the \textsf{chngpage} and % \textsf{lineno} packages, disable the |wrapcomment| environment and % issue a warning message. This is a little more user-friendly than % forcing the user to download and install two packages if all he wants % is to include an \MFT-formatted file in a \LaTeX\ document and has no % interest in ever using the |wrapcomment| environment. % \begin{macrocode} \def\mft@missing#1{% \PackageWarning{mftinc}{% Disabling the wrapcomment environment\MessageBreak (can't find #1.sty)% } \renewenvironment{wrapcomment}{% \PackageError{mftinc}{The wrapcomment environment is disabled}{% Your LaTeX installation is lacking #1.sty.\space\space The\MessageBreak mftinc package relies on both the chngpage package and\MessageBreak the lineno package in order to implement the wrapcomment \MessageBreak environment.\space\space Either install those packages, or refrain\MessageBreak from using wrapcomment in code that is formatted with mft\MessageBreak and included into LaTeX. }% }{}% \def\mft@missing##1{}% } \IfFileExists{chngpage.sty}{\RequirePackage{chngpage}}{\mft@missing{chngpage}} \IfFileExists{lineno.sty}{\RequirePackage{lineno}}{\mft@missing{lineno}} % \end{macrocode} % \end{macro} % % % \subsubsection{Other comment-related macros} % % \begin{macro}{\mfcomment} % One advantage that \MFT's |%| comments have over |%%| comments is that % they format anything that's set between vertical bars as it if it were % \MF\ code. For example, \verb+|draw z1--z2|+ is typeset as % ``$\2{draw}z_{1}\8{--}z_{2}$''. The problem is that the |explaincode| % and |wrapcomment| environments need to be typeset with~|%%|, so their % contents gets passed directly to \LaTeX. To embed \MF\ code within % one of those environments, one need only end the previous line with % |\mfcomment| and put the \MF\ code alone on the next line, preceded by % a~|%|. % \begin{macrocode} \long\def\mfcomment#1\9#2\par{\unskip#2 } % \end{macrocode} % \end{macro} % % % \subsection{Font tables} % % \TeX\ comes with a |testfont.tex| file that, among other things, % outputs a table of all the characters in a given font. This table can % be a useful addition to pretty-printed font documentation. However, % |testfont.tex| is intended to be run stand-alone. The code in this % section produces an identical-looking table to |testfont.tex|'s, but % it can be included easily in a \LaTeX\ document. % The core of |\fontable| was taken almost verbatim from |testfont.tex|. % I made the following key changes, however: % % \begin{itemize} % \item I put everything within a |minipage|, to make it easy to move % the table around and scale its width. % % \item I renamed all the global variables, so as to avoid potential % conflicts with other packages or the main document; % % \item I added argument parsing to set the table width and to limit % the character ranges. % \end{itemize} % % % \subsubsection{Range processing} % % |\fonttable| normally shows only nonempty rows of characters. The % macros in this section impose an additional limit: Only characters % within certain ranges are output; the rest are treated as if they % don't exist. % % \begin{macro}{\mft@ranges} % \begin{macro}{\mft@parse@ranges} % |\mft@parse@ranges| is the top-level range-parsing function. It % splits its argument into comma-separated ranges and uses |\@cons| to % store these ranges in |\mft@ranges| in the form ``|\@elt| % \meta{range${}_1$}|-!-!-!!| |\@elt| \meta{range${}_2$}|-!-!-!!|~\dots''. % (The exclamation marks are needed by |\mft@expand@range| to parse the % range into its components.) % \begin{macrocode} \def\mft@ranges{} \def\mft@parse@ranges#1,{% \def\mft@arg@i{#1}% \ifx\mft@arg@i\empty \else \@cons\mft@ranges{#1-!-!-!!}% \expandafter\mft@parse@ranges \fi } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\mft@expanded@ranges} % \begin{macro}{\mft@gobble@range} % \begin{macro}{\mft@expand@range} % Once |\mft@parse@ranges| has split comma-separated ranges into % elements in |\mft@ranges|, the next step is to canonicalize each % range, to simplify later range processing. That's what % |\mft@expand@range| does. It converts each range in |\mft@ranges| to % the form ``|\@elt| \meta{first}\verb!|!\meta{last}\verb!|!'', in which % neither \meta{first} nor \meta{last} is empty. Canonicalization works % in the following manner: % % \begin{center} % \begin{tabular}{r@{\texttt{-}}^^A % l@{\quad$\mapsto$\quad}^^A % r@{\texttt{\string|}}l@{\texttt{\string|}}} % \meta{first} & \meta{last} & \meta{first} & \meta{last} \\ % \meta{first} & & \meta{first} & |65535| \\ % & \meta{last} & |-1| & \meta{last} \\ % \multicolumn{2}{c@{\quad$\mapsto$\quad}}{\meta{only}} & \meta{only} & \meta{only} \\ % \end{tabular} % \end{center} % % \noindent % The resulting canonicalized list is stored in |\mft@expanded@ranges|. % The |\mft@expand@range| macro expects the input range to terminate % with ``|-!-!-!!|''. This is how it distinguishes missing components % from the end of the range. |\mft@gobble@range| discards any % exclamation marks that remain after processing. % \begin{macrocode} \def\mft@expanded@ranges{} \def\mft@gobble@range#1!!{} \def\mft@expand@range#1-#2-{% \def\mft@arg@i{#1}% \def\mft@arg@ii{#2}% \ifx\mft@arg@i\empty \def\mft@arg@i{-1}% \fi \ifx\mft@arg@ii\empty \def\mft@arg@ii{65535}% \fi \if\mft@arg@ii!% \def\mft@arg@ii{#1}% \fi \if\mft@arg@i!% \else \@cons\mft@expanded@ranges{\mft@arg@i|\mft@arg@ii|}% \fi \mft@gobble@range } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % % \subsubsection{Range checking} % % Once we know the set of ranges to output, we need to determine whether % any characters in the current row lie within any of the ranges % (|\mft@check@char|) and whether a character in a nonempty row lies % within any of the ranges (|\mft@char|). These macros actually belong % within |\fonttable|, but the macro nesting depth was starting to get % too large---I was getting lost amid long sequences of |#|s. % % \begin{macro}{\mft@check@char} % Given an octal digit, form a number by appending it to a sequence % |\mft@h| of octal digits. If the number lies within any of the ranges % listed in |\mft@expanded@ranges|, output the corresponding character. % Otherwise, output nothing. % \begin{macrocode} \def\mft@check@char#1{% \begingroup \def\@elt##1|##2|{% \ifnum"\mft@h#1<##1 \else \ifnum"\mft@h#1>##2 \else \char"\mft@h#1 \fi \fi }% \mft@expanded@ranges \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\mft@char} % If a given number lies within any of the ranges listed in % |\mft@expanded@ranges|, output the corresponding character. % Otherwise, output nothing. % \begin{macrocode} \def\mft@char#1{% \begingroup \def\@elt##1|##2|{% \ifnum#1<##1 \else \ifnum#1>##2 \else \char#1 \fi \fi }% \mft@expanded@ranges \endgroup } % \end{macrocode} % \end{macro} % % % \subsubsection{Table composition} % % Now that we've defined macros to parse |\fonttable|'s optional % argument, to process ranges of character codes, and to check for % numbers within ranges, we can finally proceed with defining % |\fonttable|, the macro that actually composes the font table. % % \begin{macro}{\mft@table@width} % |\mft@table@width| stores the width of the font table. Columns will % expand automatically to fill that width. If the specified width is % negative, |\fonttable| will instead use whatever column width is in % effect when |\fonttable| is invoked. % \begin{macrocode} \newlength{\mft@table@width} \setlength{\mft@table@width}{-1pt} % \end{macrocode} % \end{macro} % % \begin{macro}{\mft@expanded@ranges} % |\mft@expanded@ranges| stores a comma-separated list of hyphenated ranges. % The default is a single range, |0-65535|, which encompasses all character % positions. % \begin{macrocode} \def\mft@expanded@ranges{\@elt 0|65535|} % \end{macrocode} % \end{macro} % % \begin{macro}{\fonttable} % \begin{macro}{\mft@old@ranges} % \begin{macro}{\mft@old@expanded@ranges} % Display all the characters in a given font. The first (optional) % argument is a set of \meta{key}=\meta{value} pairs to specify the % table width and range of characters to output. The second (mandatory) % argument is the ``raw'' name of the font to use, e.g., |cmr10|. % \begin{macrocode} \DeclareRobustCommand{\fonttable}[2][]{% \begingroup \let\mft@old@ranges=\mft@ranges \let\mft@old@expanded@ranges=\mft@expanded@ranges \setkeys{mft}{#1}% \ifdim\mft@table@width<0pt \begin{minipage}{\linewidth}% \else \begin{minipage}{\mft@table@width}% \fi \font\testfont=#2\testfont % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\mft@m} % \begin{macro}{\mft@n} % \begin{macro}{\mft@p} % \begin{macro}{\dim} % The first three of these were called |m|, |n|, and |p| in Knuth's code. % \begin{macrocode} \newcount\mft@m \newcount\mft@n \newcount\mft@p \newdimen\dim % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\oct} % Format an octal constant. % \begin{macrocode} \def\oct##1{\hbox{\rm\'{}\kern-.2em\it##1\/\kern.05em}}% % \end{macrocode} % \end{macro} % \begin{macro}{\hex} % Format a hexadecimal constant. % \begin{macrocode} \def\hex##1{\hbox{\rm\H{}\tt##1}}% % \end{macrocode} % \end{macro} % \begin{macro}{\setdigs} % \begin{macro}{\mft@h} % \begin{macro}{\mft@zero} % \begin{macro}{\mft@one} % |\mft@h| is the hex prefix. |\mft@zero\mft@one| is the corresponding % octal prefix. These were called |\h|, |\0|, and |\1| in Knuth's code. % \begin{macrocode} \def\setdigs##1"##2{\gdef\mft@h{##2}% \mft@m=\mft@n \divide\mft@m by 64 \xdef\mft@zero{\the\mft@m}% \multiply\mft@m by-64 \advance\mft@m by\mft@n \divide\mft@m by 8 \xdef\mft@one{\the\mft@m}}% % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\testrow} % Determine if a row is empty. |\mft@p|=1 if none of the characters % exist. Note that I modified the definition of |\\| to make use of % |\mft@check@char|. % \begin{macrocode} \def\testrow{\setbox0=\hbox{\penalty 1\let\\=\mft@check@char \\0\\1\\2\\3\\4\\5\\6\\7\\8\\9\\A\\B\\C\\D\\E\\F% \global\mft@p=\lastpenalty}} % \mft@p=1 if none of the characters exist % \end{macrocode} % \end{macro} % \begin{macro}{\oddline} % Draw an odd-numbered line. % \begin{macrocode} \def\oddline{\cr \noalign{\nointerlineskip}% \multispan{19}\hrulefill& \setbox0=\hbox{\lower 2.3pt\hbox{\hex{\mft@h x}}}\smash{\box0}\cr \noalign{\nointerlineskip}}% % \end{macrocode} % \end{macro} % \begin{macro}{\ifskipping} % Are we skipping empty rows? % \begin{macrocode} \newif\ifskipping % \end{macrocode} % \end{macro} % \begin{macro}{\evenline} % Draw an even-numbered line. % \begin{macrocode} \def\evenline{\loop\skippingfalse \ifnum\mft@n<256 \mft@m=\mft@n \divide\mft@m 16 \chardef\next=\mft@m \expandafter\setdigs\meaning\next \testrow \ifnum\mft@p=1 \skippingtrue \fi\fi \ifskipping \global\advance\mft@n 16 \repeat \ifnum\mft@n=256 \let\next=\endchart\else\let\next=\morechart\fi \next}% % \end{macrocode} % \end{macro} % \begin{macro}{\morechart} % \begin{macro}{\chartline} % \begin{macro}{\chartstrut} % Define a few more helper routines. % \begin{macrocode} \def\morechart{\cr\noalign{\hrule\penalty5000}% \chartline \oddline \mft@m=\mft@one \advance\mft@m 1 \xdef\mft@one{\the\mft@m}% \chartline \evenline}% \def\chartline{&\oct{\mft@zero\mft@one x}% &&\:&&\:&&\:&&\:&&\:&&\:&&\:&&\:&&}% \def\chartstrut{\lower4.5pt\vbox to14pt{}}% % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\table} % Draw the entire table. In |testfont.tex|, this was one of the % commands that a user would invoke at the \TeX\ prompt. % \begin{macrocode} \def\table{$$\global\mft@n=0 \halign to\hsize\bgroup \chartstrut####\tabskip0pt plus10pt& &\hfil####\hfil&\vrule####\cr \lower6.5pt\null &&&\oct0&&\oct1&&\oct2&&\oct3&&\oct4&&\oct5&&\oct6&&\oct7&\evenline}% % \end{macrocode} % \end{macro} % \begin{macro}{\endchart} % Draw the last line of the table. % \begin{macrocode} \def\endchart{\cr\noalign{\hrule}% \raise11.5pt\null&&&\hex 8&&\hex 9&&\hex A&&\hex B& &\hex C&&\hex D&&\hex E&&\hex F&\cr\egroup$$\par}% \def\:{\setbox0=\hbox{\mft@char\mft@n}% \ifdim\ht0>7.5pt\reposition \else\ifdim\dp0>2.5pt\reposition\fi\fi \box0\global\advance\mft@n 1 }% % \end{macrocode} % \end{macro} % \begin{macro}{\reposition} % \begin{macro}{\centerlargechars} % Define a few more helper routines. % \begin{macrocode} \def\reposition{\setbox0=\vbox{\kern2pt\box0}\dim=\dp0 \advance\dim 2pt \dp0=\dim}% \def\centerlargechars{ \def\reposition{\setbox0=\hbox{$\vcenter{\kern2pt\box0\kern2pt}$}}}% % \end{macrocode} % \end{macro} % \end{macro} % Finally, we compose the table, finish off our |minipage|, and restore % the previous values of |\mft@ranges| and |\mft@expanded@ranges| (which % we had to save at the top of |\fonttable|, because |\@cons| contains % an |\xdef|). This concludes the definition of |\fonttable|. % \begin{macrocode} \table \end{minipage}% \global\let\mft@ranges=\mft@old@ranges \global\let\mft@expanded@ranges=\mft@old@expanded@ranges \endgroup } % \end{macrocode} % % \Finale \endinput