kpfonts 与 environ 包和 \write 错误

kpfonts 与 environ 包和 \write 错误

最小工作示例

\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 的回答很好,但如果你表现良好 (:-) 并遵循了有关如何将\protected 命令写入文件的推荐做法,你就可以避免这个问题:也就是说,你必须将\protectequal 设置为\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手术中存活下来?它不是很强大吗?”。)

相关内容