设置 Latex 的宏

设置 Latex 的宏

我想定义一个宏来轻松编写集合。例如:

\set{ 1, 2, 3, 4, 5 }

然后变成类似

\{ 1,\ 2,\ 3,\ 4,\ 5\, \}  % this
\begin{Bmatrix}\, 1,\, 2,\, 3 ,\, 4,\, 5\, \end{Bmatrix}   % or this

此外我还需要:

  • 可以改变括号:例如 \set[p]{ 1, 2, 3 }
  • 可以改变分隔符:例如用空格替换逗号
  • 段落对齐时允许每个逗号后自动换行

目前我改编了我在这里找到的东西: 更改在 Latex 中输入矩阵的方式,结果得到了以下代码(针对宏\tset):

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\tset}{ O{B} m }
 {
  \strategy_tset:nn { #1 } { #2 }
 }

\seq_new:N \l_strategy_rows_seq
\seq_new:N \l_strategy_a_row_seq
\tl_new:N \l_strategy_matrix_tl

\cs_new_protected:Npn \strategy_tset:nn #1 #2
 {
  \tl_clear:N \l_strategy_matrix_tl
  \seq_set_split:Nnn \l_strategy_rows_seq { ; } { #2 }
  \seq_map_inline:Nn \l_strategy_rows_seq
   {
    \seq_set_split:Nnn \l_strategy_a_row_seq { , } { ##1 }
    \tl_put_right:Nx \l_strategy_matrix_tl { \seq_use:Nn \l_strategy_a_row_seq { , } }
   }
  \begin{#1matrix}
  \, \tl_use:N \l_strategy_matrix_tl \,
  \end{#1matrix}
 }
\ExplSyntaxOff

我认为这不太好。特别是换行功能不起作用。

答案1

以下是用于确定分隔符和定界符的基于键值的代码。换行符只能在第二项之后和倒数第二项之前使用。

\documentclass[twocolumn]{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\tset}{O{}m}
 {
  \strategy_tset_main:nn { #1 } { #2 }
 }

\seq_new:N \l__strategy_tset_items_seq
\str_new:N \l__strategy_tset_delim_str
\tl_new:N \l__strategy_tset_sep_tl
\tl_new:N \l__strategy_tset_last_tl

\keys_define:nn { strategy/tset }
 {
  B .code:n = \str_set:Nn \l__strategy_tset_delim_str { B },
  p .code:n = \str_set:Nn \l__strategy_tset_delim_str { p },
  b .code:n = \str_set:Nn \l__strategy_tset_delim_str { b },
  comma .code:n = \tl_set:Nn \l__strategy_tset_sep_tl { , },
  space .code:n = \tl_set:Nn \l__strategy_tset_sep_tl { \ },
 }

\cs_new_protected:Nn \strategy_tset_main:nn
 {
  \group_begin:
  \keys_set:nn { strategy/tset } { B, comma, #1 }
  % left delimiter
  \str_case:Vn \l__strategy_tset_delim_str
   {
    {B}{\{}
    {p}{(}
    {b}{[}
   }
  % items with separators
  \tl_if_blank:nF { #2 }
   {
    \seq_set_from_clist:Nn \l__strategy_tset_items_seq { #2 }
    \seq_pop_right:NN \l__strategy_tset_items_seq \l__strategy_tset_last_tl
    \seq_map_indexed_inline:Nn \l__strategy_tset_items_seq
     {
      ##2 % the item
      \tl_use:N \l__strategy_tset_sep_tl % the separator
       % add \linebreak[0] only after the second and before the last but one item
      \int_compare:nT { 1 < ##1 < \seq_count:N \l__strategy_tset_items_seq }
       {
        \linebreak[0]
       }
     }
    \tl_use:N \l__strategy_tset_last_tl % the last item
   }
   % right delimiter
  \str_case:Vn \l__strategy_tset_delim_str
   {
    {B}{\}}
    {p}{)}
    {b}{]}
   }
  \group_end:
 }

\ExplSyntaxOff

\begin{document}

$\tset{1,2,3,4}$

$\tset[space,b]{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}$

Some words words ww $\tset[space,b]{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}$

Some words words words $\tset[space,b]{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}$

Some words ww $\tset[p]{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}$

Some words words words words words www $\tset[comma,p]{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}$

$\tset{}$

$
\tset[p]{
  1,
  \tset[b]{
    2,
    3,
    \tset[{B,space}]{
      a,
      b,
      c
    },
    4
  },
  5
}
$

\end{document}

在此处输入图片描述

我不会增加逗号后的空格;如果你真的想要,可以使用类似

  comma .code:n = \tl_set:Nn \l__strategy_tset_sep_tl { ,\; },

如您所见,嵌套是可以的,但如果嵌套中需要更多选项\tset,则需要将它们括在括号中,如上一个示例所示。

检查参数是否为空,在这种情况下只打印分隔符。

答案2

在此处输入图片描述

这只是用来clist映射逗号列表,然后用撤消最后的“逗号”间距\unskip

\documentclass{article}

\usepackage{amsmath}

\ExplSyntaxOn
\newcommand\set[2][\{]{
#1
\clist_map_inline:nn{#2}{##1\nolinebreak[2]\;}
\unskip\unpenalty
\ifx\{#1\}\else
\ifx(#1)\else
?\fi\fi}
\ExplSyntaxOff


\begin{document}

$\set{1,2,3}$  $\set[(]{1,2,3}$ 

some test text some test text some test text 
$\set{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}$

\end{document}

相关内容