关于在 TeX 中编写宏来修改现有样式文件的问题:fancybox.sty

关于在 TeX 中编写宏来修改现有样式文件的问题:fancybox.sty

我决定,如果要精通 LaTeX,就必须更熟练地使用 TeX。虽然这对大多数读者来说可能很明显,但我的应付能力隐藏了这个虽小但很重要的事实。例如,请考虑:

% \doublebox

\def\doublebox{\VerbBox\@doublebox}
\def\@doublebox#1{%
  \begingroup
    \setbox\@fancybox\hbox{{#1}}%
    \fboxrule=.75\fboxrule
    \setbox\@fancybox\hbox{\fbox{\box\@fancybox}}%
    \fboxrule=2\fboxrule
    \fboxsep=\fboxrule
    \advance\fboxsep .5pt
    \fbox{\box\@fancybox}%
  \endgroup}

这是 Timothy Van Zandt 的片段fancybox.sty。我希望复制并改进它(至少在我看来),通过添加对内部和外部规则宽度的控制,同样也包括分离。在这个小小的愿望清单中,我想在每个规则的基础上添加颜色。那么你说的问题是什么?问题是我对上面的内容理解不够深入,无法修改它。简而言之,我看不出有什么方法可以添加参数,\doublebox从而达到目的\@doublebox。就此而言,我不确定我是否理解了调用顺序。例如,请考虑我用作测试平台的标题页:

\documentclass{article}
\usepackage{modfancybox}
\usepackage{nth}
\begin{document}
\newlength{\fb}
\setlength{\fb}{5.625ex}
\addtolength{\fb}{1pt}
\newlength{\myl}
\setlength{\myl}{\textwidth}
\addtolength{\myl}{-\fb}
\thispagestyle{empty}
\thisfancypage{%
  \setlength{\fboxrule}{.75ex}
  \setlength{\fboxsep}{10pt}
  \doublebox
}{}
\parbox{\myl}{%
\null\vfil
\vskip 60pt
\centering
{\huge A HISTORY OF\\
THE\\
MYERS\\
OVERSTREET\\
and\\
GRAY\\
FAMILIES\\}
\vskip 2em
{\large
\lineskip .75em
\textit{\nth{1} Edition By}: Jourdan George Myers \par
\textit{\nth{2} Edition Edited By}: Hugh Shannon Myers \par
\vskip 1.5em}
{\large 1st. Edition \\December 27, 1983 \\2nd. Edition \\\today \par}
{\small vrs.\input{version}$\alpha$}
\vskip 1in
``It is not Abraham -- It is Abram''
}
\end{document}

这一切的核心似乎是:

\thisfancypage{%
  \setlength{\fboxrule}{.75ex}
  \setlength{\fboxsep}{10pt}
  \doublebox
}{}

这似乎在某种程度上引出了\parbox下面的内容。考虑到的设置\thisfancypage,这当然是有道理的。这也使得将我想要更好地控制的 3 个值硬连线起来变得合理 :) 话虽如此,我仍然想要鱼与熊掌兼得。添加颜色似乎是我最不关心的事情,因为有很多方法可以解决这个问题。现在我想起来,我还可以创建各种新的长度来添加我想要的控制。但这并不是一个真正有效的长期解决方案。我只能通过增加我的知识来做到这一点。

所以远程传输:如何创建 的参数化版本\doublebox? 发生了什么\thisfancypage? 我希望能够走得更远,不仅可以创建一个更新的版本\doubleboxP,甚至可以创建一个\Nbox。 对于那些不喜欢违反当前印刷标准的人,我深表歉意,但我喜欢的更多是 19 世纪而不是 21 世纪 :)

答案1

我会做这样的事情来参数化宏

\documentclass{article}

\usepackage{fancybox}
\usepackage{keyval}


\makeatletter

