The formular Package.^{∗}

Hans-Christoph Wirth hcw@gmx.de

2001/04/05

This package provides some commands useful for typesetting fields in formulars which are intended to be filled either manually or using TEX.

% Copyright 2001 Hans-Christoph Wirth (hcw@gmx.de)
%
% This program/package may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.2
% of this license or (at your option) any later version.
% The latest version of this license is available at
%   http://www.latex-project.org/lppl.txt
% and version 1.2 or later is part of all distributions of LaTeX
% version 1999/12/01 or later.
%
% The quintessence of LPPL is:
% - Distribute the package only in its full contents
% - If you modify any files, rename them before
%
% This program/package consists of the files
%   formular.ins  (driver file)
%   formular.dtx  (source and documentation)
%   formular.sty  (actual style file, generated)
%   formular.dvi  (documentation, generated)

1 Examples

When typesetting forms there often arises the need for defining fields which consists of one or more lines where the customer can write something down manually. To support a unique appearance of those fields we contribute some commands which define general fields.

1.1 One-line Fields

The following piece of code declares and uses a simple one-line field namef:

∗This file has version number v1.0 (c) 2001 by Hans-Christoph Wirth, dated 2001/04/05.

     \newFRMfield{namef}{15mm}
     This is \useFRMfield{namef}[John]
         and \useFRMfield{namef}.

The output is the following:

This is \underline{John} and .

More complicated fields may have a description and a default content.

     \newFRMfield{namef}{15mm}[Name][nobody]
     This is \useFRMfield{namef}[John]
         and \useFRMfield{namef}
         and \useFRMfield{namef}[]
         and \useFRMfield{namef}[Fred Long Name]

Notice that the field growths with the content:

This is \frac{John}{Name} and \frac{nobody}{Name} and \overline{Name} and \frac{Fred Long Name}{Name}

1.2 Different Styles

Each class of fields can have its own font style. Additionally there is a ruled style implemented. In the following we declare two one-line fields with different appearance:

     \newFRMfield{placef}{40mm}[Place]
     \setFRMfontfamily{cmr}
     \setFRMfontshape{it}
     \setFRMfontsize{12}
     \setFRMruledstyle
     \newFRMfield{sigf}{30mm}[Signature]
     \useFRMfield{placef}[Sometown], \useFRMfield{sigf}[U. N. Known]

\frac{Sometown}{Place} , U. N. Known_{Signature}

1.3 Multi-line Environments

The following piece of code declares and uses two multi-line environments. Notice that there are two styles: The description of the field may appear on a separate line or not. Each environment has a description and a minimal number of lines.

     \setFRMbreakstyle
     \newFRMenvironment{env1}{Foobar}{2}

\setFRMinlinestyle
\newFRMenvironment{env2}{Barfoo}{3}
\begin{env1} This is break style \end{env1}
\begin{env2} This is inline style \end{env2}

This is break style Foobar

   This is inline style

\underline{Barfoo}

1.4 Containers

A container is a collection of fields. The container specifies which fields belong to it, and where the fields are to be printed. The following piece of code declares a container which contains three fields.

