扩展xeCJK中的条件函数

扩展xeCJK中的条件函数

我现在正在写论文模板,需要更改目录行的格式。我使用以下代码来实现:

% !TeX program  = XeLaTeX
\documentclass{ctexart}
% `\xeCJK_family_if_exist:nTF` will return true if `kai` is defined.
\setCJKfamilyfont{kai}{KaiTi}

\ExplSyntaxOn

\cs_new:Nn \__foo_font_kai:
  {
    \xeCJK_family_if_exist:nTF { kai }
      { \CJKfamily{kai} } { \itshape }
  }

% Set the toc line format.
\keys_set:nn { ctex }
  {
    section / tocline = { \__foo_font_kai: \CTEXnumberline { #1 } #2 }
  }

\ExplSyntaxOff

\begin{document}
\tableofcontents
\section{Title 标题}
\end{document}

问题是\__foo_font_kai:无法正确扩展,因此在 .toc 文件中我可以找到

\contentsline {section}{\xeCJK _family_if_exist:nTF {kai}{\CJKfamily {kai}}{\itshape }\numberline {1}Title 标题}{1}

如果第二次编译以获取正确的toc,则会出现错误:

! Undefined control sequence.
<argument> \xeCJK 
                  _family_if_exist:nTF {kai}{\CJKfamily {kai}}{\itshape }\nu...
l.1 ...y {kai}}{\itshape }\numberline {1}Title}{1}

? 

我的解决方案是定义另一个“文档命令”:

\DeclareDocumentCommand \foofontkai {} { \__foo_font_kai: }

然后 toc 文件将是

\contentsline {section}{\foofontkai \numberline {1}Title 标题}{1}

可以正确编译。

但我不希望它成为用户命令(或保留名称\__foo_font_kai:),所以我该怎么办?

我希望 toc 文件可以像

\contentsline {section}{\CJKfamily{kai} \numberline {1}Title 标题}{1}

相关问题:在 LaTeX3 中扩展条件函数

答案1

这对 OP 来说可能太晚了,但只能解决一个未解答的问题。

解决方案:

\keys_set:nn { ctex }
  {
    section / tocline = {
      \protect \csname __foo_font_kai: \protect \endcsname
      \CTEXnumberline { #1 } #2 }
  }

这写道

\contentsline {section}{\csname __foo_font_kai:\endcsname \numberline {1}Title 标题}{1}

归档.toc

解释:

.toc加载文件时,@是唯一一个 catcode (本地)设置为字母的特殊字符。但 latex3 命令要求和都_具有:catcode 字母。可以使用 来避免这种情况\csname __foo_font_kai: \endcsname

但是,由于 option 的值在写入 之前section/tocline被扩展了两次(使用\protectlet to ) ,因此和各自都需要一个额外的值。\@unexpandable@protect.toc\protect\csname\endcsname

这导致了解决方案。在 latex3 中\protect \csname __foo_font_kai: \protect \endcsname没有等价的,并且不能被替代,因为这样它们每个都需要保护,所以最终结果也是如此。\protect\csname/\endcsname\cs:w/\cs_end:\csname ... \endcsname\protect \csname __foo_font_kai: \protect \endcsname

进一步讨论:输入时将_和都更改:为 catcode 字母(内部)将禁止用户输入诸如 之类的内容。\@starttoc.toc\section{$\alpha_2$}

答案2

只需定义一个用户级别受保护的命令:

% !TeX program  = XeLaTeX
\documentclass{ctexart}
% `\xeCJK_family_if_exist:nTF` will return true if `kai` is defined.
%\setCJKfamilyfont{kai}{KaiTi}

\ExplSyntaxOn

\cs_new_protected:Npn \foofontkai
  {
    \xeCJK_family_if_exist:nTF { kai }
      { \CJKfamily{kai} } { \itshape }
  }

% Set the toc line format.
\keys_set:nn { ctex }
  {
    section / tocline = { \foofontkai \CTEXnumberline { #1 } #2 }
  }

\ExplSyntaxOff

\begin{document}
\tableofcontents
\section{Title 标题}
\end{document}

相关内容