Markdown Syntax Guide
Complete guide for writing Comark (Components in Markdown) documents.
Table of Contents
Standard Markdown
Comark supports all standard CommonMark and GitHub Flavored Markdown (GFM) features:
Headings
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6Note: All headings automatically get ID attributes generated from their content for linking (e.g., # Hello World becomes <h1 id="hello-world">). Set headingIds: false in parse options to disable auto-generated ids.
Text Formatting
**Bold text**
*Italic text*
***Bold and italic***
~~Strikethrough~~
`Inline code`Lists
<!-- Unordered lists -->
- Item 1
- Item 2
- Nested item
- Another nested item
<!-- Ordered lists -->
1. First item
2. Second item
1. Nested item
2. Another nested itemLinks and Images
[Link text](https://example.com)
[Link with title](https://example.com "Link title")
Blockquotes
> This is a blockquote
> It can span multiple lines
>
> And contain other markdown elementsHorizontal Rules
---
***
___Line Breaks
Line with two trailing spaces
Creates a hard line breakFrontmatter
Comark supports YAML frontmatter at the beginning of documents:
---
title: My Document Title
author: John Doe
date: 2024-01-15
tags:
- markdown
- documentation
custom_field: custom value
---
# Document Content
Your markdown content here...Features
- Must be at the very beginning of the document
- Enclosed by
---delimiters - Parsed as YAML
- Available in the
frontmatterproperty of MarkdownDocument
Common Fields
- title: Often used for page titles or TOC labels
Note: depth and searchDepth are not automatically processed from frontmatter. They must be explicitly passed to the toc plugin options.
Example
import { parseMarkdown } from 'comark'
const content = `---
title: My Article
depth: 3
---
# Introduction
Content here...
`
const result = await parseMarkdown(content)
console.log(result.frontmatter)
// { title: 'My Article', depth: 3 }Comark Components
Comark (Components in Markdown) extends standard markdown with custom component syntax.
Block Components
Block components use the ::component-name syntax:
::component-name{prop1="value1" prop2="value2"}
Content inside the component
Can have **markdown** and other elements
::Examples
<!-- Alert component -->
::alert{type="info"}
This is an important message!
::
<!-- Card component -->
::card{title="My Card"}
Card content with **markdown** support
::
<!-- Empty component -->
::divider
::Inline Components
Inline components use the :component-name syntax:
<!-- Standalone inline component -->
:icon-check
<!-- Inline component with content -->
:badge[New]{color="blue"}
<!-- Inline component with properties -->
:tooltip{text="Hover text"}Examples
Check out this :icon-star component in the middle of text.
Click the :button[Submit]{type="primary"} to continue.
The status is :badge[Active]{color="green"} right now.Component Properties
Components support various property syntaxes:
::component{prop="value"}
<!-- Standard key-value pair -->
::
::component{bool}
<!-- Boolean property (becomes :bool="true" in AST) -->
::
::component{#custom-id}
<!-- ID attribute -->
::
::component{.class-name}
<!-- CSS class -->
::
::component{obj='{"key": "value"}'}
<!-- Object/JSON value -->
::
::component{arr='["item1", "item2"]'}
<!-- Array/JSON value -->
::
::component{multiple="props" bool #id .class}
<!-- Multiple properties combined -->
::Component Slots
Block components support named slots using the #slot-name syntax:
::card
#header
## Card Title
#content
This is the main content of the card
#footer
Footer text here
#default
Default slot
::AST Output
{
"nodes": [
[
"card",
{},
[
"template",
{ "name": "header" },
["h2", {}, "Card Title"]
],
[
"template",
{ "name": "content" },
["p", {}, "This is the main content of the card"]
],
[
"template",
{ "name": "footer" },
["p", {}, "Footer text here"]
],
[
"template",
{ "name": "default" },
["p", {}, "Default slot"]
]
]
],
"frontmatter": {},
"meta": {}
}Default Slot
Content inside a component without a slot marker is the default slot. These two forms are equivalent in rendering but produce different ASTs:
::component
hello
::::component
#default
hello
::Without #default: content becomes direct children (auto-unwrapped):
["component", {}, "hello"]With #default: content is wrapped in an explicit template node:
["component", {}, ["template", { "name": "default" }, "hello"]]Both serialize back to the same Markdown (without #default). The Vue, React, Svelte, and Angular renderers treat both forms identically: direct children and template[name="default"] children both become the default slot. Use #default explicitly when mixing named and default slots in the same component.
Nested Components
Components can be nested within each other:
::outer-component
Content in outer
:::inner-component{variant="compact"}
Content in inner
:::
More content in outer
::Attributes
Comark allows adding custom attributes to native markdown elements using {...} syntax after the element.
Strong/Bold Attributes
**bold text**{.highlight #important}
**bold text**{data-value="custom"}
**bold text**{bool}Italic/Emphasis Attributes
*italic text*{.emphasized}
_italic text_{#custom-id}Link Attributes
[Link text](url){target="_blank" rel="noopener"}
[Link text](url){.button .primary}
[External](https://example.com){target="_blank" .external-link}Image Attributes
{.responsive width="800" height="600"}
{.logo #site-logo}Inline Code Attributes
`code snippet`{.language-js}
`variable`{data-type="string"}Span Attributes
This is [highlighted text]{.highlight .yellow} in a paragraph.Attribute Types
- Boolean:
{bool}→:bool="true" - ID:
{#my-id}→id="my-id" - Class:
{.my-class}→class="my-class" - Key-Value:
{key="value"}→key="value" - JSON Objects:
{data='{"key": "val"}'}→data={"key": "val"}
Code Blocks
Comark provides advanced code block features with metadata support.
Basic Code Block
```javascript
function hello() {
console.log("Hello, World!")
}
```Language with Syntax Highlighting
```typescript
interface User {
name: string
age: number
}
```Filename Metadata
```javascript [server.js]
const express = require('express')
const app = express()
```Note: Filename is enclosed in [...] brackets.
Line Highlighting
```javascript {1-3,5}
function example() {
const a = 1 // Lines 1-3 highlighted
const b = 2
const c = 3
return a + b + c // Line 5 highlighted
}
```Highlighting Syntax
- Single line:
{3} - Range:
{1-5} - Multiple:
{1,3,5} - Combined:
{1-3,7,10-12}
Combined Metadata
```javascript {1-3} [utils.ts] meta=value
function hello() {
console.log("Hello")
}
```Metadata Order: Any order is supported:
language {highlights} [filename] metalanguage [filename] {highlights} meta- etc.
Special Characters in Filename
```typescript [@[...slug\].ts]
// Brackets and special chars are supported
// Backslash escapes special characters
```No Language Specified
```
Plain text code block
No syntax highlighting
```AST Structure
{
"nodes": [
[
"pre",
{
"language": "javascript",
"filename": "server.js",
"highlights": [1, 2, 3],
"meta": "meta=value"
},
[
"code",
{ "class": "language-javascript" },
"code content here"
]
]
],
"frontmatter": {},
"meta": {}
}Task Lists
Comark supports GitHub Flavored Markdown task lists:
- [x] Completed task
- [ ] Pending task
- [x] Another completed task
- [ ] Nested pending task
- [x] Nested completed taskFeatures
[x]or[X]for completed tasks[ ]for pending tasks- Works in both ordered and unordered lists
- Supports nesting
HTML Output
<ul class="contains-task-list">
<li class="task-list-item">
<input type="checkbox" disabled checked class="task-list-item-checkbox">
Completed task
</li>
<li class="task-list-item">
<input type="checkbox" disabled class="task-list-item-checkbox">
Pending task
</li>
</ul>Tables
Comark supports GitHub Flavored Markdown tables:
| Header 1 | Header 2 | Header 3 |
| -------- | -------- | -------- |
| Cell 1 | Cell 2 | Cell 3 |
| Cell 4 | Cell 5 | Cell 6 |Aligned Tables
| Left Aligned | Center Aligned | Right Aligned |
| :----------- | :------------: | ------------: |
| Left | Center | Right |
| Text | Text | Text |Alignment Syntax
- Left:
:--- - Center:
:---: - Right:
---:
Inline Markdown in Tables
| Feature | Status | Link |
| ------------ | --------------- | ----------------------- |
| **Bold** | *Italic* | [Link](https://example) |
| `Code` | ~~Strike~~ |  |Varying Column Widths
| Short | Medium Column | Very Long Column Name Here |
| ----- | ------------- | -------------------------- |
| A | B | C |Note: Column width is determined by the longest content in each column.