两种“旁路解决方案”。

两种“旁路解决方案”。

我有词汇表条目字段(如name、、text字段symbol),由另一个词汇表条目定义,如下所示(该compressor_motor条目由该条目定义compressor):

\newglossaryentry{compressor_motor}
{
    name={\glsname{compressor} Motor},
    sort={compressor motor},
    text={\gls{compressor} motor},
    description={Motor of the \glsname{compressor}},
    symbol={\glssymbol{compressor}m},
    parent=compressor
}

我很高兴有(写给圣诞老人的信;):

  • \Gls\GLS和命令与条目一起使用(目前不起作用,请参阅下面的 MWE)\Glssymbol\GLSsymbolcompressor_motor
  • \Gls可以将首字母大写的命令每个单词,而不仅仅是第一个单词(与提议的行为相同karlkoeller 回答可以在每个单词前加上一个‘~’字符,以防止‘字母’单词大写,正如 Nicholas Hamilton 在评论中指出的那样karlkoeller 回答(英文):
  • 与 Beamer 兼容文章文档类;

这里是 MWE:

\documentclass{article}
\usepackage[style=tree]{glossaries-extra}

\usepackage{verbatim}

\makenoidxglossaries

\newglossaryentry{subsytem}{name={Subssytems},description={\glspar},sort={1}}   
\newglossaryentry{compressor}
{
    name={Compressor},
    text={compressor},
    sort={compressor},
    description={Air Compressor},
    symbol={cp},
    parent=subsytem
}
\newglossaryentry{ejector}
{
    name={Ejector},
    text={ejector},
    sort={Ejector},
    description={Air Ejector},
    symbol={ej},
    parent=subsytem
}

\newglossaryentry{compressor_motor}
{
    name={\glsname{compressor} Motor},
    sort={compressor motor},
    text={\gls{compressor} motor},
    description={Motor of the \glsname{compressor}},
    symbol={\glssymbol{compressor}m},
    parent=compressor
}

\newglossaryentry{compressor_ejector}
{
    name={\glsname{compressor}~and \glsname{ejector}},
    sort={compressor and ejector},
    text={\gls{compressor}~and \gls{ejector}},
    description={Air \glsname{compressor} and \glsname{ejector}},
    symbol={\glssymbol{compressor}\glssymbol{ejector}},
    parent=subsytem
}


\begin{document}

    \gls{compressor};
    \gls{compressor_motor};
    \gls{compressor_ejector};
    
    \bigskip
    
    % This is not working: 
    %\verb!\Gls{compressor_motor}: !\Gls{compressor_motor};
    
    %\verb!\GLS{compressor_motor}: !\GLS{compressor_motor};
    
    %\verb!\Gls{compressor_ejector}: !\Gls{compressor_ejector};
    
    %\verb!\GLS{compressor_ejector}: !\GLS{compressor_ejector};
    
    %\verb!\Glssymbol{compressor_motor}: !\Glssymbol{compressor_motor};
    
    %\verb!\GLSsymbol{compressor_motor}: !\GLSsymbol{compressor_motor};


    \printnoidxglossary
\end{document}

所以,我想要这样的结果:

在此处输入图片描述


为什么我用另一个 gls 条目定义 gls 条目

因为我有很多条目(十个)依赖于另一个条目,如果我只是决定改变单词,我不想改变很多东西压缩机经过压缩机(例如法语)。因此,我想用这个词来定义所有条目压缩机通过使用\gls{compressor}命令...

答案1

这里给出这个答案是为了不让这个问题没有几乎“有效”的答案,如果有人(很有可能)碰到这个解决方案并希望(奇怪的是)使用它。
因此,如果有人能提出更“基于 LaTeX”且更强大的解决方案(无需使用外部工具),那就太好了!

两种“旁路解决方案”。

这两种方法的理念是相同的:创建一个新glossary_entriesPostTreated.txt文件,用于定义词汇表条目,但所有\gls类似的命令都已“扩展”。

可以使用此新文件代替原始文件(glossary_entries.tex),并且条目将毫无问题地大写。

  • 第一种方法需要make4ht一个用于html文本转换的工具(如html2text)。
  • 第二种方法直接写入文本文件(无需外部工具),但使用“低级”宏将某些\gls类似命令的“输出”写入文件(感谢Marijn 的回答)。

先决条件:

  • 所有词汇表条目定义都必须存储在文本文件中(.tex.bib等)。
    • 换行符必须在每个之后都存在,\newglossaryentry没有注释“ %”。所以这是好的
\newglossaryentry{subsystem}
{% A new line is needed after each \newglossaryentry key !!!
name={Subssytems},description={},sort={1}}

不是{subsystem}这个(在第一个 之后和之前插入一个字符{):

\newglossaryentry{subsystem}% A comment here
{% A new line is needed after each \newglossaryentry key !!!
name={Subssytems},description={},sort={1}}

或者不是{subsystem}这样(在第一个 之后和之前没有插入换行符{):

\newglossaryentry{subsystem}{% No newline here just after {subsystem}
{%
name={Subssytems},description={},sort={1}}
  • 需要 3 个包: listofitems(提取输入字段,感谢Steven B. Segletes 回答), tikz(有一个很好的 for 循环),catchfile(提取包含条目定义的文本文件的内容,感谢给出答案)。

  • 第一种方法需要make4ht一个用于html文本转换的工具(如html2text)。

1. 第一种方法(使用make4hthtml2text

MWE.tex(见下文解释):

\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}

文件内容glossary_entries.tex

\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}
}

构建方式:

$ make4ht -l MWE.tex
$ html2text -style pretty MWE.html > glossary_entries_PostTreated.txt

解释:

  • 代码的目标是使用与以下类似的方法打印所有词汇表条目的所有字段这个答案,以下称为“\printallglossaryfields答案”。

  • 基本上,代码使用命令将词汇表条目字段拆分\readlistlistofitems逗号分隔的列表(参见\printallglossaryfields回答更多细节)。

  • 为了打印字段周围的花括号(在符号之后=),该\readlist命令用于使用符号作为列表分隔符将字段键名称(例如sort)与字段标签(例如compressor)分开=(此功能在原始代码中不存在\printallglossaryfields回答)。

  • 下划线定义为\catcode'_=12便于打印(需要使用 make4ht 进行 LuaLaTeX 编译,请参阅michal.h21 回答)。

限制和可能的改进(与\printallglossaryfields回答):

  • 由于每个键后面都需要换行符\newglossaryentry且没有注释“ %”,因此不够强大(因为代码会检测每个键后面的空格,以便将键与键后列出的字段分开)。
  • tikz也许catchfile可以避免使用包裹。
  • 需要一个外部工具进行html文本转换(例如html2text

奖金 :

2. 第二种方法(仅使用 LaTeX)

MWE(见下文解释):

\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}

解释:

  • 基本与以下代码目标相同方法 1但这里的条目也直接打印到文本文件中(glossary_entries_PostTreated.txt)。

  • 一些\gls类似的命令被它们各自的“低级”宏重新定义,以便与\write命令一起使用(很好地扩展到文本文件)(感谢Marijn 的回答

  • 为了打印到文件中,对花括号进行了重新定义(参见给出答案)。

  • 重新定义百分比字符,以便打印到文件中(参见约瑟夫赖特答案)。

局限性和可能的​​改进:

  • 与...一样方法 1
  • 使用未记录和不支持的“低级”宏\glo@..@name(代码可能会在任何更新中中断,正如 David Carlisle 在评论中指出的那样这个问题)。
  • \gls这里只能使用少数类似的命令( \gls=\glstext \glsname \glssymbol)。
  • 不适用于用户创建的新自定义字段。

奖金:

  • 不需要像make4ht或 那样的外部工具html2text

两种方法的结果(glossary_entriesPostTreated.txt文件内容):

在此处输入图片描述

相关内容