不完整 \ifx

不完整 \ifx

我正在尝试定义一个函数莱特林来自莱特林一。我做到了这里成功,但我需要添加一个可选参数才能使用更多莱特林类似这样的功能赌注

\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\LettrineX #1#2{\vspace{-4ex}\lettrine[lines=1,findent=-0.1em
    \ifx\dummy#2\dummy\empty\else,#2\fi%
    ]{#1}{}}
\newcommand*{\Lettrine}[2][x]{\LettrineX{#2}{#1}}

\begin{document}\thispagestyle{empty}
\section{section 1}
\Lettrine[ante=«]{P}owerfull macro ! »
\section{section 2}
\Lettrine{P}owerfull macro !

\end{document}

它无法编译,并出现错误:

$ pdflatex MWE_lettrine_command7.tex 
This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013)
 restricted \write18 enabled.
entering extended mode
(./MWE_lettrine_command7.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)) (./MWE_lettrine_command7.aux))
! Incomplete \ifx; all text was ignored after line 17.
<inserted text> 
                \fi 
<*> MWE_lettrine_command7.tex

如果我\expandafter在 之前添加一个lettrine,它不会改变任何东西,但我对这种事情还很陌生。如果我注释掉这\ifx行代码,它确实可以编译并运行。

以下MWE在演示函数中使用可选参数内的表达式\ifx重现了相同类型的体系结构。它编译并成功运行:ifx

\documentclass{article}
\usepackage{lettrine}

