Markdown Documents skill for Codex

Markdown that renders right everywhere it lands. Codex writes Markdown for the renderer it will actually meet: it reads the repo's lint and format config first, uses GFM syntax where GitHub renders it and the docs generator's own syntax elsewhere, fixes the list-indentation and table-pipe traps, keeps diagrams as Mermaid source, and finishes with markdownlint-cli2, Prettier and an offline lychee pass over links and anchors.

  • Documents & Office
  • $markdown-documents
  • 176 lines
  • 2 files
  • ~2,000 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- markdown-documents

Installs to ~/.agents/skills/markdown-documents/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $markdown-documents, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Writes and maintains Markdown documents that render correctly across GitHub, GitLab, docs sites and editors, using CommonMark and GFM rules for headings, lists, tables, code fences, footnotes, alerts, math and Mermaid diagrams, enforced with markdownlint-cli2, Prettier and lychee link checks. Use when asked to write or clean up README, docs or design-doc Markdown, fix tables or lists that render wrong, add diagrams, set up Markdown linting in CI, or find broken links and anchors.

Use it when

  • Writing or restructuring README, design docs or docs-site pages in Markdown
  • Lists, tables, alerts or code blocks render incorrectly
  • Setting up Markdown linting, formatting or link checking
  • Adding diagrams, math or footnotes to repository docs

Use something else when

  • The task is choosing what a README should say: use readme-writing
  • You are building or versioning a whole docs site: use docs-as-code

How to check the result

markdownlint-cli2 and prettier --check pass with the repo config, lychee --offline reports no broken local links or anchors, and the page is previewed in its target renderer.

The mistake it prevents

Using GitHub-only syntax such as [!NOTE] alerts in a docs site that renders them as literal text, or indenting nested list items to the wrong column.

~/.agents/skills/markdown-documents/SKILL.md

--- name: markdown-documents description: Writes and maintains Markdown documents that render correctly across GitHub, GitLab, docs sites and editors, using CommonMark and GFM rules for… license: MIT ---

Done well means the file renders the same in every target the repo uses, passes the repo’s lint config with no inline disables added to hide problems, every link and anchor resolves, and the structure (one title, ordered headings, short sections) lets a reader scan it.

Before writing

  • Read AGENTS.md, CONTRIBUTING.md and any existing .markdownlint*, .prettierrc*, .editorconfig or .vale.ini. Follow what is there; do not introduce a second style.
  • Identify the renderer(s): GitHub/GitLab web, a docs generator (Docusaurus, MkDocs, Starlight, VitePress), an IDE preview, Pandoc. Features differ; GFM-only syntax may render as literal text elsewhere.
  • Check whether the file is generated (header comment, build script). Edit the source, not the output.

Syntax decisions

