Anzeige:
Seite 2 von 2 ErsteErste 12
Ergebnis 16 bis 24 von 24

Thema: expandieren von befehlen

  1. #16
    Registrierter Benutzer Avatar von Stefan_K
    Registriert seit
    05.04.2007
    Ort
    Hamburg
    Beiträge
    3.534

    Makro-Expansion

    Hallo Herbert,

    statt wie in Beitrag #4 und #13 herumzusticheln, könntest Du konstruktiv zeigen, wie man es in solchen Fällen dennoch schaffen könnte, oder auch danach fragen. \expandafter ist ein ganz simpler Befehl, die Mehrfachanwendung lässt es nur scheinbar komplizierter aussehen.

    Zitat Zitat von voss Beitrag anzeigen
    aber es funktioniert eben bei jeder Menge an Befehlen nicht!
    Wie nun schon genannt, funktioniert es nicht bei Befehlen, die nicht expandiert werden. Während \g@addto@macro aus diesem Grund scheitert, kann man die \expandafter-Variante leicht modifizieren, um hierin das Expandieren zu erzwingen.

    Zitat Zitat von voss Beitrag anzeigen
    Code:
    \expandafter\def\expandafter\exists\expandafter{\exists\quad}
    das war das Ausgangsproblem und auch da geht deine Lösung nicht!
    So modifiziert geht sie:
    Code:
    \expandafter\def\expandafter\exists\expandafter{\expandafter\mathchar\the\exists\quad}
    Zitat Zitat von voss Beitrag anzeigen
    Die Verfahren \g@addto@macro ist faktisch das gleiche wie die \expandafter.-Orgie
    Dass \g@addto@macro jedoch global wirkt, also über die Grenzen einer Umgebung hinaus, ist ein bedeutsamer Unterschied. So definieren manche Klassen (KOMA) und Pakete eine lokale Variante \l@addto@macro, die hier auch genannt werden dürfte.

    Rainer, mit \edef kann man es auch so hinkriegen:
    Code:
    \edef\exists{\mathchar\the\exists\quad}
    Der \the-Trick samt \expandafter ist natürlich eher was für Interessierte, in der Praxis ist es einfacher, wenn man ein neues Makro definiert und mit \let und \renewcommand arbeitet.

    Micha, es freut mich, dass Dich die Hintergründe interessieren. Vielleicht schau einmal in diese Liste: plain TeX books. Darunter finde ich das Buch "TeX by Topic" sehr gut zugänglich. Das TeXbuch von Knuth ist natürlich die Referenz und sehr zu empfehlen.

    Viele Grüße,

    Stefan

  2. #17
    Registrierter Benutzer Avatar von voss
    Registriert seit
    10.04.2005
    Beiträge
    5.045
    Zitat Zitat von Stefan_K Beitrag anzeigen
    So modifiziert geht sie:
    Code:
    \expandafter\def\expandafter\exists\expandafter{\expandafter\mathchar\the\exists\quad}
    klar ist ja auch viel einfacher als die \let-Variante ...
    oder
    Code:
     \def\exists{\mathchar"239\quad}
    Nichts für ungut ...

    Herbert

  3. #18
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.863
    Danke Herbert und Stefan,

    ich hab mal versucht, erst per \meaning herauszufinden, ob ein \mathchar notwendig wäre:
    Code:
    \documentclass[12pt]{article}
    \mathchardef\emacromc="0123
    \def\emacrosm{short}
    
    \def\foo{foo}
    \long\def\foobar{foobar}
    \def\firstofndqi#1"#2\null{#1}
    \def\firstofndq#1{\expandafter\firstofndqi#1"\null}
    \def\firstofnci#1:#2\null{#1}
    \def\firstofnc#1{\expandafter\firstofnci#1:\null}
    \newcommand*\emacrotmpi{}
    \newcommand*\emacrotmpii{}
    \newcommand*\emacro[2]{%
      \edef\emacrotmpii{\firstofndq{\meaning\emacromc}}%
      \edef\emacrotmpi{\firstofndq{\meaning#1}}%
      \ifx\emacrotmpi\emacrotmpii
        \edef#1{\mathchar\the#1 #2}%
      \else
        \edef\emacrotmpii{\firstofnc{\meaning\emacrosm}}%
        \edef\emacrotmpi{\firstofnc{\meaning#1}}%
        \ifx\emacrotmpi\emacrotmpii
          \edef#1{#1#2}%
        \else
          \typeout{Warnung: \string\emacro\ hat sich geweigert, \emacrotmpi\ zu expandieren!}
        \fi
      \fi
    }
    \begin{document}
    \emacro\exists{\quad}
    \emacro\forall{\quad}
    \emacro\foo{bar}
    \emacro\foobar{blubb}
    $\exists A$
    
    $\forall B$
    
    \foo
    
    \foobar
    \end{document}
    steht natürlich in gar keinem Verhältnis zur \let-Variante
    aber mir hat's geholfen, (La)TeX wieder ein Stückchen besser zu verstehen.;-)

    MfG
    Rainer
    There's nothing a good whack with a hammer won't fix!

  4. #19
    Registrierter Benutzer Avatar von voss
    Registriert seit
    10.04.2005
    Beiträge
    5.045
    Zitat Zitat von rais Beitrag anzeigen
    ich hab mal versucht, erst per \meaning herauszufinden, ob ein \mathchar notwendig wäre:

    steht natürlich in gar keinem Verhältnis zur \let-Variante
    aber mir hat's geholfen, (La)TeX wieder ein Stückchen besser zu verstehen.;-)
    Ja, nur so kapiert man das letztlich.
    Deine Idee funktioniert leider nicht immer, da es noch andere Typen
    gibt, die ebenfalls keinMakro sind und bei Primitiven klappt die
    \expandafter-Orgie sowieso nicht:

    Code:
    \documentclass{article}
    \usepackage[T1]{fontenc}
    \begin{document}
    \makeatletter
    
    \meaning\par
    
    \meaning\@ne
    
    \expandafter\strip@prefix\meaning\pagebreak
    
    \end{document}
    Herbert

  5. #20
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.863
    Moin Herbert,
    Danke erstmal für die zusätzlichen Anregungen!
    Zitat Zitat von voss Beitrag anzeigen
    Deine Idee funktioniert leider nicht immer, da es noch andere Typen
    gibt, die ebenfalls keinMakro sind und bei Primitiven klappt die
    \expandafter-Orgie sowieso nicht:
    gerade die Primitiven würde ich gar nicht expandieren wollen; auf ein paar Definitionen muß ich mich auch verlassen können.
    Zitat Zitat von voss Beitrag anzeigen
    Code:
    \meaning\par
    Aha, hier schließt sich der Kreis zum \long.
    Zitat Zitat von voss Beitrag anzeigen
    Code:
    \meaning\@ne
    Das scheint mir so ein Teil nach dem Motto ``damned if you do, damned if you don't'' zu sein: Die Implementation hier im \emacro ließ sich recht einfach analog zum \mathchar realisieren, aber gerade \@ne wird ja nicht nur definiert, sondern bereits verwendet -- und wenn sich hier die Bedeutung ändert, führt es fast unweigerlich zu einem Fehler (wenn auch an anderer Stelle); da fragt man sich, ob die Redefinition eines \mathchar überhaupt so ohne weiteres zulässig ist ... Ich kann ja mal ein paar Warnungen ausgeben lassen;-)
    Zitat Zitat von voss Beitrag anzeigen
    Code:
    \expandafter\strip@prefix\meaning\pagebreak
    Beim Versuch, den String weiter auseinanderzunehmen, bin ich hier sehr schnell an meine Grenzen gestoßen und letztlich bin ich das Problem unter Zuhilfenahme des substr-Pakets umgangen -- aber da kann ich mir später immer noch die Zähne dran ausbeißen;-)
    Dabei stellte sich auch noch die Frage, was mit einem Makro passieren soll, das Parameter erwartet und wie man überhaupt an dessen Parameterliste gelangt, wenn dieses Makro auch noch einen optionalen Parameter unterstützt.
    Besser erstmal abweisen:
    Code:
    \documentclass[12pt]{article}
    \usepackage{substr}
    
    \chardef\emacrotc=`\%
    \mathchardef\emacromc="0123
    \newcommand*\emacrosm{short}
    \newcommand\emacrolm{long}
    \makeatletter
      \edef\chkstr{\string\@testopt}
    \makeatother
    
    \newcommand*\foo{foo}
    \newcommand\foobar{foobar}
    \newcommand*\baz[1]{baz \textit{#1}}
    \newcommand\foobaz[1]{foobaz \textit{#1}}
    
    \long\def\firstofndqi#1"#2\null{#1}
    \long\def\firstofndq#1{\expandafter\firstofndqi#1"\null}
    \long\def\firstofnci#1:#2\null{#1}
    \long\def\firstofnc#1{\expandafter\firstofnci#1:\null}
    \long\def\firstofngti#1>#2\null{#1}
    \long\def\firstofngt#1{\expandafter\firstofngti#1>\null}
    
    \newcommand\emacro[2]{%
      \long\edef\emacrotmp{\meaning#1}%
      \edef\emacroname{\string#1}%
      \long\edef\emacrotmpii{\firstofndq{\meaning\emacromc}}%
      \long\edef\emacrotmpi{\firstofndq{\emacrotmp}}%
      \ifx\emacrotmpi\emacrotmpii% Test auf \mathchar
        \typeout{Warnung:\string\emacro: `\emacroname' war `\emacrotmpi', wird zu Makro.}%
        \edef#1{\mathchar\the#1 #2}%
      \else
        \long\edef\emacrotmpii{\firstofndq{\meaning\emacrotc}}%
        \ifx\emacrotmpi\emacrotmpii% Test auf \char
          \typeout{Warnung:\string\emacro: `\emacroname' war `\emacrotmpi', wird zu Makro.}%
          \edef#1{\char\the#1 #2}%
        \else
          \long\edef\emacrotmpiis{\firstofngt{\meaning\emacrosm}}%
          \long\edef\emacrotmpis{\firstofngt{\emacrotmp}}%
          \long\edef\emacrotmpii{\firstofnc{\emacrotmpiis}}%
          \long\edef\emacrotmpi{\firstofnc{\emacrotmpis}}%
          \ifx\emacrotmpi\emacrotmpii% Test auf (short) macro
            \ifx\emacrotmpis\emacrotmpiis% Test auf nicht optionale Parameter
              \IfSubStringInString{\chkstr}{\emacrotmp}{% Test auf \@testopt
                \typeout{Fehler: \string\emacro\space mag keine Makros mit optionalen Parametern...(\emacroname)}}{%
                \edef#1{#1#2}}%
            \else
              \typeout{Fehler: \string\emacro: was soll mit Parameter(n) geschehen (\emacroname:\emacrotmp)?}%
            \fi
          \else
            \long\edef\emacrotmpiis{\firstofngt{\meaning\emacrolm}}%
            \long\edef\emacrotmpis{\firstofngt{\emacrotmp}}%
            \long\edef\emacrotmpii{\firstofnc{\emacrotmpiis}}%
            \long\edef\emacrotmpi{\firstofnc{\emacrotmpis}}%
            \ifx\emacrotmpi\emacrotmpii% Test auf (long) macro
              \ifx\emacrotmpis\emacrotmpiis% Test auf nicht optionale Parameter
                \IfSubStringInString{\chkstr}{\emacrotmp}{% Test auf \@testopt
                  \typeout{Fehler: \string\emacro\space mag keine Makros mit optionalen Parametern...(\emacroname)}}{%
                  \typeout{Warnung: \string\emacro: \emacroname\space wird zu einem kurzen Makro umdefiniert!}%besitzt eh keine Parameter...
                  \edef#1{#1#2}}%
              \else% langes Makro mit Parameter(n):
                \typeout{Fehler: \string\emacro: was soll mit Parameter(n) geschehen (\emacroname:\emacrotmp)?}%
              \fi
            \else
              \typeout{Fehler: \string\emacro\space hat sich geweigert, `\emacroname' zu expandieren!}
            \fi
          \fi
        \fi
      \fi
    }
    \begin{document}
    \emacro\exists{\quad}
    \emacro\forall{\quad}
    \emacro\foo{bar}
    \emacro\foobar{blubb}
    \emacro\par{\foo}
    \emacro\%{\quad\foo}
    \emacro\pagebreak{\foo}
    \emacro\foobaz{\foo}
    \emacro\baz{\foo}
    
    \verb=\exists=: $\exists A$
    
    \verb=\forall=: $\forall B$
    
    \verb=\%=: \%
    
    \verb=\foo=: \foo
    
    \verb=\foobar=: \foobar
    
    \verb=\foobaz{bla}=: \foobaz{bla}
    
    \verb=\baz{bla}=: \baz{bla}
    
    \end{document}
    wieder ein Stückchen mehr;-)

    MfG
    Rainer
    There's nothing a good whack with a hammer won't fix!

  6. #21
    Registrierter Benutzer Avatar von voss
    Registriert seit
    10.04.2005
    Beiträge
    5.045
    Zitat Zitat von rais Beitrag anzeigen
    Dabei stellte sich auch noch die Frage, was mit einem Makro passieren soll, das Parameter erwartet und wie man überhaupt an dessen Parameterliste gelangt, wenn dieses Makro auch noch einen optionalen Parameter unterstützt.
    Besser erstmal abweisen:
    Code:
    \long\def\firstofndqi#1"#2\null{#1}
    \long\def\firstofndq#1{\expandafter\firstofndqi#1"\null}
    \long\def\firstofnci#1:#2\null{#1}
    \long\def\firstofnc#1{\expandafter\firstofnci#1:\null}
    \long\def\firstofngti#1>#2\null{#1}
    \long\def\firstofngt#1{\expandafter\firstofngti#1>\null}
    Hallo Rainer,
    statt \null würde ich immer mit
    Code:
    \long\def\firstofndqi#1"#2\@nil{#1}
    \long\def\firstofndq#1{\expandafter\firstofndqi#1"\@nil}
    ...
    arbeiten.

    Wenn man mal mit TeX angefangen hat, wird das eine Seuche

    Herbert

  7. #22
    Registrierter Benutzer
    Registriert seit
    26.07.2008
    Ort
    Dresden
    Beiträge
    136

    Befehl mit Parametern expandieren

    Hallo,

    ich möchte einen selbsterklärten dreiparametrigen Befehl expandieren:
    Code:
    \newcommand{\stoff}[3]{#3}%nimm nummer 3
    soll später wahlweise um folgenden Eigenschaft erweitern:
    Code:
    \subsection{#1}
    Meine Versuche mit
    Code:
    \let\Stoff=\stoff 
    \renewcommand{\stoff}{\Stoff \subsection{#1}}
    bzw.
    Code:
    \renewcommand{\stoff}[3]{\Stoff \subsection{#1}}
    sind leider gescheitert, da Latex nach dem \renewcommand plötzlich auf das zweite, anstatt des ursprünglich dritten Arguments zugreift.

  8. #23
    Registrierter Benutzer Avatar von Stefan_K
    Registriert seit
    05.04.2007
    Ort
    Hamburg
    Beiträge
    3.534

    Makro-Redefinition

    Hallo Rafael,

    reiche die Parameter weiter, etwa:
    Code:
    \renewcommand{\stoff}[3]{\Stoff{#1}{#2}{#3}\subsection{#1}}
    Viele Grüße,

    Stefan

  9. #24
    Registrierter Benutzer
    Registriert seit
    26.07.2008
    Ort
    Dresden
    Beiträge
    136
    Zitat Zitat von Stefan_K Beitrag anzeigen
    Hallo Rafael,

    reiche die Parameter weiter, etwa:
    Code:
    \renewcommand{\stoff}[3]{\Stoff{#1}{#2}{#3}\subsection{#1}}
    Stefan
    Vielen Dank, daran hatte ich schon gedacht, aber mein Hirn sagte mir, dies sei ein Denkfehler. naja, Latex wird mich wohl immer irgendwie stressen.
    Grüße
    Rafael

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •