带有案例的新命令?

带有案例的新命令?

这已得到答复这里用于文本输出,\IfEqCase使用xstring 包。但是如果我想使用输出作为值来设置函数中的参数,则会失败。

这是我的 MWE:

\documentclass[a4paper]{article} 

\usepackage{lettrine,xstring}

\newcommand*{\Lettrine}[1]{%
    \lettrine[lines=1, findent=\IfEqCase{#1}{%
        {P}{-0.8em}%
        {Q}{1em}%
    }[\PackageError{Lettrine}{Undefined option to Lettrine: #1}{}]%
    ]{\textit{#1}}{}%
}

\newcommand*{\LettrineSimply}[1]{\lettrine[lines=1, findent=-0.8em]{\textit{#1}}{}}

\begin{document} 
\LettrineSimply{P} erfectly working !
\Lettrine{P} ossibly it will work !
\end{document}

\LettrineSimply可以,但我想使用不同的找到取决于字母。在我尝试使用 时\IfEqCase,出现了以下编译错误:

$ pdflatex MWE_lettrine_command.tex 
This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013)
 restricted \write18 enabled.
entering extended mode
(./MWE_lettrine_command.tex
LaTeX2e <2011/06/27>
Babel <3.9f> and hyphenation patterns for 15 languages loaded.
(/usr/share/texmf-dist/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
(/usr/share/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texmf-dist/tex/latex/lettrine/lettrine.sty
(/usr/share/texmf-dist/tex/latex/graphics/keyval.sty)
Loading lettrine.cfg
(/etc/texmf/tex/latex/lettrine.d/lettrine.cfg))
(/usr/share/texmf-dist/tex/generic/xstring/xstring.sty
(/usr/share/texmf-dist/tex/generic/xstring/xstring.tex))
(./MWE_lettrine_command.aux)
! Missing number, treated as zero.
<to be read again> 
                   \let 
l.17 \Lettrine{P}
                  ossibly it will work !
? 

如果我只是进入

! Illegal unit of measure (pt inserted).
<to be read again> 
                   \let 
l.17 \Lettrine{P}
                  ossibly it will work !

我是否尝试将字符串分配给找到参数?我该如何解决?

否则,是否可以在命令内部定义表或关联映射?

答案1

由于您的\Lettrine命令确实做了一些不可扩展的事情,我们实际上并不需要完全可扩展的版本\IfEqCase

莱特林

\documentclass[a4paper]{article} 

\usepackage{lettrine,xstring}

\makeatletter
\newcommand*{\Lettrine}[1]{%
    \IfEqCase{#1}{%
        {P}{\def\@@temp{findent=-0.8em,}}%
        {Q}{\def\@@temp{findent=1em,}}%
    }[\PackageError{Lettrine}{Undefined option to Lettrine: #1}{}%
      \def\@@temp{}]%
    \expandafter\lettrine\expandafter[\@@temp lines=1]{\textit{#1}}{}%
}
\makeatother

\newcommand*{\LettrineSimply}[1]
   {\lettrine[lines=1, findent=-0.8em]{\textit{#1}}{}}

\begin{document}\thispagestyle{empty}

\LettrineSimply{P} erfectly working !
\Lettrine{P} ossibly it will work !
\Lettrine{Q} uite certainly it does work !
%\Lettrine{R} arely are errors encountered ! % generates error as expected
\end{document}

答案2

您需要将 \ifeqcase 定义为可扩展宏。我的解决方案仅使用 TeX 基元,不需要任何xparse包:

\documentclass[a4paper]{article}
\usepackage{lettrine}

\def\ifeqcase#1#2{\ifeqcaseA#1#2\end}
\def\ifeqcaseA#1#2#3#4{%
   \ifx#1#2#3\expandafter\ifeqcaseE\expandafter#4%
   \else\ifx#4\end
        \else \expandafter\expandafter\expandafter
              \ifeqcaseA\expandafter\expandafter\expandafter#1%
                        \expandafter\expandafter\expandafter#4% 
   \fi \fi
}
\def\ifeqcaseE#1\end#2{}

\newcommand*{\Lettrine}[1]{%
    \lettrine[lines=1, findent=\ifeqcase{#1}{%
        {P}{-0.8em}% 
        {Q}{1em}%
    }{\PackageError{Lettrine}{Undefined option to Lettrine: #1}{}}%
    ]{\textit{#1}}{}%
}
\newcommand*{\LettrineSimply}[1]{\lettrine[lines=1, findent=-0.8em]{\textit{#1}}{}}

\begin{document}   
\LettrineSimply{P}erfectly working !
\Lettrine{P}ossibly it will work !
\Lettrine{Q}next test.
\end{document}

请参阅使用不同的语法\ifcaseeq:else 部分位于普通 TeX 括号中。

我知道问题是 LaTeX 类型的,但我们可以比较在 plainTeX 中产生相同效果的代码(使用\eqifcase@jfbu)。

\input opmac

\def\eqifcase #1#2#3{\eqifcaseA #1#2#1{#3}\end}
\def\eqifcaseA #1#2#3{\ifx #1#2\eqifcaseE{#3}\fi \eqifcaseA #1}
\def\eqifcaseE #1\fi #2\end{\fi #1}

\def\letterfirst#1{\vskip.7\baselineskip\noindent{\it\thefontsize[24.7]#1}%
   \kern\eqifcase#1{P{-0.5em} Q{1em} R{.1em} S{.4em}}
   {0pt\opwarning{\string\letterfirs{#1} in unspaced}}%
}

\letterfirst Possibly it will work!
\letterfirst Qnext text.

\end

这就是 TeX 的美妙之处。

答案3

这更像是对wipet 的回答但有点太长了。

这是实现可扩展的另一种方法\ifeqcase。条件相同:我们只比较单个标记。我们使用\eqifcase作为名称。

补充说明:重新审视 wipet 的初衷\ifeqcase是将选定分支的执行移至 已清除 case-switch。完成此操作后,只需一步即可将 变成\eqifcase一个仅需两步即可扩展的宏,然后执行所选代码。值得指出的另一个方面(与添加的“仅需两步即可扩展”无关)是 可以\eqifcase用作宏的参数,这些宏通过 \romannumeral-`0 扩展其参数。我在下面添加了一个说明。

等式

\documentclass{article}

\def\eqifcase #1#2#3{\eqifcaseA #1#2#1{#3}\end }

\def\eqifcaseA #1#2#3{\ifx #1#2\eqifcaseDo{#3}\fi \eqifcaseA #1}

\def\eqifcaseDo #1\fi #2\end{\fi #1}

\def\test #1{%
    \eqifcase {#1}{{A}{aa}{B}{bb}{C}{cc}}{not found}}


\begin{document}\thispagestyle{empty}
\test{A}

\test{B}

\test{C}

\test{D}
\end{document}

说明(在宏中使用 f 扩展来扩展其参数)和扩展(case-switch 仅需两步即可扩展;此处未说明此方面)

\documentclass{article}

\def\eqifcase #1#2#3{\romannumeral0\eqifcaseA #1#2#1{#3}\end }

\def\eqifcaseA #1#2#3{\ifx #1#2\eqifcaseDo{#3}\fi \eqifcaseA #1}

\def\eqifcaseDo #1\fi #2\end{\fi \space #1}

\usepackage {xintfrac}

\makeatletter
\newcommand{\DOOPERATION}[1]{\eqifcase {#1}
    {+\xintAdd
     *\xintMul
     -\xintSub
     /\xintDiv
     T\xintTrunc}{\@gobbletwo}}
\makeatother

\begin{document}

Demonstrating the use within macros applying f-expansion to their arguments:

\xintIrr {\DOOPERATION -{113/355}{22/7}}

\xintIrr {\DOOPERATION *{1024/243}{243/1024}}

\xintIrr {\DOOPERATION /{\DOOPERATION *{1001}{999}}{\DOOPERATION *{77}{111}}}

\DOOPERATION {T}{18}{113/355}


\end{document}

ifcase 扩展

答案4

以下是最终的代码,来自吉富布解决方案,结合我从中学到的知识擦拭埃格尔

\documentclass{article}
\usepackage{lettrine}

\def\eqifcase #1#2#3{\eqifcaseA #1#2#1{#3}\end }

\def\eqifcaseA #1#2#3{\ifx #1#2\eqifcaseDo{#3}\fi \eqifcaseA #1}

\def\eqifcaseDo #1\fi #2\end{\fi #1}

\def\Lettrine #1{\vspace{-4ex}\lettrine[lines=1,findent=%
    \eqifcase {#1}{{P}{-0.8em}{T}{-0.6em}}{-0.1em}%
    ]{\textit{#1}}{}}


\begin{document}\thispagestyle{empty}
\section{section 1}
\Lettrine{P}owerfull macro !
\section{section 2}
\Lettrine{D}efault.
\section{section 3}
\Lettrine{T}remendous!
\section{section 4}
without lettrine to show that thanks to \textit{\\vspace\{-4ex\}} in the macro, we keep the same vertical space between the text baseline and the section title.
\end{document}

在此处输入图片描述 非常感谢你们三人,你们太棒了!编辑:更新感谢评论。

相关内容