Questions on macro writing in TeX to modify an existing style file: fancybox.sty

I've decided that I must become more adept at TeX if I'm to become proficient with LaTeX. While this is probably obvious to most readers who pass by, my ability to muddle through has hidden this small but important truth. As an example, consider:

% \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
\fbox{\box\@fancybox}%
\endgroup}


This is a snippet from fancybox.sty by Timothy Van Zandt. I wish to clone and improve it (at least by my lights) by adding control over inner and outer rule width, likewise separation as well. To this small wish list I want to add color on a per rule basis. So what's the problem you say? The problem is that I don't understand the above well enough to modify it. In a nutshell, I don't see a way to add parameters to \doublebox in a way that gets through to \@doublebox. For that matter I'm not really sure I understand the calling sequence. As an example consider my title page that I use as a test bed:

\documentclass{article}
\usepackage{modfancybox}
\usepackage{nth}
\begin{document}
\newlength{\fb}
\setlength{\fb}{5.625ex}
\newlength{\myl}
\setlength{\myl}{\textwidth}
\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}


The heart of all of this seems to be:

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


Which somehow seems to pull in the \parbox that follows. Given the setup of \thisfancypage, this certainly makes sense. It also makes it rational to hard-wire the 3 values I want better control over :) That said, I still want my cake and to eat it as well. Adding color seems to be the least of my concerns as there are a number of ways to handle that. And now that I think about it, I could also create the various new lengths to add the control that I want. But that isn't really a solution that works in the long term. I can only get that by increasing my knowledge.

So TLTR: How to a create a parametric version of \doublebox? And what is happening in \thisfancypage? My hope is to be able to get far enough to not only create a newer \doubleboxP but even perhaps a \Nbox as well. For those who dislike such things as somehow violating current typographic standards I apologize, but my likes relate more to the 19th century than to the 21st century :)

-
Please don't call them "style files" just because they have the ".sty" extensions. While this was the original purpose and name they are now called "packages". Most of them don't influence the document style at all. –  Martin Scharrer Jan 26 '13 at 8:32
For starters in \def\doublebox{\VerbBox\@doublebox}, \VerbBox gets \@doublebox as argument as a macro to execute after it has boxed the content. You should be able to simply write e.g. \def\doublebox#1{\VerbBox{\@doublebox{#1}}} or \newcommand\doublebox[1][]{\VerbBox{\@doublebox{#1}}}. However, the look-ahead code for optional arguments will fix the catcode of the first character which follows, which might be an issue. –  Martin Scharrer Jan 26 '13 at 8:37

I'd do something like this to parameterise the macro

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


Also don't do this

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


As that ends the font size before paragraph ends so sets huge text on a normal baseline. (You do the same with \small and possibly some other size changes)

-
Do you mean {size text} should be just size text next size text? No brace enclosure? –  hsmyers Jan 26 '13 at 13:36
No brace or include a blank line or \par before the } The baseline setting can only be set once per paragraph and the value at the end is what counts but the font changes straight away so {\huge one two three} sets big letters without increasing the baseline spacing but {\huge one two three\par} uses an appropriate baseline –  David Carlisle Jan 26 '13 at 14:48

How to a create a parametric version of \doublebox?

In the absence of any pre-defined hooks in an existing macro, you have three choices:

1. Re-write the existing macro fully.
2. Inject code via using the LaTeX2e macro \g@addto@macro or using similar macros from the etoolbox package.
3. Use the existing macro and add parameters, using a key-value interface.

I personally prefer a combination of 1) and 3), which I will explain in detail below using the LaTeX macro \rule as an example, which might come handy for your particular case.

The normal command has the format:

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


Personally, I have trouble remembering if the width comes first or the height when calling the macro, also it would be nice if one can set the color as well. A command of the form:

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


is preferable, as the key values can be typed in any order and also one can set default values at the beginning of a document. If you notice I capitalized the name of the macro as it is considered good practice to try and not change existing macros, if possible.

I also use PGF keys, as I find it quicker to code them.

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


See if you can use this approach and modify \doublebox to your requirements. If you succeed post the answer.

-
I will do so and let you know –  hsmyers Jan 26 '13 at 13:39

As advised by the good Mr Carlisle, here is my version of his excellent coding:

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


As you can see, all I've done is add two more keys, icolor and ocolor. They default to black as they would if \fboxrule were not replacing \fbox. This pretty much meets my admitedly vague specs. And even better, I've learned a fair amount in the process. Xcolor me a happy camper :)

-