我知道我以前问过这个问题。但我就是搞不懂 LaTeX 中的一些东西。比如可选参数。我得到了一些关于如何为命令执行此操作的线索,但不太确定如何为命令执行此操作。
我正在寻找将@egreg 的答案放入我自己的环境中。
现在我想要的输出是
\begin{SysOfEq}
ax^2 + bx + c = 0,
3y^2 + 8x - 5 = 0,
z + x = 0
\end{SysOfEq}
\begin{SysOfEq}[2pt]
ax^2 + bx + c = 0,
3y^2 + 8x - 5 = 0,
z + x = 0
\end{SysOfEq}
现在,如果我不使用可选参数,则默认间距应为3pt
。当使用可选间距时,它应该是3pt
+ 输入。
单独的代码(不带可选参数)如下所示
\documentclass[10pt,a4paper]{article}
\usepackage[hmargin=3cm,vmargin=3.5cm]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[norsk]{babel}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{systeme}
\makeatletter
\def\SYS@makesyspreamble@i#1{%
\ifnum#1<\SYS@preamblenum
\SYS@addtotok\SYS@systempreamble{\hfil$##$&\hfil$##$&}%
\expandafter\SYS@makesyspreamble@i\expandafter{\number\numexpr#1+ \@ne\expandafter}%
\else
\SYS@addtotok\SYS@systempreamble{\hfil$##$&$##$&\hfil$##$\null}%
\ifSYS@extracol
\SYS@addtotok\SYS@systempreamble{&\SYS@extracolstart##\SYS@extracolend \hfil\null}%
\fi
\SYS@addtotok\SYS@systempreamble{\cr\SYS@strutup}%
\fi
}
\makeatother
\newcommand{\SysOfEq}[1]{$
\syslineskipcoeff{1.2}\setlength{\tabskip}{#1}
\sysdelim..\systeme{#1}$}
\begin{document}
\SysOfEq{1cm}{
ax^2 + bx + c = 0,
3y^2 + 8x - 5 = 0,
z + x = 0}
\end{document}
上面的代码不起作用。这里的时钟快到凌晨 4 点了,所以我真的该睡觉了。无法完成像上面的代码这样简单的事情真是令人沮丧。
- 使用上面的代码(来自@egreg)创建一个新命令。
- 水平间距(也可能是垂直间距)的可选参数。
- 这些新价值应该只是添加到现有价值中。
答案1
以下是如何向\SysOfEq
命令添加可选参数的方法:
\documentclass[10pt,a4paper]{article}
\usepackage{systeme}% http://ctan.org/pkg/systeme
\makeatletter
\def\SYS@makesyspreamble@i#1{%
\ifnum#1<\SYS@preamblenum
\SYS@addtotok\SYS@systempreamble{\hfil$##$&\hfil$##$&}%
\expandafter\SYS@makesyspreamble@i\expandafter{\number\numexpr#1+ \@ne\expandafter}%
\else
\SYS@addtotok\SYS@systempreamble{\hfil$##$&$##$&\hfil$##$\null}%
\ifSYS@extracol
\SYS@addtotok\SYS@systempreamble{&\SYS@extracolstart##\SYS@extracolend \hfil\null}%
\fi
\SYS@addtotok\SYS@systempreamble{\cr\SYS@strutup}%
\fi
}
\makeatother
\begin{document}
\newcommand*{\SysOfEq}[2][0pt]{
\syslineskipcoeff{1.2}\setlength{\tabskip}{\dimexpr3pt+#1\relax}
\systeme{#2}}
\[
\syslineskipcoeff{1.2}\setlength{\tabskip}{3pt}
\systeme{
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\[
\SysOfEq{%
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\[
\SysOfEq[1cm]{%
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\end{document}
这允许单个可选参数具有默认间距3pt
(如果未指定)或“ 3pt
+ 输入”(如果指定)。
关于 的一些背景知识\newcommand
,它用于生产\SysOfEq
:
\newcommand{<cmd>}[<nargs>][<opt>]{<definition>}
<cmd>
是您要定义的命令。调用时,该命令应为未定义\newcommand
,否则您将收到
LaTeX 错误:命令
\SysOfEq
已定义。
错误(这里我尝试定义\SysOfEq
,但它已经定义)。在这些情况下,您需要使用\renewcommand
(或\providecommand
在 LaTeX2e 中)具有相同的参数定义。<nargs>
指的是参数应采用的数量<cmd>
。这可以是 1 到 9 之间的任何值。请注意,此规范是可选的,因此如果您省略,则可以创建一个采用 0 个参数的命令<nargs>
。如果您确实指定了<nargs>
,那么您可以指定<opt>
(同样是可选的,所以这不是必需的)。您在中指定的<opt>
内容将是第一的<definition>
参数必须是可选的。第一个参数将在中称为#1
,而后续(强制)参数将称为#2
...#9
或您在 中指定的任意多个参数<nargs>
。
从上面的讨论中,你可以看出,无论我在哪里提到#1
,它都意味着你指定的可选参数。无论我在哪里提到#2
,它都意味着我指定的内容后在这种情况下,你就有了方程组。
这种方式\newcommand
是 LaTeX 中定义命令(或控制序列)的标准方式,它允许使用单个可选参数。如果您想要更高级的方式来定义命令(包括混合可选/强制参数),您可以使用提供的接口xparse
- 请参阅@Gonzalo 的回答。
在编写具有许多可能修改的宏时,可选参数总是很好的,因为您可以随意使用它们。但是,如果不知道参数顺序是什么以及哪些是可选/强制的,维护起来可能会很困难。在这种情况下,对选项的符号引用是更好的选择。因此,键值对方法会很好用。为此,请考虑阅读如何创建带有键值的命令?
以下是对这种方法的看法:
\documentclass[10pt,a4paper]{article}
\usepackage{keyval}% http://ctan.org/pkg/keyval
\usepackage{systeme}% http://ctan.org/pkg/systeme
\makeatletter
\def\SYS@makesyspreamble@i#1{%
\ifnum#1<\SYS@preamblenum
\SYS@addtotok\SYS@systempreamble{\hfil$##$&\hfil$##$&}%
\expandafter\SYS@makesyspreamble@i\expandafter{\number\numexpr#1+ \@ne\expandafter}%
\else
\SYS@addtotok\SYS@systempreamble{\hfil$##$&$##$&\hfil$##$\null}%
\ifSYS@extracol
\SYS@addtotok\SYS@systempreamble{&\SYS@extracolstart##\SYS@extracolend \hfil\null}%
\fi
\SYS@addtotok\SYS@systempreamble{\cr\SYS@strutup}%
\fi
}
% ========= KEY DEFINITIONS =========
\newlength{\sys@width}%
\define@key{systeme}{vskip}{\def\sys@vskip{#1}}
\define@key{systeme}{width}{\setlength{\sys@width}{#1}}
% ========= KEY DEFAULTS =========
\setkeys{systeme}{vskip=1.2,width=0pt}%
\newcommand*{\SysOfEq}[2][,]{%
\setkeys{systeme}{#1}% Set new keys
\syslineskipcoeff{\sys@vskip}\setlength{\tabskip}{\dimexpr3pt+\sys@width\relax}% Use keys
\systeme{#2}}% Typeset system
\makeatother
\begin{document}
\[
\syslineskipcoeff{1.2}\setlength{\tabskip}{3pt}
\systeme{
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\[
\SysOfEq{%
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\[
\SysOfEq[width=1cm]{%
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\[
\SysOfEq[width=5pt,vskip=2]{%
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\end{document}
键值定义由keyval
包裹。
答案2
下面是具有两个可选参数的解决方案(使用xparse
包);第一个参数让您控制行之间的分隔,第二个参数控制水平间距:
\documentclass[10pt,a4paper]{article}
\usepackage[hmargin=3cm,vmargin=3.5cm]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[norsk]{babel}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{systeme}
\makeatletter
\def\SYS@makesyspreamble@i#1{%
\ifnum#1<\SYS@preamblenum
\SYS@addtotok\SYS@systempreamble{\hfil$##$&\hfil$##$&}%
\expandafter\SYS@makesyspreamble@i\expandafter{\number\numexpr#1+ \@ne\expandafter}%
\else
\SYS@addtotok\SYS@systempreamble{\hfil$##$&$##$&\hfil$##$\null}%
\ifSYS@extracol
\SYS@addtotok\SYS@systempreamble{&\SYS@extracolstart##\SYS@extracolend \hfil\null}%
\fi
\SYS@addtotok\SYS@systempreamble{\cr\SYS@strutup}%
\fi
}
\makeatother
\usepackage{xparse}
\NewDocumentCommand\SysOfEq{O{1}O{0pt}m}{
\syslineskipcoeff{#1}
\addtolength{\tabskip}{#2}
\systeme{#3}}
\begin{document}
\[
\SysOfEq{
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\[
\SysOfEq[2]{
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\[
\SysOfEq[2][1cm]{
2x + y + 3z = 10,
x + y + z = 6,
x + 3y + 2z = 13}
\]
\end{document}
尽管可以在没有附加包的情况下定义具有多个可选参数的命令,但这不是一个很简单的过程(当然,除非你有一些练习),并且该xparse
包为这种定义提供了许多便利。