Editar: Sobre a recompensa, estou feliz com a pergunta abaixo e esta recompensa é para essa pergunta. Eu não acho que posso aceitar melhor
Pesquisei um pouco sobre o uso de argumentos opcionais no LaTeX mas algumas coisas ainda não estão muito claras para mim.
Quando
Minha pergunta não é específica para comandos ou pacotes, mas para ambos.
Às vezes precisamos especificar um ou mais argumentos opcionais para um pacote ou comando. Podemos encontrar comandos como:
\Foo[OptArg1,OptArg2]{Arg1}{Arg2}
e gosto:
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
Pela primeira vez, vejo uma família com dois argumentos opcionais separados por vírgula. Para o segundo tenho duas famílias com um argumento opcional para cada uma.
Suponho que algo esteja diferente nessas duas formas, mas não entendi exatamente quando meu comando deve usar a primeira e quando deve usar a segunda.
Por exemplo, digamos que precisamos de um comando que use nosso primeiro argumento opcional para dividir o primeiro argumento não opcional em partes. Então prefiro a segunda forma porque na primeira minha vírgula como separador não será entendida (já é um separador). Mas eu ainda poderia usar um comando como:
\Foo[separator={,},OptArg2]{Arg1}{Arg2}
fazer a mesma coisa.
É claro que se eu quiser separar os argumentos opcionais da segunda família do meu jeito com \Foo[separator={//}][OptArg2//OptArg3] seria a única (ou pelo menos melhor) escolha porque tenho que definir o separador antes de ler os argumentos da segunda família.
Como
Além disso, às vezes o comando tem que se comportar de forma diferente se duas famílias forem dadas e diferente se uma for dada. Por exemplo, no exemplo acima, se o primeiro argumento não for fornecido, uma vírgula será usada para separar os argumentos opcionais da segunda família. Mas se for fornecido, então será usado como separador e o comando se comportará de forma diferente na leitura dos argumentos.
Nessas situações, acho que \def é uma opção mais geral para escrever o comando do que newcommand porque temos mais opções ao ler os argumentos. (\newcommand quebrará os segundos argumentos antes de ler o primeiro ou algo parecido. Considere também um ']' incluindo argumentos de segundas famílias...)
Minhas perguntas são:
- Quando (LaTeX padrão) devo usar a primeira forma e quando a segunda?
- \def é a única ou a melhor maneira de definir nossos comandos em situações gerais, como em situações em que ainda não sabemos a quantidade de argumentos ou em situações como a acima com o separador ou o ']' que já descrevi?
PS: Na segunda questão considere que quero que meu comando me permita, através da leitura do próximo caractere, lidar com muitas situações. (Por exemplo, quero ler os caracteres após o comando, um por um, e parar apenas se encontrar dois argumentos comuns ou o comando \stop etc. Não estou pedindo o código disso, apenas perguntando se \newcommand pode fazer isso - e é uma boa escolha- ou se \def for a única escolha)
Responder1
Sua pergunta mistura duas coisas distintas. LaTex2e tem argumentos opcionais []
e argumentos obrigatórios em {}
então
\Foo[OptArg1,OptArg2]{Arg1}{Arg2}
tem um argumento opcional e dois argumentos obrigatórios.
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
tem dois argumentos opcionais e dois argumentos obrigatórios.
A segunda questão é a lista separada por vírgulas, isso pode não fazer parte da sintaxe, apenas a vírgula é tratada como um caractere, por exemplo, depois
\newcommand\Foo[3][]{(#1)-(#2)(#3)}
então #1
seria OptArg1,OptArg2
, #2
seria Arg1
e #3
seria Arg2
e o resultado seria a composição
(OptArg1,OptArg2)-(Arg1)-(Arg2)
com as vírgulas sem nenhuma regra especial.
É claro que um comando pode fazer o que quiser com os argumentos e isso pode incluir iterar sobre as vírgulas. Existem facilidades no formato latex para isso ( \@for
) ou vários pacotes oferecem macros para analisar listas separadas por vírgulas. No entanto, isso é independente da detecção opcional de argumentos. No exemplo de sintaxe (legal)
\usepackage[foo,bar]{array,longtable}[2015/01/01 packages by you, me and someone]
existem dois argumentos opcionais e um argumento obrigatório, o primeiro argumento opcional e o obrigatório são posteriormente, como parte do processamento de \usepackage
, divididos em vírgulas. O segundo argumento opcional não é dividido em vírgulas, mas na verdade dividido em /
espaço para extrair a data do início do argumento.
Quanto à definição, se você tiver apenas um argumento opcional no início, você pode usar. \newcommand
Se você tiver dois ou mais, você também pode usar, \newcommand
mas precisa definir a macro em etapas, mas provavelmente é mais fácil de usar xparse
ou pacotes semelhantes para permitir um especificação mais simples e lida automaticamente com a definição das macros internas necessárias. No entanto, é melhor não ter muitos argumentos opcionais consecutivos, como se você tivesse
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
então OptArg1
não é realmente opcional se você precisar especificar OptArg2
. Uma sintaxe como
\Foo[opt1=a,opt2=b]{Arg1}
permite que cada opção seja omitida independentemente. Mas, novamente, essa análise chave=valor pode ser aplicada a qualquer sequência de tokens, seja um argumento obrigatório ou opcional. Por exemplo, graphicx
usa o keyval
pacote para analisar o ,
e =
em seu argumento opcional
\includegraphics[width=10pt,height=8pt]{image}
e hyperref
usa a mesma análise para analisar a mesma sintaxe em um argumento obrigatório
\hypersetup{colorlinks=false,plainpages=true}