使用 \newcommand 定义多个可选参数时出现问题

使用 \newcommand 定义多个可选参数时出现问题

最近我一直很困扰并且无法克服一个问题,当我想打开和结束一个带有\newcommand多个可选参数的环境时:

\documentclass[10pt,a4paper]{article}
\usepackage{caption}
\usepackage{geometry}
\usepackage{float}
\geometry{
a4paper,
total={170mm,257mm},
left=20mm,
top=20mm}
\usepackage[dvi-ps]{graphicx}
\usepackage[utf8]{inputenc}
\newfloat{obraz}{TBPH}{obr}
\floatname{obraz}{Obraz}
\newcommand{\obrc}[5][H][3.5]{\begin{obraz}[#1]
\centering
\includegraphics[width=#2 in]{#3}
\caption{#4}
\label{#5}
\end{obraz}}

因为我需要在文档中放入很多图表,所以我希望它更简单,但是我遇到了一些错误,首先是:

Missing \begin{document}. \newcommand{\obrc}[5][H][3

Missing \begin{document}. ...ommand{\obrc}[5][H][3.5]{\begin{obraz}[#1]

Illegal parameter number in definition of \@fps. ...ommand{\obrc}[5][H][3.5]{\begin{obraz}[#1]

有什么想法可以使它工作吗?

答案1

使用 LaTeX 时,您\newcommand不能定义多个可选参数。您可以使用xparse\NewDocumentCommand

\documentclass[10pt,a4paper]{article}
\usepackage{caption}
\usepackage{geometry}
\usepackage{float}
\geometry{
a4paper,
total={170mm,257mm},
left=20mm,
top=20mm}
\usepackage{graphicx}
\usepackage[utf8]{inputenc}
\newfloat{obraz}{TBPH}{obr}
\floatname{obraz}{Obraz}

\usepackage{xparse}
\NewDocumentCommand{\obrc}{
  O{H} % Optional, delimited by [], if not given use H
  D(){3.5} % Optional, delimited by (), if not given use 3.5
  m% Mandatory
  m% Mandatory
  m% Mandatory
  }{%
  \begin{obraz}[#1]
    \centering
    \includegraphics[width=#2 in]{#3}
    \caption{#4}
    \label{#5}
  \end{obraz}%
}

\begin{document}

\obrc{example-image}{No optional arguments}{hello1}

\obrc[p]{example-image}{First optional argument}{hello2}

\obrc(2){example-image}{Second optional argument}{hello3}

\obrc[b](1){example-image}{Both optional arguments}{hello4}

\end{document}

表示O{H}第一个参数是O可选的(和 LaTeX 中一样用 分隔[]),如果未给出,则默认值为HD(){3.5}表示第二个参数是可选的,并D用 分隔(),默认值为3.5。 其他三个m表示该命令将接受另外三个m可选参数。

您可以将第二个参数从 更改D(){3.5}O{3.5},然后使用 调用命令,\obrc[b][1]{...但如果不使用第一个参数,您将无法使用第二个参数。

答案2

实现您请求的输入的最简单方法是使用xparse。这允许您按以下方式指定多个可选参数(带默认值):

\usepackage{xparse}

\NewDocumentCommand{\obrc}{ O{H} O{3.5} m m m }{%
  <\obrc definition>
}

该参数O{<default>}定义了一个O具有预指定<default>值的可选参数。以下是与您的用例相匹配的完整示例:

在此处输入图片描述

\documentclass{article}

\usepackage{float,graphicx}
\usepackage{xparse}

\newfloat{obraz}{tbpH}{obr}
\floatname{obraz}{Obraz}

\NewDocumentCommand{\obrc}{ O{H} O{3.5} m m m }{%
  \begin{obraz}[#1]
    \centering
    \includegraphics[width=#2 in]{#3}
    \caption{#4}%
    \label{#5}
  \end{obraz}%
}

\begin{document}

\obrc{example-image}{Example image}{fig:example-image}

\end{document}

如果有多个可选参数,情况通常会变得很尴尬,因为您无法在不指定第一个参数的情况下指定第二个可选参数,否则无法区分哪个是哪个。但是,如果您必须指定默认值,那么这将消除指定默认值的奢侈。在这种情况下,最好创建一个命令,该命令采用键值可选参数和一些(一组)强制参数。以下是与您的用例相匹配的示例:

在此处输入图片描述

\documentclass{article}

\usepackage{float,graphicx}
\usepackage{xkeyval}

\newfloat{obraz}{tbphH}{obr}
\floatname{obraz}{Obraz}

\makeatletter
\define@cmdkey{obraz}{alignment}{}
\define@cmdkey{obraz}{float}{}
\define@cmdkey{obraz}{width}{}
\define@cmdkey{obraz}{caption}{}
\define@cmdkey{obraz}{label}{}

\newcommand{\obrc}[2][]{%
  \setkeys{obraz}{%
    float = H, % Defaut float
    width = 3.5in, % Default width
    alignment = \centering, % Default horizontal alignment
    caption = \relax, % Default caption (no caption)
    label = \relax, % Default label (no label)
    #1
  }%
  \edef\x{\noexpand\begin{obraz}[\cmdKV@obraz@float]}\x
    \cmdKV@obraz@alignment
    \includegraphics[width=\cmdKV@obraz@width]{#2}
    \ifx\cmdKV@obraz@caption\relax\else
      \caption{\cmdKV@obraz@caption}%
      \expandafter\ifx\cmdKV@obraz@label\relax\else
        \label{\cmdKV@obraz@label}% A \label without a \caption doesn't make sense, hence the nesting
      \fi
    \fi
  \end{obraz}%
}
\makeatother

\begin{document}

\obrc[%
  caption = Example image,
  label = fig:example-image%
]{example-image-a}

\obrc[%
  width = 2in,
  alignment = \raggedright,
  caption = {Example image, left-aligned}
]{example-image-b}

\end{document}

相关内容