rewrite-edit A look back: technical writing with ‘ed’

Technical writers on early computer systems used this simple but powerful editor.

Technical writers in 2024 can choose from a long list of text editors, each one targeting a specific niche audience. One popular editor is Microsoft's Visual Studio Code, a flexible editor that approaches an integrated development environment. Developers might use Visual Studio Code to create programs, but technical writers also use Visual Studio Code to write documentation with a markup system.

Modern editors are written for a graphical desktop environment. In the early days of computing, users interacted with the computer system using a video terminal, such as the popular VT52, VT100, or VT220 terminals. These video terminals were screen-addressable, allowing programs to move a cursor around the screen so the user could review and edit text documents visually.

photo of the VT 220 terminal
Photo of the VT220 terminal, from Tom Page, via Flickr (cc by-sa)

But terminals weren't always display-based. Even earlier computer interfaces were paper-based terminals, where the terminal printed the output on a continuous roll of paper loaded from the back of the machine. The TeleType Model 37 was one popular paper terminal.

photo of the Model 37 terminal
Photo of the TeleType Model 37 terminal, from M Blair Martin, via Wikipedia (cc by-sa)

Technical writing on these paper-based terminals looked quite different than the editors of today. With a paper terminal, you cannot move "up" to the previous line, and the editor cannot move the cursor to a different position. Instead, end users created documents using a line editor, which worked one line at a time. The ed editor on Unix is a typical example of a line editor.

Let's take a look back at how technical writers used a line editor to create documents. For this demonstration, I'll write a draft document about Markdown, written in Markdown.

Editing files with ‘ed’

To start editing a new file, type the ed command, followed by the name of the file to work on. If this is a new file, ed may print a warning message, although different versions of ed may simply start editing the file without printing a message.

$ ed mkdn.md
mkdn.md: No such file or directory

ed doesn't generate a prompt, so you have to type commands into the "air" where you imagine the prompt to be. To start inserting new text, use the i command. The editor will accept new text as input until you enter . on a line by itself:

i
# Re-thinking Markdown for technical writing

I have been thinking about early computer-based technical writing,
and the tools and technologies that were common at the time.
One early document markup system was RUNOFF, written by
Jerry Saltzer.
RUNOFF used "dot commands" at the start of a new line to indicate
formatting, such as `.ce` to center a line, `.in` to set the 
text indentation, and so on.
This simple markup provided a flexible foundation for writing
technical and professional documents with a computer.

RUNOFF also inspired other document markup systems. 
Doug McIlroy at Bell Labs wrote a different version in the same
style, which he called `roff`, generating output for the
TeleType model 37 terminal.
Later, Bell Labs made a new version called `nroff` (new `roff`)
that supported more complex document formatting.

Over time, technical writers have had their choice of digital  
writing tools, including TeX and LaTeX, HTML, DITA, and Markdown.
Markdown was an interesting departure, because it aimed to be a
minimal document markup system.
.

Making edits to the text

At this point, I realized I wanted to use a different word than minimal; Markdown is better described as a lightweight markup system instead. Since the last line that I entered (the current line) is the line that needs the change, any edit command will operate on that line by default.

To edit the text, let's use the s command, which operates on strings using regular expressions (often abbreviated as regex, and sometimes as re). This expression can just be plain text, or you can add regular expression identifiers like ^ to mean the beginning of a line. The s command searches for a regular expression and replaces it with new text, using the format s/regex/newtext/ with an optional g at the end if you need to change more than the first occurrence on a line.

Type this to change the word minimal to lightweight:

s/minimal/lightweight/

To verify the change, use the p command to print the current line:

p
lightweight document markup system.

In reviewing what I've written so far, I might also decide to format the RUNOFF program name using monospace type, like I did with the nroff program name. I've used RUNOFF several times throughout the document, and I want to change all of them.

You can also add a line number range before the s command. For example, 1,10s/RUNOFF/`RUNOFF`/g would replace all instances of RUNOFF with `RUNOFF` (adds the backticks) in the first ten lines. To replace all occurrences throughout the entire document, you can use $ to represent the last line in the file, so 1,$s/RUNOFF/`RUNOFF`/g will make the change everywhere. The % symbol is an alias for 1,$ so we could also write the s command like this:

