Nummerierung bei eigener Umgebung

Antwort erstellen


Diese Frage dient dazu, das automatisierte Versenden von Formularen durch Spam-Bots zu verhindern.
Smilies
:D :) :( :o :shock: :? 8) :lol: :-x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:

BBCode ist eingeschaltet
[img] ist eingeschaltet
[flash] ist ausgeschaltet
[url] ist eingeschaltet
Smilies sind eingeschaltet

Die letzten Beiträge des Themas

Ich habe die Datenschutzerklärung gelesen und bin damit einverstanden.

   

Wenn du eine Datei oder mehrere Dateien anhängen möchtest, gib die Details unten ein.

Ansicht erweitern Die letzten Beiträge des Themas: Nummerierung bei eigener Umgebung

von Epllus » Mi 10. Apr 2013, 20:09

Soweit ich es nun verstand, erspare ich mir Zeit,(um es sehr salopp auszudrücken) einerseits da ich den Hash-Speicher nicht zumülle, andererseits da sich TeX und LaTeX nicht mehr streiten, ob etwas nun definiert oder undefiniert ist.

Hmmm, ich glaube so langsam versteh Ichs (aber wohl erst morgen richtig).

Grüße
Epllus

PS. Mir ist ein weiterer Fehler in der Ausführung des Codes aufgefallen und habe ihn behoben.

von Noch so einer » Mi 10. Apr 2013, 15:54

Ach, ich vergaß. Da der Anwender verhindern kann, dass \ifundefinedorrelax definiert wird, würde ich für ein Paket oder eine Klasse immer auf \scr@ifundefinedorrelax zurück greifen. In der Dokumentpräambel oder einem Dokument kann man natürlich stattdessen unbesorgt \ifundefinedorrelax verwenden, weil man dann ja selbst der Anwender ist und die volle Kontrolle ausübt.

von Noch so einer » Mi 10. Apr 2013, 15:51

Die Suche findet jedes Mal statt, egal ob es bereits ein Control Sequence mit dem Namen gibt oder nicht. Wichtiger ist die Frage, ob in der Hash-Tabelle von TeX ein Eintrag vorgenommen wird. Hash-Einträge werden nämlich nicht mehr frei gegeben, auch wenn die zugehörige Control Sequence nicht mehr definiert ist, weil die zugehörige Gruppe beendet wurde. Und wie alle Speicher ist auch hash_memory bei TeX ein statischer Speicher. Im string_memory (Teil von pool_memory) wird der Name der Control Sequence AFAIR sogar gelöscht und der Speicher steht dann wieder zur Verfügung. Bei der Hash-Tabelle geht das aber nicht. Deshalb belegen Control Sequences, die mit \csname…\endcsname irgendwann einmal zu \relax wurden auch dann noch einen Eintrag, wenn sie wieder undefiniert sind. Bei der e-TeX-Anweisungen \ifcsname wurde aber genau das verhindert, indem die Control Sequence gar nicht erst als \relax definiert wird.

Wer nun glaubt, dass die KOMA-Script-Implementierung da nichts nützt, weil sie ja auch noch einen Test enthält, der mit \csname…\endcsname arbeitet, der irrt. Dieser Test wird nämlich nur ausgeführt, wenn die Control Sequence nicht undefiniert ist, also bereits min. als \relax definiert wurde.

Alles ein wenig kompliziert. Achja: Dass das Eintragen in der Hash-Tabelle Zeit kostet, ist natürlich richtig. Ggf. kostet außerdem die Implizite Definition als \relax durch \csname…\endcsname Zeit. Einen Unterschied merkt man hier dann natürlich nur für Anweisungen, die aus TeX-Sicht undefiniert sind. Für Anweisungen, die aus TeX-Sicht definiert, aus LaTeX-Sicht aber undefiniert sind, also Anweisungen, die \relax sind, ergibt sich kein Gewinn, sondern eher ein geringer Zeitverlust.

