This page gives contributors a quick overview of tips and best practices for writing in AsciiDoc. It is for sure not complete nor covers all possibilities, but gives a quick reference for common used writing and formatting tasks. For a complete reference see the Asciidoctor Documentation. Also see the AsciiDoc Syntax Quick Reference guide.
Table of Contents
- Initial Reading
- File Locations
- Links
- Images
- Include
- Table of Contents
- Code Blocks
- Literal Text and Blocks
- Attributes
- Admonition
- Air Quotes
- Preserve Line Breaks
- Text Formatting
- Keyboard Shortcuts and UI Button Text
- Menu Selections
- Lists
- Headers, Titles, Sections, Anchors and Paragraph Titles
- Tables
- Conditional Rendering
- TabSets
- Comments
- Relocating or Renaming Files
Here is a good starting point to get a quick Antora overview Three Core Antora Concepts
- All documents are written into the directory
modules
/module_name
/pages
/<path>
- All images are written into the directory
modules
/module_name
/assets/images
/<path>
- All examples are written into the directory
modules
/module_name
/examples
/<path>
When using paths to include, you might need to use the module_name
when linking to another module,
but you must not use pages
, assets/images
or examples
as the path component, only <path>
.
See the examples in the relevant sections.
In a nutshell, there are two kind of links.
- External links (referencing content outside the documentation)
- Internal links (referencing content inside the documentation)
Reference: Links
A link
follows this style: http(s)://domain/#section[Printed Name]
Where #section
and [Printed Name]
are optional components.
The link:
prefix is only needed when the target is not a URI. That's because the URI protocol is an implicit
macro (in other words, http(s): is recognized as a macro prefix of an implicit link).
Example: https://github.com/owncloud-docker/server#launch-with-plain-docker[in the GitHub repository]
A URL may not display correctly when it contains characters such as underscores (_), carets (^) or double quotes (") Please see Troubleshooting Complex URLs how to solve that.
This is an example of an URL containing problematic characters which needs special treatment:
https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
Strongly in favour of using attributes which greatly improves readability while authoring the document.
= The Page Header
:internal-link-name-url: https://example.com/content/link_can_be_very_long
Text {internal-link-name-url}[highlighted text] text.
For the special case when the URL also contains double quotes ("), you must additionally replace them manually with %22
(utf-8 encoding) in the attribute used.
It is important that :internal-link-name-url:
is placed directly below the page header.
Any number of these link attributes can be added. Without being mandatory, it has turned
out as a matter of good practice to end your link name with -url
.
NOTE If you want to prevent automatic linking of a URL, prepend it with a backslash (\). This will create text but not a clickable link and can be used for example URLs. This method helps prevent false positives when checking broken links.
Example:
This is an example of an unlinked web address: \http://example.com
The above example renders as: This is an example web address: http://example.com
but there is no link.
See Troubleshooting URLs for more possibilities.
Prefix: xref:
Reference: Cross Reference
In a nutshell, an internal link called Cross Reference
can link to
- an in-page reference
- a documentation file
- a section title or anchor name inside a documentation file
All content you want to reference must be inside the directory structure of modules/
.
An xref
is usually written in the following example style:
xref:module_name:<path>/file.adoc#section[Printed Name]
Where module_name:
, #section
and [Printed Name]
are optional components.
module_name:
is mandatory when referenced content is not in the same module.
<path>
is the relative path via the module name to your referenced file.
You can reference a section or an anchor inside the same file, another file - even in another module.
Section titles automatically create references, where the text is converted to lower case characters
and all special characters including an underscore are converted to a dash (_
)
You can create anchors manually anywhere in the page by using following methods:
- text
[#anchor-name]
text (anchor-name will not be printed, it is only the reference point) - text
[#anchor-name]#Anchor text to be referenced to#
text (Anchor text will be printed)
Reference Examples:
-
This example references a section title inside the same document:
xref:section-title[FAQ]
-
This example references a manual anchor inside the same document:
xref:anchor-name[FAQ]
-
This example references another file:
xref:configuration/server/occ_command.adoc[Market app]
-
This example references another file and a particular section title:
xref:configuration/server/occ_command.adoc#apps-commands[Market app]
-
This example references another file in another module and a particular section title:
xref:admin_manual:configuration/server/occ_command.adoc#apps-commands[Market app]
Strongly In general it`s advisable to use a ToC (Table of Contents) instead of a list of xref´s.
Note: Use a link checker regularly to find broken links to section titles or anchors. If an anchor link is broken, a build will not report an error as the page itself is accessible.
Prefix: image
Reference: Images
All images have to be stored in a path under modules
/module_name
/assets/images
/<path>
An image
is written in following example style: image:<path>/image_name[Alternative Image Text, options]
Please use the comma as separator for one or more options.
The , options
part is optional. Here you can define e.g. the sizing of an image like , width=40%
Example: image:configuration/files/encryption1.png[Encryption]
There are two ways that an image is treated defined by either using image:
or image::
When using image:
, the image will be part of the text written. This is useful when you want to have
an image part of the text flow like an icon you reference to.
When using image::
, the image is not part of the text written and stands on its own. This means it
will be rendered into a new line and be centered by default if not otherwise defined by an option like
align="center|left|right"
IMPORTANT Please be advised, in case you use an Alternative Image Text, not to use double quotes to highlight some text elements. Double quotes will be rendered properly when the html documentation is built, but creating the pdf will return a warning that the string can not be parsed and the complete image link is broken. You can avoid that by using single quotes and ticks (not backticks!) instead.
Bad:
image:enterprise/firewall/firewall-3.png[Protecting files tagged with "Confidential" from outside access]
Good:
image:enterprise/firewall/firewall-3.png[Protecting files tagged with 'Confidential' from outside access]
Prefix: include
Reference: Include
The include directive provides a way to import content from another file into the current document.
An include
is written in following example style: include::<path>/file[<attrlist>]
When using asciidoc
files to include, the <attrlist>
option contains as example the leveloffset=+1
to correct the level offset of the file included.
You can include example files like scripts or include documentation files. Both types are used to make the raw documentation files easier to read and to maintain.
When creating example files, these files must be saved into a path of the examples directory: module_name
/examples
The directive consists of following components:
include::{examplesdir}<additional-path>/file.ext[]
Example:
include::{examplesdir}installation/post-installation-steps.sh[]
{examplesdir}
will be resolved by the build process automatically
If you include a standard page (a page that is stored in the pages directory) into another page, you must set the page-partial
AsciiDoc attribute in the document header of the page being included.
= The Page Header
:page-partial:
Page contents.
Example:
include::encryption-types.adoc[leveloffset=+1]
(the including file in this example is in the same directory as the included file)
Prefix: toc
Reference: Table of Contents (ToC)
A table of contents (ToC) is, if not otherwise defined, an index of section and subsection titles that can be automatically generated from the pages structure when converting a document with Asciidoctor.
The easiest way of adding a ToC is shown in the following example.
= The Page Header
:toc:
Page contents.
Please also see additional directives like:
toc-title
,
toclevels
or
In-Document Placement
IMPORTANT All attributes of kind :name:
must be direct under the page header without blank lines.
Reference: Listing and source code blocks
Reference: Building blocks in AsciiDoc
[source,<language>]
----
text
text
----
Optional define the <language>
Example:
[source,bash]
----
subscription-manager repos --enable rhel-server-rhscl-7-rpms
----
You can also use include
in code blocks to include an example.
Example:
[source,bash]
----
include::example$installation/post-installation-steps.sh[]
----
- Use
plaintext
for all examples not belonging to any language as this will properly trigger css. - Note that you can copy a source block by clicking the copy symbol to the right of the example without the bash prompt if one is present.
IMPORTANT For highlighting bash
commands properly, you need to distinguish between console
and bash
as source language:
- Use
console
whenever there is a bash prompt with one of the following prompt characters> % $ #
where there can also be up to 3 whitespaces before the bash prompt, or a bash prompt like[test@ubuntu~]$
. The bash prompt will be visible, rendered differently but can't be selected with the mouse manually.bash
commands after the bash prompt will be highlighted. Note that if there is no bash prompt upfront, no highlighting will take place! - Use
bash
whenever there is no bash prompt upfront and you either show shell commands or bash scripts.
When creating examples that show how to use occ, ensure that you use the occ-command-example-prefix
attribute.
Doing so will keep all examples of its use consistent throughout the documentation.
Note: when used within a source code block, as in the following example, subs="attributes+"
has to be set, otherwise it won't render properly:
[source,bash,subs="attributes+"]
----
{occ-command-example-prefix} -h
----
This will print out the following when rendered in the docs:
sudo -u www-data occ -h
Reference: Literal Text and Blocks
Literal paragraphs and blocks display the text you write exactly as you enter it. Literal text is treated as pre-formatted text.
Example:
....
Checking system health.
- file permissions are ok.
....
Reference: Document Attributes
Reference: Inline Passthroughs
Attributes are a way of creating a variable with content which then can be used throughout the document. Using attributes increases readability a lot and makes it easy to change content one time for all locations used. Attributes are written on top of the page and have the following form:
Definition:
:name-of-an-attribute: value
Usage:
This is some text {name-of-an-attribute} which continues here.
Attributes can also be used in scripts when you want to handover common used values. In this case, you must define the attributes and macros that are handed over to the script for processing. "macros" is e.g. needed, when using inline passthroughs:
[subs=attributes+,+macros]
----
include...
----
When you have parts of texts or inside a script where you must render the content as it is, which is necessary for e.g. language constructs, read the Antora Inline Passthroughs section referenced above.
Reference: Admonitions
Reference: Admonition blocks
An admonition paragraph is rendered in a callout box with the admonition label — or its corresponding icon — in the gutter.
Asciidoctor provides five admonition style labels: NOTE
, TIP
, IMPORTANT
, CAUTION
and WARNING
Use this way when you just have to write text.
A simple admonition
is written in the following style: <label>:
Text
Example:
NOTE: If you have a large ownCloud installation and have
shell access, you should ...
A complex admonition
can contain special formatting, tables, lists, literal text and blocks
and is written in the following style, where ====
define the begin/end of the admonition block:
[<label>]
====
your complex text
====
Example:
[TIP]
====
We strongly encourage you to put your server in single user mode before setting up encryption.
To do so, run the following command:
....
sudo -u www-data occ maintenance:singleuser --on
....
====
Reference: Air Quotes
If you want to quote sentences or statements but not using an admonition, you can use air quotes. Air quotes are two double quotes on each line, emulating the gesture of making quote marks with two fingers on each hand.
Example:
""
Not everything that is faced can be changed.
But nothing can be changed until it is faced.
""
Reference: Line Breaks
Since adjacent lines of text are combined into a single paragraph, you can wrap paragraph text or put each sentence or phrase on a separate line. The line breaks won’t appear in the output.
If you want the line breaks preserved, use a space followed by the plus sign +
.
You can use this method also in tables or lists.
Example:
This is the first line, +
This is the next line separated by a line break.
Reference: Text Formatting
There are various ways to emphasize text.
You can use styles like bold
, italic
, etc respectively quote
text.
If you want to print a tick or backtick or curly brace etc as it is, you must escape it. Note, that if you want to print a full string without blanks in between like {my_text}
, you only need to escape the first curly brace \{my_text}
Please see the reference link for more details.
Reference: Keyboard Shortcuts
Reference: UI buttonss
You can create a button styled text like you want a user to press specific keyboard button(s) or browser text buttons.
The syntax for keyboard shortcuts is: kbd:[key(+key)*]
The syntax for UI button text is: btn:[text]
Examples:
kbd:[F11]
kbd:[Ctrl+T]
kbd:[Ctrl+Shift+N]
kbd:[Show disabled apps]
btn:[OK]
btn:[Open]
Reference: Menu Selections
IMPORTANT You must set the :experimental:
attribute to enable the UI macros.
Trying to explain to someone how to select a menu item can be a pain. With the menu macro, the symbols do the work.
The syntax for this is: menu:start[next > next > *]
Example:
Go to menu:Settings[Admin > Apps] and click on kbd:[Show disabled apps]
Reference: Unordered Lists
To create a list, use the *
sign.
You can give your list a title by adding on top of the list a .
directly followed by the text without a space.
If you want to nest your list, use multiple *
stars according the nesting level.
When items contain more than one line of text, leave a blank line before the next item to make the list easier to read.
If you want to add additional paragraphs or other block elements, see List Continuation
for more details.
Example:
.List Title
* level 1
** level 2
*** level 3
**** level 4
***** level 5
* level 1
For creating complex list content, such as adding code blocks to a list element, use the following formatting to keep the content correctly linked to the list element:
.Add a source code block as part of a list element's content.
* list header
+
--
Your description text for the following command:
[source,console]
----
sudo service apache2 restart
----
NOTE: You MUST run this command with sudo previleges
--
IMPORTANT Please use title case for titles and sections.
Good: Examples of Title Case
Bad: Examples of title case
Reference: Header
The document header
is a special set of contiguous lines at the start of the document that encapsulates the document title, author and revision information, and document-wide attributes (either built-in or user-defined). The header typically begins with a document title
Reference: Titles
The document title
resembles a level-0 section title, which is written using a single equal sign =
followed by at least one space, then the text of the title. The document title must be the first level-0 section title in the document. The only content permitted above the document title are blank lines, comment lines and document-wide attribute entries.
Reference: Sections
Sections
partition the document into a content hierarchy. A section title represents the heading for a section. Section title levels are specified by two to six equal =
signs. The number of equal signs in front of the title represents the nesting level (using a 0-based index) of the section.
INFO Sections automatically create a referencable anchor.
Section numbering should be in single steps. This means you will get a warning when using =
and then ===
.
Example:
= Document Title (Level 0)
== Level 1 Section Title
=== Level 2 Section Title
If a page TOC (table of content) is defined, section levels are part of the TOC if the TOC setting includes the section level. In the rare case you want to exclude a section from the TOC but keep its referencability, add [discrete]
right over the section.
Example:
= Document Title (Level 0)
:toc:
:toclevels: 3
== Level 1 Section Title
[descrete]
=== Level 2 Section Title
Note: please check for documentation build warnings or use a broken link checker for broken references to anchors!
Each section is by design its own reference ID called an Anchor
which can be referenced with xref in the same or from another document. You can also give the section an own custom ID.
When using Auto-generated IDs
some rules apply:
Compared to AsciiDoc's standard, ownCloud has set its own definition:
- All characters are converted to lowercase
- Spaces, hyphens, and periods are substituted by a dash
-
Example:
xref:my-section[Text to Print]
text
== My Section
text
When using Custom IDs
, those replace the auto-generated once. These are very useful when you want to define a stable anchor for linking to a section using a cross-reference. The benefit of using custom ID's is, that xref is independent of section text changes which can cause broken links.
Example:
xref:custom_id[Text to Print]
text
[[custom_id]]
== My Section
text
Reference: Defining an Anchor
In the same way creating a custom ID (anchor) for sections, you can create an anchor at any location you want to reference to.
Example:
xref:custom_id[Text to Print]
text
[[custom_id]]
text
Reference: Paragraph Title
You can assign a title to any paragraph, list, delimited block, or block macro. In most cases, the title is displayed immediately above the content. If the content is a figure or image, the title is displayed below the content.
The title text is rendered in a more visible style and the intention is usually to highlight the following paragraph inside a section.
INFO Compared to sections, a paragraph title does not create a referencable anchor.
A block title is defined on a line above the element. The line must begin with a dot (.) and be followed immediately by the title text.
Example:
.Title for this Paragraph
Text or lists or...
Reference: Tables
Tables are delimited by |===
and made up of cells.
Cells are separated by a vertical bar |
.
There are many ways to create and format tables, please see the reference for more details.
You can also take a look to already created tables in the documentation.
Example with defining table and cell width size plus the use of headers:
[width="80%",cols="30%,70%",options="header"]
|===
| Header of column 1 | Header of column 2
| Cell in column 1, row 1 | long Cell in column 2, row 1
| Cell in column 1, row 2 | long Cell in column 2, row 2
| Cell in column 1, row 3 | long Cell in column 2, row 3
|===
This example shows that columns can also be written underneath:
[width="90%",cols="20%,80%",options="header",]
|===
| Directory
| Description
| `data/<user>/files_encryption`
| Users’ private keys and all other keys necessary to decrypt the users’ files.
| `data/files_encryption`
| Private keys and all other keys necessary to decrypt the files stored on a system wide external storage.
|===
If you want to use block-level content in cells, such as a block image, you need to set the
cell type to a
, short for "asciidoc", which treats it as a standalone AsciiDoc document.
[cols=",,",options="header"]
|===
| Classic theme
| Dark theme
| Light theme
a| image:themes/classic.png[ownCloud iOS App - Classic theme]
a| image:themes/dark.png[ownCloud iOS App - Dark theme]
a| image:themes/light.png[ownCloud iOS App - Light theme]
|===
You can also align content in cells. Without the following directives, cells are always aligned top/left. You can set the alignment for complete columns or individual cells. The style for the alignment is always horizontal dot vertical. The dot separates the horizontal and vertical directive.
Examples:
^ center only, top automatically
^.> center, bottom
.> left automatically, bottom
Directives horizontal and vertical
`^` center center
`<` left top
`>` right bottom
To use these directives, you can either set them into the cols=""
definition which is then used for all
columns like cols="^,^.>"
or at the beginning of an individual cell ^.>| cell text
.
If you want to make a headline above a table which does not render as table headline, you need to mark the headline accordingly. To do so, see the following example:
[caption=]
.Following will render as headline and not as "Table 1. Following..."
[width="50%",cols="40%,50%",options="header"]
|===
...
References: Conditionals
Antora can render conditionally. This is e.g. needed, when content can be rendered to html but not to pdf. In these cases, you have to use a conditional render directive which renders content based on an attribute which defines the type to be rendered. ownCloud has created predefined site wide attributes for this case when the documentation is built for html or pdf.
ifeval::["{format}" == "html"]
...
endif::[]
or
ifeval::["{format}" == "pdf"]
...
endif::[]
ownCloud has added the AsciiDoc tabset
extension for the documentation. With tabsets, you can create tabs inside
your document which is very useful, for example, for scripts in different languages for the same task.
Attention: TabSets, by nature, cannot be rendered in pdf. You have to use conditional rendering and an own description for html and pdf.
[tabs]
====
Tab A::
+
--
Tab A contents
--
Tab B::
+
--
Tab B contents
--
====
Reference: Comments
If you want to add a single line comment in your page to remark a writers note which will not be rendered, use two consecutive slashes //
Example:
// Needs revision as a new release will change the parameter.
If you want to comment a block, put the block between four slashes ////
Example:
////
Needs revision as a new release will change the parameter.
Maybe complex to do but lets see.
////
The following procedure is necessary to optimize search engines (SEO). This method will help with updating search engine results over time.
In case you relocate a page to another physical location, or you rename a page, you have to do two things:
- Correct the path in the navigation
- Add a
:page-aliases:
attribute in the document moved
The page-alias attribute, which you can see in the example below, lists one or more pages that redirect to the current page. This attribute is given one or more AsciiDoc files that will redirect to the current page.
Example:
= Page Title
:page-aliases: upgrade/service/apache.adoc