Updated: February 5, 2022

Quality documentation is crucial to the success of FreeBSD, submitting documentation is one of the easiest ways to contribute to the project and anyone is welcome to submit! Willingness to contribute is the only membership requirement.

Documentation Quick-Guide

The first step to contribute is to subscribe to the FreeBSD documentation project mailing list. This is a fantastic resource for any questions or problems involving the documentation.

  1. Install a few packages. The textproc/docproj meta-package installs all of the software needed to edit and build FreeBSD documentation, git is needed to obtain a working copy of the documentation and generate patches with, and python is helpful for work with the FreeBSD documentation
    # pkg install docproj git
  2. Install a local working copy of the documentation from the FreeBSD repository in ~/doc (see Chapter 3, The Working Copy).
    % git clone https://git.freebsd.org/doc.git ~/doc
  3. Configure the text editor:
    • Word wrap set to 70 characters.
    • Tab stops set to 2.
    • Replace each group of 8 leading spaces with a single tab. Specific editor configurations are listed in Chapter 15, Editor Configuration.
  4. Update the local working copy:
    % git pull --ff-only
  5. Edit the documentation files that require changes. If a file needs major changes, consult the mailing list for input. References to AsciiDoctor can be found in Chapter 6. AsciiDoctor Primer and in the AsciiDoc Language Documentation Portal.
  6. Always build-test changes before submitting them. Running make in the top-level directory of the documentation being edited will generate that documentation in split HTML format.
    % make
  7. When changes are complete and tested, generate a “diff file”:
    % cd ~/doc
    % git diff
    > bsdinstall.diff.txt
    Give the diff file a descriptive name.
  8. Submit the diff file using the web-based Problem Report system. If using the web form, enter a Summary of [Patch] short description of problem. Select the Component Documentation. In the Description field, enter a short description of the changes and any important details about them. Use the [ Add an attachment ] button to attach the diff file. Finally, use the [ Submit Bug ] button to submit your diff to the problem report system.

Optional Tools

  • These applications are not required, but can make working on the documentation easier or add capabilities. Both editors include a special mode for editing documents with commands to reduce errors and typing.

1. Editing and Maintaining a Working Copy

The working copy is a copy of the FreeBSD repository documentation tree downloaded onto the local computer. Changes are made to the local working copy, tested, and then submitted as patches to be committed to the main repository. A full copy of the documentation tree can occupy 700 megabytes of disk space. Allow for a full gigabyte of space to have room for temporary files and test versions of various output formats.

Manual Pages

FreeBSD documentation for commands and configuration files can be found within the manual page collection. These consist of two repositories: doc for books and articles, and src for operating system and manual pages. These repositories can contain multiple versions of documentation and source code.

In order to edit manual pages, src will need to be checked out separately.

Choosing a Directory

FreeBSD documentation is traditionally stored in /usr/doc/, and system source code with manual pages in /usr/src/. These directory trees are relocatable, and users may want to put the working copies in other locations to avoid interfering with existing information in the main directories. The examples that follow use ~/doc and ~/src, both subdirectories of the user’s home directory.

Check Out a Copy

A download of a working copy from the repository is called a clone, this can be done with git clone. For example, to checkout the latest version (head) of the documentation tree.

% git clone https://git.freebsd.org/doc.git ~./doc

And to checkout the source code for manual pages:

% git clone https://git.freebsd.org/src.git ~./src

Updating the Working Copy

The FreeBSD repository is frequently updated, even a short time after the initial checkout, changes may have already been made creating differences between the local working copy and the main FreeBSD repository. To update the local version, use git pull on the directory containing the local working copy. Getting into the habit of doing this often before editing document files will be helpful.

% cd ~/doc
% git pull --ff-only

Reverting Changes

Sometimes it turns out that changes were unnecessary, or the writer wants to start over. git restore can “reset” files to their unchanged form

% git restore filename

Making a Diff

After edits to a file or group of files are completed, the differences between the local working copy and the version on the FreeBSD repository must be collected into a single file for submission. These diff files are produced by redirecting the output of git diff into a file:

% cd ~/doc
% git diff > filename

Give the file a meaningful name that identifies the contents. Thhttps://www.freebsd.org/doc/en_US.ISO8859-1/books/fdp-primer/working-copy.htmlis will be important for identifying what type of change was made, and to what part of the tree.

If the diff file is to be submitted with the web “Submit a FreeBSD problem report” interface, add a .txt extension to give the earnest and simple-minded web form a clue that the contents are plain text.

2. Documentation Build Process

Rendering AsciiDoc into Output

Different types of output can be produced from a single AsciiDoc source file.

FORMATS  File Type Description
html HTML An article or book chapter.
pdf PDF Portable Document Format.
epub EPUB Electronic Publication file format.

FreeBSD Documentation Build Toolset

These are the tools used to build and install the FDP documentation.

  • The primary build tool is make(1), specifically Berkeley Make.
  • Hugo
  • AsciiDoctor
  • Git

Understanding Makefiles in the Documentation Tree

There are three main types of Makefiles in the FreeBSD Documentation Project tree.

  • The Makefile in the documentation directory will build only the documentation.
  • The Makefile in the website directory will build only the website.
  • The Makefile at the top of the tree will build both the documentation and the website.

Documentation Makefile

These Makefiles usually take this form: (Some contents have been removed for simplicity sake):


