这已得到答复这里用于文本输出,\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}
答案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}
非常感谢你们三人,你们太棒了!编辑:更新感谢评论。