最小工作示例
\documentclass{article}
\usepackage{kpfonts}
\usepackage{environ}
\makeatletter
\AtBeginDocument{%
\begingroup
\newwrite\@bibmeta
\immediate\openout\@bibmeta=\jobname.meta-bib\relax
\endgroup
}
\NewEnviron{wwwabstract}{%
\begin{abstract}
\BODY
\end{abstract}
\immediate\write\@bibmeta{abstract = {\BODY},}
}
\makeatother
\begin{document}
\begin{wwwabstract}
Test $R_1^2$
\end{wwwabstract}
\end{document}
编译成功。
最小非工作示例
\documentclass{article}
\usepackage{kpfonts}
\usepackage{environ}
\makeatletter
\AtBeginDocument{%
\begingroup
\newwrite\@bibmeta
\immediate\openout\@bibmeta=\jobname.meta-bib\relax
\endgroup
}
\NewEnviron{wwwabstract}{%
\begin{abstract}
\BODY
\end{abstract}
\immediate\write\@bibmeta{abstract = {\BODY},}
}
\makeatother
\begin{document}
\begin{wwwabstract}
Test $\mathbf{R}_1^2$
\end{wwwabstract}
\end{document}
日志文件中出现以下错误:
LaTeX Font Info: Try loading font information for U+jkpsyb on input line 24.
(/usr/share/texmf-dist/tex/latex/kpfonts/ujkpsyb.fd
File: ujkpsyb.fd 2006/08/15 v1.0
)
LaTeX Font Info: Try loading font information for U+jkpsyc on input line 24.
(/usr/share/texmf-dist/tex/latex/kpfonts/ujkpsyc.fd
File: ujkpsyc.fd 2006/08/15 v1.0
)
! Undefined control sequence.
\GenericError ...
#4 \errhelp \@err@ ...
l.24 \end{wwwabstract}
? q
OK, entering \batchmode...
! Undefined control sequence.
\GenericError ...
\let \@err@ ...
l.24 \end{wwwabstract}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Undefined control sequence.
\GenericError ...
\@empty \def \MessageBreak...
l.24 \end{wwwabstract}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Undefined control sequence.
\GenericError ...
\endgroup
l.24 \end{wwwabstract}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
[1
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./test.aux) )
大约一个月前,相同的代码还可以运行。我想我确实更新了一些 TeXLive 软件包,但我不确定是什么出了问题。有什么想法吗?
答案1
kpfonts
与该问题无关。
问题在于存在诸如(它们无法存活)之类的命令,这里通过使第一级扩展\mathbf
不可扩展来解决。\write
\BODY
\documentclass{article}
%\usepackage{kpfonts}
\usepackage{environ}
\makeatletter
\newwrite\@bibmeta
\immediate\openout\@bibmeta=\jobname.meta-bib
\NewEnviron{wwwabstract}{%
\begin{abstract}
\BODY
\end{abstract}
\immediate\write\@bibmeta{abstract = {\unexpanded\expandafter{\BODY}},}
}
\makeatother
\begin{document}
\begin{wwwabstract}
Test $\mathbf{R}_1^2$
\end{wwwabstract}
\end{document}
周围的群体\newwrite
是\openout
没用的。没有必要\AtBeginDocument
。
一个更简单的解决方案是使用核函数,在这种情况下\protected@write
。不需要\immediate
,只要我们扩展\BODY
一个级别。
\documentclass{article}
%\usepackage{kpfonts}
\usepackage{environ}
\makeatletter
\newwrite\@bibmeta
\openout\@bibmeta=\jobname.meta-bib
\newcommand\abstract@write[1]{\protected@write\@bibmeta{}{abstract = {#1}}}
\NewEnviron{wwwabstract}{%
\begin{abstract}
\BODY
\end{abstract}
\expandafter\abstract@write\expandafter{\BODY}%
}
\makeatother
\begin{document}
\begin{wwwabstract}
Test $\mathbf{R}_1^2$
\end{wwwabstract}
\begin{wwwabstract}
Test $\mathbf{R}_1^3$
\end{wwwabstract}
\end{document}
该版本充分利用了根本不执行扩展expl3
的事实。\iow_now:Nn
\documentclass{article}
%\usepackage{kpfonts}
\usepackage{xparse,environ}
\ExplSyntaxOn
\NewEnviron{wwwabstract}
{
\begin{abstract}
\BODY
\end{abstract}
\wong_abstract_write:V \BODY
}
\iow_new:N \g_wong_abstract_stream
\iow_open:Nn \g_wong_abstract_stream { \c_sys_jobname_str.meta-bib }
\cs_new_protected:Nn \wong_abstract_write:n
{
\iow_now:Nn \g_wong_abstract_stream { #1 }
}
\cs_generate_variant:Nn \wong_abstract_write:n { V }
\ExplSyntaxOff
\begin{document}
\begin{wwwabstract}
Test $\mathbf{R}_1^2$
\end{wwwabstract}
\begin{wwwabstract}
Test $\mathbf{R}_1^3$
\end{wwwabstract}
\end{document}
答案2
当然,@egreg 的回答很好,但如果你表现良好 (:-) 并遵循了有关如何将\protect
ed 命令写入文件的推荐做法,你就可以避免这个问题:也就是说,你必须将\protect
equal 设置为\noexpand
或 设置为\@unexpandable@protect
。在这种情况下,我认为前者更合适。我还更喜欢在“ \begin{document}
-time”打开自定义文件并在文档末尾整齐地关闭它们:
\documentclass{article}
% \usepackage{kpfonts}
\usepackage{environ}
\makeatletter
\AtBeginDocument{%
\newwrite\@bibmeta
\immediate\openout\@bibmeta=\jobname.meta-bib\relax
}
\AtEndDocument{%
\immediate\closeout\@bibmeta
}
\NewEnviron{wwwabstract}{%
\begin{abstract}
\BODY
\end{abstract}
\let\protect=\noexpand
\immediate\write\@bibmeta{abstract = {\BODY},}
}
\makeatother
\newcommand*{\this}{this command}
\begin{document}
\begin{wwwabstract}
Test $\mathbf{R}_1^2$;
but let's say that you want to expand \this.
\end{wwwabstract}
\end{document}
此解决方案扩展了\BODY
宏,但健壮命令以自己的名称书写,后面跟空格。您可以自行决定是否仅阻止健壮命令的扩展(扩展所有其余命令,如此解决方案所示)或阻止整个宏的扩展\BODY
(如@egreg 的解决方案所示)。
(我写这个答案的主要原因是,读了@egreg 的答案后,有人可能会想“嘿,它怎么\mathbf
不能在\write
手术中存活下来?它不是很强大吗?”。)