PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Prüfen ob counter bereits existiert



AronaDaal
09-04-2013, 12:36
Hallo zusammen,
ich versuche gerade eine kleine Randnotiz mit Counter zu erstellen. Es funktioniert soweit auch, allerdings bekomme ich immer wieder folgende Fehlermeldung geworfen und weiß nicht wieso:

! LaTeX Error: Command \c@notecounter already defined.

Wenn ich den Counter außerhalb des Makros anlege und dann nur stepcounter im Makro verwende funktioniert es ohne Fehlermeldung. Allerdings würde ich es gerne so machen wie im folgenden Mini-Beispiel.

Wäre nett, wenn mir jemand einen Tipp geben könnte!
Viele Grüße, aronadaal

Mini-Beispiel:


\documentclass{article}
\newcommand{\note}[1]{
\@ifundefined{c@notecounter}{\newcounter{notecount er}}{\stepcounter{notecounter}}
\marginpar[\raggedleft\fbox{\texttt{Note \thenotecounter}}]{\raggedright\fbox{\texttt{Note \thenotecounter}}}
\noindent #1
}

\begin{document}
Text und eine Randnotiz
\note{1. Randnotiz}

Noch mehr Text
\note{2. Randnotiz}

\end{document}

AronaDaal
09-04-2013, 15:12
\makeatletter
\makeatother

bewirken Wunder,.... :rolleyes:
Hat sich also erledigt. Grüße, aronadaal

topskip
09-04-2013, 22:22
\makeatletter
\makeatother

bewirken Wunder,.... :rolleyes:
Hat sich also erledigt. Grüße, aronadaal

Ganz ohne \makeatletter... \makeatother geht es mit dem Paket ifthen:



\documentclass{article}
\usepackage{ifthen}

\newcommand{\note}[1]{%
\ifthenelse{\isundefined{\thenotecounter}}{\newcou nter{notecounter}}{\stepcounter{notecounter}}
\marginpar[\raggedleft\fbox{\texttt{Note \thenotecounter}}]{\raggedright\fbox{\texttt{Note \thenotecounter}}}
\noindent #1
}

\begin{document}
Text und eine Randnotiz
\note{1. Randnotiz}

Noch mehr Text
\note{2. Randnotiz}

\end{document}


Patrick

cgnieder
10-04-2013, 00:22
Unabhängig von der Fehlermeldung: Dein Code enthält unerwünschte Leerzeichen, und zwar an allen Zeilenenden, die nicht einem Makro ohne Argument (oder einem Makro auf der Suche nach einem Argument) folgen. Wie Die vermutlich klar ist durch Deine Verwendung von \note in einer neuen Zeile, wandelt TeX Zeilenenden in Leerzeichen um (außer ihnen folgt ein weiteres Zeilenende, dann werden sie in ein \par umgewandelt). Ich habe die nötigen % eingefügt:


\documentclass{article}
\makeatletter
\newcommand{\note}[1]{% <= Hier
\@ifundefined{c@notecounter}{\newcounter{notecount er}}{\stepcounter{notecounter}}% <= Hier
\marginpar[\raggedleft\fbox{\texttt{Note \thenotecounter}}]{\raggedright\fbox{\texttt{Note \thenotecounter}}}% <= Hier
\noindent #1% <= Hier unter Umständen auch
}
\makeatother
\begin{document}
Text und eine Randnotiz
\note{1. Randnotiz}
Text

Noch mehr Text
\note{2. Randnotiz}
Text

\end{document}

Ich würde das ganze übrigens ohne den Test schreiben:


\documentclass{article}

\newcounter{notecounter}
\newcommand{\note}[1]{%
\refstepcounter{notecounter}%
\marginpar
[\raggedleft\fbox{\texttt{Note \thenotecounter}}]
{\raggedright\fbox{\texttt{Note \thenotecounter}}}%
#1%
}

\begin{document}

Text und eine Randnotiz
\note{1. Randnotiz}
Text

Noch mehr Text
\note{2. Randnotiz}
Text

\end{document}

Der Code verwendet \refstepcounter, wodurch man die Notizen auch mit \label und \ref referenzieren könnte, lässt dafür \noindent weg, dessen Zweck mir an dieser Stelle nicht recht einleuchten will. Wird \note in mitten eines Absatzes eingesetzt, hat es sowieso keine Wirkung. Zu Beginn eines Absatzes würde es den Einzug natürlich verhindern.

Grüße

AronaDaal
10-04-2013, 10:25
Hallo,
euch erst einmal vielen Dank für die Hinweise.

@topskip: Jedes Paket, das nicht eingebunden werden braucht, ist sicherlich ein Vorteil. Ich habe ein wenig im Netz dazu recherchiert. Anscheinend wurde ifthen durch etoolbox "abgelöst". http://www.ctan.org/pkg/etoolbox

