存在保护问题的符号表

存在保护问题的符号表

我想创建一个在 LaTeX 中易于阅读的符号表,因此如下所示:

\begin{tabular}{*4M}
     <    & \le     & \ll   & \lll    \\
     >    & \ge     & \gg   & \ggg    \\
     \ne  & \approx & \prec & \preceq \\
     \sim & \simeq  & \succ & \succeq \\
\end{tabular}

并且在 TeXed 时生成符号和命令序列,因此类似于:

在此处输入图片描述

下面的代码几乎实现了我想要的功能,除了如上所示,\ne还有不必要的保护。有没有直接解决这个问题的方法?我试过:

  • 使用\detokenize(见下文)
  • 使用\string(无法编译)
  • 使用\cs_to_str:N来自LaTeX3
  • 使用幻想VRB

有人有更好的建议吗?

以下是产生上述输出的代码:

\documentclass{amsart}
\usepackage[T1]{fontenc}
\usepackage{mathtools}

\usepackage{amssymb}% load the AMS symbols
\usepackage[verb]{collcell}
\newcommand\showSymbol[1]{\hbox to 8em{\texttt{\detokenize{#1}}}$#1$}
\usepackage{array}
\newcolumntype{M}{>{\collectcell\showSymbol}l<{\endcollectcell}}

\begin{document}

  \begin{tabular}{*4M}
       <    & \le     & \ll   & \lll    \\
       >    & \ge     & \gg   & \ggg    \\
       \ne  & \approx & \prec & \preceq \\
       \sim & \simeq  & \succ & \succeq \\
  \end{tabular}

\end{document}

答案1

问题在于,在表格单元格的开始处,TeX 正在扩展标记以寻找\omit\span(对于\multicolumn和之类的),因此它扩展\ne\protect\ne␣,并且\protect\relax(不可扩展的因此)保持不变,然后才使用插入表格模板\collectcell\showSymbol,但此时\ne已经扩展。

有几种方法可以解决这个问题,但归结起来无非是以下两种:

  1. 查看扩展的\ne(或任何命令)并检查第一个标记是否是\protect,如果是,则排版第二个标记,或者

  2. 添加一些内容来阻止 TeX 扩展\ne

对于选项 1,您可以\showSymbol像这样定义(下面的 MWE 1):

\makeatletter
\newcommand\showSymbol[1]{%
  \expandafter\ifx\@car#1\@nil\protect\@empty
    \expandafter\@showSymbol\expandafter{\@cdr#1\@nil}%
  \else
    \@showSymbol{#1}%
  \fi}
\newcommand\@showSymbol[1]{%
  \hbox to 8em{\texttt{\detokenize{#1}}\hss}$#1$}
\makeatother

该行将\expandafter\ifx\@car#1\@nil\protect\@empty比较\ifx的第一个标记#1\protect\@empty出于安全考虑,存在 ),如果是,则将其余标记传递给\@showSymbol。请注意,这将传递\ne␣而不是\ne进行排版,因此您可能需要修剪尾随空格。

对于选项 2(下面的 MWE 2),快捷又粗略,您可以添加前缀\ne\noexpand当 TeX 扩展 时\noexpand,它将暂时执行\let\ne\relax,然后新定义的\ne将停止扩展(并将\ne恢复为其原始含义)。然后,当\collectcell它完成工作时,\ne将在那里,安全无虞:

\begin{tabular}{*4M}
  \noexpand\ne & \approx & \prec & \preceq \\
  <            & \le     & \ll   & \lll    \\
  >            & \ge     & \gg   & \ggg    \\
  \sim         & \simeq  & \succ & \succeq \\
\end{tabular}

最大能量损失 1:

\documentclass{amsart}
\usepackage[T1]{fontenc}
\usepackage{mathtools}

\usepackage{amssymb}% load the AMS symbols
\usepackage[verb]{collcell}

\makeatletter
\newcommand\showSymbol[1]{%
  \expandafter\ifx\@car#1\@nil\protect\@empty
    \expandafter\@showSymbol\expandafter{\@cdr#1\@nil}%
  \else
    \@showSymbol{#1}%
  \fi}
\newcommand\@showSymbol[1]{%
  \hbox to 8em{\texttt{\detokenize{#1}}\hss}$#1$}
\makeatother

\usepackage{array}
\newcolumntype{M}{>{\collectcell\showSymbol}l<{\endcollectcell}}

\begin{document}

\begin{tabular}{*4M}
  \ne  & \approx & \prec & \preceq \\
  <    & \le     & \ll   & \lll    \\
  >    & \ge     & \gg   & \ggg    \\
  \sim & \simeq  & \succ & \succeq \\
\end{tabular}

\end{document}

最大能量损失 2:

\documentclass{amsart}
\usepackage[T1]{fontenc}
\usepackage{mathtools}

\usepackage{amssymb}% load the AMS symbols
\usepackage[verb]{collcell}
\newcommand\showSymbol[1]{\hbox to 8em{\texttt{\detokenize{#1}}\hss}$#1$}
\usepackage{array}
\newcolumntype{M}{>{\collectcell\showSymbol}l<{\endcollectcell}}

\begin{document}

\begin{tabular}{*4M}
  \noexpand\ne & \approx & \prec & \preceq \\
  <            & \le     & \ll   & \lll    \\
  >            & \ge     & \gg   & \ggg    \\
  \sim         & \simeq  & \succ & \succeq \\
\end{tabular}

\end{document}

答案2

我会使用一种不同的方法,即只列出我们想要制作表格的符号,然后让 TeX 进行拆分。

尾随的可选参数(默认为 4)表示列对的数量;第一个可选参数表示标题。

\documentclass{article}
\usepackage{amsmath,amssymb,booktabs}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\symboltable}{O{}mO{4}}
 {
  \andrew_symboltable:nnn { #1 } { #2 } { #3 }
 }

\tl_new:N \l__andrew_symboltable_tl
\seq_new:N \l__andrew_symboltable_seq

\cs_new_protected:Nn \andrew_symboltable:nnn
 {
  \group_begin:
  \setlength{\tabcolsep}{1pc}
  \seq_set_from_clist:Nn \l__andrew_symboltable_seq { #2 }
  \tl_if_blank:nTF { #1 }
   {
    \tl_clear:N \l__andrew_symboltable_tl
   }
   {
    \tl_set:Nn \l__andrew_symboltable_tl
     {
      \multicolumn{\int_eval:n { 2*(#3) } } { @{}c@{} } { #1 } \\ \midrule
     }
   }
  \seq_map_indexed_inline:Nn \l__andrew_symboltable_seq
   {
    \tl_put_right:Nn \l__andrew_symboltable_tl
     {
      \texttt{ \token_to_str:N ##2 } & $##2$
     }
    \int_compare:nTF { \int_mod:nn { ##1 } { #3 } = 0 }
     {
      \tl_put_right:Nn \l__andrew_symboltable_tl { \\ }
     }
     {
      \tl_put_right:Nn \l__andrew_symboltable_tl { & }
     }
   }
   \int_compare:nF { \int_mod:nn { \seq_count:N \l__andrew_symboltable_seq } { #3 } = 0 }
    {
     \tl_put_right:Nn \l__andrew_symboltable_tl { \\ }
    }
  \begin{tabular}{ @{} *{ #3 }{ l@{\hspace{6pt}}l } @{} }
  \toprule
  \tl_use:N \l__andrew_symboltable_tl
  \bottomrule
  \end{tabular}
  \group_end:
 }

\ExplSyntaxOff

\begin{document}

\begin{center}
\symboltable{
  <,\le,\ll,\lll,>,\ge,\gg,\ggg,\ne,\approx,
  \prec,\preceq,\sim,\simeq,\succ,\succeq
}

\bigskip

\symboltable[Relation symbols]{
  <,\le,\ll,\lll,>,\ge,\gg,\ggg,\ne,\approx,
  \prec,\preceq,\sim,\simeq,\succ,\succeq
}[5]
\end{center}

\end{document}

在此处输入图片描述

相关内容