Last time, we started developing a troff macro
package for résumés. We left off just as we were
getting to the definitions of useful fancy text strings. We also
promised the setup for an web version of the
résumé, by (ab)using nroff to generate HTML
as output.
Fancy strings and
setup.
The last set of definitions we need in the
macros are for some strings we'll use, which we provide in
separate troff and nroff renditions:
(The name of a popular typesetting system.).\" set up some fancy strings .ie t .ds TX T\h'-.1667m'\v'.25m'E\ \v'-.25m'\h'-.125m'X .el .ds TX TeX
(The font generation tool that goes with it. We explicitly set this in Helvetica, because it's the closest thing to the TeX manfnt font -- in which we normally set the name -- that we're guaranteed to have.).ie t .ds MF \fH\s-1METAFONT\s0\fP .el .ds MF METAFONT
(We use small caps when we can, to match Adobe's practice.).ie t .ds Ps P\s-2OST\s0S\s-2CRIPT\s0 .el .ds Ps PostScript
(The name of a company where we used to work, again rendered to match the practice at that company.).ds IN \s-1INTERACTIVE\s0
(Lastly, we make special strings for the names of our favorite typesetting tools because we'll be using them a lot.).ds Nr \f2nroff\fP .ds Tr \f2troff\fP
The very last thing in the macro package is setup for the actual page size, tab stops and the like:
We begin by setting up the page and title length in both the main and page heading environment. We set the page offset to center the text on the page, or, in nroff, to give us a little left margin..ll 7i .lt 7i .ev 1 .ll 7i .lt 7i .ev .if t .po .75i .if n .po 5m
We define a string for the tab character, which we're sure to need..ds T \t
We begin with a ragged right margin, no hyphenation, and 54 points down the page..na .nh .sp |4.5v
Because of the typical font load in a POSTSCRIPT printer, we make the type a little bigger, and leave a little extra space between the words. (Those lines used to be enclosed in an if that checked the printer name, available in troff in the .T string, but we discovered that, in practice, we only used POSTSCRIPT printers.).\" the following 3 lines are .\" setup for PostScript printers .ps 11 .vs 12.375p .ss 15
We want to use the tilde for unbreakable spaces, and we set up the tab stops based on the point size we use..tr ~ .ta 1.1i*\n(.su/10u +.5i +.5i +.5i +.5i
If we've set the H number register, we want to produce the HTML version of the résumé, and we invoke an addendum to the macros, in the file html.mac. (OK, we could have defined the main résumé macros in a way that included the HTML stuff in parallel using ifs, but it's cleaner and easier to read to just supplement the original definitions with a separate macro file.).if n .if \nH .so html.mac .if t .if \nH .ab ^G^G^G============== \ can't do html in troff!!!!
The HTML version.
We'll discuss the special case HTML macros before we discuss the
text of the résumé, because there are some odd
things in the text required for the multiple output versions.
What we're doing here is using a formatter to generate input for
a formatter: we're taking our résumé source, and
pushing it through nroff to generate HTML which will be
formatted by the interpretter in a browser. Because HTML gets
formatted on-the-fly based on the sizes of the window into which
it's being displayed, and because we only have limited formatting
directives, some of the elements of our very fancy troff
version will be lost.
The only special general setup we need for the HTML version is to reset the page offset. This isn't strictly necesary, but it makes the HTML a little easier for us to read and debug..\" reset the page offset .po 0
However, we must have:
These override the font change macros we built in the typesetting version. Notice that we're allowing a third argument to the c macro: In general, we use Courier in the résumé for references to addresses -- our e-mail address, for example, or a pointer to our personal web page. This third argument allows us to add an active link in the HTML version. For example:.\" font change macros .de i <I>\\$1</I> .. .de b <B>\\$1</B> .. .de c .br .ie \w@\\$3@ <A HREF="\\$3"> .el <A HREF="\\$1"> .br <TT>\\$1</TT></A>\\$2 ..
will generate the HTML.c jsh@usenix.org ";" mailto:jsh@usenix.org
<A HREF="mailto:jsh@usenix.org> <TT>jsh@usenix.org</TT></A>;
We also need some macros for paragraphs:
We add the BR macro, which will be ignored when we generate the troff version (except that it will generate a warning message from groff). We'll use BR in between lines in centered text, because HTML won't let us center a block. The other paragraph macros are pretty simple translations, except that IP uses the non-breaking space character, which may not be recognized by all browsers. (David Siegel --see http://www.dsiegel.com-- recommends using an empty GIF file of a specified width as the work-around for this.).\" html versions of paragraphing .de BR <BR> .. .de PP <BR> .. .de IP \" indented paragraph <BR> .. .de HP \" hanging paragraph <P> ..
Our HTML-generating rendition of the bullet list macros
makes an interesting study. In our résumé, we use
three levels of list, and each item is tagged with one of the
list item macros. For troff output, each one of those
macros begins by doing a hard set of the indent, and putting the
tag.
In the HTML version, we use the native HTML unordered
list construct to generate the outline. However, like in the
troff -mm macros, we need to bracket the
unordered lists with a begin/end directive pair. For HTML, these
are <UL> and </UL>.
We invent an internal list end macro, LE, which keeps track of how many levels deep we are in the list (with the LT number register), and outputs an appropriate number of <UL>'s or </UL>'s when we change levels in the outline.
.\" special nested bullet lists .de BU \" bullet list item for summary .LE 1 <LI> .. .de DA \" dashed list item for summary .LE 2 <LI> .. .de SB \" item line for summary .LE 3 <LI> .. .de LE \" list begin/end .nr *d \\$1-\\n(LT .if \\n(*d=-1 </UL> .if \\n(*d=-2 </UL></UL> .if \\n(*d=2 <UL><UL> .if \\n(*d=1 <UL> .nr LT \\$1 ..
HTML pages and
sections
We also need to override some of the page
breaking things we set up in the troff version.
We totally remove the top of page handling -- actually, a redundant exercise because HTML is generated by nroff, for which we've set the page length to 1 line, so the top of page handling is never done. We also override the native nroff page break directive, bp, because we don't need to do real page breaks when we're formatting for HTML..\" page break handling .rm BP .de bp ..
We also need HTML output versions of the main structural elements of the résumé.
A section is marked by a horizontal rule, and an italic label in a slightly larger point size..\" resume structural markup .de SC \" begin section <HR><FONT SIZE=+1><I>\\$1</I></FONT><BR> ..
The new job macro is almost identical to its troff sibling, but puts the whole line introducing the job in italics. It doesn't rely on tab stops or other setup: it merely drops the arguments to NJ in order..de NJ \" new job .tr #- <P> <I> [[\\$1]] .if \w@\\$2@ \\$2. .ie \w@\\$4@ \\$3, \\$4:</I> .el \\$3:</I> .tr -- ..
We should have a special version of the top-of-first-page title block with our name and address information:
.de PH \" 1st page title block <HTML> <TITLE>\\*(Jf's Resume</TITLE> <BODY> <CENTER> <FONT SIZE=+1> <B><I>\\*(JF</I></B> </FONT> .BR \\*(A1 .BR \\*(A2 .BR \\*(A3 .BR .c \\*(J@ mailto:\\*(J@ </CENTER> ..
We also need to override the troff three-part title directive, because it's output would be meaningless when reformatted form the HTML by the browser. We just enclose its arguments in an HTML comment, though we could also ignore them.
.\" replace the nroff tl directive .de tl <!-- \\$1 --> ..
In the troff version, we had an end macro that generated the page footer on the last page to give us the date we printed the résumé. Here, we'll add it in small type at the bottom of the HTML. But more importantly, we have to close the HTML body.
.\" html resume end macro .de EM <P><FONT SIZE=-1>(\\*(PD)</FONT><P> </BODY></HTML> ..
Whew! That covers two different versions of the macros
which support some major differences in their output with only
minor differences in the text we input. Now it's time to look at
that text.
The résumé
text.
We begin the text with the string
definitions for name and address we talked about earlier:
(Notice that we've got two versions of the full name: one with small caps, one with lower case.) We'll immediately turn around and invoke the first page header macro:.ds JF \s+2J\s0EFFREY \s+2L C\s0OPELAND .ds Jf Jeffrey L Copeland .ds J@ copeland@alumni.caltech.edu .ds A1 1085 Albion Road .ds A2 Boulder, Colorado 80303 .ds A3 303-499-8924
.PH
We can proceed from there with the executive summary.
We've dropped down the page two-thirds of an inch before beginning the summary list itself. As we discussed when we developed the bullet list macros, we assume some base left margin indent, which we've also set up. From there, we can just start dropping bullet items:.\" summary .sp .66i .in 1i .in +3m
And so on..BU Technical skills: .DA Very experienced Unix/C developer .SB Developer of systems and applications software ..... .BU Good communications skills .DA Monthly columnist for .i SunExpert magazine
At the end of our bullet list, we need to close out the unordered lists in the HTML output, reset that page offset, and set up the résumé proper: in the nroff version, we just draw a line; in troff, we start a new page; in HTML, we rely on the first sub-section header to draw a horizontal rule.
.if \nH .LE 0 .in 0 .if t .bp .if n .if !\nH \l'\n(.lu'
In the troff case only, we want to do some fancy setup at the top of this page:
.if t \{\
.sp -2v
.ce 1
\*(JC
.sp .3v
.if !\nA .tl |\s10\*(A1, \*(A2|\
|\fC\*(J@\f1, \*(A3\s0|
\l'\n(.lu'
.\}
We begin by going back two lines, because the top of page macro
has dropped us down too far on the page -- this probably means
that our top of page processing isn't sufficiently general.
After centering our name, we reiterate our addresses, physical,
electronic, and telephonic, though we can ask for those to be
omitted by turning on the A number register. Lastly, we
draw a horizontal rule.
At this point -- nearly to the end of the second column -- we can begin actually supplying text to the résumé.
.SC Objective .HP A job as the Chief Executive Officer of a Fortune 500 company, like Disney, AT&T, or Apple, that will supply me with a megabuck severance package.
Of course, we'd also like to supply some information about the jobs we've had:
.SC Experience .NJ "11/94#8/97" \ "Senior Member of the Technical Staff" \ "QMS, Inc" "Boulder, Colorado" .PP .MG Interim manager of languages group, from December 1995 to August 1996. .IP .VE QMS's representative to the Printer Working Group, a printer industry consortium and standards-making body. See PWG web pages, at .c http://www.pwg.org/ .
Notice that we've used a couple of the tricks we
outlined above: We're including a paragraph about management
responsibility only in the management version of the
résumé. We're also allowing a pointer to an
external web page from our HTML version.
We could go on in the same vein for a while, but you've
now seen the basic structure and how to use it. If you're
interested in seeing a full résumé using these
macros, we've included an example with the software bundle for
this column.
Now, go get a haircut and a
job!
That's it. You've now got the basic tools to
produce a fancy résumé in several different forms.
The macro package, along with all the software we write for this
column, is available at http://www.alumni.caltech.edu/~copeland/work.html. Use it in good health. We'd
love to hear from you if you think of improvements to these
macros.
Until next month, happy trails.