|
|
Beiträge: 13950
Seitenaufrufe: 154719 PIs (Jun 2010)
Top-Poster: KOMA (1735)
Wir begrüßen unseren neuesten Benutzer Bill.
|
|
|
|
Probleme bei eigenem Makro |
|
| sLy |

Forum-Anfänger
|
 |
Beiträge: 29
|
 |
|
 |
Anmeldedatum: 30.09.09
|
 |
|
 |
Wohnort: ---
|
 |
|
 |
Version: ---
|
 |
|
|
 |
|
Verfasst am: 29.12.2009, 15:06
Titel: Probleme bei eigenem Makro
|
 |
| |
 |
|
Hi,
ich habe ein eigenes Makro geschrieben, bei dem in meinem eigenen Befehl
das "(B)(C)" durch den befehl \a mit
| Code: | \def \a {(B)(C)} ---> \Lampe{L,\a} |
ersetzt werden soll.
Nur funktioniert das leider nicht.
Folgende Fehler:
! Paragraph ended before \pst@lamp was complete.
! LaTeX Error: \begin{pspicture} on input line 24 ended by \end{document}.
! Missing \endgroup inserted.
! Missing } inserted.
Hier das Minimalbeispiel (\LampeI soll so funktionieren wie \LampeII):
| Code: | \documentclass{minimal}
\usepackage{etoolbox}
\usepackage{pst-circ}
\usepackage{multido}
\makeatletter
\def \a {(B)(C)}
\newcommand*{\LampeI}[1]{\L@mpeI#1\@nil}
\newcommand*{\L@mpeI}{}
\def\L@mpeI#1,#2 \@nil{%
\lamp #2 {$#1$}
}
\newcommand*{\LampeII}[1]{\L@mpeII#1\@nil}
\newcommand*{\L@mpeII}{}
\def\L@mpeII#1,#2,#3 \@nil{%
\lamp (#1)(#2) {$#3$}
}
\begin{document}
Das: \newline
\begin{pspicture}[showgrid=false](0,0)(8,5)
\pnode(0.5,4.5) {A}
\pnode(0.5,1.75) {B}
\pnode(7.5,1.75) {C}
\pnode(7.5,4.5) {D}
\battery(D)(A) {$U_0$}
\wire(A)(B)
\wire(C)(D)
% \LampeI{L,\a}
\end{pspicture}
soll so aussehen: \newline
\begin{pspicture}[showgrid=false](0,0)(8,5)
\pnode(0.5,4.5) {A}
\pnode(0.5,1.75) {B}
\pnode(7.5,1.75) {C}
\pnode(7.5,4.5) {D}
\battery(D)(A) {$U_0$}
\wire(A)(B)
\wire(C)(D)
\LampeII{B,C,L}
\end{pspicture}
\end{document}
|
Wenn ich was unklar erklärt haben sollte PN an mich.
Hoffe ihr könnt mir wiedermal helfen,
sLy
|
|
|
|
| sLy |

Forum-Anfänger
|
 |
Beiträge: 29
|
 |
|
 |
Anmeldedatum: 30.09.09
|
 |
|
 |
Wohnort: ---
|
 |
|
 |
Version: ---
|
 |
|
|
 |
|
Verfasst am: 04.01.2010, 20:07
Titel:
|
 |
danke, funktioniert!
lässt sich der code auch so umschreiben, dass ich nur noch
schreiben müsste?
also dass ich mir den backslash sparen könnte?
UND
Wo kann ich mich über die makros \@nil und \@tempa informieren??
mfg
sLy
|
|
|
|
| phi |

Moderator
|
 |
Beiträge: 344
|
 |
|
 |
Anmeldedatum: 06.02.09
|
 |
|
 |
Wohnort: ---
|
 |
|
 |
Version: MacTeX 2010
|
 |
|
|
 |
|
Verfasst am: 05.01.2010, 00:53
Titel:
|
 |
| sLy hat Folgendes geschrieben: |
lässt sich der code auch so umschreiben, dass ich nur noch
schreiben müsste?
also dass ich mir den backslash sparen könnte? | Das würde eine Mehrdeutigkeit einbauen. Wie soll das Makro ermitteln, ob mit „a“ ein PSTricks-Punkt oder ein Makroname gemeint ist?
| Zitat: |
Wo kann ich mich über die makros \@nil und \@tempa informieren??
|
Die beiden Namen sind bedeutungslos, ich habe sie nur verwendet, weil sie in ähnlicher Bedeutung auch im LaTeX-Kernel verwendet werden.
|
|
|
|
| phi |

Moderator
|
 |
Beiträge: 344
|
 |
|
 |
Anmeldedatum: 06.02.09
|
 |
|
 |
Wohnort: ---
|
 |
|
 |
Version: MacTeX 2010
|
 |
|
|
 |
|
Verfasst am: 05.01.2010, 18:30
Titel:
|
 |
| |
 |
|
| sLy hat Folgendes geschrieben: | Naja ich dachte dabei an sowas:
| Code: | \newcommand*{\@Lampe}{}
\def\@Lampe#1,#2 \@nil{%
\def\@lamp{\lamp}
\appto \@lamp{ \}
\appto \@lamp{#1}
\appto \@lamp{{$#2$}}
\@lamp
}
|
Also der backslash wird erst innerhalb der Befehlsdefinition vor den ersten Parameter gesetzt. Ich gebe zwar \Lampe{a,L} ein, aber aus dem ersten Parameter wird \a, das ich ja als (B)(C) definiert habe.
Aber wenn du sagst, dass das nicht funktioniert hat sich die Sache erledigt. |
Das funktioniert schon, wenn der zweite Parameter immer einen Befehlsnamen bezeichnet:
| Code: | % ungetestet
\def\L@mpeI#1,#2 \@nil{%
\ifcsname#2 \endcsname
\protected@edef \@tempb{%
\protect\lamp\csname#2 \endcsname{$#1$}%
}%
\@tempb
\else
\PackageError{xyz}{Command `\@backslashchar#2' not defined}{\@ehc}%
\fi
}
|
| phi hat Folgendes geschrieben: |
Die beiden Namen sind bedeutungslos, ich habe sie nur verwendet, weil sie in ähnlicher Bedeutung auch im LaTeX-Kernel verwendet werden. |
Wenn sie bedeutungslos sind, wozu hast du sie dann verwendet?
Heißt das ich könnte sie auch weglassen?
Welche bedeutung haben sie im LaTeX-Kernel?
[/quote]
Mit "bedeutungslos" meine ich, dass man auch andere einsetzen kann.
Wenn du das alles verstehen möchtest, musst du dich in die TeX-Programmierung einlesen. Fang mal mit TeX by Topic an, insbesondere den Kapiteln 11, 12 und 13. Danach kannst du im LaTeX-Kernel (source2e.pdf) nach Vorkommnissen von \@tempa und \@nil suchen. \@tempa wird einfach als temporäre Variable verwendet, \@nil als Begrenzer von Makroargumenten.[/code]
|
|
|
|
| sLy |

Forum-Anfänger
|
 |
Beiträge: 29
|
 |
|
 |
Anmeldedatum: 30.09.09
|
 |
|
 |
Wohnort: ---
|
 |
|
 |
Version: ---
|
 |
|
|
 |
|
Verfasst am: 06.01.2010, 21:15
Titel:
|
 |
| |
 |
|
danke funktioniert einwandfrei.
Ich werde mir TeX by Topic mal zu gemüte führen...
mfg
sLy
EDIT:
mein neues Problem: ich will die zugehörige Schaltung zu den Teilen bauen.
Hier mein Code
| Code: | \newcommand*{\Schaltung}[1]{% die übliche Befehlsdefinition
\protected@edef \@tempa{#1}%
\expandafter\@Schaltung\@tempa\@nil
}
\newcommand*{\@Schaltung}{}
\def\@Schaltung#1,#2,#3,#4,#5,#6,#7,#8,#9 \@nil{% Parameter 1-3 sind Einheit in cm, max. X-Wert, max. Y-Wert; Parameter 4-9 stellen die Teile dar
\psset {unit=#1cm}%
\newcounter{x}% counter zur ermittlung von xmax und ymax
\newcounter{y}
\newcounter{xmax}
\newcounter{ymax}
\setcounter{x}{#2}
\setcounter{y}{#3}
\setcounter{xmax}{\value{x}}
\setcounter{ymax}{\value{y}}
\addtocounter{xmax}{1}
\addtocounter{ymax}{1}
\begin{pspicture}[showgrid=false](-1,-1)( \value{xmax}, \value{ymax}) %das Standard-Schaltbild
\def\Standard{%
\pnode(0, \value{y}) {A}%
\pnode(0,0) {B}%
\pnode( \value{x},0) {Y}%
\pnode( \value{x}, \value{y}) {Z}%
\pnode(3,0) {C}%
\pnode(6,0) {D}%
\pnode(9,0) {E}%
\pnode(12,0) {F}%
\pnode(15,0) {G}%
\pnode(18,0) {H}%
\battery (Z)(A) {$U_0$}%
\wire (A)(B) %
\wire (Y)(Z) %
}%
\def\bc{\noexpand#4} %hier sollen die Teile zur Schaltung hinzugefügt werden
\def\cd{\noexpand#5}
\def\de{\noexpand#6}
\def\ef{\noexpand#7}
\def\fg{\noexpand#8}
\def\gh{\noexpand#9}
\eappto\Standard{\bc}
\eappto\Standard{\cd}
\eappto\Standard{\de}
\eappto\Standard{\ef}
\eappto\Standard{\fg}
\eappto\Standard{\gh}
\Standard%
\end{pspicture}%
} |
Leider funktioniert das nicht so wie es soll.
Fehler:
! Argument of \@Lampe has an extra }.
! Paragraph ended before \@Lampe was complete.
! File ended while scanning use of \@Schaltung.
! Emergency stop.
Minimalbeispiel:
| Code: | \documentclass{minimal}
\usepackage{etoolbox}
\usepackage{pst-circ}
\usepackage{multido}
\makeatletter
\def \PosA {(B)(C)}
\def \PosB {(C)(D)}
\def \PosC {(D)(E)}
\def \PosD {(E)(F)}
\def \PosE {(F)(G)}
\def \PosF {(G)(H)}
\newcommand*{\Lampe}[1]{%
\protected@edef \@tempa{#1}%
\expandafter\@Lampe\@tempa\@nil
}
\newcommand*{\@Lampe}{}
\def\@Lampe#1,#2 \@nil{%
\ifcsname#1 \endcsname
\protected@edef \@tempb{%
\protect\lamp\csname#1 \endcsname{$#2$}%
}%
\@tempb
\else
\PackageError{xyz}{Command `\@backslashchar#1' not defined}{\@ehc}%
\fi
}
\newcommand*{\Schaltung}[1]{%
\protected@edef \@tempa{#1}%
\expandafter\@Schaltung\@tempa\@nil
}
\newcommand*{\@Schaltung}{}
\def\@Schaltung#1,#2,#3,#4,#5,#6,#7,#8,#9 \@nil{%
\psset {unit=#1cm}%
\newcounter{x}
\newcounter{y}
\newcounter{xmax}
\newcounter{ymax}
\setcounter{x}{#2}
\setcounter{y}{#3}
\setcounter{xmax}{\value{x}}
\setcounter{ymax}{\value{y}}
\addtocounter{xmax}{1}
\addtocounter{ymax}{1}
\begin{pspicture}[showgrid=false](-1,-1)( \value{xmax}, \value{ymax})
\def\Standard{%
\pnode(0, \value{y}) {A}%
\pnode(0,0) {B}%
\pnode( \value{x},0) {Y}%
\pnode( \value{x}, \value{y}) {Z}%
\pnode(2,0) {C}%
\pnode(4,0) {D}%
\pnode(6,0) {E}%
\pnode(8,0) {F}%
\pnode(10,0) {G}%
\pnode(12,0) {H}%
\battery (Z)(A) {$U_0$}%
\wire (A)(B) %
\wire (Y)(Z) %
\wire (H)(Y) %
}%
\def\bc{\noexpand#4}
\def\cd{\noexpand#5}
\def\de{\noexpand#6}
\def\ef{\noexpand#7}
\def\fg{\noexpand#8}
\def\gh{\noexpand#9}
\eappto\Standard{\bc}
\eappto\Standard{\cd}
\eappto\Standard{\de}
\eappto\Standard{\ef}
\eappto\Standard{\fg}
\eappto\Standard{\gh}
\Standard%
\end{pspicture}%
}
\makeatother
\begin{document}
\begin{center}
\Schaltung{1,13,4, %
\Lampe{PosA,L_1}, %
\Lampe{PosB,L_2}, %
\Lampe{PosC,L_3}, %
\Lampe{PosD,L_4}, %
\Lampe{PosE,L_5}, %
\Lampe{PosF,L_6}%
}
\end{center}
\end{document} |
|
|
|
|
| KOMA |

TeX-Entwickler
|
 |
Beiträge: 1735
|
 |
|
 |
Anmeldedatum: 04.07.08
|
 |
|
 |
Wohnort: ---
|
 |
|
 |
Version: ---
|
 |
|
|
 |
|
Verfasst am: 25.01.2010, 12:12
Titel:
|
 |
| |
 |
|
Das kann deshalb nicht funktionieren, weil \Lampe aus den Argumenten von \Schaltung bereits beim \protected@edef expandiert wird. Die Definition von Schaltung ist also zu ändern: | Code: | \newcommand*{\Schaltung}[1]{%
\@Schaltung#1 \@nil
} | Da ich nicht die gesamte Diskussion gelesen habe, stellt sich mir aber die Frage, warum bei nur 9 verwendeten Argumenten überhaupt mit einer Liste gearbeitet wird, statt einfach 9 Argumente zu verwenden. Außerdem erscheint mir die Definition von \Lampe ebenfalls unnötig umständlich. Wenn ich mir erlaube, das ganze einmal etwas zu vereinfachen: | Code: | \documentclass{minimal}
\usepackage{pst-circ}
\def \PosA {(B)(C)}
\def \PosB {(C)(D)}
\def \PosC {(D)(E)}
\def \PosD {(E)(F)}
\def \PosE {(F)(G)}
\def \PosF {(G)(H)}
\makeatletter
\newcommand*{\Lampe}[2]{%
\expandafter\lamp#1 {$L_#2$}%
}
\newcommand*{\Schaltung}[1]{%
\@Schaltung#1 \@nil
}
\newcommand*{\@Schaltung}{}
\def\@Schaltung#1,#2,#3,#4 \@nil{%
\psset {unit=#1cm}%
\newcounter{x}
\newcounter{y}
\newcounter{xmax}
\newcounter{ymax}
\setcounter{x}{#2}
\setcounter{y}{#3}
\setcounter{xmax}{\value{x}}
\setcounter{ymax}{\value{y}}
\addtocounter{xmax}{1}
\addtocounter{ymax}{1}
\begin{pspicture}[showgrid=false](-1,-1)( \value{xmax}, \value{ymax})
\def\Standard{%
\pnode(0, \value{y}) {A}%
\pnode(0,0) {B}%
\pnode( \value{x},0) {Y}%
\pnode( \value{x}, \value{y}) {Z}%
\pnode(2,0) {C}%
\pnode(4,0) {D}%
\pnode(6,0) {E}%
\pnode(8,0) {F}%
\pnode(10,0) {G}%
\pnode(12,0) {H}%
\battery (Z)(A) {$U_0$}%
\wire (A)(B) %
\wire (Y)(Z) %
\wire (H)(Y) %
#4
}%
\Standard%
\end{pspicture}%
}
\makeatother
\begin{document}
\begin{center}
\Schaltung{1,13,4, %
\Lampe\PosA1
\Lampe\PosB2
\Lampe\PosC3
\Lampe\PosD4
\Lampe\PosE5
\Lampe\PosF{10}% Zur Verdeutlichung von mehrstelligen Nummern
}
\end{center}
\end{document} |
Das erscheint mit im Ergebnis deutlich einfacher. Die Fehlermeldung für nicht definierten \PosA etc. überlasse ich dabei einfach TeX. Man könnte jetzt natürlich \Schaltung auch einfach als Anweisung mit vier Argumenten definieren. Man spart sich dann auch gleich noch die Verwendung von \makeatletter und \makeatother. Dass man bei Schaltung alle Lampen mit einem Argument übergibt, sollte auch noch funktionieren, wenn man eure Definition von \Lampe und dann natürlich auch eure Schreibweise der Argumente von \Lampe verwendet.
_________________
goLaTeX-Knigge (mit Themen Minimalbeispiel und So stellst Du Deine Frage richtig)
DE-TeX-FAQ, UK-FAQ, l2kurz, l2tabu, CTAN, The TeX Catalogue
KOMA-Script
|
|
|
|
| sLy |

Forum-Anfänger
|
 |
Beiträge: 29
|
 |
|
 |
Anmeldedatum: 30.09.09
|
 |
|
 |
Wohnort: ---
|
 |
|
 |
Version: ---
|
 |
|
|
 |
|
Verfasst am: 26.01.2010, 21:16
Titel:
|
 |
| |
 |
|
danke für eure Hifle soweit. Ich bin dank eurer Vorschläge ein ganzes stück weiter gekommen.
Leider habe ich ein neues Problem:
Ich möchte, dass sich der Benutzer mit Hilfe eines Befehls (\ElemDef) ein eigenes Element, das auf pst-circ aufbaut, definieren kann.
Ich bin bei der vorigen definition der Elemente geblieben und habe \Schaltung dafür verändert.
Hier noch mal die Definition eines Kondensators:
| Code: |
\newcommand*{\Kondensator}[1]{%
\protected@edef \@tempa{#1}%
\expandafter\@Kondensator\@tempa\@nil
}
\newcommand*{\@Kondensator}{}
\def\@Kondensator#1,#2 \@nil{%
\ifcsname#1 \endcsname
\protected@edef \@tempb{%
\protect\capacitor\csname#1 \endcsname{$#2$}%
}%
\@tempb
\else
\protected@edef \@tempb{%
\protect\capacitor#1 {$#2$}%
}%
\@tempb
\fi
}
|
Ich habe mir vorgestellt, dass der Benutzer sich mit der Eingabe \ElemDef{Diode,diode} ein neuen Befehl \Diode definieren kann.
Der zweite Parameter stellt den pst-circ-befehl dar.
Hier mein Minimalbeispiel:
| Code: |
\documentclass{minimal}
\newcommand*{\ElemDef}[1]{\@ElemDef#1\@nil}
\newcommand*{\@ElemDef}{}
\def\@ElemDef#1,#2 \@nil{%
\newcommand*{\csname#1\endcsname}[1]{%
\protected@edef \@tempa{##1}%
\expandafter\csname@#1 \endcsname\@tempa\@nil
}
\newcommand*{\csname@#1\endcsname}{}
\def\csname{}@#1 \endcsname##1,##2 \@nil{%
\ifcsname##1 \endcsname
\protected@edef \@tempb{%
\protect\csname#2 \endcsname\csname##1 \endcsname{$##2$}%
}%
\@tempb
\else
\protected@edef \@tempb{%
\protect\csname#2 \endcsname##1 {$##2$}%
}%
\@tempb
\fi
}
}
\begin{document}
\ElemDef{Diode,diode}
\begin{pspicture}[showgrid=true](-1,-1)(15,6)
\pnode(0,5) {Y}
\pnode(0,0) {A}
\pnode(14,0) {B}
\pnode(14,5) {Z}
\battery(Y)(Z) {$U_0$}
\wire(Y)(A)
\wire(B)(Z)
\Diode{(A)(B),R_1}
\end{pspicture}
\end{document}
|
|
|
|
|
| KOMA |

TeX-Entwickler
|
 |
Beiträge: 1735
|
 |
|
 |
Anmeldedatum: 04.07.08
|
 |
|
 |
Wohnort: ---
|
 |
|
 |
Version: ---
|
 |
|
|
 |
|
Verfasst am: 27.01.2010, 11:31
Titel:
|
 |
| |
 |
|
Da funktioniert diverses nicht. Zum einen fehlen pst-circ, \makeatletter und \makeatother. Dann definierst Du hier: \csname neu. Noch deutlicher wird das bei , wobei hier eben nicht \csname, sondern \csname@ neu definiert wird. Es fehlt also auch noch ein Leerzeichen nach \csname.
Bevor Du Dich an derart komplizierte Dinge wagst, solltest Du im TeXbook oder min. in TeX by Topic mal nachlesen, wie die Expansion in TeX generell und Dinge wie \expandafter und \csname...\endcsname funktionieren. Im Beispiel müsste man erst \csname #1\endcsname expandierten und dann \newcommand, also | Code: | \expandafter\newcommand\expandafter*\expandafter{\csname #1\endcsname} |
Das ist dann aber noch nicht das Ende der Probleme. Du hast auch wieder Umwege über \protected@edef, wo diese sicher nicht erforderlich sind. Dafür sollte man überlegen, bei der \def\csname-Geschichte eher auf diesem Weg vorzugehen. Desweiteren macht wohl auch: | Code: | \expandafter\csname @#1\endcsname\@tempa\@nil | nicht das, was Du willst. Denn hier wird lediglich die Expansion von \csname verzögert. Du willst aber vermutlich die Expansion des Makros der Expansion von \csname @#1\endcsname verzögern.
Ich glaube aber, dass es den Rahmen dieses Forums sprengt, Dir die low-level TeX-Grundlagen und die Feinheiten der Expansion beizubringen. Du begibst Dich da schon recht tief in den Teil von TeX, in dem man sich leicht verirren kann und auch ein Experte gut aufpassen muss.
Um es kurz zu machen: Neben anderen Fehlern funktioniert die komplette Expansionslogik Deines Codes nicht.
_________________
goLaTeX-Knigge (mit Themen Minimalbeispiel und So stellst Du Deine Frage richtig)
DE-TeX-FAQ, UK-FAQ, l2kurz, l2tabu, CTAN, The TeX Catalogue
KOMA-Script
|
|
|
|
|
Gehe zu Seite 1, 2 Weiter
|
|
Options and Permissions
|
|
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
|
|
|