Existe uma maneira de verificar se uma etiqueta já está definido em LaTeX?

StackOverflow https://stackoverflow.com/questions/495841

  •  20-08-2019
  •  | 
  •  

Pergunta

Eu editei a pergunta após a resposta de David Hanak (graças btw!). Ele ajudou com a sintaxe, mas parece que eu não estava usando a função certa para começar.

Basicamente o que eu quero é deixar o compilador ignorar várias definições de um determinado rótulo e usar apenas o primeiro. A fim de fazer isso, eu pensei que eu tinha acabado de fazer algo parecido com isto:

    \makeatletter
    \newcommand{\mylabel}[1]{
        \@ifundefined{#1}{\label{#1}}{X}
    }
    \makeatother

Esta não funciona, porém, porque a primeira opção é sempre escolhido (não importa se o rótulo está definida ou não). Eu acho que o \ @ifundefined (e sugeriu \ ifundefined) só funcionam para os comandos e não para os rótulos, mas eu realmente não sei muito sobre LaTeX. Qualquer ajuda com isso seria ótimo! Obrigado!

Muito atualização posterior: Eu marquei a resposta de David Hanak como a resposta correta para a minha pergunta, mas não é uma solução completa, embora isso realmente me ajudou. O problema é, eu acho, mas eu não sou nenhum especialista, que, apesar de código verifica de David para ver se um rótulo é definido, ele só funciona quando o rótulo foi definido em uma execução anterior (ou seja, está no arquivo .aux). Se duas \ MyLabels com o mesmo nome são definidos no mesmo prazo, o segundo ainda será definida. Além disso, mesmo se você conseguir contornar esse problema, ele vai fazer LaTeX usar a primeira etiqueta que você definiu em ordem cronológica, e não necessariamente o primeiro no texto. De qualquer forma, abaixo é a minha solução rápida e suja. Ele usa o fato de que os contadores não parecem ser definido imediatamente.

\newcommand{\mylabel}[1]{%
    \@ifundefined{c@#1}{%
        \newcounter{#1}%
        \setcounter{#1}{0}%
    }{}%
    \ifthenelse{\value{#1} > 0}{}{%
        \label{#1}%
        \addtocounter{#1}{1}%
    }%
}

Eu não tenho certeza se é necessário inicializar o contador a 0, uma vez que parece ser um padrão provável, mas eu não poderia encontrar, se fosse esse o caso, então eu só estou sendo seguro. Além disso, este usa o pacote 'ifthen', que eu não tenho certeza que é necessário.

Foi útil?

Solução

@ é um caractere especial em LaTeX. Para tornar a sua declaração sintaticamente correto, você terá que adicionar mais duas linhas:

\makeatletter
\newcommand{\mylabel}[1]{
    \@ifundefined{#1}{\label{#1}}{X}
}
\makeatother

A primeira linha voltas @ em uma carta normal, a última linha inverte o seu efeito.

Update: Você também pode querer ter um olhar para o "simples" \ifundefined LaTeX macro .

Update 2

Ok, eu fiz alguma pesquisa para descobrir a resposta para a real problema. A coisa é que a definição de um rótulo não criar uma macro com esse nome; -lo prepends um "r @" para ele. Então tente o seguinte:

\makeatletter
\newcommand{\mylabel}[1]{
    \@ifundefined{r@#1}{\label{#1}}{X}
}
\makeatother

Para mais detalhes técnicos, consulte a linha 3863 de latex.ltx na sua distribuição LaTeX (onde diz \def\newlabel{\@newl@bel r}).

Outras dicas

Eu também não sou um especialista em LaTeX, no entanto, após um dia de tentar e pesquisar na internet o seguinte trabalhou para mim. Eu tenho usado um contador de manequim para resolver o problema. Esperemos que esta ajuda, aparentemente, não muitas pessoas estão procurando por isso.

\newcommand{\mylabel}[1]{
    \ifcsname c@#1\endcsname%
    \else%
        \newcounter{#1}\label{#1}%
    \fi%
}

Por Victor Eijkhout, "Tex por Tópico", p.143:

\def\ifUnDefinedCs#1{\expandafter\ifx\csname#1\endcsname\relax} 

Isto pode ser usado para verificar se um rótulo é definido; se não, o rótulo é impresso:

\newcommand{\myautoref}[1]{\ifUnDefinedCs{r@#1}{\color{magenta}\IDontKnow\{#1\}}\else\autoref{#1}\fi} 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top