PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : _ und Catcode oder wie?



LuPi
01-07-2011, 09:40
Wie kann ich (möglichst einfach ;)) in folgendem Beispiel auch den zweiten
Eintrag "A_B" ohne Fehlermeldung setzen? \_ oder Ähnliches geht hier leider
nicht, da #1 einen Dateinamen darstellt, der definitiv _ enthalten kann.


\documentclass{scrartcl}
\newcommand{\IDAufgabe}[1]{#1}
\begin{document}
\IDAufgabe{AB}
\IDAufgabe{A_B}
\end{document}

Das geht sicherlich mittels Catcode-Spielerei, aber das ist mir zugegebenermaßen
ein Buch mit >= 7 Siegeln.

Xenara
01-07-2011, 10:00
Mit dem abgewandelten Beispiel von hier (http://www.tex.ac.uk/cgi-bin/texfaq2html?label=actinarg) scheint es so zu klappen:



\documentclass{scrartcl}

\def\IDAufgabe{%
\begingroup
\catcode`\_=\active
\XIDAufgabe
}
\def\XIDAufgabe#1{%
#1%
\endgroup
}

\begin{document}

\IDAufgabe{AB}
\IDAufgabe{A_B}

%A_B % Wenn einkommentiert, dann Fehlermeldung

\end{document}

u_fischer
01-07-2011, 10:05
\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\makeatletter
\newcommand{\IDAufgabe}{%
\begingroup\catcode`\_=11 \@IDAufgabe}
\newcommand\@IDAufgabe[1]{\endgroup#1}
\makeatother
\begin{document}
\IDAufgabe{AB}
\IDAufgabe{A_B}
\end{document}

T1-encoding ist wichtig, nur dort existiert der Unterstrich als Glyph. Ohne musst du _ eine geeignete Definition geben.

LuPi
01-07-2011, 12:50
Vielen Dank, Ihr Beiden, das funktioniert sehr schön.

Ich bin jetzt einen Schritt weiter, stocke aber leider schon wieder.


\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\makeatletter
\newcommand{\IDAufgabe}{%
\begingroup\catcode`\_=11 \@IDAufgabe}
\newcommand{\@IDAufgabe}[1]{}
\newcommand{\Aufgabe}[3]{%
% \renewcommand{\IDAufgabe}{%
% \begingroup\catcode`\_=11 \@IDAufgabe}
\renewcommand\@IDAufgabe[1]{\endgroup#1}
ID: \IDAufgabe
}
\makeatother
\begin{document}
Test1 \Aufgabe{}{}{A_B}

Test2 \Aufgabe{}{}{AB}
\end{document}


Ich möchte in \Aufgabe dem Makro \IDAufgabe jeweils einen neuen Wert
zuweisen. So, wie oben gezeigt, läuft das leider nicht. Aber wie dann?

u_fischer
01-07-2011, 13:09
Ich verstehe nicht, was du machen willst. Aber du darfst auf keinen Fall \Aufgabe als Befehl mit drei Argumenten definieren. Dann wird {A_B} vor der \catcode-Änderungen gelesen. Der wesentliche Trick von \IDAufgabe/\@IdAufgabe ist, dass \IDAufgabe kein Argument hat, sondern zuerst den \catcode ändert und dann \@IDAufgabe aufruft, dass nun sein Argument mit den neuen catcode-Werten einliest.

LuPi
01-07-2011, 13:20
Dann versuche ich das mit einem anderen Ansatz:


\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\newcommand{\IDA}{}
\newcommand{\IDAufgabe}[1]{\renewcommand{\IDA}{A_B}}
\begin{document}
\IDAufgabe{A_B}
\begingroup\catcode`\_=11 \IDA\endgroup
\end{document}


Das funktioniert so aber leider auch nicht. Der Ansatz ist sicherlich etwas naiv.
Ich stelle mich vor, dass ich mit der Catcode-Umschaltung innerhalb der Gruppe
den Unterstrich auf \active umschalte. Aber da habe ich sicherlich etwas
übersehen beziehungsweise nicht verstanden.

u_fischer
01-07-2011, 16:52
Der Ansatz ist sicherlich etwas naiv.


Wenn nicht sogar wirr.


\newcommand{\IDAufgabe}[1]{\renewcommand{\IDA}{A_B}}


Damit steckt in \IDA A_B mit dem normalen Catcode. Den kannst du jetzt nicht mehr ändern. Bevor du weiter rumwurstelst versuche zu verstehen, was in Xenaras und meinem Code passiert. LaTeX ordnet beim Einlesen den Buchstaben einen catcode zu. Dieser catcode ist danach fest, er ist wie ein Schildchen, das an dem Buchstaben klebt:


\catcode`\A=12
A %ein A mit catcode 12
\catcode`\A=11
A % ein A mit catcode 11
\def\xxx{A} %\xxx enthält ein A mit catcode 11

Je nach catcode hat ein Zeichen eine andere Funktion. catcode 11 (wie ich es gemacht habe) macht etwas zu einem normalen Buchstaben (kann also in Befehlsnamen benutzt werden), catcode 12 ist "other" (so Kram wie Punkte und Komma), catcode 13 = \active macht etwas zu einem "1-Zeichen-Befehl".

LuPi
01-07-2011, 18:09
Hmm. Damit werde ich mich ab Montag mit etwas mehr Ruhe beschäftigen
(ich weiß schon, warum ich einen großen Bogen um derartige Interna mache).

Ein zusätzlicher Punkt dabei ist folgender: Führt es zu Problemen, wenn ich
das Argument danach noch im Argument eines \input{} benötige?
\IDAufgabe{A} soll letztlich A setzen und anschließend A.tex einlesen. Da
werde ich nächste Woche wohl noch etwas Gehirnschmalz investieren müssen.

Vielen Dank und ein schönes Wochenende

u_fischer
02-07-2011, 11:48
Führt es zu Problemen, wenn ich
das Argument danach noch im Argument eines \input{} benötige?
\IDAufgabe{A} soll letztlich A setzen und anschließend A.tex einlesen.

Nun als Beispiel, wenn du A den catcode "\active" zuordnen würdest (damit wäre A ein 1-Zeichen-Befehl) und dann \def A{Hallo} definierst, dann würde \input{A} versuchen hallo.tex zu laden. Das kann schon zu unerwünschten Ergebnissen führen ;-). Es gibt aber Lösungen: Du kannst mit \scantokens und \detokenize Eingabezeichen sozusagen "noch einmal" einzulesen und dadurch die \catcode's wieder ändern.


ich weiß schon, warum ich einen großen Bogen um derartige Interna mache

Du wirst nicht darum herum kommen, etwas darüber zu lernen.

LuPi
04-07-2011, 07:25
Hallo Ulrike, vielen Dank für Deine Hilfe und auch die sicherlich berechtigte
Aufforderung, mich tiefer in TeX zu stürzen. Glücklicherweise ist es dieses Mal
doch noch nicht erforderlich. Mehr oder weniger durch Zufall bin ich gerade
darauf gestoßen, dass ich an anderer Stelle etwas ganz Ähnliches anwende:
\nolinkurl{\IDAufgabe}. Und das funktioniert seit längerer Zeit ohne hässliche
Nebeneffekte.