当宏(\inputlineno)改变值/定义时,是否可以运行处理程序/回调函数?

当宏(\inputlineno)改变值/定义时,是否可以运行处理程序/回调函数?

我在思考我经历的调试过程为什么波浪号 ~ 有时不像不间断空格那样表现?- 基本上,为了找出宏在哪里发生了~变化,我必须在每一行代码上手动插入日志命令,如下所示:

% https://tex.stackexchange.com/questions/81789/get-current-source-line-number/81794#81794
\def\showLineMean{\typeout{line \the\inputlineno; MEANING: \meaning~}}
...
\usetikzlibrary{calc} \showLineMean                    % l.61
\usetikzlibrary{decorations.markings} \showLineMean    % l.62
\usepackage{txfonts} \showLineMean % Times font ...    % l.63
\renewcommand{\ttdefault}{pcr} \showLineMean           % l.64
...

当然,这可能有点乏味,特别是当您有一个很大的文档,而代码中没有明显需要关注的地方时。

所以,我在想 - 因为已经有一个名为的标记\inputlineno可以改变每一行代码的值,我认为如果我可以说类似这样的话会容易得多:“在每一行新的源代码上,输入\meaning~; 也许通过类似这样的伪代码:

\ontokenchange{\inputlineno}{\typeout{line \the\inputlineno; MEANING: \meaning~}}

...因此我可以将其插入到文档中的相关位置,并用以下方式停止它\ontokenchangestop;或者更好的是,使用先验有限的范围:

\ontokenchange[startval=100,stopval=130]{\inputlineno}{\typeout{line \the\inputlineno; MEANING: \meaning~}}

...(假设\inputlineno是单调递增的)将从第 100 行开始跟踪,并在进程到达第 130 行时停止跟踪。

因此,我对 Latex 设置中的这一点很感兴趣;然而,\inputlineno似乎是 tex 核心,因为它显然是在tex.web

$ grep -B1 -A1 -n 'input.*line.*no' tex.web 
8405-And the |last_item| command is modified by either |int_val|, |dimen_val|,
8406:|glue_val|, |input_line_no_code|, or |badness_code|.
8407-
8408:@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}}
8409-@d badness_code=glue_val+2 {code for \.{\\badness}}
--
8431-@!@:last_skip_}{\.{\\lastskip} primitive@>
8432:primitive("inputlineno",last_item,input_line_no_code);
8433:@!@:input_line_no_}{\.{\\inputlineno} primitive@>
8434-primitive("badness",last_item,badness_code);
--
8448-  glue_val: print_esc("lastskip");
8449:  input_line_no_code: print_esc("inputlineno");
8450-  othercases print_esc("badness")
--
8507-
8508:We also handle \.{\\inputlineno} and \.{\\badness} here, because they are
8509-legal in similar contexts.
--
8512-if cur_chr>glue_val then
8513:  begin if cur_chr=input_line_no_code then cur_val:=line
8514-  else cur_val:=last_badness; {|cur_chr=badness_code|}

从这个角度来看,我实际上无法设置在发生\inputlineno更改时执行的处理程序(见鬼,我读这段代码的水平很差,我甚至找不到它实际所在的行更改:));但我想问问社区,以确保:是否有其他方法可以设置这样的处理程序 - 也许通过使用一些外部包?(这是我在这篇文章中使用标签“包”的借口)

最后,我还尝试了一些小技巧来替换\inputlinenoLatex 中的;考虑这个微小的 MWE(例如test.tex):

\documentclass{article}

\let\oldinputlineno\inputlineno
\def\inputlineno{\oldinputlineno; MEANING: \meaning~}

\begin{document}
  \title{Test title}
  \author{test}
  \maketitle
\end{document}

如果我们运行它,我们会得到:

$ pdflatex test.tex && grep -r MEANING test.log 
This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011)
...
Transcript written on test.log.
LaTeX Font Info:    ... okay on input line 13; MEANING: macro:->\nobreakspace {
LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 13; MEANING:
LaTeX Font Info:    ... okay on input line 13; MEANING: macro:->\nobreakspace {
(Font)              <12> on input line 18; MEANING: macro:->nobreakspace {}.
(Font)              <8> on input line 18; MEANING: macro:->nobreakspace {}.
(Font)              <6> on input line 18; MEANING: macro:->nobreakspace {}.

...这意味着,我们可以在某种程度上进行挂钩\inputlineno- 但只有当它作为宏被调用/执行时才会有所不同 - 这通常(显然)发生在\typeout上下文中,通过使用\the\inputlineno。相反,我想要的是“回调”每次\inputlineno改变其值时运行(即,当正在处理新的源代码行时)。

有没有什么办法可以做到这一点(主要是pdflatex)?

答案1

使用 pdfTeX 或 XeTeX 时,您无法挂接代码来检测何时\inputlineno发生更改。它只是一个只读整数参数,在用户无法访问的程序部分中更新。

也许reader第 4.1.2.1.1 节中描述的 LuaTeX 函数可能对该引擎有帮助。

相关内容