3.8. Markup

Haddock understands certain textual cues inside documentation annotations that tell it how to render the documentation. The cues (or markup) have been designed to be simple and mnemonic in ASCII so that the programmer doesn't have to deal with heavyweight annotations when editing documentation comments.

3.8.1. Paragraphs

One or more blank lines separates two paragraphs in a documentation comment.

3.8.2. Special characters

The following characters have special meanings in documentation comments: \, /, ', `, ", @, <. To insert a literal occurrence of one of these special characters, precede it with a backslash (\).

Additionally, the character > has a special meaning at the beginning of a line, and the following characters have special meanings at the beginning of a paragraph: *, -. These characters can also be escaped using \.

Furthermore, the character sequence >>> has a special meaning at the beginning of a line. To escape it, just prefix the characters in the sequence with a backslash.

3.8.3. Character references

Although Haskell source files may contain any character from the Unicode character set, the encoding of these characters as bytes varies between systems, so that only source files restricted to the ASCII character set are portable. Other characters may be specified in character and string literals using Haskell character escapes. To represent such characters in documentation comments, Haddock supports SGML-style numeric character references of the forms &#D; and &#xH; where D and H are decimal and hexadecimal numbers denoting a code position in Unicode (or ISO 10646). For example, the references &#x3BB;, &#x3bb; and &#955; all represent the lower-case letter lambda.

3.8.4. Code Blocks

Displayed blocks of code are indicated by surrounding a paragraph with @...@ or by preceding each line of a paragraph with > (we often call these “bird tracks”). For example:

-- | This documentation includes two blocks of code:
--
-- @
--     f x = x + x
-- @
--
-- >  g x = x * 42

There is an important difference between the two forms of code block: in the bird-track form, the text to the right of the ’>‚ is interpreted literally, whereas the @...@ form interprets markup as normal inside the code block.

3.8.5. Examples

Haddock has markup support for examples of interaction with a read-eval-print loop (REPL). An example is introduced with >>> followed by an expression followed by zero or more result lines:

-- | Two examples are given below:
--
-- >>> fib 10
-- 55
--
-- >>> putStrLn "foo\nbar"
-- foo
-- bar

Result lines that only contain the string <BLANKLINE> are rendered as blank lines in the generated documentation.

3.8.6. Properties

Haddock provides markup for properties:

-- | Addition is commutative:
--
-- prop> a + b = b + a

This allows third-party applications to extract and verify them.

3.8.7. Hyperlinked Identifiers

Referring to a Haskell identifier, whether it be a type, class, constructor, or function, is done by surrounding it with single quotes:

-- | This module defines the type 'T'.

If there is an entity T in scope in the current module, then the documentation will hyperlink the reference in the text to the definition of T (if the output format supports hyperlinking, of course; in a printed format it might instead insert a page reference to the definition).

It is also possible to refer to entities that are not in scope in the current module, by giving the full qualified name of the entity:

-- | The identifier 'M.T' is not in scope

If M.T is not otherwise in scope, then Haddock will simply emit a link pointing to the entity T exported from module M (without checking to see whether either M or M.T exist).

To make life easier for documentation writers, a quoted identifier is only interpreted as such if the quotes surround a lexically valid Haskell identifier. This means, for example, that it normally isn't necessary to escape the single quote when used as an apostrophe:

-- | I don't have to escape my apostrophes; great, isn't it?

Nothing special is needed to hyperlink identifiers which contain apostrophes themselves: to hyperlink foo' one would simply type 'foo''. To hyperlink identifiers written in infix form, simply put them in quotes as always: '`elem`'.

