3

For Partial compilation commands/environment?, I would like to add \begin{comment} or \comment at the start of the document (so I could turn it off elsewhere in the code).

So, even if in the larger scope of things it is useless - in this MWE, as an exercise, I'd like the whole text to be blanked, basically, conditionally through the command line (the result would be a blank page, or even no pdf).

EDIT: However, I'd want it done in such a way, so that I could arbitrarily add \end{comment} / \begin{comment} later on it the document, and have only that snippet compile.

\documentclass[11pt]{book}
\usepackage{lipsum}

\ifx\doskip\relax
  \typeout{DOSKIP}
  \usepackage{etoolbox}
  \usepackage{comment}
  % https://tex.stackexchange.com/questions/14135/how-to-automatically-add-text-immediately-after-begindocument
  %\AtBeginDocument{\comment}         % ! Extra \endgroup.
  %\AtBeginDocument{\begin{comment}}  % Runaway argument? ! File ended while scanning use of \next.
  %\AfterEndPreamble{\comment}        % ! Extra \endgroup.
  %\AfterEndPreamble{\begin{comment}} % Runaway argument? ! File ended while scanning use of \next.
  %\AtEndDocument{\endcomment}%{\end{comment}}
  % desperate try (also fails w/ ! Extra \endgroup.):
  \protected\def\startcomment{\expandafter\comment}
  \AtEndPreamble{
\startcomment
  } % ! Extra \endgroup.
\fi

\begin{document}

\chapter{Some chapter}
\section{Section One}
\lipsum[1-3]

% later I might want to use here:
% \end{comment}
% \lipsum[5] % this would be typeset
% \begin{comment} % from this point on, again blanked

\end{document}

The idea is that the document would be "blanked" if Latex is called on the command line via
pdflatex "\let\doskip\relax\input{test.tex}"
... however, clearly there are some grouping errors; otherwise without the intervention, just using pdflatex test.tex, works fine.

Any ideas how this could be implemented?


EDIT2: closer, but not yet there: I've seen in kpsewhich comment.sty "Other 'comment' environments are defined by ... \excludecoment{versionb} ; These environments are used as \begin{versiona} ... \end{versiona} with the opening and closing commands again on a line of their own. This is not a LaTeX environment: for an included comment, the \begin and \end lines act as if they don't exist. In particular, they don't imply grouping ..."

So in the below example, which uses \excludecomment{versionb}, the begin{document} is succesfully overridden, the first part is skipped, then comment is interrupted, \lipsum[5] is typeset, and document compiles without error - but beyond that, it is very difficult to properly close either non-interrupted (fully blanked doc) or continue with blanking after once it's been interrupted:

\documentclass[11pt]{book}
\usepackage{lipsum}
\usepackage{trace}

\ifx\doskip\relax
  \typeout{DOSKIP}
  \usepackage{etoolbox}
  \usepackage{comment}
  \excludecomment{versionb}
  %\AtEndPreamble{ % here causes ! LaTeX Error: Missing \begin{document}.
  \AtBeginDocument{%
    % \expandafter\begin{versionb}\relax
    \begin{versionb}
  } % 
  %\AtEndDocument{\end{versionb}} % ! LaTeX Error: \begin{document} ended by \end{versionb}.
\fi

% \traceon
\begin{document}

\chapter{Some chapter}
\section{Section One}
\lipsum[1-3]

\end{versionb}
\lipsum[5]
% \begin{versionb}

%% \end{versionb} % can this be implicit, as per \AtEndDocument?
\end{document}
%%ENNDDD

A \typeout can be added, to this macro in comment.sty:

 \gdef\ProcessCommentLine#1^^M{\def\test{#1}
      \typeout{test: \meaning\test, \meaning\expandafter \csname End\CurrentComment Test\endcsname}

... so if there isn't a \end{versionb} before the \lipsum[5], we can see that the problem occurs because lines are attempted to be read beyond end of file:

...
test: macro:->\end{document}, \expandafter\end{versionb}
test: macro:->%%ENNDDD, \expandafter\end{versionb}
test: macro:->, \expandafter\end{versionb}
)
Runaway argument?
! File ended while scanning use of \next.
<inserted text> 
                \par 
