1

I need to manage a list of requirements, with counters that keeps their values once created. How could I do that ?

Example:

  • Step 1: the document is created with two requirements, alpha and beta, that gets numbers 1 and 2 after build:

    1 alpha
    2 beta
    
  • Step 2: a third requirement is created. Build again:

    1 alpha
    2 beta
    3 gamma
    
  • Step 3: someone wants to add another requirement at the beginning of the doc, but older references must stay the same. So the firth is number four, even if between one and two:

    1 alpha
    4 delta
    2 beta
    3 gamma
    

I think it would require a generated file to remember used references, but I don't know how to achieve this.

1
  • If the generated file is deleted in between or after some time the inserted information gets lost -- Nobody will know that delta was inserted as 4th item later on then.
    – user31729
    Commented Jun 12, 2017 at 22:08

1 Answer 1

2

You can do this with the etoolbox package, which defines list operations, booleans and string comparison (among other things). The MWE below generates a file stored.txt where the requirements are stored in order of consecutive runs. For a new run, existing items are numbered in the order of this list and new items are added at the end. Note the comment by @Christian Hupfer.

\documentclass{article}
\usepackage{etoolbox}

\newcommand{\persistent}{} % create initially empty list

\newcounter{Current}       % existing position in list
\newcounter{MaxSeq}        % highest position in list
\newtoggle{FoundInList}    % boolean test if item is found

\newcommand{\cmphandler}[2]{%
    \stepcounter{Current}%      % increase position in list
    \ifstrequal{#1}{#2}%        % if the current item is the item to print
    {\toggletrue{FoundInList}\listbreak}{}%    % then set to found and exit loop
}

% write full list to file after adding items 
\newcommand{\writeall}[1]{\write\listfile{\noexpand\listgadd{\noexpand\persistent}{#1}\noexpand\stepcounter{MaxSeq}}}

% print the current item in the document
\newcommand{\printpersistent}[1]{%
\setcounter{Current}{0}%
\togglefalse{FoundInList}%
\forlistloop{\cmphandler{#1}}{\persistent}% % find position in list
\iftoggle{FoundInList}%                     % if item is found
{\arabic{Current} #1}%                      % print position and item
{\listgadd{\persistent}{#1}\stepcounter{MaxSeq}\arabic{MaxSeq} #1}%     % else add to end of list and print item
\par                                        % start new paragraph
}

\begin{document}
% load existing list if available
\InputIfFileExists{stored.txt}{}{}

% print all items
\printpersistent{alpha $(\alpha)$}
\printpersistent{delta $(\delta)$}
\printpersistent{beta $(\beta)$}
\printpersistent{gamma $(\gamma)$}

% print full list to file
\newwrite\listfile
\openout\listfile=stored.txt
\forlistloop{\writeall}{\persistent}
\closeout\listfile
\end{document}

Result after three runs:

enter image description here

1
  • Thanks for your solution ! I works great. Now I can migrate my report to latex, instead of keeping then in MS Word with macros to generate those persistent numbers. Just one thing. If you work on Overleaf, make sure to create/import a "stored.txt" file in your project. Without it, it will compile, but persistent numbering won’t work.
    – Atiroocky
    Commented Jun 24 at 7:37

You must log in to answer this question.

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