latex3 / latex2e

The LaTeX2e kernel
https://www.latex-project.org/
LaTeX Project Public License v1.3c
1.95k stars 267 forks source link

docstrip (v2.6b <2022-09-03>) - \declarepreamble/\usepreamble breaks in case a preamble-macro and a file to generate have the same name. Same with postambles. #1150

Open Ulrich-Diez opened 1 year ago

Ulrich-Diez commented 1 year ago

docstrip (v2.6b <2022-09-03>) - \declarepreamble/\usepreamble breaks in case a preamble-macro and a file to generate have the same name. Same with postambles in case a postamble-macro and a file to generate have the same name.

This is due to the macro \@fileX:

\def\@fileX#1#2{%
  \chardef#1=\stream@closed
  \def\curout{#1}%
  \let\curinfiles\empty
  \let\curinnames\empty
  \def\curref{\MetaPrefix ^^J%
              \MetaPrefix\space The original source files were:^^J%
              \MetaPrefix ^^J}%
  \let\from\@from \let\needed\@needed
  #2%
  \let\from\err@from \let\needed\err@needed
  \checkorder
  \Name\@addto{e@\curin}{\noexpand\closeoutput{#1}}%
  \Name\let{pre@\@stripstring#1\expandafter}\currentpreamble
  \Name\let{post@\@stripstring#1\expandafter}\currentpostamble
  \Name\edef{in@\@stripstring#1}{\expandafter\iden\curinnames}
  \Name\edef{ref@\@stripstring#1}{\curref}
  }

Usually #1 holds a control-sequence-token whose name denotes the name of the file to generate.

In case a file to generate has the same name as a preamble declared via \declarepreamble and invoked via \usepreamble, the control-sequence-token denoting the name of the file to generate also denotes the macro holding that preamble. And that preamble-macro is overridden by \@fileX via \chardef#1=\stream@closed.

Therefore writing a preamble to file according to a preamble-macro declared via \declarepreamble and used via \usepreamble does not work out any more as soon as a file of same name as the preamble in question is to be generated.

Same with postambles,

Probably it should be mentioned explicitly in the manual of the package docstrip that files to generate and preambles/postambles should not have same names and that it is up to the user to ensure that no preamble or postamble is declared and used where the name is also that of a file to generate.

The requirement of names of files to differ from names of preambles/postambles is counter-intuitive if you are not familiar with the coding of docstrip: Not lightheartedly overriding macro-definitions is one thing. But the ordinary user doesn't see that with docstrip a filename internally is turned into a control word token which in turn is defined as a \chardef-token and thus can override another macro definition.

(Alternatively different pieces of data can be stored as control-sequence tokens of different namespace but when the name of the control-sequence itself is the data, then this brings along the need of stripping the namespace-part.)

Minimal example showing the problem

With the following example preambles are not written to the files student/teacher:

%<*ignore>
% Section with docstrip directives for generating different 
% .tex-input-files:
\input docstrip

\declarepreamble\teacher
________________________

Course Guide, release only for teachers, with teaching notes embedded.

Use pdflatex/pdftexify for compiling this file.

\endpreamble

\declarepreamble\student
________________________

Course Guide, release for students, no teaching notes embedded.

Use pdflatex/pdftexify for compiling this file.

\endpreamble

\generate{%
  \nopostamble
%
  \usepreamble\teacher
  \file{teacher}{\from{\jobname.tex}{teacher}}%
%
  \usepreamble\student
  \file{student}{\from{\jobname.tex}{student}}%
}%
% Here you can probably insert \write18-calls suitable for your platform
% for calling pdflatex from console for compiling the files
% just generated -- something like:
%    \immediate\write18{pdflatex teacher.tex}
%    \immediate\write18{pdflatex students.tex}
%    \immediate\write18{pdftexify teacher.tex}
%    \immediate\write18{pdftexify students.tex}
%
\csname stop\endcsname % <- end this TeX-run in case you used (pdf)LaTeX
                       %    for generating the files.
%
\bye % <- end this TeX-run in case you used (pdf)TeX for generating the 
%    %    files.
%
%</ignore>
% Section containing the actual LaTeX document, with tags for
% generating different variants with different target groups
%<*teacher,student>
\documentclass{article}
\begin{document}
This is for both for students and for teachers.
%<*teacher>
This is for teachers only.
%</teacher>
%<*student>
This is for students only.
%</student>
This is for both for students and for teachers.
\end{document}
%</teacher,student>

You get a file teacher.tex with the following content:

\pre@teacher 
\documentclass{article}
\begin{document}
This is for both for students and for teachers.
This is for teachers only.
This is for both for students and for teachers.
\end{document}

You get a file student.tex with the following content:

\pre@student 
\documentclass{article}
\begin{document}
This is for both for students and for teachers.
This is for students only.
This is for both for students and for teachers.
\end{document}

As you can see, with both files the preamble is not written properly.
That's because names of preamble-macros and names of files to create are the same.

(You also get a .pdf-file with some garbage-content, but that is not needed for tracing the issue.)

Log file (required) and possibly PDF file

CourseNotes.log

github-actions[bot] commented 8 months ago

This issue has been automatically marked as stale because it has not had recent activity.