1

Good evening, or morning, depending on where you are.

Background

I have been tinkering with an idea for how I can make my LaTeX macros easily accessible in for markdown (through MathJax) without lowering my standards in LaTeX. Specifically, I want to be able to write equations that are Ctrl+C, Ctrl+V ready. Moreover, since I have to think about writing a thesis I want it to flawlessly fall into my glossary and index system.

I have achieved a minimal working example using the rather exhaustive approach:

  1. Define notation using \newcommand, and make a "dummy" copy to be used in glossary definition.
  2. Define glossary entries where the label is the same as the notation equivalent.
  3. Redefine notation definitions such that \Hamiltonian |--> \glssymbol{Hamiltonian}\index{Hamiltonian}

Minimal Example

Typeset command (terminal):

filename=asdf.tex
pdflatex ${filename}
makeglossaries  -l ${filename%%.*}
makeindex  ${filename/.*/.idx}
pdflatex ${filename}
pdflatex ${filename}

LaTeX file:

\documentclass[b5paper]{memoir}
%
\title{This is a test}
\author{Ola}
% 1 ************** N O T A T I O N -- D E F I N I T I O N ******************* %
\usepackage{amsmath}
%% H
\newcommand{\Hamiltonian}{\ensuremath{\mathcal{H}}}% <-------------- Definition
\let\OldHamiltonian\Hamiltonian% <--------------------- Used in glossary symbol
%% L
\newcommand{\Lagrangian}{\ensuremath{\mathcal{L}}}% <--------------- Definition
\let\OldLagrangian\Lagrangian% <----------------------- Used in glossary symbol
%% P
\newcommand{\vecGeneralMomentum}{\ensuremath{\mathbf{p}}}% <------- Definition
\let\OldVecGeneralMomentum\vecGeneralMomentum% <----- Used in glossary symbol
%% Q
\newcommand{\vecGeneralPosition}{\ensuremath{\mathbf{q}}}% <-------- Definition
\let\OldVecGeneralPosition\vecGeneralPosition% <------- Used in glossary symbol
% 2 ************ G L O S S A R Y -- D E F I N I T I O N ********************* %
\usepackage{hyperref}
\usepackage[%
  nopostdot,%
  nonumberlist,%
  toc,%
  section,%
  acronym,%
]{glossaries}
%% H
\newglossaryentry{Hamiltonian}{% <--------- The same as in \newcommand
  type=main,%
  name={Hamiltonian function},%
  symbol={\OldHamiltonian},% <------------- "dummy" copy of command
  description={Hamiltonian function},%
}%
%% L
\newglossaryentry{Lagrangian}{% <---------- The same as in \newcommand
  type=main,%
  sort={Lagrangian},%
  name={Lagrangian function},%
  symbol={\OldLagrangian},% <-------------- "dummy" copy of command
  description={Lagrangian function},%
}%
%% P
\newglossaryentry{vecGeneralPosition}{% <-- The same as in \newcommand
  type=main,%
  sort={Pos},%
  name={position vector},%
  symbol={\OldVecGeneralPosition},% <------ "dummy" copy of command
  description={Generalised position vector},%
}%
%% Q
\newglossaryentry{vecGeneralMomentum}{% <--- The same as in \newcommand
  type=main,%
  name={momentum vector},%
  symbol={\OldVecGeneralMomentum},% <------- "dummy" copy of command
  description={Generalised momentum vector},%
}%
% ... Prettify the glossary table...
\newglossarystyle{mylong2col}{%
  % put glossary in a longtable
  \renewenvironment{theglossary}%
    {%
     \setlength\LTleft{0pt}
     \setlength\LTright{0pt}
     \begin{longtable}[l]{@{\extracolsep{\fill}}l|p{\glsdescwidth}@{}}%
    }%
    {\end{longtable}}%
  % Set the table header
   \renewcommand*{\glossaryheader}{%
    \bfseries Symbol &%
    \bfseries Description
    \\ \hline \endhead}%
   \renewcommand*{\glsgroupheading}[1]{}%
   \renewcommand*{\glossentry}[1]{%
      \glsentryitem{##1}%                              Entry number if required
      \glstarget{##1}{\glossentrysymbol{##1}}%                           Symbol
        & \glossentrydesc{##1}% Description
        \tabularnewline % end of row
   }%
  \renewcommand*{\glsgroupskip}{}%
}
%
\makeglossaries
\makeindex
%
% 3 ************ R E D E F I N E  --  D E F I N I T I O N S ****************** %
%% H
\renewcommand{\Hamiltonian}{\glssymbol{Hamiltonian}\index{\glsentryfirst{Hamiltonian}}}
%% L
\renewcommand{\Lagrangian}{\glssymbol{Lagrangian}\index{\glsentryfirst{Lagrangian}}}
%% P
\renewcommand{\vecGeneralMomentum}{\glssymbol{vecGeneralMomentum}\index{\glsentryfirst{vecGeneralMomentum}}}
%% Q
\renewcommand{\vecGeneralPosition}{\glssymbol{vecGeneralPosition}\index{\glsentryfirst{vecGeneralPosition}}}
% ===================== B E G I N   D O C U M E N T  ======================== %
\begin{document}
%
% ----------------------- F R O N T - M A T T E R --------------------------- %
\frontmatter
%
\maketitle
%
\printglossary[style=mylong2col]
%
% ------------------------ M A I N - M A T T E R ---------------------------- %
%
\mainmatter
%
\chapter{Classical Mechanics}
$$
  \Hamiltonian := \mathrm{d}\left(\vecGeneralPosition \vecGeneralMomentum \right) - \Lagrangian
$$
% -------------------------- A P P E N D I X -------------------------------- %
\appendix
%
% ------------------------- B A C K - M A T T E R --------------------------- %
\backmatter
\printindex
%
\end{document}

Question

I want to replace the third step above with an automated loop using the features of the glossaries package.

I was planning to use forallglsentries, i.e. something along the lines of:

\forallglsentries[main]{\glslabel}{%
  \renewcommand{\glslabel}{\glssymbol{\glslabel}\index{\glsentryfirst{\glslabel}}}
}%

However, here I am not able to get \csname \oldSymbol\endcsname to work, which is necessary because \oldSymbol expands to "Hamiltonian", whereas renewcommand needs "\Hamiltonian".

Any ideas for how to approach this situation is greatly appreciated.


Bonus question

I have a suspicion that "step 2" is redundant as well, but I do not see an obvious way around it without introducing circular references as I demand that the name given in the definition (\newcommand) should be the one that is used in the text as well.

Is there a way for me to "copy/expand" the content of a newcommand into the symbol key of the glossaryentry?

  • 1
    This is an expansion issue – user31729 Dec 28 '16 at 11:28
2

The usual issue with \renewcommand and constructing command sequences is the missing expansion with \csname ...\endcsname, so use \expandafter\renewcommand\csname\oldSymbol\endcsname{...}

However, this would not be sufficient, unless the \oldSymbol value is 'pre'-expanded before it can be used inside \glssymbol etc., otherwise, it would either cause errors or the wrong value (i.e. always the last one in the \forallglsentries - loop) will be applied.

\documentclass[b5paper]{memoir}
%
\title{This is a test}
\author{Ola}
% 1 ************** N O T A T I O N -- D E F I N I T I O N ******************* %
\usepackage{amsmath}
%% H
\newcommand{\Hamiltonian}{\ensuremath{\mathcal{H}}}% <-------------- Definition
\let\OldHamiltonian\Hamiltonian% <--------------------- Used in glossary symbol
%% L
\newcommand{\Lagrangian}{\ensuremath{\mathcal{L}}}% <--------------- Definition
\let\OldLagrangian\Lagrangian% <----------------------- Used in glossary symbol
%% P
\newcommand{\vecGeneralMomentum}{\ensuremath{\mathbf{p}}}% <------- Definition
\let\OldVecGeneralMomentum\vecGeneralMomentum% <----- Used in glossary symbol
%% Q
\newcommand{\vecGeneralPosition}{\ensuremath{\mathbf{q}}}% <-------- Definition
\let\OldVecGeneralPosition\vecGeneralPosition% <------- Used in glossary symbol
% 2 ************ G L O S S A R Y -- D E F I N I T I O N ********************* %
\usepackage{hyperref}
\usepackage[%
  nopostdot,%
  nonumberlist,%
  toc,%
  section,%
  acronym,%
]{glossaries}
%% H
\newglossaryentry{Hamiltonian}{% <--------- The same as in \newcommand
  type=main,%
  name={Hamiltonian function},%
  symbol={\OldHamiltonian},% <------------- "dummy" copy of command
  description={Hamiltonian function},%
}%
%% L
\newglossaryentry{Lagrangian}{% <---------- The same as in \newcommand
  type=main,%
  sort={Lagrangian},%
  name={Lagrangian function},%
  symbol={\OldLagrangian},% <-------------- "dummy" copy of command
  description={Lagrangian function},%
}%
%% P
\newglossaryentry{vecGeneralPosition}{% <-- The same as in \newcommand
  type=main,%
  sort={Pos},%
  name={position vector},%
  symbol={\OldVecGeneralPosition},% <------ "dummy" copy of command
  description={Generalised position vector},%
}%
%% Q
\newglossaryentry{vecGeneralMomentum}{% <--- The same as in \newcommand
  type=main,%
  name={momentum vector},%
  symbol={\OldVecGeneralMomentum},% <------- "dummy" copy of command
  description={Generalised momentum vector},%
}%
% ... Prettify the glossary table...
\newglossarystyle{mylong2col}{%
  % put glossary in a longtable
  \renewenvironment{theglossary}%
    {%
     \setlength\LTleft{0pt}
     \setlength\LTright{0pt}
     \begin{longtable}[l]{@{\extracolsep{\fill}}l|p{\glsdescwidth}@{}}%
    }%
    {\end{longtable}}%
  % Set the table header
   \renewcommand*{\glossaryheader}{%
    \bfseries Symbol &%
    \bfseries Description
    \\ \hline \endhead}%
   \renewcommand*{\glsgroupheading}[1]{}%
   \renewcommand*{\glossentry}[1]{%
      \glsentryitem{##1}%                              Entry number if required
      \glstarget{##1}{\glossentrysymbol{##1}}%                           Symbol
        & \glossentrydesc{##1}% Description
        \tabularnewline % end of row
   }%
  \renewcommand*{\glsgroupskip}{}%
}
%
\makeglossaries
\makeindex
%
% 3 ************ R E D E F I N E  --  D E F I N I T I O N S ****************** %
%% H
%\renewcommand{\Hamiltonian}{\glssymbol{Hamiltonian}\index{\glsentryfirst{Hamiltonian}}}
%% L
%\renewcommand{\Lagrangian}{\glssymbol{Lagrangian}\index{\glsentryfirst{Lagrangian}}}
%% P
%\renewcommand{\vecGeneralMomentum}{\glssymbol{vecGeneralMomentum}\index{\glsentryfirst{vecGeneralMomentum}}}
%% Q
%\renewcommand{\vecGeneralPosition}{\glssymbol{vecGeneralPosition}\index{\glsentryfirst{vecGeneralPosition}}}
% ===================== B E G I N   D O C U M E N T  ======================== %
\begin{document}
%
% ----------------------- F R O N T - M A T T E R --------------------------- %
\frontmatter
%
\maketitle
%
\printglossary[style=mylong2col]
%
% ------------------------ M A I N - M A T T E R ---------------------------- %
%
\mainmatter

\def\oldSymbol{}
\newcommand{\redefinethestuff}[1]{%
   \expandafter\renewcommand\csname#1\endcsname{\glssymbol{#1}\index{\glsentryfirst{#1}}}
}
\forallglsentries[main]{\oldSymbol}{%
  \expandafter\redefinethestuff\expandafter{\oldSymbol}%
}%

\chapter{Classical Mechanics}
\[
  \Hamiltonian := \mathrm{d}\left(\vecGeneralPosition \vecGeneralMomentum \right) - \Lagrangian
\]
% -------------------------- A P P E N D I X -------------------------------- %
\appendix
%
% ------------------------- B A C K - M A T T E R --------------------------- %
\backmatter
\printindex
%
\end{document}

Please don't use $$...$$ but \[ ... \] instead!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.