尝试找到解决方案如何在宏组合中设置字距,并在其间设置固定字符,我遇到了一个相关的问题:当用作上标(在脚注标记中)时,某些字符会太靠近主角,例如 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 节所述。但大多数其他软件包没有关于可扩展性的每个宏的文档,因此您需要自行检查。