AsciiDoc
AsciiDoc is a lightweight, semantic markup language designed primarily for authoring technical documentation, allowing users to write human-readable plain text that can be converted into multiple output formats such as HTML, PDF, and EPUB3.[1]Originally developed as a shorthand notation for DocBook XML in the early 2000s by Stuart Rackham, AsciiDoc has evolved into a standalone format focused on simplicity and extensibility for producing structured content.[2]
Its syntax leverages intuitive plain-text conventions, including attributes for metadata, sections for organization, and elements like paragraphs, lists, tables, and code blocks to create semantically rich documents without requiring specialized editors.[1]
AsciiDoc supports modular content reuse through includes and macros, making it suitable for large-scale projects, and it balances readability in source form with precise control over output rendering.[2]
Popular implementations like Asciidoctor, an open-source processor written in Ruby, handle the conversion process and have driven widespread adoption since 2012, including integration into tools for static site generation, IDEs, and CI/CD pipelines.[1]
The language is now governed by the AsciiDoc Language project at the Eclipse Foundation, where ongoing specification work aims to standardize its core elements for broader ecosystem compatibility.[2]
Key use cases include technical books, API documentation, README files, and web content, with notable adopters such as GitLab, Antora, and VMware leveraging it for consistent, version-controlled documentation workflows.[2]
Overview
Definition and Purpose
AsciiDoc is a human-readable, plain-text markup language designed for authoring technical content such as articles, books, and presentations, semantically equivalent to DocBook XML but employing simpler conventions to reduce the verbosity of XML markup.[3][2] Introduced by Stuart Rackham in 2002, it serves as a lightweight alternative to complex formatting tools, allowing writers to focus on content structure using intuitive plain-text syntax that remains readable in its source form without requiring specialized editors.[3] The primary purpose of AsciiDoc is to streamline the writing, structuring, and publishing of documentation by providing semantic markup that enables conversion to multiple output formats, including HTML, PDF, EPUB, and DocBook XML, all without necessitating direct knowledge of underlying XML or proprietary software.[2] This approach simplifies workflows for developers and technical writers, who can produce professional documents using standard text editors while leveraging existing DocBook toolchains for further processing.[3] Key benefits of AsciiDoc include its extensibility through customizable attributes for tailoring output and behavior, modularity via include directives that facilitate content reuse across documents, and built-in support for complex structures such as tables and admonitions to enhance clarity and emphasis in technical writing.[2] These features promote efficient, maintainable documentation practices, emphasizing semantic richness over superficial styling.[3]Key Features
AsciiDoc offers semantic richness through its built-in elements, which structure content to convey meaning beyond mere presentation. Sections are defined hierarchically using underlined titles, enabling a logical document outline that supports navigation and organization. Paragraphs form natural blocks of text separated by blank lines, while lists—both ordered and unordered—establish relational hierarchies among items. Links and cross-references utilize macros and anchors to connect internal and external resources, fostering interconnected knowledge. Images are embedded via block macros, integrating visual elements semantically into the narrative flow.[4] Extensibility is a core strength of AsciiDoc, achieved primarily through document and element attributes that allow dynamic content generation, conditional logic, and custom macros. Attributes such as{counter:chapter} automatically increment counters for elements like chapters, enabling reusable numbering without manual updates. Conditional inclusion directives like ifdef::attribute[] permit content to be included or excluded based on whether specific attributes are defined, supporting version-specific or audience-tailored documents. Macros extend this further by defining custom inline or block substitutions, such as for repeated phrases or complex substitutions, enhancing reusability and adaptability.[5]
AsciiDoc supports multi-format output natively through its processors, allowing a single source document to generate diverse formats including HTML5, PDF via the DocBook toolchain, man pages, and more. The backend option in processors like Asciidoctor specifies the target, with html5 producing web-ready output, docbook enabling conversion to PDF using tools like Apache FOP, and dedicated manpage support for Unix documentation. This versatility makes AsciiDoc suitable for both digital and print publishing without altering the source.[6][1]
Modularity is facilitated by the include directive, which embeds content from external files or URIs directly into the document during preprocessing. This allows large-scale projects to partition content into reusable modules, such as shared glossaries or chapters, with attributes like leveloffset adjusting hierarchy on inclusion. Nested includes further promote maintainability, enabling assembly of book-length documents from smaller, independent parts.[7]
Advanced structures in AsciiDoc include robust support for tables, sidebars, and admonitions, accommodating complex layouts and emphasis. Tables are constructed as delimited blocks with a cols attribute specifying column widths, alignments (left <, right >, center ^), and spans via hspan or vspan for merged cells, supporting data presentation with header rows and varied formats like CSV imports. Sidebars, delimited by **** or styled with [.sidebar], isolate supplementary content like quotes or code snippets for visual distinction. Admonitions such as NOTE, WARNING, TIP, IMPORTANT, and CAUTION use labeled paragraphs or blocks (e.g., [WARNING]), drawing attention to key information and optionally enhanced with icons via the :icons: font attribute.[8][9][10]
In comparison to Markdown, AsciiDoc's features enable handling of complex documents like books with chapters and indices, where Markdown's limited nesting often fails and lacks native attributes for extensibility. AsciiDoc's syntax supports deeper nesting of inline and block elements without breakage, and its attribute system provides portability across outputs that Markdown extensions cannot match reliably.[11]
History
Origins and Early Development
AsciiDoc was developed by Stuart Rackham in 2002 as a Python-based processor designed to convert plain text markup into DocBook XML, providing a simpler alternative to direct XML authoring for structured documents.[12] The tool, initially named AsciiDoc.py, emerged from Rackham's efforts to create a lightweight markup language that allowed users to write documents in a natural, readable format without the verbosity of XML schemas like DocBook, which were commonly used for technical documentation in open-source projects such as Linux manuals.[3] This motivation stemmed from the need to streamline documentation workflows, enabling authors to focus on content rather than formatting intricacies, much like composing an ordinary text document.[3] The first public release of AsciiDoc.py version 1.0 occurred on November 25, 2002, coinciding with the project's registration on SourceForge and the launch of its initial website at methods.co.nz/asciidoc.[12] Early versions emphasized basic markup for generating articles, books, and man pages, with outputs targeted at DocBook for further processing into HTML, PDF, or other formats.[12] Rackham maintained the project single-handedly in its nascent stages, focusing on core syntax elements to support semantic structuring in plain text.[13] During the growth phase from 2007 to 2010, the project transitioned to a more collaborative model, with the source repository moving to Google Code in October 2007 to facilitate broader access and contributions.[12] Community involvement expanded the feature set, incorporating elements such as tables for data presentation and theming options for customized outputs, enhancing its utility for diverse documentation needs.[14] Rackham's original Python implementation, asciidoc.py, solidified as the de facto standard, gaining traction in open-source ecosystems for its reliability and extensibility.[13] By 2011, under Rackham's continued guidance, AsciiDoc saw increased adoption in open-source projects, marking a shift toward sustained open-source maintenance and wider community-driven evolution. This period laid the groundwork for later implementations, such as the Ruby-based Asciidoctor, which began prototyping in 2012 to address performance and portability limitations.[12]Standardization and Modern Implementations
The Asciidoctor project was started in 2012 by Ryan Waldron as a Ruby-based reimplementation of the original AsciiDoc processor. In 2013, leadership transferred to Dan Allen and Sarah White as co-leads, addressing security vulnerabilities in the legacy Python tool and providing faster processing—rendering documents at least 25 times quicker—along with greater extensibility through a document object model and custom template support.[12][15] Standardization efforts advanced in 2019 when the Asciidoctor project initiated the AsciiDoc specification journey, culminating in the release of the official AsciiDoc Language Reference by the AsciiDoc Working Group. This document defined a processor-independent language specification, focusing on syntax, semantics, and rules to ensure consistency across implementations and foster broader adoption.[16][12] The Working Group, formed under the Eclipse Foundation in 2020, continues to oversee evolution, emphasizing open collaboration for language governance separate from any single tool.[16][12] By the 2020s, Asciidoctor had established itself as the reference implementation for the AsciiDoc language, with ports extending its reach to other ecosystems, including AsciidoctorJ for Java and Asciidoctor.js for JavaScript.[17][18][19] The original Python-based AsciiDoc.py processor is now considered legacy and has been superseded by Asciidoctor, with migration guidance provided to leverage Asciidoctor's enhanced syntax and consistency.[12][20] Recent developments through 2025 have integrated Asciidoctor more deeply into modern workflows, including seamless support for CI/CD pipelines via its Ruby API and plugins for tools like GitHub Actions and GitLab CI.[21] Enhanced PDF generation arrived with Asciidoctor PDF releases, such as version 2.3.9 in 2023, introducing unbreakable blocks, improved theming, and better SVG handling for professional outputs.[22] As of October 2025, Asciidoctor released version 2.0.26, enhancing compatibility with Ruby 3.3 and fixing bugs.[23] Community-driven revisions to the language specification have prioritized accessibility—through UTF-8 optimizations and semantic markup—and internationalization, enabling full support for non-English languages via encoding configurations.[24][1] Ecosystem shifts have seen widespread migration from the original AsciiDoc.py to Asciidoctor, driven by its superior performance and active maintenance, with projects updating syntax for compatibility.[20] Organizations like Red Hat, where Dan Allen contributed, have officially adopted Asciidoctor for documentation pipelines, while Gradle integrates it via the dedicated Asciidoctor Gradle Plugin Suite for automated AsciiDoc processing in builds.[12][25][26]Syntax and Elements
Document Structure
AsciiDoc documents follow a structured format that organizes content into a header, optional preamble, and body, enabling modular and hierarchical writing. The header, which is optional but recommended for formal documents, precedes the body and contains metadata such as the title, author, and revision information. This structure allows for easy parsing by processors and supports features like automatic table of contents generation.[4] The header begins with the document title marked by a single equals sign (=), followed by the author's name on the next line, and optionally the revision or date. Attributes within the header are defined using the colon syntax, such as:attribute-name: value, which sets global properties like document type or custom variables that influence rendering. For instance, a basic header might appear as:
This setup ensures metadata is centralized and can be referenced throughout the document, such as using= Document Title Author Name v1.0, 2023-01-01 :reproducible:= Document Title Author Name v1.0, 2023-01-01 :reproducible:
{author} to insert the author's name dynamically.[4]
Section hierarchy in AsciiDoc is established through underlined titles, where the number of equals signs determines the level: the document title (=) is level 0, == denotes level 1, === level 2, and so on up to six levels. Processors automatically generate IDs from section titles for internal linking, and sections can be promoted to the table of contents (TOC) by enabling the :toc: attribute in the header. Discrete sections, marked by titles without preceding content, promote the outline, while continuous sections integrate seamlessly with surrounding text. This underline-based system provides a clear, semantic outline without requiring explicit numbering.[4]
At the core of the body are blocks, which serve as the foundational units for content organization. Paragraphs form the simplest block type, consisting of one or more lines of text separated by blank lines, while lists use markers like - for unordered items or . for ordered ones. Delimited blocks enclose content within boundaries, such as ---- for open blocks that allow paragraphs and other elements inside, or ``` for source code listings with syntax highlighting support. These blocks can be nested and attributed for customization, ensuring flexible structuring of complex documents.
Modularity is achieved through the include directive, which embeds external AsciiDoc files using the syntax include::file.adoc[], placed where the content should appear. To adjust the hierarchy of included sections, the leveloffset option shifts levels up or down, such as include::chapter.adoc[leveloffset=+1] to demote sections by one level. This feature promotes reusability across documents, allowing chapters or modules to be shared without altering their internal structure.[4]
Attributes provide metadata customization, with global attributes defined in the header applying document-wide and local attributes applied to specific blocks using [#id,role=class,reftext=Custom Text]. Roles add semantic classes for styling, like [role=lead] for introductory paragraphs, while reftext customizes link anchors. Attributes can be conditional or counter-based, enabling dynamic content adaptation based on context.[4]
Formatting and Semantic Elements
AsciiDoc provides a range of inline formatting options to apply styling and emphasis to text within paragraphs or other elements. Bold text is achieved using asterisk delimiters, as in*bold text*, which renders as bold text in the output. Italic or emphasis formatting uses underscore delimiters, such as _italic text_, producing italic text. Monospace formatting, often used for code or literals, employs backtick delimiters like `monospace text`, resulting in monospace text. For content that should bypass processing, such as raw HTML, pass-through markup uses triple plus signs, for example +++raw HTML+++, which outputs the enclosed content unchanged.[27]
Links in AsciiDoc are created with a URL followed by square brackets containing the link text, such as [https](/page/HTTPS)://example.com[Link Text], which generates a hyperlink with the specified text. Additional options can be appended after a comma within the brackets, including attributes like role=external for styling or window=_blank to open in a new tab, as in [https](/page/HTTPS)://example.com[Link Text,role=external,window=_blank]. Images are handled via the image:: macro followed by the path and alt text in brackets, for instance image::image.png[Alternative text], supporting options for width, height, alignment, or float, such as image::image.png[Alt,width=50%,float=right].[27]
Lists in AsciiDoc support both unordered and ordered varieties, using simple markers at the start of lines. Unordered lists begin items with an asterisk (*), as in * First item followed by * Second item, which renders as bullet points; nested levels use additional asterisks like ** Subitem. Ordered lists use a period (.) for numbering, such as . First step and . Second step, with nesting via multiple periods like .. Substep, automatically generating sequential numbers.[27]
Tables employ a grid syntax delimited by |=== lines, where headers and cells are separated by pipes (|), for example:
This produces a basic table with borders. Colspans are specified by appending a number after a plus sign, such as|=== |Header 1 |Header 2 |Cell 1 |Cell 2 |===|=== |Header 1 |Header 2 |Cell 1 |Cell 2 |===
|Cell spanning 2+, allowing cells to merge across columns.[27]
Semantic blocks enhance meaning and presentation through specialized delimiters. Admonitions, like notes or warnings, use a label followed by a double colon or block style, such as NOTE:: This is a note. for inline or [NOTE]\n====\nThis is a note.\n==== for delimited blocks, rendering as styled callouts. Quotes are marked with underscore lines (____) and optional attribution, e.g., [quote,Author]\n____\nQuoted text\n____, displaying as indented blocks. Sidebars use four asterisks (****) to enclose content, creating floating informational panels like ****\nSidebar content\n****. Source code blocks are delimited by four dashes (----), with language specification for syntax highlighting, as in [source,ruby]\n----\nputs "Hello"\n----, which applies color-coded rendering based on the declared language.[27]
Cross-references enable internal linking via ID-based anchors. Anchors are defined with double brackets, such as [[section-id]], automatically generating a target at that point. References use double angle brackets, like <<section-id>>, which resolves to a hyperlink with the target's title or a custom label if specified, such as <<section-id,Custom Link Text>>.[27]
Examples
Basic Document Example
A basic AsciiDoc document demonstrates the language's simplicity through a minimal structure that includes a title, paragraphs, formatting for emphasis, a section heading, an unordered list, and a hyperlink, all using plain text markup that remains highly readable in its source form.[28] The following example represents a short article:When processed by an AsciiDoc converter such as Asciidoctor, this source file renders to structured HTML output. The document title becomes= My Document Title This is a paragraph with *bold* and _italic_ text. == Section One Here’s a list: * Item 1 * Item 2 * Item 3 with a link: https://example.com[Example Site]. Another paragraph.= My Document Title This is a paragraph with *bold* and _italic_ text. == Section One Here’s a list: * Item 1 * Item 2 * Item 3 with a link: https://example.com[Example Site]. Another paragraph.
<h1>My Document Title</h1>, the initial paragraph translates to <p>This is a paragraph with <strong>bold</strong> and <em>italic</em> text.</p>, and the section heading appears as <h2>Section One</h2>. The unordered list is converted to <ul><li>Item 1</li><li>Item 2</li><li>Item 3 with a link: <a href="https://example.com">Example Site</a>.</li></ul>, while the final paragraph renders as <p>Another paragraph.</p>. This transformation preserves semantic meaning while generating clean, accessible markup suitable for web display.[28]
Key takeaways from this example highlight AsciiDoc's emphasis on source readability and minimal markup, where elements like asterisks for bold (*bold*) and underscores for italic (_italic_) integrate seamlessly into the text flow without disrupting comprehension. Such lightweight syntax makes it ideal for everyday use cases, including blog posts, personal notes, or introductory technical articles, where authors prioritize writing over formatting overhead.[28]
Advanced Features Example
To illustrate the integrated use of advanced AsciiDoc features in a multi-file document suitable for technical manuals, consider a sample project documenting a software release. This setup employs attribute substitution for versioning, includes for modularity, conditionals to toggle environment-specific content, tables with cell spans for structured data, admonitions for emphasis, and cross-references for navigation. It also incorporates a table of contents (TOC) and indexed terms for enhanced readability and searchability. The main document,release-guide.adoc, serves as the entry point and defines global attributes:
This file includes modular sections from separate files. For instance, it includes an overview (= Software Release Guide {version} Author Name v{version}, {doctitle} :toc: :version: 2.1.0 :env-prod: :xrefstyle: full :sectnums: :sectnumlevels: 3 :keywords: release, deployment :important-term: ((AsciiDoc))= Software Release Guide {version} Author Name v{version}, {doctitle} :toc: :version: 2.1.0 :env-prod: :xrefstyle: full :sectnums: :sectnumlevels: 3 :keywords: release, deployment :important-term: ((AsciiDoc))
include::overview.adoc[]) and a deployment guide (include::deployment.adoc[]), allowing collaborative editing across files while maintaining a unified structure. The {version} attribute substitutes dynamically throughout the document, ensuring consistency without manual updates. The :toc: attribute generates an automatic TOC, and :sectnums: enables numbered sections for precise referencing. Indexed terms like ((AsciiDoc)) are marked for an auto-generated index at the document's end.
The overview.adoc file demonstrates conditionals, a table with spans, an admonition, and a cross-reference:
Here,== Overview The {important-term} markup enables scalable [documentation](/page/Documentation) for releases like version {version}. <<deployment-guide>> covers setup details. [WARNING] ==== This guide assumes a stable environment. Verify prerequisites before proceeding. ==== ifdef::env-prod[] In production environments, enable high-availability mode for [resilience](/page/Resilience). endif::[] |=== |Feature+ |Description |Status |Notes | |Compatibility Layers |Legacy support |Beta |Security Patches |Vulnerability fixes |Critical |Applies to all tiers |UI Enhancements |New dashboard |^2<|In Progress |===== Overview The {important-term} markup enables scalable [documentation](/page/Documentation) for releases like version {version}. <<deployment-guide>> covers setup details. [WARNING] ==== This guide assumes a stable environment. Verify prerequisites before proceeding. ==== ifdef::env-prod[] In production environments, enable high-availability mode for [resilience](/page/Resilience). endif::[] |=== |Feature+ |Description |Status |Notes | |Compatibility Layers |Legacy support |Beta |Security Patches |Vulnerability fixes |Critical |Applies to all tiers |UI Enhancements |New dashboard |^2<|In Progress |===
ifdef::env-prod[] conditionally includes production-specific instructions only when the env-prod attribute is defined (as set in the main file), allowing the same source to generate tailored outputs for development or production contexts. The table uses default column widths, with the header cell for Feature employing + to span two rows, leaving the second row's first cell empty. The last row's Status and Notes cells are merged using ^2<| for a left-aligned colspan of 2. The admonition block provides a styled warning that draws attention to critical notes. The cross-reference <<deployment-guide>> links to the included deployment section.
The deployment.adoc file, included via include::deployment.adoc[], continues with further content:
When processed with a tool like Asciidoctor (e.g.,[[deployment-guide]]== Deployment Guide Deploy the {version} release using the following steps. 1. Install dependencies. 2. Configure the server. For advanced options, refer to <<overview>>.[[deployment-guide]]== Deployment Guide Deploy the {version} release using the following steps. 1. Install dependencies. 2. Configure the server. For advanced options, refer to <<overview>>.
asciidoctor-pdf release-guide.adoc -a env-prod), the output is a self-contained PDF document. The TOC appears as a navigable sidebar or front matter, listing numbered sections like "1. Overview" and "2. Deployment Guide" for quick orientation. Indexed terms generate a back-matter index, e.g., "AsciiDoc, 1," with hyperlinks or page numbers. Conditional content under ifdef::env-prod[] renders only in production builds, hiding it otherwise to produce environment-specific PDFs without altering source files. Tables render with precise cell merging and alignments, supporting complex layouts like multi-row headers. Admonitions appear as boxed callouts with icons (e.g., a warning triangle), and cross-references resolve to section titles with page numbers (e.g., "Deployment Guide (p. 3)"). Attribute substitutions replace {version} and {doctitle} seamlessly, yielding output like "Software Release Guide 2.1.0." This PDF-friendly format ensures professional typesetting, including proper margins, fonts, and hyperlinks where applicable.
These features highlight AsciiDoc's scalability for technical manuals, where multi-file includes and conditionals facilitate version control and audience targeting, while tables, admonitions, and cross-references enhance clarity and maintainability. Attribute substitution like {version} streamlines updates across large documents, reducing errors in evolving projects.[29]
Implementations and Tools
Core Processors
Asciidoctor serves as the primary and most widely adopted processor for AsciiDoc, implemented in Ruby and recognized for its speed and comprehensive feature set.[21][17] It parses AsciiDoc source into a document model and converts it to various output formats, supporting command-line invocation such asasciidoctor [file](/page/File).adoc to generate HTML output by default. Extensions for Asciidoctor are developed as Ruby gems, enabling customization of parsing, processing, and rendering behaviors.
AsciidoctorJ provides Java bindings for Asciidoctor, allowing seamless integration within Java Virtual Machine (JVM) environments.[30] It embeds the Ruby-based Asciidoctor runtime via JRuby, facilitating use in build tools like Gradle plugins for automated document processing.[18] This port supports programmatic conversion of AsciiDoc content directly in Java applications, preserving the full capabilities of the original processor.[30]
Asciidoctor.js ports Asciidoctor to JavaScript using the Opal transpiler, enabling execution in web browsers and Node.js environments.[31] It supports real-time rendering of AsciiDoc in the browser, powering extensions like live previews for immediate feedback during authoring.[19] This implementation maintains compatibility with core Asciidoctor features while adapting them for client-side and server-side JavaScript workflows.[31]
The original AsciiDoc processor, asciidoc.py, is a Python-based implementation that remains available but is considered legacy and unmaintained for new development.[20] It handles basic conversions for older AsciiDoc syntax and maintains compatibility with simple documents, though it lacks the performance and extensibility of modern alternatives.[32]
AsciiDoc processors like Asciidoctor include built-in backends for generating HTML 5 and DocBook 5 (or 4.5) outputs directly from the document model.[17] Additional formats such as PDF are supported through extensions like Asciidoctor PDF, which leverages the Prawn library for native Ruby-based PDF generation without intermediate steps.[33] EPUB 3 output is enabled via the Asciidoctor EPUB3 extension set, which converts AsciiDoc to the EPUB package format while preserving semantic structure.[34]