使用 lualatex 写入自定义输出文件:挂钩写入过程的开始并替换不完全可扩展的宏

使用 lualatex 写入自定义输出文件:挂钩写入过程的开始并替换不完全可扩展的宏

我正在编写包含信息的文档,这些信息在每一部分的末尾都有总结。为了避免重复编写,我习惯datatool在运行时创建“缓冲区”,当我需要时,可以从中再次检索和重新打印信息。

现在我还面临着将这些“缓冲区”的内容输出datatool到自定义文件的要求。从这个问题的先前问题(构造得不好,我要求删除它)的信息中,我知道有些命令无法完全展开。由于我使用 LuaLaTeX 进行排版,我想知道是否可以以某种方式挂接到写入过程(使用适当的回调)并用可扩展的变体替换不可扩展的命令(或将它们从“要写入文件的缓冲区”中删除)。

这些命令具体包括:\textbftextit(从写入文件中删除)、\gls从词汇表(检索缩写)以及pevnaMezera从回调中删除函数。这也会将垃圾写入文件。最后一部分我在第 25 行和第 27 行尝试过,但没有成功。

所以我的问题是:有没有办法(使用 LuaTeX 或 TeX 工具)挂接到文件写入过程并以某种方式预处理要写入文件的标记缓冲区,使得一些命令将完全扩展,而不可扩展的命令将被合适的替代方案替换?

MWE(有点长):

\documentclass [a4paper, 11pt, twoside, openright, czech]{scrbook}

\usepackage [czech,shorthands=off] {babel}                          
\usepackage{fontspec}

\usepackage{csquotes}

\usepackage{datatool}

\DTLnewdb{testdb}

\DTLaddcolumn{testdb}{system}
\DTLaddcolumn{testdb}{dotaz}

\newwrite\testdboutput
\immediate\openout\testdboutput=objections.txt

\newcommand{\objection}[2]{%
#2
\DTLnewrow{testdb}
\DTLnewdbentry{testdb}{status}{#1}
\DTLnewdbentry{testdb}{text}{#2}
\ifboolexpr{ test {\ifstrequal{1}{#1}}}%
{%TRUE
%\begin{stopcallback}
\immediate\write\testdboutput{#2}
%\end{stopcallback}
}%
{%FALSE
\relax%
}%
}

\usepackage{luacode}

\begin{luacode}
function pevnaMezera(s)
  s = string.gsub(s, " a ", " a~")
  return s
end

function startcallback()
luatexbase.add_to_callback("process_input_buffer", pevnaMezera , "pevnaMezera" )
end

function stopcallback()
   luatexbase.remove_from_callback("process_input_buffer", "pevnaMezera" )
end
\end{luacode}

\newenvironment{stopcallback}{\directlua{stopcallback()}}{\directlua{startcallback()}}

\AtBeginDocument{%
  \directlua{luatexbase.add_to_callback(
  "process_input_buffer", pevnaMezera , "pevnaMezera" )}
}

\usepackage{varioref}
\usepackage[pdfencoding=auto]{hyperref}
\usepackage{cleveref}

\usepackage[xindy={language=czech, codepage=utf8}, automake, nomain, abbreviations,% create "abbreviations" glossary
                    stylemods=longbooktabs% do the adjustments for the longbooktabs styles
                    ]{glossaries-extra}                     

\setabbreviationstyle{long-short}

\newacronym{hr}{HR}{health report}

\makeglossaries

\begin{document}
\section{First section}
\label{sec:first}

\objection{2}{Test objection not output in output file - objections.txt}

\objection{1}{Test objection; should be output into - objections.txt}

\clearpage

\section{Second section}

\objection{1}{Test objection with a abbreviation \gls{hr} and quotation \enquote{marks}. There are also some citations created with custom citation command.}

%\objection{1}{I found out, that using \textit{italics} and referencing \pageref{sec:first} exceeds tex capacity. Why?The objections contain those too.}

\closeout\testdboutput
\end{document}

编辑: 在搜索 LuaTeX 文档后,我发现了回调函数process_output_buffer,它可以处理 TeX 输出的文件(除了.log),这可以帮助我解决这个问题。但是,如果还有任何解决方案可以让我更接近发送到页面的字母的状态,我会非常高兴知道。

我还根据评论更改了 MWE(如下)。添加unexpanded有助于我处理输出文件以删除命令并以 的方式替换它们str.gsub;但它比(不知何故)只将实际的字母发送到 更手动.pdf

编辑的MWE:

\documentclass [a4paper, 11pt, twoside, openright, czech]{scrbook}

\usepackage [czech,shorthands=off] {babel}                          
\usepackage{fontspec}

\usepackage{csquotes}

\usepackage{datatool}

\DTLnewdb{testdb}

\DTLaddcolumn{testdb}{system}
\DTLaddcolumn{testdb}{dotaz}

\newwrite\testdboutput
\immediate\openout\testdboutput=objections.txt

\newcommand{\objection}[2]{%
#2
\DTLnewrow{testdb}
\DTLnewdbentry{testdb}{status}{#1}
\DTLnewdbentry{testdb}{text}{#2}
\ifboolexpr{ test {\ifstrequal{1}{#1}}}%
{%TRUE
\immediate\write\testdboutput{\unexpanded{#2}}
}%
{%FALSE
\relax%
}%
}

\usepackage{luacode}

\begin{luacode}
function pevnaMezera(s)
  s = string.gsub(s, " a ", " a~")
  return s
end

function stripoutput(s)
  s = string.gsub(s, "~", " ")
  return s
end

function startcallback()
luatexbase.add_to_callback("process_input_buffer", pevnaMezera , "pevnaMezera" )
end

function stopcallback()
   luatexbase.remove_from_callback("process_input_buffer", "pevnaMezera" )
end
\end{luacode}

\newenvironment{stopcallback}{\directlua{stopcallback()}}{\directlua{startcallback()}}

\AtBeginDocument{%
  \directlua{luatexbase.add_to_callback(
  "process_input_buffer", pevnaMezera , "pevnaMezera" )}
    \directlua{luatexbase.add_to_callback(
  "process_output_buffer", stripoutput , "stripoutput" )}
}

\usepackage{varioref}
\usepackage[pdfencoding=auto]{hyperref}
\usepackage{cleveref}

\usepackage[xindy={language=czech, codepage=utf8}, automake, nomain, abbreviations,% create "abbreviations" glossary
                    stylemods=longbooktabs% do the adjustments for the longbooktabs styles
                    ]{glossaries-extra}                     

\setabbreviationstyle{long-short}

\newacronym{hr}{HR}{health report}

\makeglossaries

\begin{document}
\section{First section}
\label{sec:first}

\objection{2}{Test objection not output in output file - objections.txt}

\objection{1}{Test objection; should be output into - objections.txt}

\clearpage

\section{Second section}

\objection{1}{Test objection with a abbreviation \gls{hr} and quotation \enquote{marks}. There are also some a citations created with custom citation command.}%druhé ``a'' je na konci řádku

%\objection{1}{I found out, that using \textit{italics} and referencing \pageref{sec:first} exceeds tex capacity. Why?The objections contain those too.}

\closeout\testdboutput
\end{document}

相关内容