5

I would like to incorporate the suggested solution by Herbert, that can be found HERE, within certain glossary records.

Consider the following example:

\documentclass[a4paper]{book}

\usepackage{glossaries}
\makeglossaries
\makeatletter
    \newcommand{\fs}{\@ifnextchar.{}{.}}% test of next token 
\makeatother

\newglossaryentry{pg}{
    name={pg.},
    description={pg.},
    first={pg.},
    firstplural={pp.},
    plural={pp.}
}
\newglossaryentry{fig}{
    name={fig.},
    description={fig.},
    first={fig.},
    firstplural={figs.},
    plural={figs.}
}


\begin{document}
    as can be seen in the \glspl{fig} on the following \gls{pg}.
\end{document}

Which typesets without issue, however it creates a double dot at the end of the sentence.

A solution that I had in mind would be to try and put the defined macro \fs into the glossary records, however errors get returned, ie, the following causes the above to not compile:

\newglossaryentry{pg}{
    name={pg\fs},
    description={pg\fs},
    first={pg\fs},
    firstplural={pp\fs},
    plural={pp\fs}
}

Another approach could be to modify the \gls{...} and similar commands, to check if the evaluated record ends in a '.', and if so, replace by the \fs macro, but there are many commands as part of the glossaries package, not sure how to do it this way.

How can this be achieved. I use glossaries as a means to host many such abbreviations on a document-wide basis.

  • To get compilable code use \DeclareRobustCommand{\fs}{\@ifnextchar.{}{.}}. However, this doesn't help with eating the dot though. – Andrew Swann Jun 17 '13 at 16:13

2 Answers2

6

This requires adding a level above \gls and similar commands. One can redefine them, rather than use new commands, this is left as an exercise.

\documentclass[a4paper]{book}

\usepackage{glossaries,amsthm}
\makeglossaries

\makeatletter
% define a non space skipping version of \@ifnextchar
\newcommand\fussy@ifnextchar[3]{%
  \let\reserved@d=#1%
  \def\reserved@a{#2}%
  \def\reserved@b{#3}%
  \futurelet\@let@token\fussy@ifnch}
\def\fussy@ifnch{%
  \ifx\@let@token\reserved@d
    \let\reserved@c\reserved@a 
  \else
    \let\reserved@c\reserved@b
  \fi
 \reserved@c}

\DeclareRobustCommand{\Gls}[1]{%
  \gls{#1}\fussy@ifnextchar.{\@checkperiod}{\@}}
\DeclareRobustCommand{\Glspl}[1]{%
  \glspl{#1}\fussy@ifnextchar.{\@checkperiod}{\@}}

\newcommand{\@checkperiod}[1]{%
  \ifnum\sfcode`\.=\spacefactor\else#1\fi
}
\makeatother

\newglossaryentry{box}{
  name=box,
  description=box,
  plural=boxes,
}

\newglossaryentry{pg}{
  name={pg.},
  description={pg.},
  first={pg.},
  firstplural={pp.},
  plural={pp.}
}
\newglossaryentry{fig}{
  name={fig.},
  description={fig.},
  first={fig.},
  firstplural={figs.},
  plural={figs.}
}


\begin{document}
As can be seen in the \Glspl{fig} on the following \Gls{pg}.

As can be seen in \Glspl{box} or in \Gls{box}.

As can be seen in the \Glspl{fig}, on the following \Gls{pg}, we have commas.

As can be seen in \Glspl{box}, or in \Gls{box}, we have commas.

\end{document}

Note that amsthm is essential; actually what's needed is how it redefines \frenchspacing so a unique space factor code is set by a period and not the generic 1000.

enter image description here

egreg
  • 1,121,712
3

Adding \fs to the definitions won't work as the text generated by commands such as \gls can be quite deeply embedded within the internal workings. At the very least, it will be followed by the unsetting of the first use flag. There are two alternatives:

Method 1:

Keep track of which entries have a dot (such as including the dot in the label to remind yourself) and don't add the sentence dot. For example:

\documentclass[a4paper]{book}

\usepackage{glossaries}
\makeglossaries

\newglossaryentry{pg.}{
    name={pg.},
    description={pg.},
    first={pg.},
    firstplural={pp.},
    plural={pp.}
}
\newglossaryentry{fig.}{
    name={fig.},
    description={fig.},
    first={fig.},
    firstplural={figs.},
    plural={figs.}
}

\begin{document}
    as can be seen in the \glspl{fig.} on the following \gls{pg.}
This sentence refers to the \gls{fig.}['s] caption.
\end{document}

Result:

Image of result

Method 2:

Don't add the dot to the definitions. Instead define a command that will add the dot where required. For example:

\documentclass[a4paper]{book}

\usepackage{glossaries}
\makeglossaries

\makeatletter

  \newcommand{\abbrev}[2][]{%
    \new@ifnextchar[%
     {\@abbrev{#1}{#2}}% get the final optional argument
     {%
        \new@ifnextchar.%
        {\@gls@{#1}{#2}[]}% end of sentence found
        {\@gls@{#1}{#2}[.\spacefactor=1000]}% not end of sentence, add abbreviation dot
     }%
  }

  \def\@abbrev#1#2[#3]{%
    \new@ifnextchar.%
    {\@gls@{#1}{#2}[#3]}% end of sentence found
    {\@gls@{#1}{#2}[.#3]}% not end of sentence, add abbreviation dot
  }

  % Similar code for plural:

  \newcommand{\abbrevpl}[2][]{%
    \new@ifnextchar[%
     {\@abbrevpl{#1}{#2}}% get the final optional argument
     {%
        \new@ifnextchar.%
        {\@glspl@{#1}{#2}[]}% end of sentence found
        {\@glspl@{#1}{#2}[.\spacefactor=1000]}% not end of sentence, add abbreviation dot
     }%
  }

  \def\@abbrevpl#1#2[#3]{%
    \new@ifnextchar.%
    {\@glspl@{#1}{#2}[#3]}% end of sentence found
    {\@glspl@{#1}{#2}[.#3]}% not end of sentence, add abbreviation dot
  }

  % Do likewise for any other required variation

\makeatother

\newglossaryentry{pg}{
    name={pg.},
    text={pg},
    description={pg},
    first={pg},
    firstplural={pp},
    plural={pp}
}
\newglossaryentry{fig}{
    name={fig.},
    text={fig},
    description={fig},
    first={fig},
    firstplural={figs},
    plural={figs}
}

\begin{document}
    as can be seen in the \abbrevpl{fig} on the following \abbrev{pg}.
This sentence refers to the \abbrev{fig}['s] caption.
\end{document}

This produces:

Image of result

The second method correctly adjusts the space factor.

Nicola Talbot
  • 41,153