ALL_LANGUAGES=	bn-bd da de el en es fr hu it ja ko mn nl pl pt-br ru tr zh-cn zh-tw

LOCALBASE?=	/usr/local

RUBY_CMD =	${LOCALBASE}/bin/ruby
HUGO_CMD =	${LOCALBASE}/bin/hugo
HUGO_ARGS?=	--verbose --minify
HUGO_OFFLINE_ARGS?= 	--environment offline --verbose --minify
ASCIIDOCTORPDF_CMD=	${LOCALBASE}/bin/asciidoctor-pdf

                                                         .    .    .

.ORDER: all run

.ORDER: requirements
.ORDER: starting-message
.ORDER: starting-message build
.ORDER: build

all: requirements starting-message generate-pgpkeys-txt build
run: requirements starting-message generate-pgpkeys-txt run-local

starting-message: .PHONY
	@echo ---------------------------------------------------------------
	@echo                   Building the documentation
	@echo  included languages: ${LANGUAGES}
	@echo  excluded languages: ${SKIP_LANGS}
	@echo ---------------------------------------------------------------

run-local: .PHONY
		${HUGO_ARGS} -D $(BIND:D--bind=$(BIND)) --baseURL="http://$(.HOST):1313"

build: .PHONY

  The MAINTAINER flag specifies who is the maintainer of this Makefile.
  RUBY_CMD flag specifies the location of the Ruby binary.
  HUGO_CMD flag specifies the location of the Hugo binary.
  ASCIIDOCTOR_CMD flag specifies the location of the AsciiDoctor binary.
  ALL_LANGUAGES flag specifies in which languages the documentation has to be generated.
  .ORDER directives are used to ensure multiple make jobs may run without problem.
  all target builds the documentation and puts the result in ~/doc/documentation/public.
  starting-message shows a message in the CLI to show the user that the process is running.
  run-local runs hugo webserver on port 1313, or a random free port if that is already in use.
  build builds the documentation and puts the result in the ~/doc/documentation/public.

Website Makefile

These Makefiles share a similar format to documentation Makefiles, however, no languages tag is used.

Here is an example of the second half of a website Makefile:

.ORDER: all run

.ORDER: starting-message generate-releases
.ORDER: starting-message build
.ORDER: generate-releases build

all: starting-message generate-releases run 

starting-message: .PHONY 
	@echo ---------------------------------------------------------------
	@echo                   Building the website
	@echo ---------------------------------------------------------------

generate-releases: data/releases.toml

	${RUBY_CMD} ./tools/releases-toml.rb

run-local: .PHONY
	    ${HUGO_ARGS} -D $(BIND:D--bind=$(BIND)) --baseURL="http://$(.HOST):1313"

build: .PHONY 

all target builds the website and puts the result in ~/doc/website/public.
generate-releases calls the script used to convert from AsciiDoc variables to TOML variables. With this conversion, the releases variables can be used in AsciiDoc and in the Hugo custom templates.
build builds the website and puts the result in the ~/doc/website/public.

3. AsciiDoctor Primer

Most FDP documentation is written with AsciiDoc. This chapter explains what that means, how to read and understand the documentation source, and the techniques used. To get a complete reference of the AsciiDoctor capabilities please consult the Asciidoctor documentation. Some of the examples have been taken from the AsciiDoc Syntax Quick Reference.


AsciiDoctor supports six headings levels. If the document type is article only one level 0 (=) can be used. If the document type is book then there can be multiple level 0 (=) headings.

This is an example of headings in an article.

 = Document Title (Level 0)

 == Level 1 Section Title

 === Level 2 Section Title

 ==== Level 3 Section Title

 ===== Level 4 Section Title

 ====== Level 5 Section Title

 == Another Level 1 Section Title


Paragraphs don’t require special markup in AsciiDoc. A paragraph is defined by one or more consecutive lines of text. To create a new paragraph leave one blank line.

For example, this is a heading with two paragraphs.

 = This is the heading

 This is the first paragraph.
 This is also the first paragraph.

 And this is the second paragraph.


AsciiDoctor supports a few types of lists, the most common are ordered and unordered. To get more information about lists, see AsciiDoc Syntax Quick Reference.

To create an ordered list use the . character.

For example, this is an ordered list.

. First item
. Second item
.. Subsecond item
. Third item

And this would be rendered as.

  1. First item
  2. Second item
    1. Subsecond item
  3. Third item

To create an unordered list use the * character.

For example, this is an unordered list.

* First item
* Second item
** Subsecond item
* Third item

And this would be rendered as.

  • First item
  • Second item
    • Subsecond item
  • Third item

To point to another website the link macro should be used.


  As the AsciiDoctor documentation describes, the link macro is not required when the target starts with a URL scheme like https. However, it is a good practice to do this anyway to ensure that AsciiDoctor renders the link correctly, especially in non-latin languages like Japanese.

To point to another book or article the AsciiDoctor variables should be used. For example, if we are in the cups article and we want to point to ipsec-must these steps should be used.

  1. Include the urls.adoc file from ~/doc/shared folder.
  2. Then create a link using the AsciiDoctor variable to the ipsec-must article.
    extref:{ipsec-must}[IPSec-Must article]


We hope this guide has served as a brief introduction to the process of submitting documentation, programmers should also check out our guide on Contributing to FreeBSD as a Programmer.