我一直在用 Hendrik Vogt 对我之前问题的回答重新定义下划线以产生罗马下标其中他解释了如何使下划线字符处于活动状态并为其分配一个宏,以便可以重新定义它以生成下标中的罗马类型:
\catcode`_=\active
\newcommand_[1]{\ensuremath{\sb{\mathrm{#1}}}}
这个解决方案在数学和文本环境中非常有效,但是当我在“文字”环境中使用它时遇到了麻烦,例如文件名或引用,在这些环境中,_
主动操作会中断一些事情。
问题:如何使下划线产生罗马下标,但仍在文件名、标签、引用等中用作普通字符?我只需要在数学环境中使用下标函数。
梅威瑟:
\documentclass{article}
\catcode`_=\active
\newcommand_[1]{\ensuremath{\sb{\mathrm{#1}}}}
\begin{document}
$D_H$
\label{sec_a} % This causes a "! Missing \endcsname inserted." error
\end{document}
答案1
如果你只需要_
数学中的 ,那么\mathcode
就可以了。但是,TeX 似乎在\catcode
之前看到了\mathcode
,所以我也改变了它:
\documentclass{article}
\begingroup
\catcode`\_=\active
\gdef_#1{\ensuremath{\sb{\mathrm{#1}}}}
\endgroup
\mathcode`\_=\string"8000
\catcode`\_=12
\begin{document}
$D_H$
\label{sec_a} % This no longer causes a "! Missing \endcsname inserted." error
\end{document}
为了简单起见,我\gdef
在这里使用;如果您愿意,可以避免这种情况。
答案2
\ifmmode
您可以使用类似方法测试数学模式\ensuremath
。然后应使用两个宏来完成此操作,以便“正常下划线”不接受参数:
\documentclass{article}
\catcode`_=\active
\newcommand{_}{\ifmmode\expandafter\sbrm\else\string_\fi}
\newcommand{\sbrm}[1]{\sb{\mathrm{#1}}}
\begin{filecontents}{\jobname_test.tex}
Read input file test Test!
\end{filecontents}
\begin{document}
\label{sec_a} % Works now
$D_H$
\input{\jobname_test}
\end{document}
答案3
您不一定需要这样命名标签(尝试\label{sec:a}
),并且对于文件名或其他用例强制_
使用普通字符:
\input{file\string_name}