Nik Clayton
Published $Id$
The FreeBSD Handbook aims to be the definitive online resource for information about FreeBSD. This article explains how the Handbook is marked up to indicate the nature of the information it contains. It all discusses aspects of style to use when writing for the FreeBSD Handbook, and provides tips on how to use particular applications in order to make working with the Handbook easier.
The Handbook's top level element is <book>, and the DOCTYPE for it reads <!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V3.0-Based Extension//EN">.
The extensions are for the most part small, providing some additional elements to make the markup more precise. Where a new element is shown in this article it is clearly marked as being part of the FreeBSD extesions.
Note: There is nothing about these extensions that is FreeBSD specific, it was just felt that they were useful enhancements for this particular project. Should anyone from any of the other *nix camps (NetBSD, OpenBSD, Linux, …) be interested in collaborating on a standard DocBook extension set, please get in touch with Nik Clayton <nik@freebsd.org>.
The Handbook is then organised in to <part>s, each of which can contain one or more <chapter>s. Each chapter can contain one or more sections (<sect1>) and each section can contain subsections (by incrementing the trailing number, <sect2>, <sect3> and so on).
On disk, the Handbook is split into a number of different files. The top level file is handbook.sgml. This file contains the overall structure of the Handbook. SGML entities are used to include the remainder of the Handbook from other files.
The other files are organised into directories, one per chapter in the Handbook. The directories are named after the value of the id attribute on the <chapter> element, and the files are generally called chapter.sgml within those directories.
For example, if one of the chapter files contains:
<chapter id="kernelconfiguration"> ... </chapter>
then it will be called chapter.sgml in the kernelconfiguration directory. In general, the entire contents of the chapter will be held in this file.
When the HTML version of the Handbook is produced, this will yield kernelconfiguration.html. This is because of the id value, and is not related to the name of the directory.
Given that each chapter will be held in just one file, why not name the files after the value of the id attribute, and remove the need for directories?
This was how the LinuxDoc Handbook was arranged. It works. However, it does not scale for additional content. I envisage a point in time (hopefully relatively soon) when graphics are used within the Handbook. Most of these graphics will be specific to one chapter. At this point the graphic source files (.fig perhaps, or .ps) can be kept in the same directory as the chapter SGML itself.
Of course, as well as simple graphics, there's no reason why certain versions of the Handbook couldn't contain additional content. If anyone wants to provide a 3 minute MPEG of someone navigating through sysinstall's disk layout screens, they are more than welcome…
Important: Chapters and/or directories should not be named in a fashion that reflects their ordering within the Handbook. This ordering might change as the content within the Handbook is reorganised; this sort of reorganistion should not (generally) include the need to rename files (unless entire chapters are being promoted or demoted within the hierarchy).
Each chapter.sgml file will not be a complete SGML document. In particular, they will not have their own DOCTYPE line at the start of the file.
This is unfortunate for two reasons;
It makes it impossible to treat these as generic SGML files and simply convert them to HTML, RTF, PS, and other formats in the same way the main Handbook is generated. This would force you to rebuild the Handbook every time you want to see the effect a change as had on just one chapter.
Emacs' sgml-mode can not use it to determine the DTD to use, losing useful benefits of sgml-mode (element completion, automatic validation, and so on).
These problems are worked around in two ways.
A chapter driver file has been created. This is kept in the top level directory (with handbook.sgml) and it contains a skeleton structure for a DocBook <chapter>. With the use of some entities defined on the command line, this skeleton will read in the appropriate chapter.sgml file, and the two files will together provide a complete SGML context for the converter to work with.
For Emacs' sake, local variables will be defined at the top of each file specifying the name of the DTD the file conforms to, the top level element in the file, and so forth. This will allow sgml-mode to provide assistance when writing the document.
Unlike LinuxDoc and HTML, DocBook is very heavily orientated towards markup that describes what something is, rather than describing how it should be presented.
DocBook also contains a large number of elements, and it can be confusing sometimes to know which element to use for a particular situation. This section goes through the elements you are most likely to need, and gives examples of how you would use them.
This is not an exhaustive list of elements, since that would just reiterate the DocBook documentation. The aim of this section is to list those elements more likely to be useful to you. If you have a question about how best to markup a particular piece of content, please post it to the FreeBSD Documentation Project mailing list <freebsd-doc@freebsd.org>.
Inline vs. block and formal vs. informal: In the remainder of this document, when describing elements, inline means that the element can occur within a block element, and does not cause a line break. A block element, by comparison, will cause a line break (and other processing) when it is encountered.
Some elements may exist in two forms, formal and informal. Typically, the formal version of the element will consist of a title followed by the information version of the element. The informal version will not have a title.
DocBook supports three types of paragraphs; <formalpara>, <para>, and <simpara>.
Most of the time you will only need to use <para>. <formalpara> includes a <title> element, and <simpara> disallows some elements from within <para>. Stick with <para>.
Example 1. <para>
Use:
<para>This is a paragraph. It can contain just about any other element.</para>
Appearance:
This is a paragraph. It can contain just about any other element.
A block quotation is an extended quotation from another document that should not appear within the current paragraph. You will probably only need it infrequently.
Blockquotes can optionally contain a title and an attribution (or they can be left untitled and unattributed).
Example 2. <blockquote>
Use:
<para>A small excerpt from the US Constitution;</para> <blockquote> <title>Preamble to the Constitution of the United States</para> <attribution>Copied from a web site somewhere</attribution> <para>We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defence, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America.</para> </blockquote>
Appearance:
Preamble to the Constitution of the United States
Copied from a web site somewhere
We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defence, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America.
You may need to include extra information separate from the main body of the text. Typically this is “meta” information that the user should be aware of.
Depending on the nature of the information, one of <tip>, <note>, <warning>, <caution>, and <important> should be used. Alternatively, if the information is related to the main text but is not one of the above, use <sidebar>.
The circumstances in which to choose one of these elements over another is unclear. The DocBook documentation suggests;
A Note is for information that should be heeded by all readers.
An Important element is a variation on Note.
A Caution is for information regarding possible data loss or software damage.
A Warning is for information regarding possible hardware damage or injury to life or limb.
Example 3. <warning>
Use:
<warning> <para>Installing FreeBSD may make you want to delete Windows from your harddisk.</para> </warning>
Warning |
Installing FreeBSD may make you want to delete Windows from your harddisk. |
You will often need to list pieces of information to the user, or present them with a number of steps that must be carried out in order to accomplish a particular goal.
In order to do this, use <itemizedlist>, <orderedlist>, or <procedure>[1]
<itemizedlist> and <orderedlist> are similar to the counterparts in HTML, <ul> and <ol>. Each one consists of one or more <listentry> elements, and each <listentry> contains one or more block elements. The <listentry> elements are analagous to HTMLs <li> tags. However, unlike HTML they are required.
<procedure> is slightly different. It consists of <step>s, which may in turn consists of more <step>s or <substep>s. Each <step> contains block elements.
Example 4. <itemizedlist>, <orderedlist>, and <procedure>
Use:
<itemizedlist> <listitem> <para>This is the first itemized item.</para> </listitem> <listitem> <para>This is the second itemized item.</para> </listitem> </itemizedlist> <orderedlist> <listitem> <para>This is the first ordered item.</para> </listitem> <listitem> <para>This is the second ordered item.</para> </listitem> </orderedlist>
Appearance:
This is the first itemized item.
This is the second itemized item.
This is the first ordered item.
This is the second ordered item.
If you want to show a fragment of a file (or perhaps a complete file) to the user, wrap it in the <programlisting> element.
White space and line breaks within <programlisting> are significant. In particular, this means that the closing tag should appear on the same line as the last line of the output, otherwise a spurious blank line will be included.
Example 5. <programlisting>
Use:
<para>When you have finished, your program should look like this;</para> <programlisting> #include <stdio.h> int main(void) { printf("hello, world\n"); }</programlisting>
Notice how the angle brackets in the #include line need to be referenced by their entities instead of being included literally.
Appearance:
When you have finished, your program should look like this;
#include <stdio.h> int main(void) { printf("hello, world\n"); }
Note: There is a mechanism within DocBook for referring to sections of a previously occuring <programlisting>, called callouts (see <programlistingco> for more information). I don't fully understand (i.e., have never used) this feature, so can't document it here. For the mean time, you can include line numbers within the content, and then refer to them later on in your description. That will change, as soon as I find the time to understand and document callouts.
Unlike HTML, you do not need to use tables for layout purposes, as the stylesheet handles those issues for you. Instead, just use tables for marking up tabular data.
In general terms (and see the DocBook documentation for more detail) a table (which can be either formal or informal) consists of a <table> element. This contains at least one <tgroup> element, which specifies (as an attribute) the number of columns in this table group. Within the tablegroup you can then have one <thead> element, which contains elements for the table headings (column headings), and one <tbody> which contains the body of the table.
Both <tgroup> and <thead> contain <row> elements, which in turn contain <entry> elements. Each <entry> element specifies one cell in the table.
Example 6. <informaltable>
Use:
<informaltable> <tgroup cols="2"> <thead> <row> <entry>This is column head 1</entry> <entry>This is column head 2</entry> </row> </thead> <tbody> <row> <entry>Row 1, column 1</entry> <entry>Row 1, column 2</entry> </row> <row> <entry>Row 2, column 1</entry> <entry>Row 2, column 2</entry> </row> </tbody> </tgroup> </informaltable>
Appearance:
This is column head 1 | This is column head 2 |
---|---|
Row 1, column 1 | Row 1, column 2 |
Row 2, column 1 | Row 2, column 2 |
If you don't want a border around the table the frame attribute can be added to the <informaltable> element with a value of none (i.e., <informaltable frame="none">).
Appearance:
This is column head 1 | This is column head 2 |
---|---|
Row 1, column 1 | Row 1, column 2 |
Row 2, column 1 | Row 2, column 2 |
A lot of the time you need to show examples for the user to follow. Typically, these will consist of dialogs with the computer; the user types in a command, the user gets a response back, they type in another command, and so on.
A number of distinct elements and entities come in to play here.
Most of the time these examples will occur “mid-flow” as it were, and you won't need to put a title on them. So, most of the time, the outermost element will be <informalexample>. For those times when you do need to include a title on the example, use <example>.
Everything the user sees in this example will be on the computer screen, so the next element is <screen>.
Within <screen>, white space is significant.
Some of the things the user will be seeing on the screen are prompts from the computer (either from the OS, command shell, or application. These should be marked up using <prompt>.
As a special case, the two shell prompts for the normal user and the root user have been provided as entities. Every time you want to indicate the user is at a shell prompt, use one of &prompt.root; and &prompt.user; as necessary. They do not need to be inside <prompt>.
Note: &prompt.root; and &prompt.user; are FreeBSD extensions to DocBook, and are not part of the original DTD.
When displaying text that the user should type in, wrap it in <userinput> tags. It will probably be displayed differently to the user.
Example 7. <informalexample>, <screen>, <prompt>, and <userinput>
Use:
<informalexample> <screen>&prompt.user; <userinput>ls -1</userinput> foo1 foo2 foo3 &prompt.user; <userinput>ls -1 | grep foo2</userinput> foo2 &prompt.user; <userinput>su</userinput> <prompt>Password: </prompt> &prompt.root; <userinput>cat foo2</userinput> This is the file called 'foo2'</screen> </informalexample>
Note: Even though we are displaying the contents of the file foo2, it is not marked up as <programlisting>. Reserve <programlisting> for showing fragments of files outside the context of user actions.
Appearance:
% ls -1 foo1 foo2 foo3 % ls -1 | grep foo2 foo2 % su Password: # cat foo2 This is the file called 'foo2'
When you want to emphasise a particular word or phrase, use <emphasis>. This may be presented as italic, or bold, or might be spoken differently with a text-to-speech system.
There is no way to change the presentation of the emphasis within your document, no equivalent of HTML's <b> and <i>. If the information you are presenting is important then consider presenting it in <important> rather than <emphasis>.
Example 8. <emphasis>
Use:
<para>FreeBSD is without doubt <emphasis>the</emphasis> premiere Unix like operating system for the Intel architecture.</para>
Appearance:
FreeBSD is without doubt the premiere Unix like operating system for the Intel architecture.
You will frequently want to refer to both applications and commands when writing for the Handbook. The distinction between them is simple; an application is the name for a suite (or possibly just 1) of programs that fulfil a particular task. A command is the name of a program that the user can run.
In addition, you will occasionally need to list one or more of the options that a command might take.
Finally, you will often want to list a command with it's manual section number, in the “command(number)” format so common in Unix manuals.
Mark up application names with <application>.
When you want to list a command with it's manual section number (which should be most of the time) use <citerefentry>. This will contain a further two elements, <refentrytitle> and <manvolnum>. The content of <refentrytitle> is the name of the command, and the content of <manvolnum> is the manual page section.
Use <command> when you want to include a command name “in-line” but present it as something the user should type in.
Use <option> to mark up a command's options.
This can be confusing, and sometimes the choice is not always clear. Hopefully this example makes it clearer.
Example 9. Applications, commands, and options.
Use:
<para><application>Sendmail</application> is the most widely used Unix mail application.</para> <para><application>Sendmail</application> includes the <citerefentry> <refentrytitle>sendmail</refentrytitle> <manvolnum>8</manvolnum> </citerefentry>, <citerefentry> <refentrytitle>mailq</refentrytitle> <manvolnum>8</manvolnum> </citerefentry>, and <citerefentry> <refentrytitle>newaliases</refentrytitle> <manvolnum>8</manvolnum> </citerefentry> programs.</para> <para>One of the command line parameters to <citerefentry> <refentrytitle>sendmail</refentrytitle> <manvolnum>8</manvolnum> </citerefentry>, <option>-bp</option>, will display the current status of messages in the mail queue. Check this on the command line by running <command>sendmail -bp</command>.</para>
Appearance:
Sendmail is the most widely used Unix mail application.
Sendmail includes the sendmail(8), mailq(8), and newaliases(8) programs.
One of the command line parameters to sendmail(8), -bp, will display the current status of messages in the mail queue. Check this on the command line by running sendmail -bp.
Whenever you wish to refer to the name of a file, a directory, or a file extension, use <filename>.
Example 10. <filename>
Use:
<para>The SGML source for the Handbook in English can be found in <filename>/usr/doc/en/handbook/</filename>. The first file is called <filename>handbook.sgml</filename> in that directory. You should also see a <filename>Makefile</filename> and a number of files with a <filename>.ent</filename> extension.</para>
Appearance:
The SGML source for the Handbook in English can be found in /usr/doc/en/handbook/. The first file is called handbook.sgml in that directory. You should also see a Makefile and a number of files with a .ent extension.
FreeBSD extension: These elements are part of the FreeBSD extension to DocBook, and do not exist in the original DocBook DTD.
When referring to devices you have two choices. You can either refer to the device as it appears in /dev, or you can use the name of the device as it appears in the kernel. For this latter course, use <devicename>.
Sometimes you will not have a choice. Some devices, such as networking cards, do not have entries in /dev, or the entries are markedly different from those entries.
Example 11. <devicename>
Use:
<para><devicename>sio</devicename> is used for serial communication in FreeBSD. <devicename>sio</devicename> manifests through a number of entries in <filename>/dev</filename>, including <filename>/dev/ttyd0</filename> and <filename>/dev/cuaa0</filename>.</para> <para>By contrast, the networking devices, such as <devicename>ed0</devicename> do not appear in <filename>/dev</filename>. <para>In MS-DOS, the first floppy drive is referred to as <devicename>a:</devicename>. In FreeBSD it is <filename>/dev/fd0</filename>.</para>
Appearance:
sio is used for serial communication in FreeBSD. sio manifests through a number of entries in /dev, including /dev/ttyd0 and /dev/cuaa0.
By contrast, the networking devices, such as ed0 do not appear in /dev.
In MS-DOS, the first floppy drive is referred to as a:. In FreeBSD it is /dev/fd0.
FreeBSD extension: These elements are part of the FreeBSD extension to DocBook, and do not exist in the original DocBook DTD.
You can markup identification information for networked computers (hosts) in several ways, depending on the nature of the information. All of them use <hostid> as the element, with the role attribute selecting the type of the marked up information.
With no role attribute (i.e., <hostid>...<hostid> the marked up information is the simple hostname, such as freefall or wcarchive. You can explicitly specify this with role="hostname".
The text is a domain name, such as freebsd.org or ngo.org.uk. There is no hostname component.
The text is a Fully Qualified Domain Name, with both hostname and domain name parts.
The text is an IP address, probably expressed as a dotted quad.
The text is a network mask, which might be expressed as a dotted quad, a hexadecimal string, or as a / followed by a number.
The text is an ethernet MAC address, expressed as a series of 2 digit hexadecimal numbers seperated by colons.
Example 12. <hostid> and roles
Use:
<para>The local machine can always be referred to by the name <hostid>localhost</hostid>, which will have the IP address <hostid role="ipaddr">127.0.0.1</hostid>.</para> <para>The <hostid role="domainname">freebsd.org</hostid> domain contains a number of different hosts, including <hostid role="fqdn">freefall.freebsd.org</hostid> and <hostid role="fqdn">bento.freebsd.org</hostid>.</para> <para>When adding an IP alias to an interface (using <command>ifconfig</command>) <emphasis>always</emphasis> use a netmask of <hostid role="netmask">255.255.255.255</hostid> (which can also be expressed as <hostid role="netmask">0xffffffff</hostid>.</para> <para>The MAC address uniquely identifies every network card in in existence. A typical MAC address looks like <hostid role="mac">08:00:20:87:ef:d0</hostid>.</para>
Appearance:
The local machine can always be referred to by the name localhost, which will have the IP address 127.0.0.1.
The freebsd.org domain contains a number of different hosts, including freefall.freebsd.org and bento.freebsd.org.
When adding an IP alias to an interface (using ifconfig) always use a netmask of 255.255.255.255 (which can also be expressed as 0xffffffff.
The MAC address uniquely identifies every network card in in existence. A typical MAC address looks like 08:00:20:87:ef:d0.
FreeBSD extension: These elements are part of the FreeBSD extension to DocBook, and do not exist in the original DocBook DTD.
When you need to refer to a specific username, such as root or bin, use <username>.
Example 13. <username>
Use:
<para>To carry out most system administration functions you will need to be <username>root</username>.</para>
Appearance:
To carry out most system administration functions you will need to be root.
FreeBSD extension: These elements are part of the FreeBSD extension to DocBook, and do not exist in the original DocBook DTD.
Two elements exist to describe parts of Makefiles, <maketarget> and <makevar>.
<maketarget> identifies a build target exported by a Makefile that can be given as a parameter to make. <makevar> identifies a variable that can be set (in the environment, on the make command line, or within the Makefile) to influence the process.
Example 14. <maketarget> and <makevar>
Use:
<para>Two common targets in a <filename>Makefile</filename> are <maketarget>all</maketarget> and <maketarget>clean</maketarget>.</para> <para>Typically, invoking <maketarget>all</maketarget> will rebuild the application, and invoking <maketarget>clean</maketarget> will remove the temporary files (<filename>.o</filename> for example) created by the build process.</para> <para><maketarget>clean</maketarget> may be controlled by a number of variables, including <makevar>CLOBBER</makevar> and <makevar>RECURSE</makevar>.</para>
Appearance:
Two common targets in a Makefile are all and clean.
Typically, invoking all will rebuild the application, and invoking clean will remove the temporary files (.o for example) created by the build process.
clean may be controlled by a number of variables, including CLOBBER and RECURSE.
You will often need to include “literal” text in the Handbook. This is text that is excerpted from another file, or which should be copied from the Handbook into another file verbatim.
Some of the time, <programlisting> will be sufficient to denote this text. <programlisting> is not always appropriate, particularly when you want to include a portion of a file “in-line” with the rest of the paragraph.
On these occasions, use <literal>.
Example 15. <literal>
Use:
<para>The <literal>maxusers 10</literal> line in the kernel configuration file determines the size of many system tables, and is a rough guide to how many simultaneous logins the system will support.</para>
Appearance:
The maxusers 10 line in the kernel configuration file determines the size of many system tables, and is a rough guide to how many simultaneous logins the system will support.
There will often be times when you want to show the user what to do, or refer to a file, or command line, or similar, where the user can not simply copy the examples that you provide, but must instead include some information themselves.
<replaceable> is designed for this eventuality. Use it inside other elements to indicate parts of that element's content that the user must replace.
Example 16. <replaceable>
Use:
<informalexample> <screen>&prompt.user; <userinput>man <replaceable>command</replaceable></userinput></screen> </informalexample>
Appearance:
% man command
<replaceable> can be used in many different elements, including <literal>. This example also shows that <replaceable> should only be wrapped around the content that the user is meant to provide. The other content should be left alone.
Use:
<para>The <literal>maxusers <replaceable>n</replaceable></literal> line in the kernel configuration file determines the size of many system tables, and is a rough guide to how many simultaneous logins the system will support.</para> <para>For a desktop workstation, <literal>32</literal> is a good value for <replaceable>n</replaceable>.</para>
Appearance:
The maxusers n line in the kernel configuration file determines the size of many system tables, and is a rough guide to how many simultaneous logins the system will support.
For a desktop workstation, 32 is a good value for n.
Recent versions of Emacs or Xemacs (available from the ports collection) contain a very useful package called PSGML. Automatically invoked when a file with .sgml extension is loaded, or by typing M-x sgml-mode, it is a major mode for dealing with SGML files, elements and attributes.
An understanding of some of the commands provided by this mode can make working with SGML documents such as the Handbook much easier.
Runs sgml-insert-element. You will be prompted for the name of the element to insert at the current point. You can use the TAB key to complete the element. Elements that are not valid at the current point will be disallowed.
The start and end tags for the element will be inserted. If the element contains other, mandatory, elements then these will be inserted as well.
Runs sgml-change-element-name. Place the point within an element and run this command. You will be prompted for the name of the element to change to. Both the start and end tags of the current element will be changed to the new element.
Runs sgml-tag-region. Select some text (move to start of text, C-space, move to end of text, C-space) and then run this command. You will be prompted for the element to use. This element will then be inserted immediately before and after your marked region.
Runs sgml-untag-element. Place the point within the start or end tag of an element you want to remove, and run this command. The element's start and end tags will be removed.
Runs sgml-fill-element. Will recursively fill (i.e., reformat) content from the current element in. The filling will affect content in which whitespace is significant, such as within <programlisting> elements, so run this command with care.
Runs sgml-edit-attributes. Opens a second buffer containing a list of all the attributes for the closest enclosing element, and their current values. Use TAB to navigate between attributes, C-k to remove an existing value and replace it with a new one, C-c to close this buffer and return to the main document.
Runs sgml-validate. Prompts you to save the current document (if necessary) and then runs an SGML validator. The output from the validator is captured into a new buffer, and you can then navigate from one troublespot to the next, fixing markup errors as you go.
Doubtless there are other useful functions of this mode, but those are the ones I use most often.
In order to promote consistency between the myriad authors of the Handbook, some guidelines have been drawn up for Handbook authors to follow.
Do not use contractions. Always spell the phrase out in full. “Don't use contractions” would be wrong.
Avoiding contractions makes for a more formal tone, is more precise, and slightly easier for translators.
In a list of items within a paragraph, seperate each item from the others with a comma. Seperate the last item from the others with a comma and the word “and”.
For example, look at the following quote;
This is a list of one, two and three items.
Is this a list of three items, “one”, “two”, and “three”, or a list of two items, “one” and “two and three”?
It is better to be explicit and include a serial comma;
This is a list of one, two, and three items.
Try not to use redundant phrases. In particular, “the command”, “the file”, and “man command” are probably redundant.
These two examples show this for commands. The second example is preferred.
Use the command cvsup to update your sources
Use cvsup to update your sources
These two examples show this for filenames. The second example is preferred.
… in the filename /etc/rc.local…
… in /etc/rc.local…
These two examples show this for manual references. The second example is preferred (the second example uses <citerefentry>).
See man edquota for more information.
See edquota(1) for more information.