我正在编写包含信息的文档,这些信息在每一部分的末尾都有总结。为了避免重复编写,我习惯datatool
在运行时创建“缓冲区”,当我需要时,可以从中再次检索和重新打印信息。
现在我还面临着将这些“缓冲区”的内容输出datatool
到自定义文件的要求。从这个问题的先前问题(构造得不好,我要求删除它)的信息中,我知道有些命令无法完全展开。由于我使用 LuaLaTeX 进行排版,我想知道是否可以以某种方式挂接到写入过程(使用适当的回调)并用可扩展的变体替换不可扩展的命令(或将它们从“要写入文件的缓冲区”中删除)。
这些命令具体包括:\textbf
和textit
(从写入文件中删除)、\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}