1

If I create an environment using environ and \BODY or xparse and +b, the synctex functionality breaks: instead of going to the appropriate line, it goes at the end of the environment. I guess that the fact that \BODY is put into a macro disturbs LaTeX, but I'm curious to know if I can solve it somehow (eventually in 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}

EDIT

The solution proposed by user202729 works nicely for the above MWE (and it definitely answers part of my question and will surely turn out to be useful if I can't find a more generalizable answer). However, here is another MWE that I'd like to solve where the solution proposed by user202729 does not work anymore:

I'm duplicating a text between two sections (by writing first the content to a file before inputting that file). Unfortunately, this breaks synctex: not only for the copied text (it goes to the dummy file instead of the main file), but also for the initial text (it goes to the end of the environment).

Would it be possible to make synctex work at least for the text in the first section? And if you can make it work also for the text in the second section… it would be awesome.

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}

tobiasBora
  • 8,684
  • Anyway, do you still want an answer? Maybe edit the MWE to make it nontrivial (currently it's trivial, that is, can be handled by making a normal environment that does nothing), I don't feel like looking at your package to see what it does – user202729 May 29 '22 at 11:03
  • @user202729 Yes, I'm still interested by an answer. Technically, the first environment testSynctex can't be replaced as far as I know with a normal environment as it deletes its content when called with a star, so I guess it still works as a MWE. – tobiasBora May 29 '22 at 18:17
  • Ah, I just notice (actually this is also a special case that can be handled with only normal LaTeX programming.) – user202729 May 30 '22 at 00:37
  • 1
    That particular question is conditionals - Hide custom environment content based on boolean - TeX - LaTeX Stack Exchange . (it doesn't contain the answer I want though. Will do something about it later.) – user202729 May 30 '22 at 00:45
  • 1
    Okay, now there's an answer there that is adaptable to this case. Make a more complex MWE if you want. – user202729 May 30 '22 at 12:19
  • @user202729 Thanks a lot for your answer, it works nicely for the simpler use-case I have (and if I can't find a more general solution for my second problem, your solution will definitely turn out to be super useful). In practice, I'd love to also solve a more generic problem: I added a more complete MWE that should be enough to illustrate my need (in practice I'll also be able to choose if I want one text or both… but let's keep things simple for now), and I'd love to hear if you have a solution for this as well. Thanks a lot! – tobiasBora May 31 '22 at 05:57
  • 1
    Should be possible (possibly subject to certain restrictions)... will do something about it when I have time. – user202729 May 31 '22 at 15:03
  • @user202729 It would be great, thanks a lot in advance! Do you mean that one could imagine a solution that also works for the text in the second section, or "only" for the first section (which is already really interesting)? – tobiasBora May 31 '22 at 16:51

2 Answers2

2

I don't see how that would be possible in a macro expansion language. The content of a macro is not processed so you can only get error messages or synctex markers where it is used and that may be nowhere near the defintion. In these cases the internal macro saving the environment body happens to be used close to the definition so the synctex data is close to the source but to tex your example is like

\def\abc{
some text

XXX

that gets saved here }

multiple pages of arbitrary document source

\abc

and you are asking that synctex associates XXX with line 4 in the middle of the definition of \abc not with a line "multiple pages later" where \abc gets used.

David Carlisle
  • 757,742
  • Thanks for your answer. But I don't see why it's fundamentally a problem: there could be a way to translate automatically your text into \def\abc{{\set_synctex_line{2}some text} {\set_synctex_line{4}XXX}},. This way, when calling \abc, the macro expansion would locally change the value of the synctex line to write to a file… does not seems that crazy to me. Also, people are doing some similarly crazy things, and I hope there may be ways to adapt it to this issue https://tex.stackexchange.com/questions/631887/how-can-i-capture-and-rescan-tex-source-code-while-preserving-synctex-data/632368 – tobiasBora May 06 '22 at 19:57
  • @tobiasBora where are those commands, or do you mean to use luatex and access synctex data from lua? Still I'll happily delete this answer if someone posts something more constructive:-) – David Carlisle May 06 '22 at 20:04
  • Oh, I was mostly trying to see why macro languages would be fundamentally unable to do so, and I was just imaginating a macro-like keeping information on where the text was defined (but I'm not an expert in macro languages). Concerning the \set_synctex_line{X}, it's just a dream command that would say "the next text is on line X". But if you say that (lua)LaTeX can't cope with this, I trust you! But out of curiosity, why is my question different from the aforementionned solution based on lua? Is it solely because I don't write in a file? Could I make it work with an additional file? – tobiasBora May 06 '22 at 20:28
  • @tobiasBora I said I made it into a package... well, remind me to document it soon. // if you post a particular use case I can post answer (try not too over-simplify the problem -- if it's too simple it can be done without BODY at all and thus trivially preserve synctex) // yes, but you surely need to learn lots of Lua and TeX to use it properly. – user202729 May 07 '22 at 05:01
  • @user202729 Do you mean that the code in the question could be synctexable? I did try your package (just included it) but synctex was not working better after. The actual usecase I have is to solve https://github.com/leo-colisson/proof-at-the-end/issues/10 and/or https://github.com/leo-colisson/proof-at-the-end/issues/9 but the above MWE (xparse version) should capture the requirement of the first issue. – tobiasBora May 07 '22 at 07:13
  • @tobiasBora See, the problem with no documentation. You need to capture the content verbatim and resend it with \resendsync (or something, I don't really remember) providing the correct line number etc. for it to work. Will document later... – user202729 May 07 '22 at 07:15
  • @user202729 https://chat.stackexchange.com/transcript/message/3973372#3973372 – David Carlisle May 07 '22 at 08:11
2

Alright, the solution.

If compiles with lualatex both sections will have synctex preserved, otherwise only the first section will be.

%! 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}

It doesn't actually write the content to a file, the content is stored in \savedcontent in some peculiar format that the user isn't supposed to touch. If the user wants to manipulate the content manually, use the programmatic API of rescansync package.

Note

user202729
  • 7,143