![关于在 TeX 中编写宏来修改现有样式文件的问题:fancybox.sty](https://linux22.com/image/261970/%E5%85%B3%E4%BA%8E%E5%9C%A8%20TeX%20%E4%B8%AD%E7%BC%96%E5%86%99%E5%AE%8F%E6%9D%A5%E4%BF%AE%E6%94%B9%E7%8E%B0%E6%9C%89%E6%A0%B7%E5%BC%8F%E6%96%87%E4%BB%B6%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%9Afancybox.sty.png)
我决定,如果要精通 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
?
在没有任何预定义的情况下钩子在现有的宏中,您有三个选择:
- 完全重写现有的宏。
- 通过使用 LaTeX2e 宏
\g@addto@macro
或使用包中的类似宏来注入代码etoolbox
。 - 使用现有的宏并添加参数,使用键值接口。
我个人更喜欢 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
}
如您所见,我所做的只是添加了两个键,icolor
和ocolor
。它们默认为黑色,就像\fboxrule
没有替换一样\fbox
。这几乎满足了我承认的模糊规格。更棒的是,我在这个过程中学到了很多东西。Xcolor 让我很开心 :)