---
title: Chapter 6. Asciidoctor Primer
prev: books/fdp-primer/doc-build
next: books/fdp-primer/rosetta
description: A brief introduction to Asciidoctor
tags: ["AsciiDoc", "Asciidoctor", "Primer", "Introduction", "Guide"]
showBookMenu: true
weight: 7
params:
  path: "/books/fdp-primer/asciidoctor-primer/"
---

[[asciidoctor-primer]]
= Asciidoctor Primer
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 6
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/fdp-primer/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

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 link:https://docs.asciidoctor.org/home/[Asciidoctor documentation].
Some of the examples used in this chapter have been taken from the link:https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference[AsciiDoc Syntax Quick Reference].

[[asciidoctor-primer-overview]]
== Overview

In the original days of computers, electronic text was simple.
There were a few character sets like ASCII or EBCDIC, but that was about it.
Text was text, and what you saw really was what you got.
No frills, no formatting, no intelligence.

Inevitably, this was not enough.
When text is in a machine-usable format, machines are expected to be able to use and manipulate it intelligently.
Authors want to indicate that certain phrases should be emphasized, or added to a glossary, or made into hyperlinks.
Filenames could be shown in a “typewriter” style font for viewing on screen, but as “italics” when printed, or any of a myriad of other options for presentation.

It was once hoped that Artificial Intelligence (AI) would make this easy.
The computer would read the document and automatically identify key phrases, filenames, text that the reader should type in, examples, and more. 
Unfortunately, real life has not happened quite like that, and computers still require assistance before they can meaningfully process text.

More precisely, they need help identifying what is what.
Consider this text:

To remove [.filename]#/tmp/foo#, use man:rm[1].

[source,shell]
----
% rm /tmp/foo
----

It is easy for the reader to see which parts are filenames, which are commands to be typed in, which parts are references to manual pages, and so on.
But the computer processing the document cannot reliably determine this.
For this we need markup.

The previous example is actually represented in this document like this:

....
To remove */tmp/foo*, use man:rm[1].

[source,shell]
----
% rm /tmp/foo
----
....

[[asciidoctor-headings]]
== Headings

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
....

[WARNING]
====
Section levels cannot be skipped when nesting sections.

The following syntax is not correct.

....
= Document Title

== Level 1

==== Level 3
....
====

[[asciidoctor-paragraphs]]
== Paragraphs

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-lists]]
== Lists

Asciidoctor supports a few types of lists, the most common are `ordered` and `unordered`.
To get more information about lists, see link:https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/#lists[AsciiDoc Syntax Quick Reference].

[[asciidoctor-ordered-lists]]
=== Ordered lists

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.

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

[[asciidoctor-unordered-lists]]
=== Unordered lists

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

[[asciidoctor-links]]
== Links

[[asciidoctor-links-external]]
=== External links

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

....
link:https://www.FreeBSD.org[FreeBSD]
....

[NOTE]
====
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.
====

[[asciidoctor-links-internal]]
=== Links to another book or article

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.

. Include the [.filename]#urls.adoc# file from [.filename]#~/doc/shared# folder.
+
....
\include::shared/{lang}/urls.adoc[]
....
+
. Then create a link using the Asciidoctor variable to the `ipsec-must` article.
+
....
extref:{ipsec-must}[IPSec-Must article]
....
+
And this would be rendered as.
+
extref:{ipsec-must}[IPSec-Must article]

[NOTE]
====
The `extref` macro is defined as an extension.
It is designed to render the correct link across the different outputs
====

=== Links to the same file or to another file in the same book

Books are structured in different directories to keep a sane layout.
To create a link from one subdirectory of a book to another subdirectory of the
same book, use the `crossref` macro:
....
crossref:doc-build[documentation-makefile, This link]
....
And this would be rendered as

crossref:doc-build[documentation-makefile, This link]

[NOTE]
====
The `crossref` macro is defined as an extension.
It is designed to render the correct link across the different outputs
====

[NOTE]
====
Use the `crossref` macro for intra-document links too.
Although it might be inconvenient to write the name of the current document,
it ensures the correct link is rendered across the different outputs
====

[WARNING]
====
Do not use either the `xref` macro or its shortcut `<<` `>>`.
They do not work well in all output formats.
====

[[asciidoctor-images-icons]]
== Images and Icons

Images and icons play a crucial role in enhancing the overall user experience.
These visual elements are strategically integrated to convey information, clarify concepts, and provide a visually engaging interface.

[[asciidoctor-images]]
=== Images

Images help illustrate complex concepts, making them more accessible to users.

The first step will be to add the image in the images directory in the path:

* [.filename]#~/website/static/images/# for the website.
* [.filename]#~/documentation/static/images/# for the documentation.

For example, to add a new image to the FreeBSD installation process, the image will be saved to the path [.filename]#~/documentation/static/images/books/handbook/bsdinstall/new-image3.png#.

The next step will be to configure the Asciidoctor attributes `images-path` and `imagesdir`.

We are going to use as an example the header of the extref:{freebsd-releng}[FreeBSD Release Engineering] article.

[source,asciidoc]
....
= FreeBSD Release Engineering
:doctype: article

[...]

:images-path: articles/freebsd-releng/ <1>

[...]

:imagesdir: ../../../images/{images-path} <2>

[...]

....

<.> Makes reference to the path inside [.filename]#/static/images# folder.
<.> Makes reference to the Asciidoctor attribute.

Once the image is in the correct path and the Asciidoctor attributes have been configured in the document, the `image` macro can be used.

This is an example:

....
image::new-image3.png[New step in the FreeBSD install process]
....

[TIP]
====
To improve accessibility, it is mandatory to add descriptive text to each image.
====

[[asciidoctor-icons]]
=== Icons

Icons serve as intuitive symbols for quick recognition and navigation.

The first step to use icons is to add the `icons` property to the Asciidoctor properties section, at the top of each document.

....
:icons: font
....

Once the Asciidoctor icon property has been set an icon supported by link:https://fontawesome.com/v4/icons/[Font Awesome] can be added.

This is an example about how to use the `envelope` icon:

....
icon:envelope[link=mailto:test@example.com, title="contact"]
....

[TIP]
====
To improve the accessibility of the website, the `title` attribute is mandatory.
====

[[asciidoctor-conclusion]]
== Conclusion

This is the conclusion of this Asciidoctor primer.
For reasons of space and complexity, several things have not been covered in depth (or at all).
