Asciidoctor is a fast, open source text processor and publishing toolchain for converting AsciiDoc content to HTML5, DocBook, PDF, and other formats. Asciidoctor is written in Ruby and runs on all major operation systems. To simplify installation, Asciidoctor is packaged and distributed as a gem to RubyGems.org and is packaged for popular Linux distributions and macOS. Asciidoctor can also be run in a JVM using AsciidoctorJ or in any JavaScript environment using Asciidoctor.js. The Asciidoctor project is hosted on GitHub.
Sponsors
We want to recognize our generous sponsors, without whose support Asciidoctor would not be possible. Thank you sponsors for your dedication to improving the state of technical documentation!
Major funding for Asciidoctor is provided by our Change Makers, Okta and OpenDevise, and our Strategy Sponsors, Khronos Group and Linda Roberts. Additional funding is provided by our Community Backers.
You can support this project by becoming a sponsor on OpenCollective.
The Big Picture
Asciidoctor reads content written in plain text, as shown in the panel on the left in the image below, and converts it to HTML5, as shown rendered in the right panel. Asciidoctor applies a default stylesheet to the HTML5 document to provide a pleasant out-of-the-box experience.
image::{image-uri-screenshot}[Preview of AsciiDoc source and corresponding rendered HTML]
AsciiDoc Processing
Asciidoctor reads and parses text written in the AsciiDoc syntax, then feeds the parse tree to a set of built-in converters to produce HTML5, DocBook 5, and man(ual) page output. You have the option of using your own converter or loading Tilt-supported templates to customize the generated output or produce additional formats.
Asciidoctor is a drop-in replacement for the original AsciiDoc Python processor (asciidoc.py
).
The Asciidoctor test suite has > 2,000 tests to ensure compatibility with the AsciiDoc syntax.
In addition to the classic AsciiDoc syntax, Asciidoctor recognizes additional markup and formatting options, such as font-based icons (e.g., icon:fire[]
) and UI elements (e.g., button:[Save]
).
Asciidoctor also offers a modern, responsive theme based on Foundation to style the HTML5 output.
Where Ruby goes, Asciidoctor follows
You can run Asciidoctor on the JVM using JRuby. To invoke the Asciidoctor API directly from Java and other JVM languages, use AsciidoctorJ. There are plugins available for Apache Maven, Gradle, and Javadoc, which allow you to integrate AsciiDoc processing directly into your build using AsciidoctorJ.
Asciidoctor also runs in JavaScript. Opal is used to transcompile the Ruby source to JavaScript to produce Asciidoctor.js. Asciidoctor.js is a fully-functional version of Asciidoctor that works in any JavaScript environment, such as a web browser or Node.js. It’s used to power the AsciiDoc preview extensions for Chrome, Atom, Brackets and other web-based tooling.
Requirements
Asciidoctor works on Linux, macOS and Windows and requires one of the following implementations of Ruby:
-
Ruby (MRI/CRuby 1.8.7 - 2.5)
-
JRuby (1.7 in Ruby 1.8 and 1.9 modes, 9000)
-
Rubinius 2.2.x
-
Opal (JavaScript)
Caution
|
If you’re using a non-English Windows environment, you may bump into an chcp 65001 Once you make this change, all your Unicode headaches will be behind you. If you’re using an IDE like Eclipse, make sure you set the encoding to UTF-8 there as well. Asciidoctor works best when you use UTF-8 everywhere. |
Installation
Asciidoctor can be installed using (a) package managers for popular Linux distributions, (b) Homebrew for macOS, (c) the gem install
command (recommended for Windows users), (d) the Asciidoctor Docker image, or (e) Bundler.
The benefit of using your operating system’s package manager to install the gem is that it handles installing Ruby and the RubyGems library if those packages are not already installed on your machine.
(a) Linux package managers
The version of Asciidoctor installed by the package manager may not match the latest release of Asciidoctor. Consult the package repository for your distribution to find out which version is packaged per distribution release.
If you want to use a version of Asciidoctor that is newer than what is installed by the package manager, see the gem installation instructions.
apk (Alpine Linux)
To install the gem on Alpine Linux, open a terminal and type:
$ sudo apk add asciidoctor
pacman (Arch Linux)
To install the gem on Arch-based distributions, open a terminal and type:
$ sudo pacman -S asciidoctor
APT
On Debian and Debian-based distributions such as Ubuntu, use APT to install Asciidoctor. To install the package, open a terminal and type:
$ sudo apt-get install -y asciidoctor
DNF
On RPM-based Linux distributions, such as Fedora, CentOS, and RHEL, use the DNF package manager to install Asciidoctor. To install the package, open a terminal and type:
$ sudo dnf install -y asciidoctor
(b) Homebrew (macOS)
You can use Homebrew, the macOS package manager, to install Asciidoctor.
If you don’t have Homebrew on your computer, complete the installation instructions at brew.sh first.
Once Homebrew is installed, you’re ready to install the asciidoctor
gem.
Open a terminal and type:
$ brew install asciidoctor
Homebrew installs the asciidoctor
gem into an exclusive prefix that’s independent of system gems.
(c) Windows
To use Asciidoctor with Windows, you have two easy options.
Chocolatey
When you already use chocolatey on your machine, you can use:
choco install ruby
Then follow gem installation instructions.
Rubyinstaller
Or you use the Rubyinstaller, download the package for your Windows Version and after the installation go ahead with gem installation instructions.
(d) gem install
Before installing Asciidoctor using gem install
, you should use RVM to install Ruby in your home directory (i.e., user space).
Then, you can safely use the gem
command to install or update the Asciidoctor gem.
When using RVM, gems are installed in a location isolated from the system.
Open a terminal and type:
$ gem install asciidoctor
If you want to install a pre-release version (e.g., a release candidate), use:
$ gem install asciidoctor --pre
(e) Docker
(f) Bundler
-
Create a Gemfile in the root folder of your project (or the current directory)
-
Add the
asciidoctor
gem to your Gemfile as follows:source 'https://rubygems.org' gem 'asciidoctor' # or specify the version explicitly # gem 'asciidoctor', '1.5.8'
-
Save the Gemfile
-
Open a terminal and install the gem using:
$ bundle
To upgrade the gem, specify the new version in the Gemfile and run bundle
again.
Using bundle update
(without specifying a gem) is not recommended as it will also update other gems, which may not be the desired result.
Upgrade
If you installed Asciidoctor using a package manager, your operating system is probably configured to automatically update packages, in which case you don’t need to update the gem manually.
apk (Alpine Linux)
To upgrade the gem, use:
$ sudo apk add -u asciidoctor
APT
To upgrade the gem, use:
$ sudo apt-get upgrade -y asciidoctor
DNF
To upgrade the gem, use:
$ sudo dnf update -y asciidoctor
Homebrew (macOS)
To upgrade the gem, use:
$ brew update $ brew upgrade asciidoctor
gem install
If you previously installed Asciidoctor using the gem
command, you’ll need to manually upgrade Asciidoctor when a new version is released.
You can upgrade the gem by typing:
$ gem install asciidoctor
When you install a new version of the gem using gem install
, you end up with multiple versions installed.
Use the following command to remove the old versions:
$ gem cleanup asciidoctor
Usage
If the Asciidoctor gem installed successfully, the asciidoctor
command line interface (CLI) will be available on your PATH.
To verify it’s available, run the following in your terminal:
$ asciidoctor --version
You should see information about the Asciidoctor version and your Ruby environment printed in the terminal.
Asciidoctor 1.5.8 [https://asciidoctor.org] Runtime Environment (ruby 2.5.1p57 [x86_64-linux]) (lc:UTF-8 fs:UTF-8 in:- ex:UTF-8)
Asciidoctor also provides an API. The API is intended for integration with other Ruby software, such as Rails, Sinatra and GitHub, and other languages, such as Java (via AsciidoctorJ) and JavaScript (via Asciidoctor.js).
Command line interface (CLI)
The asciidoctor
command allows you to invoke Asciidoctor from the command line (i.e., a terminal).
The following command converts the file README.adoc to HTML and saves the result to the file README.html in the same directory.
The name of the generated HTML file is derived from the source file by changing its file extension to .html
.
$ asciidoctor README.adoc
You can control the Asciidoctor processor by adding various flags and switches, which you can learn about using:
$ asciidoctor --help
For instance, to write the file to a different directory, use:
$ asciidoctor -D output README.adoc
The asciidoctor
man page provides a complete reference of the command line interface.
Refer to the following resources to learn more about how to use the asciidoctor
command.
Ruby API
To use Asciidoctor in your application, you first need to require the gem:
require 'asciidoctor'
You can then convert an AsciiDoc source file to an HTML file using:
Asciidoctor.convert_file 'README.adoc', to_file: true, safe: :safe
Warning
|
When using Asciidoctor via the API, the default safe mode is :secure .
In secure mode, several core features are disabled, including the include directive.
If you want to enable these features, you’ll need to explicitly set the safe mode to :server (recommended) or :safe .
|
You can also convert an AsciiDoc string to embeddable HTML (for inserting in an HTML page) using:
content = '_Zen_ in the art of writing https://asciidoctor.org[AsciiDoc].'
Asciidoctor.convert content, safe: :safe
If you want the full HTML document, enable the header_footer
option as follows:
content = '_Zen_ in the art of writing https://asciidoctor.org[AsciiDoc].'
html = Asciidoctor.convert content, header_footer: true, safe: :safe
If you need access to the parsed document, you can split the conversion into discrete steps:
content = '_Zen_ in the art of writing https://asciidoctor.org[AsciiDoc].'
document = Asciidoctor.load content, header_footer: true, safe: :safe
puts document.doctitle
html = document.convert
Keep in mind that if you don’t like the output Asciidoctor produces, you can change it! Asciidoctor supports custom converters that can handle converting from the parsed document to the generated output.
One easy way to customize the output piecemeal is by using the template converter. The template converter allows you to supply a Tilt-supported template file to handle converting any node in the document.
However you go about it, you can have 100% control over the output. For more information about how to use the API or to customize the output, refer to the user manual.
Contributing
New contributors are always welcome! If you discover errors or omissions in the source code, documentation, or website content, please don’t hesitate to submit an issue or open a pull request with a fix.
Here are some ways you can contribute:
-
by using prerelease (alpha, beta or preview) versions
-
by reporting bugs
-
by suggesting new features
-
by writing or editing documentation
-
by writing code with tests — No patch is too small.
-
fix typos
-
add comments
-
clean up inconsistent whitespace
-
write tests!
-
-
by refactoring code
-
by fixing issues
-
by reviewing patches
The Contributing guide provides information on how to create, style, and submit issues, feature requests, code, and documentation to the Asciidoctor Project.
Getting Help
Asciidoctor is developed to help you easily write and publish your content. But we can’t do it without your feedback! We encourage you to ask questions and discuss any aspects of the project on the discussion list, on Twitter or in the chat room.
- Discussion list (Nabble)
-
#asciidoctor hashtag or @asciidoctor mention
The Asciidoctor organization on GitHub hosts the project’s source code, issue tracker, and sub-projects.
- Source repository (git)
- Issue tracker
- Asciidoctor organization on GitHub
License
Copyright © 2012-2018 Dan Allen, Sarah White and the individual contributors to Asciidoctor. Use of this software is granted under the terms of the MIT License.
See the LICENSE for the full license text.
Authors
Asciidoctor is led by Dan Allen and Sarah White and has received contributions from many individuals in Asciidoctor’s awesome community. The project was initiated in 2012 by Ryan Waldron and based on a prototype written by Nick Hengeveld.
AsciiDoc was started by Stuart Rackham and has received contributions from many individuals in the AsciiDoc community.
Changelog
1.5.7.1 (2018-05-10) - @mojavelinux
- Fixes
-
-
fix regression where block attributes where being inherited by sibling blocks in a complex list item (#2771)
-
don’t apply lead styling to first paragraph in nested document (AsciiDoc table cell) if role is present (#2624)
-
- Build / Infrastructure
-
-
drop obsolete logic in rake build (@aerostitch)
-
allow lib dir to be overridden for tests using an environment variable (PR #2758) (@aerostitch)
-
load asciidoctor/version from LOAD_PATH in gemspec if not found locally (PR #2760) (@aerostitch)
-
1.5.7 (2018-05-02) - @mojavelinux
- Enhancements
-
-
BREAKING: drop XML tags, character refs, and non-word characters (except hyphen, dot, and space) when auto-generating section IDs (#794)
-
hyphen, dot, and space are replaced with value of idseparator, if set; otherwise, spaces are dropped
-
-
allow attribute names to contain any word character defined by Unicode (#2376, PR #2393)
-
do not recognize attribute entry line if name contains a colon (PR #2377)
-
route all processor messages through a logger instead of using Kernel#warn (#44, PR #2660)
-
add MemoryLogger for capturing messages sent to logger into memory (#44, PR #2660)
-
add NullLogger to prevent messages from being logged (#44, PR #2660)
-
log message containing source location / cursor as an object; provides more context (#44, PR #2660)
-
pass cursor for include file to
:include_location
key in message context (PR #2729) -
add
:logger
option to API to set logger instance (#44, PR #2660) -
add
--failure-level=LEVEL
option to CLI to force non-zero exit code if specified logging level is reached (#2003, PR #2674) -
parse text of xref macro as attributes if attribute signature found (equal sign) (#2381)
-
allow xrefstyle to be specified per xref by assigning the xrefstyle attribute on the xref macro (#2365)
-
recognize target with .adoc extension in xref macro as an interdocument xref
-
resolve nested includes in remote documents relative to URI (#2506, PR #2511)
-
allow
relfilesuffix
attribute to control file extension used for interdoc xrefs (#1273) -
support
!name@
(preferred),!name=@
,name!@
, andname!=@
syntax to soft unset attribute from API or CLI (#642, PR #2649) -
allow modifier to be placed at end of name to soft set an attribute (e.g.,
icons@=font
) (#642, PR #2649) -
interpret
false
attribute value defined using API as a soft unset (#642, PR #2649) -
number parts if
partnums
attribute is set (#2298) -
allow footnote macro to define or reference footnote reference (footnoteref macro now deprecated) (#2347, PR #2362)
-
allow custom converter to be used with custom templates; converter must declare that it supports templates (#2619)
-
allow manpage path for manpage help topic to be specified using ASCIIDOCTOR_MANPAGE_PATH environment variable (PR #2653) (@aerostitch)
-
if manpage cannot be found in default path inside gem, use
man -w asciidoctor
to resolve installed path (PR #2653) -
uncompress contents of manpage for manpage help topic if path ends with .gz (PR #2653) (@aerostitch)
-
define source and manual refmiscinfo entries in manpage output if manual and source attributes are defined (PR #2636) (@tiwai)
-
add syntax for adding hard line breaks in block AsciiMath equations (#2497, PR #2579) (@dimztimz)
-
add positioning option to sectanchors attribute (sectanchors=before or sectanchors=after) (#2485, PR #2486)
-
allow table striping to be configured using stripes attribute (even, odd, all, or none) or stripes roles on table (#1365, PR #2588)
-
recognize
ends
as an alias totopbot
for configuring the table frame -
add rel=nofollow property to links (text or image) when nofollow option is set (#2605, PR #2692)
-
populate Document#source_location when sourcemap option is enabled (#2478, PR #2488)
-
populate source_location property on list items when sourcemap option is set on document (PR #2069) (@mogztter)
-
populate Table::Cell#source_location when sourcemap option is enabled (#2705)
-
allow local include to be flagged as optional by setting optional option (#2389, PR #2413)
-
allow block title to begin with a period (#2358, PR #2359)
-
catalog inline anchor at start of list items in ordered and unordered lists, description list terms, and table cells (#2257)
-
register document in catalog if id is set; assign reftext to document attributes if specified in a block attribute line (#2301, PR #2428)
-
allow automatic width to be applied to individual columns in a table using the special value
~
(#1844) -
use the quote element in DocBook converter to represent smart quotes (#2272, PR #2356) (@bk2204)
-
parse and pass all manpage names to output document master (i.e., shadow man pages) (#1811, #2543, PR #2414)
-
parse credit line of shorthand quote block as block attributes; apply normal subs to credit line in shorthand quote blocks (#1667, PR #2452)
-
populate copyright element in DocBook output from value of copyright attribute (#2728)
-
preserve directories if source dir and destination dir are set (#1394, PR #2421)
-
allow linkcss to be unset from API or CLI when safe mode is secure
-
convert quote to epigraph element in DocBook output if block has epigraph role (#1195, PR #2664) (@bk2204)
-
number special sections in addition to regular sections when sectnums=all (#661, PR #2463)
-
upgrade to Font Awesome 4.7.0 (#2569)
-
upgrade to MathJax 4.7.4
-
- Bug fixes
-
-
set
:to_dir
option value correctly when output file is specified (#2382) -
preserve leading indentation in contents of AsciiDoc table cell if contents starts with a newline (#2712)
-
the shorthand syntax on the style to set block attributes (id, roles, options) no longer resets block style (#2174)
-
match include tags anywhere on line as long as offset by word boundary on left and space or newline on right (#2369, PR #2683)
-
warn if an include tag specified in the include directive is unclosed in the included file (#2361, PR #2696)
-
use correct parse mode when parsing blocks attached to list item (#1926)
-
fix typo in gemspec that removed README and CONTRIBUTING files from the generated gem (PR #2650) (@aerostitch)
-
preserve id, role, title, and reftext on open block when converting to DocBook; wrap in
<para>
or<formalpara>
(#2276) -
don’t turn bare URI scheme (no host) into a link (#2609, PR #2611)
-
don’t convert inter-document xref to internal anchor unless entire target file is included into current file (#2200)
-
fix em dash replacement in manpage converter (#2604, PR #2607)
-
don’t output e-mail address twice when replacing bare e-mail address in manpage output (#2654, PR #2665)
-
use alternate macro for monospaced text in manpage output to not conflict w/ AsciiDoc macros (#2751)
-
enforce that absolute start path passed to PathResolver#system_path is inside of jail path (#2642, PR #2644)
-
fix behavior of PathResolver#descends_from? when base path equals / (#2642, PR #2644)
-
automatically recover if start path passed to PathResolver#system_path is outside of jail path (#2642, PR #2644)
-
re-enable left justification after invoking tmac URL macro (#2400, PR #2409)
-
don’t report warning about same level 0 section multiple times (#2572)
-
record timings when calling convert and write on Document (#2574, PR #2575)
-
duplicate header attributes when restoring; allows header attributes to be restored an arbitrary number of times (#2567, PR #2570)
-
propagate
:catalog_assets
option to nested document (#2564, PR #2565) -
preserve newlines in quoted CSV data (#2041)
-
allow opening quote around quoted CSV field to be on a line by itself
-
output table footer after body rows (#2556, PR #2566) (@PauloFrancaLacerda)
-
move @page outside of @media print in default stylesheet (#2531, PR #2532)
-
don’t throw exception if text of dd node is nil (#2529, PR #2530)
-
don’t double escape ampersand in manpage output (#2525) (@dimztimz)
-
fix crash when author_1 attribute is assigned directly (#2481, PR #2487)
-
fix CSS for highlighted source block inside colist (#2474, PR #2490)
-
don’t append file extension to data uri of admonition icon (#2465, PR #2466)
-
fix race condition in Helpers.mkdir_p (#2457, PR #2458)
-
correctly process nested passthrough inside unconstrained monospaced (#2442, PR #2443)
-
add test to ensure ampersand in author line is not double escaped (#2439, PR #2440)
-
prevent footnote ID from clashing with auto-generated footnote IDs (#2019)
-
fix alignment of icons in footnote (#2415, PR #2416)
-
add graceful fallback if pygments.rb fails to return a value (#2341, PR #2342)
-
escape specialchars in source if pygments fails to highlight (#2341)
-
do not recognize attribute entry line if name contains colon (PR #2377)
-
allow flow indexterm to be enclosed in round brackets (#2363, PR #2364)
-
set outfilesuffix to match file extension of output file (#2258, PR #2367)
-
add block title to dlist in manpage output (#1611, PR #2434)
-
scale text to 80% in print styles (#1484, PR #2576)
-
fix alignment of abstract title when using default stylesheet (PR #2732)
-
only set nowrap style on table caption for auto-width table (#2392)
-
output non-breaking space for man manual if absent in DocBook output (PR #2636)
-
don’t crash if stem type is not recognized (instead, fallback to asciimath)
-
- Improvements / Refactoring
-
-
BREAKING: rename table spread role to stretch (#2589, PR #2591)
-
use cursor marks to track lines more accurately; record cursor at the start of each block, list item, or table cell (PR #2701, PR #2547) (@seikichi)
-
log a warning message if an unterminated delimited block is detected (#1133, PR #2612)
-
log a warning when nested section is found inside special section that doesn’t support nested sections (#2433, PR #2672)
-
read files in binary mode to disable automatic endline coercion (then explicitly coerce to UTF-8) (PR #2583, PR #2694)
-
resolve / expand parent references in start path passed to PathResolver#system_path (#2642, PR #2644)
-
update PathResolver#expand_path to resolve parent references (#2642, PR #2644)
-
allow start path passed to PathResolver#system_path to be outside jail if target brings resolved path back inside jail (#2642, PR #2644)
-
don’t run File.expand_path on Dir.pwd (assume Dir.pwd is absolute) (#2642, PR #2644)
-
posixify working_dir passed to PathResolver constructor if absolute (#2642, PR #2644)
-
optimize detection for footnote* and indexterm* macros (#2347, PR #2362)
-
log a warning if a footnote reference cannot be resolved (#2669)
-
set logger level to DEBUG when verbose is enabled
-
coerce value of
:template_dirs
option to an Array (PR #2621) -
make block roles specified using shorthand syntax additive (#2174)
-
allow paragraph to masquerade as open block (PR #2412)
-
move callouts into document catalog (PR #2394)
-
document ID defined in block attribute line takes precedence over ID defined inside document title line
-
don’t look for link and window attributes on document when resolving these attributes for an image
-
when linkattrs is set, only parse attributes in link macro if equals is present
-
skip line comments in name section of manpage (#2584, PR #2585)
-
always activate extension registry passed to processor (PR #2379)
-
skip extension registry activation if no groups are registered (PR #2373)
-
don’t apply lead styling to first paragraph if role is present (#2624, PR #2625)
-
raise clearer exception when extension class cannot be resolved (#2622, PR #2623)
-
add methods to read results from timings (#2578, PR #2580)
-
collapse bottom margin of last block in AsciiDoc table cell (#2568, PR #2593)
-
set authorcount to 0 if there are no authors (#2519, PR #2520)
-
validate fragment of interdoc xref that resolves to current doc (#2448, PR #2449)
-
put id attribute on tag around phrase instead of preceding anchor (#2445, PR #2446)
-
add .plist extension to XML circumfix comment family (#2430, PR #2431) (@akosma)
-
alias Document#title method to no args Document#doctitle method (#2429, PR #2432)
-
upgrade missing or unreadable include file to an error (#2424, PR #2426)
-
add compliance setting to disable natural cross references (#2405, PR #2460)
-
make hash in inter-document xref target optional if target has extension (#2404, PR #2406)
-
add CSS class to part that matches role (#2401, PR #2402)
-
add fit-content class to auto-width table (#2392)
-
automatically assign parent reference when adding node to parent (#2398, PR #2403)
-
leave inline anchor in section title as is if section has ID (#2243, PR #2427)
-
align and improve error message about invalid use of partintro between HTML5 and DocBook converters
-
rephrase warning when level 0 sections are found and the doctype is not book
-
report correct line number when duplicate bibliography anchor is found
-
only warn if thread_safe gem is missing when using built-in template cache
-
rename enumerate_section to assign_numeral; update API docs
-
drop deprecated compact option from CLI; remove from manpage
-
use more robust mechanism for lazy loading the asciimath gem
-
use consistent phrase to indicate the processor is automatically recovering from a problem
-
change Reader#skip_comment_lines to not return skipped lines
-
add styles to default stylesheet for display on Kindle (kf8) devices (PR #2475)
-
purge render method from test suite (except to verify alias)
-
- Documentation
-
-
translate 'section-refsig' for German language (PR #2633) (@ahus1)
-
synchronize French README with English version (PR #2637) (@flashcode)
-
- Build / Infrastructure
-
-
create an official logo for the project (#48) (@mmajko)
-
update Ruby versions in appveyor build matrix (PR #2388) (@miltador)
-
add mailinglist, changelog, source, and issues URI to gem spec
-
allow blocks and substitutions tests to be run directly
-
asciidoctor formula now available for Homebrew (@zmwangx)
-
- Distribution Packages
Refer to the CHANGELOG for a complete list of changes in older releases.