找回密码
 快速注册
搜索
查看: 2972|回复: 1

多个可选参数,中置、后置可选参数

[复制链接]

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

kuing 发表于 2016-11-17 17:22 |阅读模式
我们都知道 LaTeX 可以用 \newcommand 来定义带可选参数的命令,但可选参数最多只有一个,
下面介绍利用 LaTeX 的内部宏 \@ifnextchar 来实现多个可选参数的命令,并且可选参数的位置可以是后置或中置。
\@ifnextchar 的意思懂英文的都能猜到,又由于 \@ifnextchar 有个 @,所以以下代码须放在 \makeatletter 与 \makeatother 之间。

先从简单开始,把单可选参数的做一下,了解其基本思路。

\def\ff{%
        \@ifnextchar[{\fff}{\fff[x]}%
        }
\def\fff[#1]{f(#1)}

这样,当 \ff 后面是中括号,\ff 就变成 \fff,否则就变成 \fff[x],而 \fff[#1] 就是实际输出内容的命令。

所以,\$\ff,\ff[0]\$ 得 $f(x),f(0)$。

那么,双可选参数就在此基础上再判断一次即可,比如:

\def\bb{%
        \@ifnextchar[{\bbb}{\bbb[-\infty]}%
        }
\def\bbb[#1]{%
            \@ifnextchar[{\bbbb[#1]}{\bbbb[#1][+\infty]}%
            }
\def\bbbb[#1][#2]{(#1,#2)}

这样,\$\bb,\bb[a],\bb[a][b]\$ 得 $(-\infty,+\infty),(a,+\infty),(a,b)$。

同理可得更多可选参数的定义方法。

但是这里有个不足,那就是要想改变第二个可选参数,就必须也写上第一个可选参数的值,
也就是说要用 \bb 来输出 $(-\infty,b)$ 就只能写 \bb[-\infty][b],前者无法省略,尽管是默认值。
故此有必要改进一下,比如将 \bb 的定义改成这样:

\def\bb{%
        \@ifstar{\bbbb[-\infty]}{%
                \@ifnextchar[{\bbb}{\bbb[-\infty]}%
                }%
        }

其余不变,这样,\$\bb,\bb[a],\bb[a][b],\bb*[b]\$ 得 $(-\infty,+\infty),(a,+\infty),(a,b),(-\infty,b)$。


下面再玩玩带必要参数的情形,其实也没多大区别,而由于位置无限制,所以就能产生后置、中置的可选参数,比如:

\def\ts#1{%
        \@ifnextchar[{\ttt#1}{\ttt#1[+]}%
        }
\def\ttt#1[#2]#3{\frac{x^2}{#1^2}#2\frac{y^2}{#3^2}=1}
%
\def\TS{%
        \@ifnextchar[{\TTT}{\TTT[a^2]}%
        }
\def\TTT[#1]#2{%
        \@ifnextchar[{\TTTT[#1]#2}{\TTTT[#1]#2[b^2]}%
        }
\def\TTTT[#1]#2[#3]{\frac{x^2}{#1}#2\frac{y^2}{#3}=1}

那么 \\[ \ts34, \ts3[-]4, \TS+, \TS-, \TS[m]+, \TS[m]-[n] \\] 得
\[\frac{x^2}{3^2}+\frac{y^2}{4^2}=1,\frac{x^2}{3^2}-\frac{y^2}{4^2}=1,
\frac{x^2}{a^2}+\frac{y^2}{b^2}=1,\frac{x^2}{a^2}-\frac{y^2}{b^2}=1,
\frac{x^2}{m}+\frac{y^2}{b^2}=1,\frac{x^2}{m}-\frac{y^2}{n}=1\]

测试文档: $type [1][2][3]test.tex (863 Bytes, 下载次数: 820)

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2023-8-15 15:43
刚才在知乎见到类似问题:
zhihu.com/question/617362905/answer/3166462074
  1. LaTeX如何定义有两个参数的证明环境(具体看问题描述)?
  2. 我想定义一个proof环境, 它带有两个参数, 我希望能实现下面的效果:
  3. \begin{proof} 就显示"证明"
  4. \begin{proof}[定理1.1的证明] 就显示"定理1.1的证明"
  5. \begin{proof}[][XXX] 就显示"证明 (XXX)"
  6. 我试过使用\ifblank如下
  7. \renewenvironment{proof}[2][][]
  8. {\addvspace{1em} \noindent \textbf{\ifblank{#1}{证明}{#1} \ifblank{#2}{}{\ (#2)}} \hspace{0.5em} }
  9. {\hfill $\blacksquare$ \par \ignorespacesafterend \addvspace{1em}}
  10. 但是这样会报错, 报错信息为You can't use `macro parameter character #' in horizontal mode. ...fblank{#1}{证明}{#1} \ifblank{#2}{}{\ (#2)}}
复制代码


我用类似 1 楼的方式,用 \@ifstar 和 \@ifnextchar 给出如下方法:
  1. \documentclass[UTF8]{ctexart}
  2. \usepackage{amsmath}
  3. \usepackage{amssymb}
  4. \usepackage{amsthm}
  5. \newcommand\zhmgs[1]{\textbf{#1}\hspace{0.5em}}
  6. \makeatletter
  7. \def\zhm{\@ifstar{\zhmm[证明]}{\@ifnextchar[{\zhmm}{\zhmm[证明]}}}
  8. \def\zhmm[#1]{\@ifnextchar[{\zhmmm[#1]}{\zhmgs{#1}}}
  9. \def\zhmmm[#1][#2]{\zhmgs{#1\ (#2)}}
  10. \makeatother
  11. \renewenvironment{proof}
  12. {\addvspace{1em} \noindent \zhm}
  13. {\hfill $\blacksquare$ \par \ignorespacesafterend \addvspace{1em}}
  14. \begin{document}
  15. \begin{proof}
  16. test
  17. \end{proof}
  18. \begin{proof}[定理1.1的证明]
  19. test
  20. \end{proof}
  21. \begin{proof}*[XXX]
  22. test
  23. \end{proof}
  24. \begin{proof}[定理2.2的证明][YYY]
  25. test
  26. \end{proof}
  27. \end{document}
复制代码

(我把你想的写法 begin{proof}[][XXX] 简化为 begin{proof}*[XXX],简便一点)

手机版|悠闲数学娱乐论坛(第3版)

GMT+8, 2025-3-4 12:29

Powered by Discuz!

× 快速回复 返回顶部 返回列表