npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@asciidoc-js/adast

v1.0.0

Published

AsciiDoc Abstract Syntax Tree format

Readme

ADAST

AsciiDoc Abstract Syntax Tree format.


Contents

Introduction

This document defines a format for representing AsciiDoc documents as abstract syntax trees. Development of adast started in 2025. This spec is written in a Web IDL-like grammar.

Where this specification fits

adast extends unist, a format for syntax trees, to benefit from its ecosystem of utilities.

adast relates to mdast (Markdown) and hast (HTML) as a sibling specification — all three extend unist but represent different source languages. Converters between the formats (e.g., adast-to-mdast) can live in separate packages.

An adast tree is typically produced by parsing an AsciiDoc document with a tool such as Asciidoctor and can be serialized back to AsciiDoc source, converted to hast for HTML rendering, or processed by any unist utility.

Types

TypeScript types for adast nodes are published as the adast npm package:

npm install --save-dev @asciidoc-js/adast
import type {Document, Paragraph, Section} from '@asciidoc-js/adast'

Nodes (abstract)

adast inherits the abstract node types from unist:

Node

interface Node {
  type: string
  data: Data?
  position: Position?
}

The type field is a non-empty string that identifies the node variant.

The data field is an optional object for storing implementation-specific information that does not need to be in the AST.

The position field is an optional object indicating where the node originates in the source document.

Parent

interface Parent <: Node {
  children: [Node]
}

A node that contains other nodes.

Literal

interface Literal <: Node {
  value: string
}

A node that contains a text value.

Attributes

dictionary Attributes {
  [name: string]: string | number | boolean | null
}

A key-value map of AsciiDoc attributes. Present on most block and inline nodes. Attribute names are lowercase strings; values are typically strings.


Nodes (root)

Document

interface Document <: Parent {
  type: 'document'
  doctype: 'article' | 'book' | 'manpage' | 'inline'?
  title: string?
  attributes: Attributes?
  children: [DocumentContent]
  data: DocumentData?
}

Document (Parent) represents a complete AsciiDoc document. It is always the root of the tree.

doctype indicates the document type — 'article' (default), 'book', 'manpage', or 'inline'.

title is the resolved document title (level-0 heading), or null if the document has no title.

attributes holds document-level attributes set with :name: value lines in the document header.

For example, the AsciiDoc document:

= My Document
Author Name
:toc:

Some introductory text.

== First Section

Content here.

Yields:

{
  "type": "document",
  "doctype": "article",
  "title": "My Document",
  "attributes": {"toc": ""},
  "children": [
    {
      "type": "preamble",
      "children": [
        {
          "type": "paragraph",
          "children": [{"type": "text", "value": "Some introductory text."}]
        }
      ]
    },
    {
      "type": "section",
      "depth": 1,
      "title": "First Section",
      "children": [
        {
          "type": "paragraph",
          "children": [{"type": "text", "value": "Content here."}]
        }
      ]
    }
  ]
}

Preamble

interface Preamble <: Parent {
  type: 'preamble'
  children: [BlockContent]
}

Preamble (Parent) represents content between the document header and the first section. A document has at most one preamble, and it is always the first child of the document (when present).


Nodes (sections)

Section

interface Section <: Parent {
  type: 'section'
  depth: 0 | 1 | 2 | 3 | 4 | 5
  title: string
  numbered: boolean?
  sectname: string?
  numeral: string?
  id: string?
  attributes: Attributes?
  children: [Section | BlockContent]
}

Section (Parent) represents a document section created by a heading marker (= through ======).

depth indicates the nesting level: 0 for the document title / part level, 1 through 5 for section levels.

title is the resolved section title text (after substitutions).

sectname classifies the section kind. Standard values:

| Value | Meaning | | ------------------- | -------------------------------- | | 'section' | Normal section | | 'chapter' | Level 1 in book doctype | | 'part' | Level 0 in multi-part book | | 'appendix' | Appendix section | | 'preface' | Preface | | 'colophon' | Colophon | | 'dedication' | Dedication | | 'acknowledgments' | Acknowledgments | | 'glossary' | Glossary | | 'bibliography' | Bibliography | | 'index' | Index | | 'abstract' | Abstract | | 'synopsis' | Synopsis (manpage) |

