{"id":14624,"date":"2026-09-09T01:00:00","date_gmt":"2026-09-09T05:00:00","guid":{"rendered":"https:\/\/www.both.org\/?p=14624"},"modified":"2026-09-06T02:26:24","modified_gmt":"2026-09-06T06:26:24","slug":"why-i-love-classic-markup","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=14624","title":{"rendered":"Why I love classic markup"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"14624\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p class=\"wp-block-paragraph\">When I was an undergraduate student in the early 1990s, I discovered a loophole in the university\u2019s computer lab policy: they charged you per-page to print to the lab\u2019s laser printer, but printing to the line printer or dot matrix printer was free\u2014as long as you didn\u2019t abuse it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While I had used a DOS word processor until then (and was quite happy with it) I decided to take advantage of the \u201cfree\u201d printing. That started me on a journey to learn my first document markup: nroff.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Unix and nroff<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The story of how nroff <em>became nroff<\/em> is one of my favorite stories about Bell Labs Unix. Here\u2019s a quick overview:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ken Thompson and others on the Unix team had used an old PDP computer system to work on the first Unix system. But that system was slow, and they wanted to buy a newer, faster system. They put in several requests to purchase a new PDP computer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, that wasn\u2019t too long after Bell Labs had tried (and failed) to participate in the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Multics\">Multics project<\/a>, and management was feeling \u201cburned out\u201d on operating system development. Every request was rejected.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Around that same time, the Bell Labs legal department was about to purchase a computer system that would allow them to write patent applications, which required specific formatting. The hardware was ready, but the vendor would need more time to finish the software. The Unix team struck a deal: <em>you buy us a new computer<\/em>, we\u2019ll put Unix on it, and make updates to the current roff document preparation system to support patent applications.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And technically, <em>no one would be working on operating systems<\/em>. It just happened that they would have to make updates to Unix to support the new hardware\u2014but technically, not <em>operating systems development<\/em>. You get the idea.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s how the Unix team got a new computer. And that\u2019s how the <strong>roff<\/strong> command became <strong>nroff<\/strong> (or <em>new roff<\/em>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">It was dot commands<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Back to my story of learning nroff. A document is just a plain text file with <em>dot commands<\/em> that make nroff do certain things or apply special formatting. Each dot command starts on a new line; otherwise, it\u2019s just text. For example, you can center the next line with the <code>.ce<\/code> command, add extra spaces between paragraphs with <code>.sp<\/code>, set the left margin or \u201cpage offset\u201d with <code>.po<\/code>, or set the temporary \u201cfirst line\u201d indent for a new paragraph with the <code>.ti<\/code> command.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You could format a document entirely using these basic commands, but it more likely you\u2019d use a macro package that applied formatting for you. One macro system was created by Eric Allman, called the <strong>e<\/strong> macros, invoked with nroff\u2019s <code>-me<\/code> command line option. The \u201cstandard\u201d macro package was the <strong>s<\/strong> macros, developed at Bell Labs; you\u2019d use these with the <code>-ms<\/code> command line option. At the time, I used the <code>-me<\/code> macros, although these days I prefer the <code>-ms<\/code> macros.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s look at a short document written for the <code>-ms<\/code> macros. The Bell Labs macros are all uppercase, which makes it easy to identify them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this sample document, I\u2019ll define the document\u2019s title with the <code>.TL<\/code> command, and set the author\u2019s name and institution with <code>.AU<\/code> and <code>.AI<\/code> respectively. In technical writing, the first paragraph in a new section should be \u201cblock\u201d formatted, with no first line indent; use the <code>.LP<\/code> command for that. Other paragraphs use the <code>.PP<\/code> command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.TL\nClass Paper\n.AU\nJ. Hall\n.AI\nUniv. of Wisconsin-River Falls\n.LP\nThis is a sample report written in nroff.\nI wrote many class papers in nroff when I was an\nundergraduate student because nroff produced\noutput that could be easily printed on a\ndot matrix printer.\n.PP\nThat meant I could write my papers in nroff and\nprint them on the low-cost printer in the computer\nlab.\nNote that nroff automatically justifies the output\nso the left and right margins look nice.\nThis is also called \"adjusted\" text.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s save this file as <code>report.ms<\/code>, although the file extension doesn\u2019t really matter. When I process this input file using the <strong>nroff<\/strong> command and the <code>-ms<\/code> macros, I\u2019ll get a 1-page document with all lines starting on the left margin.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A printed page on a dot matrix printer, or any other typewriter-like device, typically used 10 characters per inch and 6 lines per inch. For what we call \u201cUS Letter\u201d page size today, that\u2019s 8 \u00bd\u2005\u00d7\u200511 inches, or 85 columns wide and 66 lines long. You can simulate a printed page by shrinking the font size in a terminal window and resizing the terminal so it is 85 columns wide and 67 lines long (the extra line means you can see the next command prompt without \u201closing\u201d the top line of the document). But for this sample, I\u2019ll just show the text output without the extra lines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>linux$ nroff -ms report.ms<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"> <code>                          Class Paper\n\n\n                             J. Hall\n                 Univ. of Wisconsin\u2010River Falls\n\n\nThis is a sample report written in nroff.  I wrote many class pa\u2010\npers  in  nroff when I was an undergraduate student because nroff\nproduced output that could be easily  printed  on  a  dot  matrix\nprinter.\n\n     That  meant  I could write my papers in nroff and print them\non the low\u2010cost printer in the computer lab.  Note that nroff au\u2010\ntomatically justifies the output so the left  and  right  margins\nlook nice.  This is also called \"adjusted\" text.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The justified lines are each 65 characters wide. For paper that is 85 columns wide, we need to add extra space on the left side with the <code>.po<\/code> (page offset) command. If we add 10 spaces on the left, and each line is 65 columns wide, that means we\u2019ll have 10 spaces left over on the right side. The output will be neatly balanced:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>linux$ (echo '.po 10' ; cat report.ms) | nroff -ms<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"614\" height=\"806\" src=\"http:\/\/www.both.org\/wp-content\/uploads\/2026\/09\/nroff-ms.png\" alt=\"1-page document with a title, author, and two paragraphs, as plain text\" class=\"wp-image-14622\"\/><figcaption class=\"wp-element-caption\">sample nroff output, captured as a screenshot from a terminal with 67 lines<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Upgrading to typesetting<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Later, Bell Labs purchased a phototypesetter, and they updated nroff to become <strong>troff<\/strong> (or <em>typesetter roff<\/em>). When they purchased a second typesetter, troff became <strong>ditroff<\/strong> (<em>device independent troff<\/em>). These days, you can use <strong>groff<\/strong> (or <em>GNU roff<\/em>) to simulate typesetter output; to generate a PDF file as the output, use the <strong>pdfroff<\/strong> command and redirect the output to a file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Bell Labs team continued to develop the <code>-ms<\/code> macros to support the extra formatting in the typesetter. That means extra font styles like italic and bold, and (eventually) new fonts like Courier and Helvetica.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s update the <code>report.ms<\/code> file to support this extra formatting. To add bold text, use the <code>.B<\/code> command. Use <code>.I<\/code> to turn on italic text, <code>.CW<\/code> for constant-width text (like a typewriter), and <code>.R<\/code> to go back to normal or \u201croman\u201d text style. Each command will switch the type style\u2014although it will limit formatting to just a word if you provide that word as the next option on the same line. This is easier to see in a demonstration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.nr PS 18\n.TL\nClass Paper\n.AU\nJ. Hall\n.AI\nUniv. of Wisconsin-River Falls\n.LP\n.I\nThis is a sample report written in nroff.\n.R\nI wrote many class papers in nroff when I was an\nundergraduate student because nroff produced\noutput that could be easily printed on a\ndot matrix printer.\n.PP\n.B\nThat meant I could write my papers in nroff and\n.R\nprint them on the low-cost printer in the computer\nlab.\nNote that nroff automatically justifies the output\nso the left and right margins look nice.\nThis is also called\n.I adjusted\ntext.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To make the output easier to see as a screenshot, I\u2019ve also used the <code>.nr<\/code> command to set a <em>number register<\/em>. In this case, <code>PS<\/code> is the number register for the text size (\u201cpoint size\u201d) which I\u2019ve set to 18-point text. The default font is Times.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s process this using <strong>pdfroff<\/strong> so we can see what the output might have looked like on a phototypesetter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ pdfroff -ms report.ms &gt; report.pdf<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"614\" height=\"794\" src=\"http:\/\/www.both.org\/wp-content\/uploads\/2026\/09\/troff-ms.png\" alt=\"1-page document with a title, author, and two paragraphs\" class=\"wp-image-14623\"\/><figcaption class=\"wp-element-caption\">sample troff output, generated as a pdf using pdfroff<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">More to learn<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is a simplified version of what I talk about in my new book, <a href=\"https:\/\/link.springer.com\/book\/10.1007\/979-8-8688-2931-4\">From Markup to Markdown<\/a>, now available from Springer\/Apress. If you\u2019re a programmer or technical writer, you\u2019ll love this book!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>From Markup to Markdown<\/em> is about how we\u2019ve used computers for writing, including RUNOFF, nroff, LaTeX, HTML, and DITA. There\u2019s even a chapter in there about word processing with WordStar, one of the first desktop word processors. I added a ton of references and examples in each chapter, so you can see how to create and format documents. Many chapters also provide source code of a simple implementation of each system, to show how things worked.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I have so many favorite parts of this book; I can\u2019t really pick <em>just one<\/em> thing that I love. But I think the nroff and troff chapters really stick with me. That\u2019s how I got started with document preparation, before I learned other markup and writing tools.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>From Markup to Markdown<\/em> is available in print and ebook editions <a href=\"https:\/\/link.springer.com\/book\/10.1007\/979-8-8688-2931-4\">from Springer\/Apress<\/a>. You can also order it <a href=\"https:\/\/www.amazon.com\/Markup-Markdown-Evolution-Typesetting-Frameworks\/dp\/B0GZYBF3F1\">from Amazon<\/a> and other book sellers.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"932\" height=\"699\" src=\"http:\/\/www.both.org\/wp-content\/uploads\/2026\/09\/jim-book.jpg\" alt=\"a man reading a book at a desk\" class=\"wp-image-14621\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Explore the history of \u201cwriting with computers\u201d in my new book<\/p>\n","protected":false},"author":33,"featured_media":2820,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":"","_members_access_role":[],"_members_access_error":""},"categories":[57,579],"tags":[574,303],"class_list":["post-14624","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-books","category-writing","tag-book","tag-writing"],"modified_by":"Jim Hall","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14624","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/33"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=14624"}],"version-history":[{"count":2,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14624\/revisions"}],"predecessor-version":[{"id":14627,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14624\/revisions\/14627"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/2820"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=14624"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=14624"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=14624"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}