我正在尝试使用解析 LaTeX 代码然后将函数值写入文件的问题示例来掌握 LaTeX3。
问题。生成一段 pdfLaTeX XML 文件,其中包含来自当前文件(文章标题、作者列表、摘要、关键词、参考文献列表等)的规范化(在 XML 中允许且有意义)LaTeX 变量。例如,规范化文本是其中\,
消失的文本,\&
被替换为&
、~
- 被
、--
- 被–
,字符串$x_2$
被替换为x<sub>2</sub>
、\emph{
... }
- 被<em>
...<em>
等等。由于我不需要将整篇文章转换为 XML,因此在我看来,只需使用标准 TeX 或 LaTeX3 函数将带有必要 XML 标签的行写入文件即可。我或多或少弄明白了中的正则表达式expl3
,但我无法将函数的值写入\normalize
文件。在这里,在最小工作示例中,我专注于我需要的一些非 XML 功能。我试图弄清楚如何将函数的值而不是函数的文本保存到文件中。
也就是说,在这种情况下,我希望在文件中获取我在屏幕上第一行看到的确切内容。为什么将值传递给函数不起作用\normalize
?
我将非常感激您提供解决方案和解释。“LATEX3 接口”对我来说仍然有点复杂,但我正在一点点地了解它。
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\tl_new:N \l_normalize_tl
\cs_new:Npn \normalize #1 {
\tl_set:Nn \l_normalize_tl {#1}
\regex_replace_all:nnN { \c{,} } { } \l_normalize_tl
\regex_replace_all:nnN { \c{&} } { \c{&}amp; } \l_normalize_tl
\regex_replace_all:nnN { \~ } { \c{&}nbsp; } \l_normalize_tl
\regex_replace_all:nnN { -- } { \c{&}ndash; } \l_normalize_tl
\regex_replace_all:nnN { \c{emph}\{(.*?)\} } { \c{textless} em\c{textgreater}\1\c{textless}/em\c{textgreater} } \l_normalize_tl
\tl_use:N \l_normalize_tl
}
\DeclareDocumentCommand\wout { m }
{ \iow_now:Nx \g_xml_out_iow { #1 } }
\DeclareDocumentCommand\writexml{ }
{
\iow_new:N \g_xml_out_iow
\iow_open:Nn \g_xml_out_iow { \c_sys_jobname_str.xml }
\wout{ \exp_not:V\normalize\teststring }
\iow_close:N \g_xml_out_iow
}
\ExplSyntaxOff
\begin{document}
\def\teststring{This is~-- a test document by \emph{A.\,A.~Smith}.}
\normalize{This is~-- a test document by \emph{A.\,A.~Smith}.}
\normalize\teststring
\writexml
\end{document}
我在 *.xml 文件中看到
\normalize This is\protect \unhbox \voidb@x \protect \penalty \@M \ {}-- a test document by \protect \unhbox \voidb@x \bgroup \edef .{A.\,A.~Smith}\let \futurelet \@let@token \let \protect \relax \itshape A.\protect \protect \leavevmode@ifvmode \kern +.16667em\relax A.\protect \unhbox \voidb@x \protect \penalty \@M \ {}Smith\egroup .
答案1
您要先进行规范化,然后再进行书写。
\documentclass{article}
\ExplSyntaxOn
\tl_new:N \l_crosfield_normalize_tl
\iow_new:N \g_xml_out_iow
\cs_generate_variant:Nn \iow_now:Nn { NV }
\cs_new_protected:Npn \crosfield_normalize:n #1
{
\tl_set:Nn \l_crosfield_normalize_tl {#1}
\regex_replace_all:nnN { \c{,} } { } \l_crosfield_normalize_tl
\regex_replace_all:nnN { \c{&} } { & } \l_crosfield_normalize_tl
\regex_replace_all:nnN { \~ } { } \l_crosfield_normalize_tl
\regex_replace_all:nnN { -- } { – } \l_crosfield_normalize_tl
\regex_replace_all:nnN { \c{emph}\{(.*?)\} } { <em> \1 </em> } \l_crosfield_normalize_tl
}
\NewDocumentCommand\writexml{ m }
{
\iow_open:Nn \g_xml_out_iow { \c_sys_jobname_str.xml }
\crosfield_normalize:n { #1 }
\iow_now:NV \g_xml_out_iow \l_crosfield_normalize_tl
\iow_close:N \g_xml_out_iow
}
\ExplSyntaxOff
\begin{document}
\writexml{This is~-- a test document by \emph{A.\,A.~Smith}.}
\end{document}
你不想\iow_now:Nx
,因为\textless
没有扩展为并且 或也<
类似。只需使用所需的字符即可。\&
\textless
该文件的内容xml
是
This is – a test document by <em>A.A. Smith</em>.
如果您希望能够使用“变量”:
\documentclass{article}
\ExplSyntaxOn
\tl_new:N \l_crosfield_normalize_tl
\iow_new:N \g_xml_out_iow
\cs_generate_variant:Nn \iow_now:Nn { NV }
\cs_new_protected:Npn \crosfield_normalize:n #1
{
\tl_set:Nn \l_crosfield_normalize_tl {#1}
\regex_replace_all:nnN { \c{,} } { } \l_crosfield_normalize_tl
\regex_replace_all:nnN { \c{&} } { & } \l_crosfield_normalize_tl
\regex_replace_all:nnN { \~ } { } \l_crosfield_normalize_tl
\regex_replace_all:nnN { -- } { – } \l_crosfield_normalize_tl
\regex_replace_all:nnN { \c{emph}\{(.*?)\} } { <em> \1 </em> } \l_crosfield_normalize_tl
}
\cs_generate_variant:Nn \crosfield_normalize:n { e }
\NewDocumentCommand\writexml{ m }
{
\iow_open:Nn \g_xml_out_iow { \c_sys_jobname_str.xml }
\crosfield_normalize:e { \text_expand:n { #1 } }
\iow_now:NV \g_xml_out_iow \l_crosfield_normalize_tl
\iow_close:N \g_xml_out_iow
}
\ExplSyntaxOff
\begin{document}
\newcommand\test{This is~-- a test document by \emph{A.\,A.~Smith}.}
\writexml{\test}
\end{document}
输出是一样的。