Lint a file before publishing

Anchorify surfaces authoring warnings ("your slide deck frontmatter isn't going to be detected", "this CSV is semicolon-delimited", "this JSON has a syntax error") on three surfaces:

  1. Share-render owner banner — visible only to you (the share's org admin) inline above the rendered share.
  2. CLI publish — printed to stderr after a successful publish.
  3. Lint API — pre-publish check via POST /api/v1/lint.

All three use the same analyzer, so the warnings are consistent across surfaces.

CLI: anchorify lint <file>

anchorify lint deck.md

Returns one of:

  • Exit 0 with ok — deck.md lints clean as slides_marp when there are no issues.
  • Exit 0 with one or more warn/info lines when the file will preview but is worth tightening up.
  • Exit 1 with one or more error lines when the file will look broken to recipients.

Use --type to lint as a specific content type when the filename doesn't match:

anchorify lint data.txt --type csv

API: POST /api/v1/lint

Auth: per-user bearer token (same as other write endpoints). Request body:

{
  "content": "---\nmarp: true\n---\n# Slide one",
  "filename": "deck.md",
  "content_type": "slides_marp"
}
  • content (required): the file contents as a string.
  • filename (optional): used for filename-extension content-type detection.
  • content_type (optional): override; one of markdown, code, json, yaml, csv, tsv, html, slides_marp, slides_reveal.

Response (200):

{
  "effective_content_type": "slides_marp",
  "warnings": [
    {
      "kind": "slide_deck_no_separators",
      "severity": "warn",
      "message": "This deck has no `---` slide separators after the frontmatter — everything will render as a single slide.",
      "doc_url": "/docs/guide-slides#slide-separators",
      "location": { "line": 4 }
    }
  ]
}

effective_content_type is the type the publish would actually use — handy when the API caller wants to confirm the sniffer's decision.

warnings is always present (an empty array means the file is clean).

Warning kinds

kind severity What it means
empty warn Content is empty / whitespace only.
slide_frontmatter_unrecognized error File contains marp: true / reveal: true but the frontmatter is malformed (e.g. no closing ---, blocked by content before the opener).
slide_deck_no_separators warn Marp/reveal deck with no --- slide separators — renders as a single slide.
unclosed_frontmatter warn File opens with --- but the block never closes; renders as <hr> followed by content.
json_parse_failed error JSON is unparseable (after trailing-comma recovery). Pretty-print won't fire.
csv_likely_wrong_delimiter info File is stored as CSV but the header row looks semicolon/tab-delimited. The renderer auto-detects, but the file isn't portable.
markdown_looks_like_html warn Content begins with <!DOCTYPE> / <html>. Switch to --type html so DOMPurify sanitizes.
code_no_language info Code with no filename → no language detection → no syntax highlighting.
binary_under_text_type error NUL bytes detected in content stored as a text type. Re-upload via the web form.

Severity meanings

  • error — the file will look broken to recipients (raw frontmatter visible, JSON parse failed, etc.). Fix before publishing.
  • warn — the file might look subtly wrong. Renders but worth a look.
  • info — the file renders correctly; this is a portability/best-practice note.

What the lint does NOT check

  • The actual rendered output (we don't run Marp or marked just to verify).
  • Spelling, grammar, broken links inside the content.
  • File size (the upload form enforces that separately).
  • Whether the filename + slug are clean (slug rules are enforced at publish time).

Next steps