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:
- Share-render owner banner — visible only to you (the share's org admin) inline above the rendered share.
- CLI publish — printed to stderr after a successful publish.
- 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_marpwhen there are no issues. - Exit 0 with one or more
warn/infolines when the file will preview but is worth tightening up. - Exit 1 with one or more
errorlines 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 ofmarkdown,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
- Slide decks — fix the most common slide-deck warning.
- Content types and rendering — what each renderer expects.
- Command-line — the rest of the CLI surface.