如何在保留 synctex 数据的同时捕获并重新扫描 TeX 源代码?

如何在保留 synctex 数据的同时捕获并重新扫描 TeX 源代码?

这个问题导致了一个新的方案的出现:
rescansync

假设我想用...替换a某一部分中的所有内容(源代码中,而不是渲染的输出)b

%! TEX program = lualatex
\documentclass{article}
\usepackage{filecontentsdef}
\begin{document}
\begin{filecontentsdefmacro}{\zzz}
abc

abc

abc
\end{filecontentsdefmacro}
\ExplSyntaxOn
\regex_replace_all:nnN {a} {b} \zzz
\ExplSyntaxOff
\filecontentsexec\zzz
\end{document}

它可以工作,但是 synctex 数据丢失(它指向整个块,而不是单个段落/行)

我怎样才能保留 synctex 数据?

仅使用 LuaTeX 的解决方案就可以了。

答案1

有一种方法。有关文档,请参阅texdoc luatextexdoc ltluatex(以及正在导入的包)。

缺点:需要写入真实的外部文件(不是\scantokens

!!在代码中搜索重要部分。(请注意,使用的directlua是 而不是luacode*,因此请小心使用 catcode)

%! TEX program = lualatex
\documentclass{article}
\usepackage{currfile} % !! need this package for currfilename to be defined
\begin{document}

% write the content to a separate file
\directlua{magic_offset=1 inputlineno_offset=tex.inputlineno+magic_offset} % !!
\begin{filecontents*}[overwrite]{b.tex}
\typeout{1}
abc

abc

abc
\typeout{2}
\end{filecontents*}

% it's also possible to typeset something between the "write" part and the "rescan" part
first line

\directlua{ --[[ !! ]]
saved_synctex_tag=tex.get_synctex_tag()
function handler()
    if token.get_macro("currfilename")=="b.tex" and tex.get_synctex_tag()>0 then
        if not (saved_synctex_tag==nil) then
            tex.set_synctex_tag(saved_synctex_tag)
            saved_synctex_tag=nil
        end
        tex.set_synctex_line(tex.inputlineno+inputlineno_offset)
    end
end
tex.set_synctex_mode(2)
luatexbase.add_to_callback('process_input_buffer', handler, "synctex patch callback")
}\input{b.tex}\directlua{luatexbase.remove_from_callback('process_input_buffer', "synctex patch callback") tex.set_synctex_mode(0) tex.set_synctex_line(0) }

last line

last line
\end{document}

请注意,由于某些奇怪的原因,如果[abspath]提供了选项来currfile打包,则处理程序将被调用多次tex.get_synctex_tag()==0

因此添加了检查以便它只被调用一次,但针对实际文件。

(我猜是因为原始的仅扩展命令\input或者别的什么)

删除saved_synctex_tag=nil线;或者get_macro("currfilename")=="b.tex"检查会使事情变得更糟,因为(我认为,未测试) 如果 b.tex 包含 egctex,则set_synctex_line不应运行c.tex

回调的替代方法是,在输入文件本身内设置标签总是有效的。

相关内容