mdita-lsp

module
v0.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2026 License: MIT

README

mdita-lsp

An LSP server for MDITA (Markdown DITA) documents, designed as the companion editor tooling for the redhat.mdita.extended DITA-OT plug-in.

Every LSP feature maps directly to a markdown construct that the DITA-OT plug-in converts to DITA XML. The server validates, completes, and navigates MDITA content so that problems are caught at authoring time rather than at build time.

Install

From GitHub Releases

Download the binary for your platform from Releases and place it on your PATH.

From source
go install github.com/aireilly/mdita-lsp/cmd/mdita-lsp@latest

Or clone and build:

git clone https://github.com/aireilly/mdita-lsp.git
cd mdita-lsp
make install   # installs to ~/.local/bin

Ensure the install location is on your PATH:

# For go install:
echo 'export PATH=$PATH:~/go/bin' >> ~/.bashrc
# For make install:
echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc
source ~/.bashrc

Editor setup

VS Code

Use any generic LSP client extension with:

{
  "lsp.server.command": "mdita-lsp",
  "lsp.server.filetypes": ["markdown"]
}
Neovim (nvim-lspconfig)
vim.api.nvim_create_autocmd("FileType", {
  pattern = { "markdown" },
  callback = function()
    vim.lsp.start({
      name = "mdita-lsp",
      cmd = { "mdita-lsp" },
      root_dir = vim.fs.dirname(vim.fs.find({ ".mdita-lsp.yaml", ".git" }, { upward = true })[1]),
    })
  end,
})
Helix

Add to ~/.config/helix/languages.toml:

[[language]]
name = "markdown"
language-servers = ["mdita-lsp"]

[language-server.mdita-lsp]
command = "mdita-lsp"

Configuration

Create .mdita-lsp.yaml in your project root or ~/.config/mdita-lsp/config.yaml for user-wide settings. Project config overrides user config, which overrides built-in defaults.

core:
  markdown:
    file_extensions: [md, markdown, mditamap]
  mdita:
    enable: true
    map_extensions: [mditamap]

completion:
  max_candidates: 50

code_actions:
  create_missing_file:
    enable: true

build:
  dita_ot:
    enable: true
    dita_path: ""          # Path to dita binary (empty = search $PATH)
    output_dir: "out"      # Output directory relative to workspace root

diagnostics:
  mdita_compliance: true
  ditamap_validation: true
  keyref_resolution: true
  link_validation: true
  nbsp_detection: true

Supported markdown features

The LSP supports the same markdown features as the redhat.mdita.extended DITA-OT plug-in. Each feature below corresponds to a DITA conversion the plug-in performs.

YAML front matter

The plug-in uses YAML front matter for topic type detection and prolog metadata. The LSP provides:

  • Completion of all supported YAML keys: $schema, id, author, source, publisher, permissions, audience, category, keyword, resourceid
  • Hover documentation for each key explaining its DITA mapping
  • Diagnostics for missing front matter (code 4) and unrecognized $schema values (code 7)
  • Code action to scaffold MDITA YAML front matter with default schema
---
$schema: urn:oasis:names:tc:dita:xsd:task.xsd
id: install-software
author: Documentation Team
category: Installation
keyword:
  - install
  - setup
---

Supported $schema values:

Schema URN Topic type
urn:oasis:names:tc:dita:xsd:concept.xsd Concept
urn:oasis:names:tc:dita:xsd:reference.xsd Reference
urn:oasis:names:tc:dita:xsd:task.xsd Task
urn:oasis:names:tc:dita:xsd:topic.xsd Generic topic
urn:oasis:names:tc:mdita:rng:topic.rng MDITA topic
Headings and document structure

Headings map to DITA topic titles (H1) and sections (H2). The LSP provides:

  • Document symbols showing a hierarchical heading outline
  • Workspace symbols to search headings across all documents
  • Folding ranges for heading sections and YAML front matter
  • Selection ranges for progressive expansion (line → element → section)
  • Linked editing of heading text
  • Rename with cross-file reference updates via the symbol graph
  • Document highlight for headings and their intra-document references
  • Code lens showing reference counts on headings
  • Diagnostics for invalid heading hierarchy (code 6) and heading-level skips
Task topics

When $schema declares a task, the plug-in maps markdown constructs to DITA task elements. The LSP provides:

  • Diagnostics for task missing procedure (code 8), concept has procedure (code 9), task section order (code 24), and duplicate sections (code 25)
  • Completion of task section headings: Prerequisites, About this task, Verification, Next steps, Troubleshooting
  • Code actions to insert missing task sections
  • Hover on task section headings showing their DITA element mapping
