
Pregunta simple. Tengo dos macros para mostrar días abreviados de la semana, como MWF o TR. No estoy seguro de por qué falla la primera macro de mi MWE mientras la segunda macro funciona. Preferiría que algo como la primera macro funcionara porque es más corta.
\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}
Respuesta1
No estoy seguro de por qué complicar las cosas \MakeLowercase
cuando puedes usar minúsculas en la definición.
De todos modos, xstring
los comandos no son ampliables y este es el problema que tienes.
Puede que se resuelva con xstring
, pero hay una manera mucho mejor.
\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}
Yo no usaría suffix
.
Respuesta2
Con \textsc*
\MakeLowercase
internamente se realiza una expansión completa \protected@edef
mientras que \IfSubStr
no es expandible.
Puede usarlo \unexpanded
para prevenir la expansión.
\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}
De esta manera, la ampliación del argumento se retrasa hasta después de ponerlo en minúsculas. Cuando se escriben minúsculas, \IfSubStr
se llevan a cabo las directivas -. \IfSubStr
también amplía completamente el argumento.
Pero al poner en minúsculas un argumento, cuya expansión se evita durante la escritura en minúsculas, pasar \csname..\endcsname
expresiones -cuya expansión en algún momento produce secuencias de dígitos puede ser un problema porque las minúsculas podrían cambiar lo que hay entre \csname
y \endcsname
y, por lo tanto, podría cambiar qué token de secuencia de control se forma a partir de la \csname...\endcsname
expresión - .
Por lo tantola solución de egreges preferir.
Alternativamente, puede utilizarlo únicamente \noexpand
para evitar la expansión del token \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}
Aún así, no se evita poner el argumento en minúsculas, lo que con \lccode
configuraciones personalizadas puede generar resultados inesperados.