%^^A* legal notices % \iffalse % % This program is part of the Frankenstein bundle for LaTeX. % % Copyright 1995-2001 Matt Swift . % % This file contains both the code and documentation for the % titles LaTeX package. It will work ONLY if it is placed in a % proper directory. Files called README, INSTALL, titles.tex % and titles.ins should have also been distributed to you % with this file. See them for more information on how to typeset % the documentation with LaTeX and how to generate a version of this % file that will work faster than this one. % % This program is free software; you may redistribute it and/or % modify it under the conditions of the LaTeX Project Public % License, either version 1.2 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. % % This program 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 % LaTeX Project Public License for more details. % % \fi % %^^A* checks % %^^A NOTE: The character table, with two %'s, will get written to all files. %% \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 \~} % % \CheckSum{783} % %^^A** abstract % \begin{abstract} % The \package{titles} package defines macros that typeset the titles of % books, journals, etc. and handle following spacing and punctuation % intelligently, based on context. These are useful for bibliographic % databases, for example. Also defined is other markup like \cs\word, % \cs\defn, \cs\phrase, etc. % \end{abstract} % \tableofcontents % % \part{Discussion} % % \section{Options} % % There are two package options, \option{british} and \option{american}, the default % is \option{american}. They select the conventional way to use quotation marks: % British style is use single quotes, and do not suck following period or comma % inside; American style is to use double quotes and to suck following period % or comma inside. % % \section{Words and phrases} % % \DescribeMacro\word % Typeset a word or phrase referred to as a noun with \cs\word\marg{word}. % The argument is not expected to contain punctuation. % % \begin{bothexample} % \word{Elephant} is such a silly word. % \end{bothexample} % % \DescribeMacro\phrase % Typeset a phrase used as a noun rather than direct quotation with % \cs\phrase\marg{phrase}. The argument might well have punctuation, % including final punctuation, which should not be considered to be % punctuation of the containing sentence. % % \begin{bothexample} % The sentence \phrase{And stop calling me Shirley!} occurs % twenty-seven times. % \end{bothexample} % % \DescribeMacro{\foreign} % Typeset a foreign word or phrase with \cs\foreign\marg{foreign text}. % % \begin{bothexample} % I couldn't think of the \foreign{mot juste} at the time. % \end{bothexample} % % \DescribeMacro{\foreignword} % Typeset a foreign word or phrase referred to as a noun with % \cs\foreignword\marg{foreign word}. % % \begin{bothexample} % Only later did I realize that the right word was % \foreignword{bouffon}. % \end{bothexample} % % \caveat {Notice that writing \code{\foreign{\word{text}}} or vice versa is % not necessarily going to do the right thing. Suppose \cs\foreign and % \cs\word were both set to \cs\textitswitch (which are in fact the default % settings below). Then \code{\foreign{\word{text}}} is going to cancel out % and look just like the surrounding text. This is not the most intuitive % fact, but it's not worth it to try to make \cs\foreign and \cs\word smart % enough to see each other inside themselves.} % % \DescribeMacro{\term} % \cs\term\marg{technical term} typesets a techincal term in a different % font. You might want to use this where a techincal term is first used, or % defined. One could enhance this macro and \cs\defn to help build an % automatic glossary % % \begin{bothexample} % This sort of thing is called a \term{blibnil}. % \end{bothexample} % % \DescribeMacro{\defn} % \cs\defn\marg{definition} typesets a definition, perhaps of a technical % term. One could enhance this macro and \cs\defn to help build an automatic % glossary % % \begin{bothexample} % We may describe a \term{blibnil} as \defn{a slibnil with % three arms}. % \end{bothexample} % % \section{Titles} % % \DescribeMacro\book % \cs\book\marg{book title} typesets a book title. % % \begin{bothexample} % Some people find \book{Moby-Dick} dull, but I thought % it was exciting. % \end{bothexample} % % \DescribeMacro\journal % \cs\journal\marg{journal title} typesets a journal title. % % \begin{bothexample} % I liked it so much I started a scholarly journal called % \journal{The Melville Times} with the inheritance from % my grandmother. % \end{bothexample} % % \DescribeMacro\music % \cs\music\marg{music title} typesets a music title. % % \begin{bothexample} % My journal didn't do very well; I moped around my office % and listened to Schubert's \music{Winterreise}. % \end{bothexample} % % \DescribeMacro\article % \cs\article\marg{article title} typesets a article title. % % \begin{bothexample} % Then one day I received an article, \article{Pip and % the Milk of Human Kindness}, by express mail from Wales. % \end{bothexample} % % \DescribeMacro\poemtitle % \cs\poemtitle\marg{poem title} typesets a poem title. % % \begin{bothexample} % I then wrote my famous poem \poemtitle{Jump for Joy like % the Butterflies of Troy} in five minutes. % \end{bothexample} % % Sometimes longer poems are distinguished from shorter ones in type when % they have been published separately as a book [FIX give reference]. This % package defines a macro \cs\longpoem in the configuration file in the % following way: % \begin{codeexample} % \newlet\longpoem\textitswitch % \end{codeexample} % % \DescribeMacro\play % \cs\play\marg{play title} typesets a play title. % % \begin{bothexample} % To celebrate the popularity of the article, I took the % author to the theater to see the acclaimed play % \play{Grave in Waterloo}, starring Vincent Price. % \end{bothexample} % % \DescribeMacro\craft % \cs\craft\marg{craft title} typesets a title of a craft or ship. % % \begin{bothexample} % With tears in my heart, I put the author on the \craft{HMS Shangrila} % bound for Wales. % \end{bothexample} % % \DescribeMacro\species % \cs\species\marg{[ genus ] species [ subspecies ]} typesets the Latin % generic and/or specific names for an organism. % % \begin{lesson} % \manual specifies italic type. Genus names should be capitalized, and % may be abbreviated on subsequent appearances with the initial letter. % Following designations should be in roman. E.g., ``var.''\ for % ``variant'' following species name and ``sp.''\ for ``species'' following % genus name, meaning ``any species in the genus.'' \attrib{7.102--4} % % Higher groupings should be in capitalized roman. English derivatives of % scientific names, e.g., amoeba, are lowercased. \attrib{7.105--6} % % \todo{\package{abbrevs} % category for genus/species and/or datemark for suffixes} % \end{lesson} % % \begin{warning} % Right now there is a small discrepancy between the behavior of % \cs\textitswitch and \cs\Wrapquotes regarding what happens when followed by % a command sequence such as \cs\footnote. I hope to make these things % completely parallel one day, but for now, realize that after using a % titling macro that uses \cs\Wrapquotes, you must use |{}| before any % following command sequence that you want to immediately follow the title % with no intervening space. The only case I can think of is \cs\footnote. % If you forget the |{}|, you will have an extra space after the title and before the % footnotemark. The following example illustrates this behavior and % contrasts it with \cs\textitswitch: % \begin{bothexample} % \newabbrev\foo{Foo} % % \book{Foo}\foo % % \book{Foo} \foo % % \book{Foo}\footnote{footie} % % \book{Foo}{}\footnote{footie} % % \poemtitle{Foo}\foo % % \poemtitle{Foo} \foo % % \poemtitle{Foo}\footnote{footie} % % \poemtitle{Foo}{}\footnote{footie} % % \poemtitle{Foo}.\footnote{footie} % \end{bothexample} % \end{warning} % % \section{Programmer's interface} % % \DescribeMacro\Wrapquotes % \DescribeMacro\WrapquotesNS % \DescribeMacro\WrapquotesIS % \DescribeMacro\WrapquotesNN % \DescribeMacro\WrapquotesIN % \DescribeMacro\WrapquotesSN % \DescribeMacro\WrapquotesDN % \DescribeMacro\WrapquotesSK % \cs\Wrapquotes\marg{text} wraps \meta{text} in quotes. Single quotes are % used initially if the \option{singlequotes} option is given to the % package, and double quotes if no option or the \option{doublequotes} % option is given to the package. % % When quotation marks inserted by \cs\Wrapquotes and friends are doubled up % (this occurs sometimes when nesting them), a thinspace (|\,|) is inserted % between the abutted quotes. % % \cs\Wrapquotes will be \cs\let to one of the six macros % \cs\Wrapquotes\meta{XY}. % % In the two-letter suffix \meta{XY}, first letter |N| means ``normal'' and % |I| means ``inverse.'' These are macros that switch between single and % double quotes when they nest: an inverse wrapquotes wraps with single % quotes when a normal wrapquotes would wrap with double quotes, and vice % versa. First letter |S| for ``single'' and |D| for ``double'' are for % macros that always wrap with single or double quotes. Spacing and % punctuation following the closing quotes are handled intelligently by % macros with second letter |S|, which means means suck a following period % or comma into the closing quote, that is, if what follows is a comma or % period, it is pulled inside the quotes (following American practice). % Second letter |N| means ``nosuck,'' that is, don't suck. Second letter % |K| means ``kill'': the same as |N| but suppress the effect of any % punctuation in the quoted argument on spacing that follows the closing % quotes (i.e., execute \cs\@, which sets the spacefactor to~1000). This is % only useful in certain technical writing where punctuation in the quoted % argument should not be considered puncutation of the containing sentence. % % A space is inserted after the closing quotes unless what follows is in the % set |;?:!-)]'\textquoteright{|, in which case no space is inserted.^^A for Emacs: } % FIX: that would be |\nospacelist| % % \DescribeMacro\IfQuestionOrExclamation % \cs\IfQuestionOrExclamation\marg{text}\marg{true}\marg{false} % executes \meta{true} clause iff \meta{text} ends with a question mark or % an exclamation point; executes \meta{false} clause otherwise. % % \subsection{Limitations of Wrapquotes and friends} % ^^A FIX: hmm, can't use \cs or \protect\cs % \subsubsection{Nesting} % \begin{warning} % For proper nesting of \cs\Wrapquotes and friends, user commands must be % \cs\let to \cs\Wrapquotes or one of the six \cs\Wrapquotes\meta{XY} % commands instead of using a \cs\def-like defining command. It's OK to % \cs\let % a user macro to something like \cs\Wrapquotes which itself % has been % \cs\let to one of the six \cs\Wrapquotes\meta{XY} macros. % % The user command which is \cs\let to one of the \cs\Wrapquotes commands % must furthermore appear in the source. That is, it must not appear as % the result of an expansion. Among other things, this means that % nesting won't work properly if you put \cs\Wrapquotes into an abbrev % (see the \package{abbrevs} package in the \Frankenstein bundle). % % For applications where nesting will not occur, there should be nothing % to worry about. % \end{warning} % % \subsubsection{Italic corrections} % % \begin{warning} % The question of when to insert an italic correction is not nearly as % simple as it might seem. I cannot figure good rules which cover all % cases, and I do not trust the behavior of the kernel's macros as a % guide. So I can not tell you whether this package handles italic % corrections properly. If you discover behavior which you think is % wrong, please let me know with an example and an argument. % \end{warning} % % \subsubsection{A slight bug} % \begin{warning} % Right now there is a small bug in cases where closing quotes fall at % the end of italic text, such as % \begin{bothexample} % \normalfont % \book{My love of \poemtitle{Daffodils}}, by H.~Moneysworth. % \end{bothexample} % These cases loose because the closing quotation marks and any % sucked-in punctuation are going to be in roman, not italic, or italic, % not roman. Only the more obsessive will notice this flaw. I'm sure I % will come up with a way to handle this for a future version of this % package. % \end{warning} % % \StopEventually{} % % \part{Implementation} % % \section{Version control} % % \begin{macro}{\fileinfo} % \begin{macro}{\DoXUsepackagE} % \begin{macro}{\HaveECitationS} % \begin{macro}{\fileversion} % \begin{macro}{\filedate} % \begin{macro}{\docdate} % \begin{macro}{\PPOptArg} % These definitions must be the first ones in the file. % \begin{macrocode} \def\fileinfo{title macros (Frankenstein's references)} \def\DoXPackageS {} \def\initelyHavECitationS {} \def\fileversion{v1.2} \def\filedate{2001/08/31} \def\docdate{2001/08/31} \edef\PPOptArg {% \filedate\space \fileversion\space \fileinfo } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % If we're loading this file from a \cs\ProcessDTXFile command (see the % \package{compsci} package), then \cs\JusTLoaDInformatioN will be defined; % othewise we assume it is not (that's why the FunkY NamE). % % If we're loading from \cs\ProcessDTXFile, we want to load the packages listed % in \cs\DoXPackageS (needed to typeset the documentation for this file) and % then bail out. Otherwise, we're using this file in a normal way as a % package, so do nothing. \cs\DoXPackageS, if there are any, are declared in % the \ext{dtx} file, and, if you're reading the typeset documentation of this % package, would appear just above. (It's OK to call \cs\usepackage with an % empty argument or \cs\relax, by the way.) % \begin{macrocode} \makeatletter% A special comment to help create bst files. Don't change! \@ifundefined{JusTLoaDInformatioN} {% }{% ELSE (we know the compsci package is already loaded, too) \UndefineCS\JusTLoaDInformatioN \SaveDoXVarS \eExpand\csname DoXPackageS\endcsname\In {%use \csname in case it's undefined \usepackage{#1}% }% \RestoreDoXVarS \makeatother \endinput }% A special comment to help create bst files. Don't change! % \end{macrocode} % % Now we check for \LaTeX2e and declare the LaTeX package. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{titles}[\PPOptArg] % \end{macrocode}^^A special comment to help create bst files. Don't change! % % ^^A NOTE: We have to compensate for the above backslashes, which are not % ^^A actually in the .dtx file the author works on, by adding to the % ^^A CheckSum. %% % \AddToCheckSum{17}^^A `dtx-update-checksum' automatically handles this. % \AddToCheckSum{7}^^A The half a macrocode env. at the top is missed, however... % \AddToCheckSum{10}^^A ... and so are the 5 \defs from the .dtx file % ^^A that precede it. % \IfCitations {% % \AddToCheckSum{2}^^A When \initelyHavECitationS is defined in % } ^^A the .dtx file, we need 2 more in the CheckSum. % % % \section{Requirements} % % \begin{macrocode} \RequirePackage{moredefs,slemph} % \end{macrocode} % % \section{Options} % % \begin{macro}{\ti@domelater} % \begin{macrocode} \ReserveCS\ti@domelater \DeclareOption{british} {% \def\ti@domelater {% \let\Wrapquotes\WrapquotesNN \@doublequotes@false } } \DeclareOption{american} {% \def\ti@domelater {% \let\Wrapquotes\WrapquotesNS \@doublequotes@true } } \ExecuteOptions{american} \ProcessOptions % \end{macrocode} % \end{macro} % % \section{Wrapquotes} % % Here we go! This is not a picnic, so leave your jelly jar home. % % \subsection{Titles that are Questions or Exclamations} % % \begin{macro}{\IfQuestionOrExclamation} % \begin{macro}{\ti@checkfor@q} % \begin{macro}{\ti@checkfor@e} % \begin{macro}{\ti@prev} % \begin{macro}{\ti@prev@prev} % \begin{macro}{\@ti@sw@true} % \begin{macro}{\@ti@sw@false} % \begin{macro}{\if@ti@sw@} % \mbox{} % \begin{macrocode} \newcommand\IfQuestionOrExclamation [1] {% \@tempswafalse \ti@checkfor@q #1?\@nil \ti@checkfor@e #1!\@nil \if@tempswa \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} % The large majority of titles will not contain a question mark or exclamation % point. The large majority of those that do will have a single mark or point % at the end. We could (I think) use a simpler check that processed all titles % by looping through to examine the end, but a slightly more complicated check % will handle the majority of cases very quickly (and at a constant speed, % rather than proportional to title length) and not greatly slow down % processing the remaining two unusual cases. We divide our argument (with an % extra question mark tacked onto the end) into what's before the first % question mark and what's after it. Then we examine what's after it and % interpret the results thus: % \begin{description} % \item [empty] no question mark in title % \item [question mark] title ends with question mark (and there are no other % question marks) % \item [text ending with one question mark] a question mark occurs in the % title, but not at the end % \item [text ending with two question marks] title ends with a question mark % (and there is a previous question mark) % \end{description} % We set switch |a| to true if the title ends with a question mark. % \begin{macrocode} \newboolean{@ti@sw@} \ReserveCS\ti@prev \ReserveCS\ti@prev@prev \NewName{ti@checkfor@q} {#1?#2\@nil} {% \def\sc@t@a{#2}% \def\sc@t@b{?}% \ifx\sc@t@a\ShortEmpty \else \ifx\sc@t@a\sc@t@b \@tempswatrue \else % \end{macrocode} % We use a loop to whittle down |#2| until \cname{ti@prev} contains the last % character and \cname{ti@prev@prev} contains the second-to-last. We know that % \cname{ti@prev} is going to be a question mark. Iff \cname{ti@prev@prev} is a % question mark, we are in the final case above. % \begin{macrocode} \let\ti@prev\sc@t@a \let\ti@prev@prev\sc@t@a \@ti@sw@true \@whilesw \if@ti@sw@ \fi {% \ifx\sc@t@a\ShortEmpty \@ti@sw@false \else \let\ti@prev@prev\ti@prev \let\ti@prev\sc@t@a \edef\sc@t@a{\E@cdr\sc@t@a\@nil}% \fi }% \edef\ti@prev@prev{\E@car\ti@prev@prev\@nil}% \ifx\ti@prev@prev\sc@t@b \@tempswatrue \fi \fi \fi } % \end{macrocode} % Exact same logic applies to exclamation points. % \begin{macrocode} \NewName{ti@checkfor@e} {#1!#2\@nil} {% \def\sc@t@a{#2}% \def\sc@t@b{!}% \ifx\sc@t@a\ShortEmpty \else \ifx\sc@t@a\sc@t@b \@tempswatrue \else \let\ti@prev\sc@t@a \let\ti@prev@prev\sc@t@a \@ti@sw@true \@whilesw \if@ti@sw@ \fi {% \ifx\sc@t@a\ShortEmpty \@ti@sw@false \else \let\ti@prev@prev\ti@prev \let\ti@prev\sc@t@a \edef\sc@t@a{\E@cdr\sc@t@a\@nil}% \fi }% \edef\ti@prev@prev{\E@car\ti@prev@prev\@nil}% \ifx\ti@prev@prev\sc@t@b \@tempswatrue \fi \fi \fi } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \subsection{Highlevel macros} % % \begin{macro}{\ti@wrapquotes@suck} % \begin{macro}{\ti@wrapquotes@nosuck} % These two are the top-level internal macros, and they are pretty sane. One % sucks in a following period or comma, the other does not. % \cname{ti@wrapquotes@suck} does not suck, however, when the title ends in a % question or exclamation point. % % The group here is necessary to scope the \cname{@doublequotes@} boolean. % \begin{macrocode} \newcommand*\ti@wrapquotes@suck [1] {% % \DTypeout{top of wrapquotes@suck}% \IfQuestionOrExclamation {#1} {% \ti@wrapquotes@nosuck{#1}% }{% ELSE % \DTypeout{top of wrapquotes@suck ELSE}% \begingroup \if@doublequotes@ % \DTypeout{double true in suck}% \@doublequotes@false \def\sc@t@a {\ti@open@double #1\ti@close@double@suck}% \else % \DTypeout{double false in suck}% \@doublequotes@true \def\sc@t@a {\ti@open@single #1\ti@close@single@suck}% \fi \sc@t@a \endgroup }% } \newcommand*\ti@wrapquotes@nosuck [1] {% \begingroup \if@doublequotes@ % \DTypeout{double true in nosuck}% \@doublequotes@false \def\sc@t@a {\ti@open@double #1\ti@close@double@nosuck}% \else % \DTypeout{double false in nosuck}% \@doublequotes@true \def\sc@t@a {\ti@open@single #1\ti@close@single@nosuck}% \fi \sc@t@a \endgroup } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\WrapquotesNS} % \begin{macro}{\WrapquotesIS} % \begin{macro}{\WrapquotesNN} % \begin{macro}{\WrapquotesIN} % \begin{macro}{\WrapquotesSN} % \begin{macro}{\WrapquotesDN} % \begin{macro}{\WrapquotesSK} % \begin{macro}{\Wrapquotes} % \begin{macro}{\if@doublequotes@} % \begin{macro}{\@doublequotes@true} % \begin{macro}{\@doublequotes@false} % Now we can define the secondary programmers' macros. % % We simply reserve \cs\Wrapquotes here, and assign it in the user options % section above. % \begin{macrocode} \newboolean{@doublequotes@} \newcommand*\WrapquotesNS {% % \DTypeout{starting wrapquotes NS}% \ti@wrapquotes@suck } \newcommand*\WrapquotesIS {% % \DTypeout{starting wrapquotes IS}% \ToggleBoolean{@doublequotes@}% \ti@wrapquotes@suck } \newcommand*\WrapquotesNN {% % \DTypeout{starting wrapquotes NN}% \ti@wrapquotes@nosuck } \newcommand*\WrapquotesIN {% % \DTypeout{starting wrapquotes IN}% \ToggleBoolean{@doublequotes@}% \ti@wrapquotes@nosuck } \newcommand*\WrapquotesSN [1] {% % \DTypeout{starting wrapquotes SN}% \begingroup \ti@open@single #1\ti@close@single@nosuck \endgroup } \newcommand*\WrapquotesDN [1] {% % \DTypeout{starting wrapquotes DN}% \begingroup \ti@open@double #1\ti@close@double@nosuck \endgroup } \newcommand*\WrapquotesSK [1] {% FIX: test % \DTypeout{starting wrapquotes SK}% \begingroup \ti@open@single #1\ti@close@single@nosuck\@% \endgroup } \ReserveCS\Wrapquotes \ti@domelater % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \subsection{Opening quotes} % % \begin{macro}{\ti@open@double} % \begin{macro}{\ti@open@single} % \begin{macro}{\ti@openquote} % We start by putting an opening mark in scratch |f| with a global % definition. % % I can't remember why it's global. In the macros that close quotes, we want % to keep that information around past a group end because we're using % \cs\aftergroup, but that doesn't seem to apply for opening them. Best not % to change what's not broke, however. % \begin{macrocode} \newcommand\ti@open@double {% \gdef\sc@t@f {\textquotedblleft}% \ti@openquote } \newcommand\ti@open@single {% \gdef\sc@t@f {\textquoteleft}% \ti@openquote } % \end{macrocode} % Then we look ahead with scratch |a|. We are looking ahead at the first % character of the contents of the \cs\Wrapquotes. % \begin{macrocode} \newcommand\ti@openquote {% \futurelet\sc@t@a\ti@@openquote } % \end{macrocode} % Insert the opening mark. Then, if we are about to open another quote, insert % the space appropriate to separate contiguous quotation marks. % \begin{macrocode} \newcommand\ti@@openquote {% \sc@t@f \ifx\sc@t@a\WrapquotesNS % \DTypeout{Quotation marks are doubled up (next is NS); inserting padding.}% \,% \else \ifx\sc@t@a\WrapquotesNN % \DTypeout{Quotation marks are doubled up (next is NN); inserting padding.}% \,% \else \ifx\sc@t@a\WrapquotesIN % \DTypeout{Quotation marks are doubled up (next is IN); inserting padding.}% \,% \else \ifx\sc@t@a\WrapquotesIS % \DTypeout{Quotation marks are doubled up (next is IS); inserting padding.}% \,% \else \ifx\sc@t@a\WrapquotesSN % \DTypeout{Quotation marks are doubled up (next is SN); inserting padding.}% \,% \else \ifx\sc@t@a\WrapquotesDN % \DTypeout{Quotation marks are doubled up (next is DN); inserting padding.}% \,% \else \ifx\sc@t@a\WrapquotesSK % \DTypeout{Quotation marks are doubled up (next is SK); inserting padding.}% \,% \else \fi \fi \fi \fi \fi \fi \fi } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \subsection{Closing macros that don't suck} % % This case that doesn't suck is easier, so we warm up with it. % % \begin{macro}{\ti@close@single@nosuck} % \begin{macro}{\ti@close@double@nosuck} % \begin{macro}{\ti@close@single@@nosuck} % \begin{macro}{\ti@close@double@@nosuck} % \mbox{} % \begin{macrocode} \newcommand*\ti@close@single@nosuck {% \aftergroup\ti@close@single@@nosuck } \newcommand*\ti@close@double@nosuck {% \aftergroup\ti@close@double@@nosuck } \newcommand*\ti@close@single@@nosuck {% \gdef\sc@t@f {\textquoteright}% \ti@close@quote@nosuck } \newcommand*\ti@close@double@@nosuck {% \gdef\sc@t@f {\textquotedblright}% \ti@close@quote@nosuck } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\ti@close@quote@nosuck} % \begin{macro}{\if@look@nosuck@} % \begin{macro}{\@look@nosuck@true} % \begin{macro}{\@look@nosuck@false} % \todo{Document this flag. It's a hack, we must set it before each call % to \cname{ti@q@ifnextcharin} I think. What it stands for is something % like the presence of the tokens \cname{ti@close@single@nosuck} and % \cname{ti@close@double@nosuck} in the list of chars to look for, but since % they aren't really chars they can't go in the list, so instead we set the % flag. Somewhat cleaner would be putting a flag char in the list, but I % can't think of what char I could safely use.} % \begin{macrocode} \newboolean{@look@nosuck@} \@look@nosuck@false \newcommand\ti@close@quote@nosuck {% % \DTypeout{Starting ti@close@quote@nosuck}% \@look@nosuck@true % \end{macrocode} %% FIX % Aha, but here is a good reason to leave in |.,| in our substitute for \cs\nospacelist. % \begin{macrocode} \expandafter \ti@q@ifnextcharin \expandafter {\nospacelist} {% % \DTypeout{Found a nosuck no-spacer. C=[\meaning\sc@t@c] F=[\meaning\sc@t@f]}% \sc@t@f }{% ELSE % \DTypeout{Found a nosuck spacer. C=[\meaning\sc@t@c] F=[\meaning\sc@t@f]}% \sc@t@f\space }% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \subsection{Closing macros that suck} % % \begin{macro}{\ti@close@double@suck} % \begin{macro}{\ti@close@single@suck} % We need to look ahead beyond the \cs\endgroup that ends % \cname{Wrapquotes??}. The lookahead mechanism that gets invoked in scratch % |a| below could handle looking past the \cs\endgroup, but I think it is % more efficient to skip it by using \cs\aftergroup. % \begin{macrocode} \newcommand\ti@close@double@suck {% \aftergroup\ti@close@double@@suck } \newcommand\ti@close@single@suck {% \aftergroup\ti@close@single@@suck } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ti@close@double@@suck} % \begin{macro}{\ti@close@single@@suck} % This part isn't so bad yet. To close the quotes, we again start with the % closing mark in scratch |f|, with a global definition. % \begin{macrocode} \newcommand\ti@close@double@@suck {% \gdef\sc@t@f {\textquotedblright}% \ti@close@quote@suck } \newcommand\ti@close@single@@suck {% \gdef\sc@t@f {\textquoteright}% \ti@close@quote@suck } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\nospacelist} % Put these in the order of their frequency. Anything in \cs\nocorrlist % should also be in here, most likely. I'm putting in \cname{@xobeysp} % because it's in the \package{xspace} package, but I can't tell you when it % would come up. % \begin{macrocode} \requirecommand\nospacelist {% ,.':;?-/\slash~!)]\bgroup\egroup\@sptoken\ \space\/\@xobeysp } % \end{macrocode} % \end{macro} % % \begin{macro}{\ti@close@quote@suck} % Then we use \cname{ti@q@ifnextcharin} to look as far ahead as necessary for % a significant character. The latest significant character found is % available in scratch |c|. The work of handling all the cases of what we % might find while looking ahead is divided up between % \cname{ti@close@quote@suck} and \cname{ti@q@ifnextcharin}. % \cname{ti@close@quote@suck} handles the last step in the process, and % \cname{ti@q@ifnextcharin} handles all the steps up to the last. % % Here is what \cname{ti@close@quote@suck} does, in English. If we find a % comma or period, we put it inside the closing quote, and gobble the one we % found. That is, we print out scratch |c|, then scratch |f|, then gobble a % character. If we find something in the set given in \cs\nospacelist, do % not leave a space after the closing mark. That is, just print out scratch % |f|. If we find something else, we leave a space after the closing mark. % That is, print scratch |f| and a space. % \begin{macrocode} \newcommand\ti@close@quote@suck {% % \DTypeout{Starting ti@close@quote@suck}% \@look@nosuck@false \ti@q@ifnextcharin {.,} {% % \DTypeout{Found a comma or period. C=[\meaning\sc@t@c] F=[\meaning\sc@t@f]}% \sc@t@c\sc@t@f\DGobbleM % This gobbles the original punctuation. }{% ELSE % \DTypeout {Before second ti@qifnextcharin. C=[\meaning\sc@t@c] F=[\meaning\sc@t@f]}% \@look@nosuck@true % \end{macrocode} % \begin{todoenv} % Using \cs\nospacelist is inefficient here, since some of the cases, %^^A for Emacs { % namely \verb*|,.\@sptoken}|, are never going to be there and shouldn't be % checked for, since they are passed over by \cname{ti@q@ifnextcharin} before % the list is compared. But it would be good to have this parallelism between % \package{abbrevs} and \package{titles}. % \end{todoenv} % \begin{macrocode} \expandafter \ti@q@ifnextcharin \expandafter {\nospacelist} {% % \DTypeout{Found a suck no-spacer. C=[\meaning\sc@t@c] F=[\meaning\sc@t@f]}% \sc@t@f }{% ELSE % \DTypeout{Found a suck spacer. C=[\meaning\sc@t@c] F=[\meaning\sc@t@f]}% \sc@t@f\space }% }% } % \end{macrocode} % \end{macro} % % \subsection{Looking ahead} % % Now things are getting fun. % % \begin{macro}{\ti@q@ifnextcharin} % \begin{macro}{\ti@q@check} % \begin{macro}{\ti@q@ifnch} % \begin{macro}{\ti@q@@ifnch} % These macros are modeled after the definition of \cname{@ifnextchar} which % skips spaces. While looking ahead for the next significant character, % these macros skip spaces, \cs\egroup, \cs\endgroup, \cname{check@icr}, % \cname{ti@close@double} and \cname{ti@close@single} while doing the right % thing after each. % % The first argument should be a list of tokens. If the next significant % char is in the list, then the |true| clause is executed, otherwise the % |false| clause is executed. The next significant char is left in scratch % |c| so it can be accessed by the clauses. % % The three arguments to \cname{ti@q@ifnextcharin} are saved in global % variables because while looking ahead we must continue past the ends of % groups. % %% FIX % Not sure I need gdef for scratch |e|. % \begin{macrocode} \newcommand\ti@q@ifnextcharin [3] {% args: charlist true false % \sc@toks@a{#1}% % \DTypeout{charlist unexpanded is =[\the\sc@toks@a]}% \gdef\sc@t@e {#1}% \gdef\sc@t@a {#2}% \gdef\sc@t@b {#3}% \ti@q@check } % \end{macrocode} % Having saved the arguments, we look ahead with scratch |c|. This step is not % in the macro above so that we can jump back to \cname{ti@q@check} whenever we % want to look ahead another character. % \begin{macrocode} \newcommand\ti@q@check {% \futurelet\sc@t@c\ti@q@ifnch } % \end{macrocode} % Scratch |c| contains the current char. Scratch |d| is the action to take at % the end of this macro. We attempt to order these possibilities to make % \cs\Wrapquotes most efficient, though it is a guess which items will be % encountered most frequently. % % The actions taken for each of the possibilities are the following: % \begin{description} % \item[\cs\ifvmode] Assume that the \cs\Wrapquotes was the argument of a % \cs\TextFontCommand from certain \LaTeX{} kernels. Gobble three more tokens % expected to follow the \cs\ifvmode, execute them, and continue on to look % ahead another character. See documentation of % \cname{ti@q@handle@ifvmode} for more details. % \item[\cname{check@icr}] This means the \cs\Wrapquotes was the % argument of a \cs\TextFontCommand. Gobble the \cname{check@icr} % and look ahead another character after we exit the % group that the \cs\TextFontCommand has given us. % \item[\cs\endgroup and {\normalfont\ttfamily \}}] Pass right by an \cs\endgroup or % |}| and look ahead another char. % \item[\cname{@sptoken} (a non-explicit space)] Handle a non-explicit space by calling % \cname{ti@q@handle@space}, which gobbles the space and looks ahead % another char. When the user or a macro has followed the titles with an % \emph{explicit} space such as a tie, or the %% \verb*|\ | % or \cs\space macros, we do nothing and let this be caught by the % comparison to the tokens in the argument of \cname{ti@q@ifnextcharin}. % \item[\cname{ti@close@double@suck}, % \cname{ti@close@single@suck}] % \item[\cname{ti@close@double@nosuck}, and % \cname{ti@close@single@nosuck}] We are in a nested % \cs\Wrapquotes. Call \cname{ti@q@handle@single/double@suck/nosuck} % as appropriate, which % gobbles the closequotes token, adds properly-padded closing quotes to % scratch |f|, and then goes on to look ahead another character. % \end{description} % The lookahead process stops when it finds something not on this list. Then % it compares what it found to the list of characters given to % \cname{ti@q@ifnextcharin} and executes the |true| or |false| clause as % appropriate. % % First we have to handle the case of finding an \cs\ifvmode. We can't bundle % this test in with the tests for other tokens, so it gets its own macro, % \cname{ti@q@handle@ifvmode}, which see for details. The remaining cases are % handled in \cname{ti@q@@ifnch}. % \begin{macrocode} \newcommand\ti@q@ifnch {% % \DTypeout{The lookahead in ti@q@ifnch: [\meaning\sc@t@c]}% \ifx\sc@t@c\ifvmode \let\sc@t@d\ti@q@handle@ifvmode \else \let\sc@t@d\ti@q@@ifnch \fi \sc@t@d } \newcommand\ti@q@@ifnch {% % \DTypeout{entering ti@q@@ifnch}% % \expandafter\sc@toks@a\expandafter{\sc@t@c}% % \DTypeout{ti@q@@ifnch: C expanded once is =[\the\sc@toks@a]}% \ifx\sc@t@c\check@icr % \DTypeout{Handling check@icr}% \defcommand\sc@t@d [1] {% % \DTypeout{check@icr handler: gobbling [\meaning ##1]}% ##1\aftergroup\ti@q@check }% \else \ifx\sc@t@c\endgroup % \DTypeout{Handling endgroup}% \def\sc@t@d {\aftergroup\ti@q@check}% \else \ifx\sc@t@c\@sptoken % \DTypeout{Handling space}% \let\sc@t@d\ti@q@handle@space \else \ifx\sc@t@c\egroup % \DTypeout{Handling egroup}% \def\sc@t@d {\aftergroup\ti@q@check}% \else \ifx\sc@t@c\ti@close@double@suck % \DTypeout{Handling ti@close@double@suck}% \let\sc@t@d\ti@q@handle@double@suck \else \ifx\sc@t@c\ti@close@single@suck % \DTypeout{Handling ti@close@single@suck}% \let\sc@t@d\ti@q@handle@single@suck \else \ifx\sc@t@c\ti@close@double@nosuck % \DTypeout{Handling ti@close@double@nosuck}% \let\sc@t@d\ti@q@handle@double@nosuck \else \ifx\sc@t@c\ti@close@single@nosuck % \DTypeout{Handling ti@close@single@nosuck}% \let\sc@t@d\ti@q@handle@single@nosuck \else % \end{macrocode} % We've handled all the lookahead cases, so now we are left with the simple % comparison of the next char with the charlist. % \begin{macrocode} \@tempswafalse \expandafter \@tfor \expandafter \sc@t@g \expandafter :% \expandafter =% \sc@t@e \do {% \expandafter\ifx\sc@t@g\sc@t@c % \DTypeout{We have a match of [\meaning\sc@t@c] % with [\expandafter\meaning\sc@t@g]}% \@tempswatrue \@break@tfor \else % \DTypeout{We have NO match between [\meaning\sc@t@c] % with [\meaning\sc@t@g]}% \fi }% \if@tempswa % \DTypeout{Choosing true clause [\meaning\sc@t@a]}% \let\sc@t@d\sc@t@a % the ``true'' clause \else % \DTypeout{Choosing false clause [\meaning\sc@t@b]}% \let\sc@t@d\sc@t@b % the ``false'' clause \fi \fi \fi \fi \fi \fi \fi \fi \fi % \DTypeout{About to fall out of ti@q@@ifnch and do this [\meaning\sc@t@d]}% \sc@t@d } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\ti@q@handle@ifvmode} % This is in its own macro for clarity and to avoid problems with skipping % over clauses. % % \cname{ti@q@ifnch} has to take two different kinds of \LaTeX{} kernel into % account. The 1996/12/01 and 1997/06/01 kernels used a different definition % of \cs\DeclareTextFontCommand: % \begin{macrocode} %\def \DeclareTextFontCommand #1#2{% % \DeclareRobustCommand#1[1] {% % \ifmmode % \nfss@text{#2##1}% % \else % \leavevmode % {\text@command{##1}% % #2\check@icl ##1\ifvmode\else\check@icr\fi % \expandafter}% % \fi % }% %} % \end{macrocode} % All other kernels leave out the check for vertical mode (kernels from % 1997/12/01 include it when necessary inside \cname{check@icr}). The macro % \cname{ti@q@ifnch}, which will be called immediately before this point of % difference, handles both cases by looking for both \cs\ifvmode and % \cname{check@icr}. For the history, see \LaTeX{} bug report 2646. % % The check for \cs\ifvmode must not be part of a nested conditional. \TeX{} % can't match \cs\if{}s with \cs\fi{}s properly when you nest tests for % \cs\if-type tokens. See p.~211 of the \TeX{}book. % % When we encounter an \cs\ifvmode, we must assume we are inside a % TextFontCommand declared by one of the two kernel versions mentioned above. % If not, we are in an unknown situation and we will bomb. Since the error % message in this case won't be helpful, we warn the user in the log file. % We use scratch |d| to gobble both the \cs\ifvmode and what we expect will % follow the \cs\ifvmode, namely \code{\else\check@icr\fi}. After swallowing % those, we reissue those same commands and then proceed with our lookahead. % We want to issue those commands, which conditionally introduce an italic % correction, before looking further ahead. % \begin{macrocode} \newcommand\ti@q@handle@ifvmode {% % \DTypeout{Handling ifvmode}% \FrankenInfo{titles} {Handling an \string\ifvmode\space following a title.\MessageBreak If you now get an error that \string\sc@t@d\space does not\MessageBreak match its definition, this \string\ifvmode\space is\MessageBreak unexpected}% \DefName{sc@t@d} {\ifvmode\else\check@icr\fi} {% \ifvmode \else \check@icr \fi \aftergroup\ti@q@check }% \sc@t@d } % \end{macrocode} % \end{macro} % % \begin{macro}{\ti@q@handle@space} % Handle the case of a following space: gobble the space and call % \cname{ti@q@check}. % % This little bit of trickery sneaks a space in as the \cs\def template, % thereby causing a space following \cname{ti@q@handle@space} to get gobbled. % We use the control character \cname{:} and restore its value. % \begin{macrocode} \ReserveCS\ti@q@handle@space \let\sc@t@a\: \def\:{\ti@q@handle@space} \expandafter\def\: {\ti@q@check} \let\:\sc@t@a % \end{macrocode} % \end{macro} % % \begin{macro}{\ti@q@handle@single@suck} % \begin{macro}{\ti@q@handle@double@suck} % Handle the single and double sucking cases: gobble the closequotes token % with a \cs\def template, add some stuff to scratch |f| and call % \cname{ti@q@check}. These are put in their own macros only to avoid % clutter above. % \begin{macrocode} \newcommand*\ti@q@handle@double@suck [1] {% % \DTypeout{handle double suck: gobbling [\meaning#1]}% % \DTypeout{scratch f before: [\meaning\sc@t@f]}% \g@addto@macro\sc@t@f {\,\textquotedblright}% % \DTypeout{scratch f after: [\meaning\sc@t@f]}% \ti@q@check } \newcommand*\ti@q@handle@single@suck [1] {% % \DTypeout{handle single suck: gobbling [\meaning#1]}% % \DTypeout{scratch f before: [\meaning\sc@t@f]}% \g@addto@macro\sc@t@f {\,\textquoteright}% % \DTypeout{scratch f after: [\meaning\sc@t@f]}% \ti@q@check } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ti@q@handle@single@nosuck} % \begin{macro}{\ti@q@handle@double@nosuck} % Handle the single and double nosucking cases. Add inter-quote space to % scratch |f| and exit \cname{ti@q@@ifnch} with |true| or |false| depending % on whether we were looking for it. We had to do it this way instead of the % normal \cname{if} test above at the end of \cname{ti@q@@ifnch} because % \cname{ti@close@double@nosuck} is more than one character long. % \begin{macrocode} \newcommand*\ti@q@handle@double@nosuck [1] {% % \DTypeout{handle double nosuck: gobbling [\meaning#1]}% \if@look@nosuck@ % \DTypeout{And we're looking for \string\ti@close@double@nosuck.}% \g@addto@macro\sc@t@f {\,\textquotedblright}% % \DTypeout{After adding padding, F=[\meaning\sc@t@f]}% \let\sc@t@d\sc@t@a % the ``true'' clause of ti@q@ifnextcharin \else % \DTypeout{But we're not looking for \string\ti@close@double@nosuck.}% % \DTypeout{F is unchanged, F=[\meaning\sc@t@f]}% \let\sc@t@d\sc@t@b % the ``false'' clause of ti@q@ifnextcharin \fi \ti@q@check } \newcommand*\ti@q@handle@single@nosuck [1] {% % \DTypeout{handle single nosuck: gobbling [\meaning#1]}% \if@look@nosuck@ % \DTypeout{And we're looking for \string\ti@close@single@nosuck.}% \g@addto@macro\sc@t@f {\,\textquoteright}% % \DTypeout{After adding padding, F=[\meaning\sc@t@f]}% \let\sc@t@d\sc@t@a % the ``true'' clause of ti@q@ifnextcharin \else % \DTypeout{But we're not looking for \string\ti@close@single@nosuck.}% % \DTypeout{F is unchanged, F=[\meaning\sc@t@f]}% \let\sc@t@d\sc@t@b % the ``false'' clause of ti@q@ifnextcharin \fi \ti@q@check } % \end{macrocode} % \end{macro} % \end{macro} % % \section{Words and phrases} % % \begin{macro}{\word} % \begin{macro}{\foreign} % \begin{macro}{\foreignword} % \begin{macro}{\phrase} % \begin{macro}{\term} % \begin{macro}{\defn} % \mbox{} % \begin{macrocode} \newlet\word\textitswitch \newlet\foreign\textitswitch % \end{macrocode} % \todo{\cs\phrase is the result of expansion here: what effect will this have % on its proper nesting, and is this something to worry about?} % \begin{macrocode} \newcommand\foreignword [1] {% \phrase{\word{#1}}% } % \end{macrocode} % The \cs\@ cancels the effect on spacing of any final punctuation in the % argument. % \begin{macrocode} % \newlet\phrase\WrapquotesSK -- whoops, doesn't work as intended, % \phrase{foo}s puts a space before the following `s' % old definition: \newcommand\phrase [1] {% \textquoteleft #1\textquoteright\@% } \newlet\term\textitswitch \newlet\defn\textslswitch % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \section{Titles} % % \begin{macro}{\book} % \begin{macro}{\journal} % \begin{macro}{\music} % \begin{macro}{\article} % \begin{macro}{\storytitle} % \begin{macro}{\poemtitle} % \begin{macro}{\play} % \begin{macro}{\craft} % \begin{macro}{\species} % \mbox{} % \begin{macrocode} \newlet\book\textitswitch \newlet\journal\textitswitch \newlet\music\textitswitch \newlet\article\Wrapquotes \newlet\storytitle\Wrapquotes \newlet\poemtitle\Wrapquotes \newlet\play\textitswitch % \manualref{7.145} \newlet\craft\textitswitch \newlet\species\textitswitch % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \part{Configuration} % % User alterations and additions and package testing are in a configuration % file. % \begin{macrocode} \InputIfFileExists{titles.cfg}{}{} % \end{macrocode} % % The contents of the \emph{distributed} configuration file are below. % % \InputIfFileExists{titles.cfg}{}{} % % \Finale