Children of a section can be nested sections (of greater depth) and block content.

For example:

== Introduction

Paragraph text.

=== Background

More details.

Yields:

{
  "type": "section",
  "depth": 1,
  "title": "Introduction",
  "sectname": "section",
  "children": [
    {
      "type": "paragraph",
      "children": [{"type": "text", "value": "Paragraph text."}]
    },
    {
      "type": "section",
      "depth": 2,
      "title": "Background",
      "sectname": "section",
      "children": [
        {
          "type": "paragraph",
          "children": [{"type": "text", "value": "More details."}]
        }
      ]
    }
  ]
}

Nodes (compound blocks)

Compound blocks contain other block-level nodes as children.

Paragraph

interface Paragraph <: Parent {
  type: 'paragraph'
  id: string?
  attributes: Attributes?
  children: [InlineContent]
}

Paragraph (Parent) represents a block of prose. Its children are inline content nodes.

Admonition

interface Admonition <: Parent {
  type: 'admonition'
  name: 'note' | 'tip' | 'important' | 'warning' | 'caution'
  textlabel: string?
  title: string?
  id: string?
  attributes: Attributes?
  children: [BlockContent]
}

Admonition (Parent) represents a call-out block with a severity label.

name identifies the admonition type.

Can be created from a paragraph-style shorthand (NOTE: text) — in which case children will contain a single Paragraph — or from a delimited block with admonition style ([NOTE] on an ==== block).

For example:

NOTE: Remember to save your work.

Yields:

{
  "type": "admonition",
  "name": "note",
  "textlabel": "Note",
  "children": [
    {
      "type": "paragraph",
      "children": [{"type": "text", "value": "Remember to save your work."}]
    }
  ]
}

Example

interface Example <: Parent {
  type: 'example'
  title: string?
  caption: string?
  id: string?
  attributes: Attributes?
  children: [BlockContent]
}

Example (Parent) represents an example block — ==== delimiters.

Sidebar

interface Sidebar <: Parent {
  type: 'sidebar'
  title: string?
  id: string?
  attributes: Attributes?
  children: [BlockContent]
}

Sidebar (Parent) represents a sidebar block — **** delimiters.

Quote

interface Quote <: Parent {
  type: 'quote'
  title: string?
  attribution: string?
  citetitle: string?
  id: string?
  attributes: Attributes?
  children: [BlockContent]
}

Quote (Parent) represents a blockquote — ____ delimiters.

attribution names the quoted person or source. citetitle identifies the source work.

For example:

[quote, Albert Einstein]
____
Imagination is more important than knowledge.
____

Yields:

{
  "type": "quote",
  "attribution": "Albert Einstein",
  "children": [
    {
      "type": "paragraph",
      "children": [
        {"type": "text", "value": "Imagination is more important than knowledge."}
      ]
    }
  ]
}

Open

interface Open <: Parent {
  type: 'open'
  style: string?
  title: string?
  id: string?
  attributes: Attributes?
  children: [BlockContent]
}

Open (Parent) represents an open block — -- delimiters.

The style attribute can morph it into other block types: 'abstract', 'partintro', 'comment', 'example', 'literal', 'listing', 'pass', 'quote', 'sidebar', 'source', 'verse', 'admonition'.


Nodes (leaf blocks)

Leaf blocks contain text content (a value string) rather than child nodes.

Listing

interface Listing <: Literal {
  type: 'listing'
  value: string
  style: 'source'?
  language: string?
  title: string?
  caption: string?
  id: string?
  attributes: Attributes?
}

Listing (Literal) represents a listing block — ---- delimiters.

When style is 'source', the block is a source code block with optional syntax highlighting via the language field.

For example:

[source,javascript]
----
console.log('Hello, world!')
----

