Write Markdown.
Publish Beautiful Articles.
A Markdown editor with a design-token-driven theme system. Every element — headings, code blocks, diagrams, formulas — shares one visual language. Switch themes, everything updates instantly.
One-time purchase · No subscriptions · Lifetime updates
One theme system. Every element.
No more mismatched code blocks and diagrams. Every Markdown element derives its style from the same token set.
Design-Token Themes
Every element — headings, code blocks, diagrams, formulas — shares one token system. Switch themes, everything updates instantly.
Export & Publish Anywhere
Single-file HTML with dark mode. PDF, PNG (4 sizes), rich text for WeChat / Notion / Juejin. All formats.
Real-time Preview
CodeMirror 6 editor with scroll sync, syntax highlighting, and instant rendered preview side by side.
Code-block DSL Toolkit
Every fenced code block is an extension point. Charts, CSV tables, HTTP runners, diffs, tabs, pricing cards — all with the same fence syntax, zero plugins to install.
Try it yourself
Paste your Markdown, switch themes, see the difference.
# The Art of Technical Writing
Great documentation is as important as great code. Here's why **clarity matters** — and how _good writing_ compounds over time. Every element on this page responds to the active theme: headings, code blocks, tables, and blockquotes all share the same token system.
## Code & Syntax Highlighting
Every annotation responds to the active theme:
**① 文件名 + 行号 + 元数据高亮 `{3,8-9}`**
```typescript title="src/article.ts" showLineNumbers {3,8-9}
interface Article {
id: string;
title: string;
author: string;
tags: string[];
publishedAt: Date;
}
async function fetchArticle(slug: string): Promise<Article> {
const res = await fetch(`/api/articles/${slug}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json() as Promise<Article>;
}
```
**② Diff 增删 `[!code ++]` / `[!code --]`**
```typescript
// Refactor: add types + template literals
async function getUser(id) {
// [!code --]
return fetch('/users/' + id); // [!code --]
} // [!code --]
async function getUser(id: string) {
// [!code ++]
return fetch(`/users/${id}`); // [!code ++]
} // [!code ++]
```
**③ 行内高亮 `[!code highlight]` · 错误 `[!code error]` · 警告 `[!code warning]` · 信息 `[!code info]`**
```javascript
function processOrder(order) {
if (!order.userId) throw new Error('userId missing'); // [!code error]
if (order.total < 0) {
// [!code warning]
order.total = 0;
}
const tax = order.total * 0.1; // [!code highlight]
return { ...order, tax }; // [!code info]
}
```
**④ 聚焦模式 `[!code focus]` — 非焦点行模糊,悬停恢复**
```typescript
function parseConfig(raw: string) {
// [!code focus]
const lines = raw.split('\n'); // [!code focus]
return Object.fromEntries(
// [!code focus]
lines.map((l) => l.split('=')) // [!code focus]
); // [!code focus]
}
function loadFile(path: string) {
return require('fs').readFileSync(path, 'utf8');
}
```
**⑤ 单词高亮 `[!code word:xxx]`**
```typescript
const MAX_RETRIES = 3; // [!code word:MAX_RETRIES:5]
async function fetchWithRetry(url: string) {
for (let i = 0; i < MAX_RETRIES; i++) {
const res = await fetch(url);
if (res.ok) return res;
}
throw new Error(`Failed after ${MAX_RETRIES} retries`);
}
```
## Terminal · Shell
终端块自动解析提示符、命令、参数、路径和输出,分别着色:
```bash
$ git clone https://github.com/mark-build/mark-build.git ~/projects/mark-build
$ cd ~/projects/mark-build
$ pnpm install
✓ done 312 packages in 4.2s
$ pnpm build
error Build failed: Missing environment variable API_KEY
$ export API_KEY=sk-prod-xxxxxxxxxxxx
$ pnpm build
✓ Build complete in 8.1s — dist/ ready
```
```zsh
# Deploy to production
➜ pnpm deploy --env production --region us-east-1
✓ Uploading assets (42 files)
✓ Edge cache purged
✓ Deployed to https://mark.build
```
## Diff 视图
标准 unified diff 格式,`---`/`+++` 文件头、`@@` 块头、增删行分别着色:
```diff
--- a/packages/renderer/src/render.ts
+++ b/packages/renderer/src/render.ts
@@ -1,8 +1,12 @@
import { unified } from 'unified';
import remarkParse from 'remark-parse';
+import remarkGfm from 'remark-gfm';
+import remarkMath from 'remark-math';
import remarkRehype from 'remark-rehype';
-import rehypeStringify from 'rehype-stringify';
+import rehypeKatex from 'rehype-katex';
+import rehypePrettyCode from 'rehype-pretty-code';
+import rehypeStringify from 'rehype-stringify';
export async function render(markdown: string) {
- return unified().use(remarkParse).use(remarkRehype).use(rehypeStringify);
+ const processor = unified().use(remarkParse).use(remarkGfm);
+ if (options.math) processor.use(remarkMath).use(rehypeKatex);
+ return processor.use(rehypePrettyCode).use(rehypeStringify);
}
```
## 程序输出
`output`/`stdout`/`stderr`/`log` 代码块自动识别 error / warn / success 行并着色:
```output
✓ TypeScript compiled — 0 errors
✓ 84 tests passed (2 skipped)
warn: 3 deprecated API calls in src/legacy/
warn: Bundle size 512 KB exceeds recommended 400 KB
error: Snapshot mismatch in ThemeGallery.test.tsx
Expected: border-color: #e5e7eb
Received: border-color: #d1d5db
```
```stderr
error: Cannot find module '@mark-build/themes'
Require stack:
- packages/renderer/src/render.ts
- apps/web/src/lib/renderMarkdown.ts
error: Build failed with 1 error
```
## CSV 数据表
`csv`/`tsv` 代码块解析为可交互的数据表格,支持复制、下载、导出 PNG:
```csv
Theme,Style,Accent,Font,Dark Mode
Default,Clean,Blue,Inter,✅
Tech Blog,Hacker,Purple,JetBrains Mono,✅
Academic,Scholarly,Teal,Lora + Inter,✅
Minimal,Zen,Gray,System UI,✅
Magazine,Editorial,Red,Playfair Display,✅
```
```tsv
Plugin Language IDs Output Priority
rehype-terminal bash sh zsh fish Terminal card P0
rehype-mermaid mermaid SVG diagram P0
rehype-math katex Rendered formula P0
rehype-diff diff patch Colored diff P1
rehype-csv csv tsv Data table P1
rehype-http http rest curl Request card P1
```
## HTTP 请求
`http`/`rest` 代码块渲染为语义化请求卡片,点击 ▶ Run 直接发送请求并展示响应:
```http
GET https://jsonplaceholder.typicode.com/posts/1 HTTP/1.1
Accept: application/json
```
```http
POST https://httpbin.org/post HTTP/1.1
Content-Type: application/json
{"title": "Getting Started with Mark.build", "draft": false}
```
```http
GET https://httpbin.org/get?theme=default&format=json HTTP/1.1
Accept: application/json
X-Client: mark-build
```
## Writing Principles
Effective technical writing follows a small set of rules:
1. **Write for your future self** — you'll forget the context in three months
2. **Lead with the conclusion** — readers scan before they commit
3. **Use concrete examples** over abstract descriptions
4. **Revise everything** — first drafts are just thinking out loud
Supporting habits that compound over time:
- Read your draft aloud before publishing
- Cut every sentence that doesn't add information
- Prefer active voice; passive voice hides the actor
- Weak: _The bug was introduced by the recent refactor_
- Strong: _The recent refactor introduced the bug_
- Use numbered lists for steps, bullet lists for items without order
### Task Tracking
- [x] Draft the outline
- [x] Write the first section
- [x] Add code examples
- [ ] Review and edit with fresh eyes
- [ ] Publish and share
### Nested Lists
Unordered lists support arbitrary depth:
- Frontend
- Frameworks
- React
- Vue
- Svelte
- Tooling
- Vite
- Bun
- Backend
- Node.js
- Go
- Rust
Ordered lists with nested unordered steps:
1. Set up the project
- Initialize the repository
- Configure the build tools
2. Write the code
- Follow the style guide
- Add tests alongside features
3. Review and ship
## Mathematics
Inline math: the quadratic formula $x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$ fits naturally within a paragraph.
Display math renders centered on its own line:
$$
\sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6}
$$
$$
\int_0^\infty e^{-x^2}\, dx = \frac{\sqrt{\pi}}{2}
$$
## Blockquotes
> Great writing is rewriting. Edit ruthlessly, then edit again.
> — William Zinsser, _On Writing Well_
Nested blockquotes preserve hierarchy:
> Documentation is a love letter to your future self.
>
> > The hardest part of writing is starting. The second hardest is stopping.
> >
> > > Write drunk, edit sober.
## Comparison Table
| Format | Readable | Portable | Styled | Version control |
| -------------- | :------: | :------: | :----: | :-------------: |
| Plain text | ✅ | ✅ | ❌ | ✅ |
| HTML | ❌ | ✅ | ✅ | ⚠️ |
| Word / Pages | ✅ | ❌ | ✅ | ❌ |
| LaTeX | ⚠️ | ✅ | ✅ | ✅ |
| **Mark.build** | **✅** | **✅** | **✅** | **✅** |
Tables inherit the theme's header background, border color, and row styling from the same token set.
## Diagrams
Flow charts and sequence diagrams render as inline SVG — no external dependencies, fully theme-aware:
```mermaid
graph LR
A[Write Markdown] --> B[Pick a Theme]
B --> C{Export}
C --> D[HTML]
C --> E[PDF]
C --> F[Rich Text]
```
## Inline Formatting
Text can be **bold**, _italic_, ~~strikethrough~~, or `monospace`. You can combine them: **_bold italic_**, **`bold code`**, or [hyperlinks](https://mark.build) that use the accent color.
> **Note:** Horizontal rules provide visual breaks between major sections.
---
Switch themes above to see every element — headings, code blocks, tables, math, blockquotes — update in unison from a single set of design tokens.
## Interactive Blocks
### Comparison
```compare
--- left: Mark.build
Designed for writers. Themes, export to PDF/HTML/DOCX, and a growing set of specialized code-block tools baked in.
--- right: Notion
Designed for teams. Great for databases and wikis, but limited styling and export options.
```
### Citation
```cite
title: The Unreasonable Effectiveness of Data
authors: Halevy, A.; Norvig, P.; Pereira, F.
year: 2009
venue: IEEE Intelligent Systems
url: https://research.google/pubs/the-unreasonable-effectiveness-of-data/
type: paper
```
### Breadcrumb
```breadcrumb
Home > Documentation > Getting Started > Installation
```
### Author Note
```author-note
TODO: expand the "Interactive Blocks" section with more examples (regex, js-run, log).
This note is only visible in the editor — it disappears in PDF and PNG exports.
```
### JavaScript Sandbox
```js-run
const primes = n => {
const sieve = Array(n + 1).fill(true);
sieve[0] = sieve[1] = false;
for (let i = 2; i * i <= n; i++)
if (sieve[i]) for (let j = i * i; j <= n; j += i) sieve[j] = false;
return sieve.reduce((a, v, i) => v ? [...a, i] : a, []);
};
console.log('Primes up to 50:', primes(50).join(', '));
```
Free for most. One-time for power users.
Web editor and Desktop Lite are free forever. Desktop Pro is a one-time purchase.
Desktop Pro
- ✓ Everything in Desktop Lite (free)
- ✓ Vue & Svelte component support (Vite-powered)
- ✓ Whole-site Astro static export
- ✓ Cloud sync across your Macs
- ✓ Lifetime updates
One-time purchase · No recurring fees · Lifetime updates
Questions? hi@mark.build