\newcommand*{\Test}[2][xxx]{option=#1; argument=#2}

\def\testX #1#2{%
  \Test[\ifx\dummy#2\dummy\empty\else,#2\fi]{#1}%
}

\newcommand*{\test}[2][]{\testX{#2}{#1}}

\begin{document}\thispagestyle{empty}
With one argument:  "\test{MAIN-ARG---ONLY-ONE}"\par
With two arguments: "\test[OPTION=2]{MAIN-ARG}"
\end{document}

结果: 在此处输入图片描述

我都快要疯掉了,不知道自己做错了什么。有什么想法吗?

答案1

代码在键值列表中包含以下内容:

\ifx\dummy#2\dummy\empty\else,#2\fi

列表中的第一个元素是(假设#2不包含,):

\ifx\dummy#2\dummy\empty\else

接下来是

#2\fi

\ifx构造由键值解析器在逗号处划分。

以下实现部分扩展了选项以获取有效的键值选项列表:

\documentclass{article}
\usepackage{lettrine}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\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}

\newcommand*{\Lettrine}[2][]{%
  \vspace{-4ex}%
  \edef\LettrineNext{%
    \noexpand\lettrine[%
      lines=1,
      findent=%
        \eqifcase {#2}{{P}{-0.8em}{T}{-0.6em}}{-0.1em},%
      \unexpanded{#1}%
    ]%
  }%
  \LettrineNext{\textit{#2}}{}%
}

\begin{document}\thispagestyle{empty}
\section{section 1}
\Lettrine[ante=«]{P}owerfull macro ! »
\section{section 2}
\Lettrine{P}owerfull macro !
\end{document}

结果

支持附加功能的新实现

  • 大写字母可以隐藏在宏内部,例如\dropCap

  • 该字母可以由多个标记组成,例如D'

\DeclareFindents配置间隙长度:

\DeclareFindents{-0.1em}{
  P=-0.8em,
  T=-0.6em,
  D'=-1em,
}

第一个参数是默认值。然后是键值列表;键是字母(也可能是多个标记),值是此字母的间隙长度。

软件包kvsetkeys提供了可配置键值解析器的框架,该解析器将列表条目与实际字母进行比较。键和字母都经过运行\protected@edef以扩展宏,例如\dropCap

示例文件:

\documentclass{article}
\usepackage{lettrine}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{kvsetkeys}

\makeatletter
\newcommand*{\DeclareFindents}[2]{%
  \def\findent@default{#1}%
  \def\findent@list{#2}%
}
\DeclareFindents{0pt}{}% initializing

\newcommand*{\findent@set}[1]{%
  \protected@edef\findent@letter{#1}%
  \let\findent@value\findent@default
  \expandafter\kv@parse\expandafter{\findent@list}{%
    \protected@edef\kv@key{\kv@key}%
    \ifx\findent@letter\kv@key
      \let\findent@value\kv@value
      \kv@break
    \fi
    \@gobbletwo % key and value arguments are not needed
  }%
}
\newcommand*{\Lettrine}[2][]{%
  \vspace{-4ex}%
  \findent@set{#2}%
  \edef\LettrineNext{%
    \noexpand\lettrine[%
      lines=1,
      findent=\findent@value,
      \unexpanded{#1}%
    ]%
  }%
  \LettrineNext{\textit{#2}}{}%
}
\makeatother

\DeclareFindents{-0.1em}{
  P=-0.8em,
  T=-0.6em,
  D'=-1em,
}
\begin{document}\thispagestyle{empty}
\section{section 1}
\Lettrine[ante=«]{P}owerfull macro ! »
\section{section 2}
\Lettrine{P}owerfull macro !
\section{section 3}
\Lettrine{D'}Artagnan and his friends.
\section{section 4}
\newcommand*{\dropCap}{D'}
\Lettrine\dropCap Artangan does not drop his friends.
\end{document}

结果

答案2

\lettrine这不是一个答案,而是一个评论:我对你使用with key和空的第二个参数感到有点困惑lines=1。我看了一下lettrine 包,默认情况下,字母的高度lines=2和 的高度lines=1计算为 baselineskip 加上x小写字母的高度。这样,lines=2字母的顶部与完成段落第一个单词的小写字母的顶部相匹配。如果您不使用第二个参数,也不使用小写字母,则会出现不匹配的情况。

但是您使用的是lines=1。有人可能会争辩说,不应该考虑小型大写字母的高度x,因为这会非常随意,只需将字母的高度设置为一个或两个基线跳跃,或者可能是 1.5 个基线跳跃。有人可能会问,\lettrine如果要使用 ,为什么要使用该命令\lines=1

可以加载该包并以不正当的方式使用它来重新使用其计算的正确字体大小,从而为字母提供给定的高度。我们可以直接这样做,但也许该文档会有一些\lettrine用处lines>1...

莱特林

\documentclass{article}
% LET'S NOT FORGET TO ALLOW EXTRA SIZES!:
\usepackage[T1]{fontenc}
\usepackage{lettrine}
\usepackage{lmodern}

% http://tex.stackexchange.com/a/179403/4686
\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}


\makeatletter
% The .5\baselineskip and 1.5\baselineskip should be customized
\def\Lettrine #1{\vspace{.5\baselineskip}%
               {\def\Lettrine@height {\setlength{\L@height}{1.5\baselineskip}}%
                  \renewcommand\LettrineFontHook{\itshape}%
                  \noindent\LettrineFont #1}% <-\smash{#1} possible
                  \kern\eqifcase % whatever is wished and here we
                  % actually don't need an expandable eqifcase anymore
                  % but as we have it handy we can use it here after \kern
                  {#1}{{P}{-0.4em}{T}{-0.5em}{D}{-0.2em}}{-0.1em}\relax
                }
\makeatother               

\begin{document}

\section{section 1}


\lettrine[lines=2]{P}{owerful} macro ! Various parameters are
provided to control the size and layout of the dropped capital and match
the requirements described in the books.\hrulefill\par\nointerlineskip

\Lettrine{P}owerful macro ! \smash{\rule{1pt}{2\baselineskip}} Various parameters are
provided to control the size and layout of the dropped capital and match
the requirements described in the books


\section{section 2}

\Lettrine{D}efault.  \smash{\rule{1pt}{1.5\baselineskip}} The letter glyph
extends a bit above its box. Various parameters are
provided to control the size and layout of the dropped capital and match
the requirements described in the books

\section{section 3}

\Lettrine{T}his is nice!  \smash{\rule{1pt}{1.5\baselineskip}} The letter glyph
extends a bit above its box. Various parameters are
provided to control the size and layout of the dropped capital and match
the requirements described in the books

\end{document}

答案3

这是一个失败的解决方案,尝试应用什么埃格尔教会了我这里获得 \Lettrine{D'}Artagnan 能力,坚持海科·奥伯迪克的第一个解决方案(缩进覆盖是故意的,--第一个字母- 还):

在此处输入图片描述

\documentclass{article}
\usepackage{lettrine}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\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}

\usepackage{fp,stringstrings}

\makeatletter
\def\extract@first#1#2\@nil{#1}
\newcommand*{\Lettrine}[2][]{%
  \vspace{-4ex}%
  \def\dropCap{\extract@first#2\@empty\@nil}%
  \FPset\myindent\expandafter\eqifcase {\dropCap}{{D}{-1em}{P}{-0.6em}{T}{-0.6em}}{-0.1em}%
  % later more operations with \myindent
  \edef\LettrineNext{%
    \noexpand\lettrine[%
      lines=1,
      findent=\myindent,%
      %findent=%
      %  \expandafter\eqifcase {\dropCap}{{D}{-1em}{P}{-0.6em}{T}{-0.6em}}{-0.1em},%
      \unexpanded{#1}%
    ]%
  }%
  \LettrineNext{\textit{#2}}{---\dropCap---}%
}
\makeatother
\renewcommand{\LettrineTextFont}{}

\begin{document}\thispagestyle{empty}
\section{section 1}
\Lettrine[ante=«]{P}owerfull macro ! »
\section{section 2}
\Lettrine{P}owerfull macro !
\section{section 3}
\Lettrine{D'}Artagnan and his friends.

\end{document}

\myindent始终采用默认值-0.1em。有什么线索吗?

相关内容