Başar Alabay schrieb:
Teile mitten in einer Quelltextzeile auskommentieren, so dass sie gar
nicht gelesen werden und keine (in späteren Schritten zu verar-
beitenden) Token gebildet werden, geht nicht.
Auskommentieren, so dass er nicht gelesen wird und keine (in späteren
Schritte zu verarbeitenden) Token gebildet werden, kann man nur den
ganzen Rest einer Quelltextzeile.
Aber ich kann einen Mechanismus anbieten, mit dem man nicht
auf Quelltextebene, also bereits beim Einlesen und Tokenizen,
Zeilenteile auskommentiert, sondern mit dem man Dinge
unter dem catcode-Régime des \verb-Befehls einlesen lassen
und die entstehenden Token entweder an \scantokens weiterreichen
oder per \@gobble "verschlucken" lassen kann.
Dieser Mechanismus sollte ähnlich funktionieren wie das
comment-Package.
Der Unterschied sollte sein:
Mit den Befehlen \includecomment bzw \excludecomment des comment-Package
definiert man Umgebungen, deren Inhalt übernommen resp. nicht übernommen
wird.
Mit den Befehlen
\MyIncludeCommentmarkerCommand{<Kontrollsequenz-Token>}
bzw
\MyExcludeCommentmarkerCommand{<Kontrollsequenz-Token>}
aus meinem Mechanismus definiert man Makros, die ein Argument gemäß
\verb-Syntax (oder mit geschweiften Klammern, wobei dann auch verschachtelte
geschweifte Klammern erlaubt sind) "verbatimisiert", d.h. mit dem
catcode-Régime des \verb-Befehls, einlesen und dieses Argument
per \scantokens ausgeben resp. per \@gobble "verschlucken".
Im Gegensatz zu \verb erlauben meine Makros Argumente, die über
mehrere Zeilen gehen.
[ Innerhalb von \scantokens wird mit \endinput gearbeitet, so dass
das letzte beim "Einleseteil" von \scantokens gemäß \endlinechar
eingefügte Endzeilenzeichen (normalerweise ^^M; ^^M wiederum
hat normalerweise CatCode 5 und wird entweder zu gar nichts
oder zu einem Leerzeichen oder zu einem \par-Token, je nach
Status des Leseapparatus) nicht ins Gewicht fällt.]
Der Mechanismus (bzw die mit ihm definierten Makros) funktioniert
(bzw funktionieren) _nicht_ innerhalb von Argumenten, die von
Makros bzw Kontrollsequenzen bzw Active Characters bzw dergleichen
verarbeitet werden, da hier die entsprechenden Quelltext-Sequenzen
bereits fürs Verarbeiten der Argumente dieser Makros / Kontrollsequenzen /
Active Characters unter normalem Catcode-Régime eingelesen und getokenized
worden sind, sod ass kein Einlesen unter \verb-Catdode-Régime mehr
stattfinden kann...
Der Mechanismus "geht davon aus", dass \endlinechar den üblichen
Wert 13 = `\^^M = ASCII-Return hat und dass \newlinechar den üblichen
Wert 10 = `\^^J hat, dass also beim Schreiben auf Terminal/Bildschirm
oder in externe Dateien beim Auftauchen von zu schreibenden Character-Token
mit Character-Code `\^^J angefangen wird, in eine neue Zeile zu schreiben.
Den Mechanismus habe ich eben in sieben Minuten spontan aus Sachen
zusammengeschustert, die ich schon früher gebastelt habe,
Ich habe ihn nicht exzessiv getestet.
Ich gebe also keinerlei Gewähr.
Im Rahmen der LPPL kann aber gerne jede/r die Sacbe _auf eigenes Risiko_
nach eigenem Gusto ausprobieren/testen/verwenden/ausschlachten/verwerfen/
was auch immer ...
Falls man unter Verwendung eines Web-Interface wie google-Groups fürs Lesen
von Usenet-Postings gerne per Copy-Paste Teile meines Codes aus diesem Posting
herauskopieren möchte, empfehle ich, dieses Posting im "Originalformat"
anzeigen zu lassen.
Solche Web-Interfaces tendieren nämlich dazu, Text, und damit leider auch
Quelltext, neu umzubrechen - in der Annahme, die Sache sähe dann hübscher
und/oder lesbarer aus.
Bei meinem Code ist aber "streckenweise" der Zeilenumbruch entscheidend und
es kann gut sein, dass er nicht mehr (korrekt) funktioniert wenn er anders
umbrochen wird.
\documentclass{article}
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% June 25, 2013 / by Ulrich Diez (
eu_an...@web.de) / License: LPPL.
%
% Stuff for reading arguments "verbatim":
%
% Syntax of \UDverbarg:
%
% \UDverbarg{<^^M-replacement>}{<Mandatory 1>}{<Mandatory 2>}<verbatim-Arg>
%
% yields:
%
% <Mandatory 1>{<Mandatory2>{<verbatim-Arg>}}
%
% with each character ^^M (usually=\endline-char) replaced by
% token-sequence <^^M-replacement>
%
% The Mandatory-Arguments are mandatory. If they consist of several
% tokens, they must be nested into catcode-1/2-character-pair / braces.
% If reading is necessary, they will be read under normal catcode-
% conditions.
% The verbatim-Arg is also mandatory. It will be read under
% verbatim-catcode-conditions. If its first character is a brace,
% it will be "assumed" that the argument is nested into braces.
% Otherwise it will be assumed, that the argument is delimited
% by the first character - like the argument of \verb.
%
% Empty-lines will not be ignored.
%
% By nesting calls to \UDverbarg within \UDverbarg's first
% argument, you can collect "verbatim-arguments" within its second
% argument.
%
% E.g.,
%
% \UDverbarg{<^^M-replacement>}{\UDverbarg{<^^M-replacement>}{\UDverbarg{<^^M-replacement>}{<actionA>}}}% <- Mandatory 1
% {<actionB>}% <- Mandatory
% <verbatim-Arg1><verbatim-Arg2><verbatim-Arg3>
%
% yields:
%
% \UDverbarg{<^^M-replacement>}{\UDverbarg{<^^M-replacement>}{<actionA>}}% <- Mandatory 1
% {<actionB><verbatim-Arg1>}% <- Mandatory 2
% <verbatim-Arg2><verbatim-Arg3>
%
% yields:
%
% \UDverbarg{<^^M-replacement>}{<actionA>}% <- Mandatory 1
% {<actionB>{<verbatim-Arg1>}{<verbatim-Arg2>}}% <- Mandatory 2
% <verbatim-Arg3>
%
% yields:
%
% <actionA>{<actionB>{<verbatim-Arg1>}{<verbatim-Arg2>}{<verbatim-Arg3>}}
%
% Assume <actionA> = \@firstofone -> equals:
%
% \@firstofone{<actionB>{<verbatim-Arg1>}{<verbatim-Arg2>}{<verbatim-Arg3>}}
%
% yields:
%
% <actionB>{<verbatim-Arg1>}{<verbatim-Arg2>}{<verbatim-Arg3>}
\begingroup
\catcode`\^^M=12 %
\@firstofone{%
\endgroup%
\newcommand*\UDEndlreplace[2]{%
\romannumeral0\@UDEndlreplace{#2}#1^^M\relax{}%
}%
\newcommand\@UDEndlreplace{}%
\def\@UDEndlreplace#1#2^^M#3\relax#4#5{%
\ifx\relax#3\relax%
\expandafter\@firstoftwo%
\else%
\expandafter\@secondoftwo%
\fi%
{ #5{#4#2}}{\@UDEndlreplace{#1}#3\relax{#4#2#1}{#5}}%
}%
}%
\newcommand\UDverbarg[3]{%
\@bsphack
\begingroup
\let\do\@makeother\dospecials
\catcode`\{=1 %
\catcode`\ =10 %
\@ifnextchar\bgroup
{\catcode`\}=2 \@UDverbarg{#1}{#2}{#3}{}}%
{\do\{\@UDverbarg{#1}{#2}{#3}}%
}%
\newcommand\@UDverbarg[4]{%
\do\ %
\catcode`\^^M=12 %
\long\def\@tempb##1#4{%
\edef\@tempb{##1}%
\@onelevel@sanitize\@tempb
\expandafter\UDEndlreplace\expandafter{\@tempb}{#1}{\def\@tempb}%
\expandafter\@@UDverbarg\expandafter{\@tempb}{#2}{#3}%
}%
\@tempb
}%
\newcommand\@@UDverbarg[3]{%
\endgroup
\@esphack
#2{#3{#1}}%
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand*\UDRemoveTillCharacterMarker{%
\@bsphack\UDverbarg{^^J}%
{\expandafter\@esphack\@gobble}%
{}%
}%
\newcommand\UDCallScantokens[1]{\scantokens{#1\endinput}}%
\newcommand*\UDKeepTillCharacterMarker{%
\UDverbarg{^^J}%
{\@firstofone}%
{\UDCallScantokens}%
}%
\newcommand\MyIncludeCommentmarkerCommand[1]{%
\global\let#1=\UDKeepTillCharacterMarker
}%
\newcommand\MyExcludeCommentmarkerCommand[1]{%
\global\let#1=\UDRemoveTillCharacterMarker
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatother
\MyIncludeCommentmarkerCommand{\CommentMarkerA}
%\MyExcludeCommentmarkerCommand{\CommentMarkerA}
\MyExcludeCommentmarkerCommand{\CommentMarkerB}
%\MyIncludeCommentmarkerCommand{\CommentMarkerB}
\begin{document}
Hier ein Beispiel mit \texttt{\string\verb}-Syntax:
Normaler Text A. \CommentMarkerA~Das bleibt. Das bleibt.~ Normaler Text A.
Normaler Text A. \CommentMarkerA|Das bleibt. Und der naechste Absatz
auch:
Hier ist der naechste Absatz.
Auch \texttt{\string\verb} bleibt: \verb-\TeX- Text.| Normaler Text A.
Normaler Text A. Normaler Text B. \CommentMarkerB|Das bleibt nicht.| Normaler
Text B. Normaler Text B. \CommentMarkerB|Das bleibt nicht und der naechste
Absatz auch nicht:
Hier ist der naechste Absatz.| Normaler Text B. Normaler Text B.
\bigskip
Hier ein Beispiel mit geschweifte-Klammern-Syntax:
Normaler Text A. \CommentMarkerA{Das bleibt. {Das} bleibt.} Normaler Text A.
Normaler Text A. \CommentMarkerA{Das bleibt. Und der naechste Absatz
auch:
Hier ist der naechste Absatz.
Auch \texttt{\string\verb} bleibt: \verb-\TeX- Text.} Normaler Text A.
Normaler Text A. Normaler Text B. \CommentMarkerB{Das {b{leibt}} nicht.} Normaler
Text B. Normaler Text B. \CommentMarkerB{Das {blei{bt nicht und der naechste
Abs}a}tz auch {nicht:
Hier} ist der naechste Absatz.} Normaler Text B. Normaler Text B.
\bigskip
Hier was mit und ohne Mais und mit und ohne Gurken:
\MyExcludeCommentmarkerCommand{\MaisOderGurken}
\MyIncludeCommentmarkerCommand{\Mais}
\MyIncludeCommentmarkerCommand{\Gurken}
\Mais{\MyIncludeCommentmarkerCommand{\MaisOderGurken}}
\Gurken{\MyIncludeCommentmarkerCommand{\MaisOderGurken}}
Dies ist ein Satz%
\MaisOderGurken{, der von }\Mais{gelbem Mais }\Mais{\Gurken{und
von }}\Gurken{gruenen Gurken }\MaisOderGurken{handelt}.
\MyExcludeCommentmarkerCommand{\MaisOderGurken}
\MyIncludeCommentmarkerCommand{\Mais}
\MyExcludeCommentmarkerCommand{\Gurken}
\Mais{\MyIncludeCommentmarkerCommand{\MaisOderGurken}}
\Gurken{\MyIncludeCommentmarkerCommand{\MaisOderGurken}}
Dies ist ein Satz%
\MaisOderGurken{, der von }\Mais{gelbem Mais }\Mais{\Gurken{und
von }}\Gurken{gruenen Gurken }\MaisOderGurken{handelt}.
\MyExcludeCommentmarkerCommand{\MaisOderGurken}
\MyExcludeCommentmarkerCommand{\Mais}
\MyIncludeCommentmarkerCommand{\Gurken}
\Mais{\MyIncludeCommentmarkerCommand{\MaisOderGurken}}
\Gurken{\MyIncludeCommentmarkerCommand{\MaisOderGurken}}
Dies ist ein Satz%
\MaisOderGurken{, der von }\Mais{gelbem Mais }\Mais{\Gurken{und
von }}\Gurken{gruenen Gurken }\MaisOderGurken{handelt}.
\MyExcludeCommentmarkerCommand{\MaisOderGurken}
\MyExcludeCommentmarkerCommand{\Mais}
\MyExcludeCommentmarkerCommand{\Gurken}
\Mais{\MyIncludeCommentmarkerCommand{\MaisOderGurken}}
\Gurken{\MyIncludeCommentmarkerCommand{\MaisOderGurken}}
Dies ist ein Satz%
\MaisOderGurken{, der von }\Mais{gelbem Mais }\Mais{\Gurken{und
von }}\Gurken{gruenen Gurken }\MaisOderGurken{handelt}.
\end{document}
========================================================================
Eine einfache Alternative könnte sein, zwischen dem Auskommentieren und
dem Beibehalten von Zeilenteilen an Zeilenenden hin- und herzuschalten,
indem man ein eher selten gebrauchtes Zeichen, zB ^^A verwendet und
ihm mal den catcode 14 (comment) und mal den catcode 9 (ignored)
zuweisen lässt.
Mit catcode 14 (comment) wird das Zeichen vom Leseapparatus "als Anlass
genommen", dahinterstehende Zeilenteile nicht mehr zu lesen und sich
gleich der nächsten Zeile zuzuwenden. Die besagten Zeilenteile werden
in diesem Fall also vom Leseapparatus ignoriert.
Mit catcode 9 (ignore) wird das Zeichen selbst beim Einlesen und Tokenizen
ignoriert sodass nachfolgende Zeilenteile eingelesen und getokenized
werden.
Beispiel:
\documentclass{article}
\begin{document}
\catcode`\^^A=14\relax
Der folgende Zeilenteil erscheint nicht:^^A Folgender Zeilenteil.
\catcode`\^^A=9\relax
Der folgende Zeilenteil erscheint:^^A Folgender Zeilenteil.
\end{document}
Ulrich