AsciiDoc basics
AsciiDoc is fully documented, and its documentation is actively maintained. This document has information about AsciiDoc markup to get you started.
For details and additional options, see:
-
AsciiDoc/Asciidoctor writers' guide.
-
AsciiDoc quick reference.
-
Asciidoctor user manual.
In addition, you can ask questions in https://asciidoctor.zulipchat.com/
Best practice is to test the PDF build often to ensure that you have not accidentally introduced something that breaks the build.
|
Send questions to help@riscv.org. |
Paragraphs
In AsciiDoc, normal paragraphs do not require markup.
To create a new paragraph, put a space after the earlier line of text and continue.
Basics of blocks and indents
If you add an indent, your indented text becomes a block like this.
-
You can add indented, explanatory paragraphs to lists.
Add a
+directly preceding the line of text that you want to indent within the list. -
Another point.
Using the
+to create an indented paragraph works only within the context of a numbered or bulleted list.
AsciiDoc/Asciidoctor supports code blocks with syntax highlighting for many languages. You can use either periods or dashes to indicate code blocks, and use macros to indicate that the block has code in the specified language, as in the following example:
[source,python]
....
mono-spaced code block
add a1,a2,a3; # do an ADD
....
This example renders as follows:
mono-spaced code block
add a1,a2,a3; # do an ADD
See Admonition blocks for additional information about blocks.
Headers
When you author in AsciiDoc, you cannot jump directly from a Head 1 to a Head 3 or 4. Your headers must appear in sequence from Head 1 to Head 2, and onward. If you skip over a header in the sequence, Asciidoctor throws an error.
The following example is a valid sequence of headers.
= Title head (book or report title)
[colophon]
= Colophon head (in frontmatter, used for preface)
[[chapter_title]]
== Head 1 (chapter)
=== Head 2 (section)
==== Head 3 (subsection)
===== Head 4 (sub-subsection)
[appendix]
== Appendix title
[index]
Index
Settings in the header file (modules/ROOT/pages/spec-sample.adoc in the docs-spec-template repository) trigger auto-generation of Appendix prefixes and of the Index (among other things).
|
Lists
Create unordered lists with the * before the list item. Ordered lists require a . Add a space between any supporting text at the beginning of a list.
Unordered list
To create an unordered list, place a * and a space before an item. Put each new list item on a new line. Add a space between any supporting text at the beginning of a list.
Example:
* Priv
* Unpriv
* Debug
Example output:
-
Priv
-
Unpriv
-
Debug
Ordered list
To create an ordered (numbered) list, place a . and a space before an item. Put each new list item on a new line. Add a space between any supporting text at the beginning of a list.
. Priv
. Unpriv
. Debug
Example output:
-
Priv
-
Unpriv
-
Debug
Nested list
To create a nested unordered list, use `** ` before the nested item.
* Priv ** Intro *** Definitions ** CSRs * Unpriv
Example output:
-
Priv
-
Intro
-
Definitions
-
-
CSRs
-
-
Unpriv
To create a nested ordered list, use `.. ` before the nested list item.
. first item
.. nested item
.. second nested item
. back to original level.
Example output:
-
first item
-
nested item
-
second nested item
-
-
back to original level.
You can also create an unordered list that has a nested ordered list (or an ordered list that has a nested unordered list).
* unordered item
.. numbered item
.. second numbered item
* another bullet
Example output:
-
unordered item
-
numbered item
-
second numbered item
-
-
another bullet
Hyperlinks and cross references
Asciidoctor automates some linking as follows:
-
Recognizes hyperlinks to Web pages and shortens them for readability.
-
Automatically creates an anchor for every section and discrete heading.
Hyperlinks
To create highlighted links, use the pattern in the following example:
https://asciidoctor.org[Asciidoctor]
You can set attributes for your external links
Cross references
Use macros for cross references (links within a document) as in the following example:
<<Index markers>> describes how index markers work.
This example renders as:
[Index markers] describes how index markers work.
For more information about options, see Cross References.
Tables
By using tables, you can group information into logical units, which can make the infromation presented easier to understand.
General rules for tables
Follow these general rules when you create a table.
-
Avoid tables in the middle of lists.
-
Do not use tables to lay out a page. For example, if you have a long list of items, do not use a 2 column table to save space. The information should make sense side by side.
-
Do not create a table that has a single row or a single column, unless you are following an earlier layout. For example, if each section in a chapter includes a table of options, then use a table even if one of the sections has only a single option.
-
Always use table headers and captions to make your tables more accessible.
-
Use introductory sentences for your table. For example, "The following table has the options for the CSR." You can use either a period or a colon for your introductory sentence.
-
Do not refer to the "table above" or the "below table". Use words such as "The following table" or "The preceeding table".
|
Never use automated wrapping for table titles, figure captions, and example captions. Asciidoctor reads a hard return as an indicator to start a new "Normal" paragraph. |
Simple table
The following example shows a simple table with 2 rows and 2 columns. To indicate a new row, put a empty line between them.
[cols="1,1"]
|===
|Cell in column 1, row 1
|Cell in column 2, row 1
|Cell in column 1, row 2
|Cell in column 2, row 2
|===
Results in the following table.
Cell in column 1, row 1 |
Cell in column 2, row 1 |
Cell in column 1, row 2 |
Cell in column 2, row 2 |
Adding table headers
Headers can add additional information to your table, making them easier to understand.
You can add a header row by adding the first row of cells directly in a line.
[cols="1,1,1"] |=== |Col 1, header row|Col 2, header row|Col 3, header row |Cell in col 1, row 2 |Cell in col 2, row 2 |Cell in col 3, row 2 |===
Or you can use the header option.
[%header,cols="1,1,1"] |=== |Col 1, header row |Col 2, header row |Col 3, header row |Cell in col 1, row 2 |Cell in col 2, row 2 |Cell in col 3, row 2 |===
Either table renders with table headers.
| Col 1, header row | Col 2, header row | Col 3, header row |
|---|---|---|
Cell in col 1, row 2 |
Cell in col 2, row 2 |
Cell in col 3, row 2 |
Table captions
The modules/ROOT/pages/spec-sample.adoc file in the docs-spec-template repository sets the full cross-reference attribute to enable captions to display from targets in the anchors. You can set captions for tables, blocks, and illustrations. If you do not offer a caption, Asciidoctor defaults to the basic cross-reference style.
To set a caption for a table or image, use the pattern as follows:
The following table, <<trapcharacteristics,Characteristics of traps>> shows the characteristics of each kind of trap.
[[trapcharacteristics,Characteristics of traps]]
.Characteristics of traps.
[cols="<,^,^,^,^",options="header",]
|===
| |Contained |Requested |Invisible |Fatal
|Execution terminates |No |Nolatexmath:[$^{1}$] |No |Yes
|Software is oblivious |No |No |Yes |Yeslatexmath:[$^{2}$]
|Handled by environment |No |Yes |Yes |Yes
|===
The following table, Table 1 shows the characteristics of each kind of trap.
| Contained | Requested | Invisible | Unrecoverable | |
|---|---|---|---|---|
Execution terminates |
No |
No |
No |
Yes |
Software is oblivious |
No |
No |
Yes |
Yes |
Handled by environment |
No |
Yes |
Yes |
Yes |
AsciiDoc tables from CSV data.
You can also create AsciiDoc tables directly from CSV data. Set the format block attribute to csv and insert the data inside the block delimiters directly:
[%header,format=csv]
|===
Artist,Track,Genre
Baauer,Harlem Shake,Hip Hop
The Lumineers,Ho Hey,Folk Rock
|===
The prior example renders as follows:
| Artist | Track | Genre |
|---|---|---|
Baauer |
Harlem Shake |
Hip Hop |
The Lumineers |
Ho Hey |
Folk Rock |
There are many formatting options available. While some of the property settings are cryptic, they can be quite useful. There are examples available at https://asciidoc.org/newtables.html. Here is an example showing spans alignment in tables from that page:
[cols="e,m,^,>s",width="25%"]
|============================
|1 >s|2 |3 |4
^|5 2.2+^.^|6 .3+<.>m|7
^|8
|9 2+>|10
|============================
Which renders as follows:
1 |
2 |
3 |
4 |
5 |
|
|
|
8 |
|||
9 |
|
||
The following example is code for a numbered encoding table with link target.
| We have added annotations to the code to illustrate their use. |
[[proposed-16bit-encodings-1] (1)
.proposed 16-bit encodings-1 (2)
[width="100%",options=header]
|===
|15 |14 |13 |12 |11 |10 |9 |8 |7 |6 |5 |4 |3 |2 |1 |0 |instruction
3+|100|1|0|0|0 2+|field|0 |0 2+|00 | field 2+|00|mnemonic1
3+|100|1|0|0 3+|field|bit|1 3+|field 2+|00|mnemonic2
3+|110|1|0|0 3+|field|1 |0 3+|field 2+|00|mnemonic3
17+|This row spans the whole table
3+|100|1|1|1 8+| field 2+| 00 | mnemonic4
|===
-
Link target.
-
Numbered table title.
The earlier example results in the following table.
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | instruction |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
100 |
1 |
0 |
0 |
0 |
field |
0 |
0 |
00 |
field |
00 |
mnemonic1 |
|||||
100 |
1 |
0 |
0 |
field |
bit |
1 |
field |
00 |
mnemonic2 |
|||||||
110 |
1 |
0 |
0 |
field |
1 |
0 |
field |
00 |
mnemonic3 |
|||||||
This row spans the whole table |
||||||||||||||||
100 |
1 |
1 |
1 |
field |
00 |
mnemonic4 |
||||||||||
Unicode symbols
For PDFs, five-digit unicode symbols generally do not work and some other unicode symbols are buggy. This failure happens because the Ruby asciidoctor-pdf toolchain makes use of Prawn to build PDFs and it is Prawn that has the problems.
Here are a few unicode examples from https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references that might be useful:
As an example, encode ♦ as follows:
♦
| sym | num | name |
|---|---|---|
^ |
94 |
caret |
|
136 |
|
⋮ |
8942 |
vdots |
♦ |
9830 |
name |
" |
0034 |
name |
w |
0077 |
w |
∴ |
8756 |
therefore |
♯ |
9839 |
sharp |
ш |
1096 |
shcy |
ϖ |
982 |
piv varpi |
ω |
969 |
omega |
℘ |
8472 |
weierp wp |
∑ |
8721 |
sum |
∞ |
8734 |
infin |
∫ |
8747 |
integral |
≠ |
8800 |
not equal to |
≤ |
8804 |
le |
≥ |
8805 |
ge |
≈ |
8776 |
numerical approximation |
D |
68 |
mathematical D? |
⇒ |
8658 |
rightwards double arrow |
X |
88 |
Latin Capital x |
χ |
967 |
Greek x |
× |
215 |
times |
☑ |
9745 |
boxed checkmark |
r |
114 |
latin small letter r |
For many other symbols, use asciidoctor-mathematical. See [Superscripts and other mathematical notations].
| sym | num | name |
|---|---|---|
⍼ |
9084 |
angzarr not working |
⋙ |
8921 |
ggg not working |
↩ |
8617 |
hookleftarrow not working |
⍻ |
9083 |
not checkmark not working |
Mathematical notations
| Asciidoctor-mathematical has some limitations. For inline expressions, the graphical representations are displayed small and center vertically. In some cases where there is a single-character Asciidoctor-mathematical expression, it unintentionally is displayed as a superscript. For this reason, always use viable options such as italics or unicode (see Unicode symbols). |
Superscripts and subscripts
To indicate a superscript, enclose the string for the superscript in carets as in the following example:
2^8^
Which renders as:
28
You can indicate text in a superscript as well:
1234^NOTE^
Which renders as:
1234NOTE
For subscripts, use tildes:
C~2~ H~6~
With the following result:
C2 H6
An example:
"`Well the H~2~O formula written on their whiteboard could be part of a shopping list, but I don't think the local bodega sells E=mc^2^,`" Lazarus replied.
Renders as:
"Well the H2O formula written on their whiteboard could be part of a shopping list, but I don’t think the local bodega sells E=mc2," Lazarus replied.
Latexmath
You can make use of LaTeX notation as in the following:
latexmath:[$C = \alpha + \beta Y^{\gamma} + \epsilon$]
Which renders as:
|
Latexmath rendering has some limitations with respect to sizing and placement inline. This happens because of how the images for the mathematical renders symbols within the build process. For this reason, avoid using single character latexmath expressions inline and preferentially make use of unicode or superscripts and subscripts when possible. |
Stem content
The :stem: latexmath setting makes use of asciidoctor-mathematical for asciidoctor-pdf output.
Asciidoctor Mathematical is a Ruby gem that uses native extensions. It has a few system prerequisites that limit installation to Linux and macOS. See the README in the RISC-V docs-templates repo for information on the asciidoctor-mathematical install.
[stem]
++++
sqrt(4) = 2
++++
In some cases, you might want to make use of unicode characters. Remember that asciidoctor-pdf supports only decimal character references. See https://github.com/asciidoctor/asciidoctor-pdf/issues/486
For updates to asciidoctor-pdf, see https://github.com/asciidoctor/asciidoctor-pdf.
Admonition blocks
Five types of standard admonition blocks are available in AsciiDoc. RISC-V uses these five types with the default icons.
| The admonition type is not displayed, only the icon. |
- Note
-
Highlight extra information that should stand out from the rest of the text. A "by the way, you should know this" statement.
| example of note type |
- Caution
-
Cautions users about a condition or action that can lead to bad outcomes such as personal injury or damage equipment. A "we don’t recommend" statement.
| example of caution type |
- Warning
-
Warns users about a situation that is undesirable. A "Do not do this!" or "You must do this" statement.
| example of warning type |
- Important
-
Information that a user must have. For example, "After you set your password, you cannot change it."
| example of important type |
- Tip
-
Used for Non-normative text such as clarification or hints for implementers or to convey design rationale and why the team discontinued other options. RISC-V tech team is working on a solution that enables users to turn off these admonitions.
| example of tip type |
As a general rule, follow these guidelines for admonitions:
-
Understand that admonitions are interruptions. They should be relevant to the topic, but not necessary. If the reader skips reading it, they can still succeed.
-
If the information is necessary, make it part of the topic and even add a heading. do not put it in an admonition.
-
Limit admonitions to a maximum of 3 on a page (standard PDF page - longer HTML pages can use more.)
-
Do not include results, steps, or prerequisites in admonitions.
-
Make your admonition clear and concise.
Single paragraph admonition
For a single paragraph admonition, use a double colon:
NOTE: Note content.
that renders as:
| Note content. |
Admonition blocks
An admonition block can contain any AsciiDoc content.
[IMPORTANT]
====
As a general rule, follow these guidelines for admonitions:
* Understand that admonitions are interruptions. They should be relevant to the topic, but not necessary. If the reader skips reading it, they can still succeed.
* If the information is necessary, make it part of the topic and even add a heading. Don't put it in an admonition.
* Limit admonitions to a maximum of 3 on a page (standard PDF page - longer HTML pages can use more.)
* Do not include results, steps, or prerequisites in admonitions.
* Make your admonition clear and concise.
====
that renders as:
|
As a general rule, follow these guidelines for admonitions:
|
Admonition with a title
You can add a title to your admonition block.
[WARNING]
.Security vulnerability
====
*Be aware that RLB introduces a security vulnerability if you set iiiiiit after the boot process is over.* Use with caution, even when you use it temporarily. Editable PMP rules in M-mode gives a false sense of security since it only takes a few malicious instructions to lift any PMP restrictions this way. It doesn't make sense to have a security control in place and leave it unprotected. Rule Locking Bypass is only meant as a way to optimize the allocation of PMP rules, catch errors durring debugging, and allow the bootrom/firmware to register executable _Shared-Region_ rules. If developers / vendors have no use for such functionality, they should never set ``mseccfg.RLB`` and if possible hard-wire it to 0. In any case *RLB should be disabled and locked as soon as possible*.
====
Rendered:
|
Security vulnerability
Be aware that RLB introduces a security vulnerability if you set it after the boot process is over. Use with caution, even when you use it temporarily. Editable PMP rules in M-mode gives a false sense of security since it only takes a few malicious instructions to lift any PMP restrictions this way. It does not make sense to have a security control in place and leave it unprotected. Rule Locking Bypass is only meant as a way to optimize the allocation of PMP rules, catch errors durring debugging, and allow the bootrom/firmware to register executable Shared-Region rules. If developers / vendors have no use for such functionality, they should never set |
RISC-V admonition icon colors
The admonition icons are set in risc-v_spec-pdf.yml. RISC-V uses custom colors, as indicated in the Table 5.
| note |
| tip |
| warning |
| caution |
| important |
| Icon | default | customized |
|---|---|---|
NOTE |
19407c |
6489b3 |
TIP |
111111 |
5g27ag |
WARNING |
bf6900 |
9c4d4b |
CAUTION |
bf3400 |
c99a2c |
IMPORTANT |
bf0000 |
b58f5b |
Code blocks
AsciiDoc enables code blocks that support syntax highlighting.
For example, preceding a block with a macro [source,json] enables json syntax highlighting:
{
"weather": {
"city": "Zurich",
"temperature": 25,
}
}
While syntax highlighters for machine code that integrate with the Asciidoctor Ruby toolchain do leave something to be desired, the Rouge highlighter enables line numbers within the code examples.
We are numbering examples as in the following:
.A spinlock with fences
[source%linenums,asm]
....
sd x1, (a1) # Arbitrary unrelated store
ld x2, (a2) # Arbitrary unrelated load
li t0, 1 # Initialize swap value.
again:
amoswap.w t0, t0, (a0) # Attempt to acquire lock.
fence r, rw # Enforce "acquire" memory ordering
bnez t0, again # Retry if held.
# ...
# Critical section.
# ...
fence rw, w # Enforce "release" memory ordering
amoswap.w x0, x0, (a0) # Release lock by storing 0.
sd x3, (a3) # Arbitrary unrelated store
ld x4, (a4) # Arbitrary unrelated load
....
With the following result:
sd x1, (a1) # Arbitrary unrelated store
ld x2, (a2) # Arbitrary unrelated load
li t0, 1 # Initialize swap value.
again:
amoswap.w t0, t0, (a0) # Attempt to acquire lock.
fence r, rw # Enforce "acquire" memory ordering
bnez t0, again # Retry if held.
# ...
# Critical section.
# ...
fence rw, w # Enforce "release" memory ordering
amoswap.w x0, x0, (a0) # Release lock by storing 0.
sd x3, (a3) # Arbitrary unrelated store
ld x4, (a4) # Arbitrary unrelated load
Change bars
Change indicators within text files are exceedingly useful and also can be equally complex to implement. Please consider the fact that much of the software programming for Git revolves around handling various kinds of change indicators.
In exploring possible implementation of change bars for RISC-V, we have looked for a solution that is as simple as possible while maximizing value with respect to the time invested in implementing, maintaining, and using the tools and procedures.
The suggested solution makes use of:
-
an AsciiDoc
role. -
modification of two files in the Ruby gem with code snippets (see procedure in the README for https://github.com/riscv/docs-templates).
-
Git features.
-
a few procedures associated, specifically, with Git updates.
Indicate changes
Indicators for the changed lines must be inserted manually:
[.Changed]#SELECT clause#
Text without the change bar
[.Changed]#Text with the change bar#
SELECT clause
Text without the change bar
Text with the change bar
For change bars associated with headings, place the change indicator after the heading indicator and before the text, like the following:
== [.Changed]#SELECT clause#
Footnotes
AsciiDoc has a limitation in that footnotes appear at the end of each chapter. Asciidoctor does not support footnotes appearing at the bottom of each page.
You can add footnotes to your presentation using the footnote macro. If you plan to reference a footnote more than once, use the footnote macro with a target that you identify in the brackets.
Initiate the hail-and-rainbow protocol at one of three levels:
- doublefootnote:[The double hail-and-rainbow level makes my toes tingle.]
- tertiary
- apocalyptic
A bold statement!footnote:disclaimer[Opinions are my own.]
Another outrageous statement.footnote:disclaimer[]
Renders as:
The hail-and-rainbow protocol can be initiated at three levels:
-
double[1]
-
tertiary
-
apocalyptic
A bold statement![2]
Another outrageous statement.[2]
Sidebars
Sidebars provide for a form of commentary.
****
This is content in a sidebar block.
image:example-3.svg[]
This is more content in the sidebar block.
****
This renders as follows:
You can add a title, along with any kind of content. Best practice for many of the "commentaries" in the LaTeX source that elucidate the decision-making process is to convert to this format with the TIP icon that illustrates a conversation or discussion, as in the following example:
.Optional Title
****
Sidebars are used to visually separate auxiliary bits of content
that supplement the main text.
TIP: They can contain any type of content, including admonitions like this, and code examples like the following.
.Source code block within a sidebar
[source,js]
/---- (1)
const { expect, expectCalledWith, heredoc } = require('../test/test-utils')
/---- (2)
****
1 and 2. Escapes are necessary to preserve this as an AsciiDoc code example.
Once the escapes are removed, the above renders with both the admonition and code blocks within the sidebar: