asciicrystal
= asciicrystal :description: A Crystal port of the Asciidoctor document processor. :repo_url: https://github.com/aloli-crystal/asciicrystal
A Crystal port of the https://github.com/asciidoctor/asciidoctor[Asciidoctor] document processor.
This shard provides a complete AsciiDoc processing pipeline in Crystal: an Abstract Syntax Tree (AST) model, a parser, a substitution engine, and three output converters (HTML5, DocBook 5, Manpage), faithfully ported from the Ruby implementation.
== Versions
[cols="2,2,2"] |=== | | Version | Date
| Gem Ruby Asciidoctor (source du portage) | 2.0.26 | 2025-10-24
| Shard Crystal asciicrystal | 2.0.26.14 | 2026-09-16 |===
NOTE: Ce shard est un portage de la gem Ruby Asciidoctor 2.0.26. Vérifier les https://rubygems.org/gems/asciidoctor/versions[versions sur RubyGems] pour savoir si une mise à jour est disponible.
== Status
Beta -- The core pipeline (parse → substitute → convert) is functional. Extensions API and syntax highlighting integration are not yet implemented.
=== Implemented
[cols="3,2,2"] |=== | Component | Crystal module | Ruby source
| Abstract node (base class) | Asciicrystal::AbstractNode | abstract_node.rb | Abstract block | Asciicrystal::AbstractBlock | abstract_block.rb | API (load / convert) | Asciicrystal.load, Asciicrystal.convert | load.rb, convert.rb | Attribute list parser | Asciicrystal::AttributeList | attribute_list.rb | Block | Asciicrystal::Block | block.rb | Callouts | Asciicrystal::Callouts | callouts.rb | CLI (options / invoker) | Asciicrystal::Cli::Options, Asciicrystal::Cli::Invoker | cli/options.rb, cli/invoker.rb | Constants | Asciicrystal::* | asciidoctor.rb | Content model (enum) | Asciicrystal::ContentModel | (symbols in Ruby) | Converter base | Asciicrystal::Converter::Base | converter.rb | Converter DocBook 5 | Asciicrystal::Converter::DocBook5Converter | converter/docbook5.rb | Converter HTML5 | Asciicrystal::Converter::Html5Converter | converter/html5.rb | Converter Manpage | Asciicrystal::Converter::ManPageConverter | converter/manpage.rb | Document | Asciicrystal::Document | document.rb | Document catalog | Asciicrystal::Catalog | (part of document.rb) | Helpers | Asciicrystal::Helpers | helpers.rb | Inline | Asciicrystal::Inline | inline.rb | List / ListItem | Asciicrystal::List, Asciicrystal::ListItem | list.rb | Logging | Asciicrystal::Logger | logging.rb | Parser | Asciicrystal::Parser | parser.rb | Reader / PreprocessorReader | Asciicrystal::Reader | reader.rb | Regular expressions | Asciicrystal::*Rx | rx.rb | Safe mode | Asciicrystal::SafeMode | (constants in asciidoctor.rb) | Section | Asciicrystal::Section | section.rb | Source location | Asciicrystal::SourceLocation | (part of abstract_block.rb) | Substitution (flags enum) | Asciicrystal::Substitution | substitutors.rb | Substitutors (inline engine) | Asciicrystal::Substitutors | substitutors.rb | Table / Column / Cell | Asciicrystal::Table, Table::Column, Table::Cell | table.rb |===
=== Not yet implemented
- Extensions API
- Syntax highlighting integration
- Template-based converter
== Installation
Add the dependency to your shard.yml:
[source,yaml]
dependencies: asciicrystal: github: aloli-crystal/asciicrystal version: "~> 2.0.26.12"
Run shards install.
== Usage
=== Command line
The shard also ships an executable, asciicrystal — the equivalent of the Ruby asciidoctor command (AsciiDoc in, HTML 5 / DocBook 5 / manpage out):
[source,sh]
shards build # produces bin/asciicrystal
bin/asciicrystal doc.adoc # → doc.html bin/asciicrystal doc.adoc -o out.html # explicit output bin/asciicrystal doc.adoc -b docbook5 # another backend bin/asciicrystal --help # all options
NOTE: For PDF output, use the companion shard https://github.com/aloli-crystal/asciicrystal-pdf[asciicrystal-pdf].
=== High-level API
[source,crystal]
require "asciicrystal"
Convert an AsciiDoc string to HTML5
html = Asciicrystal.convert("= Hello\n\nA bold paragraph.") puts html
Convert to DocBook 5
docbook = Asciicrystal.convert("= Hello\n\nA paragraph.", {"backend" => "docbook5"}) puts docbook
Convert to an HTML fragment, without the wrapper
fragment = Asciicrystal.convert("A bold paragraph.", {"standalone" => "false"}) puts fragment # =>
Load a document (parse without converting)
doc = Asciicrystal.load("= My Document\n\n== Section One\n\nParagraph.") puts doc.doctitle # => "My Document"
IMPORTANT: By default convert returns a standalone HTML document — <html>, <head> and a fallback stylesheet included — as Ruby Asciidoctor does. Pass {"standalone" => "false"} (or {"header_footer" => "false"}) to obtain an embeddable fragment. The full list of accepted keys is known_options in src/asciicrystal/api.cr.
=== Low-level parsing
[source,crystal]
require "asciicrystal"
source = <<-ASCIIDOC = My Document Author Name
== Introduction
This is a paragraph.
== Details
Another paragraph with bold text. ASCIIDOC
doc = Asciicrystal::Document.new reader = Asciicrystal::Reader.new(source.lines) Asciicrystal::Parser.parse(reader, doc)
Access the document title
puts doc.doctitle # => "My Document"
Traverse the tree
doc.find_by(context: :paragraph).each do |block| puts block.as(Asciicrystal::Block).source end
Access sections
doc.blocks.each do |block| if block.is_a?(Asciicrystal::Section) puts "Section: #{block.title} (level #{block.level})" end end
=== Building the AST manually
[source,crystal]
require "asciicrystal"
Create a document with an HTML5 converter
doc = Asciicrystal::Document.new converter = Asciicrystal::Converter::Html5Converter.new doc.converter = converter
Create a section
section = Asciicrystal::Section.new(document: doc, parent: doc, level: 1) section.title = "Introduction" section.id = "introduction" section.numeral = "1" doc << section
Create a paragraph block
para = Asciicrystal::Block.new( parent_block: section, context: :paragraph, content_model: Asciicrystal::ContentModel::Simple, source: "Hello, AsciiDoc!" ) section << para
Convert to HTML
puts converter.convert_section(section)
== Development
[source,sh]
Run all tests (468 examples)
crystal spec
Run only integration tests
crystal spec spec/integration/
Type-check without codegen
crystal build --no-codegen src/asciicrystal.cr
== Contributing
. Fork it ({repo_url}/fork) . Create your feature branch (git checkout -b my-new-feature) . Commit your changes (git commit -am 'Add some feature') . Push to the branch (git push origin my-new-feature) . Create a new Pull Request
== License
This project is licensed under the MIT License -- see the LICENSE file for details.
== Acknowledgements
This project is a Crystal port of https://github.com/asciidoctor/asciidoctor[Asciidoctor], originally written in Ruby by Dan Allen, Sarah White, and the Asciidoctor community. The AST model, parser, and converters follow the same architecture and naming conventions as the original.
asciicrystal
- 6
- 0
- 7
- 11
- 1
- 7 days ago
- February 28, 2026
MIT License
Tue, 29 Sep 2026 13:21:11 GMT