NeedUseAvoid
TitleOne # heading at the top (unless front matter title replaces it)Several # headings
Sections##, ### in order, no skipped levelsBold text as fake headings
Emphasis**strong**, _emphasis_ consistentlyMixing * and _ styles in one repo
CodeFenced blocks with a language tag (```bash)Indented code blocks, untagged fences
Commands the reader copiesOne command per line, no $ prompt prefix unless output is shownPrompts that break copy-paste
Callouts on GitHub> [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING], > [!CAUTION]Emoji-prefixed blockquotes
Callouts in a docs siteThat generator’s admonition syntax (:::note, !!! note)GitHub alert syntax, which other renderers show literally
Diagrams```mermaid fenced block (GitHub, GitLab, most docs sites)Screenshots of diagrams with no source
Math$inline$ and $$block$$ or ```math on GitHubImages of equations
Footnotestext[^1] and [^1]: note (GFM)Manual superscripts
Collapsible detail<details><summary>Title</summary> with a blank line before the Markdown bodyHuge always-open logs
Line break inside a paragraphEnd the line with \Two trailing spaces (invisible, stripped by editors)

Lists

  • A nested item must be indented to the content start of its parent: 2 spaces under - item, 3 under 1. item, 4 under 10. item. Inconsistent indentation is the top cause of broken nesting.
  • Put a blank line before a list that follows a paragraph; some renderers merge it otherwise.
  • Code blocks or paragraphs inside a list item are indented to the item’s content column.
  • Ordered lists: write 1. for every item if the repo lints with one style, or number sequentially if it uses ordered; check MD029’s config.

Tables

  • GFM only. Header row, delimiter row, then body; alignment with :--, :-:, --:.
  • Escape literal pipes as \|, including inside inline code in a cell.
  • No multi-line cells; use <br> sparingly, or turn the table into headings with lists when cells need paragraphs.
  • More than about 5 columns or long prose cells: the table will scroll on GitHub and mobile. Restructure.
  • Prettier aligns table columns; let it, rather than hand-aligning.
| Option | Default | Description |
|---|---|---|
| `--retries` | `3` | Attempts before giving up; `0` disables retry |
| `--format` | `text` | One of `text` \| `json` |
  • Relative links between repo files (../guides/setup.md#install) so they work on forks and branches; absolute URLs only for external resources.
  • GitHub anchor slugs: lowercase, spaces to hyphens, most punctuation removed; duplicate headings get -1, -2. Renaming a heading breaks inbound anchors; search for them.
  • Link text says where it goes (“installation guide”), never “here”.
  • Reference-style links ([guide][setup] with [setup]: ./setup.md) keep long tables and paragraphs readable.
  • Images: ![meaningful alt text](./img/flow.png); empty alt only for decorative images.

Mermaid

flowchart LR
  A[Upload] --> B{Valid?}
  B -- yes --> C[Queue job]
  B -- no --> D[Return 422]

Keep diagrams under about 15 nodes; split bigger ones. Quote labels that contain parentheses or special characters: A["Parse (strict)"]. Validate syntax by rendering with mermaid-cli when available: npx -p @mermaid-js/mermaid-cli mmdc -i flow.mmd -o flow.svg (downloads a headless browser; needs network). GitHub’s renderer may lag the latest Mermaid syntax; avoid brand-new diagram types for repo docs.

Front matter

Docs generators read YAML front matter (--- block at line 1). Quote values containing : or starting with special characters, keep keys the generator expects (title, description, sidebar_position), and do not add front matter to files GitHub renders directly unless the repo already does (GitHub shows it as a table).

Tooling

markdownlint-cli2 (configuration in .markdownlint-cli2.jsonc):

{
  "config": {
    "default": true,
    "MD013": false,                       // line length: off for prose; Prettier handles wrapping
    "MD024": { "siblings_only": true },   // duplicate headings allowed in different sections
    "MD033": { "allowed_elements": ["details", "summary", "br", "kbd", "sup"] }
  },
  "globs": ["**/*.md"],
  "ignores": ["node_modules/**", "CHANGELOG.md", "vendor/**"]
}
npx markdownlint-cli2                    # uses globs from the config
npx markdownlint-cli2 --fix "docs/**/*.md"
npx prettier --check "**/*.md"           # --prose-wrap preserve|always|never from .prettierrc
lychee --offline --include-fragments "**/*.md"   # local files and #anchors only, no network
lychee "**/*.md"                          # also external URLs; needs network

npx downloads packages on first use; in an offline sandbox, use the versions in the repo’s devDependencies or ask before installing. If the repo already uses markdownlint (the Node library through a different runner) or remark-lint, keep it.

CI step example (GitHub Actions) when the user asks for it:

- uses: DavidAnson/markdownlint-cli2-action@v20
  with:
    globs: "**/*.md"

Check the action’s current major version in its README before pinning.

Workflow for a document change

- [ ] 1. Read conventions and renderer targets
- [ ] 2. Outline with headings before writing paragraphs
- [ ] 3. Write; keep sections short, put commands in fenced blocks
- [ ] 4. Run lint, format check and offline link check
- [ ] 5. Preview the rendered output in the target renderer
- [ ] 6. Report what changed and anything not verified

For step 5, at minimum render with the repo’s docs tool (npm run docs:build or similar, from package.json) or view on GitHub after pushing a branch. When neither is available, say that rendering was not checked.

Gotchas

  • A line starting with a number and period (2026. was a good year) becomes a list item; escape it as 2026\..
  • < in prose (a < b, List<String>) can be eaten as HTML; use inline code.
  • Underscores inside words are safe in GFM but not in some older renderers; use code spans for identifiers like snake_case_name.
  • Headings need a space after # (#Title is a paragraph in CommonMark).
  • Tabs in indentation behave like 4 spaces for list nesting; mixed tabs break lists.
  • Copy-pasted smart quotes and non-breaking spaces inside code blocks break commands.
  • HTML blocks end at the first blank line; Markdown inside <details> needs a blank line after <summary>.

Output

## Docs change: docs/deploy.md
- Restructured into Prerequisites / Deploy / Rollback / Troubleshooting (H2s), 1 H1
- Converted 2 screenshot diagrams to Mermaid; tables reduced from 7 to 4 columns
- Checks: markdownlint-cli2 clean, prettier --check clean, lychee --offline 0 broken
- Not verified: external links (sandbox offline), GitHub rendering of the new alert block

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Markdown Documents"
  short_description: "Markdown that renders right everywhere it lands"
  default_prompt: "$markdown-documents Clean up docs/ so markdownlint passes without disabling rules everywhere"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc
Just launched

Codex Skills Pro is live

79 premium skills for Codex, each with scripts, references and an evidence report that proves the result.

Bought one by one$882.21
All 79 skills$49
94% off

That's $0.62 a skill, paid once.

Get all 79 for $49Or pick single skills from $4.99 →

Secure checkout by Creem