summaryrefslogtreecommitdiff
path: root/macros/generic/midnight/border.tex
diff options
context:
space:
mode:
Diffstat (limited to 'macros/generic/midnight/border.tex')
-rw-r--r--macros/generic/midnight/border.tex319
1 files changed, 319 insertions, 0 deletions
diff --git a/macros/generic/midnight/border.tex b/macros/generic/midnight/border.tex
new file mode 100644
index 0000000000..87403f021a
--- /dev/null
+++ b/macros/generic/midnight/border.tex
@@ -0,0 +1,319 @@
+\ifx\BORDER\relax\endinput\else\let\BORDER=\relax\fi % \input only once
+%
+% border.tex: Macros to typeset borders.
+% version: 1.0 release: 21 October 1991
+%
+% copyright (c) 1991 Marcel R. van der Goot
+% You can use these macros to typeset documents. You may
+% distribute this file freely, provided that you also distribute
+% the accompanying documentation.
+% You may make changes to this file, or extract portions
+% of it for inclusion in other files, provided that
+% (1) you change the name of the file;
+% (2) you give proper credit and include copyright
+% information where applicable;
+% (3) explain how an unchanged version can be obtained; and
+% (4) document the usage of your macros/changes (if usage
+% of your macros is not worth documenting, they must not
+% be worth using).
+% You are not allowed to use the name ``Midnight Macros'' for
+% any changed files.
+% The above rules for making changes do not apply where it
+% is explicitly noted in this file that something can be changed
+% to conform to your local installation.
+%
+% USAGE:
+% See the file border.doc
+%
+% original: csvax.cs.caltech.edu [131.215.131.131] in pub/tex
+% (use anonymous ftp). Also in various archives.
+%
+% Caltech, Pasadena --- Marcel van der Goot
+% marcel@cs.caltech.edu
+% Caltech 256--80
+% Pasadena, CA 91125
+% USA
+% (818) 356--4603
+%
+
+% update history:
+% version 1.0: This one.
+% release 21 Oct 1991: The original
+%
+
+%%%%%% CODE: (you don't need to read this to use the macros)
+
+\edef\borderelm{\the\catcode`\_} % minor trick to remember the catcode
+\catcode`\_=11% letter, to make private macros
+
+% Note: we use \box0, \box2, \box4, \dimen0, \dimen2, and \count2, rather than
+% allocating new boxes, dimensions, and counts. That is usually ok because all
+% assignments are done within \hbox{...} or \vbox{...}, which provides
+% grouping.
+
+%%%%%%% exactly fitting border with overlaps
+% \border makes a border of the specified dimensions, by overlapping some
+% of the elements when necessary.
+% \hborder takes four arguments, the width, and the indices of the left
+% element, the middle element, and the right element. It makes an horizontal
+% border of the form \hbox to wd{ l m+ r }, where there is at least one m.
+% If wd is large enough to set at least {l m r}, all overlap is between
+% elements of type m. In the unusual case where wd is too small, the overlap
+% is necessarily with the corner elements.
+
+\def\hborder#1#2#3#4% wd, l, m, r
+ {\hbox to#1
+ {\setbox0=\hbox{\borderelm#3}%
+ \borderelm#2%
+ \hskip0pt minus1fil %
+ \copy0\kern-.5\wd0 %
+ \cleaders\copy0\hskip0pt plus1fil %
+ \kern-.5\wd0\copy0 %
+ \hskip0pt minus1fil %
+ \borderelm#4%
+ }%
+ }
+
+% \border does the vertical equivalent of \hborder: the top and bottom
+% elements are hboxes generated with \hborder, and the middle element is
+% an \hbox{ l \hss r }. This middle element is again used at least once,
+% and if possible all overlap will be among middle elements.
+% The \kern0sp at the end is to get depth 0, rather than the depth of
+% the last hbox. (\boxmaxdepth is set to the largest possible value to make
+% sure that the depth is indeed 0, not negative.)
+
+\def\border#1#2% ht, wd
+ {\vbox to#1
+ {\offinterlineskip\boxmaxdepth=\maxdimen
+ \dimen2=#2
+ \setbox0=\hbox to\dimen2{\borderelm3\hss\borderelm4}
+ \dimen0=\ht0 \advance\dimen0 by\dp0
+ \hborder{\dimen2}012
+ \vskip0pt minus1fil
+ \copy0\kern-.5\dimen0
+ \cleaders\copy0\vskip0pt plus1fil
+ \kern-.5\dimen0\copy0
+ \vskip0pt minus1fil
+ \hborder{\dimen2}567
+ \kern0sp
+ }%
+ }
+
+%%%%%%% exactly fitting border with spaces
+% \xborder also makes a border of the specified dimensions, but rather than
+% overlapping elements, it leaves space between the elements.
+% \xhborder makes a horizontal border. Unlike \hborder, there are zero (not
+% one) or more middle elements. The extra space is equally distributed
+% between all the elements.
+
+\def\hxborder#1#2#3#4% wd, l, m, r
+ {\hbox to#1
+ {\setbox0=\hbox{\borderelm#3}%
+ \borderelm#2%
+ \xleaders\copy0\hskip0pt plus1fil minus1fil %
+ \borderelm#4%
+ }%
+ }
+
+% \xborder is to \hxborder as \border is to \hborder.
+
+\def\xborder#1#2% ht, wd
+ {\vbox to#1
+ {\offinterlineskip\boxmaxdepth=\maxdimen
+ \dimen2=#2
+ \setbox0=\hbox to\dimen2{\borderelm3\hss\borderelm4}
+ \hxborder{\diemn2}012
+ \xleaders\copy0\vskip0pt plus1fil minus1fil
+ \hxborder{\dimen2}567
+ \kern0sp
+ }%
+ }
+
+%%%%%%% rounded border with abutting elements
+% \plusborder and \minusborder make borders with abutted elements (no
+% overlaps, no spaces). To make this possible, the border dimensions are
+% rounded so that an integral number of elements fits. \plusborder rounds
+% up, \minusborder rounds down. \plusgray and \minusgray are similiar, except
+% that \borderelm8 is used as center element (normally the center is white).
+% \plus_border and \minus_border are used for both, where the 3rd argument
+% indicates whether there is a center element.
+
+% The computation consists of determining the space D that has to be
+% filled with middle elements. If the width of the middle element is d,
+% there fit (D div d) middle element in a `minus border.'
+% To avoid minor inaccuracies in the arithmetic, what we actually do is
+% (D+100sp) div d. 100sp is so small as to be invisible.
+
+\def\hminusborder#1#2#3#4% wd, l, m, r
+ {\hbox
+ {\dimen0=#1\count2=\dimen0 %
+ \setbox0=\hbox{\borderelm#2}\advance\count2 by-\wd0 %
+ \setbox0=\hbox{\borderelm#4}\advance\count2 by-\wd0 %
+ \setbox0=\hbox{\borderelm#3}%
+ \advance\count2 by100 %
+ \divide\count2 by\wd0 %
+ \borderelm#2%
+ \cleaders\copy0\hskip\count2\wd0 %
+ \borderelm#4%
+ }%
+ }
+
+\def\minus_border#1#2#3% ht, wd, #3=empty ==> no center element
+ {\vbox
+ {\offinterlineskip\boxmaxdepth=\maxdimen
+ \dimen2=#2\relax
+ \dimen0=#1\count2=\dimen0
+ \setbox0=\hminusborder{\dimen2}012
+ \advance\count2 by-\ht0 \advance\count2 by-\dp0
+ \setbox2=\hminusborder{\dimen2}567
+ \advance\count2 by-\ht2 \advance\count2 by-\dp2
+ \if.#3.\setbox4=\hbox to\wd0{\borderelm3\hss\borderelm4}
+ \else \setbox4=\hminusborder{\dimen2}384
+ \fi
+ \advance\count2 by100
+ \dimen0=\ht4\advance\dimen0 by\dp4
+ \divide\count2 by\dimen0
+ \box0
+ \cleaders\copy4\vskip\count2\dimen0
+ \box2
+ \kern0sp
+ }%
+ }
+
+\def\minusborder#1#2{\minus_border{#1}{#2}{}}
+
+\def\minusgray#1#2{\minus_border{#1}{#2}{1}}
+
+
+% Rounding upwards is achieved with (D + d - 1) div d, but again, we
+% actually do (D + d - 100sp) div d.
+
+\def\hplusborder#1#2#3#4% wd, l, m, r
+ {\hbox
+ {\dimen0=#1\count2=\dimen0 %
+ \setbox0=\hbox{\borderelm#2}\advance\count2 by-\wd0 %
+ \setbox0=\hbox{\borderelm#4}\advance\count2 by-\wd0 %
+ \setbox0=\hbox{\borderelm#3}%
+ \advance\count2 by\wd0\advance\count2 by-100 %
+ \divide\count2 by\wd0 %
+ \borderelm#2%
+ \cleaders\copy0\hskip\count2\wd0 %
+ \borderelm#4%
+ }%
+ }
+
+\def\plus_border#1#2#3% ht, wd, #3=empty ==> no center element
+ {\vbox
+ {\offinterlineskip\boxmaxdepth=\maxdimen
+ \dimen2=#2\relax
+ \dimen0=#1\relax\count2=\dimen0
+ \setbox0=\hplusborder{\dimen2}012
+ \advance\count2 by-\ht0 \advance\count2 by-\dp0
+ \setbox2=\hplusborder{\dimen2}567
+ \advance\count2 by-\ht2 \advance\count2 by-\dp2
+ \if.#3.\setbox4=\hbox to\wd0{\borderelm3\hss\borderelm4}
+ \else\setbox4=\hplusborder{\dimen2}384
+ \fi
+ \dimen0=\ht4\advance\dimen0 by\dp4
+ \advance\count2 by\dimen0\advance\count2 by-100
+ \divide\count2 by\dimen0
+ \box0
+ \cleaders\copy4\vskip\count2\dimen0
+ \box2
+ \kern0sp
+ }%
+ }
+
+\def\plusborder#1#2{\plus_border{#1}{#2}{}}
+
+\def\plusgray#1#2{\plus_border{#1}{#2}{1}}
+
+%%%%%%% border example (rounded corners)
+% This example creates a border with rounded corners. The corners are taken
+% from the manfnt font, as described in The TeXbook, p.389. However, we
+% reposition them in their boxes, as their original position is inconvenient:
+% We want tight-fitting boxes, because the boxes determine the border width
+% and height. The original position is described in The TeXbook.
+
+% If \manfnt is already defined, we do not redefine it.
+\ifx\manfnt\UNDEFINED
+\font\manfnt=manfnt
+\fi
+
+% \roundcorners is a bit messy, but that is not so important.
+% Just so that you can use \minusgray and \plusgray, we added a center
+% character (just some random character from the font). That meant that the
+% left and right character had to be given widths equal to the corner elements.
+% \roundcorners scales properly with \manfnt.
+
+\def\roundcorners#1% use as \borderelm
+ {{\manfnt
+ \setbox2=\hbox{\char'44}% for demonstration purposes
+ \ifcase#1
+ \setbox0=\hbox{d}% lu
+ \hbox to\ht0{\vbox to\fontdimen8\font{\vss\box0}\hss}%
+ \or\hbox{\vrule width\wd2 height\fontdimen8\font depth0pt\hss}% u=d
+ \or\setbox0=\hbox{a}% ru
+ \hbox to\ht0{\kern\dp0\vbox to\fontdimen8\font{\vss\box0}\hss}%
+ \or\setbox0=\hbox{d}%
+ \hbox to\ht0{\vrule width\fontdimen8\font height\ht2 depth\dp2\hss}% l
+ \or\setbox0=\hbox{d}%
+ \hbox to\ht0{\hss\vrule width\fontdimen8\font height\ht2 depth\dp2}% r
+ \or\setbox0=\hbox{c}% ld
+ \hbox to\ht0{\vbox{\copy0\kern-\dp0}\hss}%
+ \or\hbox{\vrule width\wd2 height\fontdimen8\font depth0pt\hss}% d=u
+ \or\setbox0=\hbox{b}% rd
+ \hbox to\ht0{\kern\dp0\vbox{\copy0\kern-\dp0}\hss}%
+ \or\box2 % center character
+ \fi
+ }}
+
+%%%%%%% centering text within a border
+% \setborder[bwd, hspace, vspace]\bordermacro uses \bordermacro (one of
+% \border, \xborder, etc.) to typeset a border. The width of the border is bwd,
+% the height of the border depends on the amount of text within the border.
+% This text is read and typeset in a vbox, with the hsize set so that the
+% width has the appropriate value. This is done in a somewhat convoluted way
+% with \afterassignment to set the hsize, and \aftergroup to create the border.
+% The reason is that now the text is not read as an argument of \setborder,
+% which is important, for instance, if the text contains catcode changes.
+% We did not write \setborder[#1,#2,#3]#4#{ , which would have ensured that a
+% brace follows: that would have required an explicit brace, whereas now you
+% can also use \bgroup (useful if you want to put \setborder in some other
+% macro).
+
+\newbox\brd_txt
+\newbox\brd_box
+
+\def\setborder[#1,#2,#3]#4% wd, hspace, vspace, bordermacro
+ {\def\brd_inbox
+ {\hsize=#1
+ \advance\hsize by-#2
+ \advance\hsize by-#2
+ \aftergroup\set_border
+ }%
+ \def\set_border
+ {\setbox\brd_txt=\vbox
+ {\vskip#3
+ \box\brd_txt
+ \vskip#3
+ }%
+ \setbox\brd_box=#4{\ht\brd_txt}{#1}%
+ \vbox to\ht\brd_box
+ {\copy\brd_box \kern-\ht\brd_box
+ \vss
+ \hbox to\wd\brd_box{\hss\box\brd_txt\hss}
+ \vss
+ }%
+ }%
+ \afterassignment\brd_inbox
+ \setbox\brd_txt=\vbox
+ }
+
+
+%%%%%%% initialization
+
+\catcode`\_=\borderelm % restore catcode
+
+\let\borderelm=\roundcorners % only reasonable initialization
+