
간단한 질문입니다. 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
With는 \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
또한 주장을 완전히 확장합니다. 그러나 소문자로 변환 하는
동안 확장이 방지되는 인수를 소문자로 변환 하면 일부 단계에서 확장이 숫자 시퀀스를 생성하는 -expression을 전달하는 것이 문제 \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
-settings를 사용하면 예상치 못한 결과가 발생할 수 있습니다.