Como \string e \newcommand funcionam?

Como \string e \newcommand funcionam?

Tento escrever um comando que cada notação possa vincular à primeira aparição. Considere uma notação A e um vetor B. Defina um comando que fun{'}=B' e fun{x}=B^{x} para x=/='. Se eu quiser escrever B^(A), preciso usar o código "fun{(A)}". Observe que este “A” utiliza o código “hiperlink”. Mas \equalnão é trabalho quando \equal{(\hyperlink{x}{y})}{z}.

Aqui está um exemplo mínimo do meu problema:

\documentclass{article}
\usepackage{hyperref}
\usepackage{ifthen}

\newcommand{\hyperaword}{(\hyperlink{1}{456})}

\begin{document}

\hypertarget{1}{3} % work
\hyperlink{1}{2} % work
\ifthenelse{\equal{\string\hyperaword}{456}}{123}{456} % work
\ifthenelse{\equal{\string (\hyperlink{1}{456})}{456}}{123}{456} % ERROR: Use of \hyper@link@ doesn't match its definition.
\end{document}

Este problema só acontece quando uso "(\hyperlink{xx}{xx})". Se eu usar "\hyperlink{xx}{xx}" e não usar "( )", tudo bem.

Responder1

Deixe-me reescrever sua pergunta:

Eu tenho um comando

\newcommand \f [1] { \ifthenelse { \equal {#1} {...} } ... }

Isso funciona na maioria das vezes, mas quando #1contains \hyperlink, ocorre um erro em vez de apenas executar o branch falso.

Responder: Conforme explicado no ifthenpacote, #1éexpandidopara fazer com que a string seja comparada.

Se você quiser comparar o conteúdo bruto, use \detokenize.

\stringsó funciona em casos limitados.

\newcommand \f [1] { \ifthenelse { \equal {\detokenize{#1}} {\detokenize{...}} } ... }

Abordagem alternativa: use expl3 e \str_if_eq:nnTFou \tl_if_eq:nnTF.

Responder2

\stringem um comando name retorna o nome como uma string (uma sequência de caracteres do catcode 12), portanto \usepackageé um único token, mas \string\usepackagesão os 11 tokens\ u s e p a c k a g e

\ifthenelse equalexpande os dois argumentos e testa se eles são iguais.

\equal{\string\hyperaword}{456}

testa se os 11 tokens \hyperaword são iguais aos três tokens 4 5 6 isso nunca é verdade, então

\ifthenelse{\equal{\string\hyperaword}{456}}{123}{456}

é sempre456

No segundo teste \string(expande para (as (já é um caractere do catcode 12. mas \hyperlinké um comando frágil que você não pode usar em um contexto de expansão. De qualquer forma, ele constrói um link usando primitivas pdftex (se você estiver usando pdftex) para que, especialmente quando cercado por (), nunca seja igual a 456você poderia evitar o erro usando, \protect\hyperlinkmas então o teste é se os três tokens ( \hyperlink )são iguais ao três fichas 4 5 6e novamente isso nunca é verdade.

Responder3

Quando o visualizador de PDF está mostrando o arquivo PDF,um "hipertarget" é basicamente apenas uma área 1 em uma página de um arquivo PDF que possui um nome pelo qual pode ser identificado.

Quando o visualizador de PDF está mostrando o arquivo PDF, um "hiperlink" é basicamente apenas uma área 1 em uma página do arquivo PDF, onde clicar tem o efeito de rolar 2 outra área do arquivo PDF para a janela onde o arquivo pdf é exibido.

Portanto, a macro \hypertargeté uma instrução para o compilador LaTeX escrever nas diretivas do arquivo pdf que no momento da visualização do arquivo pdf, ou seja, no momento em que o compilador LaTeX não roda mais, o pdf- o programa de visualização usa para dar um nome a uma área no arquivo PDF. Essa área nomeada é chamada de "alvo". O nome dessa área é chamado de "destino". Se essa área nomeada for tão pequena que possa ser considerada um único ponto no arquivo pdf, ela também será chamada de "âncora". 3

E a macro \hyperlinké uma instrução para o compilador LaTeX escrever nas diretivas do arquivo pdf que no momento da visualização do arquivo pdf, ou seja, no momento em que o compilador LaTeX não roda mais, o pdf- o programa de visualização usa para conectar uma área do arquivo pdf com a instrução de rolar outra área (destino) do arquivo pdf até a janela onde o arquivo pdf é exibido ao clicar.

Durante a execução do TeX, os mecanismos baseados em pdfTeX acompanham nomes = destinos de áreas nomeadas = alvos / âncoras e geram mensagens de erro no final da execução do TeX no caso de ter colocado um hiperlink sem ter introduzido um destino correspondente, fornecendo um nome correspondente para uma área-alvo/âncora dentro do arquivo pdf.

Masnenhum mecanismo TeX usa o mecanismo \hypertarget/ \hyperlinkpara rastrear frases textuais, etc., que ocorrem nas áreas roláveis ​​nomeadas do arquivo pdf.

Summa summarum:

A macro \hyperlinknão retorna nenhuma informação útil durante a execução do LaTeX. Ele apenas aciona instruções de gravação no arquivo PDF que são processadas pelo programa de visualização de PDF no momento da visualização do arquivo PDF.Ou seja, estas instruções não são processadas pelo compilador latex, mas por um programa diferente, nomeadamente o programa de visualização de pdf. Ou seja, essas instruções são processadas no momento em que o compilador de látex não está mais em execução e quando todos os dados que existem apenas durante a execução do compilador de látex deixaram de existir.

Expressões em seu código como
\ifthenelse{\equal{\string\hyperaword}{456}}{123}{456}
e
\ifthenelse{\equal{\string (\hyperlink{1}{456})}
indicam tentativas de avaliar de alguma forma um "resultado" da aplicação \hyperlinkdurante a execução do compilador de látex.

Portanto, embora eu não saiba exatamente o que você tenta alcançar, duvido que a macro \hyperlinkforneça tokens/informações cujo processamento/exame adicional durante a execução do TeX seria de alguma utilidade para você.

Se bem entendi, a questão agora envolve um mal-entendido sobre o que \hyperlinkrealmente é a macro TeX, o que já torna difícil entender a questão.

Por favor, especifique exatamente o que você deseja alcançar. Provavelmente posso modificar minha resposta para adicionar um exemplo de código que exiba uma abordagem para o assunto.


1 No caso de quebras de página/quebra de coluna e similares, tanto os hipertargets quanto os hiperlinks podem consistir em diversas áreas, e não apenas em uma única área.

2 O significado de "rolar outra área do arquivo pdf até a janela onde o arquivo pdf é exibido" depende do programa em uso para visualizar o arquivo pdf, porque as "ações" no decorrer da obediência a estas instruções são implementadas nesse programa. O comportamento de diferentes programas de visualização de PDF varia em casos extremos.

3 O pacote hyperref funciona com âncoras em muitas situações, assumindo que um ponto de ancoragem é rolado para o canto superior esquerdo da janela na qual o arquivo pdf é exibido quando um link correspondente é clicado. Internamente, o pacote hyperref especifica a posição de um ponto de ancoragem em relação ao ponto de referência daquela caixa que contém o texto/material que será visto na janela de exibição quando o link for clicado. No modo horizontal, onde o próprio TeX divide as coisas em caixas, até onde eu sei é o ponto de referência da primeira caixa horizontal que contém partes do texto/material que devem ser vistas na janela de exibição quando o link é clicado.



O exemplo a seguir fornece uma macro \LinkOrTarget{<destination name>}{<phrase>}da qual a primeira instância com um valor especificado⟨nome do destino⟩forma o hiperdestino e as instâncias subsequentes formam hiperlinks.

Se ocorrer um comando \IntroduceHypertargetHere{<destination name>}{<phrase>}, isso formará o hiperdestino enquanto todas as instâncias do formulário \LinkOrTarget{<destination name>}{<phrase>}formam hiperlinks.
Se \IntroduceHypertargetHere{<destination name>}{<phrase>}ocorrer um comando, você precisará de mais de uma execução de látex até que tudo corresponda.

Assim: Obedeça às informações e avisos no terminal e no arquivo .log sobre a necessidade de reexecutar o LaTeX (sem excluir arquivos auxiliares entre as execuções do LaTeX).

Não coloque \IntroduceHypertargetHere{<destination name>}{<phrase>}para o mesmo⟨nome do destino⟩mais de uma vez. Se fizer isso, você receberá avisos sobre rótulos definidos de forma múltipla e o hipertarget será criado na primeira dessas instâncias.

\documentclass{article}
\usepackage{hyperref}
\usepackage{zref}

\makeatletter
\zref@newprop{DestinationExplicitlyPlaced}{}%
\newcommand\WrapHypertargetInHy@raisedlink[2]{%
  \Hy@raisedlink{\hypertarget{#1}{}}#2%
}%
\newcommand\IntroduceHypertargetHere[1]{%
  \zref@setcurrent{DestinationExplicitlyPlaced}{true}%
  \zref@labelbyprops{ExplicitDestination-#1}{DestinationExplicitlyPlaced}%
  \IntroduceHypertargetHereInternal{#1}%
}%
\newcommand\IntroduceHypertargetHereInternal[2]{%
  \@ifundefined{NameOfDestination_#1}{%
    \expandafter\gdef\csname NameOfDestination_#1\endcsname{}%
    \WrapHypertargetInHy@raisedlink
  }{\hyperlink}{#1}{#2}%
}%
\newcommand\LinkOrTarget[2]{%
  \zref@ifrefundefined{ExplicitDestination-#1}{\IntroduceHypertargetHereInternal}{%
    \zref@ifrefcontainsprop{ExplicitDestination-#1}{DestinationExplicitlyPlaced}%
                           {\hyperlink}{\IntroduceHypertargetHereInternal}%
  }%
  {#1}{#2}%
}%
\makeatother

\begin{document}

Dummy page
\newpage
Smme text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
\newpage
Some text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
\newpage
Some text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
%Some text \IntroduceHypertargetHere{destination name}{Phrase which is in target area}.
\newpage
Some text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.
\newpage
Some text \LinkOrTarget{destination name}{Phrase which either is in link area or is in target area}.

\end{document}

informação relacionada