goLaTeX - Mein LaTeX-Forum

Mein LaTeX-Forum


Login  | Registrieren
Direktlinks:
Zuletzt aktive Beiträge
Unbeantwortete Beiträge
[Erweitert]

Forenstatistik:
Beiträge: 98011
Top-Poster: Johannes_B (5059)

Wir begrüßen unseren neuesten Benutzer katjaa.

Links:


Mit Unterstützung von DANTE e.V.: Deutschsprachige Anwendervereinigung TeX. Danke den Mitgliedern!





Forum
      Option
[Erweitert]
  • Diese Seite weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Parsen bei \newcommand unterdrücken?

 

Rolli
Forum-Guru
Forum-Guru

Beiträge: 321
Anmeldedatum: 15.02.17
Wohnort: Mittelfranken
Version: MikTeX 2.9 64-bit
     Beitrag Verfasst am: 08.02.2019, 00:33     Titel: Parsen bei \newcommand unterdrücken?
  Antworten mit Zitat      
Hallo allerseits,

ich habe mal wieder ein (vermutlich recht kleines) Problem, das ich aber nicht alleine hin bekomme - mein altes Thema: Ich suche schon seit längerer Zeit, aber vermutlich mit dem falschen Suchbegriff (schäm).

Die Frage ist eigentlich recht simpel: Was muss ich \newcommand mitgeben bzw. ändern, damit der LaTeX-Compiler die übergebenen Argumente nicht parst, sondern 1:1 weiter gibt? Und dass mein selbst definiertes Makro das ebenfalls fehlerfrei verarbeiten kann? Sozusagen etwas in der Art, wie es verbatim macht.

Im InfoMinimalbeispiel möchte ich, dass der zweite \myCommand-Aufruf einfach Hello_world! setzt, ohne das Gemeckere, dass eine Mathematik-Umgebung fehle.

Code • Öffne in Overleaf

\documentclass{scrartcl}

