Documentation / Plain Markdown

Plain Markdown

Plain Markdown earns its place as the least magical content format in a Moth project.

The compiler can import it, render it and hand the result to the HTML builder. It never pretends the file contains Moth code.

Choose the explanation level: Markdown files

Markdown files

A .md file is plain Markdown. The compiler renders it and hands the HTML to the builder.

The simplest content file


        # Welcome

        This is **plain Markdown**.
    

Why it is portable

No Moth syntax is interpreted. The file is pure Markdown. You can use it with any Markdown tool.

A .md file is plain Markdown content. It uses a separate plain-Markdown renderer and is not a moth template file.

What it is

A .md file is rendered to HTML at compile time and exposed as one generated constant:


    content #String = "<rendered html>"
    

The renderer is CommonMark-compatible with GFM extensions. It is not the Moth md renderer used by moth template files.

What it is not

  • It is not a moth template file. Moth template syntax is not interpreted.
  • It has no captures, directives or declarations.
  • It does not see same-directory module root constants or @html constants.
  • It has no Moth scope at all.

Moth syntax is not interpreted

  • Double-dash is Markdown text, not a Moth comment.
  • Dollar-prefixed text is text, not a template directive.
  • Double-bracket template bodies and single-bracket insertions are text, not template syntax.
  • Template delimiters, insertions and directives are literal text.

Compile-time imported content

The rendered HTML is a compile-time String constant. It folds before the importing file uses it. It is not a runtime value.

Output type

The exported field is content, a compile-time String constant. It is the only generated member.

Target and builder availability

Plain Markdown is available in HTML project builds. The renderer is registered by the HTML builder.

File ownership and relative path

A .md file belongs to the module that contains its directory. It follows the same import path resolution as .moth and .mtf files.

Related concepts

Choose the explanation level: Markdown imports

Markdown imports

Import a .md file the same way as any other source file.

Import and use


    import @docs/intro {content as intro_html}

    [: [intro_html] ]
    

The content constant is the rendered HTML string.

Do not include the extension

import @docs/intro.md is rejected. Use import @docs/intro.

Plain Markdown content is imported with the same extensionless source import syntax as Moth and moth template source assets.

Import syntax


    import @docs/intro

    [: [intro.content] ]
    

A namespace import exposes content as a field. A grouped import brings it directly:


    import @docs/intro {content as intro_html}

    [: [intro_html] ]
    

Aliases

Use as to give the imported content a local name. This is the standard form when multiple content files are imported into the same page.

Insertion into templates and pages

Insert the imported content into a template body. The caller decides where it appears. Imported content does not become a page fragment automatically.

Import path and module visibility

Content imports follow the same path resolution and module visibility rules as normal source imports. @intro resolves from the importing file's owning module root. @docs/intro resolves from the entry root. @./... has no supported meaning. Cross-module imports require the module root's export: block to re-export the content.

No automatic page fragment

Importing a .md file and inserting its content into a template does not create a page fragment. Only direct top-level templates in an entry-selected module root become page fragments.

Direct extension imports are rejected


    import @docs/intro.md {content}
    

This is rejected with MOTH-IMPORT-0024. Use import @docs/intro without the .md extension.

Dependency tracking

Imported content participates in normal dependency tracking. The .md file is compiled before the importing file uses its content constant.

Distinction from asset imports

.md content imports are not asset imports. They produce a compile-time content #String constant, not a tracked asset path. Markdown links and images render literal href and src values. They are not tracked assets and are not rewritten. Use normal Moth asset paths when a file should participate in tracked-asset output.

Related concepts

Choose the explanation level: Rendering contract

Rendering contract

Plain Markdown supports common formatting through a CommonMark-compatible renderer.

Supported forms

  • Headings, paragraphs, emphasis, bold
  • Links, ordered and unordered lists, nested lists
  • Inline code and fenced code blocks
  • Tables, task lists, strikethrough, footnotes
  • Raw HTML is preserved

One clear limitation

Moth template syntax is not interpreted. Dollar-prefixed directives are plain text. Bracket-delimited template bodies are plain text. Use moth template files if you need Moth-aware content.

The plain Markdown renderer uses a CommonMark-compatible parser with GFM extensions. This is a different renderer from Moth's md renderer.

Supported features

  • Headings: #, ##, ### and deeper render as <h1>, <h2>, <h3> etc.
  • Paragraphs: separated by blank lines, rendered as <p>.
  • Emphasis: *italic* renders as <em>, **bold** renders as <strong>.
  • Links: standard Markdown link syntax renders as <a href="...">.
  • Unordered lists: - item renders as <ul><li>.
  • Ordered lists: 1. item renders as <ol><li>.
  • Nested lists: indentation creates nested <ul> or <ol>.
  • Inline code: single backticks render as <code>.
  • Fenced code blocks: triple backticks render as pre and code elements. A language tag adds a class attribute.
  • Tables: pipe table syntax renders as <table> with <thead>, <th>, <tbody> and <td>.
  • Task lists: bracketed checkbox syntax renders as disabled checkboxes.
  • Strikethrough: ~~text~~ renders as <del>.
  • Footnotes: caret-bracketed syntax renders footnote anchors and text.
  • Raw HTML: HTML tags in the source are preserved in the output.

Unsupported extensions

  • Moth template syntax is not interpreted. Dollar-prefixed directives, double-bracket template bodies and single-bracket insertions are literal text.
  • Smart punctuation is disabled. -- remains --, not an em dash.
  • There is no sanitizer or raw-HTML policy key. Raw HTML is preserved as-is.

Ordinary Markdown links versus Moth md links

In plain Markdown, links use ordinary Markdown syntax. The href and src values are rendered literally. They are not rewritten or tracked as assets.

In Moth's md renderer (used by moth template files), at-path link syntax creates Moth-aware links. This syntax is not available in plain Markdown.

Renderer configuration

The renderer uses pulldown-cmark with the following options enabled:

  • ENABLE_TABLES
  • ENABLE_TASKLISTS
  • ENABLE_STRIKETHROUGH
  • ENABLE_FOOTNOTES
  • ENABLE_GFM

Smart punctuation is not enabled. The renderer is registered by the HTML builder.

Related concepts

Choose the explanation level: Choosing a content format

Choosing a content format

Three formats, one choice.

.md for plain Markdown

Use when the content is ordinary Markdown with no Moth syntax needed.

.mtf for Moth-aware Markdown

Use when the content needs compile-time constants, nested templates or builder helpers.

.moth for full Moth

Use when runtime values, control flow, imports or page fragments are needed.

Choose the content format based on what the content needs.

Use .md when

  • The content is ordinary Markdown.
  • No Moth values, captures or templates are needed.
  • Portability matters. The file can be used with any Markdown tool.
  • Fenced code blocks, pipe tables or raw HTML preservation are needed.
  • The content should not see Moth scope.

Use .mtf when

  • The content needs compile-time Moth constants from the same-directory module root.
  • Nested templates or builder helpers such as codeblock are needed.
  • The $md Markdown subset is sufficient for the content's formatting needs.
  • Moth-aware link syntax @path (label) is useful.

Use .moth templates when

  • Runtime values or runtime control flow are needed.
  • Full slot and wrapper composition is needed.
  • The content is part of broader program logic.
  • Imports, declarations or page fragments are needed in the same file.

Distinguishing raw asset files

Raw asset files such as images, stylesheets or JavaScript files are not content imports. They are tracked assets handled by the builder. Use normal Moth asset paths when a file should participate in tracked-asset output.

Distinguishing package source

Core packages and project-local source-backed packages are not content formats. They provide typed declarations and functions. See Package origins and backing.

Related concepts