For compatibility with other systems, the following alternative form of markup is accepted[3]: `T'.

3.8.8. Emphasis, Bold and Monospaced text

Emphasis may be added by surrounding text with /.../. Other markup is valid inside emphasis. To have a forward slash inside of emphasis, just escape it: /fo\/o/

Bold (strong) text is indicated by surrounding it with __...__. Other markup is valid inside bold. For example, __/foo/__ will make the emphasised text foo bold. You don't have to escape a single underscore if you need it bold: __This_text_with_underscores_is_bold__.

Monospaced (or typewriter) text is indicated by surrounding it with @...@. Other markup is valid inside a monospaced span: for example @'f' a b@ will hyperlink the identifier f inside the code fragment.

3.8.9. Linking to modules

Linking to a module is done by surrounding the module name with double quotes:

-- | This is a reference to the "Foo" module.

A basic check is done on the syntax of the header name to ensure that it is valid before turning it into a link but unlike with identifiers, whether the module is in scope isn't checked and will always be turned into a link.

3.8.10. Itemized and Enumerated lists

A bulleted item is represented by preceding a paragraph with either * or -. A sequence of bulleted paragraphs is rendered as an itemized list in the generated documentation, eg.:

-- | This is a bulleted list:
--
--     * first item
--
--     * second item

An enumerated list is similar, except each paragraph must be preceded by either (n) or n. where n is any integer. e.g.

-- | This is an enumerated list:
--
--     (1) first item
--
--     2. second item

Lists of the same type don't have to be separated by a newline:

-- | This is an enumerated list:
--
--     (1) first item
--     2. second item
--
-- This is a bulleted list:
--
--     * first item
--     * second item

You can have more than one line of content in a list element:

-- |
-- * first item
-- and more content for the first item
-- * second item
-- and more content for the second item

You can even nest whole paragraphs inside of list elements. The rules are 4 spaces for each indentation level. You're required to use a newline before such nested paragraph:

{-|
* Beginning of list
This belongs to the list above!

    > nested
    > bird
    > tracks

    * Next list
    More of the indented list.

        * Deeper

            @
            even code blocks work
            @

            * Deeper

                    1. Even deeper!
                    2. No newline separation even in indented lists.
-}

The indentation of the first list item is honoured. That is, in the following example the items are on the same level. Before Haddock 2.16.1, the second item would have been nested under the first item which was unexpected.

{-|
    * foo

    * bar
-}

3.8.11. Definition lists

Definition lists are written as follows:

-- | This is a definition list:
--
--   [@foo@]: The description of @foo@.
--
--   [@bar@]: The description of @bar@.

To produce output something like this:

foo

The description of foo.

bar

The description of bar.

Each paragraph should be preceded by the “definition term” enclosed in square brackets and followed by a colon. Other markup operators may be used freely within the definition term. You can escape ] with a backslash as usual.

Same rules about nesting and no newline separation as for bulleted and numbered lists apply.

3.8.12. URLs

A URL can be included in a documentation comment by surrounding it in angle brackets, for example:

<http://example.com>

If the output format supports it, the URL will be turned into a hyperlink when rendered.

If Haddock sees something that looks like a URL (such as something starting with http:// or ssh://) where the URL markup is valid, it will automatically make it a hyperlink.

3.8.13. Links

Haddock supports Markdown syntax for inline links. A link consists of a link text and a URL. The link text is enclosed in square brackets and followed by the URL enclosed in regular parentheses, for example:

[some link](http://example.com)

The link text is used as a descriptive text for the URL, if the output format supports it.

3.8.14. Images

Haddock supports Markdown syntax for inline images. This resembles the syntax for links, but starts with an exclamation mark. An example looks like this:

![image description](pathtoimage.png)

If the output format supports it, the image will be rendered inside the documentation. The image description is used as relpacement text and/or image title.

3.8.15. Anchors

Sometimes it is useful to be able to link to a point in the documentation which doesn't correspond to a particular entity. For that purpose, we allow anchors to be included in a documentation comment. The syntax is #label#, where label is the name of the anchor. An anchor is invisible in the generated documentation.

To link to an anchor from elsewhere, use the syntax "module#label" where module is the module name containing the anchor, and label is the anchor label. The module does not have to be local, it can be imported via an interface. Please note that in Haddock versions 2.13.x and earlier, the syntax was "module\#label". It is considered deprecated and will be removed in the future.

3.8.16. Headings

Headings inside of comment documentation are possible be preceding them with a number of =s. From 1 to 6 are accepted. Extra =s will be treated as belonging to the text of the heading. Note that it's up to the output format to decide how to render the different levels.

-- |
-- = Heading level 1 with some /emphasis/
-- Something underneath the heading.
--
-- == /Subheading/
-- More content.
--
-- === Subsubheading
-- Even more content.

Note that while headings have to start on a new paragraph, we allow paragraph-level content to follow these immediately.

-- |
-- = Heading level 1 with some __bold__
-- Something underneath the heading.
--
-- == /Subheading/
-- More content.
--
-- === Subsubheading
-- >>> examples are only allowed at the start of paragraphs

As of 2.15.1, there's experimental (read: subject to change or get removed) support for collapsible headers: simply wrap your existing header title in underscores, as per bold syntax. The collapsible section will stretch until the end of the comment or until a header of equal or smaller number of =s.

-- |
-- === __Examples:__
-- >>> Some very long list of examples
--
-- ==== This still falls under the collapse
-- Some specialised examples
--
-- === This is does not go into the collapsable section.
-- More content.

3.8.17. Metadata

Since Haddock 2.16.0, some support for embedding metadata in the comments has started to appear. The use of such data aims to standardise various community conventions in how such information is conveyed and to provide uniform rendering.

3.8.17.1. Since

@since annotation can be used to convey information about when the function was introduced or when it has changed in the way significant to the user. @since is a paragraph-level element. While multiple such annotations are not an error, only the one to appear in the comment last will be used. @since has to be followed with a version number, no further description is currently allowed. The meaning of this feature is subject to change in the future per user feedback.

-- |
-- Some comment
--
-- @since 1.2.3


[3] We chose not to use this as the primary markup for identifiers because strictly speaking the ` character should not be used as a left quote, it is a grave accent.