
Eu gostaria de criarum comando que verifica se uma expressão é totalmente expansível e trava se não(idealmente imprimindo uma mensagem de erro). Eu gostaria de fazer aquilosem um mecanismo TeX específico em mente. Eu acho que está relacionado a esta questãoVerifique se a macro é totalmente expansível, mas a resposta fornecida requer LuaTeX.
Código de teste
Um código de teste ficaria assim:
\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xparse}
\usepackage{xstring}
\NewDocumentCommand{\checkexpandability}{m}{
% CODE HERE
}
\newcommand{\expandable}[1]{#1}
\newcommand{\notexpandable}[1]{%
\edef\myvariable{\expandable{#1}}%
\myvariable%
}
\begin{document}
\checkexpandability{\expandable{test}} % Should be OK
\checkexpandability{\notexpandable{test}} % Should CRASH
\checkexpandability{\IfBeginWith{string}{str}{true}{false}} % Should CRASH
\end{document}
Caso seja muito complicado
Se não for possível, posso modificar a assinatura do comando para incluir um parâmetro para o qual o comando deve se expandir:
\begin{document}
\checkexpandability{\expandable{test}}{test} % Should be OK
\checkexpandability{\notexpandable{test}}{test} % Should CRASH
\checkexpandability{\IfBeginWith{string}{str}{true}{false}}{true} % Should CRASH
\end{document}
Comente sobre expansibilidade
Como a definição de totalmente expansível não é tão clara quanto se poderia imaginar (veja o comentário abaixo), o contexto desta questão é que estou apenas tentando criar algo que me ajude a depurar algum código. Posso restringir a questão a este comportamento específico: se a macro funcionaria nas macros de contexto como o \color
comando:
\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xcolor}
\newcommand{\expandable}[1]{#1}
\newcommand{\notexpandable}[1]{%
\edef\myvariable{\expandable{#1}}%
\myvariable%
}
\begin{document}
\color{\expandable{blue}} % OK
\color{\notexpandable{red}} % CRASHES
X
\end{document}
Basicamente, o \color
comando faz o tipo de trabalho que procuro, só que gostaria de chamá-lo \checkexpandability
, ser um pouco mais genérico e imprimir uma bela mensagem de erro.
Responder1
Acho que o mal-entendido básico é
Basicamente, o
\color
comando faz o tipo de trabalho que procuro,
O \color
comando não faz verificações do tipo solicitado, simplesmente espera que após a expansão o argumento seja um nome de cor definido. Se a expansão falhar, você receberá um erro de baixo nível ou se ela se expandir para uma cor indefinida, você receberá uma mensagem de erro específica, mas nenhuma parte do processamento é genérica ou se aplica a um comando diferente dos comandos que esperam cores.
A única versão que pode ser implementada é a versão com uma expansão esperada, pois simplesmente pergunta se os dois argumentos são iguais após a expansão. A camada de programação L3 tem diversas variantes disso ou você pode usar o ifthen
pacote e
\ifthenelse{\equal{\expandable{test}}{test}}{yes}{no}
que retornará sim se os argumentos se expandirem para a mesma coisa, não se não o fizerem, ou fornecerá um erro de baixo nível se o argumento não for seguro em um contexto de expansão (que é o que normalmente significa "não é expansível")
Responder2
Para depurar seu código, eu usaria apenas \typeout
.
\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xcolor}
\newcommand{\expandable}[1]{#1}
\newcommand{\notexpandable}[1]{%
\edef\myvariable{\expandable{#1}}%
\myvariable%
}
\begin{document}
\typeout{\expandable{blue}} % OK, print "blue"
\typeout{\notexpandable{red}} % CRASHES
X
\end{document}
A questão é que \typeout
expandirá totalmente seu argumento e, em seguida, imprimirá qualquer resultado totalmente expandido no terminal --- para que você possa apenas dar uma olhada no terminal.
Para o primeiro caso ele imprime blue
, então está tudo bem. No segundo caso, ele trava.
Claro, existem dois problemas com a abordagem acima.
Ainda que
\expandable{blue}
étotalmente expansível (seja lá o que isso signifique),pode não ser o caso que\color
garanta a expansão total do seu argumento antes de interpretar o resultado como uma cor. (acho que porLei de Hyrumseria praticamente para evitar a quebra de "pacotes existentes".)Então, se você quiser ter mais certeza, é melhor expandi-lo antecipadamente usando, por exemplo
\ExpandArgs
.As informações sobre o código da categoria, bem como qualquer caractere especial oculto no código (por exemplo, espaço versus tabulação), são perdidas.
Na prática isso não importaria muito, mas às vezes importa. (por exemplo, quando você tenta depurar algum pacote que tenta capturar o corpo do ambiente literalmente)
Se for esse o caso, considere experimentarMeu pacote. (o código está uma bagunça agora, mas funciona bem, e existem pacotes com código-fonte pior por aí)