简单的问题。我有两个宏用于显示星期几的缩写,例如 MWF 或 TR。我不确定为什么我的 MWE 中的第一个宏会失败而第二个宏可以工作。我更希望第一个宏之类的东西可以工作,因为它更短。
\documentclass{article}
\usepackage{stix2}
\usepackage{suffix}
\WithSuffix\newcommand\textsc*[1]{%
\textsc{\MakeLowercase{#1}}%
}
\usepackage{tikz}
\newcommand{\Repeat}[2]{%\repeat already used
\foreach \n in {1,...,#1}{#2}%
}
\usepackage{xstring}
%\newcommand{\weekdays}[1]{%doesn't work
% \textsc*{%
% \IfSubStr{#1}{1}{N}{}%Sunday
% \IfSubStr{#1}{2}{M}{}%Monday
% \IfSubStr{#1}{3}{T}{}%Tuesday
% \IfSubStr{#1}{4}{W}{}%Wednesday
% \IfSubStr{#1}{5}{R}{}%Thursday
% \IfSubStr{#1}{6}{F}{}%Friday
% \IfSubStr{#1}{7}{S}{}%Saturday
% }%
%}
\newcommand{\weekdays}[1]{%
\IfSubStr{#1}{1}{\textsc*{N}}{}%Sunday
\IfSubStr{#1}{2}{\textsc*{M}}{}%Monday
\IfSubStr{#1}{3}{\textsc*{T}}{}%Tuesday
\IfSubStr{#1}{4}{\textsc*{W}}{}%Wednesday
\IfSubStr{#1}{5}{\textsc*{R}}{}%Thursday
\IfSubStr{#1}{6}{\textsc*{F}}{}%Friday
\IfSubStr{#1}{7}{\textsc*{S}}{}%Saturday
}
\begin{document}
\weekdays{246}\quad\weekdays{35}
\Repeat{7}{\par\weekdays{\n}}
\end{document}
答案1
我不确定为什么\MakeLowercase
在定义中使用小写字母会使事情变得复杂。
无论如何,xstring
命令是不可扩展的,这就是您遇到的问题。
它也许可以通过 来解决xstring
,但还有更好的方法。
\documentclass{article}
\usepackage{stix2}
\usepackage{tikz}
\newcommand{\Repeat}[2]{%\repeat already used
\foreach \n in {1,...,#1}{#2}%
}
\ExplSyntaxOn
\NewDocumentCommand{\textsmallcaps}{m}
{
\textsc { \text_lowercase:n { #1 } }
}
\NewExpandableDocumentCommand{\weekdayinitial}{m}
{
\exp_args:Ne \str_map_function:nN { #1 } \egreg_weekday:n
}
\cs_new:Nn \egreg_weekday:n
{
\str_case:nn { #1 }
{
{1}{N}
{2}{M}
{3}{T}
{4}{W}
{5}{R}
{6}{F}
{7}{S}
}
}
\NewDocumentCommand{\weekdays}{m}
{
\textsmallcaps { \weekdayinitial { #1 } }
}
\ExplSyntaxOff
\begin{document}
\weekdays{246}\quad\weekdays{35}
\Repeat{7}{\par\weekdays{\n}}
\end{document}
我不会用suffix
。
答案2
内部通过不可扩展的方式\textsc*
\MakeLowercase
进行完全扩展。 您可以使用它来防止扩展。\protected@edef
\IfSubStr
\unexpanded
\documentclass{article}
\usepackage{stix2}
\usepackage{suffix}
\WithSuffix\newcommand\textsc*[1]{%
\textsc{\MakeLowercase{#1}}%
}
\usepackage{tikz}
\newcommand{\Repeat}[2]{%\repeat already used
\foreach \n in {1,...,#1}{#2}%
}
\usepackage{xstring}
\DeclareRobustCommand{\weekdays}[1]{%
\textsc*{%
\unexpanded{%
\IfSubStr{#1}{1}{N}{}%Sunday
\IfSubStr{#1}{2}{M}{}%Monday
\IfSubStr{#1}{3}{T}{}%Tuesday
\IfSubStr{#1}{4}{W}{}%Wednesday
\IfSubStr{#1}{5}{R}{}%Thursday
\IfSubStr{#1}{6}{F}{}%Friday
\IfSubStr{#1}{7}{S}{}%Saturday
}%
}%
}
\begin{document}
\weekdays{246}\quad\weekdays{35}
\Repeat{7}{\par\weekdays{\n}}
\end{document}
这样,参数的扩展就被延迟到小写之后。小写完成后,\IfSubStr
将执行 - 指令。\IfSubStr
还会完全扩展参数。
但是,如果将参数小写,则在小写过程中会阻止其扩展,传递\csname..\endcsname
在某个阶段扩展会产生数字序列的 - 表达式可能会出现问题,因为小写可能会改变和之间的内容\csname
,\endcsname
从而可能会改变从 - 表达式形成的控制序列标记\csname...\endcsname
。
所以解决egreg问题是更喜欢。
或者,您也可以使用\noexpand
它来仅防止令牌的扩展\IfSubStr
。
\documentclass{article}
\usepackage{stix2}
\usepackage{suffix}
\WithSuffix\newcommand\textsc*[1]{%
\textsc{\MakeLowercase{#1}}%
}
\usepackage{tikz}
\newcommand{\Repeat}[2]{%\repeat already used
\foreach \n in {1,...,#1}{#2}%
}
\usepackage{xstring}
\DeclareRobustCommand{\weekdays}[1]{%
\textsc*{%
\noexpand\IfSubStr{#1}{1}{N}{}%Sunday
\noexpand\IfSubStr{#1}{2}{M}{}%Monday
\noexpand\IfSubStr{#1}{3}{T}{}%Tuesday
\noexpand\IfSubStr{#1}{4}{W}{}%Wednesday
\noexpand\IfSubStr{#1}{5}{R}{}%Thursday
\noexpand\IfSubStr{#1}{6}{F}{}%Friday
\noexpand\IfSubStr{#1}{7}{S}{}%Saturday
}%
}
\begin{document}
\weekdays{246}\quad\weekdays{35}
\Repeat{7}{\par\weekdays{\n}}
\par
\def\foobar{1357}
\weekdays{\foobar}
\end{document}
仍然不能阻止将参数小写,如果使用自定义\lccode
设置可能会导致意外结果。