@cgnieder: Danke für die %s. Es hat ja auch "so" funktioniert - zumindest in meinen Tests. Es hätte sicherlich später, in bestimmten Situation, ein sonderbares Verhalten ausgelöst und man wäre wieder auf die Suche gegangen.

Die Variable außerhalb des Makros zu definieren war auch mein erster Ansatz. Da dieses Makro aber in einer Vorlage Verwendung finden soll, die von mehreren Usern benutzt werden wird, war die Idee zu sagen man hat einen "Block" den man sich auch in ein anderes Dokument (ohne diese Vorlage) kopieren kann. So muss man nicht gesondert aufpassen, dass man auch die Erzeugung von "notecounter" mitkopiert. Auf der anderen Seite wird jedesmal zusätzlicher Code interpretiert, um zu prüfen, ob die Variable da ist. ... Geschmacksache, würde ich sagen ;)

Idee:
Mir kam gestern beim Erstellen des Makros die Idee, dass es evtl. hilfreich wäre, wenn in der Marginalie auch die Gesamtzahl der notes zu finden wäre. Also sowas wie "note 3/42". Ist sowas "einfach" realisierbar? Kann mir vorstellen, dass dies erst nach mehreren TeX-Durchläufen berechnet werden kann. Weiß jemand wie man so etwas macht?

Grüße aronadaal

cgnieder
10-04-2013, 11:07
Anscheinend wurde ifthen durch etoolbox "abgelöst".
Naja, abgelöst wurde es durch etoolbox nicht, es findet noch an vielen Stellen Einsatz. Allerdings stellt etoolbox viele Test-Makros zur Verfügung, so dass man ifthen eigentlich nicht braucht, wenn man etoolbox verwendet. In diesem Fall wäre z.B. \ifcsdef die passende etoolbox-Lösung.


@cgnieder: Danke für die %s. Es hat ja auch "so" funktioniert - zumindest in meinen Tests.
Dann ist Die offensichtlich in Deinem Minimalbeispiel (mit \makatletter und \makeatother) offensichtlich nicht aufgefallen, dass dort die Leerräume vor und nach »1. Randnotiz« (und »2. Randnotiz«) zu groß waren...


Mir kam gestern beim Erstellen des Makros die Idee, dass es evtl. hilfreich wäre, wenn in der Marginalie auch die Gesamtzahl der notes zu finden wäre. Also sowas wie "note 3/42". Ist sowas "einfach" realisierbar? Kann mir vorstellen, dass dies erst nach mehreren TeX-Durchläufen berechnet werden kann. Weiß jemand wie man so etwas macht?

Grundsätzlich lässt man am Ende des Dokuments den Wert des Zählers in die aux-Datei schreiben, so dass der Wert bei nächsten Lauf verfügbar ist:


\documentclass{article}

\makeatletter
\newcounter{notecounter}
\newcommand{\note}[1]{%
\refstepcounter{notecounter}%
\marginpar
[\raggedleft\fbox{\texttt{Note \thenotecounter/\totalnotes}}]
{\raggedright\fbox{\texttt{Note \thenotecounter/\totalnotes}}}%
#1%
}
\AtEndDocument{%
\immediate\write\@auxout{\gdef\noexpand\@totalnote s{\thenotecounter}}%
}
\newcommand\totalnotes{%
\@ifundefined{@totalnotes}{??}{\@totalnotes}}

\makeatother

\begin{document}

Text und eine Randnotiz
\note{1. Randnotiz}
Text

Noch mehr Text
\note{2. Randnotiz}
Text

\end{document}

Grüße

klops
10-04-2013, 11:36
Die Variable außerhalb des Makros zu definieren war auch mein erster Ansatz. Da dieses Makro aber in einer Vorlage Verwendung finden soll, die von mehreren Usern benutzt werden wird, war die Idee zu sagen man hat einen "Block" den man sich auch in ein anderes Dokument (ohne diese Vorlage) kopieren kann. So muss man nicht gesondert aufpassen, dass man auch die Erzeugung von "notecounter" mitkopiert.
Wer den Code so wenig verstanden hat, dass er diesen Fehler macht und selbst nicht wieder heraus findet, der sollte den Code schlicht überhaupt nicht kopieren. Hirnlose Code-Kopiererei ist eines der größten Übel, mit dem wir hier zu kämpfen haben.

Eine sehr schöne Lösung wäre, wenn Du nicht einfach eine Vorlage mit unzähligen Definitionen in der Präambel bereit stellen würdest, sondern ein oder mehrere Pakete oder eine Wrapper-Klasse und das am besten mit Doku und über CTAN. Für Dich hat es den Vorteil, dass Du eine größere Chance auf Rückmeldungen hast und bei Fragen zu längst gelösten Problemen einfach auf die neue Version verweisen kannst. Bei Verwendung einer freien Lizenz hast Du außerdem gute Chancen, dass das ganze recht schnell über die Paketmanager von MiKTeX und TeX Live installierbar sein wird. Du musst also gar nicht erst lange die Installation erklären. Für uns hat es den Vorteil, dass wir Fragestellern, die Dein Werk verwenden, nicht erst lange aus der Nase ziehen müssen, wie man an die Vorlage kommt.