\begin{document}
\newcommand{\myCommand}[1]{#1}

\myCommand{Hello, world!\par} % funktioniert natürlich
\myCommand{Hello_world!\par}  % bringt Fehler
\end{document}
 


Danke für Eure Gedankenanstöße!

Gruß vom Rolli
_________________

Rolli's Korollar:
Jede Aktion führt zu (meist unerwünschten)
Nebeneffekten.
Beweis: Rückführung auf Murphy's Gesetz.
-----------------------------------------------------
Linux ist ein Betriebssystem.
WinDoof ist ein Zustand!
-----------------------------------------------------
Fleißiges Löschen der .AUX-Datei führt oft zum Ziel.
-----------------------------------------------------
Beim Arbeiten mit TeX/LaTeX sollten die Dateipfade
weder Umlaute/ß noch Leerräume noch sonstige
Nicht-ASCII7-Zeichen (wie beispielsweise diakritische
Zeichen) haben.
Private Nachricht senden Benutzer-Profile anzeigen

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.02.2019, 09:10     Titel:
  Antworten mit Zitat      
Das Zauberwort heißt \catcode. Der Category-Code eines Zeichens bestimmt, was für ein Token beim Einlesen des Quellcodes gebildet wird. Das bedeutet, sobald ein Zeichen gelesen ist, ist es zu spät dafür.

Genau damit arbeitet \verb. Deshalb ist \verb auch nicht so definiert, dass es selbst ein Argument einliest. Im LaTeX-Kern wirst Du also weder etwas wie \newcommand*{\verb}[1] noch etwas wie \def\verb#1 finden. Stattdessen beginnt es mit \def\verb{. Dann wird als zentrales Element eine Gruppe geöffnet, Category-Codes geändert (u. a. über \dospecials) und weitere Umdefinierungen vorgenommen und erst dann wird das Argument gelesen, wobei das im Fall on \verb auch noch ziemlich ungewöhnlich erfolgt, weil \verb eine sehr spezielle Form eines Argument verarbeitet. Am Ende muss natürlich auch noch die Gruppe wieder geschlossen und damit die Änderungen rückgängig gemacht werden.

Es wird also nicht etwa das Parsen unterdrückt, sondern der Parser umprogrammiert, bevor das Argument gelesen wird.

Es ist zu beachten, dass einige Zeichen im normalen Encoding von Fonts gar nicht in der gewünschten Form enthalten sind. Beispielsweise würde ein \ im normalen Textfont nicht funktionieren, weil auf der entsprechenden Code-Position ein anderes Zeichen liegt. Deshalb ergeben beispielsweise \string\test und \texttt{\string\test} unterschiedliche Ergebnisse.

In deinem Fall kommt erschwerend hinzu, dass Du offenbar gar nicht das Verhalten von \verb willst. Das würde nämlich \par als Text ausgeben und keinen Absatz erzeugen. Damit käme eher die Verwendung der alltt-Umgebung des Pakets alltt in Frage, beispielsweise in der Form:
Code • Öffne in Overleaf
\documentclass{scrartcl}
\usepackage{alltt}

\makeatletter
\newcommand{\myCommand}{%
  \begin{alltt}\@myCommand
}
\newcommand{\@myCommand}[1]{#1\end{alltt}}
\makeatother

\begin{document}
\myCommand{Hello, world!\par} % funktioniert natürlich
\myCommand{Hello_world!\par}  % funktioniert natürlich auch
\end{document}

Die Gruppe (in Form der Umgebung alltt wird hier also geöffnet und damit Category-Codes geändert, bevor \@myCommand das Argument liest.

An dem Beispiel kann man auch zeigen, dass das ganze von \ttfamily abhängt:
Code • Öffne in Overleaf
\documentclass{scrartcl}
\usepackage{alltt}

\makeatletter
\newcommand{\myCommand}{%
  \begin{alltt}\normalfont\@myCommand
}
\newcommand{\@myCommand}[1]{#1\end{alltt}}
\makeatother

\begin{document}
\myCommand{Hello, world!\par} % funktioniert natürlich
\myCommand{Hello_world!\par}  % funktioniert natürlich auch
\end{document}
bringt nicht das gewünschte Ergebnis, weil normalerweise an der Code-Position von _ ein anderes Zeichen liegt. Man müsste also diverse Zeichen noch explizit umdefinieren, beispielsweise:
Code • Öffne in Overleaf
\documentclass{scrartcl}
\usepackage{alltt}

\makeatletter
\newcommand{\myCommand}{%
  \begin{alltt}\normalfont\myCommand@extraspecials\@myCommand
}
\newcommand{\@myCommand}[1]{#1\end{alltt}}
\begingroup
\catcode`\_=\active
\gdef\myCommand@extraspecials{%
  \catcode`\_=\active
  \let_=\_
}
\makeatother

\begin{document}
\myCommand{Hello, world!\par} % funktioniert natürlich
\myCommand{Hello_world!\par}  % funktioniert natürlich auch
\end{document}

Du siehst, das ganze kann je nachdem, was man braucht und will, recht aufwändig werden. Dagegen ist es recht einfach, ein zweites \verb zu definieren, also eine Anweisung, die sich tatsächlich wie \verb verhällt:
Code • Öffne in Overleaf
\documentclass{scrartcl}
\newcommand*{\myCommand}{}
\let\myCommand\verb

\begin{document
}
\myCommand*+Hello, world!\par+ % funktioniert natürlich
\myCommand+Hello_world!\par+  % funktioniert natürlich auch
\end{document}


Wenn Du Dich tiefer mit Category-Codes und der Funktion des Scanners und des Parsers von TeX beschäftigen willst, sei auf TeX by Topic verwiesen (ist seit einigen Jahren frei erhältlich und zumindest bei TeX Live sogar dabei). Daneben natürlich auf das Standardwerk zu TeX: The TeXbook. Letzteres ist wirklich schwere Kost. Wer das verstanden hat, hat dann aber auch verstanden, wie TeX funktioniert und warum einige scheinbar einfache Dinge nicht ganz einfach zu lösen sind.

u_fischer
Forum-Meister
Forum-Meister


Beiträge: 3894
Anmeldedatum: 22.11.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.02.2019, 10:27     Titel:
  Antworten mit Zitat      
Nun, die einfache Variante wäre \detokenize. Aber ich habe den Verdacht, dass du nicht wirklich willst, dass dein Befehl sich verbatim verhält, sondern dass du nur bestimmte Eingaben (wie _) anders behandeln willst.


Code • Öffne in Overleaf
\documentclass{scrartcl}
\usepackage[T1]{fontenc} %wichtig für korrekte Ausgabe
\begin{document}
\newcommand{\myCommand}[1]{\detokenize{#1}}

\verb+Hello_world!\par+

\myCommand{Hello, world!\par} % funktioniert natürlich
\myCommand{Hello_world!\par}  %
\end{document}
 

_________________

Ulrike Fischer
www.troubleshooting-tex.de
Private Nachricht senden Benutzer-Profile anzeigen

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.02.2019, 11:18     Titel:
  Antworten mit Zitat      
u_fischer hat Folgendes geschrieben:
Nun, die einfache Variante wäre \detokenize.

Wobei \detokenize Leerzeichen nach vermeintlichen Befehlen einfügt:
Code • Öffne in Overleaf
\documentclass{scrartcl}
\usepackage[T1]{fontenc} %wichtig für korrekte Ausgabe
\begin{document}
\newcommand{\myCommand}[1]{\detokenize{#1}}

\verb+Hello_world!\par\par+

\myCommand{Hello, world!\par\par} % funktioniert natürlich
\myCommand{Hello_world!\par\par}  %
\end{document}
und die Ausgabe eben wieder vom Font-Encoding abhängt. Ob das eine Rolle spielt, hängt vom tatsächlichen Einsatzzweck ab.

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.02.2019, 11:23     Titel:
  Antworten mit Zitat      
Anonymous hat Folgendes geschrieben:
Ob das eine Rolle spielt, hängt vom tatsächlichen Einsatzzweck ab.

Verwendet man beispielsweise Umlaute mit pdflatex, so spielt das recht schnell eine Rolle:
Code • Öffne in Overleaf
\documentclass{scrartcl}
\usepackage[T1]{fontenc} %wichtig für korrekte Ausgabe
\begin{document}
\newcommand{\myCommand}[1]{\detokenize{#1}}

\verb+Märchen+ vs. \myCommand{Märchen}
\end{document}

Mit lualatex ist zumindest das hingegen kein Problem.
Code • Öffne in Overleaf
\documentclass{scrartcl}
\usepackage{fontenc}
\begin{document}
\newcommand{\myCommand}[1]{\detokenize{#1}}

\verb+Märchen+ vs. \myCommand{Märchen}
\end{document}

Die Ausgabe von \detokenize ist also nicht nur vom Font-Encoding, sondern auch von der Eingabecodierung abhängig und so indirekt auch von der Engine.

Rolli
Forum-Guru
Forum-Guru

Beiträge: 321
Anmeldedatum: 15.02.17
Wohnort: Mittelfranken
Version: MikTeX 2.9 64-bit
     Beitrag Verfasst am: 08.02.2019, 15:30     Titel: Konkrete Anwendung
  Antworten mit Zitat      
Ohje, was habe ich da wieder angerichtet! Ich dachte, es sei ganz einfach ...
Zunächst Euch vielen Dank für die Informationen - wieder was gelernt.
So richtig weiter komme ich damit aber nicht. Ich möchte Folgendes tun:
Im Dateisystem habe ich hierarchisch verschiedene Dokumente, und ich möchte eine Übersicht erstellen, welche Unterverzeichnisse und Dokumente vorhanden sind. Das Ganze soll anklickbar sein - so dass sich - je nach Eintragtyp - automatisch ein Explorerfenster (bei Verzeichnissen), oder ein PDF-Betrachter usw. öffnet.
Das funktioniert auch alles ganz gut - bis auf den Umstand, dass es leider Dateienamen gibt, in denen ein Underscore _ ist; möglicherweise auch ein Prozent %. Unten ein konkretes Beispiel.

Mit alltt geht das leider nicht, da ich in meinem \aEntry das \item drin habe.
Ich fürchte, da muss ich mich mit \catcode auseinandersetzen - oder hat jemand eine einfachere Idee?

Gruß vom Rolli

Code • Öffne in Overleaf

\documentclass{scrartcl}
\usepackage{xcolor}
\usepackage{csquotes}
\usepackage{hyperref}

\begin{document}

\newcommand\aEntry[4]{% #1 FILE oder DIR    #2 Farbe    #3 Link    #4 Beschreibungstext
   \item [\color{#2}#1] \href[pdfnewwindow]{run:#3}{\color{#2}\textquote{#3}}{\color{#2}: #4}
}

\begin{description}
   \aEntry{FILE}{black}{Uebersicht.pdf}{Diese Datei}
   \aEntry{DIR~}{black}{Beispiele}{In diesem Unterverzeichnis sind die Beispiele}
   \begin{description}
      \aEntry{FILE}{red}{Beispiele/Beispiel1.tex}{Hier ist das erste Beispiel}
      \aEntry{FILE}{black}{Beispiele/Beispiel2.tex}{Hier ist das zweite Beispiel}
      \aEntry{DIR~}{black}{Beispiele/Fortgeschritten}{In diesem Unterverzeichnis sind kompliziertere Beispiele}
      \begin{description}
         \aEntry{FILE}{red}{Beispiele/Fortgeschritten/Beispielx.tex}{Hier ist ein kompliziertes Beispiel}
      \end{description}
   \end{description}
\end{description}

\end{document}
 

_________________

Rolli's Korollar:
Jede Aktion führt zu (meist unerwünschten)
Nebeneffekten.
Beweis: Rückführung auf Murphy's Gesetz.
-----------------------------------------------------
Linux ist ein Betriebssystem.
WinDoof ist ein Zustand!
-----------------------------------------------------
Fleißiges Löschen der .AUX-Datei führt oft zum Ziel.
-----------------------------------------------------
Beim Arbeiten mit TeX/LaTeX sollten die Dateipfade
weder Umlaute/ß noch Leerräume noch sonstige
Nicht-ASCII7-Zeichen (wie beispielsweise diakritische
Zeichen) haben.
Private Nachricht senden Benutzer-Profile anzeigen

Neues Thema eröffnen Neue Antwort erstellen



Options and Permissions
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum herunterladen
.

goLaTeX ist Teil der goForen
goForen.de goMATLAB.de goLaTeX.de


  Datenschutzerklärung | Impressum | FAQ | goLaTeX RSS Button RSS-Feed

Copyright © 2008 - 2019 goLaTeX.de