\newFRMcontainer{Grades}
  {\setFRMruledstyle
   \newFRMfield{Ma}{30mm}[][////]
   \newFRMfield{Ph}{30mm}[][////]
   \newFRMfield{En}{30mm}[english grade][////]
  }{%
   \parbox[t]{0.45\linewidth}{\baselineskip18pt
      Maths   \dotfill\ \useFRMfield{Ma}\newline
      Physics \dotfill\ \useFRMfield{Ph}}\hfill
   \parbox[t]{0.45\linewidth}{%
      English  \dotfill\ \useFRMfield{En}}%
   }
\begin{Grades}
 \setMa{excellent}
 \setPh{very good}
\end{Grades}

Maths . . . . .  excellent
Physics . . . . .  very good

English . . . . .  ////_{english grade}

2 Command Description

2.1 Style Parameters

The commands explained in this section select the general appearance of the fields. A call to a command affects all fields which are declared subsequently (within the same scope).

\setFRMrulewidth The command
     \setFRMrulewidth{⟨dimen⟩}

sets the thickness of the underlining rules to ⟨dimen⟩ (default: 0.1pt). The instruction \setFRMrulewidth{0pt} makes rules disappear.

\setFRMrulesep The command
     \setFRMrulesep{⟨dimen⟩}

sets the vertical distance between the font baseline and the underlining rules (default: 2pt).

\setFRMmargin The command
     \setFRMmargin{⟨dimen⟩}

sets the horizontal indentation of the content of multi-line FRMenvironments (default: 5pt).

\setFRMbaselineskip The command
     \setFRMbaselineskip{⟨dimen⟩}

sets the baselineskip of the content of multi-line FRMenvironments (default: 18pt).

\setFRMfontencoding The \setFRMfont… commands select the font used for the content, and the corre-

\setFRMfontsize
\setFRMfontfamily
\setFRMfontseries
\setFRMfontshape

sponding \setFRMdfont… commands select the font of the description of one-line fields. For a description of the meaning of the parameters we refer to command \usefont in standard L^{A}TEX2e documentation. Notice that \setFRMfontsize has only one parameter, since the baselineskip is selected with a separate command.

All above commands can be supplied with an optional parameter specifying a (already declared) field. This enables to change the appearance of fields after declaration. The following example illustrates this:

     \newFRMfield{foo}{3cm}
     \setFRMfontsize[foo]{20pt}

To this end, there are some more commands which have only effect when this optional parameter is supplied:

\setFRMcontent The commands
\setFRMdescription
\setFRMwidth        \setFRMcontent[⟨field⟩]{⟨content⟩}
     \setFRMdescription[⟨field⟩]{⟨content⟩}

set the (default) content and the description of the field, while

     \setFRMwidth[⟨field⟩]{⟨width⟩}

changes the (minimal) width.

2.2 One-line Fields

A FRMfield consists of three ingredients:

1. The content of the field. This is a (maybe empty) one-line string.

2. A horizontal rule. The length of the rule is at least the minimal width of the field, but it grows with the content or the description. It is guaranteed that the rule exceeds the content at least by the amount which is set with

\setFRMmargin.

3. The description. This is a (maybe empty) one-line string printed below the rule.

\newFRMfield A FRMfield must be declared as follows:

\newFRMfield{⟨field id⟩}{⟨width⟩}

\newFRMfield{⟨field id⟩}{⟨width⟩}[⟨description⟩] \newFRMfield{⟨field id⟩}{⟨width⟩}[⟨description⟩][⟨default content⟩]

The field is associated with the style setting which is valid at this moment.

\useFRMfield When a field is declared, it can be used with the command

\useFRMfield{⟨name⟩}
\useFRMfield{⟨name⟩}[⟨content⟩]

If the ⟨content⟩ is not supplied to \useFRMfield, then the ⟨default content⟩ is printed.

\renewFRMfield The macro \renewFRMfield is nearly the same as \newFRMfield, but it changes

an existing field rather than defining a new one.

\setFRMruledstyle Besides the style parameters discussed above, the user has the additional choice \setFRMplainstyle between the following two styles: With

\setFRMplainstyle

the content is underlined by a single rule. With

\setFRMruledstyle

the content is printed over a field of rules. The height of the ruled field adjusts automatically to the current font size.

2.3 Multi-line Environments

A FRMenvironment consists of three ingredients:

1. The content of the field. This is a (possibly empty) text.

2. A collection of rules which underline the content.

3. The description. This is a one-line string printed at the beginning of the environment.

\newFRMenvironment A FRMenvironment must be declared as follows:

\newFRMenvironment{⟨envid⟩}{⟨description⟩}{⟨default lines⟩}

As one may expect, the current style settings are associated with the environment from this point on. The FRMenvironment is used in the following way:

\begin{⟨envid⟩} ⟨content⟩ \end{⟨envid⟩}

\begin{⟨envid⟩}[⟨lines⟩] ⟨content⟩ \end{⟨envid⟩}

This will print a FRMenvironment with description ⟨description⟩ and content ⟨content⟩. The environment extends to at least ⟨default lines⟩ many lines (or to ⟨lines⟩ lines, if the optional argument is supplied). If the ⟨content⟩ does not fit into this space, the environment is further extended and a warning is issued.

\setFRMbaselineskip The baselineskip of the content can be adjusted with

     \setFRMbaselineskip{⟨dimen⟩}

\setFRMmargin The indentation of the content can be adjusted with

     \setFRMmargin{⟨dimen⟩}

It defaults to 5pt.

\setFRMbreakstyle There are two styles implemented: The content may start in the same line as the \setFRMinlinestyle description (\setFRMinlinestyle), or the description may appear on its own line

(\setFRMbreakstyle). Notice that in break style, the description’s line is not counted within the line range.

2.4 Containers

A FRMcontainer is a simple way to collect several FRMfields into one logical unit. The container defines the set of fields, their default content, and how to print the individual fields. This definition can go to the preamble of the document.

The content of the container will usually consist solely of commands which set the field’s content. So the user must not care about the actual typesetting of the fields.

\newFRMcontainer The command

\newFRMcontainer{⟨cid⟩}{⟨init code⟩}{⟨apply code⟩}

defines a new container ⟨cid⟩. The container will be used afterwards like a environment

\begin{⟨cid⟩} ⟨container content⟩ \end{⟨cid⟩}

The ⟨init code⟩ may contain any code needed for setup of the container. In particular, one may employ at this point:

• All style setting commands \setFRM… of this package

Notice that the container always initializes the settings to the situtation which was valid when the call to \newFRMcontainer happens. This ensures that multiple calls to the same container always appear in the same style.

• The command \newFRMfield to declare local fields.

\set... Within the ⟨init code⟩ of a container, a call to \newFRMfield{⟨field⟩} defines one more command, namely \set⟨field⟩. The command

\set⟨field⟩{⟨content⟩}

is a convenient shortcut for

     \setFRMcontent[⟨field⟩]{⟨content⟩}

It may be used in the content of the container to define the content of the individual fields. (See example in Section 1.4.)

3 The Implementation

 1 \NeedsTeXFormat{LaTeX2e}
 2 \ProvidesPackage{formular}[\filedate \space \fileversion]

3

 4 \RequirePackage{xspace}
 5 \def\FRM@err{\PackageError{formular}}
 6 \def\FRM@warn{\PackageWarning{formular}}

7

 8 \newlength\frm@margin
 9 \newlength\frm@baselineskip
10 \newbox\frm@namebx
11 \newbox\frm@contbx
12 \newcount\frm@cnt
13 \newcount\frm@lbound
14 \newif\iffrm@breakstyle
15 \newif\iffrm@ruledstyle

3.1 Global defaults

The current and global settings are stored internally in \frm@.... The settings of individual field ⟨f ⟩ is stored in \frm@⟨f ⟩@....

Auxiliary macros to define the \setFRM… commands. Those commands, when called with optional argument containing a field id, must check whether the field is declared and then modify its settings.

16 \newcommand{\FRM@generatesetcommand}[1]{%

17 \expandafter
18 \newcommand\expandafter{\csname setFRM#1\endcsname}[2][]{%
19  \ifx##1\relax\relax
20  \expandafter\def\csname frm@#1\endcsname{##2}\else
21  \@ifundefined{frm@##1@content}
22  {\FRM@err{FRMfield `##1' not declared.}}{%
23  \expandafter\def\csname frm@##1@#1\endcsname{##2}}\fi

24 } 25 }

This is for the handling of \setFRM...style commands. The call

\FRM@generatesetstylecommand{⟨a⟩}{⟨b⟩}{⟨c⟩}

generates \setFRM⟨a⟩style which itself will let \iffrm@⟨b⟩style to be \if⟨c⟩. For individual fields, the \if... are stored in one macro only.

26 \newcommand{\FRM@generatesetstylecommand}[3]{%
27 \expandafter
28 \newcommand\expandafter{\csname setFRM#1style\endcsname}[1][]{%
29  \ifx##1\relax\relax
30  \csname frm@#2style#3\endcsname \else
31  \@ifundefined{frm@##1@content}
32  {\FRM@err{FRMfield `##1' not declared.}}{%
33  \expandafter\let\csname iffrm@##1@#2style\expandafter
34  \endcsname \csname if#3\endcsname }\fi

35 } 36 }

This is for the handling of \setFRM... counters and lengths. Since we do not want to waste registers, we store the contents of registers in macros (rather than in registers) for the individual fields.

37 \newcommand{\FRM@generatesetlengthcommand}[1]{%
38 \expandafter
39 \newcommand\expandafter{\csname setFRM#1\endcsname}[2][]{%
40  \ifx##1\relax\relax
41  \csname frm@#1\endcsname=##2\relax \else
42  \@ifundefined{frm@##1@content}
43  {\FRM@err{FRMfield `##1' not declared.}}{%
44  \expandafter\def\csname frm@##1@#1\endcsname{##2}}\fi

45 } 46 }

The first two commands generated have no effect if called without the optional parameter.

47 \FRM@generatesetcommand{content}
48 \FRM@generatesetcommand{description}

Thickness of all rules

49 \FRM@generatesetcommand{rulewidth}
50 \setFRMrulewidth{0.1pt}

Vertical distance between baseline and an underlining rule

51 \FRM@generatesetcommand{rulesep}
52 \setFRMrulesep{2pt}

3.2 Defaults for one-line environments

Style of a one-line environment

53 \FRM@generatesetstylecommand{plain}{ruled}{false}
54 \FRM@generatesetstylecommand{ruled}{ruled}{true}

Default width of fields (not user accessible)

55 \def\frm@width{0pt}

3.3 Defaults for multi-line environments

Indentation of the content of a multi-line environment

56 \FRM@generatesetlengthcommand{margin}
57 \setFRMmargin{5pt}

\baselineskip within a multi-line environment

58 \FRM@generatesetlengthcommand{baselineskip}
59 \setFRMbaselineskip{18pt}

Style of a multi-line environment

60 \FRM@generatesetstylecommand{break}{break}{true}
61 \FRM@generatesetstylecommand{inline}{break}{false}

Default number of lines (not user accessible)

62 \frm@lbound=0

3.4 Font selection for the fields

Font shape of the content of all fields

63 \FRM@generatesetcommand{fontencoding}
64 \FRM@generatesetcommand{fontsize}
65 \FRM@generatesetcommand{fontfamily}
66 \FRM@generatesetcommand{fontseries}
67 \FRM@generatesetcommand{fontshape}
68 \setFRMfontencoding{T1}
69 \setFRMfontsize{10}
70 \setFRMfontfamily{cmtt}
71 \setFRMfontseries{m}
72 \setFRMfontshape{n}

Font shape of the description of one-line fields

73 \FRM@generatesetcommand{dfontencoding}
74 \FRM@generatesetcommand{dfontsize}
75 \FRM@generatesetcommand{dfontfamily}
76 \FRM@generatesetcommand{dfontseries}
77 \FRM@generatesetcommand{dfontshape}
78 \setFRMdfontencoding{T1}
79 \setFRMdfontsize{6}
80 \setFRMdfontfamily{cmss}

 81 \setFRMdfontseries{m}
 82 \setFRMdfontshape{n}

3.5 Auxiliary Macros for saving and restoring the settings

Store the current settings for a individual field. All TEX registers are also stored in macros.

 83 \newcommand{\FRM@storeappearance}[1]{%
 84 \expandafter\let\csname frm@#1@content\endcsname \frm@content
 85 \expandafter\let\csname frm@#1@description\endcsname \frm@description
 86 \expandafter\let\csname iffrm@#1@breakstyle\endcsname \iffrm@breakstyle
 87 \expandafter\let\csname iffrm@#1@ruledstyle\endcsname \iffrm@ruledstyle
 88 \expandafter\let\csname frm@#1@width\endcsname \frm@width
 89 \expandafter\let\csname frm@#1@rulewidth\endcsname \frm@rulewidth
 90 \expandafter\let\csname frm@#1@rulesep\endcsname \frm@rulesep
 91 \expandafter\edef\csname frm@#1@lbound\endcsname{\the\frm@lbound}
 92 \expandafter\edef\csname frm@#1@baselineskip\endcsname{\the\frm@baselineskip}
 93 \expandafter\edef\csname frm@#1@margin\endcsname{\the\frm@margin}
 94 \expandafter\let\csname frm@#1@fontfamily\endcsname \frm@fontfamily
 95 \expandafter\let\csname frm@#1@fontseries\endcsname \frm@fontseries
 96 \expandafter\let\csname frm@#1@fontsize\endcsname \frm@fontsize
 97 \expandafter\let\csname frm@#1@fontshape\endcsname \frm@fontshape
 98 \expandafter\let\csname frm@#1@fontencoding\endcsname \frm@fontencoding
 99 \expandafter\let\csname frm@#1@dfontfamily\endcsname \frm@dfontfamily
100 \expandafter\let\csname frm@#1@dfontseries\endcsname \frm@dfontseries
101 \expandafter\let\csname frm@#1@dfontsize\endcsname \frm@dfontsize
102 \expandafter\let\csname frm@#1@dfontshape\endcsname \frm@dfontshape
103 \expandafter\let\csname frm@#1@dfontencoding\endcsname \frm@dfontencoding

104 }

Load the current settings from a individual field. All TEX registers which were stored in macros are retransformed into registers.

105 \newcommand{\FRM@restoreappearance}[1]{%
106 \expandafter\let\expandafter\frm@content
107  \csname frm@#1@content\endcsname
108 \expandafter\let\expandafter\frm@description
109  \csname frm@#1@description\endcsname
110 \expandafter\let\expandafter\iffrm@breakstyle
111  \csname iffrm@#1@breakstyle\endcsname
112 \expandafter\let\expandafter \iffrm@ruledstyle
113  \csname iffrm@#1@ruledstyle\endcsname

114 %

115 \expandafter\let\expandafter\frm@width
116  \csname frm@#1@width\endcsname
117 \expandafter\let\expandafter\frm@rulewidth
118  \csname frm@#1@rulewidth\endcsname
119 \expandafter\let\expandafter\frm@rulesep
120  \csname frm@#1@rulesep\endcsname

121 %

122 \expandafter
123  \frm@lbound\expandafter=\csname frm@#1@lbound\endcsname
124 \expandafter

125  \frm@baselineskip=\csname frm@#1@baselineskip\endcsname
126 \expandafter
127  \frm@margin=\csname frm@#1@margin\endcsname

128 %

129 \expandafter\let\expandafter\frm@fontencoding
130  \csname frm@#1@fontencoding\endcsname
131 \expandafter\let\expandafter\frm@fontseries
132  \csname frm@#1@fontseries\endcsname
133 \expandafter\let\expandafter\frm@fontshape
134  \csname frm@#1@fontshape\endcsname
135 \expandafter\let\expandafter\frm@fontsize
136  \csname frm@#1@fontsize\endcsname
137 \expandafter\let\expandafter\frm@fontfamily
138  \csname frm@#1@fontfamily\endcsname

139 %

140 \expandafter\let\expandafter\frm@dfontencoding
141  \csname frm@#1@dfontencoding\endcsname
142 \expandafter\let\expandafter\frm@dfontseries
143  \csname frm@#1@dfontseries\endcsname
144 \expandafter\let\expandafter\frm@dfontshape
145  \csname frm@#1@dfontshape\endcsname
146 \expandafter\let\expandafter\frm@dfontsize
147  \csname frm@#1@dfontsize\endcsname
148 \expandafter\let\expandafter\frm@dfontfamily
149  \csname frm@#1@dfontfamily\endcsname

150 }

Shorthands for actually switching to the font settings

151 \newcommand{\FRM@selectfont}{%
152 \fontsize{\frm@fontsize}{\the\frm@baselineskip}%
153 \usefont{\frm@fontencoding}{\frm@fontfamily}
154  {\frm@fontseries}{\frm@fontshape}%

155 }

156 \newcommand{\FRM@selectdfont}{%
157 \fontsize{\frm@dfontsize}{\the\frm@baselineskip}%
158 \usefont{\frm@dfontencoding}{\frm@dfontfamily}
159  {\frm@dfontseries}{\frm@dfontshape}%

160 }

3.6 One-line fields

\newFRMfield Parameter list: #1 field id #2 minimum field width #3 description (optional) #4 default content (optional)

161 \newcommand{\newFRMfield}[1]{%
162 \@ifundefined{frm@#1@content}
163  {\new@FRMfield{#1}}{\FRM@err{cannot
164  \string\new... existing field `#1'}}

165 }

166 \newcommand{\renewFRMfield}[1]{%

167 \@ifundefined{frm@#1@content}
168  {\FRM@err{cannot \string\renew... undeclared
169  field `#1'}}{\new@FRMfield{#1}}

170 }

\new@FRMfield We first must fiddle around with the two optional parameters. Then we set the default values (if any) and store all settings of the individual field.

171 \def\new@FRMfield#1#2{%
172 \@ifnextchar[%]
173 {\new@FRMfield@{#1}{#2}}{\new@FRMfield@@{#1}{#2}[][]}}
174 \def\new@FRMfield@#1#2[#3]{%
175 \@ifnextchar[%]
176 {\new@FRMfield@@{#1}{#2}[#3]}{\new@FRMfield@@{#1}{#2}[#3][]}}
177 \def\new@FRMfield@@#1#2[#3][#4]{%
178 \def\frm@width{#2}
179 \def\frm@description{#3}
180 \def\frm@content{#4}
181 \FRM@storeappearance{#1}
182 \new@FRMcontainerhook{#1}

183 }

The hook is used by \newFRMcontainer to define the \set... shortcut afterwards.

184 \let\new@FRMcontainerhook\@gobble
185 \def\new@FRMfieldspecials#1{%
186 \expandafter\def\csname set#1\endcsname##1{\setFRMcontent[#1]{##1}}
187 %  \expandafter\def\csname use#1\endcsname{\useFRMfield{#1}\relax}

188 }

\useFRMfield Parameter list: #1 field id #2 field content (optional)

189 \newcommand{\useFRMfield}[1]{%
190 \@ifundefined{frm@#1@content}
191  {\FRM@err{FRMfield `#1' is not declared.}}
192  {\use@FRMfield{#1}}

193 }

194 \def\use@FRMfield#1{%
195 \@ifnextchar[%]
196  {\use@FRMfield@{#1}}
197  {\use@FRMfield@{#1}[\csname frm@#1@content\endcsname]\xspace}

198 }

This macro does the actual typesetting job. We must open a group to keep changes to the current settings (via \FRM@restore...) locally.

199 \def\use@FRMfield@#1[#2]{\begingroup
200 \FRM@restoreappearance{#1}%
201 \setbox\frm@contbx=\hbox{%
202  \FRM@selectfont
203  \kern\frm@margin #2\kern\frm@margin}%
204 \dp\frm@contbx0pt\relax

The baseline of the final field is the baseline of the content and has depth extending to the underlining rule. This makes alignment of more than one field on the same line less complex.

205 \leavevmode
206 \vtop to \frm@rulesep{%
207  \halign{\hfil##\hfil\cr
208  \usebox{\frm@contbx}\cr
209  \noalign{\kern\frm@rulesep
210  \iffrm@ruledstyle
211  \dimen0=\frm@fontsize pt\dimen2=0pt\relax
212  \loop
213  \kern-2pt\advance\dimen2 by 2pt%
214  \hrule height\frm@rulewidth \kern-\frm@rulewidth
215  \advance\dimen0 by-2pt%
216  \ifnum\dimen0>0%
217  \repeat
218  \kern\dimen2\relax
219  \fi
220  \hrule height\frm@rulewidth depth0pt \kern2pt}%
221  \FRM@selectdfont \frm@description\cr
222  \vrule width \frm@width height 0pt\cr}\vss
223  }\endgroup

224 }

3.7 Multi-line fields

\newFRMenvironment Parameter list:

#1 environment id #2 description #3 number of lines

225 \newcommand{\newFRMenvironment}[3]{%
226 \def\frm@description{#2}%
227 \frm@lbound=#3\relax
228 \FRM@storeappearance{env@#1}%
229 \newenvironment{#1}{%
230  \FRM@restoreappearance{env@#1}%
231  \@ifnextchar[%]
232  {\FRM@openenvironment}
233  {\FRM@openenvironment[\the\frm@lbound]}%
234  }{%
235  \FRM@closeenvironment%

236 }% 237 }

 Define the \begin{} part of the FRMenvironment.
238 \def\FRM@openenvironment[#1]{%
239 \frm@lbound=#1\relax

Set the description of the environment. If the current style is a break style, then extend the box to \hsize. The top line gets a “strut” of height \frm@baselineskip minus \frm@rulesep. The lowest line will have depth \frm@rulesep. Hence multiple environments fit smoothly to each other.

240 \setbox\frm@namebx\hbox
241  \iffrm@breakstyle to\hsize\fi
242  {\frm@description\enspace
243  \skip0=\frm@baselineskip \advance\skip0-\frm@rulesep
244  \vrule width0pt height \skip0\hfil}%

Start the box containing the body.

245 \setbox\frm@contbx=\vtop\bgroup
246 \advance\hsize-2\frm@margin

Leave out the horizontal space needed for the description. If the description extends the whole line, allow for a line break after this.

247 \hskip-\frm@margin
248 \hskip\wd\frm@namebx
249 \hskip-\frm@margin\penalty0\relax
250 \hskip2\frm@margin
251 \FRM@selectfont

252 }

Define the \end{} part of the environment.

253 \newcommand{\FRM@closeenvironment}{%

Close the content box and count the number of lines below the baseline. Set the box with depth zero.

254 \par\egroup
255 \frm@cnt=\dp\frm@contbx
256 \dimen0=\frm@baselineskip
257 \divide\frm@cnt\dimen0\relax
258 \leavevmode\rlap{\dp\frm@contbx0pt \kern\frm@margin \usebox\frm@contbx}%

Now set the rules box. It must be shifted down, since the rules should be below the actual baseline.

259 \raise-\frm@rulesep\vtop{%

The first line contains the description and a rule (if it does not extend the whole line). The description is shifted back to be aligned with the baseline.

260  \hbox to\hsize{%
261  \dp\frm@namebx0pt%
262  \raise\frm@rulesep\hbox{\usebox{\frm@namebx}}\leaders \hrule
263  height \frm@rulewidth \hfill}

If there is no break style, then the first line contains already one rule and the line bound must be decreased by one.

264  \iffrm@breakstyle\else \advance\frm@lbound-1\fi\relax

If the bound on the number of lines is exceeded then issue a warning.

265  \ifnum\frm@cnt>\frm@lbound\relax
266  \@tempcnta\frm@cnt \advance\@tempcnta-\frm@lbound\relax
267  \FRM@warn{Line bound in FRMenvironment exceeded by
268  \the\@tempcnta\space line(s)}
269  \else \frm@cnt\frm@lbound \fi

In each case, \frm@cnt contains the number of remaining rules. Plot them now. The depth of the final box is determined by the lowest rule.

270  \loop
271  \ifnum\frm@cnt>0\relax
272  \advance\frm@cnt-1\relax
273  \kern\frm@baselineskip \kern-\frm@rulewidth
274  \hrule height \frm@rulewidth\relax
275  \repeat

276 }% 277 }

3.8 Containers

\newFRMcontainer Parameter list:

#1 container id #2 init code #3 apply code

We store the current settings for restore at the beginning of the init code. Moreover, we use the hook to let \newFRMfield also define the \set... shortcut afterwards.

278 \long\def\newFRMcontainer#1#2#3{%
279 \FRM@storeappearance{con@#1}%
280 \newenvironment{#1}{%
281  \let\new@FRMcontainerhook=\new@FRMfieldspecials
282  \FRM@restoreappearance{con@#1}#2}{#3}

283 }

Seems to be a convention:

284 \endinput

Index

Numbers written in italic refer to the page where the corresponding entry is described, the ones underlined to the code line of the definition, the rest to the code lines where the entry is used.

N

 \new@FRMfield . . . . . \underline{171}
 \newFRMcontainer 6, \underline{278}
 \newFRMenvironment .

. . . . . . . . . 6, \underline{225}

 \newFRMfield . . . . 5, \underline{161}

R

 \renewFRMfield . . . . . 5

S \set... . . . . . . . . . . . 7

                           \setFRMbaselineskip

. . . . . . . . . . . 4, 6

                           \setFRMbreakstyle . . 6
                           \setFRMcontent . . . . . 4
                           \setFRMdescription . . 4
                           \setFRMfontencoding . 4
                           \setFRMfontfamily . . 4
                           \setFRMfontseries . . 4
                           \setFRMfontshape . . . 4

                                                    \setFRMfontsize . . . . 4
                                                    \setFRMinlinestyle . . 6
                                                    \setFRMmargin . . . . 4, 6
                                                    \setFRMplainstyle . . 5
                                                    \setFRMruledstyle . . 5
                                                    \setFRMrulesep . . . . . 4
                                                    \setFRMrulewidth . . . 4
                                                    \setFRMwidth . . . . . . . 4

U

                                                    \useFRMfield . . . . 5, \underline{189}