Portable Markdown publication contract
This page defines the portable Markdown publication contract used for LongitudeOne documentation. The goal is to ensure that every published document is predictable, independently consumable, machine-friendly, and semantically similar to its HTML representation.
This contract is intentionally strict. It prevents Docusaurus-specific details from leaking into the published Markdown and it guarantees that Markdown output remains usable outside the Docusaurus rendering environment.
Scope
The portable publication format is GitHub Flavored Markdown (GFM).
Published Markdown must not depend on any of the following:
- MDX;
- JSX;
- React components;
- Docusaurus-specific rendering constructs;
- raw embedded HTML.
If a source element cannot be represented in the portable Markdown contract without losing relevant semantic meaning, the build must fail instead of silently skipping or degrading the content.
Publication identity and path rules
Every published documentation resource must have two explicit representations:
- an HTML representation using the
.htmlextension; - a Markdown representation using the
.mdextension.
The publication contract does not use directory-style document identities or
implicit index.html resolution.
HTML and Markdown counterparts are published in the same directory and differ
only by their representation extension. An internal staging or generation
directory must not introduce a public markdown/ prefix. For example,
/shared/index.html is paired with /shared/index.md, not
/markdown/shared/index.md. This rule also applies to llms.txt, resource
mappings, download links and deployed files, including development base URLs.
For example:
Source:
docs/spatial-core/geometry/point.md
HTML:
/spatial-core/geometry/point.html
Markdown:
/spatial-core/geometry/point.md
The following representation is not valid:
/spatial-core/geometry/point/
The explicit representation is:
/spatial-core/geometry/point.html
Path components used for published documentation must follow strict portable naming rules:
- lowercase characters only;
- no spaces;
- no problematic or reserved path characters;
- suitability for case-sensitive filesystems and URLs.
This rule applies to both the source hierarchy and the generated HTML/Markdown representations. For example, the following names are valid:
docs/spatial-core/geometry/point.md
The following are invalid:
docs/Spatial-Core/geometry/point.md
docs/spatial-core/Geometry/Point.md
docs/spatial-core/geometry/point example.md
Documentation paths are treated as case-sensitive on every supported platform.
The file names point.md and Point.md must never be considered equivalent,
including on case-insensitive local filesystems.
Production resource negotiation
In production, the extensionless URI (for example, /shared/index) identifies
an abstract documentation resource. Apache internally selects the existing
.html or .md representation from the HTTP Accept header, without a redirect.
This virtual endpoint is not a third representation or a source-document link target.
Explicit .html and .md URLs always select their representation, regardless
of Accept. Existing source and generated link rules continue to require explicit
representation extensions, including the representation switching links.
Negotiation respects media ranges and quality values. HTML wins equal preferences
and is the default for absent Accept or */*. A quality of zero rejects that
representation; a request accepting neither representation receives HTTP 406.
Negotiated responses expose Vary: Accept and the selected text/html or
text/markdown content type. Both representation files must exist.
The production corpus includes the version-controlled, deterministically generated
.htaccess infrastructure. Apache MultiViews is disabled; only the paired HTML
and Markdown files are eligible. Physical files and directories bypass negotiation.
GitHub Pages and the local static preview do not implement this server behavior.
Localized document identities
A language suffix is part of the resource name. For example, legal-notice.fr.md
maps to legal-notice.fr.html; legal-notice.en.md maps to legal-notice.en.html.
The negotiated production resource endpoints are legal-notice.fr and legal-notice.en.
The .fr.md suffix identifies French HTML content; unsuffixed and .en.md sources
use English. Language switches remain ordinary relative .md links in source and
portable Markdown, and become explicit .html links in the HTML representation.
Required metadata
Every published Markdown document must contain YAML front matter. The metadata must include at least the following fields:
---
title: Point
description: Represents a zero-dimensional geometry.
---
The title and description values are mandatory. Docusaurus-specific
metadata must not appear in the publication output unless it has independent
semantic value for the published document.
Examples of metadata that must not be propagated solely because Docusaurus uses
them include sidebar ordering and rendering configuration.
The source slug field is not supported: publication paths are derived from the
source hierarchy. The generated front matter contains only title,
description, canonical_html, and canonical_markdown.
Deterministic generation
The Markdown representation is generated from the source document using a Markdown syntax tree, not by rewriting source text with regular expressions. Generation must be deterministic and idempotent: identical source documents must produce byte-identical output, and rerunning generation without source changes must not modify the published corpus.
Generated Markdown must use UTF-8 without a byte-order mark and LF line endings.
HTML comments in source are removed; other raw HTML and content that cannot be
represented without semantic loss must cause generation to fail.
index.md documents retain an explicit index.html representation.
Generated files are staged and promoted as one publication operation so a
failed generation does not replace the last valid corpus.
Representation URLs
The publication process must generate two canonical representation URLs for each document:
- the canonical HTML URL;
- the canonical Markdown URL.
These values are derived automatically from the source document path and must not require manual duplication in each source file.
The HTML representation URL must always use the .html extension.
The Markdown representation URL must always use the .md extension.
For example:
---
title: Point
description: Represents a zero-dimensional geometry.
canonical_html: ./point.html
canonical_markdown: ./point.md
---
An index.md source must map to:
canonical_html: ./index.html
canonical_markdown: ./index.md
The exact metadata field names and serialization may vary across implementations, but the publication contract must clearly distinguish both representations.
Document titles and headings
The document title is defined by the mandatory title metadata. The
publication generator must not insert an additional level-one Markdown heading
solely to repeat this title.
Therefore, this is not required:
# Point
when the document already declares the title in YAML front matter.
The first content heading may therefore begin at level two.
HTML link in generated Markdown
Every published Markdown document must provide an explicit link to its HTML representation immediately after the document metadata and therefore directly below the title when a consumer renders the metadata.
For example:
[View HTML version](./point.html)
This link must:
- use a relative path;
- explicitly include the
.htmlextension; - point directly to the matching HTML representation.
Directory-style URLs such as the following are not valid:
[View HTML version](./point/)
Internal documentation links
Links between documents in the same published documentation corpus must remain inside the Markdown representation.
For example:
[LineString](./linestring.md)
must be used instead of:
[LineString](./linestring.html)
[LineString](./linestring/)
[LineString](https://example.org/docs/linestring.html)
Internal documentation links must:
- use relative paths;
- explicitly include the
.mdextension; - target the published Markdown representation;
- preserve document fragments when present;
- respect the exact lowercase path of the target document.
Absolute URLs are forbidden for links whose destination belongs to the same published documentation corpus.
Validation resolves AST link nodes against the published source hierarchy under
docs/, before canonical serialization or replacement of the published corpus.
Directory targets and extensionless links are source errors; the generator never
adds .md, infers index.md, repairs casing or falls back to HTML. Documentation
targets cannot escape docs/ or use symbolic links. A target must be an included,
real source document; drafts, unlisted and hidden pages cannot be linked as
published documentation.
Inline and reference-style links follow the same rules. Their paths are
canonicalized relative to the source document; external URLs, query strings,
fragments, code and literal text retain their meaning. Shared asset references
are distinguished from documentation links and are not rewritten by this step.
An outside relative resource requires an existing shared static publication
resource; arbitrary files outside docs/ are not documentation targets.
Errors identify the source path, original and resolved target, reason, and line and column when available. Invalid links fail generation before publication, leaving the previous generated corpus intact.
The explicit View HTML version link remains the intentional exception that
allows navigation from Markdown to the corresponding HTML representation.
Every published Markdown page must be reachable from index.md by following
these internal Markdown links. The resource verifier checks this coverage after
generation; listing a page only in llms.txt or an HTML sidebar is insufficient
for a reader browsing the Markdown corpus.
Heading anchors
Links to document sections may use GFM-compatible generated heading anchors.
For example:
[Coordinate dimension](./point.md#coordinate-dimension)
Generated anchor values must be predictable according to the chosen GFM rules. Internal fragment links must be validated during the documentation build. A link targeting a nonexistent generated anchor must fail validation.
Same-document links remain fragment-only links. Cross-document fragments must resolve against the target's GFM headings. Heading-anchor collisions are errors, including headings with different formatting that produce the same anchor. Authors must use distinct headings rather than relying on automatically generated numeric suffixes to distinguish repeated headings.
Shared assets
Resources shared between HTML and Markdown representations must not be duplicated. Published Markdown should reference shared assets using paths relative to the current Markdown document.
For example:

Root-relative references such as the following are not allowed in the portable Markdown representation when a relative reference can be generated:

This rule applies to all shared resources, including:
- images;
- diagrams;
- schemas;
- downloadable files;
- example data files;
- externally stored code samples;
- other static documentation assets.
The resulting Markdown corpus remains navigable when moved together with its shared asset hierarchy.
The shared assets publication contract defines the dedicated source hierarchy, allowed formats, safety validation, manifest and atomic publication requirements.
Raw HTML and unsupported content
Raw HTML must not be part of the portable Markdown publication format. Content requiring HTML must be rewritten using supported Markdown constructs.
The generator must not silently preserve unsupported HTML as a fallback. If equivalent semantic content cannot be produced using the supported Markdown profile, the build must fail.
This includes any case where a source construct:
- has no supported portable Markdown representation;
- would lose relevant semantic information during conversion;
- cannot be converted deterministically.
Warnings alone are insufficient when a semantic conversion failure occurs.
Admonitions
Admonitions must be represented using portable Markdown constructs rather than Docusaurus-specific directives. A simple blockquote representation is used.
For example:
> **Warning**
>
> This geometry representation is not supported.
A standardized set of labels such as Note, Warning, Important, and Tip
may be used when it improves clarity. The representation must remain legible in a
generic Markdown renderer that provides no special admonition support.
Tables
GFM tables are part of the publication format.
| Dimension | Coordinates |
|-----------|-------------|
| XY | X, Y |
| XYZ | X, Y, Z |
Tables must remain valid GFM and must not depend on HTML table markup. Columns must be aligned. If a construct cannot reasonably be represented as a GFM table, it must be expressed using another portable Markdown structure.
Code blocks
Fenced code blocks must declare a language identifier whenever the content language or format is known.
For example:
```php
$geometry = new Point(...);
```
A known language must not be emitted as an untyped fenced block. Domain-specific identifiers may be used when they add useful semantics, including:
php;json;sql;wkt;ewkt;geojson;- other clearly identified formats used by LongitudeOne documentation.
Build-only comments and directives
Comments, annotations, and directives used exclusively by the documentation build process must be removed from the published Markdown representation. They must not be exposed merely because they appear in the source file.
Information intended for documentation consumers must instead be represented as document content or publication metadata.
Table of contents
The publication generator must not inject a table of contents into individual Markdown documents. Document headings remain available to consumers who wish to derive their own navigation.
This avoids duplicating structure that is already expressed by the document's headings.