Using the Markdown Library
==========================

The most central part of the Markdown library is the function `parse`:

```stormdoc
- markdown.parse(core.Str)
```

As can be seen above, the function returns a [stormname:markdown.Document] on success. This class
represents the root of the Markdown document as a sequence of elements
([stormname:markdown.ElementSeq]). The `Document` itself has the following members apart from the
`toS` member that outputs a formatted version of the document as Markdown:

```stormdoc
@markdown.Document
- .elements
- .toHtml()
- .visit(*)
```

Elements
--------

The document consists of a list of elements. Each element corresponds to a piece of the document.
Some elements, such as lists, may themselves contain other elements, or lists of elements. The
document thus follows a tree-like structure.

As noted above, lists of elements are typically stored as the class [stormname:markdown.ElementSeq]
internally, in order to share some of the logic related to traversing such lists. The class has a
member `elements` that is the stored array of elements. The `ElementSeq` class is not an element
itself, and is typically safe to ignore in most cases.

The class [stormname:markdown.Element] contains the following members, that all other elements need
to override:

```stormdoc
@markdown.Element
- .visit(*)
- .toHtml(*)
```

The following elements are provided by the library (and generated by the parser):

- [stormname:markdown.Heading]

  Represent a heading in Markdown. The level of the heading is stored in the `level` member (1 and
  upward). The contained text is stored in the `text` member.

  Produces `<hX>` tags in HTML, where `X` is the level.

- [stormname:markdown.Paragraph]

  A paragraph of text in Markdown. The text is stored in the `text` member.

  Produces a `<p>` tag around the text in HTML.

- [stormname:markdown.List]

  Represents a list in Markdown. The member `ordered` determines if the list is ordered or not. The
  elements in the list are stored in the `items` array. Each item consists of a sequence of elements
  (represented by an `ElementSeq` instance).

  The list produces `<ol>` or `<ul>` elements in HTML. Each element will then be turned into a
  `<li>` element. If the first element in the item is a paragraph, the `<p>` tags around that
  element are removed.

- [stormname:markdown.CodeBlock]

  Represents a block of code in Markdown. The language is available as the member `language`. The
  code is stored as an array of individual lines in the `code` member.

  It produces a `<pre>` tag in HTML.

- [stormname:markdown.CustomHtml]

  This element is not produced by the Markdown parser. Rather, it can be used by libraries to insert
  custom HTML code into the document when producing HTML output.

  The element has two member variables: `code` that is a string that contains the HTML code to
  produce, and `skipIndent` that determines whether the code inside `code` should be indented to
  match the surrounding context. If the HTML code contains for example a `<pre>` tag, this extra
  indentation might change the appearence of the code and `skipIndent` must be set to `true`.


- [stormname:markdown.PackedElements]

  This element is not produced by the Markdown parser. Rather, it is mainly intended to be used in
  conjunction with `Visitor`s. Whenever a `PackedElements` object is inserted into an `ElementSeq`,
  the contained elements are inserted one by one. Thus, the `PackedElements` are essentially
  flattened immediately.

  This is useful when one wishes to replace a single element with multiple elements using a
  `Visitor`, for example.


Formatted Text
--------------

The class [stormname:markdown.FormattedText] represents a piece of text with formatting. Most of the
elements use this class to represent their contained text. A `FormattedText` instance is a list of
[stormname:markdown.TextSpan] classes that each represent individual pieces of the text, each with
possibly different formatting. As we shall see, some `TextSpan`s contain `FormattedText` objects
themselves. This makes it possible to apply more than one formatting option to a single piece of
text.

The `FormattedText` class has the following members:

```stormdoc
@markdown.FormattedText
- .spans
- .__init(Str)
- .__init(TextSpan)
- .add(*)
- .addLine(*)
- .toHtml(*)
```

The `TextSpan` class is similar to the `Element` class, and has the following members that
subclasses need to implement:

```stormdoc
@markdown.TextSpan
- .toHtml(*)
- .visit(*)
```

The following spans are provided by the library:

- [stormname:markdown.PlainTextSpan]

  A span that contains plain text (stored as `text`). This is essentially the leaf nodes of a tree
  of formatted text, since most other nodes contain a `FormattedText` instance themselves.

- [stormname:markdown.ItalicText]

  A span that corresponds to *italic* text. Contains formatted text stored as `text`. Produces
  `<em>` tags in HTML.

- [stormname:markdown.BoldText]

  A span that corresponds to **bold** text. Contains formatted text stored as `text`. Produces
  `<strong>` tags in HTML.

- [stormname:markdown.InlineCode]

  A span that corresponds to inline code. The code is stored as the member `text`, as a string. This
  means that no additional formatting may be applied to the text inside the code span. Produces
  `<code>` tags in HTML.

- [stormname:markdown.Link]

  A span that corresponds to a link. The text of the link is stored as `text` (as formatted text),
  and the target of the link is stored as `target` (as a `Str`). Produces an `<a>` tag with the
  `target` as the `href`.

- [stormname:markdown.CustomText]

  A span that corresponds to the appearance of a `[]` element without parentheses afterwards in the
  Markdown source. As mentioned previously in the manual, this element is purely used as an
  extension mechanism. The text inside the brackets are stored as `text` (as a `Str`). By default,
  the span simply outputs `text` without modification.

- [stormname:markdown.CustomInlineHtml]

  This span is not generated by the parser. It is intended to be used by others to inject custom
  HTML code in the context of a span. The HTML code is stored as the member `text`.

- [stormname:markdown.PackedText]

  This element is not generated by the parser. Rather, it is intended to be used in conjunction with
  the `Visitor`, to allow replacing a single span with multiple spans. As such, whenever a
  `PackedText` span is inserted into a `FormattedText` object (or a `PackedText` object), it is
  flattened into a list.


Visitors
--------

The classes above all have a `visit` function to allow traversing the hierarchy conveniently. The
`visit` functions take a `Visitor` as a parameter, and calls one of the member functions for each
element. Each of the member functions return an instance of the same object that was received. The
`visitor` function uses the returned object to replace the original one. In this way, it is possible
to also replace elements in the hierarchy, regardless of what element they are located inside.

If it is necessary to replace one element with multiple elements, the classes
[stormname:markdown.PackedElements] and [stormname:markdown.PackedText] can be used.

The `Visitor` class has the following members. The default implementation of all of them is to
simply return the object passed as a parameter, so that they implement a no-op by default:

```stormdoc
@markdown.Visitor
- .visit(*)
```
