wenzelm@26862: % underscore.sty 21-Sep-2005 Donald Arseneau asnd@triumf.ca wenzelm@26862: % Make the "_" character print as "\textunderscore" in text. wenzelm@26862: % Copyright 1998,2001,2005,2006 Donald Arseneau; wenzelm@26862: % License: LPPL version 1.2 or later. wenzelm@26862: % Instructions follow after the definitions. wenzelm@26862: wenzelm@26862: \ProvidesPackage{underscore}[2006/09/13] wenzelm@26862: wenzelm@26862: \begingroup wenzelm@26862: \catcode`\_=\active wenzelm@26862: \gdef _{% \relax % No relax gives a small vulnerability in alignments wenzelm@26862: \ifx\if@safe@actives\iftrue % must be outermost test! wenzelm@26862: \string_% wenzelm@26862: \else wenzelm@26862: \ifx\protect\@typeset@protect wenzelm@26862: \ifmmode \sb \else \BreakableUnderscore \fi wenzelm@26862: \else wenzelm@26862: \ifx\protect\@unexpandable@protect \noexpand_% wenzelm@26862: \else \protect_% wenzelm@26862: \fi\fi wenzelm@26862: \fi} wenzelm@26862: \global\let\ActiveUnderscore=_ wenzelm@26862: \gdef\normalUnderscoreDef{\let_\ActiveUnderscore} wenzelm@26862: \endgroup wenzelm@26862: wenzelm@26862: % At begin: set catcode; fix \long \ttdefault so I can use it in comparisons; wenzelm@26862: % reapply definition of active _ in output routine (\@firstofone to strip wenzelm@26862: % away braces, so avoiding deeper nesting). wenzelm@26862: \AtBeginDocument{% wenzelm@26862: {\immediate\write\@auxout{\catcode\number\string`\_ \string\active}}% wenzelm@26862: \catcode\string`\_\string=\active wenzelm@26862: \edef\ttdefault{\ttdefault}% wenzelm@26862: \output=\expandafter\expandafter\expandafter wenzelm@26862: {\expandafter\expandafter\expandafter\normalUnderscoreDef wenzelm@26862: \expandafter\@firstofone\the\output}% wenzelm@26862: } wenzelm@26862: wenzelm@26862: \newcommand{\BreakableUnderscore}{\leavevmode\nobreak\hskip\z@skip wenzelm@26862: \ifx\f@family\ttdefault \string_\else \textunderscore\fi wenzelm@26862: \usc@dischyph\nobreak\hskip\z@skip} wenzelm@26862: wenzelm@26862: \DeclareRobustCommand{\_}{% wenzelm@26862: \ifmmode \nfss@text{\textunderscore}\else \BreakableUnderscore \fi} wenzelm@26862: wenzelm@26862: wenzelm@26862: \let\usc@dischyph\@dischyph wenzelm@26862: \DeclareOption{nohyphen}{\def\usc@dischyph{\discretionary{}{}{}}} wenzelm@26862: \DeclareOption{strings}{\catcode`\_=\active} wenzelm@26862: wenzelm@26862: \ProcessOptions wenzelm@26862: \ifnum\catcode`\_=\active\else \endinput \fi wenzelm@26862: wenzelm@26862: %%%%%%%% Redefine commands that use character strings %%%%%%%% wenzelm@26862: wenzelm@26862: \@ifundefined{UnderscoreCommands}{\let\UnderscoreCommands\@empty}{} wenzelm@26862: \expandafter\def\expandafter\UnderscoreCommands\expandafter{% wenzelm@26862: \UnderscoreCommands wenzelm@26862: \do\include \do\includeonly wenzelm@26862: \do\@input \do\@iinput \do\InputIfFileExists wenzelm@26862: \do\ref \do\pageref \do\newlabel wenzelm@26862: \do\bibitem \do\@bibitem \do\cite \do\nocite \do\bibcite wenzelm@26862: \do\Ginclude@graphics \do\@setckpt wenzelm@26862: } wenzelm@26862: wenzelm@26862: % Macro to redefine a macro to pre-process its string argument wenzelm@26862: % with \protect -> \string. wenzelm@26862: \def\do#1{% Avoid double processing if user includes command twice! wenzelm@26862: \@ifundefined{US\string_\expandafter\@gobble\string#1}{% wenzelm@26862: \edef\@tempb{\meaning#1}% Check if macro is just a protection shell... wenzelm@26862: \def\@tempc{\protect}% wenzelm@26862: \edef\@tempc{\meaning\@tempc\string#1\space\space}% wenzelm@26862: \ifx\@tempb\@tempc % just a shell: hook into the protected inner command wenzelm@26862: \expandafter\do wenzelm@26862: \csname \expandafter\@gobble\string#1 \expandafter\endcsname wenzelm@26862: \else % Check if macro takes an optional argument wenzelm@26862: \def\@tempc{\@ifnextchar[}% wenzelm@26862: \edef\@tempa{\def\noexpand\@tempa####1\meaning\@tempc}% wenzelm@26862: \@tempa##2##3\@tempa{##2\relax}% wenzelm@26862: \edef\@tempb{\meaning#1\meaning\@tempc}% wenzelm@26862: \edef\@tempc{\noexpand\@tempd \csname wenzelm@26862: US\string_\expandafter\@gobble\string#1\endcsname}% wenzelm@26862: \if \expandafter\@tempa\@tempb \relax 12\@tempa % then no optional arg wenzelm@26862: \@tempc #1\US@prot wenzelm@26862: \else % There is optional arg wenzelm@26862: \@tempc #1\US@protopt wenzelm@26862: \fi wenzelm@26862: \fi wenzelm@26862: }{}} wenzelm@26862: wenzelm@26862: \def\@tempd#1#2#3{\let#1#2\def#2{#3#1}} wenzelm@26862: wenzelm@26862: \def\US@prot#1#2{\let\@@protect\protect \let\protect\string wenzelm@26862: \edef\US@temp##1{##1{#2}}\restore@protect\US@temp#1} wenzelm@26862: \def\US@protopt#1{\@ifnextchar[{\US@protarg#1}{\US@prot#1}} wenzelm@26862: \def\US@protarg #1[#2]{\US@prot{{#1[#2]}}} wenzelm@26862: wenzelm@26862: \UnderscoreCommands wenzelm@26862: \let\do\relax \let\@tempd\relax % un-do wenzelm@26862: wenzelm@26862: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wenzelm@26862: wenzelm@26862: \endinput wenzelm@26862: wenzelm@26862: underscore.sty 13-Sep-2006 Donald Arseneau wenzelm@26862: wenzelm@26862: Features: wenzelm@26862: ~~~~~~~~~ wenzelm@26862: The "\_" command (which normally prints an underscore character or wenzelm@26862: facsimile) is altered so that the hyphenation of constituent words wenzelm@26862: is not affected, and hyphenation is permitted after the underscore. wenzelm@26862: For example, "compound\_fracture" hyphenates as com- pound\_- frac- ture. wenzelm@26862: If you prefer the underscore to break without a hyphen (but still with wenzelm@26862: the same rules for explicit hyphen-breaks) then use the [nohyphen] wenzelm@26862: package option. wenzelm@26862: wenzelm@26862: A simple "_" acts just like "\_" in text mode, but makes a subscript wenzelm@26862: in math mode: activation_energy $E_a$ wenzelm@26862: wenzelm@26862: Both forms use an underscore character if the font encoding contains wenzelm@26862: one (e.g., "\usepackage[T1]{fontenc}" or typewriter fonts in any encoding), wenzelm@26862: but they use a rule if there is no proper character. wenzelm@26862: wenzelm@26862: Deficiencies: wenzelm@26862: ~~~~~~~~~~~~~ wenzelm@26862: The skips and penalties ruin any kerning with the underscore character wenzelm@26862: (when a character is used). However, there doesn't seem to be much, if wenzelm@26862: any, such kerning in the ec fonts, and there is never any kerning with wenzelm@26862: a rule. wenzelm@26862: wenzelm@26862: You must avoid "_" in file names and in cite or ref tags, or you must use wenzelm@26862: the babel package, with its active-character controls, or you must give wenzelm@26862: the [strings] option, which attempts to redefine several commands (and wenzelm@26862: may not work perfectly). Even without the [strings] option or babel, you wenzelm@26862: can use occasional underscores like: "\include{file\string_name}". wenzelm@26862: wenzelm@26862: Option: [strings] wenzelm@26862: ~~~~~~~~~~~~~~~~~ wenzelm@26862: The default operation is quite simple and needs no customization; but wenzelm@26862: you must avoid using "_" in any place where LaTeX uses an argument as wenzelm@26862: a string of characters for some control function or as a name. These wenzelm@26862: include the tags for "\cite" and "\ref", file names for "\input", wenzelm@26862: "\include", and "\includegraphics", environment names, counter names, wenzelm@26862: and placement parameters (like "[t]"). The problem with these contexts wenzelm@26862: is that they are `moving arguments' but LaTeX does not `switch on' the wenzelm@26862: "\protect" mechanism for them. wenzelm@26862: wenzelm@26862: If you need to use the underscore character in these places, the package wenzelm@26862: option [strings] is provided to redefine commands that take such a string wenzelm@26862: argument so that protection is applied (with "\protect" being "\string"). wenzelm@26862: The list of commands is given in "\UnderscoreCommands", with "\do" before wenzelm@26862: each; plus several others covering "\input", "\includegraphics, "\cite", wenzelm@26862: "\ref", and their variants. Not included are many commands regarding font wenzelm@26862: names, everything with counter names, environment names, page styles, and wenzelm@26862: versions of "\ref" and "\cite" defined by external packages (e.g., "\vref" wenzelm@26862: and "\citeyear"). wenzelm@26862: wenzelm@26862: You can add to the list of supported commands by defining "\UnderscoreCommands" wenzelm@26862: before loading this package; e.g. wenzelm@26862: wenzelm@26862: \usepackage{chicago} wenzelm@26862: \newcommand{\UnderscoreCommands}{% (\cite already done) wenzelm@26862: \do\citeNP \do\citeA \do\citeANP \do\citeN \do\shortcite wenzelm@26862: \do\shortciteNP \do\shortciteA \do\shortciteANP \do\shortciteN wenzelm@26862: \do\citeyear \do\citeyearNP wenzelm@26862: } wenzelm@26862: \usepackage[strings]{underscore} wenzelm@26862: wenzelm@26862: Not all commands can be supported this way! Only commands that take a wenzelm@26862: string argument *first* can be protected. One optional argument before wenzelm@26862: the string argument is also permitted, as exemplified by "\cite": both wenzelm@26862: "\cite{tags}" and "\cite[text]{tags}" are allowed. A command like wenzelm@26862: "\@addtoreset" which takes two counter names as arguments could not wenzelm@26862: be protected by listing it in "\UnderscoreCommands". wenzelm@26862: wenzelm@26862: *When you use the [strings] option, you must load this package wenzelm@26862: last* (or nearly last). wenzelm@26862: wenzelm@26862: There are two reasons: 1) The redefinitions done for protection must come wenzelm@26862: after other packages define their customized versions of those commands. wenzelm@26862: 2) The [strings] option requires the "_" character to be activated immediately wenzelm@26862: in order for the cite and ref tags to be read properly from the .aux file wenzelm@26862: as plain strings, and this catcode setting might disrupt other packages. wenzelm@26862: wenzelm@26862: The babel package implements a protection mechanism for many commands, wenzelm@26862: and will be a complete fix for most documents without the [strings] option. wenzelm@26862: Many add-on packages are compatible with babel, so they will get the wenzelm@26862: strings protection also. However, there are several commands that are wenzelm@26862: not covered by babel, but can easily be supported by the [strings] and wenzelm@26862: "\UnderscoreCommands" mechanism. Beware that using both [strings] and wenzelm@26862: babel might lead to conflicts, but none are seen yet (load babel last). wenzelm@26862: wenzelm@26862: Implementation Notes: wenzelm@26862: ~~~~~~~~~~~~~~~~~~~~~ wenzelm@26862: The first setting of "_" to be an active character is performed in a local wenzelm@26862: group so as to not interfere with other packages. The catcode setting wenzelm@26862: is repeated with "\AtBeginDocument" so the definition is in effect for the wenzelm@26862: text. However, the catcode setting is repeated immediately when the wenzelm@26862: [strings] option is detected. wenzelm@26862: wenzelm@26862: The definition of the active "_" is essentially: wenzelm@26862: wenzelm@26862: \ifmmode \sb \else \BreakableUnderscore \fi wenzelm@26862: wenzelm@26862: where "\sb" retains the normal subscript meaning of "_" and where wenzelm@26862: "\BreakableUnderscore" is essentially "\_". The rest of the definition wenzelm@26862: handles the "\protect"ion without causing "\relax" to be inserted before wenzelm@26862: the character. wenzelm@26862: wenzelm@26862: "\BreakableUnderscore" uses "\nobreak\hskip\z@skip" to separate the wenzelm@26862: underscore from surrounding words, thus allowing TeX to hyphenate them, wenzelm@26862: but preventing free breaks around the underscore. Next, it checks the wenzelm@26862: current font family, and uses the underscore character from tt fonts or wenzelm@26862: otherwise "\textunderscore" (which is a character or rule depending on wenzelm@26862: the font encoding). After the underscore, it inserts a discretionary wenzelm@26862: hyphenation point as "\usc@dischyph", which is usually just "\-" wenzelm@26862: except that it still works in the tabbing environment, although it wenzelm@26862: will give "\discretionary{}{}{}" under the [nohyphen] option. After wenzelm@26862: that, another piece of non-breaking interword glue is inserted. wenzelm@26862: Ordinarily, the comparison "\ifx\f@family\ttdefault" will always fail wenzelm@26862: because "\ttdefault" is `long' whereas "\f@family" is not (boooo hisss), wenzelm@26862: but "\ttdefault" is redefined to be non-long by "\AtBeginDocument". wenzelm@26862: wenzelm@26862: The "\_" command is then defined to use "\BreakableUnderscore". wenzelm@26862: wenzelm@26862: If the [strings] option is not given, then that is all! wenzelm@26862: wenzelm@26862: Under the [strings] option, the list of special commands is processed to: wenzelm@26862: wenzelm@26862: - retain the original command as "\US_"*command* (e.g., "\US_ref") wenzelm@26862: - redefine the command as "\US@prot\US_command" for ordinary commands wenzelm@26862: ("\US@prot\US_ref") or as "\US@protopt\US_command" when an optional wenzelm@26862: argument is possible (e.g., "\US@protopt\US_bibitem"). wenzelm@26862: - self-protecting commands ("\cite") retain their self-protection. wenzelm@26862: wenzelm@26862: Diagnosing the state of the pre-existing command is done by painful wenzelm@26862: contortions involving "\meaning". wenzelm@26862: wenzelm@26862: "\US@prot" and "\US@protopt" read the argument, process it with wenzelm@26862: "\protect" enabled, then invoke the saved "\US_command". wenzelm@26862: wenzelm@26862: Modifications: wenzelm@26862: ~~~~~~~~~~~~~~ wenzelm@26862: 13-Sep-2006 Reassert my definition in the output routine (listings). wenzelm@26862: 21-Sep-2005 \includegraphics safe. wenzelm@26862: 12-Oct-2001 Babel (safe@actives) compatibility and [nohyphen] option. wenzelm@26862: wenzelm@26862: Test file integrity: ASCII 32-57, 58-126: !"#$%&'()*+,-./0123456789 wenzelm@26862: :;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~