我一直在研究 TeX 原语,特别是 catcodes,以处理各种 LaTeX 情况(并扩展我的能力)。
我在以下帮助下创建了一个 token 吞噬者https://tex.stackexchange.com/a/33536/13552
为什么我在类别代码列表中看不到任何数字 10?
测试是否安全\@empty
?如果是,使用
\g@addto@macro{\tempa}{\fbox{ }}%
\documentclass{article}
\begin{document}
\makeatletter
\def\scanfunction#1{#1}% Don't know why this is here
\let\tempa\@empty
\def\scan@letters#1#2{% https://tex.stackexchange.com/a/33536/13552
\bgroup\catcode`\ \active \let\ \fbox{ }\egroup%Try changing space to visible box
\def\getcategory##1{\the\catcode`##1}% ` changes char into ASCI number required for \catcode
\def\currcatcode{\getcategory{#1}}% put everything into unified token for \if
\currcatcode, % spurious space intentional % first character missing
\if 10\currcatcode%
\fbox{#2}% if catcode 10 fed, print it as a box
\fi
\g@addto@macro{\tempa}{#1\hskip 0pt plus 1sp minus 1sp}%
\ifx#2\@empty%\@empty is what the end of the line will look like ^^M?
\else
\expandafter\scan@letters % recall yourself using #2 until this conditional becomes true
\fi
#2}
\def\scan#1{%
%\catcode"0020 11 % Tried changing space to catcode 11
%\the\catcode"0020 % Test to ensure change happened
\scan@letters #1\@empty
}
\makeatother
\scan{ mac::exception == }
% \scan{ } % crashes with "Improper alphabetic constant."
\begin{itemize}
\item \tempa
\end{itemize}
\end{document}
当然,我期望\scan{ mac::exception == }
10, 10, 11, 11, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 12, 12, 10, 10,
我的收藏以供参考
显然,它是有可能看到 10。
\the\catcode`\
结果:13(错误地预期为10)
\the\catcode`\ %
结果:10
\the\catcode"0020
结果:10
2016 年 6 月 24 日更新实用解决方案
知道这一点也许很有用,所以我把它放在这里。使用上下文和 David Carlisle 的回答来理解,\afterassignment
以便我可以测试第 10 类(空格),我修改了我的代码,在每个非空格字符后添加粘连,这样 LaTeX 换行机制就会在以下情况下触发:
- 所有字符框的总宽度 =
\textwidth
样本
\documentclass{article}
\usepackage{fontspec}
\newfontfamily\macmonofont{Inconsolatazi4-Regular.otf}
%\makeatletter % or \catcode"0040=11
\def\macmono#1{\xscan#1\relax}% calls xscan which looks ahead one token, #1
\def\xscan{\afterassignment\xxscan\let\token= }% assign single token to \token and call \xxscan
\def\xxscan{%
\macmonofont% apply mono font
\ifx\token\relax\normalfont\else%test for end-of-line or end of group and switch back to normal font
\ifcat\token\space%
\token% token is catcode 10
\spaceskip=.5em% remove glue from space for fixed-width space
\xspaceskip=.5em% remove glue from space for fixed-width space
\else%
\token\hskip 0pt plus 1sp minus 1sp % add glue to any non-catcode 10 (space)
\fi
\expandafter\xscan
\fi}
%\makeatother % or \catcode"0040=12
\parindent=0pt % remove firstpar autoindent
\obeylines% insert \par after each end-of-line (^^M)
\begin{document}
\begin{itemize}
\item Some random error created by C++: \macmono{mac::IOException [File: sharecpp/trunk/PROJECTS/SpecialOps/B/Build/Implementation/Library/GenerateDocumentation.cpp, Line: 999]
Found documentation overview begin marker more than once in DocumentationManual!
mac::IOException [File: sharecpp/trunk/PROJECTS/SpecialOps/B/Build/Implementation/Library/DocumentationThread.cpp, Line: 934]
Processing of DocumentationManual failed while generating DocumentationOverview!} and some trailing test to make sure font changing works. \end{itemize}
\end{document}
输出
答案1
无括号的 catcode 10 个字符永远不会被视为无界参数,因此您可以
\def\foo#1#2#3{...}
\foo a b c
并以 a、b 和 c(而不是它们之间的空格)作为三个参数。
通常的解决方案是使用\futurelet
(或如下所示\afterassignment
和\let
),但这取决于您想要做什么。
您的 catcode 发生变化,例如
\catcode`\ \active
没有效果,因为空格已经在\scan
宏的参数中被标记了。
10,10,
即使你修复了扫描仪,你也不应该期望连续的 10,因为输入文件中任何数量的连续空格都被标记为单个 catcode 10 标记
\documentclass{article}
\def\scan#1{\xscan#1\relax}
\def\xscan{\afterassignment\xxscan\let\tmp= }
\def\xxscan{%
\ifx\tmp\relax\else
\ifcat\tmp\space10 \else
\ifcat\tmp a11 \else
\ifcat\tmp 112 \else%...
\fi\fi\fi
\expandafter\xscan
\fi}
\begin{document}
\scan{ mac::exception == }
\end{document}