Yields:

{
  "type": "listing",
  "style": "source",
  "language": "javascript",
  "value": "console.log('Hello, world!')"
}

Literal

interface Literal <: Literal {
  type: 'literal'
  value: string
  title: string?
  id: string?
  attributes: Attributes?
}

Literal (Literal) represents a literal block — .... delimiters or indented lines.

Content is rendered monospace, preserving whitespace. Only special-character substitutions are applied.

Verse

interface Verse <: Literal {
  type: 'verse'
  value: string
  attribution: string?
  citetitle: string?
  title: string?
  id: string?
  attributes: Attributes?
}

Verse (Literal) represents a verse block — a ____ block with [verse] style.

Line breaks are preserved as written. Typically used for poetry.

Pass

interface Pass <: Literal {
  type: 'pass'
  value: string
  id: string?
  attributes: Attributes?
}

Pass (Literal) represents a passthrough block — ++++ delimiters. Content is passed to the output without substitution.

Stem

interface Stem <: Literal {
  type: 'stem'
  value: string
  style: 'asciimath' | 'latexmath'?
  id: string?
  attributes: Attributes?
}

Stem (Literal) represents a STEM (math) block.

style indicates the notation format.


Nodes (void blocks)

Void blocks have no text content and no children.

Image

interface Image <: Node {
  type: 'image'
  target: string
  alt: string?
  title: string?
  caption: string?
  id: string?
  attributes: Attributes?
}

Image (Node) represents a block image — image::target[alt].

Audio

interface Audio <: Node {
  type: 'audio'
  target: string
  title: string?
  id: string?
  attributes: Attributes?
}

Audio (Node) represents a block audio macro.

Video

interface Video <: Node {
  type: 'video'
  target: string
  title: string?
  id: string?
  attributes: Attributes?
}

Video (Node) represents a block video macro.

ThematicBreak

interface ThematicBreak <: Node {
  type: 'thematicBreak'
}

