Synctex: faça funcionar com o ambiente acessando seu conteúdo (por exemplo, opção environ ou xparse +b)

Synctex: faça funcionar com o ambiente acessando seu conteúdo (por exemplo, opção environ ou xparse +b)

Se eu criar um ambiente usando environand \BODYou xparseand +b, a funcionalidade do synctex será interrompida: em vez de ir para a linha apropriada, ela vai para o final do ambiente. Acho que o fato de \BODYser colocado em uma macro atrapalha o LaTeX, mas estou curioso para saber se consigo resolver de alguma forma (eventualmente em lualatex)

MWE

\documentclass[]{article}
\usepackage{environ}% http://ctan.org/pkg/environ

%% The +b is needed because in real life the text may be moved to another file
\NewDocumentEnvironment{testSynctex}{s+b}{
  \IfBooleanTF{#1}{}{#2}%
}{}

\NewEnviron{testSynctexEnviron}{%
  \BODY
}

\begin{document}

\section{xparse}

\begin{testSynctex}
  This

  is

  a

  long

  text

  try

  to synctex

  me !
\end{testSynctex}

\section{xparse*}

\begin{testSynctex}*
  This

  text
  should

  be

  hidden
\end{testSynctex}

\section{environ}

\begin{testSynctexEnviron}
  This

  is

  a

  long

  text

  try

  to synctex

  me !
\end{testSynctexEnviron}

\end{document}

EDITAR

A solução proposta por user202729 funciona bem para o MWE acima (e definitivamente responde parte da minha pergunta e certamente será útil se eu não conseguir encontrar uma resposta mais generalizável). Porém, aqui está outro MWE que gostaria de resolver onde a solução proposta pelo user202729 não funciona mais:

Estou duplicando um texto entre duas seções (gravando primeiro o conteúdo em um arquivo antes de inseri-lo). Infelizmente, isso quebra o sintex: não apenas para o texto copiado (vai para o arquivo fictício em vez do arquivo principal), mas também para o texto inicial (vai para o final do ambiente).

Seria possível fazer o sintex funcionar pelo menos para o texto da primeira seção? E se você conseguir fazer funcionar também para o texto da segunda seção… seria incrível.

MWE:

\documentclass{article}
\def\nameOfFile{mydummyfile.tex}

%% Write to a file
\newwrite\appendwrite
\NewDocumentCommand\writetofile{m+m}{%
  %% Open the file
  \immediate\openout\appendwrite #1\relax%
  %% Write the text to the file
  \immediate\write\appendwrite{#2}%
  %% Close the file
  \immediate\closeout\appendwrite%
}
  
\NewDocumentEnvironment{duplicateContentKeepSynctex}{+b}{%
  #1%
  \writetofile{\nameOfFile}{#1}%
}{}

\begin{document}

\section{Main body}

\begin{duplicateContentKeepSynctex}
  This content is duplicated to another section.

  However synctex does not work in both sections.

  Ideally I'd love to make synctex work in both sections (in such a way that it always links to the main file, NOT mydummyfile).

  But I guess it's impossible.

  But at least, is it possible to make it work for the first section?
\end{duplicateContentKeepSynctex}

\section{Duplicated section}

\input{\nameOfFile}

\end{document}

Responder1

Não vejo como isso seria possível em uma linguagem de expansão macro. O conteúdo de uma macro não é processado, portanto você só pode obter mensagens de erro ou marcadores sincronizados onde ela é usada e que podem estar longe da definição. Nestes casos, a macro interna que salva o corpo do ambiente é usada perto da definição, então os dados sincronizados estão próximos da fonte, mas para tex seu exemplo é como

\def\abc{
some text

XXX

that gets saved here
}

multiple pages of arbitrary document source

\abc

e você está pedindo que o syntex associe XXX à linha 4 no meio da definição de \abcnão com uma linha "várias páginas depois" onde \abcé usado.

Responder2

Tudo bem, a solução.

Se compilar com lualatex ambas as seções terão o sinctex preservado, caso contrário apenas a primeira seção será.

%! TEX program = pdflatex

\documentclass{article}
\usepackage{saveenv}
\usepackage{currfile}
\usepackage{rescansync}

  
\ExplSyntaxOn
\NewDocumentEnvironment{duplicateContentKeepSynctex}{}{%
  \rescansyncSaveenvghostPacked \savedcontent
}{
  \endrescansyncSaveenvghostPacked
}
\ExplSyntaxOff

\begin{document}

\section{Main body}

\begin{duplicateContentKeepSynctex}
  This content is duplicated to another section.

  However synctex does not work in both sections.

  Ideally I'd love to make synctex work in both sections (in such a way that it always links to the main file, NOT mydummyfile).

  But I guess it's impossible.

  But at least, is it possible to make it work for the first section?
\end{duplicateContentKeepSynctex}

\section{Duplicated section}

\rescansyncPacked \savedcontent

\end{document}

Na verdade, ele não grava o conteúdo em um arquivo; o conteúdo é armazenado em \savedcontentalgum formato peculiar que o usuário não deve tocar. Caso o usuário queira manipular o conteúdo manualmente, utilize a API programática do rescansyncpacote.

Observação

informação relacionada