如何从另一个命令的“返回值”中获取第一个字符?

如何从另一个命令的“返回值”中获取第一个字符?

尝试找到解决方案如何在宏组合中设置字距,并在其间设置固定字符,我遇到了一个相关的问题:当用作上标(在脚注标记中)时,某些字符会太靠近主角,例如 o 和上标 j 这样的组合。

为了解决这两个问题,我想创建一个函数,根据标记的“字符串值”的第一个字符返回字距调整值。

我的第一个尝试是简单地使用\tl_head:n,然后我读将字符串转换为标记列表?– 两者给出的结果相同,但不是所需的结果。

\documentclass{book}

\usepackage{refcount}
\usepackage{xstring}
\usepackage{xparse}
\usepackage{expl3}

\ExplSyntaxOn
\makeatletter
\DeclareDocumentCommand \aalph {m}
 {
  \IfInteger { #1 }
   {
    \myAlph:n { #1 }
   }{
    \@ifundefined { r@#1 }
     { yyyy }
     {
      \IfInteger { \getrefnumber { #1 } }
       { \myAlph:n { \getrefnumber { #1 } } }
       { zzzz }
     }
   }
 }

\cs_new_protected:Npn \myAlph:n #1
 {
  \int_to_alph:n { #1 }
 }

\DeclareDocumentCommand \alphKern {m}
 {
  \l_alphKern:n { #1 }
 }

\cs_new:Npn \l_alphKern:n #1
 {
  \str_clear_new:N \l_alph_str
  \tl_clear_new:N \l_tmp_tl

  \str_set:Nn \l_alph_str { \aalph { #1 } }

  \tl_set_rescan:Nno \l_tmp_tl { } { \l_alph_str }

  \tl_head:n \l_tmp_tl
 }
\ExplSyntaxOff

\newcounter{test}

\begin{document}

\setcounter{test}{1}
>\aalph{\thetest}<>\alphKern{\thetest}< (exp.: >a<>a<)\\

>\aalph{27}<>\alphKern{27}< (exp.: >aa<>a<)\\

>\aalph{53}<>\alphKern{53}< (exp.: >ba<>b<)\\

>\aalph{283}<>\alphKern{283}< (exp.: >jw<>j<)\\

\end{document}

结果:

>a<>a< (exp.: >a<>a<)
>aa<>aa< (exp.: >aa<>a<)
>ba<>ba< (exp.: >ba<>b<)
>jw<>jw< (exp.: >jw<>j<)

我可能忽略了一些非常明显的事情——任何帮助都值得感激!

(PS:对于这个,我正在使用 XeTeX,由于项目即将完成,我无法换用其他任何东西)

答案1

(接问题评论)

关键点在于\str_set:Nn \l_alph_str { \aalph { #1 } }你需要确保\aalph { #1 }是完全可扩展的,然后使用\str_set:Ne将扩展结果转换为字符串并将其存储在中\l_alph_str

假设您可以\IfInteger通过其他(完全可扩展的)方式避免,以下示例显示了一种尝试:

\documentclass{book}

\usepackage{refcount}
\usepackage{xstring}
\usepackage{xparse}

\ExplSyntaxOn
\makeatletter
% make \aalph itself expandable
\DeclareExpandableDocumentCommand \aalph {m}
 {
%  \IfInteger { #1 }
%   {
    \myAlph:n { #1 }
%   }{
%    \@ifundefined { r@#1 }
%     { yyyy }
%     {
%      \IfInteger { \getrefnumber { #1 } }
%       { \myAlph:n { \getrefnumber { #1 } } }
%       { zzzz }
%     }
%   }
 }

% do not use protected version
\cs_new:Npn \myAlph:n #1
 {
  \int_to_alph:n { #1 }
 }

\DeclareDocumentCommand \alphKern {m}
 {
  \l_alphKern:n { #1 }
 }

\cs_new:Npn \l_alphKern:n #1
 {
  \str_clear_new:N \l_alph_str
  \tl_clear_new:N \l_tmp_tl

  % use \str_set:Ne to fully expand its 2nd arg before converting to string
  \str_set:Ne \l_alph_str { \aalph { #1 } }

  \tl_set_rescan:Nno \l_tmp_tl { } { \l_alph_str }

  % here you need arg-spec "N", not "n"
  \tl_head:N \l_tmp_tl
 }

% this defines \str_set:Ne
\cs_generate_variant:Nn \str_set:Nn {Ne}
\ExplSyntaxOff

\newcounter{test}

\begin{document}

\setcounter{test}{1}
>\aalph{\thetest}<>\alphKern{\thetest}< (exp.: >a<>a<)\\

>\aalph{27}<>\alphKern{27}< (exp.: >aa<>a<)\\

>\aalph{53}<>\alphKern{53}< (exp.: >ba<>b<)\\

>\aalph{283}<>\alphKern{283}< (exp.: >jw<>j<)\\

\end{document}

笔记:

  • xparse已经加载,expl3所以我删除了\usepacakge{expl3}。此外,自 LaTeX2e 2020/02/02 以来,(很大一部分)expl3已以 LaTeX2e 格式预加载。
  • 完全可扩展的 LaTeX3 函数在文档中以星号 (⭑) 表示interface3,如同一文档第 I.2 节所述。但大多数其他软件包没有关于可扩展性的每个宏的文档,因此您需要自行检查。

相关内容