topskip
10-04-2013, 12:00
@topskip: Jedes Paket, das nicht eingebunden werden braucht, ist sicherlich ein Vorteil.

Ich habe ein wenig im Netz dazu recherchiert.

Anscheinend wurde ifthen durch etoolbox "abgelöst".


Zu Satz 1: halte ich für völlig falsch, wenn man nicht genau weiß, was man tut. Meist sind die Sachen doch nicht so einfach, wie man glaubt, und Pakete kümmern sich meistens auch um Sonderfälle (Beispiele: setspace.sty, parskip.sty).

Zu Satz 2: Bezieht sich der Satz auf den ersten Satz? Wenn ja, was waren dann die Ergebnisse?

Zu Satz 3: da wurde ja schon was dazu geschrieben.

Schönen Gruß

Patrick

AronaDaal
10-04-2013, 13:57
Dann ist Die offensichtlich in Deinem Minimalbeispiel (mit \makatletter und \makeatother) offensichtlich nicht aufgefallen, dass dort die Leerräume vor und nach »1. Randnotiz« (und »2. Randnotiz«) zu groß waren...
Doch, eigentlich schon. Ich wollte aber erst das Counter-Problem lösen. Werd' auf alle Fälle das nächste Mal darauf achten.


Grundsätzlich lässt man am Ende des Dokuments den Wert des Zählers in die aux-Datei schreiben, so dass der Wert bei nächsten Lauf verfügbar ist:

Super, vielen Dank! So etwas hatte ich im Sinn.


Wer den Code so wenig verstanden hat, dass er diesen Fehler macht und selbst nicht wieder heraus findet, der sollte den Code schlicht überhaupt nicht kopieren. Hirnlose Code-Kopiererei ist eines der größten Übel, mit dem wir hier zu kämpfen haben.

Eine sehr schöne Lösung wäre, wenn Du nicht einfach eine Vorlage mit unzähligen Definitionen in der Präambel bereit stellen würdest, sondern ein oder mehrere Pakete oder eine Wrapper-Klasse und das am besten mit Doku und über CTAN. Für Dich hat es den Vorteil, dass Du eine größere Chance auf Rückmeldungen hast und bei Fragen zu längst gelösten Problemen einfach auf die neue Version verweisen kannst. Bei Verwendung einer freien Lizenz hast Du außerdem gute Chancen, dass das ganze recht schnell über die Paketmanager von MiKTeX und TeX Live installierbar sein wird. Du musst also gar nicht erst lange die Installation erklären. Für uns hat es den Vorteil, dass wir Fragestellern, die Dein Werk verwenden, nicht erst lange aus der Nase ziehen müssen, wie man an die Vorlage kommt.
Die Überlegung hatte ich auch schon, aber Danke nochmals für den Hinweis. Da es sich bei der Vorlage auch eher um eine hausinterne Vorlage handelt, kommt CTAN erstmal nicht in Frage. Allerdings könnte man damit viele Pakete der Präambel vor dem Anwender 'verstecken'. Ich schau mir das mal an. Hast du vielleicht einen Tipp welche Vorlage sich für den Einstieg (Wie machen es andere?) in die Thematik eignet?


Zu Satz 1: halte ich für völlig falsch, wenn man nicht genau weiß, was man tut. Meist sind die Sachen doch nicht so einfach, wie man glaubt, und Pakete kümmern sich meistens auch um Sonderfälle (Beispiele: setspace.sty, parskip.sty).

Zu Satz 2: Bezieht sich der Satz auf den ersten Satz? Wenn ja, was waren dann die Ergebnisse?

Zu Satz 3: da wurde ja schon was dazu geschrieben.

zu 2) Ergebnis war, wie eben auch geschrieben, dass im Netz eher die etoolbox empfohlen wird, da neuer und in aktiver Maintenance.

zu 1) Ich will den Thread nicht zu einer Grundsatzdiskussion verkommen lassen. Ich gebe dir Recht, dass viele Pakete einem die tägliche Arbeit deutlich erleichtern. Allerdings sieht man doch immer wieder, dass durch das kunterbunte Zusammenmischen von Paketen 'nette' Seiteneffekte entstehen, die dann in diversen Foren über das Netz verteilt von zig fortgeschrittenen Anwendern gelöst werden sollen. Wie oft ließt man denn Sätze à la schau mal in l2tabu.pdf rein & Co. Wer weiß denn bei Latex so richtig richtig was er da macht? Doch nur ein Bruchteil derer, die sich tiefer damit beschäftigen. Daher füge ich persönlich nur dann ein Paket ein, wenn ich einen gewissen Nutzen habe. In diesem Fall, tun es die beiden Befehle.

rstuby
10-04-2013, 14:26
Das kann einem mit einem Befehl genauso passieren wie mit einem Paket. Siehe deine Leerzeichen.