Heading text DITA element
Prerequisites <prereq>
About this task <context>
Verification <result>
Next steps <postreq>
Troubleshooting <tasktroubleshooting>

The plug-in also maps:

  • Ordered lists → <steps> (nested OL → <substeps>)
  • Unordered lists → <steps-unordered> (nested UL → <choices>)
  • Content before the first list → <context>
  • Content after the list → <result>

H2 headings titled "Related information" or "Related links" are converted by the plug-in to <related-links>. The LSP provides:

  • Code action to add a related links section
  • Diagnostics for non-link content inside related links sections (code 26)
  • Hover showing the DITA <related-links> mapping

The plug-in auto-classifies links based on URL pattern. The LSP provides:

  • Completion of file paths inside ]( and heading anchors after #
  • Go to definition for markdown links to other documents and headings
  • Diagnostics for broken links (code 2) and ambiguous links (code 1)
  • Document links making external URLs clickable
  • Inlay hints showing resolved link targets inline
  • File rename support that auto-updates cross-references when files are renamed
Key references

The plug-in processes DITA key references. Keys are derived from MDITA map topicrefs. The LSP provides:

  • Completion of keyref shortcut references ([keyname])
  • Go to definition for keyrefs
  • Hover showing resolved key targets and titles
  • Inlay hints showing keyref resolution inline
  • Diagnostics for unresolved keyrefs (code 16)
Admonitions

Fenced admonitions (!!! type) are converted to DITA <note> elements. The LSP provides:

  • Diagnostics for unknown admonition types (code 15)
  • Semantic tokens for admonition syntax highlighting

Supported types: note, tip, fastpath, restriction, important, remember, attention, caution, notice, danger, warning, trouble. Other qualifiers produce type="other".

Definition lists

Definition lists are converted to DITA <dl>/<dlentry>. The LSP detects definition lists for profile validation:

  • Diagnostics when definition lists appear in MDITA core profile topics (code 12), since they require the extended profile
Fenced code blocks

Fenced code blocks become <codeblock> with the language mapped to @outputclass. Extended metadata syntax ({.class #id key=value}) is supported. The LSP provides:

  • Semantic tokens for attribute metadata highlighting
  • Hover on attribute classes and key-value pairs
Pipe tables

Tables are converted to DITA <simpletable>. The LSP provides:

  • Formatting to align table columns
  • Diagnostics for reference topics missing a table (code 10)
Images

Images are converted to <image> elements, with title-bearing images wrapped in <fig>. Standalone images receive placement="break".

Blockquotes

Blockquotes are converted to DITA <lq> (long quote).

Inline formatting

The plug-in converts bold to <b>, italic to <i>, and code to <codeph> (or <tt> in extended profile). Superscript and subscript are supported in extended profile.

Hard line breaks

Trailing backslash or two trailing spaces produce a <?linebreak?> processing instruction.

Footnotes

Footnotes are supported in the extended MDITA profile. The LSP provides:

  • Diagnostics for footnote references without definitions (code 13) and orphaned definitions (code 14)
  • Code actions to create missing footnote definitions
Inline HTML

Inline HTML tags are transformed to DITA equivalents by the plug-in via XSLT.

Domain element specializations

The LSP supports inline attribute syntax for DITA domain specializations. These map standard markdown formatting to specific DITA elements:

Click **File > Open**{.menucascade} to open the dialog.
Edit `config.yaml`{.filepath} to set options.
See *RFC 7231*{.cite} for details.
  • Completion of domain element classes after {. and {
  • Hover showing the DITA element name, domain, and description
  • Inlay hints showing DITA element mappings inline
  • Diagnostics for unknown outputclass (code 20) and wrong parent element (code 21)
Domain Elements Markdown parent
UI (ui-d) uicontrol, wintitle, menucascade, shortcut bold
Software (sw-d) filepath, cmdname, userinput, systemoutput, varname, msgph `code`
Programming (pr-d) codeph, option, parmname, apiname, kwd `code`
Topic cite italic
Topic draft-comment paragraph
Step elements

Inside task topics, step-level elements can be applied:

Element Description
stepresult Expected result of a step
stepxmp Example for a step
Conditional processing attributes

Block-level attributes for DITA profiling:

{platform="linux" audience="admin"}
  • Completion of attribute names after {
  • Hover documentation for each conditional attribute
  • Diagnostics for unknown conditional attributes (code 23)

Supported: audience, platform, product, otherprops, deliveryTarget, props, rev.

MDITA map format

.mditamap files define document structure using nested markdown lists. The plug-in converts these to DITA map XML.

---
$schema: urn:oasis:names:tc:dita:xsd:map.xsd
---

# Product Documentation

- [Getting Started](getting-started.md)
  - [Installation](install.md)
  - [Configuration](config.md)
- [User Guide](user-guide.md)

The LSP provides:

  • Diagnostics for broken map references (code 17), circular maps (code 18), inconsistent heading hierarchy (code 19), body content in maps (code 11), and reltable column inconsistency (code 29)
  • Code actions to add topics to an existing map
  • Execute command to build XHTML or DITA output via DITA OT
Topic references and sub-maps

Links become <topicref> elements. Links to .ditamap or .mditamap files are emitted as <mapref>.

Ordered lists

Ordered list items produce <topicref collection-type="sequence">.

Topic heads

List items without links become <topichead> with <navtitle>.

Key definitions

Keys are derived from topic filenames (e.g., install.md → key install). Use [install] in topic files to create keyref shortcut references.

Relationship tables

Tables in .mditamap files are parsed as DITA <reltable>:

| [Overview](overview.md) | [Install](install.md) |
|-------------------------|----------------------|
| [Config](config.md)     | [Troubleshoot](ts.md) |

LSP capabilities

Capability Detail
Text sync Incremental (mode 2) with 200ms diagnostic debouncing
Completion Trigger characters: [, #, (, { with resolve support
Definition Markdown links, keyrefs
Hover Links, keyrefs, headings, YAML keys, domain elements, task sections, conditional attributes
References Cross-workspace heading references via symbol graph
Rename Heading rename with prepare support
Code actions Create missing files, add front matter, add to map, add task sections, add related links, fix NBSP/footnotes/heading hierarchy, build DITA OT
Code lens Reference counts on headings
Document links External URL detection
Document symbols Hierarchical heading outline
Workspace symbols Cross-document heading search
Folding ranges Headings, YAML front matter
Selection ranges Progressive expansion (line → element → section)
Linked editing Heading text
Formatting Table alignment, trailing whitespace, heading spacing, trailing newline (full + range)
Inlay hints Link targets, keyref targets, domain element mappings
Document highlight Heading and intra-document reference highlighting
Semantic tokens Full + range encoding with attribute decorator tokens
Pull diagnostics textDocument/diagnostic (LSP 3.17)
File operations didCreate, didDelete, willCreate, willRename
Execute commands createFile, addToMap, ditaOtBuild

Diagnostic codes

Code Name Severity DITA plug-in feature
2 Broken link Error Link processing
3 Non-breaking whitespace Warning Heading/title processing
4 Missing YAML front matter Warning $schema topic type detection
5 Missing short description Warning <shortdesc> generation
6 Invalid heading hierarchy Warning Topic/section nesting
7 Unrecognized schema Warning $schema validation
8 Task missing procedure Warning Task step generation
9 Concept has procedure Info Topic type validation
10 Reference missing table Info <simpletable> generation
11 Map has body content Info Map structure validation
12 Extended feature in core profile Warning Core vs. extended profile
13 Footnote ref without def Warning Footnote processing
14 Footnote def without ref Info Footnote processing
15 Unknown admonition type Warning <note> type mapping
16 Unresolved keyref Warning Key reference resolution
17 Broken map reference Error <topicref> processing
18 Circular map reference Error <mapref> processing
19 Inconsistent map heading hierarchy Info Map nesting validation
20 Unknown outputclass Warning Domain element classes
21 Domain class wrong parent Warning Domain specialization rules
23 Unknown conditional attribute Warning Conditional processing
24 Task section out of order Warning Task section ordering
25 Duplicate task section Error Task section uniqueness
26 Related links non-link content Warning <related-links> generation
27 Menucascade missing separator Warning <menucascade> formatting
28 Step element outside task Warning Task step validation
29 Reltable inconsistent columns Warning <reltable> validation

Development

make build     # Build binary
make test      # Run 210+ tests with race detection
make lint      # Run golangci-lint
make publish   # Cross-compile for 5 platforms (~3.5 MB each)
make clean     # Remove build artifacts

Dependencies: goldmark, yaml.v3 (2 total).

License

See LICENSE.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL