This answer is here in order to not let this question without an almost "working" answer, if someone (by the greatest of chance) comes across this solution and wishes (strangely) to use it.
So, if someone comes with a more "LaTeX based" and robust solution (without using external tools) it would be great!
Two "bypass-solutions".
With both methods, the idea is the same: create a new glossary_entriesPostTreated.txt
file used to define glossary entries but with all \gls
like commands already "expanded".
This new file can be used instead of the original one (glossary_entries.tex
) and the entries will capitalized without problem.
- The first method needs
make4ht
and a tool for html
to text conversion (as html2text
).
- The second method write directly to a text file (without an external tool) but use "low level" macros for writing the "output" of some
\gls
like commands to the file (thanks to Marijn's answer).
Prerequisite:
- All glossary entries definitions must be stored into a text file (
.tex
, .bib
, etc.).
- A newline MUST be present after each
\newglossaryentry
with no comments "%
". So this is Ok:
\newglossaryentry{subsystem}
{% A new line is needed after each \newglossaryentry key !!!
name={Subssytems},description={},sort={1}}
But NOT this (a character is inserted just after {subsystem}
and just before the first {
):
\newglossaryentry{subsystem}% A comment here
{% A new line is needed after each \newglossaryentry key !!!
name={Subssytems},description={},sort={1}}
or also NOT this (no newline inserted just after {subsystem}
and just before the first {
):
\newglossaryentry{subsystem}{% No newline here just after {subsystem}
{%
name={Subssytems},description={},sort={1}}
Needs 3 packages: listofitems
(to extract the entry fields, thanks to Steven B. Segletes answer), tikz
(to have a nice for loop), catchfile
(to extract the content of the text file containing the entries definitions, thanks to egreg answer).
The first method needs make4ht
and a tool for html
to text conversion (as html2text
).
1. First Method (with make4ht
and html2text
)
MWE.tex (see explanations below):
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{listofitems}
\usepackage{tikz}% To make a nice for loop
\usepackage{catchfile}% To read the glossary entries file
\usepackage[style=tree]{glossaries-extra}
\input{glossary_entries.tex}
% For a good print of underscore
\catcode`_=12
\begin{document}
\IfFileExists{glossary_entries.tex}%
{\CatchFileEdef{\glsEntriesListString}{glossary_entries.tex}{\endlinechar=13}}%
\glsEntriesListString % This call is needed to a good behaviour of \readlist
\noindent
\ignoreemptyitems % Ingnore empty items from le list
\setsepchar{\newglossaryentry|| /,}% Define separator for nested list with e.g. first list separator "\newglossaryentry" or " " (space) and second list separator "," (comma)
\readlist\myglsentrylist{\glsEntriesListString}% Extract the list from glossary entriesc
\setsepchar{,}% Define separator for the list inside a glossary entry (in order to extract fields)
\foreach \i in {1,2,...,\myglsentrylistlen}{%Loop under the glossary entry list
\ifodd\i% If odd, print the list element
\itemtomacro\myglsentrylist[\i]\myglsentrylisttowrite
\textbackslash{}newglossaryentry\{\myglsentrylisttowrite\}\{\%\newline
\else % If even, make another list with the fields after removing curly braces "{}" surronding the fields
\itemtomacro\myglsentrylist[\i]\myfieldslisttemp \expandafter\def\expandafter\myfieldslisttemp\myfieldslisttemp % Removing curly braces "{}"
\setsepchar{,}% Define separator for the list inside a glossary entry (in order to extract fields)
\readlist*\myfieldslist{\myfieldslisttemp}% Ignore extreme spaces
\foreach \j in {1,2,...,\myfieldslistlen}{%Loop under the glossary entry list
\itemtomacro\myfieldslist[\j]\myfieldskeylisttemp
\setsepchar{=}% Define separator for the list inside a glossary entry (in order to extract fields)
\readlist\myfieldskeylist{\myfieldskeylisttemp}%
\itemtomacro\myfieldskeylist[1]\myfieldskeylistONEtowrite
\indent\myfieldskeylist[1]=\{%First item = field key name
\itemtomacro\myfieldskeylist[2]\myfieldskeylistTWOtowrite
\ifnum \j=\myfieldslistlen % Last field with NO comma at the end
\myfieldskeylist[2]\}\newline\}\%\newline
\else
\myfieldskeylist[2]\},\newline
\fi
}%
\fi
}%
\end{document}
Contents of glossary_entries.tex
file:
\newglossaryentry{subsystem}
{% A new line is needed after each \newglossaryentry key !!!
name={Subssytems},description={},sort={1}}
\newglossaryentry{compressor}
{% A new line is needed after each \newglossaryentry key !!!
name={Compressor},
sort={compressor},
text={compressor},
description={Compressor},
symbol={Cp},
parent={subsystem}
}
\newglossaryentry{compressor_motor}
{% A new line is needed after each \newglossaryentry key !!!
name={\glsname{compressor} Motor},
text={\gls{compressor} motor},
description={Motor of the \gls{compressor}},
symbol={\glssymbol{compressor}m},
parent={compressor}
}
\newglossaryentry{ejector}
{% A new line is needed after each \newglossaryentry key !!!
name={Ejector},
text={Ejector},
description={Air Ejector},
symbol={ej},
parent={subsystem}
}
Build with:
$ make4ht -l MWE.tex
$ html2text -style pretty MWE.html > glossary_entries_PostTreated.txt
Explanations:
The goal of the code is to print all the fields of all glossary entries using a similar method as the one used in this answer, called hereafter as the "\printallglossaryfields
answer".
Basically the code split the glossary entries fields with the \readlist
command of the listofitems
by considering them as a comma separated list (see \printallglossaryfields
answer for more details).
In order to print the curly braces around the fields (after the =
symbol), the \readlist
command is used to split the field key name (e.g. sort
) from the field label (e.g. compressor
) using =
symbol as list separator (this feature was not present in the orignal code in the \printallglossaryfields
answer).
Underscore is defined with \catcode'_=12
in order to be printed easily (need LuaLaTeX compilation with make4ht, see michal.h21 answer).
- Not robust with the need of newline after each
\newglossaryentry
with no comments "%
" (because the code detects the space after each key in order to separate the key from the fields listed after the key).
- The use of packages
tikz
and catchfile
could probably be avoided.
- Need an external tool for
html
to text conversion (e.g. html2text
)
Bonus :
2. Second Method (with only LaTeX)
MWE (see explanations below):
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{listofitems}
\usepackage{tikz}% To make a nice for loop
\usepackage{catchfile}% To read the glossary entries file
\usepackage[style=tree]{glossaries-extra}
\newcommand{\entriesfilename}{glossary_entries}
\input{\entriesfilename.tex}
% For a good print of curly braces, percent and underscore
% Curly braces
\begingroup
\catcode`<=1 \catcode`>=2
\catcode`{=12 \catcode`}=12
\gdef\wbgroup<{>
\gdef\wegroup<}>
\endgroup
% Percent
\def\percentchar#1{}
\edef\percentchar{\expandafter\percentchar\string\%}
% Underscore
\catcode`_=12
% Redefinition of some \gls like commands by their respective "low level" macro in order to use them with \write command
\makeatletter
\renewcommand{\gls}[1]{\csname glo@#1@text\endcsname}
\renewcommand{\glsname}[1]{\csname glo@#1@name\endcsname}
\renewcommand{\glsdesc}[1]{\csname glo@#1@desc\endcsname}
\renewcommand{\glstext}[1]{\csname glo@#1@text\endcsname}
\renewcommand{\glssymbol}[1]{\csname glo@#1@symbol\endcsname}
\makeatother
\newwrite\myoutputfile
\immediate\openout\myoutputfile=\entriesfilename_PostTreated.txt
\begin{document}
\noindent
% Read the text (.tex or .bib...) file containing the glossary entries definition
\IfFileExists{\entriesfilename.tex}%
{\CatchFileEdef{\glsEntriesListString}{\entriesfilename.tex}{\endlinechar=13}}%
\glsEntriesListString% This call is needed to a good behaviour of \readlist
\ignoreemptyitems% Ingnore empty items from le list
\setsepchar{\newglossaryentry|| /,}% Define separator for nested list with e.g. first list separator "\newglossaryentry" or " " (space) and second list separator "," (comma)
\readlist\myglsentrylist{\glsEntriesListString}% Extract the list from glossary entriesc
\setsepchar{,}% Define separator for the list inside a glossary entry (in order to extract fields)
\foreach \i in {1,2,...,\myglsentrylistlen}{%Loop under the glossary entry list
\ifodd\i% If odd, print the list element
\itemtomacro\myglsentrylist[\i]\myglsentrylisttowrite
\textbackslash{}newglossaryentry\{\myglsentrylisttowrite\}\{\%\newline
\immediate\write\myoutputfile{\unexpanded{\newglossaryentry}\myglsentrylisttowrite\wbgroup\percentchar}%
\else% If even, make another list with the fields after removing curly braces "{}" surronding the fields
\itemtomacro\myglsentrylist[\i]\myfieldslisttemp \expandafter\def\expandafter\myfieldslisttemp\myfieldslisttemp % Removing curly braces "{}"
\setsepchar{,}% Define separator for the list inside a glossary entry (in order to extract fields)
\readlist*\myfieldslist{\myfieldslisttemp}% Ignore extreme spaces
\foreach \j in {1,2,...,\myfieldslistlen}{%Loop under the glossary entry list
\itemtomacro\myfieldslist[\j]\myfieldskeylisttemp
\setsepchar{=}% Define separator for the list inside a glossary entry (in order to extract fields)
\readlist\myfieldskeylist{\myfieldskeylisttemp}%
\itemtomacro\myfieldskeylist[1]\myfieldskeylistONEtowrite
\indent\myfieldskeylist[1]=\{%First item = field key name
\itemtomacro\myfieldskeylist[2]\myfieldskeylistTWOtowrite
\ifnum \j=\myfieldslistlen% Last field with NO comma at the end
\myfieldskeylist[2]\}\newline\}\%\newline
\immediate\write\myoutputfile{\myfieldskeylistONEtowrite=\myfieldskeylistTWOtowrite}%
\immediate\write\myoutputfile{\wegroup\percentchar}% closing }
\else
\myfieldskeylist[2]\},\newline
\immediate\write\myoutputfile{\myfieldskeylistONEtowrite=\myfieldskeylistTWOtowrite,}%
\fi
}%
\fi
}
\immediate\closeout\myoutputfile
\end{document}
Explanations:
Basically the same code goal as Method 1 but here the entries are also printed directly into a text file (glossary_entries_PostTreated.txt
).
Some \gls
like commands are redefine by their respective "low level" macros in order to use them with \write
command (for good expand to the text file) (thanks to Marijn's answer.
Curly braces are redefined in order to be printed to a file (see egreg answer).
Percent character is redefined in order to be printed to a file (see Joseph Wright answer)..
Limitations and possible improvements :
- Same as Method 1.
- Use non documented and non suported "low level" macros as
\glo@..@name
(the code may break on any update as pointed out by David Carlisle in comment of this question).
- Only few
\gls
like commands usable here (\gls=\glstext
\glsname
\glssymbol
).
- Doesn't Work with new custom fields created by the user.
Bonus:
- No external tool needed as
make4ht
or html2text
.
Result of both method (glossary_entriesPostTreated.txt
file content):