<*> \let\doskip\relax\input{test.tex}

So, I'm still in need of help on how to make this code work for all circumstances...

  • 1
    LaTeX is not executing code in such environments, it simply skims over the tokens and looks for the actual string "\end{comment}". You can't have both: "Ignore this code" and "look if the code expands to something important". So you can't hide the \end{comment} in \AtEndDocument. – Ulrike Fischer Feb 19 '15 at 9:58
  • Thanks @UlrikeFischer - I'm just beginning to realize that distinction... Cheers! – sdaau Feb 19 '15 at 10:54
2

You can use the following code somewhere in the preamble after \documentclass.

\def\doskipA{\begin{document}\end{document}}
\ifx\doskip\relax \expandafter\doskipA\fi
  • Thanks @wipet - this would indeed blank the entire document, but then it doesn't leave any possibilities for that blanking to be interrupted with a snippet I'd want explicitly compiled; edited the OP, hope it clarifies that better now. Cheers! – sdaau Feb 19 '15 at 6:17
  • I don't understand why do you ignore the possibility to put \begin{comment} immediately after \begin{document} and to put \end{comment} immediately before \end{document} if you need to interrupt the comment area by another \end{comment}...\begin{comment}. – wipet Feb 19 '15 at 12:42
0

Ok, I finally got somewhere, though maybe not ideal. The below MWE behaves like this:

  • If compiled with pdflatex test.tex, the comment stuff is ignored, and the document compiles fully; but there will be these two warnings generated in the log (don't know how to fix that):

    (\end occurred inside a group at level 2)
    
    ### semi simple group (level 2) entered at line 86 (\begingroup)
    ### semi simple group (level 1) entered at line 86 (\begingroup)
    ### bottom level...
    
  • If compiled with pdflatex "\let\doskip\relax\input{test.tex}"; then there is an \excludecomment defined, called SKIPLINES, and \begin{document} starts it automatically; the code compiles without warnings, and only the segment between \end{SKIPLINES} and \begin{SKIPLINES} (note the order) which here is \lipsum[5] will be typeset. Also messages like these will be output to terminal:

    ...
    test: macro:->, macro:->\end{SKIPLINES}
    noend macro:-> macro:->\end{document}
    test: macro:->\end{document}, macro:->\end{SKIPLINES}
    yesend
    

I guess, this requires \excludecomment so that additional (?) grouping is avoided. However, there are still some hacks that are needed, and so the code includes modified versions of {comment}'s \excludecomment and \ProcessCommentLine. In particular, as @UlrikeFischer noted, if it happens that Latex is in "comment mode" when reading \end{document}, it will be skipped, resulting with errors; so the redefined \ProcessCommentLine additionally checks for \end{document} as a token for stopping comment mode, and then re-executes the proper \end{document} if that condition is encountered.

This means, one should be able to, in \doskip mode, to add \end{SKIPLINES} and \begin{SKIPLINES} at will, to define parts of the compilable regions, without needing to worry whether they are closed properly for the \end{document}: a single pair of \end{SKIPLINES} and \begin{SKIPLINES} should work, just as well as a doc with none of them (or with an additional \end{SKIPLINES}).

Obviously, this is not a truly proper solution (this one does not work with \inputted files), so I hope a more erudite answer will eventually emerge; but for now, here is the MWE (and sorry for the mess):

\documentclass[11pt]{book}
\usepackage{lipsum}
\usepackage{trace}

\newif\ifSKIPLINESAct % if active
\ifx\doskip\relax
  \typeout{DOSKIP}
  \usepackage{etoolbox}
  \usepackage{comment}
  \usepackage{xstring}
  \def\excludecommentB
   #1{\message{Excluding comment '#1'}%
      %\csarg\newif{if#1Act}% declare globally; http://tex.stackexchange.com/questions/228994/handling-a-conditionally-defined-newif-nested-in-an-ifx-conditional
      \csarg\def{#1}{\endgroup \message{Excluding '#1' comment.}%
          \csname #1Acttrue\endcsname
          \begingroup
             \DefaultCutFileName \def\ProcessCutFile{}%
             \def\ThisComment####1{}\ProcessComment{#1}}%
      \csarg\def{After#1Comment}{%
        \global\csname #1Actfalse\endcsname% must globalize - inside a group here!
        \CloseAndInputCutFile \endgroup}
      \CommentEndDef{#1}}
  % redef this too:
  \csarg\xdef{EndDocTest}{\string\end\string{document\string}}
%   \showme\EndDocTest
  {\catcode`\^^M=12 \endlinechar=-1 %
   \gdef\xComment#1^^M{\ProcessCommentLine}
   \gdef\ProcessCommentLine#1^^M{\def\test{#1}
        \typeout{test: \meaning\test, \expandafter\meaning \csname End\CurrentComment Test\endcsname}
        \csarg\ifx{End\CurrentComment Test}\test
            \edef\next{\endgroup\noexpand\EndOfComment{\CurrentComment}}%
        \else \ThisComment{#1}\let\next\ProcessCommentLine
        \fi%
        % also add for end document; use \IfStrEq else catcodes could be a problem
        \IfStrEq*{\EndDocTest}{\test}{%
            %\traceon%
            \typeout{yesend}%
            \def\next{%\endgroup\noexpand\EndOfComment{\CurrentComment}%
            \endgroup\noexpand\EndOfComment{\noexpand\CurrentComment}% % must add \noexpand to \CurrentComment, else it leaks and gets typeset in the doc!
            %\SKIPLINESActfalse% no; use:
            \AfterSKIPLINESComment% % both sets false and ends group
            \enddocument%
            }%
        }{\typeout{noend \meaning\test\space\meaning\EndDocTest}%\ThisComment{#1}\let\next\ProcessCommentLine% don't execute here, just typeout
        }%
        \next}
  }
  \excludecommentB{SKIPLINES} % define, also \ifSKIPLINESAct
  %\AtEndPreamble{ % here causes ! LaTeX Error: Missing \begin{document}.
  \AtBeginDocument{%
    % \expandafter\begin{SKIPLINES}\relax
    \begin{SKIPLINES}
  } % ! Extra \endgroup.
  %\AtEndDocument{\end{SKIPLINES}} % ! LaTeX Error: \begin{document} ended by \end{SKIPLINES}. % redefine instead?
  %% no need for this:
  % \global\let\oldenddocument\enddocument
  % \gdef\enddocument{% redefine
  %   %\ifSKIPLINESAct\expandafter\end\expandafter{SKIPLINES}\fi
  %   \oldenddocument%
  % }
\else
  % still need this, when calling without \doskip:
  \makeatletter
  \newenvironment{SKIPLINES}{%
  \begingroup\def\@currenvir{document}%
  }{%
  % comment.sty: % sabotage LaTeX's environment testing \begingroup\def\@currenvir{#1}\end{#1}
  \begingroup\def\@currenvir{SKIPLINES}%\endgroup
  }
  % \def\endSKIPLINES{\begingroup\def\@currenvir{SKIPLINES}} % nope
  \makeatother
\fi

% \traceon
\begin{document}

\chapter{Some chapter}
\section{Section One}
\lipsum[1-3]

% \traceon
\end{SKIPLINES}
% \traceoff
\lipsum[5]
\begin{SKIPLINES} % will cause ### semi simple group (level 2) entered at line 90 if without \doskip and unclosed, but doc will compile

\lipsum[10]

% \end{SKIPLINES} % if this is uncommented when \doskip, it will allow the next typeout to execute (else they will be gobbled)

% these print to stdout only if \end{SKIPLINES} occured last previously:
\typeout{\meaning\endSKIPLINES}
\ifx\doskip\relax
  \ifSKIPLINESAct\typeout{SKIPLINES Active}\else\typeout{no SKIPLINES}\fi%
\else
\fi

\end{document}
%%ENNDDD

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.