여러 선택적 매개변수를 사용하여 매크로를 정의하는 방법은 무엇입니까?

여러 선택적 매개변수를 사용하여 매크로를 정의하는 방법은 무엇입니까?

작동하는 매크로를 얻은 후 일부 매개변수를 선택 사항으로 만들어 매크로를 개선하려고 했습니다. 불행히도 매크로는 더 이상 작동하지 않습니다. 대신 이해할 수 없는 오류가 발생합니다. 예를 들면 다음과 같습니다.

LaTeX Warning: Label `####5' multiply defined.
LaTeX Warning: Label `####5' multiply defined.
! LaTeX Error: \fLab undefined.
! Illegal parameter number in definition of \fLab.
! Illegal parameter number in definition of \reserved@a.
! LaTeX Error: \fCap undefined.

...등등. 내가 시도한 마지막 코드는 다음과 같습니다.

%% Graphics figure with caption and label
% [1:placement,] 2:relative width, 3:file name[, 4:caption[, 5:label]]
\newcommand{\figCapLab}[5][htbp]{%
\ifthenelse{\equal{#5}{}}%
{\renewcommand{\fLab}{}}%
{\renewcommand{\fLab}{\label{##5}}}%
\ifthenelse{\equal{#4}{}}%
{\renewcommand{\fCap}{\fLab}}%
{\renewcommand{\fCap}{\caption{\fLab{\small{}##4}}}}%
\begin{figure}[#1]%
\centering%
\begin{minipage}[t]{#2\textwidth}%
\includegraphics[width=\textwidth]{#3}% is width of surrounding minipage
\fCap%
\end{minipage}%
\end{figure}
}
%% Graphics figure with caption
% [1:placement,] 2:relative width, 3:file name, 4:caption
\newcommand{\figCap}[4]{%
\ifthenelse{\equal{#1}{}}%
{\figCapLab{#2}{#3}{#4}{}}%
{\figCapLab[#1]{#2}{#3}{#4}{}}%
}
%% Graphics figure with label
% [1:placement,] 2:relative width, 3:file name, 4:label
\newcommand{\figLab}[4]{%
\ifthenelse{\equal{#1}{}}%
{\figCapLab{#2}{#3}{}{#4}}%
{\figCapLab[#1]{#2}{#3}{}{#4}}%
}

누가 무엇이 잘못되었는지 설명할 수 있나요?

완전한 예제를 좋아하는 사람들은 다음 프롤로그를 추가해야 합니다:

\documentclass[a4paper,twoside]{report}
\usepackage{german}
\usepackage[latin1]{inputenc}
\usepackage{a4}
\usepackage{amsmath}
\usepackage{url}
\usepackage{graphicx}
\usepackage{ifthen}

...이 에필로그는 다음과 같습니다.

\begin{document}
See \ref{foo}.
\figCapLab{0.9}{whatever.pdf}{Caption}{foo}
\end{document}

답변1

잘못된 동작을 나타내는 컴파일 가능한 예제를 직접 작성하라는 모호한 지시에 따를 때

\documentclass[a4paper,twoside]{report}
\usepackage{german}
\usepackage[latin1]{inputenc}
\usepackage{a4}
\usepackage{amsmath}
\usepackage{url}
\usepackage{graphicx}
\usepackage{ifthen}

%% Graphics figure with caption and label
% [1:placement,] 2:relative width, 3:file name[, 4:caption[, 5:label]]
\newcommand{\figCapLab}[5][htbp]{%
\ifthenelse{\equal{#5}{}}%
{\renewcommand{\fLab}{}}%
{\renewcommand{\fLab}{\label{##5}}}%
\ifthenelse{\equal{#4}{}}%
{\renewcommand{\fCap}{\fLab}}%
{\renewcommand{\fCap}{\caption{\fLab{\small{}##4}}}}%
\begin{figure}[#1]%
\centering%
\begin{minipage}[t]{#2\textwidth}%
\includegraphics[width=\textwidth]{#3}% is width of surrounding minipage
\fCap%
\end{minipage}%
\end{figure}
}
%% Graphics figure with caption
% [1:placement,] 2:relative width, 3:file name, 4:caption
\newcommand{\figCap}[4]{%
\ifthenelse{\equal{#1}{}}%
{\figCapLab{#2}{#3}{#4}{}}%
{\figCapLab[#1]{#2}{#3}{#4}{}}%
}
%% Graphics figure with label
% [1:placement,] 2:relative width, 3:file name, 4:label
\newcommand{\figLab}[4]{%
\ifthenelse{\equal{#1}{}}%
{\figCapLab{#2}{#3}{}{#4}}%
{\figCapLab[#1]{#2}{#3}{}{#4}}%
}

\begin{document}
See \ref{foo}.
\figCapLab{0.9}{whatever.pdf}{Caption}{foo}
\end{document}

, 설명하신 오류는 발생하지 않지만 다음과 같은 오류가 발생합니다.

LaTeX Warning: Reference `foo' on page 1 undefined on input line 43.


! LaTeX Error: \fLab undefined.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.44 \figCapLab{0.9}{whatever.pdf}{Caption}{foo}

? 
! Illegal parameter number in definition of \fLab.
<to be read again> 
                   5
l.44 \figCapLab{0.9}{whatever.pdf}{Caption}{foo}

? 

! LaTeX Error: \fCap undefined.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.44 \figCapLab{0.9}{whatever.pdf}{Caption}{foo}

? 
! Illegal parameter number in definition of \fCap.
<to be read again> 
                   4
l.44 \figCapLab{0.9}{whatever.pdf}{Caption}{foo}

? 

LaTeX Warning: File `whatever.pdf' not found on input line 44.


! Package pdftex.def Error: File `whatever.pdf' not found: using draft setting.


See the pdftex.def package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.44 \figCapLab{0.9}{whatever.pdf}{Caption}{foo}

? 
! Illegal parameter number in definition of \reserved@a.
<to be read again> 
                   4
l.44 \figCapLab{0.9}{whatever.pdf}{Caption}{foo}

? 
! Illegal parameter number in definition of \reserved@a.
<to be read again> 
                   5
l.44 \figCapLab{0.9}{whatever.pdf}{Caption}{foo}

? 
! You can't use `macro parameter character #' in restricted horizontal mode.
<argument> ...e : \ignorespaces \fLab {\small {}##
                                                  4}
l.44 \figCapLab{0.9}{whatever.pdf}{Caption}{foo}

? 
[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./test.aux)

LaTeX Warning: There were undefined references.

대신에 나는 다음을 수행합니다.

\documentclass[a4paper,twoside]{report}
\usepackage{german}
\usepackage[latin1]{inputenc}
\usepackage{a4}
\usepackage{amsmath}
\usepackage{url}
\usepackage{graphicx}
\usepackage{ifthen}

% As later \renwecommand is done on these macros, 
% they should be defined: !!!!!!!!!!!!
\newcommand{\fLab}{}
\newcommand{\fCap}{}

%% Graphics figure with caption and label
%  #1: optional: placement
%  #2: non-optional: relative width
%  #3: non-optional: file name
%  #4: non-optional: in case not empty: caption
%  #5: non-optional: in case not empty: label
\newcommand{\figCapLab}[5][htbp]{%
\ifthenelse{\equal{#5}{}}%
{\renewcommand{\fLab}{}}%
{\renewcommand{\fLab}{\label{#5}}}% !!!!Don't double the hash!!!!
\ifthenelse{\equal{#4}{}}%
{\renewcommand{\fCap}{\fLab}}%
{\renewcommand{\fCap}{\caption{\fLab{\small{}#4}}}}% !!!!Don't double the hash!!!!
\begin{figure}[#1]%
\centering
\begin{minipage}[t]{#2\textwidth}%
\includegraphics[width=\textwidth]{#3}% is width of surrounding minipage
\fCap
\end{minipage}%
\end{figure}%%%%%%%
}
%% Graphics figure with caption
% [1:placement,] 2:relative width, 3:file name, 4:caption
\newcommand{\figCap}[4]{%
\ifthenelse{\equal{#1}{}}%
{\figCapLab{#2}{#3}{#4}{}}%
{\figCapLab[#1]{#2}{#3}{#4}{}}%
}
%% Graphics figure with label
% [1:placement,] 2:relative width, 3:file name, 4:label
\newcommand{\figLab}[4]{%
\ifthenelse{\equal{#1}{}}%
{\figCapLab{#2}{#3}{}{#4}}%
{\figCapLab[#1]{#2}{#3}{}{#4}}%
}

\begin{document}
See \ref{foo}.
\figCapLab{0.9}{example-grid-100x100pt.pdf}{Caption}{foo}
\end{document}

, 두 번째 컴파일에서는 오류나 경고가 표시되지 않습니다.


그건 그렇고 1 :

나는 가지고 있지 않다뭐든지.pdf내 시스템의 texmf-트리에 있습니다.

이미지를 처리하는 예제를 제공하려는 경우 최신 LaTeX 시스템이 제공하는 즉시 사용 가능한 이미지를 사용할 수 있습니다.

예를 들어 Martin Scharrer의 문서MWE 패키지해당 패키지로 인해 사용 가능한 모든 이미지가 나열됩니다. 현재 TeX 플랫폼과 최신 릴리스를 사용하면MWE 패키지, 이미지는 texmf-tree 및 filename-database에 통합되어 있으므로 패키지를 로드할 필요 없이 사용할 수 있습니다.

그런데 2:

일반적인 상황에서는 가독성을 높이기 위해 TeX 소스 코드 줄을 들여쓸 수 있습니다. ;-) 이는 (La)TeX가 입력 줄을 읽기 시작할 때 읽기 장치의 상태가 N(새 줄) 상태인 반면 상태에서는 범주 코드 10(공백)의 N 문자가 토큰화되지 않기 때문입니다. 공간 토큰으로 사용되지만 토큰을 전혀 생성하지 않습니다.

그런데 3:

잘못된 동작을 정확하게 재현하기 위해 사람들이 있는 그대로 컴파일할 수 있는 예제를 제공하는 것이 좋습니다. 잘못된 동작을 재현할 수 있는 능력은 잘못된 동작을 생성하는 코드를 디버깅하는 데 중요합니다.


니콜라 탤벗 박사의LaTeX 최소 예제 만들기몇 가지 지침을 제공합니다.

또한 있다'최소한의 예'를 만드는 방법질문에 대한 조언에 대한 링크도 포함되어 있는 texfaq.org에서.

~ 안에최소 작업 예제는 무엇입니까?Christian Faulhammer는 "최소 예제"라는 용어를 사용하지 않지만 잘못된 동작을 나타내는 데 충분하다는 의미에서만 작동하는 예제에도 "최소 작업 예제"라는 용어를 사용합니다.

질문에 대한 답변에도 관심이 있을 수 있습니다.방금 최소한의 예를 작성해 달라는 요청을 받았습니다. 그게 무엇입니까?

답변2

OP는 이 답변에 대한 약간의 설명을 요청했으므로 여기에 텍스트를 추가하겠습니다. 선택적 인수에 대한 표준 LaTeX 메커니즘에서는 필수 인수 앞에 오는 하나의 선택적 인수를 허용합니다. 따라서 선택적 인수, 2개의 필수 인수, 2개의 선택적 인수를 제공하는 구문을 생성하려면 3개의 선택적 인수가 요청되므로 3개의 매크로를 연속적으로 연결해야 합니다.

첫 번째 매크로는 선택적 인수와 2개의 필수 인수를 흡수한 다음 두 번째 매크로를 호출해야 하며 여기에 핵심이 있습니다.마지막 행동으로! 두 번째 매크로 호출이 첫 번째 매크로의 최종 작업이어야 하는 이유는 두 번째 매크로가 선택적 인수를 흡수해야 하기 때문입니다. 체인에서 두 번째 매크로 호출을 따르는 첫 번째 매크로에 토큰이 있는 경우 첫 번째 매크로의 다른 토큰은 의도된 것이 아닌 인수로 흡수됩니다.

마찬가지로 두 번째 매크로는 세 번째 매크로를 최종 작업으로 호출해야 합니다.

특정 기발한 하이라이트:

  1. 연속 매크로가 블록 내부에서 호출되는 경우 연속 매크로가 또는 를 흡수하려고 시도하지 않도록 연속 매크로보다 먼저 \if호출되어야 합니다 .\expandafter\else\fi

  2. 이 특별한 경우 마지막 선택적 인수인 레이블은 캡션이 지정된 경우에만 호출 가능합니다. 따라서 체인의 두 번째 매크로는 캡션이 지정된 경우에만 세 번째 매크로를 호출합니다. 그렇지 않으면 시퀀스가 ​​잘립니다.

MWE:

\documentclass{article}
\usepackage{graphicx}
\newcommand\addtofigtoks[1]{\expandafter\figtoks\expandafter
  {\the\figtoks#1}}
\newtoks\figtoks
\newcommand\figCapLab[3][htbp]{%
  \figtoks{\begin{figure}[#1]}
  \addtofigtoks{\centering}
  \addtofigtoks{\includegraphics[width=#2\textwidth]{#3}}
  \optcap
}
\newcommand\optcap[1][\relax]{%
  \ifx\relax#1\relax
    \addtofigtoks{\end{figure}}
    \the\figtoks
  \else
    \addtofigtoks{\caption{#1}}%
    \expandafter\labelopt
  \fi
}
\newcommand\labelopt[1][\relax]{%
  \ifx\relax#1\relax\else\addtofigtoks{\label{#1}}\fi
  \addtofigtoks{\end{figure}}
  \the\figtoks
}
\begin{document}
\figCapLab{.2}{example-image-a}
\figCapLab{.2}{example-image-b}[My caption]
\figCapLab{.2}{example-image-c}[My caption][fg:label1]
\figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

In figures \ref{fg:label1} and \ref{fg:label2}...
\end{document}

여기에 이미지 설명을 입력하세요

아슈알리, 생각해보면 토큰도 필요하지 않네요.

\documentclass{article}
\usepackage{graphicx}
\newcommand\figCapLab[3][htbp]{%
  \begin{figure}[#1]
  \centering
  \includegraphics[width=#2\textwidth]{#3}
  \optcap
}
\newcommand\optcap[1][\relax]{%
  \ifx\relax#1\relax
    \end{figure}
  \else
    \caption{#1}%
    \expandafter\labelopt
  \fi
}
\newcommand\labelopt[1][\relax]{%
  \ifx\relax#1\relax\else\label{#1}\fi
  \end{figure}
}
\begin{document}
\figCapLab{.2}{example-image-a}
\figCapLab{.2}{example-image-b}[My caption]
\figCapLab{.2}{example-image-c}[My caption][fg:label1]
\figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

In figures \ref{fg:label1} and \ref{fg:label2}...
\end{document}

답변3

다음은 다음을 사용하여 목표를 달성하는 방법입니다.xparse:

여기에 이미지 설명을 입력하세요

\documentclass{article}

\usepackage{graphicx,xparse}

% \figCapLab
%   [<float spec>]   #1
%   {<width factor>} #2
%   {<image>}        #3
%   [<caption>]      #4
%   [<label>]        #5
\NewDocumentCommand{\figCapLab}{ O{htbp} m m o o }{%
  \begin{figure}[#1]
    \centering
    \includegraphics[width=#2\linewidth]{#3}% Set image at width
    \IfValueT{#4}
      {\caption{#4}\IfValueT{#5}{\label{#5}}}% Set possible \caption and \label
  \end{figure}
}

\begin{document}

\figCapLab{.2}{example-image-a}
\figCapLab{.2}{example-image-b}[My caption]
\figCapLab{.2}{example-image-c}[My caption][fg:label1]
\figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

In figures \ref{fg:label1} and \ref{fg:label2}\ldots

\end{document}

기본값이 있는 선택적 인수는 를 사용하여 지정되는 O{<default>}반면 기본값이 없는 선택적 인수는 를 사용합니다 o. 값 제공 여부에 대한 조건은 를 사용하여 수행됩니다 \IfValueTF{<parameter>}{<true>}{<false>}. 또한 단수 조건문 \IfValueT및 가 있는데 \IfValueF, 그 중 전자가 위에서 사용되었습니다.

위 코드에서는 빈 캡션(공백의 네 번째 인수)에는 \label(다섯 번째) 인수가 필요하지 않다고 가정합니다. 필요한 경우 분기 \IfValueT{#5}{\label{#5}}밖으로 이동하십시오 .<true>\IfValueT{#4}

\NewDocumentCommand{\figCapLab}{ O{htbp} m m o o }{%
  \begin{figure}[#1]
    \centering
    \includegraphics[width=#2\textwidth]{#3}% Set image at width
    \IfValueT{#4}{\caption{#4}}% Possible \caption
    \IfValueT{#5}{\label{#5}}% Possible \label
  \end{figure}
}

관련 정보