%s/RUNOFF/`RUNOFF`/g

Searching for text

Let's try to find any example of RUNOFF in the document, to verify that the last edit was successful. To search for text in the file, use the / command with a regular expression. The regular expression makes it possible to only search for certain text at the start of a line with ^, or the end of the line with $, or using other regular expression special characters to match specific patterns of text.

To search forwards for the string RUNOFF at the start of a line, type this:

/^RUNOFF
?

The question mark response indicates that ed either didn't understand the command, or it failed to find a match. In this case, we didn't find an occurrence of RUNOFF at the beginning of a line, because we already replaced RUNOFF with `RUNOFF` (with the backticks). So we need to use a slightly different search:

/^`RUNOFF`
`RUNOFF` used "dot commands" at the start of a new line to indicate

Note that since we started the search from the last line of the file, ed "wrapped around" to continue the search from the first line of the file. Not all versions of ed will do this, but the GNU version does, and that's the version I'm using on Linux.

But if we look back at the ed editing session, we can see that this is not the first type we mentioned RUNOFF. There's another instance two lines before that. Let's see if we can find it using the ? command, which operates the same way as / except searching backwards.

To search backwards for the string RUNOFF anywhere on a line, type this:

?RUNOFF
One early document markup system was `RUNOFF`, written by

Printing lines of text

If we want to know the line number where this was found, we can use the n command to print the line, preceded by the line number. Without a line number range, the n command operates on the current line:

n
5       One early document markup system was `RUNOFF`, written by

To print several lines like this, we can add a range. For example, use this to print the first ten lines, with a line number for each:

1,10n
1       # Re-thinking Markdown for technical writing
2       
3       I have been thinking about early computer-based technical writing,
4       and the tools and technologies that were common at the time.
5       One early document markup system was `RUNOFF`, written by
6       Jerry Saltzer.
7       `RUNOFF` used "dot commands" at the start of a new line to indicate
8       formatting, such as `.ce` to center a line, `.in` to set the
9       text indentation, and so on.
10      This simple markup provided a flexible foundation for writing

But since we know the text is from the first ten lines, we don't need to print them with line numbers. The p command will print them without line numbers, like this:

1,10p
# Re-thinking Markdown for technical writing

I have been thinking about early computer-based technical writing,
and the tools and technologies that were common at the time.
One early document markup system was `RUNOFF`, written by
Jerry Saltzer.
`RUNOFF` used "dot commands" at the start of a new line to indicate
formatting, such as `.ce` to center a line, `.in` to set the
text indentation, and so on.
This simple markup provided a flexible foundation for writing

A more interesting example is to print out all lines in the file that have the word RUNOFF in it. To do that, we can use the g command to operate globally. This uses a syntax with slashes around a regular expression to search for, and provide a command like n to number the lines or p to print them without numbers.

For example, we can print all matching lines, with line numbers, like this:

g/RUNOFF/n
5       One early document markup system was `RUNOFF`, written by
7       `RUNOFF` used "dot commands" at the start of a new line to indicate
13      `RUNOFF` also inspired other document markup systems.

This tells us that the word RUNOFF occurs on lines 5, 7, and 13. To just print those lines without numbers, repeat the command with p instead of n:

g/RUNOFF/p
One early document markup system was `RUNOFF`, written by
`RUNOFF` used "dot commands" at the start of a new line to indicate
`RUNOFF` also inspired other document markup systems.

In other words, the g command uses the syntax g/re/p to print text without line numbers. If you're familiar with the Linux command line, you might be interested to know that's where the grep command got its name, because it's derived from the code in ed to do a global regular expression print of matching text in a file.

Saving and exiting

You should save your file as you work on it, so you don't lose your important changes. Use w to write the file to the disk:

w
1067

As a way to confirm it's saved the file, ed prints the number of bytes that it wrote to the file. In this case, my file is 1,067 bytes long, or just over 1 kilobyte.

Once the file is saved, you can safely exit the program and return to the command line. Use the q command to quit.

q
$ 

And on my system, the dollar sign is my Linux shell prompt, indicating that I have exited the ed editor, and back in the command line.