선택적 인수가 비어 있거나 선택적 인수를 전혀 제공하지 않습니까?

선택적 인수가 비어 있거나 선택적 인수를 전혀 제공하지 않습니까?

나는 에 5개의 인수가 있다는 것을 알게 되었습니다 . \parbox즉, . \parbox[<align>][<height>][<inner-align>]{<width>}{<text>}그래서 나는 \sloppy\setlength\parfillskip{0pt}#5 앞에 추가하는 내 자신의 \myparbox를 구성했습니다. 그러나 그것은 실패합니다. \myparbox를 재정의하는 이유와 방법은 무엇입니까?

MWE:

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\myparbox}{ooomm}{%
  \parbox[#1][#2][#3]{#4}{\sloppy\setlength\parfillskip{0pt}#5}
}
\begin{document}
AAA\fbox{\parbox[][][]{4em}{aa bb cc dd ee ff}}AAA\\% parbox typesets nothing. why?
BBB\fbox{\myparbox{4em}{aa bb cc dd ee ff}}BBB% This fails to compile
\end{document}

편집하다:

\documentclass{article}
\usepackage{xparse}
\let\oldparbox\parbox
\RenewDocumentCommand{\parbox}{sO{c}oO{t}mm}{%
  \IfBooleanTF{#1}
    {%
      \IfNoValueTF{#3}
        {\oldparbox[#2]{#5}{\sloppy\setlength\parfillskip{0pt}#6}}
        {\oldparbox[#2][#3][#4]{#5}{\sloppy\setlength\parfillskip{0pt}#6}}
    }
    {%
      \IfNoValueTF{#3}
        {\oldparbox[#2]{#5}{#6}}
        {\oldparbox[#2][#3][#4]{#5}{#6}}
    } 
}
\begin{document}\the\fboxsep
AAA\fbox{\parbox[t]{8em}{aa bb cc dd ee ff gg hh ii}}AAA\\% parbox typesets nothing why?.
BBB\fbox{\parbox*{6em}{aa bb cc dd ee ff}}BBB% This fails to compile
\end{document}

답변1

주석에서 언급했듯이, 빈 선택적 인수는 []선택적 인수를 전혀 제공하지 않는 것과 동일할 필요는 없습니다. 인수를 제공하지 않는 것이 특정 값을 전달하는 것과 동일한지 여부는 문서나 명령 구현을 통해 확인해야 합니다.

예제에서는 해당 선택적 인수가 제공되지 않은 경우 의 xparse선택적 o인수에 실제로 특수 표시된 값이 포함되어 있기 때문에 상황이 더욱 악화됩니다. (에서 제안한대로) -NoValue-값이 있는지 테스트할 수 있고 테스트해야 합니다.\IfNoValueTF달리프님의 댓글).

이는 처리할 선택적 인수가 하나만 있는 경우 매우 실행 가능한 솔루션이지만 인수 수가 증가하면 지저분해집니다.

의 경우 기본 인수가 특수 마커로서 이고 에서 정의를 조회할 때 \parbox알 수 있습니다 .c\relaxssourc2e.pdf

그래서 당신은 시도해 볼 수 있습니다

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\myparbox}{O{c}O{\relax}O{s}mm}{%
  \parbox[#1][#2][#3]{#4}{\sloppy\setlength\parfillskip{0pt}#5}%
}
\begin{document}
BBB\fbox{\parbox{4em}{\sloppy\setlength\parfillskip{0pt}aa bb cc dd ee ff}}BBB

BBB\fbox{\myparbox{4em}{aa bb cc dd ee ff}}BBB
\end{document}

일반적으로 저는 기본 선택적 인수 값/동작을 알아야 하거나 \IfNoValueTF첫 번째 방법은 취약해 보이고 두 번째 방법은 매우 장황하고 반복적이므로 올바른 인수를 얻기 위해 많은 수의 테스트가 필요한 이와 같은 문제를 해결하려고 노력합니다. 다음과 유사한 접근 방식마리진의 답변대안일 수도 있지만, 적어도 이 경우에는 의 정의에 대한 깊은 지식이 필요합니다 \parbox.


편집하다: 방금 질문의 새 버전을 봤습니다.\let 선택적 인수가 있는 강력한 명령에는 충분하지 않습니다.\LetLtxMacro는 언제 사용하나요?. 또한 \parbox구현이 이전 버전과 호환되더라도 기본 명령을 재정의하지 말 것을 강력히 제안합니다 . 새로운 이름이 훨씬 더 안전합니다.

답변2

또는 를 사용하여 xpatch변수를 전달할 필요 없이 명령의 올바른 위치에 추가 코드를 삽입할 수 있습니다. 해당 \parbox명령어는 실제 내용을 처리하는 내부 \@iiiparbox명령어를 호출하므로 이 내부 명령어를 패치해야 한다. MWE:

\documentclass{article}
\usepackage{xpatch}
\begin{document}
\makeatletter
\xpatchcmd{\@iiiparbox}{#5}{\sloppy\setlength\parfillskip{0pt}#5}{}{}
\makeatother
AAA\fbox{\parbox{4em}{aa bb cc dd ee ff}}AAA
\end{document}

이로 인해 모든 Parbox의 동작이 변경됩니다. 정렬된 사용자 정의 명령을 원하고 일반 명령도 유지하려는 경우 명령 복사본을 사용하여 사용자 정의 명령을 정의 \@iiiparbox하고 원본 대신 복사본을 패치할 수 있습니다. MWE:

\documentclass{article}
\usepackage{xpatch}
\begin{document}
\makeatletter
\def\myparbox{\@ifnextchar [\@iparbox {\myiiiparbox c\relax [s]}}
\let\myiiiparbox\@iiiparbox
\xpatchcmd{\myiiiparbox}{#5}{\sloppy\setlength\parfillskip{0pt}#5}{}{} 
\makeatother
AAA\fbox{\parbox{4em}{aa bb cc dd ee ff}}AAA

BBB\fbox{\myparbox{4em}{aa bb cc dd ee ff}}BBB
\end{document}

결과:

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

답변3

선택적 인수에는 \parbox특정 토큰이 포함되어야 합니다(있는 경우). 첫 번째의 기본값은 c이므로 선택적 인수가 있는지 확인하는 데 약간의 시간을 투자할 수 있습니다. 마지막 것부터 시작해야 합니다.

첫 번째 선택적 인수는 c(기본값) t또는 b; 두 번째는 길이여야 합니다. 마지막 것은 c, t, b또는 이어야 합니다 s(제공되지 않은 경우 첫 번째 것이 사용됩니다).

다른 단락을 입력할 수 있으려면 의 마지막 인수 \myparbox는 으로 표시되어야 합니다 . +m매크로 \deliverparbox는 코드 중복을 최소화하기 위해 사용됩니다.

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\myparbox}{O{c}oom+m}{%
  \IfNoValueTF{#3}
   {%
    \IfNoValueTF{#2}
     {%
      \parbox[#1]{#4}{\deliverparbox{#5}}%
     }%
     {%
      \parbox[#1][#2]{#4}{\deliverparbox{#5}}%
     }%
   }%
   {%
    \parbox[#1][#2][#3]{#4}{\deliverparbox{#5}}%
   }
}
\NewDocumentCommand{\deliverparbox}{+m}{%
  \sloppy\setlength\parfillskip{0pt}#1%
}

\begin{document}

AAA\fbox{\parbox{4em}{aa bb cc dd ee ff}}AAA

BBB\fbox{\myparbox{4em}{aa bb cc dd ee ff}}BBB

BBB\fbox{\myparbox[t][12ex][s]{4em}{aa bb cc dd ee ff\par\vfil aa bb}}BBB

\end{document}

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

관련 정보