ThematicBreak (Node) represents a horizontal rule — '''.

PageBreak

interface PageBreak <: Node {
  type: 'pageBreak'
}

PageBreak (Node) represents a page break — <<<.

Toc

interface Toc <: Node {
  type: 'toc'
  id: string?
  attributes: Attributes?
}

Toc (Node) represents a table-of-contents macro — toc::[].

FloatingTitle

interface FloatingTitle <: Parent {
  type: 'floatingTitle'
  depth: 1 | 2 | 3 | 4 | 5
  id: string?
  attributes: Attributes?
  children: [InlineContent]
}

FloatingTitle (Parent) represents a discrete heading — a heading with the [discrete] attribute that does not create a section.


Nodes (lists)

UnorderedList

interface UnorderedList <: Parent {
  type: 'unorderedList'
  style: string?
  title: string?
  id: string?
  attributes: Attributes?
  children: [ListItem]
}

UnorderedList (Parent) represents a bullet list — lines starting with *, -, etc.

OrderedList

interface OrderedList <: Parent {
  type: 'orderedList'
  style: 'arabic' | 'loweralpha' | 'upperalpha' | 'lowerroman' | 'upperroman' | 'lowergreek'?
  start: number?
  reversed: boolean?
  title: string?
  id: string?
  attributes: Attributes?
  children: [ListItem]
}

OrderedList (Parent) represents a numbered list — lines starting with ., .., etc.

DescriptionList

interface DescriptionList <: Parent {
  type: 'descriptionList'
  style: string?
  title: string?
  id: string?
  attributes: Attributes?
  children: [DescriptionListEntry]
}

DescriptionList (Parent) represents a description (definition) list — term:: description entries.

CalloutList

interface CalloutList <: Parent {
  type: 'calloutList'
  title: string?
  id: string?
  attributes: Attributes?
  children: [ListItem]
}

CalloutList (Parent) represents a callout list — explanations for callout markers in listing/literal blocks.

ListItem

interface ListItem <: Parent {
  type: 'listItem'
  marker: string?
  checked: boolean?
  attributes: Attributes?
  children: [BlockContent]
}

ListItem (Parent) represents a single item in an unordered, ordered, or callout list.

marker is the source marker string (e.g., '*', '.').

checked indicates checkbox state for task list items: true for checked ([x]), false for unchecked ([ ]), undefined for regular items.

DescriptionListEntry

interface DescriptionListEntry <: Parent {
  type: 'descriptionListEntry'
  children: [DescriptionListTerm | DescriptionListDescription]
}

DescriptionListEntry (Parent) groups one or more terms with an optional description in a {@link DescriptionList}.

DescriptionListTerm

interface DescriptionListTerm <: Parent {
  type: 'descriptionListTerm'
  children: [InlineContent]
}

DescriptionListTerm (Parent) is a term in a description list entry.

DescriptionListDescription

interface DescriptionListDescription <: Parent {
  type: 'descriptionListDescription'
  children: [BlockContent]
}

DescriptionListDescription (Parent) is the description part of a description list entry.


Nodes (table)

Table

interface Table <: Parent {
  type: 'table'
  columns: [TableColumn]
  title: string?
  caption: string?
  id: string?
  attributes: Attributes?
  children: [TableHead | TableBody | TableFoot]
}

Table (Parent) represents a table block — |===.

columns is an array of TableColumn objects describing each column's alignment, width, and default style.

Children are table sections: an optional TableHead, one or more TableBody, and an optional TableFoot.

TableColumn

dictionary TableColumn {
  halign: 'left' | 'center' | 'right'?
  valign: 'top' | 'middle' | 'bottom'?
  width: number?
  colpcwidth: number?
  style: 'asciidoc' | 'emphasis' | 'header' | 'literal' | 'monospaced' | 'strong'?
}

TableColumn is a data object (not a node) that describes default properties for a column.

TableHead

interface TableHead <: Parent {
  type: 'tableHead'
  children: [TableRow]
}

TableHead (Parent) contains the header row(s) of a table.

TableBody

interface TableBody <: Parent {
  type: 'tableBody'
  children: [TableRow]
}

TableBody (Parent) contains the body rows of a table.

TableFoot

interface TableFoot <: Parent {
  type: 'tableFoot'
  children: [TableRow]
}

TableFoot (Parent) contains the footer row(s) of a table.

TableRow

interface TableRow <: Parent {
  type: 'tableRow'
  children: [TableCell]
}

TableRow (Parent) represents a row in a table section.

TableCell

interface TableCell <: Parent {
  type: 'tableCell'
  colspan: number?
  rowspan: number?
  halign: 'left' | 'center' | 'right'?
  valign: 'top' | 'middle' | 'bottom'?
  style: 'asciidoc' | 'emphasis' | 'header' | 'literal' | 'monospaced' | 'strong'?
  children: [BlockContent | InlineContent]
}

TableCell (Parent) represents a cell in a table row.

When style is 'asciidoc', the cell contains a nested AsciiDoc document and children are block content. Otherwise children are inline content.


Nodes (inline — parent)

Inline parent nodes contain other inline nodes as children.

Strong

interface Strong <: Parent {
  type: 'strong'
  id: string?
  attributes: Attributes?
  children: [InlineContent]
}

Strong (Parent) represents bold text — *text* or **text**.

Emphasis

interface Emphasis <: Parent {
  type: 'emphasis'
  id: string?
  attributes: Attributes?
  children: [InlineContent]
}

Emphasis (Parent) represents italic text — _text_ or __text__.

Mark

interface Mark <: Parent {
  type: 'mark'
  id: string?
  attributes: Attributes?
  children: [InlineContent]
}

Mark (Parent) represents highlighted text — #text# or ##text##.

Superscript

interface Superscript <: Parent {
  type: 'superscript'
  children: [InlineContent]
}

Superscript (Parent) — ^text^.

Subscript

interface Subscript <: Parent {
  type: 'subscript'
  children: [InlineContent]
}

Subscript (Parent) — ~text~.

DoubleQuoted

interface DoubleQuoted <: Parent {
  type: 'doubleQuoted'
  children: [InlineContent]
}

DoubleQuoted (Parent) represents smart/typographic double quotes — "`text`".

SingleQuoted

interface SingleQuoted <: Parent {
  type: 'singleQuoted'
  children: [InlineContent]
}

SingleQuoted (Parent) represents smart/typographic single quotes — '`text`'.

Link

interface Link <: Parent {
  type: 'link'
  url: string
  title: string?
  id: string?
  attributes: Attributes?
  children: [InlineContent]
}

Link (Parent) represents a hyperlink — link:url[text] or an auto-detected URL.

CrossReference

interface CrossReference <: Parent {
  type: 'crossReference'
  target: string
  refid: string?
  path: string?
  fragment: string?
  id: string?
  attributes: Attributes?
  children: [InlineContent]
}

CrossReference (Parent) represents a cross-reference to another location — <<id>> or xref:target[].

target is the raw reference target. refid is the resolved reference ID (without #). path and fragment are the path and fragment components for inter-document references.

Footnote

interface Footnote <: Parent {
  type: 'footnote'
  identifier: string?
  index: number?
  children: [InlineContent]
}

Footnote (Parent) represents a footnote — footnote:[text].


Nodes (inline — literal)

Inline literal nodes contain a text value rather than child nodes.

Text

interface Text <: Literal {
  type: 'text'
  value: string
}

Text (Literal) represents plain text content.

Monospaced

interface Monospaced <: Literal {
  type: 'monospaced'
  value: string
  id: string?
  attributes: Attributes?
}

Monospaced (Literal) represents inline code text — `text` or ``text``.

InlinePass

interface InlinePass <: Literal {
  type: 'inlinePass'
  value: string
}

InlinePass (Literal) represents an inline passthrough — +text+ or pass:[text].


Nodes (inline — void)

Void inline nodes have no children and no text value.

Anchor

interface Anchor <: Node {
  type: 'anchor'
  identifier: string
  reftext: string?
}

Anchor (Node) represents an inline anchor (bookmark) — [[id]] or anchor:id[].

BibliographyReference

interface BibliographyReference <: Node {
  type: 'bibliographyReference'
  identifier: string
  label: string?
}

BibliographyReference (Node) represents a bibliography entry — [[[id]]] or [[[id, label]]].

InlineImage

interface InlineImage <: Node {
  type: 'inlineImage'
  target: string
  alt: string?
  attributes: Attributes?
}

InlineImage (Node) represents an inline image — image:target[alt].

Icon

interface Icon <: Node {
  type: 'icon'
  name: string
  attributes: Attributes?
}

Icon (Node) represents an inline icon — icon:name[].

LineBreak

interface LineBreak <: Node {
  type: 'lineBreak'
}

LineBreak (Node) represents a hard line break — + at end of line.

InlineCallout

interface InlineCallout <: Node {
  type: 'inlineCallout'
  number: number
}

InlineCallout (Node) represents a callout marker in a listing block — <1>, <2>, etc.

Keyboard

interface Keyboard <: Node {
  type: 'keyboard'
  keys: [string]
}

Keyboard (Node) represents a keyboard shortcut — kbd:[Ctrl+Alt+Del].

Button

interface Button <: Node {
  type: 'button'
  label: string
}

Button (Node) represents a UI button — btn:[Save].

Menu

interface Menu <: Node {
  type: 'menu'
  menuName: string
  submenus: [string]
  menuitem: string
}

Menu (Node) represents a menu selection — menu:File[Save As...].

IndexTerm

interface IndexTerm <: Node {
  type: 'indexTerm'
  terms: [string]
  visible: boolean?
}

IndexTerm (Node) represents an index entry — indexterm:[primary, secondary, tertiary] or ((primary)).


Content model

Each node belongs to one or more content categories that constrain where it may appear in the tree.

| Category | Description | | --------------------------- | ----------------------------------------------- | | DocumentContent | Nodes that can be children of Document | | SectionContent | Nodes that can be children of Section | | BlockContent | Block-level nodes for any compound container | | ListContent | Children of lists (ListItem) | | DescriptionListContent | Children of description lists | | TableContent | Children of tables (table sections) | | RowContent | Children of table sections (TableRow) | | InlineContent | Inline (phrasing) content |

DocumentContent

DocumentContent = Preamble | Section | BlockContent

SectionContent

SectionContent = Section | BlockContent

BlockContent

BlockContent = Paragraph | Admonition | Listing | Literal | Example
             | Sidebar | Quote | Verse | Open | Pass | Stem | Table
             | Image | Audio | Video | ThematicBreak | PageBreak | Toc
             | FloatingTitle | UnorderedList | OrderedList
             | DescriptionList | CalloutList

InlineContent

InlineContent = Text | Strong | Emphasis | Monospaced | Superscript
              | Subscript | Mark | DoubleQuoted | SingleQuoted | Link
              | CrossReference | Anchor | BibliographyReference
              | InlineImage | Icon | Footnote | LineBreak
              | InlineCallout | Keyboard | Button | Menu | IndexTerm
              | InlinePass

Glossary

  • block content — content that participates in the block layout flow (paragraphs, sections, lists, tables, etc.)
  • compound block — a block whose content model is 'compound', meaning it contains other blocks as children
  • inline content — content that participates in the inline (text) flow (formatted text, links, images, etc.)
  • leaf block — a block whose content model is 'simple', 'verbatim', or 'raw', meaning it holds text content
  • void block — a block whose content model is 'empty', meaning it has neither text content nor children

Mapping to Asciidoctor

The following table maps adast node types to Asciidoctor's internal context values and classes.

| adast type | Asciidoctor context | Asciidoctor class | | --------------------------- | ---------------------- | ------------------ | | document | document | Document | | preamble | preamble | Block | | section | section | Section | | paragraph | paragraph | Block | | admonition | admonition | Block | | listing | listing | Block | | literal | literal | Block | | example | example | Block | | sidebar | sidebar | Block | | quote | quote | Block | | verse | verse | Block | | open | open | Block | | pass | pass | Block | | stem | stem | Block | | image | image | Block | | audio | audio | Block | | video | video | Block | | thematicBreak | thematic_break | Block | | pageBreak | page_break | Block | | toc | toc | Block | | floatingTitle | floating_title | Block | | unorderedList | ulist | List | | orderedList | olist | List | | descriptionList | dlist | List | | calloutList | colist | List | | listItem | list_item | ListItem | | table | table | Table | | tableCell | table_cell | Table::Cell | | strong | quoted (type=strong) | Inline | | emphasis | quoted (type=emphasis)| Inline | | monospaced | quoted (type=monospaced)| Inline | | superscript | quoted (type=superscript)| Inline | | subscript | quoted (type=subscript)| Inline | | mark | quoted (type=mark) | Inline | | doubleQuoted | quoted (type=double) | Inline | | singleQuoted | quoted (type=single) | Inline | | link | anchor (type=link) | Inline | | crossReference | anchor (type=xref) | Inline | | anchor | anchor (type=ref) | Inline | | bibliographyReference | anchor (type=bibref) | Inline | | inlineImage | image (type=image) | Inline | | icon | image (type=icon) | Inline | | footnote | footnote | Inline | | lineBreak | break | Inline | | inlineCallout | callout | Inline | | keyboard | kbd | Inline | | button | button | Inline | | menu | menu | Inline | | indexTerm | indexterm | Inline | | inlinePass | quoted (type=monospaced, subs=none) | Inline |


References

  • unist — Universal Syntax Tree format
  • mdast — Markdown Abstract Syntax Tree format
  • hast — Hypertext Abstract Syntax Tree format
  • AsciiDoc — AsciiDoc Language Documentation
  • Asciidoctor — AsciiDoc processor

License

MIT © Pablo Angelani [email protected]