* texdoc xparse * [http://tug.org/TUGboat/tb31-1/tb97wright-xparse.pdf Beyond \newcommand with xparse] * [https://tug.org/TUGboat/tb31-3/tb99wright.pdf From \newcommand to \NewDocumentCommand with xparse] * \usepackage{xparse}가 필요함. [[TableOfContents]] === \newcommand에서 \NewDocumentCommand로... === ==== \newcommand 대체하기: basics ==== * 단순 대체 {{{#!tex %\newcommand\bsh{\textbackslash} \NewDocumentCommand\bsh{}{\textbackslash} }}} {{{#!tex \bsh\texttt{newcommand} 대체하기. }}} * 인자 하나 있는 명령... {{{m}}}: mandatory argument {{{#!tex %\newcommand\hi[1]{Hello, #1} \NewDocumentCommand\hi{m}{Hello, #1} }}} {{{#!tex \hi{Tom}. }}} * 인자 두개 있는 명령... {{{mm}}} {{{#!tex %\newcommand\hii[2]{Hello, #1 and #2} \NewDocumentCommand\hii{mm}{Hello, #1 and #2} }}} {{{#!tex \hii{Tom}{Judy}. Long time no see. }}} * \renewcommand -> \RenewDocumentCommand {{{#!tex %\newcommand\hii[2]{Hello, #1 and #2} \renewcommand\hii[2]{Hi, #1 and #2} \RenewDocumentCommand\hii{mm}{Hi, #1 and #2} }}} {{{#!tex \hii{Tom}{Judy}. Long time no see. }}} ==== \newcommand 대체하기: 하나의 옵션이 있는 경우 ==== * {{{o}}}: 옵션, {{{m}}}: mandatory argument {{{#!tex %\usepackage{kotex,xcolor} %\newcommand\myword[2][]{\textcolor{#1}{#2}} \NewDocumentCommand\myword{om}{\textcolor{#1}{#2}} }}} {{{#!tex \myword[black]{검정 글씨}, \myword[blue]{파랑 글씨} }}} * {{{O{}}}}: 디폴트값이 있는 옵션 지시자 {{{#!tex %\usepackage{kotex,xcolor} %\newcommand\Myword[2][black]{\textcolor{#1}{#2}} \NewDocumentCommand\Myword{O{black}m}{\textcolor{#1}{#2}} }}} {{{#!tex \Myword{검정 글씨}, \Myword[blue]{파랑 글씨} }}} ==== \newcommand 넘어서기: 두 개 이상의 옵션이 있는 경우 ==== * {{{O{}mO{}}}} {{{#!tex \NewDocumentCommand\myfbox{O{.4pt}mO{3pt}} { {\setlength{\fboxrule}{#1} \setlength{\fboxsep}{#3} \fbox{#2}} } }}} {{{#!tex \myfbox{default box} \myfbox[2pt]{thick frame} \myfbox{wider space}[5pt] \myfbox[2pt]{wider space with thick frame}[5pt] }}} output: attachment:twooptions1.png?width=600px === argument specifiers === * m: mandatory argument 꼭 있어야 하는 인자... 위 아래의 예 참조 * l: 첫 여는 활괄호"{"를 만날 때까지 적힌 모든 것을 인자로 받는다. (다음 예에서 l은 첫번째 인자, m은 두번째 인자) {{{#!tex %\usepackage{xcolor} \NewDocumentCommand\arglm{lm}{\textcolor{#2}{#1}} }}} {{{#!tex \arglm Do I know you?{red} \arglm Excuse me?{blue} \arglm Should I know you?{red} }}} output: attachment:doiknowyou.png?width=400px [http://www.ktug.org/xe/index.php?mid=KTUG_open_board&order_type=desc&sort_index=regdate&page=3&document_srl=202894 'love' version] * r: 구분자가 필요한(required) 인자. 바로 이어 나오는 토큰 두개를 구분자로 간주. {{{#!tex \NewDocumentCommand\argr{r<>m}{`#1' and \textbf{#2}} }}} {{{#!tex \argr{outside} }}} output: attachment:argr-output.png?width=200px * 위 예에서 구분자 "<"와 ">"는 "("와 ")"처럼 다른 것으로 각각 대체해도 된다. * 좀 더 과격하게는 "@"와 "^" 따위로 대체해도 결과는 같다. * R: "required" with default {{{#!tex \NewDocumentCommand\argrR{R@^{default}m}{`#1' and \textbf{#2}} }}} {{{#!tex \argrR@in between^{outside} }}} output: attachment:argr-output.png?width=200px * u: 지정하는 토큰까지(until) 적힌 모든 것을 인자로 받는다. {{{#!tex \NewDocumentCommand\argu{u{+}}{`\textsc{#1}'} }}} {{{#!tex \argu Thakj Lkd Pks Alkj+ is what you might want to see. }}} output: attachment:argu-output.png?width=400px * v: verbatim처럼 프린트되는 인자 {{{#!tex \NewDocumentCommand\vtext{v}{\fbox{\texttt{#1}}}}}} {{{#!tex \vtext+$\ln xy$+는 \vtext{\(\ln xy\)}와 같은 결과를 보여주지만, \vtext{\v_$^text}는 에러... }}} output: attachment:vtext-output.png?width=500px * +...+나 |...|처럼 짝지어진 구분자 사이에 인자를 넣으면 된다. * 다른 함수의 인자 안에서는 작동하지 않는다. === optional argument specifiers === * o: optional argument * "[http://wiki.ktug.org/wiki/wiki.php/xparse?action=show#s-1.2 대체하기]"의 예 참조 * O: optional argument with default * "[http://wiki.ktug.org/wiki/wiki.php/xparse?action=show#s-1.2 대체하기]"의 예 참조 * d: delimited option {{{#!tex \NewDocumentCommand\tzdot{r()d()}{\tikz{\filldraw (#1) circle (#2);}} }}} {{{#!tex \tzdot(0,0)(2pt) }}} * D: delimited option with default {{{#!tex \NewDocumentCommand\tzDotx{O{overlay}r()D(){3pt}}{\tikz{\filldraw [#1] (#2) circle (#3);}} }}} {{{#!tex \tzDotx(0,0)\tzDotx(1,0)(4pt)\tzDotx[overlay,red](2,0)\tzDotx[overlay,blue](3,0)(5pt) }}} output: attachment:tzDotx.png?width=150px * g: option delimited by "{" and "}" (group tokens) {{{#!tex \NewDocumentCommand\tzdotg{r()g}{\tikz{\filldraw (#1) circle (#2);}} }}} {{{#!tex \tzdotg(0,0){2pt} }}} * G: {option} with default {{{#!tex \NewDocumentCommand\tzDotG{O{overlay}r()G{3pt}}{\tikz{\filldraw [#1] (#2) circle (#3);}} }}} {{{#!tex \tzDotG(0,0)\tzDotG(1,0){4pt}\tzDotG[overlay,orange](2,0)\tzDotG[overlay,green](3,0){5pt} }}} output: attachment:tzDotG.png?width=150px * s: starred version {{{#!tex \NewDocumentCommand\tzcirc{sr()}{ \IfBooleanTF#1 {{\tikz{\draw [fill,overlay,blue!80] (#2) circle (3pt);}} } {{\tikz{\draw [overlay,blue!80] (#2) circle (3pt);}} } } }}} {{{#!tex \verb+\tzcirc*(0,0)+: \tzcirc*(0,0), \quad\verb+\tzcirc(0,0)+: \tzcirc(0,0) }}} output: attachment:tzcirc-output-a.png?width=500px * t: more general token {{{#!tex \DeclareDocumentCommand\tzcirc{t=r()}{ \IfBooleanTF#1 {{\tikz{\draw [fill,overlay,blue!80] (#2) circle (3pt);}} } {{\tikz{\draw [overlay,blue!80] (#2) circle (3pt);}} } } }}} {{{#!tex \verb|\tzcirc=(0,0)|: \tzcirc=(0,0), \quad\verb|\tzcirc(0,0)|: \tzcirc(0,0) }}} output: attachment:tzcirc-output-b.png?width=500px * s 옵션에서 *를 사용하는 것과 같이, t 옵션에서는 *뿐만 아니라 =,+,!,@,#,/,^,알파벳 등 다양한 토큰 사용 가능 === xparse 명령 함수 === * NewDocumentCommand\Foo... * 같은 이름을 가진 명령이 있는지 검사하여, 없으면 새로운 명령 \Foo를 정의한다 * 있으면, 'already defined' 에러를 낸다. * RenewDocumentCommand\Foo... * 같은 이름을 가진 명령이 있는지 검사하여, 있으면 기존 명령을 대체하여 새로 정의한다. * 없으면, 'not yet defined' 에러를 낸다. * ProvideDocumentCommand\Foo... * 같은 이름을 가진 명령이 있는지 검사하여, 없으면 새로운 명령을 정의한다. * 있으면, 아무 일도 하지 않는다. 에러도 내지 않는다. * DeclareDocumentCommand\Foo... * 같은 이름을 가진 명령이 있는지 검사하지 않고, 항상 명령을 새롭게 정의한다. === Examples === * text color {{{#!tex \documentclass{article} \usepackage{kotex} \usepackage{xparse} \usepackage{xcolor} \usepackage{jiwonlipsum} \NewDocumentCommand\txtcol{lm}{\textcolor{#2}{#1}} \begin{document} \txtcol \jiwon[1]{blue!30} \txtcol \jiwon[2]{blue!50} \txtcol \jiwon[3-4]{blue!70} \end{document} }}} * {{{\frac{b}}}}->1/b, {{{\frac{a}{b}}}}->a/b [http://www.texdev.net/2010/05/23/from-newcommand-to-newdocumentcommand/ 출처] {{{#!tex \documentclass{article} \usepackage{xparse} \let\RealFrac\frac \RenewDocumentCommand\frac{mg}{% \IfNoValueTF{#2} {\RealFrac{1}{#1}} {\RealFrac{#1}{#2}}% } \begin{document} One arg: \verb|$\frac{10}$| prints $\frac{10}$. Two args: \verb|$\frac{2}{30}$| prints $\frac{2}{30}$. \end{document} }}} * 옵션을 활괄호 안에 넣기 [http://www.texdev.net/2010/05/22/promoting-xparse/ 출처] {{{#!tex \documentclass{article} \usepackage{xparse} \NewDocumentCommand\en{g}{% \IfNoValueTF{#1}{\epsilon}{\epsilon_{#1}}% } \begin{document} \verb|\en| prints \( \en \) and \verb|\en{stuff}| prints \( \en{stuff} \). \end{document} }}} * ProcessList, SplitList, xparse {{{#!tex \documentclass{article} \usepackage{xparse} \NewDocumentCommand\mylist{>{\SplitList{;}}m} { \begin{itemize} \ProcessList {#1} { \insertitem} \end{itemize} } \newcommand\insertitem[1]{\item #1} \begin{document} Short list: \mylist{a;b} Longer list: \mylist{a;b;c;d} List within a list: \mylist{a;b\mylist{A;B;C;D};c;d} \end{document} }}}