Cmarkit.Label
Labels.
Labels are used by reference links to refer to the definitions of link reference definitions, footnote definitions and your own interpretations.
The type for label keys. These are link labels normalized for matching.
The type for link labels.
val make : ?meta:Meta.t -> key:string -> Block_line.tight list -> t
make key text
is a label with key id
and unormalized text text
.
val text : t -> Block_line.tight list
text l
is the text of l
.
val text_to_string : t -> string
text_to_string l
is the lines of text
separated by spaces. In contrast to key
this has not gone throught normalization.
A label definition is the content referenced by its key
.
Labels are defined in documents via footnotes and link reference definitions. Additional label definitions can be added before parsing starts by using the defs
argument of Doc.of_string
. They can also be manipulated and created on the fly during parsing by using a resolver.
The type for label definitions. See for example Link_definition.Def
or Block.Footnote.Def
.
type defs = def Map.t
The type for label definitions. Maps label keys to their definition.
To have more control over the label definitions used in a document, the defs
argument of Doc.of_string
can be specified to pre-populate the label definitions used during parsing; for example with those of a previously parsed document.
In addition the resolver
argument can be specified to:
In particular 2. can be used to create synthetic label definitions on undefined label references. This provides the ability to treat the very liberal link label syntax as a domain specific language of yours (e.g. for data binding).
Note that parsing is not finished when resolvers are invoked this is the reason why you don't get access to the definition's data during resolution.
See an example.
type context = [
|
`Def of t option * t
Label definitions
*)|
`Ref of [ `Link | `Image ] * t * t option
Label references
*) ]
The type for resolver contexts. See resolver
.
The type for resolvers. context
is:
`Def (prev, current)
when we just hit a link reference definition or footnote definition that defines the label current
. If there is already a definition for current
's key
it is provided in prev
(whose meta
has the location of the definition if you parse with locations). If None
is returned the current
definition is ignored, and definition prev
(if any) is kept for the document. If Some l
is returned l
's key will be bound to the parsed definition for current
in Doc.defs
at the end of parsing. The result of the resolver is stored in the abstract syntax tree and available via Link_definition.defined_label
and Block.Footnote.defined_label
.`Ref (kind, ref, def)
when we just hit a link or image referencing label ref
. def
is the label defining ref
's key
in the document (if any). The result of the resolver is the label stored for resolving the reference to its definition in the resulting Inline.Link
node; None
means that label
is undefined and the inline becomes Inline.Text
like in CommonMark.See an example and the default_resolver
.
val default_resolver : resolver
default_resolver
is the default resolver.
This resolves according to the CommonMark specification. The first label definition always takes over subsequent ones and resolution is left untouched (i.e. a label has to be defined in the document to be used):
let default_resolver = function
| `Def (None, l) -> Some l
| `Def (Some _, _) -> None (* Previous takes over *)
| `Ref (_, _, def) -> def
In this example we assume references to undefined labels denote links to pages or media in our wiki and want to process them them later via a tree transformation or in a renderer extension.
We devise a resolver to create synthetic labels on any undefined label so that the CommonMark parser does not turn them into text.
let wikilink = Cmarkit.Meta.key () (* A meta key to recognize them *)
let make_wikilink label = (* Just a placeholder label definition *)
let meta = Cmarkit.Meta.tag wikilink (Cmarkit.Label.meta label) in
Cmarkit.Label.with_meta meta label
let with_wikilinks = function
| `Def _ as ctx -> Cmarkit.Label.default_resolver ctx
| `Ref (_, _, (Some _ as def)) -> def (* As per doc definition *)
| `Ref (_, ref, None) -> Some (make_wikilink ref)