这里有一些非常好的人帮助我编写了下面的代码片段。代码运行良好,它打印出正确的潜台词,并且通过输入以下内容获得可选参数*
\documentclass[10pt,a4paper]{article}
\newcounter{problem}
\setcounter{problem}{0}
\newcounter{alternative}
\setcounter{alternative}{0}
\newif\iffirstalt
\usepackage{xparse}
\NewDocumentCommand{\Oppgave}{s m}{%
\IfBooleanTF{#1}%
{\stepcounter{alternative}\iffirstalt\else\stepcounter{problem}\firstalttrue\fi}%
{\setcounter{alternative}{0}\stepcounter{problem}\firstaltfalse}%
\section*{Oppgave \arabic{problem}%
{\normalfont\IfBooleanTF{#1}{~Alternative \Roman{alternative}\ }{}
\normalsize (#2 poeng)}%
\addcontentsline{toc}{section}{Oppgave \arabic{problem} }}
}
\begin{document}
\tableofcontents
\oppgaveS{3}
\oppgaveS{4}
\oppgaveS*{2}
\oppgaveS*{2}
\oppgaveS{3}
\oppgaveS*{2}
\end{document}
是否有可能添加零个可选输入?我的意思是我可以写
\Oppgave and \Oppgave*
显示为
奥普加夫 1和反对 1 替代方案 1
我只是希望没有小文本,如果我只是简单地写下命令=)
答案1
下面是一个使用默认 TeX 语法且不带 xparse 包的示例,它更适合包开发人员而不是具有本地宏的用户:
\documentclass[10pt,a4paper]{article}
\newcounter{problem}
\newcounter{alternative}
\newif\iffirstalt
\makeatletter
\def\Oppgave{\@ifnextchar*{\Oppgave@i}{\Oppgave@ii}}
\def\Oppgave@i*{\@ifnextchar\bgroup{\Oppgave@iii}{\Oppgave*{1}}}
\def\Oppgave@ii{\@ifnextchar\bgroup{\Oppgave@iv}{\Oppgave{1}}}
\def\Oppgave@iii#1{%
\setcounter{alternative}{0}\stepcounter{problem}\firstaltfalse
\section*{Oppgave \arabic{problem}%
\normalfont~Alternative \Roman{alternative}\ \normalsize (#1 poeng)}%
\addcontentsline{toc}{section}{Oppgave \arabic{problem} }}
\def\Oppgave@iv#1{\stepcounter{alternative}\iffirstalt\else\stepcounter{problem}\firstalttrue\fi
\section*{Oppgave \arabic{problem} \normalsize (#1 poeng)}%
\addcontentsline{toc}{section}{Oppgave \arabic{problem} }}
\makeatletter
\begin{document}
\tableofcontents
\Oppgave{3}
\Oppgave{4}
\Oppgave*{2}
\Oppgave*{2}
\Oppgave{3}
\Oppgave*{2}
\Oppgave
\Oppgave*
\end{document}
答案2
以下需要对您的输入进行小幅修改。不要使用\oppgaveS*{<num>}
,而要使用\oppgaveS*[<num>]
:
\documentclass[10pt,a4paper]{article}
\newcounter{problem} %\setcounter{problem}{0}
\newcounter{alternative} %\setcounter{alternative}{0}
\newif\iffirstalt
\usepackage{xparse}% http://ctan.org/pkg/xparse
\NewDocumentCommand{\oppgaveS}{s o}{%
\IfBooleanTF{#1}%
{\stepcounter{alternative}\iffirstalt\else\stepcounter{problem}\firstalttrue\fi}%
{\setcounter{alternative}{0}\stepcounter{problem}\firstaltfalse}%
\section*{Oppgave~\arabic{problem}~%
{\normalfont\IfBooleanTF{#1}{Alternative \Roman{alternative}~}{}}%
\IfNoValueTF{#2}{}{\normalfont\normalsize (#2 poeng)}}%
\addcontentsline{toc}{section}{Oppgave~\arabic{problem}}
}
\begin{document}
\tableofcontents
\oppgaveS[3]
\oppgaveS[4]
\oppgaveS*[2]
\oppgaveS*[2]
\oppgaveS[3]
\oppgaveS*[2]
\oppgaveS*
\oppgaveS*[3]
\oppgaveS
\oppgaveS
\oppgaveS*
\end{document}
可选参数规范o
来自xparse
\NoValue
若为空则取值(使用\oppgaveS
或时\oppgaveS*
),并以使用 为条件\IfNoValueTF
。
答案3
您可以通过将定义的第一行更改为来将参数声明为可选
\NewDocumentCommand{\Oppgave}{s g}{%
你也必须\normalsize (#2 poeng)
变成
\IfNoValueTF{#2}{}{\ \normalsize (#2 poeng)}
删除\
前一行的(控制空格)。
另一方面,如果你采用以下语法,会更清楚
\Oppgave*[n]
(只需将参数中的“g”更改\NewDocumentCommand
为“o”)。
\NewDocumentCommand{\oppgaveS}{s g}{% Put o instead of g for clearer syntax
\IfBooleanTF{#1}%
{\stepcounter{alternative}\iffirstalt\else\stepcounter{problem}\firstalttrue\fi}%
{\setcounter{alternative}{0}\stepcounter{problem}\firstaltfalse}%
\section*{Oppgave~\arabic{problem}%
{\normalfont\IfBooleanTF{#1}{\ Alternative \Roman{alternative}}{}}%
\IfNoValueTF{#2}{}{\ \normalfont\normalsize (#2 poeng)}}%
\addcontentsline{toc}{section}{Oppgave~\arabic{problem}}
}
答案4
如果我理解正确的话,你想说的是\Oppgave
,这应该和\Oppgave{1}
和\Oppgave*
一样\Oppgave*{1}
如果是这样,您只需替换
\NewDocumentCommand{\Oppgave}{s m}{%
和
\NewDocumentCommand{\Oppgave}{s O{1}}{%
然后第一个参数(#2
因为s
代表 ,*
被认为是#1
)是可选的,如果没有指定,它将采用 的值。如果没有指定参数,则{1}
带有 的部分是默认值。{}
从文档xparse
,你可以用小写o
或大写定义可选参数O
:
o
标准的 LaTeX 可选参数,用方括号括起来,\NoValue
如果未给出,将提供特殊标记。
O
与 相同o
,但{default}
如果未给出值则返回。应给出O{default}
。
如果你希望能够使用{}
可选参数,你应该使用
g
一对 TEX 组标记(在标准 LATEX 中)内给出的可选参数,如果不存在则{}
返回。\NoValue
G
与 g 相同,但default
如果没有给出值则返回:G{default
}`。
您提供的 MWE 使用了m
记录如下的选项:
m
标准强制参数,可以是单个标记,也可以是用花括号括起来的多个标记。无论输入是什么,该参数都将传递给用括号对括起来的内部代码。这是普通 TEX 参数的 xparse 类型说明符。