CommonDoc ยป Defining Nodes

CommonDoc allows the user to define new nodes through the use of define-node, which is similar to defclass with the addition of the :tag-name class option and the :attribute-name slot option.

In a language with a regular syntax, like Scriba or VerTeX, all syntactic structures have an explicit name and optionally an attribute list. This allows the parser and emitter to associate these structures with CommonDoc nodes, by mapping a string (the :tag-name) in the text to a class. This approach allows macro nodes to be parsed without actually modifying the parser of any of these formats.

Markdown, Textile, and other formats that explicitly map specific syntaxes to specific nodes won't benefit from these extensions, since for every node you want to support you have to modify both parser and emitter to add a new syntactic construct that creates it.

For example, Codex defines the following macro nodes:

(define-node cl-doc (macro-node)
  (:tag-name "cl:doc")
  (:documentation "Insert documentation of a node."))(define-node with-package (macro-node)
  ((name :reader package-macro-name
         :type string
         :attribute-name "name"
         :documentation "The package's name."))
  (:tag-name "cl:with-package")
  (:documentation "Set the current package to use in the body."))

(define-node param (macro-node)
  (:tag-name "cl:param")
  (:documentation "An argument of an operator."))

(define-node spec (macro-node)
  (:tag-name "cl:spec")
  (:documentation "Add a link to the Common Lisp HyperSpec."))

This means that, if there's a Scriba file with the text:

... the parameter @cl:param(array) is the array of elements which...

The cl:param tag will be parsed into the param macro node. This doesn't require modifying the source code of the Scriba parser.


define-node(name (&rest superclasses) slots &rest class-options)
Define a CommonDoc node.
Find a node class by its tag name.
Return a node class' tag name.
Return a node class' special slots.