6

How can I create a counter which is fixed once it has been set?

The idea is to insert some kind of remarks into a text which should be numbered, but increasing with the date of actual implementation into the source code.

They should not depend on the order in the source code, and they should keep their value even if some of them are removed.

Here not a MWE, but an idea how the implementation should look like:

\documentclass{article}
\begin{document}
  \mynote{Some note I've added first}, 
  \mynote{A fourth note}, 
  \mynote{A second note}, 
  \mynote{A fifth note}, 
  \mynote{A third note}.    
\end{document}

This should give an output as:

Note 1: Some note I've added first
Note 4: A fourth note,
Note 2: A second note,
Note 5: A fifth note,
Note 3: A third note.

If I delete the line with the second note, it should give:

Note 1: Some note I've added first,
Note 4: A fourth note,
Note 5: A fifth note,
Note 3: A third note.

9
  • At the moment I can only think of manually setting the countervalue on each note. Jul 15, 2013 at 15:51
  • @Martin to point why I want to use counters is to avoid searching in the document to find the actual number.
    – jjdb
    Jul 15, 2013 at 15:56
  • 3
    I guess you can do it with the help of your editor, but not from *tex alone (one reason at least: two identical tex documents are supposed to give the same output, no matter in which order they were written).
    – T. Verron
    Jul 15, 2013 at 16:01
  • 2
    The idea is to write the current counter value on a temp file and then when you'll use the command again you'll need to read the last line of the temp file to know the new value to be used on the counter.
    – Sigur
    Jul 15, 2013 at 16:09
  • 1
    Basically, you want your input file to have some "memory". You can achieve that by writing to and reading from some auxiliary file, as suggested by Sigur. See this.
    – jub0bs
    Jul 15, 2013 at 16:12

2 Answers 2

7

Here is a proof of concept, but using an auxiliary file in this way is very dangerous, because an error might ruin the previous copy and the order of the notes would be lost. So a routine that backs up the .notes file must be run at the end of the LaTeX job.

\documentclass{article}

\makeatletter
\newwrite\jjdbout
\newcounter{jjdbnotes}
\def\countnotes#1#2{\stepcounter{jjdbnotes}}
\def\savenote#1#2{%
  \expandafter\gdef\csname #1\endcsname{#2}%
  \addnote{#1}{#2}%
}
\makeatletter
\def\addnote#1#2{%
  \toks@=\expandafter{\jjdbnotes}%
  \xdef\jjdbnotes{\the\toks@^^J%
    \noexpand\jjdbnote{#1}{#2}}%
}
\makeatother
\let\jjdbnote\countnotes
\InputIfFileExists{\jobname.notes}{}{}
\let\jjdbnote\savenote
\gdef\jjdbnotes{} % initialize
\InputIfFileExists{\jobname.notes}{}{}

\newcommand{\mynote}[1]{%
  \par
  \ifcsname\pdfmdfivesum{#1}\endcsname
    \textbf{Note \csname\pdfmdfivesum{#1}\endcsname: }#1%
  \else
    \stepcounter{jjdbnotes}%
    \expandafter\addnote{\pdfmdfivesum{#1}}{\thejjdbnotes}%
    \textbf{Note \thejjdbnotes: }#1%
  \fi
}
\AtEndDocument{
  \immediate\openout\jjdbout=\jobname.notes
  \immediate\write\jjdbout{\unexpanded\expandafter{\jjdbnotes}}
}

\begin{document}
  \mynote{Some note I've added first},
  \mynote{A fourth note},
  \mynote{A second note},
  \mynote{A fifth note},
  \mynote{A third note}.

\end{document}

The .notes file is read twice; the first one for counting the entries and the second one to assign a meaning to the lines.

Each note is stored as its MD5 checksum, which should be uniquely associated to the text. Of course, if a note text gets changed, the ordering will be lost again.

So to each checksum the note number is assigned. If during a run we find a new note, it will be added to the \jjdbnotes macro, whose contents will be written out to the .notes file at the end of the job. Note that TeX cannot append lines to an existing file.

The shown output has been obtained by uncommenting the lines one by one according to the stated order.

enter image description here

A better approach would be to have the notes stored in a separate file notes.tex say in the form

\makeatletter
\newcommand{\savenote}[2]{\@namedef{jjdb@note#2}{#1}}
\newcommand{\mynote}[1]{\@nameuse{jjdb@note#1}}
\makeatother

\savenote{Some note I've added first}{1}
\savenote{A second note}{2}
\savenote{A third note}{3}
\savenote{A fourth note}{4}
\savenote{A fifth note}{5}

and do \input{notes} in the preamble. Then in the document you can use

\mynote{1},
\mynote{4},
\mynote{2},
\mynote{5},
\mynote{3}.

In this way you simply add the notes sequentially.

5
  • 2
    +1. Day after day I'm sure that @egreg is the creator of TeX... lol
    – Sigur
    Jul 15, 2013 at 17:31
  • @Sigur I never wear traditional Norwegian overalls. ;-) youtube.com/watch?v=cI6tt9QfRdo
    – egreg
    Jul 15, 2013 at 17:32
  • +1, nice! would give another +1 for the second solution, and another +1 for the command \jjdbnotes
    – jjdb
    Jul 16, 2013 at 7:46
  • In the third line of the second code block, there is a closing bracket missing.
    – jjdb
    Jul 16, 2013 at 8:53
  • @jjdb There was, you weren't able to see it. ;-) Thanks.
    – egreg
    Jul 16, 2013 at 8:58
2

I think that what you want is exactly the case where the cross-referencing in LaTeX doesn't help you : it's enough to hard code them. If you want to format (bold and so on), you can use a description environement, or create you own command like :

\newcommand{\mynote}[1]{\par\noindent\bfseries Note#1}

and use

\mynote{1} some text
\mynote{3} some other text

EDIT : As suggested by other users, add '\writecommand in\mynote` to get something like :

\documentclass{article}
\begin{document}
\newwrite\notenumber
\immediate\openout\notenumber=note.dat
\newcommand{\mynote}[1]{%
           \immediate\write\notenumber{#1}\par\noindent\bfseries Note~#1:}
\mynote{3} the note number 3
\mynote{1} the note number 1
\end{document}

You can then sort them in yourtext editor, or in LaTeX by using the anwswer of this question

3
  • The bold is not the point, I've just put it as the output was not in separate lines before the edit. Still, if I have a huge document with hundreds of unsorted notes, how should I find the next number I have to put as argument?
    – jjdb
    Jul 15, 2013 at 16:21
  • Using an auxiliary file is not a good way to go; if it gets corrupted, everything is lost.
    – egreg
    Jul 15, 2013 at 17:03
  • @egreg: in my approach, this file would only contains a list of the hard-codded numbers, then you have merely nothing to loss, which is not already in the tex field, isn'it ?
    – Jhor
    Jul 15, 2013 at 17:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .