O que há de errado com minha macro de freio?

O que há de errado com minha macro de freio?

Com base na solução alternativa do egreg para o meupergunta anteriorcom o qual aprendi a ideia de transformar caracteres em macros, agora defini uma sintaxe diferente para colchetes, da qual gosto ainda mais. Minha macroquasefunciona (embora haja um pouco de programação de culto à carga acontecendo aqui porque copiei uma parte de sua solução que não entendi completamente - as duas linhas que começam com \begingroup\lccode- em minha macro e as adaptei ligeiramente; suspeito que o problema seja aí, porque o resto creio ter compreendido suficientemente, graças às explicações da egregs para a outra questão).

Aqui está minha definição de macro:

\newcommand{\braket}[2][\middle]{\ensuremath{
\begingroup
\begingroup\lccode`~=`<
  \lowercase{\endgroup\def~}{#1\langle}
\begingroup\lccode`~=`|
  \lowercase{\endgroup\def~}{#1\pipedel}
\begingroup\lccode`~=`>
  \lowercase{\endgroup\def~}{#1\rangle}
\edef\pipedel{\delimiter\the\delcode`|}
\mathchardef\lt\mathcode`<
\mathchardef\pipechar\mathcode`|
\mathchardef\gt\mathcode`>
\mathcode`\<=\string"8000
\mathcode`\|=\string"8000
\mathcode`\>=\string"8000
\left.
#2
\right.
\endgroup
}}

Todos os usos a seguir funcionam conforme o esperado:

\braket{<\psi|\psi>}
\braket{<\psi|A|\psi>}
\braket{<\psi|\frac{p^2}{2m}|\psi>}
\braket[\Big]{<\alpha|\beta>}
\braket{|a \gt 0>}
\braket[]{<\psi|\frac{p^2}{2m}|\phi>}

(o último simplesmente desativa a adaptação automática de tamanho).

No entanto, o seguinte faznãofuncionar corretamente:

\braket{<0|1>}

Deveria dar "〈0|1〉" mas só dá "〈0〉".

Então, o que há de errado com minha macro e como posso corrigir isso?

Responder1

O problema é que quando o TeX encontra o pipe ativo, ele o expande para

\delimiter 2532108

e um número seguinte será incorporado a esse código.

\mathchardef\lt\mathcode`<
\mathchardef\pipechar\mathcode`|
\mathchardef\gt\mathcode`>
\edef\pipedel{\delimiter\the\delcode`| }
\show\pipedel
\newcommand{\braket}[2][\middle]{
  \begingroup
  \begingroup\lccode`~=`<
    \lowercase{\endgroup\def~}{#1\langle}
  \begingroup\lccode`~=`|
    \lowercase{\endgroup\def~}{#1\pipedel\relax}
  \begingroup\lccode`~=`>
     \lowercase{\endgroup\def~}{#1\rangle}
  \mathcode`\<=\string"8000
  \mathcode`\|=\string"8000
  \mathcode`\>=\string"8000
  \mathopen{}\left.#2\right.\mathclose{}
  \endgroup
}

Isso \relaxevitará o problema. Além disso, algumas partes são melhores fora da definição e \ensuremathnão são recomendáveis.

Nota sobre o \lowercasetruque

Quando um caractere (de código de categoria 11 ou 12) recebe código matemático "8000e é encontrado no modo matemático, ele é tratado pelo TeX como se estivesse ativo (ou seja, como uma macro) e é necessária uma definição dele como um caractere ativo. .

Um truque muito comumente usado é explorar isso~ éativo; quando queremos dar um significado ao ativo <, existem duas estratégias. O primeiro é

{\catcode`<=\active \gdef<{something}}

que tem alguma desvantagem: somos obrigados a executá-lo antecipadamente e églobal. Então usamos uma estratégia diferente:

\begingroup\lccode`~=`< \lowercase{\endgroup\def~}{something}

Como é que isso funciona? Primeiro de tudo, abrimos um grupo e no grupo dizemos ao TeX que a contraparte minúscula de ~é <. Então fazemos \lowercase, o que transformafichas de personagemem sua contraparte minúscula (mas deixando as sequências de controle inalteradas) e coloca de volta os tokens como se estivessem lá desde o início. Então o TeX vê

\endgroup\def<{something}

(mas< éativo, pois \lowercasenão altera códigos de categoria). O \endgroupdesfaz a correspondência entre ~e <e a definição é executada. Quando, mais tarde, dissermos \mathcode`<=\string"8000, a mágica vai acontecer ( \stringé uma precaução contrababelque poderia ter se tornado "um personagem ativo).

informação relacionada