Comark Documentation

repository·main·Indexed 21 days ago

https://github.com/comarkdown/comark

A documentation engine for rendering Markdown with rich styling. Comark provides core parsing utilities like parseMarkdown() and autoCloseMarkdown(), and offers dedicated Markdown components for Vue, React, Svelte, and Angular. It includes specialized packages such as @comark/ansi for terminal-based applications, @comark/html for HTML string rendering, and integrations for Astro, Next.js, Nuxt, SvelteKit, and VitePress.

Tokens
194.5K
Snippets
836
Records
955
Agent score
71%

What's inside Comark

  1. Comark syntax overview

    main

    Comark supports standard Markdown features alongside its extended component syntax:

    • Inline formatting: **bold**, *italic*, `code`, and [links](url).
    • Lists: Unordered (-) and ordered (1.) lists with full Markdown support inside items.
    • Code blocks: Standard fenced code blocks with out-of-the-box syntax highlighting (e.g., ```js).
    • Block quotes: Standard > quote syntax.
    • Components: The ::name{attr="val"} syntax for embedding interactive or styled elements.
  2. Compare Comark vs react-markdown

    main

    Comark is designed for advanced use cases that react-markdown does not support, specifically:

    • Component Syntax: Authors can write custom components directly in Markdown using ::component{prop="value"} syntax without using raw HTML or JSX.
    • Streaming Support: Comark handles incomplete Markdown during token-by-token streaming (e.g., LLM responses) by using an auto-close mechanism that prevents broken formatting.
    • Decoupled Parsing: Unlike react-markdown which parses inside the component on the client, Comark allows you to parse Markdown into a serializable AST on the server and render that AST on the client.
    • Multi-Framework: Comark provides renderers for Vue, React, Svelte, Angular, Nuxt, HTML, and ANSI, whereas react-markdown is React-only.
    • Built-in Features: Includes frontmatter parsing and GitHub Flavored Markdown (tables, task lists, etc.) out of the box.
  3. Core Features of Comark

    main

    Comark is a high-performance Markdown engine designed for modern web applications with the following capabilities:

    • One Parser, Every Renderer: The same source renders to Vue, React, Svelte, Angular, Nuxt, HTML, and ANSI.
    • Real-time Streaming: Built-in support for parsing content as it arrives (e.g., for AI chat interfaces) with Auto-close functionality that renders incomplete syntax correctly at every frame.
    • Component Syntax: Natively handles components and attributes within Markdown.
    • Extensible Plugin Ecosystem: Supports Comark-specific plugins and is compatible with markdown-it plugins.
    • Serializable Document Model: Parses to a MarkdownDocument that is easy to traverse, cache, serialize, and send over the wire.
  4. Compare Comark and Markdoc

    main

    Comark and Markdoc both treat Markdown as data with runtime parsing, avoiding the MDX model of compiling content into code. Both tools parse content into a serializable tree and resolve components at render time from a registry.

    Key Differences

    FeatureComarkMarkdoc
    Component Syntax::callout{type="note"}{% callout type="note" %}
    StreamingSupports auto-closing unterminated syntax for AI outputNot supported
    AST ShapeCompact, array-based: ['tag', props, ...children]Object-based: { type, tag, attributes, ... }
    Official RenderersVue, React, Svelte, Angular, Nuxt, HTML, ANSIReact, HTML
    Schema ValidationNo built-in schema; components validate own propsFirst-class schemas per tag
    Variables/FunctionsHandled via binding plugin and application logicBuilt-in $variables and functions
    PartialsHandled in application codeBuilt-in {% partial %}
    Plugin EcosystemComark + markdown-it pluginsCustom nodes/tags configuration
  5. Features of the JSON Render plugin

    main

    The JSON Render plugin provides several capabilities for composing UI via Markdown:

    • Full Spec Format: Define a complete tree of named elements starting from a root entry point.
    • Single Element Shorthand: Use a simplified format when defining single elements.
    • Nested Layout: Compose deep component trees by referencing children by their keys.
    • YAML Support: Allows writing specifications in YAML for improved readability.
    • Styling: When used in the provided example, it is styled with Nuxt UI, supporting dark mode.
  6. Comark vs Streamdown: Comparison

    main

    Comark and Streamdown both solve the problem of rendering incomplete Markdown during AI streaming (handling unterminated bold, code fences, etc.), but they differ in scope and flexibility.

    Key Differences

    FeatureComarkStreamdown
    StreamingAuto-closes incomplete syntax at every frameHandles unterminated blocks
    Custom ComponentsSupports ::component{attr="val"} syntax in contentElement remapping only
    FrameworksVue, React, Svelte, Angular, Nuxt, HTML, ANSIReact only
    ArchitectureDecoupled parser (AST) and renderersCoupled rendering component
    ExtensibilityPlugin-based (Shiki, KaTeX, Mermaid, etc.)Built-in (Zero-config)
    AI SDKWorks with useChat in any frameworkDesigned for @ai-sdk/react

    When to choose Comark

    • You need custom component syntax (e.g., ::alert) within the LLM output.
    • You want to use the same content across multiple frameworks (Vue, Svelte, etc.) or environments (HTML, Terminal/ANSI).
    • You want a decoupled architecture where you can parse Markdown on the server and stream the AST.
    • You want a lightweight core and only opt-in to features like Shiki or KaTeX via plugins.
  7. What is Comark?

    main

    Comark (Components in Markdown) is an extension of Markdown that allows you to embed custom components directly within your content using a specific syntax.

    Component Syntax

    Components are defined using :: delimiters. They can accept properties (attributes) and children (slots).

    Example of a block component with properties and children:

    ::alert{type="warning"}
    This is an important message!
    ::

    Core Workflow

    Comark operates in three distinct stages:

    1. Parse: Markdown is parsed into a compact, serializable MarkdownDocument.
    2. Transform: The resulting document can be inspected, transformed, cached, or serialized.
    3. Render: Framework-specific renderers convert the document into various outputs including Vue, React, Svelte, Angular, HTML, ANSI, or plain Markdown.

    Key Capabilities

    • Streaming Support: Real-time incremental parsing designed for AI chat interfaces.
    • Framework Agnostic: Dedicated renderers for Vue, React, Svelte, Angular, and Nuxt, as well as HTML and ANSI.
    • Extensible: Built on markdown-exit (a TypeScript rewrite of markdown-it), meaning existing markdown-it plugins are compatible.
    • Rich Syntax: Full GitHub Flavored Markdown (GFM) support and built-in Shiki integration for syntax highlighting.
    # Welcome to my blog
    
    This is regular **markdown** with a custom component:
    
    ::alert{type="warning"}
    This is an important message!
    ::
  8. Overview of Comark Core APIs

    main

    Comark provides two primary utility APIs for handling markdown content:

    1. parseMarkdown(): Used for parsing markdown strings into a structured format.
    2. autoCloseMarkdown(): Used to handle incomplete or unclosed syntax, which is particularly useful for streaming content integration.
  9. Represent nested unordered lists in Comark AST

    main

    When parsing nested unordered lists, Comark generates an Abstract Syntax Tree (AST) where nested lists are represented as child nodes within a list item (li) node. A list item containing a nested list will typically contain a paragraph (p) node for its text content followed by the nested ul node.

    {
      "frontmatter": {},
      "meta": {},
      "nodes": [
        [
          "ul",
          {},
          [
            "li",
            {},
            "First item"
          ],
          [
            "li",
            {},
            [
              "p",
              {},
              "Third item"
            ],
            [
              "ul",
              {},
              [
                "li",
                {},
                "Indented item"
              ]
            ]
          ]
        ]
      ]
    }