如何在 LaTeX 中创建枚举值?

如何在 LaTeX 中创建枚举值?

我想创建一个meta.tex文件,模板用户将在其中填写一些常用值。我想让他在一些预定义的值中进行选择:

%meta.tex
\title{Something Fun}
\author{John Doe}

% Uncomment ONE item
\department{Foo}
%\department{Bar}
%\department{Foobar}

最好这样做:

\departments{FOO=Foo, BAR=Bar, FOOBAR=Foobar}
\department{FOO}

在 LaTeX 中实现此目的的最佳方法是什么?

在 Google 上搜索LaTeX enum似乎不是一个明智的建议 :(

答案1

设置枚举类结构的一种相当简单的方法是通过名称包含“枚举 ID”的辅助宏。因此,如果您想让用户在 、FOOBAR之间进行选择FOOBAR,您可以定义三个内部辅助宏\nowox@enum@FOO\nowox@enum@BAR\nowox@enum@FOOBAR。当用户选择一个枚举值时,您可以检查内部宏\nowox@enum@<user input>是否已定义,如果已定义,则使用它(其中“使用”实际上可能意味着非常不同的事情),如果没有,则抛出错误,表明选择了无效的枚举值。

就实际使用或处理用户输入的方式和时间而言,这种方法相当灵活。在下面的示例中,每个枚举 ID 都有一个可打印的输出。用户选择的枚举的可打印输出存储在(带有\let)通用辅助宏中。然后可以使用通用辅助宏进行排版。但完全可以考虑选择的不同用途。例如,您可以在每个枚举辅助宏中存储可执行代码,并在选择枚举时执行该代码。

该包etoolbox用于提供命令,以\csdef使事情变得更容易,并避免大量的\expandafters (\csname 和 \endcsname 到底起什么作用?何时使用 \edef、\noexpand 和 \expandafter?)。

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}

\usepackage{etoolbox}

\makeatletter
% internal name for user selection
% can be given a default value
% or generate an error if not set
\newcommand*{\nowox@dep}{%
  \PackageError{nowox}
    {No department set}
    {Choose a valid department\MessageBreak
     with \string\department}}

% helper macro to typeset user-selected dep
\newcommand*{\typesetmydep}{%
  \nowox@dep}

% create new enum values
% {<id>}{<value>}
\newcommand*{\mkdepartment}[1]{%
  \csdef{nowox@dep@#1}}

% user command to select department from
% valid enum values
\newcommand*{\department}[1]{%
  \ifcsundef{nowox@dep@#1}
    {\PackageError{nowox}
       {Department '#1' undefined}
       {Choose a valid department}}
    {\letcs\nowox@dep{nowox@dep@#1}}}
\makeatother

\mkdepartment{foo}{Dep.~of~Foo}
\mkdepartment{bar}{Dep.~of~Bar}
\department{foo}

\begin{document}
\typesetmydep

Lorem
\end{document}

答案2

如果根据“部门”而变化的只是一些文本短语:

使用最新的 LaTeX-distro,您可以通过 expl3/xparse 维护每个部门的属性列表:

\documentclass{article}

%=========================================================================================
\RequirePackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\Departments {m} {
  \keyval_parse:NNn \__MYPREAMBLECODE_prop_const_from_keyval:n \__MYPREAMBLECODE_prop_const_from_keyval:nn {#1}
}
\NewDocumentCommand\Department {m} {
  \prop_if_exist:cF {\MYPREAMBLECODE_DepartmentPropertiesPrefix: #1}
                    {  % An error about unknown Department/unknown property list:
                       \msg_error:nnx {MYPREAMBLECODE} {UndefinedDepartment} {#1}
                    }
  \cs_gset:Npx \__MYPREAMBLECODE_SelectedDepartment: {\MYPREAMBLECODE_DepartmentPropertiesPrefix: #1}
}
\msg_new:nnnn {MYPREAMBLECODE} 
              {UndefinedDepartment}
              {\token_to_str:N\Department:\ No\ properties\ defined\ for\ Department\ `\tl_to_str:n{#1}'\ \msg_line_context: .} 
              {Use\ the\ command\ \token_to_str:N\Departments\ for\ specifying\ properties\ of\ Departments.  }
\prop_gput:Nnn \g_msg_module_type_prop { MYPREAMBLECODE } {}
\prop_gput:Nnn \g_msg_module_name_prop { MYPREAMBLECODE } {Preamble-Code}

\NewDocumentCommand\GetSelectedDepartmentsPropertyValue{mm}{
  % #1 = property
  % #2 = tokens in case property is not defined
  %      Reasons could be: 
  %        1. property is not defined for the selected department. 
  %        2. selected department is not defined.
  %        3. \Departments or \Department was not called.
  %      Could be a warning/error-message and/or some
  %      default-value.
  \prop_if_exist:cTF \__MYPREAMBLECODE_SelectedDepartment: {
    \prop_if_in:cnTF \__MYPREAMBLECODE_SelectedDepartment: 
                     {#1}
                     {  \prop_item:cn \__MYPREAMBLECODE_SelectedDepartment: {#1}   }
  }{\use:n}{#2}
}
\cs_new:Nn \__MYPREAMBLECODE_prop_const_from_keyval:n {
  \__MYPREAMBLECODE_prop_const_from_keyval:nn {#1}{}
}
\cs_new:Nn \__MYPREAMBLECODE_prop_const_from_keyval:nn {
  \prop_const_from_keyval:cn {\MYPREAMBLECODE_DepartmentPropertiesPrefix: #1} {#2}
}
\cs_new:Nn  \__MYPREAMBLECODE_SelectedDepartment: {}
\cs_new:Nn  \MYPREAMBLECODE_DepartmentPropertiesPrefix: {Department:}
\ExplSyntaxOff
%=========================================================================================

\Departments{
  FOO={
           Property1=FOO---Property1's value, 
           Property2=FOO---Property2's value, 
           Property3=FOO---Property3's value
      }, 
  BAR={
           Property1=BAR---Property1's value, 
           Property2=BAR---Property2's value, 
           Property3=BAR---Property3's value
      }, 
  FOOBAR={
           Property1=FOOBAR---Property1's value, 
           Property2=FOOBAR---Property2's value,
           Property3=FOOBAR---Property3's value
          },
  \empty={
           Property1=[Nameless Department]---Property1's value, 
           Property2=[Nameless Department]---Property2's value,
           Property3=[Nameless Department]---Property3's value
          },
}


\Department{FOO}
%\Department{BAR}
%\Department{FOOBAR}
%\Department{}
%\Department{FOOL}

\begin{document}

\GetSelectedDepartmentsPropertyValue{Property1}{\textsf{??}}

\GetSelectedDepartmentsPropertyValue{Property2}{\textsf{??}}

\GetSelectedDepartmentsPropertyValue{Property3}{\textsf{??}}

\GetSelectedDepartmentsPropertyValue{Property4}{\textsf{??}} % Property 4 is undefined with the selected department, therefore: ??

\end{document}

(使用\Department{FOO}相应\Department{BAR}\Department{FOOBAR}命令\GetSelectedDepartmentsPropertyValue将产生为这些部门定​​义的短语。
使用\Department{}\Department{\empty}命令\GetSelectedDepartmentsPropertyValue将产生为无名部门定义的短语。
使用原因 2 的\Department{FOOL}命令总是产生\GetSelectedDepartmentsPropertyValue⟨如果属性未定义,则使用 token⟩

相关内容