[Tex/LaTex] macro for glossaries counter

countersglossariesmacros

I want custom my glossaries, and specially I want to have something like

My glossary entry, its signification (see p. 1), if this entry mentioned only once

or

My glossary entry, its signification (see pp. 1,2), if this entry mentioned several times

So I create command to count the number of item in the list ##2 used by

\newglossarystyle

and another command to print see p. or see pp.

I tested these command outside of the \newglossarystyle definition, it seems to work. But inside this definition the command to count the number of item in the list don't accept the ##2 argument.

Here is my example:

% arara: pdflatex
% arara: makeglossaries
% arara: pdflatex
% arara: makeglossaries
% arara: pdflatex

\documentclass[onecolumn,twoside,openright,a4paper,11pt]{report}    

\usepackage[utf8]{inputenc}     
\usepackage[T1]{fontenc}        

\usepackage{hyperref}       
\usepackage{calc}
\usepackage{pgffor}     % you don't need this if tikz is already included

\usepackage[toc,acronym,xindy,section=section]{glossaries} 



\newcounter{moncompteur}

\newcommand{\Znumlist}[1]{
\setcounter{moncompteur}{0}
    \foreach \e in{#1}{%
    \addtocounter{moncompteur}{1}
    }
\themoncompteur
}

\newcommand{\montest}[1]{%
    \ifnum#1<2%
        \seename\ p.
    \else%
        \seename\ pp.
    \fi%
}
\newglossarystyle{mylist}{  %
    \setglossarystyle{list} % base this style on the list style
    \renewcommand*{\glossentry}[2]{%
    \item[\glsentryitem{##1}%
    \glstarget{##1}{\glossentryname{##1}}]
    %\glossentrydesc{##1}\glspostdescription\space \Znumlist{##2}\montest{\themoncompteur}\space ##2} %
    \glossentrydesc{##1}\glspostdescription\space \Znumlist{##2}\space ##2}
}


\newglossary[ntg]{notation}{not}{ntn}{Glossaire}
\newglossary[slg]{symbols}{sym}{sbl}{Nomenclature}

 \makeglossaries        %




\newglossaryentry{glscard}{ %type=main,
    name=cardinality,
    description={The number of elements in the specified set}}

\newglossaryentry{mesh}{type=notation,
    name={Mesh},
    description={maillage},
    sort={m}}

\newglossaryentry{mbb}{type=symbols,    
    name={\ensuremath{ {M} }},
    text={ {M} },                                 
    description={matrix},               
    sort=m,                             
    see=[see also]{glscard}} 

\begin{document}       % 

\setglossarystyle{mylist}    
\printglossary[toctitle=Lexique,type=main]
\newacronym{pc}{PC}{personal computer}   
\printglossary[toctitle=Acronyms,type=acronym]
\printglossary[type=notation]
\printglossary[type=symbols]

\chapter{Introduction}
\section{ab}

 \gls{pc}; \gls{glscard}; \gls{mbb}; \gls{mesh}; \newpage 
 \gls{mesh}

\Znumlist{1,3,4} \montest{\themoncompteur}

\end{document}

How do I use a argument like ##2 inside a command?

Best Answer

The glossaries package already provides a mechanism for counting the number of times an entry has been used, but it must be enabled using \glsenableentrycount. This was added to version 4.14 and is documented in section 14.1 of the user manual.

Example:

\documentclass{article}

\usepackage{glossaries}

\makeglossaries

\glsenableentrycount

\newglossaryentry{sample}{name={sample},description={an example}}

\newacronym{ab}{AB}{sample abbreviation}

\begin{document}
Number of times ``sample'' was used on the last run:
\glsentryprevcount{sample}.

\gls{sample}. \gls{sample}. \gls{ab}.

Number of times ``sample'' has been used in this run \emph{so far}:
\glsentrycurrcount{sample}.

\newpage

\gls{sample}. \gls{ab}.

\newpage

\printglossaries

\end{document}

This produces (after a second run):

Image of result. Used 3 times on previous run and 2 times so far

Notes:

  1. \glsenableentrycount must be used before you define your entries.
  2. This mechanism imposes a preamble-only restriction on the use of \newglossaryentry (and, therefore, also \newacronym which internally uses \newglossaryentry).

You can then use \glsentryprevcount in your glossary style:

\newglossarystyle{mylist}
{%
  \setglossarystyle{list}%
  \renewcommand*{\glossentry}[2]{%
    \item[\glsentryitem{##1}%
          \glstarget{##1}{\glossentryname{##1}}]
       \glossentrydesc{##1}\glspostdescription\space
       \ifnum\glsentryprevcount{##1}>1 pp.\else p.\fi\ ##2}%
}

Take care as the previous count value represents the total number of times the entry has been used. This value is reset back to zero with \glsreset and it also doesn't necessarily match the number of locations in the location list. For example, if an entry is used twice on one page but nowhere else in the document, then the location list will have a single location (that page) but the entry count will be 2.

The (currently experimental) glossaries-extra package enhances this feature and provides per-unit counting.

Edit:

Just using glossaries:

% arara: pdflatex
% arara: makeglossaries
% arara: pdflatex
\documentclass{report}    

\usepackage[utf8]{inputenc}     
\usepackage[T1]{fontenc}        

\usepackage[colorlinks]{hyperref}       

\usepackage[toc,acronym,xindy,section=section]{glossaries} 

\newglossarystyle{mylist}{%
  \setglossarystyle{list}% base this style on the list style
  \renewcommand*{\glossentry}[2]{%
  \item[\glsentryitem{##1}%
  \glstarget{##1}{\glossentryname{##1}}]
  \glossentrydesc{##1}\glspostdescription\space
  \ifnum\glsentryprevcount{##1}>1 pp.\else p.\fi\ ##2}%
}


\newglossary[ntg]{notation}{not}{ntn}{Glossaire}
\newglossary[slg]{symbols}{sym}{sbl}{Nomenclature}

\makeglossaries        %

\glsenableentrycount

\newglossaryentry{glscard}{
    name=cardinality,
    description={The number of elements in the specified set}}

\newglossaryentry{mesh}{type=notation,
    name={Mesh},
    description={maillage},
    sort={m}}

\newglossaryentry{mbb}{type=symbols,    
    name={\ensuremath{M}},
    text={M},                                 
    description={matrix},               
    sort=m,                             
    see=[see also]{glscard}} 

\newacronym{pc}{PC}{personal computer}   

\setglossarystyle{mylist}    

\begin{document} 
\printglossary[toctitle=Lexique,type=main]
\printglossary[toctitle=Acronyms,type=acronym]
\printglossary[type=notation]
\printglossary[type=symbols]

\chapter{Introduction}
\section{ab}

\gls{pc}; \gls{pc}; \gls{glscard}; \gls{mbb}; \gls{mesh}; \newpage 
\gls{mesh}

\end{document}

This produces:

image of glossaries

This mostly works except for the pc entry which occurs twice on page 2 but not on any other page. Since the total usage for that entry is greater than 1, pp is used instead of p even though there's only a single page in the location list. Below is an alternative solution that uses glossaries-extra.

Caveat: glossaries-extra is still experimental and this may fail in the odd occasions where entries occur in a page-break spanning paragraph due to TeX's asynchronous output routine.

The following adapts your mwe to use glossaries-extra:

% arara: pdflatex
% arara: makeglossaries
% arara: pdflatex
\documentclass{report}    

\usepackage[utf8]{inputenc}     
\usepackage[T1]{fontenc}        

\usepackage[colorlinks]{hyperref}       
\usepackage[nopostdot=false,% put a dot after the descriptions
 abbreviations,% create a separate list of abbreviations
 xindy,section=section]{glossaries-extra} 

\GlsXtrEnableEntryUnitCounting
 {general,abbreviation}% apply to both general and abbreviation categories
 {0}% don't trigger index suppression
 {page}% count per page

\newglossarystyle{mylist}{%
  \setglossarystyle{list}% base this style on the list style
  \renewcommand*{\glossentry}[2]{%
  \item[\glsentryitem{##1}%
  \glstarget{##1}{\glossentryname{##1}}]
  \glossentrydesc{##1}\glspostdescription\space
  \ifnum\glsentryprevtotalcount{##1}>1 pp.\else p.\fi\ ##2}%
}

% In case an entry is used two or more times on one page but not on any of the
% other pages.
\let\ORGglsxtrpostunset\glsxtrpostunset

\renewcommand*{\glsxtrpostunset}[1]{%
  \ifnum\glsentrycurrcount{#1}>0 \else\ORGglsxtrpostunset{#1}\fi
}


\newglossary[ntg]{notation}{not}{ntn}{Glossaire}
\newglossary[slg]{symbols}{sym}{sbl}{Nomenclature}

\makeglossaries

% general entries

\newglossaryentry{glscard}{
    name=cardinality,
    description={The number of elements in the specified set}}

\newglossaryentry{mesh}{type=notation,
    name={Mesh},
    description={maillage},
    sort={m}}

\newglossaryentry{mbb}{type=symbols,    
    name={\ensuremath{M}},
    text={M},                                 
    description={matrix},               
    sort=m,                             
    see=[see also]{glscard}} 

% abbreviations

\newabbreviation{pc}{PC}{personal computer}   

\setglossarystyle{mylist}    

\begin{document} 

\printglossary[toctitle=Lexique,type=main]
\printabbreviations
\printglossary[type=notation]
\printglossary[type=symbols]

\chapter{Introduction}
\section{ab}

 \gls{pc}; \gls{pc}; \gls{glscard}; \gls{mbb}; \gls{mesh}; \newpage 
 \gls{mesh}

\end{document}

This produces:

image of glossaries

Notes:

  • Although the glossaries-extra package internally loads the glossaries package, it sets different defaults (e.g. toc and nopostdot). To illustrate this I've removed the toc option and added nopostdot to emulate the settings of your mwe.
  • The glossaries-extra package has a different (and better) way of dealing with abbreviations.
  • With the per unit counting, \glsentrycurrcount and \glsentryprevcount refer to the count for the current unit. So if you have, say, \glsentryprevcount{pc} on page 1, you'll get the number of times the entry was used on page 1 (where the unit counter is page). This means that it's of no use in the glossary style, since you're not interested in how many times the entry has been used in the glossary (which happens to be 0).
  • The total count (from the previous run) is obtained with \glsentryprevtotalcount so the style tests if this value is greater than one.
  • To cater for the possibility of an entry being used two or more times on one page of the document but not used at all on any other page, I've adjusted the definition of \glsxtrpostunset. For example, I've used pc twice on one page but nowhere else, which would've set the total count to 2, and "pp" would've appeared in the glossary for the pc entry (as in the previous example). This modification effectively sets a maximum count of 1 per page.
Related Question