von Epllus » Mi 10. Apr 2013, 14:48

Ich habe jetzt \ifundefined durch \ifundefinedorrelax ersetzt, nach der Lektüre vom KOMA-Script Manual und nachdem ich mich auf Wikipedia informiert habe, was ein "Hash Speicher" ist.
So weit ichs (so lala) verstanden habe, werden die Informationen in einer Hash-Tabelle eingeordnet, und mittels einer Funktion wird für jedes Objekt ein Wert errechnet; das Objekt wird mittels diesem Wert in ein Bucket einsortiert (im wirklichen Optimalfall, der eigentlich nie der Fall wird, da mehrere Objekte in einen Bucket kommen können etc.) etc. Beim Herausholen wird mittels eines Schlüssels der Hash-Wert berrechnet, der zum dazugehörigen Bucket führt, worin sich das Objekt befindet (wobei es sein kann, dass sich mehrere Objekte in einem Bucket befinden was zu Kollisionen führt etc.) etc.
Also soweit ich es verstanden habe, erspare ich mir mit \ifundefinedorrelax das Einordnen in einer Tabelle, das Heraussuchen, Kollisionen,……… also etwas Zeit.

Vielleicht bilde ich es mir nur ein, aber ich habe ich wirklich das Gefühl, dass sich die Kompilierungszeit meines Dokuments (in dem ich die Umgebung sehr of habe) wirklich verringert hat (habe auch versucht es mittels "time pdflatex" nachzumessen, im Durchschnitt würde ich sagen, dauert es sogar wirklich kürzer).

Grüße
Epllus

von Noch so einer » Di 9. Apr 2013, 18:52

Die einzige andere Möglichkeit das zu lösen, die ich sehe, wäre die Umgebung mit Hilfe von environ zu lesen und zunächst in eine Box zu schreiben, um bei einem ersten Durchgang schlicht zu ermitteln, ob Begriffe mehrfach vorkommen. Erst beim zweiten Durchgang würde man dann tatsächlich ausgeben und hätte bereits die Information ob ein Begriff mehrfach verwendet wird. Aber das hat dann auch wieder Nachteile, beispielsweise müsste man im ersten Durchgang das Setzen von labels deaktivieren, weil die sonst ggf. zweimal gesetzt werden. Deshalb denke ich, dass ein Weg über die aux-Datei ein durchaus guter Weg ist. Man kann allenfalls noch darüber nachdenken, was man am besten in die aux-Datei schreibt. Der label-Mechanismus schreit aber schon fast danach, in der einen oder anderen Form dafür verwendet zu werden.

BTW: So etwas wie Dein \ifundefined gibt es übrigens schon. Das heißt \scr@ifundefinedorrelax. Siehe dazu Seite 263 in der aktuellen KOMA-Script-Anleitung. Die Anweisung von KOMA-Script hat dabei den Vorteil, dass sie für undefinierte Makros wohl keinen Hash-Speicher belegt, da sie mit e-TeXs \ifcsname arbeitet. Es gibt auch noch ein \ifnotundefined, das nicht ganz das Gegenteil davon ist. Näheres ist der Anleitung zu entnehmen.

von Epllus » Di 9. Apr 2013, 14:25

Edits/Edit/etc./Edit: Find a very good answer on TeX.SH(<-?).

Ich habe das Problem nun mit einer ref und label Aktion gelöst (auch, wie mir jetzt auffällt, ich kein ref verwendet habe).
Vermutlich ist es nicht die feine englische Art… aber es funktioniert.

