\ Def e \ define o mesmo no ConTeXt?

Existe alguma diferença entre definir uma variável usando \def e \define, quando usado sem um número entre colchetes, por exemplo \def\somecommand{\percent} e \define\somecommand{\percent}? Posso sempre usar \define em locais onde \def pode ser usado?

Comentários

  • Pelo que vejo, \define\xyz{...}, quando \xyz já está definido, emite um aviso, mas executa a definição de qualquer forma. É claro que \def não ' emite nenhum aviso.

Resposta

Para referência: existem duas definições de \define: a primeira em syst-aux.mkiv mostra o comportamento que Egreg citado em seu comentário: se a macro já estiver definida, ela deixa como está. (Um complemento, \redefine permite que você sobrescreva a definição atual de macro, independentemente de ela estar em uso.) Ironicamente, esta definição preliminar é sobrescrita sem aviso assim que o formato é carregado > core-sys.mkiv (enquanto \redefine permanece para sempre).

O real a definição da macro \define conforme fornecida pela interface do usuário não só verifica as sequências de controle definidas anteriormente com o mesmo nome, mas também serve como algum tipo de notação curta para argumentos obrigatórios. Ele tem o esquema

\define [<digit>] <macro> {<definition>} 

onde o primeiro argumento, um dígito, especifica o número de argumentos que a nova macro vai aceitar. Obviamente, isso pode resultar em definições mais curtas. Para comparação, o seletor

\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7} \starttext \sevenofnine abcdefghi\par \stoptext 

requer menos digitação com a macro \define:

\define[9]\sevenofnine{#7} 

Portanto, essas definições podem resultar em um código mais legível – o que é sempre uma boa coisa ao escrever TEX.

Infelizmente, o \define o wrapper tira uma boa parte da expressividade dos \def simples. No Contexto, você deve ter notado, macros que usam argumentos opcionais são comuns em relação à interface do usuário. Por exemplo, você simplesmente não pode substituir a segunda \def iniciação no snippet abaixo por uma expressão equivalente usando \define:

\unprotect \def\myfoo{\dosingleempty\do_my_foo} \def\do_my_foo[#1]#2{% \iffirstargument{\bf\WORD#1}\fi #2\par% } \protect \starttext \myfoo{bar} \myfoo[foo]{bar} \stoptext 

Isso porque com \define você não pode especificar os delimitadores de argumento (aqui: colchetes) necessários para argumentos opcionais, portanto, basicamente, suas macros são limitadas a aceitar apenas argumentos obrigatórios (colchetes). Pela mesma razão, não há como definir ambientes \{start|stop}something baratos:

\let\stopfoo\relax \def\startfoo#1\stopfoo{\bgroup\bold#1\egroup} %%% ^^^^^^^^ not possible \starttext \startfoo bar \stopfoo \stoptext 

(A interface do usuário para isso é \definestartstop (cf. core-sys.mkiv ), de qualquer maneira.)

Finalmente, hoje em dia a desvantagem mais importante de \define é que não permite argumentos no estilo mkvi . Simplesmente não há como se referir a um parâmetro por seu nome se você não puder atribuí-lo em primeiro lugar.

% macros=mkvi \unprotect \def\foo{\dosingleempty\do_foo} \def\do_foo[#optional]#mandatory{% \bgroup\sansbold#optional\space\egroup #mandatory\par% } \protect \starttext \foo{bar} \foo[foo]{bar} \stoptext 

Então, se você quiser escrever macros a sério, em breve aprenderá a evitar \define, embora seja seguro para tarefas menos complexas.

Comentários

  • Obrigado por esta resposta útil. Esclarecimento: quando você diz " argumentos no estilo mkiv ", isso significa argumentos nomeados, como #optional em seu exemplo? Você tem uma referência para onde eu possa ler mais sobre isso?
  • @LarsH Sim, macros Mk VI (não MkIV!) São aquelas com nomes de parâmetros (opcionais). Não tenho certeza se existe qualquer documentação de nível de usuário além da fonte: o código do pré-processador pode ser encontrado em luat-mac.lua (para Contexto) e luatex-preprocessor.lua para Luatex-Plain. Hth.
  • Desculpe, erro meu.
  • Não ' sei se era esse o caso no momento em que escrevi esta resposta, mas hoje as macros definidas usando \define são protegidas pelo e-TeX. Para que seja expansível, é necessário usar \defineexpandable (ou simples \def).

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *