All Starknet documentation should conform to the same rules and guidelines. See the Starknet documentation style guide.
The rest of this topic details the modular structure and AsciiDoc / Antora requirements and conventions for building Starknet documentation.
- Style guidance and writing guidance
- Adding files to the collection
- Structuring information
- Style guidance
- General text editor guidelines
- Topic metadata
- Conditional text
- Text snippet file metadata
- Attribute files
- File names
- Directory names
- Discrete headings
- Anchoring titles and section headings
- Writing concepts
- Writing procedural topics
- Writing text snippets
- Embedding a local source code file
- Verification of your content
- Images
- Formatting
- Admonitions (Notes, Tips, Cautions…)
- Peer reviews
When you create new files, you must add them to the components/Starknet/modules/<module>/nav*.adoc
file so that the build system can render them in the table of contents.
For possible values of <module>
, see the directories under /components/Starknet/modules/
.
If you don’t include the file in the nav*.adoc
file, Antora includes the file in the built output, but it is not accessible via the TOC.
The documentation guidelines for Starknet build on top of the Red Hat modular docs reference guide. However, because Antora does not natively account for assemblies, Starknet documentation does not use assemblies, so when reading this guide, focus on the information related to modularizing content based on the three major information types:
-
Conceptual
-
Procedural
-
Reference
These Documentation guidelines are primarily concerned with the modular structure and AsciiDoc / Antora requirements for building Starknet documentation. For style guidance, use these style guides in the following order:
-
Starknet documentation style guide Reference this guide first. It provides guidance that is specific to Starknet documentation.
-
Red Hat supplementary style guide for product documentation. This guide overrides certain guidance from the Google developer documentation style guide.
If you cannot find helpful information or if you must deviate from the guidance in any of these guides, open an issue in the Starknet documentation style guide repo. The stakeholders can then discuss and determine if and how to address the issue.
- Style guidance and writing guidance
- Adding files to the collection
- Structuring information
- Style guidance
- General text editor guidelines
- Topic metadata
- Conditional text
- Text snippet file metadata
- Attribute files
- File names
- Directory names
- Discrete headings
- Anchoring titles and section headings
- Writing concepts
- Writing procedural topics
- Writing text snippets
- Embedding a local source code file
- Verification of your content
- Images
- Formatting
- Admonitions (Notes, Tips, Cautions…)
- Peer reviews
-
Set your editor to strip trailing whitespace.
-
The end of each file should have an empty line.
Every topic should be placed in a logical directory under /components/StarkNet/modules
with the following metadata at the top of the file:
[id="<topic-anchor>_{context}"] (1) = Topic title (2)
-
A topic anchor with
{context}
that must be lowercase and must match the topic’s file name. -
Human readable title. To ensure consistency in the results of the leveloffset values in include statements, you must use a level one heading ( = ) for the topic title.
Example:
[id="cli-basic-commands_{context}"] = Basic CLI commands
Starknet documentation uses AsciiDoc’s ifdef/endif
macro to conditionalize and reuse content, down to the single-line level.
For information on conditionalization in AsciiDoc, see Conditionals in the AsciiDoc Language Documentation.
For example, if the same file should appear in Document A and Document B, with only minor differences:
This first line is unconditionalized, and will appear in both _Document A_ and _Document B_. ifdef::document_A[] This line will only appear for _Document A_. endif::document_A[] ifdef::document_B This line will only appear for _Document B_. endif::document_B[] ifndef::document_B This line will not appear for _Document B_. endif::[]
Note
|
While the |
Every text snippet should be placed in the partials
folder for the topic in which they are used, and should contain the following metadata at the top:
// Text snippet included in the following files: (1)
//
// * list of files where this text snippet is included
-
List of topics in which this text snippet is included.
Note
|
An anchor ID and human readable title are not required metadata. This type of component is text only and not intended to be published or cross referenced on its own. See Writing text snippets. |
// Text snippet included in the following files:
//
// * getting_started/pages/account_setup.adoc
// * getting_started/pages/deploying_contracts.adoc
[NOTE]
====
Starknet accounts are smart contracts. As such, creating one involves sending a transaction, and takes a bit longer than creating an EOA on other networks.
You can learn more in https://docs.starknet.io/documentation/architecture_and_concepts/Account_Abstraction/introduction/[What is an account?].
====
Document attributes are effectively document-scoped variables for the AsciiDoc language. The AsciiDoc language defines a set of built-in attributes, and also allows the author (or extensions) to define additional document attributes, which may replace built-in attributes when permitted.
For detailed information on attributes in AsciiDocs, see Document Attributes in the AsciiDoc Language Documentation.
If an attribute is used in multiple files, it is helpful to place those attributes in a single attributes file, and use an include
statement to import those attributes where relevant. The attribute file is a normal AsciiDoc file.
All attribute files must be placed in the partials
directory for the primary topic that uses them. Reference an attributes file using the following syntax:
include::partial$attributes/<file_name>.adoc[]
For example:
include::partial$attributes/attributes.adoc[]
If files in more than one topic reference the same attribute file, use the following syntax, or suggest a new strategy in a Github issue:
-
Create a symlink to the attributes file in the
partials
directory of the parent module for the file that includes the attributes file.
For example: Consider the following files:
-
Attributes file:
/components/Starknet/modules/ROOT/partials/attributes.adoc
-
Content file:
/components/Starknet/modules/useful_info/pages/audit.adoc
To include attributes.adoc
in audit.adoc
:
include::$ROOT:partial$attributes.adoc[]
Try to shorten the file name as much as possible without abbreviating important terms that might cause confusion. For example, the managing-authorization-policies.adoc
file name would be appropriate for a topic entitled Managing Authorization Policies.
If you create a directory with a multiple-word name, separate each word with an underscore, for example backup_and_restore
.
Do not create or rename a top-level directory in the repository and topic map without checking with the docs team first.
If you have a section heading that you do not want to appear in the TOC, for example, if you think that some section is not worth showing up or if there are already too many nested levels, you can use a discrete heading:
To use a discrete heading, just add [discrete]
to the line before your unique ID. For example:
[discrete] [id="managing-authorization-policies_{context}"] == Managing authorization policies
All titles and section headings must have an anchor ID. The anchor ID must be similar to the title or section heading.
You must add the {context}
variable to the end of each anchor ID in topic files. When called, the {context}
variable is resolved into the value declared in the :context:
attribute in the corresponding section of the document. This enables cross-referencing to topic IDs in context when a topic is included in multiple locations.
Note
|
The |
The following is an example of an anchor ID for a topic file title:
[id="sending-notifications-to-external-systems_{context}"] = Sending notifications to external systems
The following is an example of an anchor ID for a second level (==
) heading:
[id="deployment-scaling-benefits_{context}"] == Deployment and scaling benefits
A concept contains information to support the tasks that users want to do and must not include task information like commands or numbered steps.
Avoid using gerunds in concept titles. "About <concept>" is a common concept topic title.
For more information about creating concept topics, see the Red Hat modular docs reference guide and the concept template.
A procedure contains the steps that users follow to complete a process or task. Procedures contain ordered steps and explicit commands.
Use a gerund in the procedure title, such as "Creating".
For more information about writing procedural topics, see the Red Hat modular docs reference guide and the procedure template.
A text snippet is an optional component that lets you reuse content in multiple topics. Text snippets are not a substitute for topics but instead are a more granular form of content reuse.
While a topic is content that a reader can understand on its own (like an article) or as part of a larger body of work (like a guide), a text snippet is not self-contained and is not intended to be published or cross referenced on its own.
Examples include the following:
-
Admonitions that appear in multiple locations.
-
An introductory paragraph that appears in multiple locations.
-
The same series of steps that appear in multiple procedural topics.
-
A deprecation statement that appears in multiple sets of release notes.
Example:
You could write the following paragraph once and include it in each location that explains how to install a cluster using the installer-provisioned default values:
In {product-title} version {product-version}, you can install a cluster on {cloud-provider-first} ({cloud-provider}) that uses the default configuration options.
For more information about creating text snippets, see the Red Hat modular docs reference guide.
You can embed local source code files in AsciiDoc topics.
Use the include
directive to target the local file.
To use a local source code file, add it to the /<module>/attachments/
directory, and include it in your module. For example:
include::attachment$install-config.yml[]
Note
|
Do not include lines by content ranges. This approach can lead to content errors when the included file is subsequently updated. |
You can use AsciiDoc callouts in the source code file. Comment out the callout in the YAML file to ensure that file can still be parsed as valid YAML. Asciidoctor recognizes the commented callout and renders it correctly in the output. For example:
apiVersion: v1 # (1)
All documentation changes must be verified by a subject matter expert before merging. This includes executing all procedure changes and confirming expected results. There are exceptions for typo-level changes, formatting-only changes, and other negotiated documentation sets and distributions.
To include a block image (an image on its own line):
-
Put the image file in the
modules/<module>/images
folder. -
In the
.adoc
content, use this format to link to the image:image::<module>:<image_filename>[<alt_text>]
Notice the double
::
instead of a single:
, as seen in inline image usage.Exampleimage::documentation:architecture_and_concepts:l1l2.png[L1 to L2 messaging]
The image file,
l1l2.png
, is inmodules/architecture_and_concepts/images/
.
For all of the system blocks including table delimiters, use four characters. For example:
|=== for tables ---- for code blocks
Note
|
You can use backticks or other markup in the title for a block, such as a code block |
Code blocks generally show examples of command syntax, example screen output, and configuration files.
The main distinction between showing command syntax and a command example is that a command syntax shows readers how to use the command without real values. An example command, however, shows the command with actual values with an example output of that command, where applicable.
For example:
Run the following command to initialize an account: [source,terminal] ---- starknet new_account --account <account_name> ---- .Example output [source,terminal] ---- Account address: 0x04e93e1fb507d23b398f0a09f5873d3a7769b0e7ed40dbbe8fe7a2e8ea831006 Public key: 0x07a328511fa8552cd61aaaa89076fe40c3566f4594f29324aa754d41d7c7c55e Move the appropriate amount of funds to the account, and then deploy the account by invoking the 'starknet deploy_account' command. NOTE: This is a modified version of the OpenZeppelin account contract. The signature is computed differently. ----
This renders as:
Run the following command to initialize an account:
>starknet new_account --account <account_name>Example outputAccount address: 0x04e93e1fb507d23b398f0a09f5873d3a7769b0e7ed40dbbe8fe7a2e8ea831006 Public key: 0x07a328511fa8552cd61aaaa89076fe40c3566f4594f29324aa754d41d7c7c55e Move the appropriate amount of funds to the account, and then deploy the account by invoking the 'starknet deploy_account' command. NOTE: This is a modified version of the OpenZeppelin account contract. The signature is computed differently.
The following guidelines go into more detail about specific requirements and recommendations when using code blocks:
-
If a step in a procedure is to run a command, make sure that the step text includes an explicit instruction to "run" or "enter" the command. In most cases, use one of the following patterns to introduce the code block:
-
<Step description> by running the following command:
-
<Step description> by entering the following command:
-
<Step description>, run the following command:
-
<Step description>, enter the following command:
-
-
Any example of command line input must begin with a prompt, as follows:
-
A terminal prompt for a normal user should begin with a dollar sign (
$
) prompt:$ <regular_user_permission_command_line_input>
-
A terminal prompt for a superuser should begin with a hash symbol (
#
) prompt:# <superuser_permission_command_line_input>
-
A terminal prompt for a command in a non-standard shell, such as a Docker shell, should use the prompt of that shell. For example:
root@17617744386d:/app# ./player.py
-
-
Avoid using markup in a code block. If you must use any markup in code blocks, see the Asciidoctor documentation on source blocks and substitutions:
-
It can take some trial and error to figure out the correct source block macro to use for the exact markup you want to use.
-
For all code blocks, you must include an empty line above a code block (unless that line is introducing block metadata, such as
[source,terminal]
for syntax highlighting).Acceptable:
Lorem ipsum ---- $ lorem.sh ----
Not acceptable:
Lorem ipsum ---- $ lorem.sh ----
Without the line spaces, the content is likely to be not parsed correctly.
-
Use
[source,terminal]
for CLI commands, and any other commands that you enter in the terminal, to enable syntax highlighting. Any[source]
metadata must go on the line directly before the code block. For example:[source,terminal] ---- $ oc get nodes ----
If you are also showing a code block for the output of the command, use
[source,terminal]
for that code block as well. -
Use source tags for the programming language used in the code block to enable syntax highlighting. For example:
-
[source,cairo]
-
[source,python]
-
[source,javascript]
-
[source,json]
-
-
If your command contains multiple lines and uses callout annotations, you must comment out the callout(s) in the codeblock, as shown in the following example:
To scale based on the percent of CPU utilization, create a `HorizontalPodAutoscaler` object for an existing object: [source,terminal] ---- $ oc autoscale <object_type>/<name> \// (1) --min <number> \// (2) --max <number> \// (3) --cpu-percent=<percent> (4) ---- <1> Specify the type and name of the object to autoscale. <2> Optional: Specify the minimum number of replicas when scaling down. <3> Specify the maximum number of replicas when scaling up. <4> Specify the target average CPU utilization over all the pods, represented as a percent of requested CPU.
-
Separate a command and its related example output into individual code blocks. This enables a reader to easily copy the command using the Copy button on docs.starknet.io.
In addition, prepend the code block for the output with the title
.Example output
to make it consistently clear across the docs when this is being represented. A lead-in sentence explaining the example output is optional. For example:Run the `starknet new_account` command to initialize an account: [source,terminal] ---- $ starknet new_account --account <account_name> ---- The output verifies that a new account was initialized: .Example output [source,terminal] ---- Account address: 0x04e93e1fb507d23b398f0a09f5873d3a7769b0e7ed40dbbe8fe7a2e8ea831006 Public key: 0x07a328511fa8552cd61aaaa89076fe40c3566f4594f29324aa754d41d7c7c55e Move the appropriate amount of funds to the account, and then deploy the account by invoking the 'starknet deploy_account' command. NOTE: This is a modified version of the OpenZeppelin account contract. The signature is computed differently. ----
-
To mark up command syntax, use the code block and wrap any replaceable values in angle brackets (
<>
) with the required command parameter, using underscores (_
) between words as necessary for legibility. For example:To deploy the account you initialized, now run the following command: [source,terminal] ---- $ starknet deploy_account --account=<account_name> ----
This renders as:
To deploy the account you initialized, now run the following command:
$ starknet deploy_account --account=<account_name>
-
When referring to a path to a location that the user has selected or created, treat the part of the path that the user chose as a replaceable value. For example:
Create a secret that contains the certificate and key in the namespace: [source,terminal] ---- $ oc create secret tls <certificate> --cert=<path_to_certificate>/cert.crt ----
This renders as:
Create a secret that contains the certificate and key in the namespace:
$ oc create secret tls <certificate> --cert=<path_to_certificate>/cert.crt
-
If you must provide additional information on what a line of a code block represents, you can use callouts (
<1>
,<2>
, etc.) to provide that information.Use this format when embedding callouts into the code block:
---- code example 1 <1> code example 2 <2> ---- <1> A note about the first example value. <2> A note about the second example value.
-
If you must provide additional information on what a line of a code block represents and the use of callouts is impractical, you can use a description list to provide information about the variables in the code block. Using callouts might be impractical if a code block contains too many conditional statements to easily use numbered callouts or if the same note applies to multiple lines of the codeblock.
---- code <variable_1> code <variable_2> ---- + where: [horizontal] <variable_1>:: Specifies the explanation of the first variable. <variable_2>:: Specifies the explanation of the first variable.
Be sure to introduce the description list with "where:" and start each variable description with "Specifies."
-
For long lines of code that you want to break up among multiple lines, use a backslash to show the line break. For example:
$ oc get endpoints --all-namespaces --template \ '{{ range .items }}{{ .metadata.namespace }}:{{ .metadata.name }} \ {{ range .subsets }}{{ range .addresses }}{{ .ip }} \ {{ end }}{{ end }}{{ "\n" }}{{ end }}' | awk '/ 172\.30\./ { print $1 }'
-
For snippets or sections of a file, use an ellipsis (
…
or# …
for YAML) to show that the file continues before or after the quoted block.apiVersion: v1 kind: Pod metadata: labels: test: liveness # ...
Do not use
[…]
,<snip>
, or any other variant.
Do NOT show full commands or command syntax inline within a sentence. The next section covers how to show commands and command syntax.
The only use case for inline commands would be general commands and operations, without replaceables and command options. In this case use back ticks to indicate an inline command. For example:
Use the `GET` operation to do x.
This renders as:
Use the
GET
operation to do x.
System messages include error, warning, confirmation, and information messages.
If a message is short enough to include inline, enclose it in back ticks:
Previously, image builds and pushes would fail with the `error reading blob from source` error message because the builder logic would compute the contents of new layers twice.
This renders as:
Previously, image builds and pushes would fail with the
error reading blob from source
error message because the builder logic would compute the contents of new layers twice.
If a message is too long to include inline, put it inside a code block with [source,text]
metadata:
Previously, the AWS Terraform provider that the installation program used occasionally caused a race condition with the S3 bucket, and the cluster installation failed with the following error message: [source,text] ---- When applying changes to module.bootstrap.aws_s3_bucket.ignition, provider level=error msg="\"aws\" produced an unexpected new value for was present, but now absent. ---- Now, the installation program uses different AWS Terraform provider code, which now robustly handles S3 eventual consistency, and the installer-provisioned AWS cluster installation does not fail with that error message.
This renders as:
Previously, the AWS Terraform provider that the installation program used occasionally caused a race condition with the S3 bucket, and the cluster installation failed with the following error message:
When applying changes to module.bootstrap.aws_s3_bucket.ignition, provider level=error msg="\"aws\" produced an unexpected new value for was present, but now absent.Now, the installation program uses different AWS Terraform provider code, which now robustly handles S3 eventual consistency, and the installer-provisioned AWS cluster installation does not fail with that error message.
Note
|
Always refer to a message with the type of message it is, followed by the word message. For example, refer to an error message as an error message, and not simply as an error. |
Write numbered lists as shown in this example:
. Item 1 (2 spaces between the period and the first character) . Item 2 . Item 3
This renders as:
Item 1
Item 2
Item 3
If you must add any text, admonitions, or code blocks you have to add the +
below the line to indicate continuation. For example:
. Item 1 + ---- some code block ---- . Item 2 . Item 3
This renders as:
Item 1
some code blockItem 2
Item 3
Avoid footnotes when possible.
If you reference a footnote from only a single location, use the following syntax:
footnote:[This is the footnote text.]
If you reference a footnote from multiple locations, set an attribute with the footnote text. As a consequence, this will duplicate the footnote text at bottom of the page.
:note-text: This is a footnote. This text has a footnote qualifier attached footnote:[{note-text}]. But this other text uses the same qualifier elsewhere footnote:[{note-text}].
You can collapse sections of content by using the collapsible
option, which converts the Asciidoctor markup to HTML details
and summary
sections. The collapsible
option is used at the writer’s discretion and is appropriate for considerably long code blocks, lists, or other such content that significantly increases the length of a topic.
Note
|
You must set a title for the |
Collapsible content is formatted as shown:
.Title of the `summary` dropdown [%collapsible] ==== This is content within the `details` section. ====
This renders as a dropdown with collapsed content:
Title of the Summary
dropdown
This is content within the Details
section.
If your collapsible content includes an admonition such as a note or warning, you must nest the admonition:
.Collapsible content that includes an admonition [%collapsible] ==== This content includes an admonition. [source,terminal] ---- $ oc whoami ---- [NOTE] ===== Nest admonitions when using the `collapsible` option. ===== ====
This renders as:
Collapsible content that includes an admonition
This content includes an admonition.
$ oc whoami
Note
|
Nest admonitions when using the |
Markup in command syntax | Description | Substitute value in Example block |
---|---|---|
|
Name of user account |
|
|
User password |
password |
Markup in command syntax | Description | Substitute value in Example block |
---|---|---|
|
Name of project |
myproject |
|
Name of an application |
myapp |
The following guidelines apply to all "Additional resources" sections:
-
Avoid including paragraphs in the section. Use an unordered list.
-
The links and xrefs in the unordered list must contain human-readable text between the square brackets.
-
Each item in the unordered list must contain a minimum of text besides the link or xref.
-
Use
.Additional resources
formatting for an Additional resources section when it applies to a section within a topic. For example:.Additional resources
-
Use
==
formatting for the section heading (== Additional resources
) when it applies to the entire topic. For example:[id="additional-resources_configuring-alert-notifications"] == Additional resources * link:some-url.com[Human readable label] * xref:some_xref[Human readable label] * xref:some_other_xref[Human readable label]
Format admonitions, such as notes and warnings, as follows:
[ADMONITION] ==== Text for admonition ====
For a list of available admonition types, see Admonitions in the Red Hat supplementary style guide for product documentation.
-
Easy fixes: For simple fixes such as fixing typos, any writer with merge permissions can go ahead and merge those fixes without any review.
-
New features: When documenting new features or significant changes to existing functionality, you must have a peer review prior to merging.
-
Outdated content that should be updated as quickly as possible: You should get a peer review, but if the assigned reviewer does not review it within ~48 hours, then you can merge it with technical updates and follow up with the peer review as soon as possible.