Edit: Durch die Veränderung des Codes, ist jetzt leider ein kleines Problem entstanden: Umlaute werden als Fehler gemeldet.
Um dieses Problem zu umgehen, habe ich etwas konstruiert, das die Fehlermeldung verhindert.
Wenn man nun ein Umlaut oder ein Dialektzeichen verwenden möchte (das noch nicht vordefiniert ist), macht man folgendes:
  • Ihr nehmt den von mir dafür definierten Befehl \dazu.
  • In die erste Klammer kommt der Umlaut (z.B. Â (es ist ein Beispiel, mit T1 fontenc funktioniert auch dieser Buchstabe, am besten ihr probierts einfach aus)).
  • In die zweite kann eigentlich alles mögliche (außer Umlaute, Sonderzeichen etc.) kommen. Am besten der Name des Umlautes (z.B. hatschekA) oder eine unsinnige Buchstabenkombination, die noch nicht definiert wurde(z.B. khjwefhkewfjkh).
    Warum? Das könnt ihr ja nachfragen. Ich mag es hier nicht erklären.
  • Beispiel: \dazu{Â}{hatschekA}
Hier ist der funktionierende Code (braucht zwei Durchläufe):
\documentclass[ngerman]{scrartcl} 
\usepackage{blindtext} 
\usepackage{selinput} 
\usepackage[T1]{fontenc} 
\SelectInputMappings{ 
adieresis={ä}, germandbls={ß},} 
\usepackage{babel}

% Version 3.2 (jetzt hoffentlich noch immer Bug frei, aber umständlich) 

\makeatletter 
\@ifundefined{scr@ifundefinedorrelax}{\let\KOMAundefinedornot\@ifundefined}{\let\KOMAundefinedornot\scr@ifundefinedorrelax} 


\def\ZuruckUmlautanderung{} 
\def\Umlautanderungenweilwichtig{} 

