Construindo uma lista de rótulos não duplicados a partir de texto em tempo real

Construindo uma lista de rótulos não duplicados a partir de texto em tempo real

Como acompanhamento Diferença no tempo de compilação entre duas versões ligeiramente diferentes escreviExcluindo duplicatas de uma lista de strings separadas por vírgula.

Resumo do problema: A pergunta anterior mostrava algum código TeX que usava uma lista de strings que eram rótulos derivados de referências no texto. No entanto, essa lista pode conter duplicatas e esse código não desduplicou essa lista. A última questão teve como foco a desduplicação dessa lista após recolhê-la do texto.

Porém, David Carlisle indicou no chat que talvez seja possível criar uma lista sem duplicatas em primeira instância. Eu presumi que seria mais rápido e fácil criar uma lista com duplicatas e depois removê-las, mas talvez não. De qualquer forma, estou interessado em uma solução que utilize essa abordagem.

A troca relevante começou em

http://chat.stackexchange.com/transcript/message/20082058#20082058

onde David escreveu

Não vejo por que você precisaria de \clist_remove_duplicates:N se as duplicatas forem um problema, simplesmente não as coloque na lista.

Eu respondi com

@DavidCarlisle bem, você teria que verificar a lista a cada adição. Alguém poderia fazer isso, certamente, mas provavelmente é mais eficiente remover os ingênuos no final.

Ao que David respondeu:

@FaheemMitha duvido

e seguiu com

@FaheemMitha Você está adicionando ref, então se \csname r@#1\endcsname já estiver definido, você já viu esta ref antes e não precisa adicioná-la novamente. É necessário construir uma lista com duplicatas

Eu respondi:

Presumivelmente, você está dizendo que o código da pergunta original pode ser modificado para que os ingênuos não sejam adicionados.

ao que ele respondeu

@FaheemMitha sim, embora não esteja testando r@#1 (pois isso apenas indica que existe um rótulo), mas você pode fazer com que cada árbitro deixe um csname para saber que o viu (isso troca espaço por tempo)

Responder1

Você pode simplesmente definir uma macro de sinalização (para qualquer coisa) e não adicionar uma nova entrada se a macro já estiver definida.

% VERSION 1
\iftrue
\makeatletter
\let\oldref\ref
\def\ref#1{%
  \expandafter\ifx\csname R@#1\endcsname\relax
  \global\expandafter\let\csname R@#1\endcsname\@empty
  \immediate\write\@auxout{%
    \string\gappto\string\ReferencedIDs{#1,}%
  }%
 \fi
  \oldref{#1}%
}
\def\ReferencedIDs{}
\makeatother

\else
% VERSION 2

 \makeatletter
 \AtBeginDocument{\providecommand\ReferencedIDs{}}
 \AtEndDocument{\immediate\write\@auxout{\gdef\string\ReferencedIDs{\ReferencedIDs}}}
 \let\oldref\ref
 \def\ref#1{%
  \expandafter\ifx\csname R@#1\endcsname\relax
  \global\expandafter\let\csname R@#1\endcsname\@empty
   \g@addto@macro\ReferencedIDs{#1,}%
  \fi
   \oldref{#1}%
 }
 \makeatother
\fi

informação relacionada