Open Pratched opened 3 years ago
Dealing with catcodes can be very error prone so i tried to provide a defensive solution. But as glossaries writes to an auxiliary file, the catcode changes have to be in charge when defining the symbols. So you have to use \nsymbol
after the subscript definitions (see also the last comment to #57).
\documentclass[ngerman]{tudscrartcl}
\usepackage[T1]{fontenc}
\usepackage{babel}
% ...
% at the very end of the preamble
% \usepackage{hyperref}% load late but before glossaries if necessary
\usepackage[symbols]{glossaries}
\newcommand*{\nsymbol}[5][]{%
\newglossaryentry{#2}{%
type=symbols,%
name={#3},%
description={\nopostdesc},%
symbol={\ensuremath{#4}},%
sort={#2},%
#1,%
}%
}
\defglsentryfmt[symbols]{%
\ifmmode%
\glssymbol{\glslabel}%
\else%
\glsgenentryfmt~\glsentrysymbol{\glslabel}%
\fi%
}
% definitions fur active subscripts
\makeatletter
\newcommand*\mathsub@upright[1]{\sb{\mathrm{#1}}}
\newcommand*\mathsub@italic[1]{\sb{\mathit{#1}}}
\newcommand*\mathsub@default{}
\newcommand*\mathsub@variant{}
\newcommand*\uprightsubscripts{
\let\mathsub@default\mathsub@upright%
\def\mathsub@variant(##1){\mathsub@italic{##1}}%
}
\newcommand*\italicsubscripts{%
\let\mathsub@default\mathsub@italic%
\def\mathsub@variant(##1){\mathsub@upright{##1}}%
}
\newcommand*\mathsub@choice{%
\kernel@ifnextchar(%)
{\mathsub@variant}%
{\mathsub@default}%
}
\catcode`\_=\active%
\gdef_{\relax\ifmmode\expandafter\mathsub@choice\else\textunderscore\fi}%
\AtBeginDocument{%
% ensure right catcodes
\catcode`\_=\active%
\mathcode`_="8000%
% default setting if \[upright|italic]subscripts wasn't invoked so far
\ifx\mathsub@variant\@empty\italicsubscripts\fi%
}
\makeatother
% define symbols when catcode changes are in charge
\nsymbol{ipv}{current v}{i_{pv}}{A}
\begin{document}
\uprightsubscripts
\gls{ipv}
$i_{pv}$
\end{document}
Cheers again! I needed some time to verify as to why I still having problems compiling. However, using underscores as acronym/symbol identifiers appears to be effected by these settings (they didnt with the previous one nor the original 3-line-setting). The errors says Missing \endcsname inserted.
Reproducible with the follwing
\nsymbol{i_pv}{current v}{i_{pv}}{A}
\newacronym{m_we}{MWE}{Minimal Working Example}\glsunset{m_we}
I thought Id share this in case you want to keep working on that, but I can work with omitting underscores for now and this is well above my knowledge.
You could do \newglossaryentry{\detokenize{#2}}{...}
and then define \nsymbol{i_pv}...
and use it with \gls{i\string_pv}
but that is rather uncomfortable. As the underscore is defined as active character, reckless usage of it will cause several issues. Just try to create a label \label{fig_reference}
, this will also fail.
Alternatively, you could set \catcode`_=13
but then using the underscore in text mode will neither raise an error nor provide a sufficient output as \textunderscore
would do.
Alright, I havnt really encountered issues with that so far. I tend to use them a lot at least in path directories but sometimes also as labels or to differentiate between acronyms and symbols. I was aware, that this is tricky outside of commands and options, but didnt realise that it is somewhat reckless in general. I have followed up on your first response in #57 and the solution provided there, works for now with glossaries and continued use of underscore. But I am sure youd have your reasons as to why you would use a different approach. If you want I am happy to hear as to why, but no worries if you dont want to bother. Thanks so far in any case.
Edit: sorry for the mess, got distracted.
I was aware, that this is tricky outside of commands and options, but didnt realise that it is somewhat reckless in general.
You should consider an underscore always as potential source of errors as it normally has a special meaning/catcode (8
) different from string (12
). The kernel itself as well as dozens of packages are considering this fact, but you can't say in general, that is "save" to use an underscore in arguments for commands and/or options.
In the last proposal, I did this:
\catcode`\_=\active%
\gdef_{\relax\ifmmode\expandafter\mathsub@choice\else\textunderscore\fi}%
in order to get a real underscore when writing something like a_b
in text mode. It turned out, that this is actually not needed, if \usepackage[T1]{fontenc}
is used. --- I'm still wondering, why this isn't set as default by LaTeX2e. Anyways, as this workaround isn't really needed, setting \catcode`_=\active
globally isn't needed either. So the (hopefully) final proposal supports underscores in labels as requested:
\documentclass[ngerman]{tudscrartcl}
\usepackage[T1]{fontenc}% comment out and see bar_{foo}
\usepackage{babel}
% ...
% at the very end of the preamble
%
% definitions fur active subscripts
\makeatletter
\newcommand*\mathsub@upright[1]{\sb{\mathrm{#1}}}
\newcommand*\mathsub@italic[1]{\sb{\mathit{#1}}}
\newcommand*\mathsub@default{}
\newcommand*\mathsub@variant{}
\newcommand*\uprightsubscripts{
\let\mathsub@default\mathsub@upright%
\def\mathsub@variant(##1){\mathsub@italic{##1}}%
}
\newcommand*\italicsubscripts{%
\let\mathsub@default\mathsub@italic%
\def\mathsub@variant(##1){\mathsub@upright{##1}}%
}
% default setting
\italicsubscripts
\newcommand*\mathsub@choice{%
\kernel@ifnextchar(%)
{\mathsub@variant}%
{\mathsub@default}%
}
% setting catcodes and apply the actual patch
\catcode`\_=12%
\begingroup%
\catcode`\_=\active%
% \gdef_{\relax\ifmmode\expandafter\mathsub@choice\else\textunderscore\fi}%
\gdef_{\mathsub@choice}%
\endgroup%
% ensure right catcodes
\AtBeginDocument{\catcode`\_=12\mathcode`_="8000}
\makeatother
%
\usepackage{hyperref}% load late but before glossaries if necessary
\usepackage[symbols]{glossaries}
\defglsentryfmt[symbols]{%
\ifmmode%
\glssymbol{\glslabel}%
\else%
\glsgenentryfmt~\glsentrysymbol{\glslabel}%
\fi%
}
\newcommand*{\nsymbol}[5][]{%
\newglossaryentry{#2}{%
type=symbols,%
name={#3},%
description={\nopostdesc},%
symbol={\ensuremath{#4}},%
sort={#2},%
#1,%
}%
}
\nsymbol{i_pv}{current}{i_{pv}}{A}
\begin{document}
\minisec{upright}
\uprightsubscripts
\gls{i_pv}
$i_{pv}$
\begin{figure}
\caption{$x_y$}
\label{z_up}
\end{figure}
bar_{foo}
bar_(foo)
$bar_{foo}$
$bar_(foo)$
\bigskip
$a_(b)$
$a_(bv)$
$a_b$
$x_{default}$
$x_(variant)$
\italicsubscripts
\minisec{italic}
\gls{i_pv}
$i_{pv}$
\begin{figure}
\caption{$x_y$}
\label{z_it}
\end{figure}
bar_{foo}
bar_(foo)
$bar_{foo}$
$bar_(foo)$
\bigskip
$a_(b)$
$a_(bv)$
$a_b$
$x_{default}$
$x_(variant)$
\end{document}
Note for implementation: Check catcodes with \AtBeginDocument
Havnt encountered any issues so far, so Id say its working quite fine. Even without the use of \usepackage[T1]{fontenc}
. Thans again.
Following #57 I have encountered that the solution provided there does not apply when defining symbols with the
glossaries
package. The second line math-line within the document is shown as wanted, but the upright index setting is not applied to the defined symbol. The 3-line solution shown in #57 hasnt been affected by any packages or settings I have used so far and due to my limited knowledge of latex I have played around with different line orders, but nothing changed the behaviour.