\newcommand{\dazu}[2]{% 
\expandafter\xdef\csname #2\endcsname#1{#1}% 
\g@addto@macro\ZuruckUmlautanderung{% 
\def#1{\csname#2\endcsname#1}}% 
\g@addto@macro\Umlautanderungenweilwichtig{\def#1{#2}}% 
} 

% man braucht mehr, wenn man kein fontenc verwendet
\dazu{ß}{scharfess} 

\newif\ifTTT@at@begining@TTT 
\newcounter{TTT@Label@Ref@CounterTTT} 

\def\Tipps@item[#1]{\Umlautanderungenweilwichtig% 
\KOMAundefinedornot{ifT#1}{\expandafter\newif\csname ifT#1\endcsname}{}% 
\KOMAundefinedornot{c@T#1}{\newcounter{T#1}}{}% 
\csname ifT#1\endcsname \else\setcounter{T#1}{0}\csname T#1true\endcsname\fi% 
\ifTTT@at@begining@TTT\else\stepcounter{TTT@Label@Ref@CounterTTT}\TTT@at@begining@TTTtrue\fi% 
\edef\TTTcurrentnumberTTT{\csname theT#1\endcsname}% 
\label{\TTTcurrentnumberTTT LabelT#1T\theTTT@Label@Ref@CounterTTT}% 
   \stepcounter{T#1}% 
\edef\TTTcurrentnumberTTT{\csname theT#1\endcsname}% 
  \if@noparitem 
    \@donoparitem 
  \else 
    \if@inlabel 
      \indent \par 
    \fi 
    \ifhmode 
      \unskip\unskip \par 
    \fi 
    \if@newlist 
      \if@nobreak 
        \@nbitem 
      \else 
        \addpenalty\@beginparpenalty 
        \addvspace\@topsep 
        \addvspace{-\parskip}% 
      \fi 
    \else 
      \addpenalty\@itempenalty 
      \addvspace\itemsep 
    \fi 
    \global\@inlabeltrue 
  \fi 
  \everypar{% 
    \@minipagefalse 
    \global\@newlistfalse 
    \if@inlabel 
      \global\@inlabelfalse 
      {\setbox\z@\lastbox 
       \ifvoid\z@ 
         \kern-\itemindent 
       \fi}% 
      \box\@labels 
      \penalty\z@ 
    \fi 
    \if@nobreak 
      \@nobreakfalse 
      \clubpenalty \@M 
    \else 
      \clubpenalty \@clubpenalty 
      \everypar{}% 
    \fi}% 
  \if@noitemarg 
    \@noitemargfalse 
    \if@nmbrlist 
      \refstepcounter\@listctr 
    \fi 
  \fi 
  \sbox\@tempboxa{\ZuruckUmlautanderung\makelabel{#1}% 
\Umlautanderungenweilwichtig% 
       \ifnum\TTTcurrentnumberTTT=1% 
       \KOMAundefinedornot{r@\TTTcurrentnumberTTT LabelT#1T\theTTT@Label@Ref@CounterTTT}{}{~1}% 
         \else% 
       ~\TTTcurrentnumberTTT% 
          \fi:}% 
  \global\setbox\@labels\hbox{% 
    \unhbox\@labels 
    \hskip \itemindent 
    \hskip -\labelwidth 
    \hskip -\labelsep 
    \ifdim \wd\@tempboxa >\labelwidth 
      \box\@tempboxa 
    \else 
      \hbox to\labelwidth {\unhbox\@tempboxa}% 
    \fi 
    \hskip \labelsep}% 
  \ignorespaces\ZuruckUmlautanderung} 

% - - - - - - - - - - - - - - - - - - - - - - 

\def\Tippsitem{% 
  \@inmatherr\Tippsitem 
  \@ifnextchar [\Tipps@item{\@noitemargtrue \Tipps@item[\@itemlabel]}} 
  
% - - - - - - - - - - - - - - - - - - - - - - 
  \newenvironment{Hinweis}{\let\item\Tippsitem% 
\begin{description}} 
{\end{description}} 

\makeatother 


% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
\begin{document} 

\blindtext 
\begin{Hinweis} 
\item[Hinweis] $\leftarrow$ Hier kommt (automatisch) eine \textbf{1} hin     
\item[Hinweis] Nach 2 durchläufen 
\item[Hinweis] passt 
\item[Achtung!!]  Passt 
\item[Hmmm] Passt 
\end{Hinweis} 


\blindtext 
\begin{Hinweis} 
\item[Hinweis] $\leftarrow$ Hier kommt (automatisch) eine \textbf{1} hin   
\item[Hinweis] Nach 2 durchläufen 
\item[Vielleicht]  Text 
\item[Achtung] $\leftarrow$ Hier kommt (automatisch) eine \textbf{1} hin   
\item[Achtung]  Nach 2 durchläufen 
\item[Achtung]  Text 
\item[odd]  Text 
\end{Hinweis} 

\blindtext 

\begin{Hinweis} 
\item[Würfel]  Text 
\item[Ärger]  Text 
\item[Ärger]  Text 
\item[Ärger]  Text 
\item[Ärger]  Text 
\item[Würfel]  Text 
\item[Würfel]  Text 
\item[Würfel]  Text 
\item[Würfel]  Text 
\end{Hinweis} 


\end{document} 
Wie schon gesagt, braucht es 2 Durchläufe.

Grüße
Epllus

Nummerierung bei eigener Umgebung

von Epllus » Di 9. Apr 2013, 12:36

Ich hab mir eine Umgebung mittels description definiert, die die fettgedruckten Wörter automatisch durchnummeriert, falls sie öfters vorkommen.
Dies funktioniert auch sehr gut, nur leider schaffe ich es nicht, dass eine 1 dazugeschreiben wird, wenn das Wort öfters vorkommt.

Zur besseren Verdeutlichung hier mal mein as-minimal-as-possible Beispiel:
\documentclass{scrartcl} 
\usepackage{blindtext}

\makeatletter
\newcommand*{\ifundefined}[1]{%
  \begingroup\expandafter\expandafter\expandafter\endgroup
  \expandafter\ifx\csname #1\endcsname\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

% - - - - - - - - - - - - - - - - - - - - - - 
\def\Tipps@item[#1]{% % % % % % % % % % % % % % % % %  Verändert
\ifundefined{if#1T}{\expandafter\newif\csname if#1T\endcsname}{}%
    \ifundefined{c@T#1}{\newcounter{T#1}}{}%
   \csname if#1T\endcsname \else\setcounter{T#1}{1}\csname #1Ttrue\endcsname\fi
  \if@noparitem
    \@donoparitem
  \else
    \if@inlabel
      \indent \par
    \fi
    \ifhmode
      \unskip\unskip \par
    \fi
    \if@newlist
      \if@nobreak
        \@nbitem
      \else
        \addpenalty\@beginparpenalty
        \addvspace\@topsep
        \addvspace{-\parskip}%
      \fi
    \else
      \addpenalty\@itempenalty
      \addvspace\itemsep
    \fi
    \global\@inlabeltrue
  \fi
  \everypar{%
    \@minipagefalse
    \global\@newlistfalse
    \if@inlabel
      \global\@inlabelfalse
      {\setbox\z@\lastbox
       \ifvoid\z@
         \kern-\itemindent
       \fi}%
      \box\@labels
      \penalty\z@
    \fi
    \if@nobreak
      \@nobreakfalse
      \clubpenalty \@M
    \else
      \clubpenalty \@clubpenalty
      \everypar{}%
    \fi}%
  \if@noitemarg
    \@noitemargfalse
    \if@nmbrlist
      \refstepcounter\@listctr
    \fi
  \fi
  \sbox\@tempboxa{\makelabel{#1}% % % % % % % % % % % % % % % % %  Verändert
       \ifnum\expandafter\the\csname c@T#1\endcsname=1 \relax%
         \else%
       ~\expandafter\the\csname c@T#1\endcsname \fi:}%
  \global\setbox\@labels\hbox{%
    \unhbox\@labels
    \hskip \itemindent
    \hskip -\labelwidth
    \hskip -\labelsep
    \ifdim \wd\@tempboxa >\labelwidth
      \box\@tempboxa
    \else
      \hbox to\labelwidth {\unhbox\@tempboxa}%
    \fi
    \hskip \labelsep}%
  \ignorespaces\stepcounter{T#1}}


% - - - - - - - - - - - - - - - - - - - - - - 

\def\Tippsitem{%
  \@inmatherr\Tippsitem 
  \@ifnextchar [\Tipps@item{\@noitemargtrue \Tipps@item[\@itemlabel]}}
  
% - - - - - - - - - - - - - - - - - - - - - - 
  \newenvironment{Hinweis}{\let\item\Tippsitem%
\begin{description}}
{\end{description}}

\makeatother


% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 \begin{document}

\blindtext
\begin{Hinweis}
\item[Hinweis] $\leftarrow$ Hier sollte (automatisch) eine \textbf{1} hin  
\item[Hinweis] Passt 
\item[Hinweis] passt 
\item[Achtung!!]  Passt
\item[Hmmm] Passt 
\end{Hinweis}


\blindtext
\begin{Hinweis}
\item[Hinweis] $\leftarrow$ Hier sollte (automatisch) eine \textbf{1} hin 
\item[Hinweis] Text 
\item[Vielleicht]  Text
\item[Achtung!]  $\leftarrow$ Hier sollte (automatisch) eine \textbf{1} hin 
\item[Achtung!]  Text
\item[Achtung!]  Text
\item[odd]  Text
\end{Hinweis}


\end{document}
Wie schon gesagt, wenn ein Begriff öfters vorkommt, wäre es toll, wenn dort automatisch eine 1 stehen würde.

Hat jemand ein paar Ideen, Lösungen, Hinweise, bin offen für alles?

Grüße
Epllus

PS. Mir ist leider keine bessere Überschrift eingefallen.

Nach oben