|
| 1 | +% underscore.sty 12-Oct-2001 Donald Arseneau asnd@triumf.ca |
| 2 | +% Make the "_" character print as "\textunderscore" in text. |
| 3 | +% Copyright 1998,2001 Donald Arseneau; Distribute freely if unchanged. |
| 4 | +% Instructions follow after the definitions. |
| 5 | + |
| 6 | +\ProvidesPackage{underscore}[2001/10/12] |
| 7 | + |
| 8 | +\begingroup |
| 9 | + \catcode`\_=\active |
| 10 | + \gdef_{% \relax % No relax gives a small vulnerability in alignments |
| 11 | + \ifx\if@safe@actives\iftrue % must be outermost test! |
| 12 | + \string_% |
| 13 | + \else |
| 14 | + \ifx\protect\@typeset@protect |
| 15 | + \ifmmode \sb \else \BreakableUnderscore \fi |
| 16 | + \else |
| 17 | + \ifx\protect\@unexpandable@protect \noexpand_% |
| 18 | + \else \protect_% |
| 19 | + \fi\fi |
| 20 | + \fi} |
| 21 | +\endgroup |
| 22 | + |
| 23 | +% At begin: set catcode; fix \long \ttdefault so I can use it in comparisons; |
| 24 | +\AtBeginDocument{% |
| 25 | + {\immediate\write\@auxout{\catcode\number\string`\_ \string\active}}% |
| 26 | + \catcode\string`\_\string=\active |
| 27 | + \edef\ttdefault{\ttdefault}% |
| 28 | +} |
| 29 | + |
| 30 | +\newcommand{\BreakableUnderscore}{\leavevmode\nobreak\hskip\z@skip |
| 31 | + \ifx\f@family\ttdefault \string_\else \textunderscore\fi |
| 32 | + \usc@dischyph\nobreak\hskip\z@skip} |
| 33 | + |
| 34 | +\DeclareRobustCommand{\_}{% |
| 35 | + \ifmmode \nfss@text{\textunderscore}\else \BreakableUnderscore \fi} |
| 36 | + |
| 37 | +\let\usc@dischyph\@dischyph |
| 38 | +\DeclareOption{nohyphen}{\def\usc@dischyph{\discretionary{}{}{}}} |
| 39 | +\DeclareOption{strings}{\catcode`\_=\active} |
| 40 | + |
| 41 | +\ProcessOptions |
| 42 | +\ifnum\catcode`\_=\active\else \endinput \fi |
| 43 | + |
| 44 | +%%%%%%%% Redefine commands that use character strings %%%%%%%% |
| 45 | + |
| 46 | +\@ifundefined{UnderscoreCommands}{\let\UnderscoreCommands\@empty}{} |
| 47 | +\expandafter\def\expandafter\UnderscoreCommands\expandafter{% |
| 48 | + \UnderscoreCommands |
| 49 | + \do\include \do\includeonly |
| 50 | + \do\@input \do\@iinput \do\InputIfFileExists |
| 51 | + \do\ref \do\pageref \do\newlabel |
| 52 | + \do\bibitem \do\@bibitem \do\cite \do\nocite \do\bibcite |
| 53 | +} |
| 54 | + |
| 55 | +% Macro to redefine a macro to pre-process its string argument |
| 56 | +% with \protect -> \string. |
| 57 | +\def\do#1{% Avoid double processing if user includes command twice! |
| 58 | + \@ifundefined{US\string_\expandafter\@gobble\string#1}{% |
| 59 | + \edef\@tempb{\meaning#1}% Check if macro is just a protection shell... |
| 60 | + \def\@tempc{\protect}% |
| 61 | + \edef\@tempc{\meaning\@tempc\string#1\space\space}% |
| 62 | + \ifx\@tempb\@tempc % just a shell: hook into the protected inner command |
| 63 | + \expandafter\do |
| 64 | + \csname \expandafter\@gobble\string#1 \expandafter\endcsname |
| 65 | + \else % Check if macro takes an optional argument |
| 66 | + \def\@tempc{\@ifnextchar[}% |
| 67 | + \edef\@tempa{\def\noexpand\@tempa####1\meaning\@tempc}% |
| 68 | + \@tempa##2##3\@tempa{##2\relax}% |
| 69 | + \edef\@tempb{\meaning#1\meaning\@tempc}% |
| 70 | + \edef\@tempc{\noexpand\@tempd \csname |
| 71 | + US\string_\expandafter\@gobble\string#1\endcsname}% |
| 72 | + \if \expandafter\@tempa\@tempb \relax 12\@tempa % then no optional arg |
| 73 | + \@tempc #1\US@prot |
| 74 | + \else % There is optional arg |
| 75 | + \@tempc #1\US@protopt |
| 76 | + \fi |
| 77 | + \fi |
| 78 | + }{}} |
| 79 | + |
| 80 | +\def\@tempd#1#2#3{\let#1#2\def#2{#3#1}} |
| 81 | + |
| 82 | +\def\US@prot#1#2{\let\@@protect\protect \let\protect\string |
| 83 | + \edef\US@temp##1{##1{#2}}\restore@protect\US@temp#1} |
| 84 | +\def\US@protopt#1{\@ifnextchar[{\US@protarg#1}{\US@prot#1}} |
| 85 | +\def\US@protarg #1[#2]{\US@prot{{#1[#2]}}} |
| 86 | + |
| 87 | +\UnderscoreCommands |
| 88 | +\let\do\relax \let\@tempd\relax % un-do |
| 89 | + |
| 90 | +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 91 | + |
| 92 | +\endinput |
| 93 | + |
| 94 | +underscore.sty 12-Oct-2001 Donald Arseneau |
| 95 | + |
| 96 | +Features: |
| 97 | +~~~~~~~~~ |
| 98 | +\_ prints an underscore so that the hyphenation of constituent words |
| 99 | +is not affected and hyphenation is permitted after the underscore. |
| 100 | +For example, "compound\_fracture" hyphenates as com- pound_- frac- ture. |
| 101 | +If you prefer the underscore to break without a hyphen (but still with |
| 102 | +the same rules for explicit hyphen-breaks) then use the [nohyphen] |
| 103 | +package option. |
| 104 | + |
| 105 | +A simple _ acts just like \_ in text mode, but makes a subscript in |
| 106 | +math mode: activation_energy $E_a$ |
| 107 | + |
| 108 | +Both forms use an underscore character if the font encoding contains |
| 109 | +one (e.g., "\usepackage[T1]{fontenc}" or typewriter fonts in any encoding), |
| 110 | +but they use a rule if the there is no proper character. |
| 111 | + |
| 112 | +Deficiencies: |
| 113 | +~~~~~~~~~~~~~ |
| 114 | +The skips and penalties ruin any kerning with the underscore character |
| 115 | +(when a character is used). However, there doesn't seem to be much, if |
| 116 | +any, such kerning in the ec fonts, and there is never any kerning with |
| 117 | +a rule. |
| 118 | + |
| 119 | +You must avoid "_" in file names and in cite or ref tags, or you must use |
| 120 | +the babel package, with its active-character controls, or you must give |
| 121 | +the [strings] option, which attempts to redefine several commands (and |
| 122 | +may not work perfectly). Even without the [strings] option or babel, you |
| 123 | +can use occasional underscores like: "\include{file\string_name}". |
| 124 | + |
| 125 | +Option: [strings] |
| 126 | +~~~~~~~~~~~~~~~~~ |
| 127 | +The default operation is quite simple and needs no customization; but |
| 128 | +you must avoid using "_" in any place where LaTeX uses an argument as |
| 129 | +a string of characters for some control function or as a name. These |
| 130 | +include the tags for \cite and \ref, file names for \input, \include, |
| 131 | +and \includegraphics, environment names, counter names, and placement |
| 132 | +parameters (like "[t]"). The problem with these contexts is that they |
| 133 | +are `moving arguments' but LaTeX does not `switch on' the \protect |
| 134 | +mechanism for them. |
| 135 | + |
| 136 | +If you need to use the underscore character in these places, the package |
| 137 | +option [strings] is provided to redefine commands taking a string argument |
| 138 | +so that the argument is protected (with \protect -> \string). The list |
| 139 | +of commands is given in "\UnderscoreCommands", with "\do" before each, |
| 140 | +covering \cite, \ref, \input, and their variants. Not included are many |
| 141 | +commands regarding font names, everything with counter names, environment |
| 142 | +names, page styles, and versions of \ref and \cite defined by external |
| 143 | +packages (e.g. \vref and \citeyear). |
| 144 | + |
| 145 | +You can add to the list of supported commands by defining \UnderscoreCommands |
| 146 | +before loading this package; e.g. |
| 147 | + |
| 148 | + \usepackage{chicago} |
| 149 | + \newcommand{\UnderscoreCommands}{% (\cite already done) |
| 150 | + \do\citeNP \do\citeA \do\citeANP \do\citeN \do\shortcite |
| 151 | + \do\shortciteNP \do\shortciteA \do\shortciteANP \do\shortciteN |
| 152 | + \do\citeyear \do\citeyearNP |
| 153 | + } |
| 154 | + \usepackage[strings]{underscore} |
| 155 | + |
| 156 | +Not all commands can be supported this way! Only commands that take a |
| 157 | +string argument *first* can be protected. One optional argument before |
| 158 | +the string argument is also permitted, as exemplified by \cite: both |
| 159 | +\cite{tags} and \cite[text]{tags} are allowed. A command like |
| 160 | +\@addtoreset which takes two counter names as arguments could not |
| 161 | +be protected by adding it to \UnderscoreCommands. |
| 162 | + |
| 163 | +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| 164 | +!! When you use the [strings] option, you must load this package !! |
| 165 | +!! last (or nearly last). !! |
| 166 | +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| 167 | + |
| 168 | +There are two reasons: 1) The redefinitions done for protection must come |
| 169 | +after other packages define their customized versions of those commands. |
| 170 | +2) The [strings] option requires the _ character to be activated immediately |
| 171 | +in order for the cite and ref tags to be read properly from the .aux file |
| 172 | +as plain strings, and this catcode setting might disrupt other packages. |
| 173 | + |
| 174 | +The babel package implements a protection mechanism for many commands, |
| 175 | +and will be a complete fix for most documents without the [strings] option. |
| 176 | +Many add-on packages are compatible with babel, so they will get the |
| 177 | +strings protection also. However, there are several commands that are |
| 178 | +not covered by babel, but can easily be supported by the [strings] and |
| 179 | +\UnderscoreCommands mechanism. Beware that using both [strings] and babel |
| 180 | +may lead to conflicts, but does appear to work (load babel last). |
| 181 | + |
| 182 | +Implementation Notes: |
| 183 | +~~~~~~~~~~~~~~~~~~~~~ |
| 184 | +The first setting of "_" to be an active character is performed in a local |
| 185 | +group so as to not interfere with other packages. The catcode setting |
| 186 | +is repeated with \AtBeginDocument so the definition is in effect for the |
| 187 | +text. However, the catcode setting is repeated immediately when the |
| 188 | +[strings] option is detected. |
| 189 | + |
| 190 | +The definition of the active "_" is essentially: |
| 191 | + \ifmmode \sb \else \BreakableUnderscore \fi |
| 192 | +where "\sb" retains the normal subscript meaning of "_" and where |
| 193 | +"\BreakableUnderscore" is essentially "\_". The rest of the definition |
| 194 | +handles the "\protect"ion without causing \relax to be inserted before |
| 195 | +the character. |
| 196 | + |
| 197 | +\BreakableUnderscore uses "\nobreak\hskip\z@skip" to separate the |
| 198 | +underscore from surrounding words, thus allowing TeX to hyphenate them, |
| 199 | +but preventing free breaks around the underscore. Next, it checks the |
| 200 | +current font family, and uses the underscore character from tt fonts or |
| 201 | +otherwise \textunderscore (which is a character or rule depending on |
| 202 | +the font encoding). After the underscore, it inserts a discretionary |
| 203 | +hyphenation point as "\usc@dischyph", which is usually just "\-" |
| 204 | +except that it still works in the tabbing environment, although it |
| 205 | +will give "\discretionary{}{}{}" under the [nohyphen] option. After |
| 206 | +that, another piece of non-breaking interword glue is inserted. |
| 207 | +Ordinarily, the comparison "\ifx\f@family\ttdefault" will always fail |
| 208 | +because \ttdefault is `long' where \f@family is not (boooo hisss), but |
| 209 | +\ttdefault is redefined to be non-long by "\AtBeginDocument". |
| 210 | + |
| 211 | +The "\_" command is then defined to use "\BreakableUnderscore". |
| 212 | + |
| 213 | +If the [strings] option is not given, then that is all! |
| 214 | + |
| 215 | +Under the [strings] option, the list of special commands is processed to: |
| 216 | +- retain the original command as \US_command (\US_ref) |
| 217 | +- redefine the command as \US@prot\US_command for ordinary commands |
| 218 | + (\ref -> \US@prot\US_ref) or as \US@protopt\US_command when an optional |
| 219 | + argument is possible (\bibitem -> \US@protopt\US_bibitem). |
| 220 | +- self-protecting commands (\cite) retain their self-protection. |
| 221 | +Diagnosing the state of the pre-existing command is done by painful |
| 222 | +contortions involving \meaning. |
| 223 | + |
| 224 | +\US@prot and \US@protopt read the argument, process it with \protect |
| 225 | +enabled, then invoke the saved \US_command. |
| 226 | + |
| 227 | +Modifications: |
| 228 | +~~~~~~~~~~~~~~ |
| 229 | +12-Oct-2001 Babel (safe@actives) compatibility and [nohyphen] option. |
| 230 | + |
| 231 | +Test file integrity: ASCII 32-57, 58-126: !"#$%&'()*+,-./0123456789 |
| 232 | +:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ |
0 commit comments