\define@key{myfb}{inner}{\def\myfb@inner{#1}}
\define@key{myfb}{outer}{\def\myfb@outer{#1}}
\define@key{myfb}{sep}{\def\myfb@sep{#1}}
\newcommand\mydoublebox[1][]{%
\def\myfbkeys{\setkeys{myfb}{#1}}%
\VerbBox\@doublebox}
\def\@doublebox#1{%
  \begingroup
    \def\myfb@inner{.75\fboxrule}%
    \def\myfb@outer{2\fboxrule}%
    \def\myfb@sep{\fboxrule+.5pt}%
    \myfbkeys
    \setbox\@fancybox\hbox{{#1}}%
    \fboxrule\dimexpr\myfb@inner\relax
    \setbox\@fancybox\hbox{\fbox{\box\@fancybox}}%
    \fboxrule\dimexpr\myfb@outer\relax
    \fboxsep\dimexpr\myfb@sep\relax
    \fbox{\box\@fancybox}%
  \endgroup}
\makeatother

\begin{document}

\mydoublebox{hello}

\mydoublebox[inner=4pt,sep=10pt]{hello}

\end{document}

在此处输入图片描述

也不要这样做

{\huge A HISTORY OF\\
THE\\
MYERS\\
OVERSTREET\\
and\\
GRAY\\
FAMILIES\\}

由于段落结束前的字体大小已结束,因此在正常基线上设置了大文本。(您可以执行相同的操作,\small并可能进行其他一些大小更改)

答案2

我对您的问题提供更一般的答案:

如何创建参数化版本\doublebox

在没有任何预定义的情况下钩子在现有的宏中,您有三个选择:

  1. 完全重写现有的宏。
  2. 通过使用 LaTeX2e 宏\g@addto@macro或使用包中的类似宏来注入代码etoolbox
  3. 使用现有的宏并添加参数,使用键值接口。

我个人更喜欢 1)和 3)的组合,我将在下面使用 LaTeX 宏\rule作为示例详细解释,这可能对您的特定情况有用。

正常命令的格式如下:

     \rule[<raised>]{<width>}{<height>}   

就我个人而言,我很难记住在调用宏时是width先出现还是先出现height,如果可以设置颜色就更好了。命令形式如下:

   \Rule[rule color = thegray,
            rule thickness = 1pt,
            rule raised = 2pt,
            rule width = 85pt]      

是可取的,因为可以按任何顺序输入键值,还可以在文档开头设置默认值。如果您注意到,我将宏的名称大写,因为如果可能的话,尝试不更改现有宏被认为是一种很好的做法。

我还使用PGF密钥,因为我发现对它们进行编码更快。

\documentclass{article}
\usepackage{pgf}

\definecolor{thegray} {rgb}{0.9,0.9,0.9}
\def\setcolor#1{\color{#1}}

% create family of keys called rule
\pgfkeys{/rule/.is family}
\def\cxset{\pgfqkeys{/rule}}


\cxset{rule width/.store in = \rulewidth@my,
       rule thickness/.store in=\rulethickness@my,
       rule color/.code ={\setcolor{#1}},
       rule raised/.store in = \ruleraised@my
      }

\cxset{rule thickness = 10pt,
       rule raised = 2pt,
       rule width = 45pt}

\newcommand\Rule[1][rule color = thegray,
       rule thickness = 1pt,
       rule raised = 2pt,
       rule width = 85pt]{%
  \colorlet{originalcolor}{.}%
  \cxset{#1}%
  \begingroup
  \rule{\rulewidth@my}{\rulethickness@my}%
  \endgroup
  \color{originalcolor}}

\begin{document}
\Rule

\Rule[rule width=60pt, 
      rule color= purple]

test
\end{document}

看看你是否可以使用这种方法并\doublebox根据你的要求进行修改。如果成功,请发布答案。

答案3

根据好心的卡莱尔先生的建议,下面是我对他出色编码的版本:

\define@key{myfb}{inner}{\def\myfb@inner{#1}}
\define@key{myfb}{outer}{\def\myfb@outer{#1}}
\define@key{myfb}{sep}{\def\myfb@sep{#1}}
\define@key{myfb}{ocolor}{\def\myfb@ocolor{#1}}
\define@key{myfb}{icolor}{\def\myfb@icolor{#1}}
\newcommand\mydoublebox[1][]{%
\def\myfbkeys{\setkeys{myfb}{#1}}%
\VerbBox\@doublebox}
\def\@doublebox#1{%
  \begingroup
    \def\myfb@inner{.75\fboxrule}%
    \def\myfb@outer{2\fboxrule}%
    \def\myfb@sep{\fboxrule+.5pt}%
    \def\myfb@ocolor{black}
    \def\myfb@icolor{black}
    \myfbkeys
    \setbox\@fancybox\hbox{{#1}}%
    \fboxrule\dimexpr\myfb@inner\relax%
    \setbox\@fancybox\hbox{\fcolorbox{\myfb@icolor}{white}{\box\@fancybox}}%
    \fboxrule\dimexpr\myfb@outer\relax%
    \fboxsep\dimexpr\myfb@sep\relax%
    \fcolorbox{\myfb@ocolor}{white}{\box\@fancybox}%
  \endgroup
}

如您所见,我所做的只是添加了两个键,icolorocolor。它们默认为黑色,就像\fboxrule没有替换一样\fbox。这几乎满足了我承认的模糊规格。更棒的是,我在这个过程中学到了很多东西。Xcolor 让我很开心 :)

相关内容