Argumentos opcionais em "famílias"... Quando e como?

Argumentos opcionais em "famílias"... Quando e como?

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:

  1. Quando (LaTeX padrão) devo usar a primeira forma e quando a segunda?
  2. \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 #1seria OptArg1,OptArg2, #2seria Arg1e #3seria Arg2e 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. \newcommandSe 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 xparseou 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 OptArg1nã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, graphicxusa o keyvalpacote para analisar o ,e =em seu argumento opcional

\includegraphics[width=10pt,height=8pt]{image}

e hyperrefusa a mesma análise para analisar a mesma sintaxe em um argumento obrigatório

\hypersetup{colorlinks=false,plainpages=true}

informação relacionada