listings 包定义了一个钩子,EveryLine
允许用户在列表的每一行开头执行 TeX 代码;以下内容直接取自listings
源代码(listings.dtx
):
\hookname{EveryLine} Executed at the beginning of each \emph{output} line, i.e.~more than once for broken lines. This hook must not change the horizontal or vertical position.
下面的代码是我尝试使用此钩子测试每行的第一个字符是否是,如果是f
,则在它前面插入YES
。但是,正如您在下面看到的,我没有得到预期的输出。
起初,我以为这可能是一个分组问题:插入的代码EveryLine
可能隐藏在一个组内,因此我的测试无法访问该行上的第一个标记,因为该标记位于相关组之外。然而,快速测试(包括本地增加 TeX 寄存器)表明情况并非如此。
知道我做错了什么吗?
\documentclass{article}
\usepackage{listings}
\usepackage{filecontents}
\begin{filecontents*}{sample.c}
foo
bar
frivolous
thing
discourse
fragile
\end{filecontents*}
\makeatletter
\lst@AddToHook{EveryLine}{\@ddedToEveryline}
\def\detectF#1{\ifx f#1 YES#1\fi}
\newcount\mycount
\def\advandprintCount{\advance\mycount by \@ne\the\mycount}
\makeatother
\begin{document}
\makeatletter
\let\@ddedToEveryline\detectF
\lstinputlisting[basicstyle=\ttfamily]{sample.c}
\let\@ddedToEveryline\advandprintCount
\lstinputlisting[basicstyle=\ttfamily]{sample.c}
\makeatother
\end{document}
答案1
这是我的尝试:
\documentclass{article}
\usepackage{pdftexcmds}
\usepackage{listings}
\usepackage{filecontents}
\begin{filecontents*}{sample.c}
foo
bar
frivolous
thing
discourse
fragile
\end{filecontents*}
\makeatletter
\lst@AddToHook{EveryLine}{\@ddedToEveryline}
\def\@splitfirstchar#1#2\@nil{\gdef\@detectF{#1}}
\def\splitfirstchar#1{\@splitfirstchar#1\@nil}
\def\@detectF{%
% -\the\lst@token-
\expandafter\splitfirstchar\expandafter{\the\lst@token}%
\def\@tempa{f}%
% -\@detectF-
\ifnum\pdf@strcmp{\@detectF}{\@tempa}=\z@
YES
\else
NO
\fi%
}
\newcount\mycount
\def\advandprintCount{\advance\mycount by \@ne\the\mycount}
\makeatother
\begin{document}
\makeatletter
\let\@ddedToEveryline\@detectF
\lstinputlisting[basicstyle=\ttfamily]{sample.c}
\let\@ddedToEveryline\advandprintCount
\lstinputlisting[basicstyle=\ttfamily]{sample.c}
\makeatother
\end{document}