@aiquants/markdown
v1.18.0
Published
Markdown renderer for React with advanced features
Readme
@aiquants/markdown
Advanced Markdown renderer for React with support for various extensions and custom components.
Features
- Rich Markdown Support: Full support for CommonMark, GitHub Flavored Markdown (GFM), and LaTeX Math expressions.
- Offloaded Parser: CPU-heavy Markdown parsing and AST transformation are offloaded to a high-performance Go API server running
goldmarkandConnectRPC. - Custom Extensions & Plugins: Pluggable support for subscript, superscript, mark highlights, table cell merges, embeds (YouTube, Twitter), and Zenn-style directives.
- Dynamic Configuration: Easily enable or disable custom extensions dynamically using parse options.
- Syntax Highlighting: Code blocks with Shiki syntax highlighting.
- TypeScript: Full TypeScript support with comprehensive type definitions.
Installation
npm install @aiquants/markdown
# or
pnpm add @aiquants/markdown
# or
yarn add @aiquants/markdownパーサーバイナリの配布
Markdown の解析は Go 製サービス (markdown-api) が担当します。このバイナリはプラットフォーム別のパッケージとして配布され、パッケージマネージャが実行環境に合うものだけを自動選択します (esbuild や Biome と同じ方式)。本体パッケージにバイナリは含まれません。
| プラットフォーム | 対応 | | --- | --- | | Linux x64 / arm64 | ✅ | | macOS x64 (Intel) / arm64 (Apple Silicon) | ✅ | | Windows x64 / arm64 | ✅ |
postinstall スクリプトは不要です (実行権限は npm の bin 契約で保証されます)。ライフサイクルスクリプトを禁止している環境でもそのまま動きます。
parseMarkdown は最初の呼び出し時にサービスが待ち受けていなければ自動起動します。プロセスマネージャ (supervisor / systemd など) で markdown-api を別プロセスとして管理している構成では、そのソケットへそのまま接続します。
サービスを自分でビルドし、その場所を教えてください。
git clone https://github.com/fehde-k/aiquants.git
cd aiquants/packages/go/markdown-api
go build -o dist/markdown-api .export MARKDOWN_API_BINARY=/path/to/markdown-api環境変数
| 変数 | 既定値 | 用途 |
| --- | --- | --- |
| MARKDOWN_SOCKET_PATH | /tmp/markdown.sock | サービスと通信する UNIX ドメインソケットのパス |
| MARKDOWN_API_BINARY | (なし) | 自前ビルドしたバイナリの明示指定 |
| MARKDOWN_API_STARTUP_TIMEOUT_MS | 10000 | 自動起動したサービスが待ち受け開始するまでの猶予 |
Usage
Basic Usage
import { MarkdownRenderer } from "@aiquants/markdown"
import { parseMarkdown } from "@aiquants/markdown/server"
import "@aiquants/markdown/styles/markdown.css"
const MyComponent = async () => {
const markdownText = `# Hello World
This is a **bold** text with inline math: $y=x^2$ and subscript: H~2~O.
\`\`\`javascript
console.log("Hello, World!")
\`\`\`
`
// Parse the markdown using the Go parser server
const parseResult = await parseMarkdown(
markdownText,
"/workspace/tmp/my-file.md",
"/workspace"
)
// parseResult: ParseResult
// htmlContent: string — レンダリング済み HTML
// headings: { text: string; depth: number; id: string }[] — 目次構築用の見出し一覧
return (
<MarkdownRenderer
htmlContent={parseResult.htmlContent}
theme="light"
iFrameAllowedDomains={["www.youtube.com"]}
/>
)
}Pluggable Parser Options
You can dynamically enable or disable custom extensions using ParseOptions (exported from @aiquants/markdown/server):
const parseResult = await parseMarkdown(
markdownText,
"/workspace/tmp/my-file.md",
"/workspace",
undefined, // OAuth Token if needed
{
validateExistence: true,
enableSubscript: false, // Disable subscript (leaves ~2~ as plain text)
enableSuperscript: true, // Enable superscript
enableMark: false, // Disable highlight mark
enableTableMerge: true, // Enable table merges (> and ^)
enableEmbeds: true, // Enable YouTube / Twitter embeds
enableZennDirectives: true // Enable :::message / :::details
}
)Extended Syntax
The parser supports the following extended markdown syntax in addition to CommonMark and GFM.
LaTeX Math Expressions
- Inline math:
$y=x^2$ - Display math:
$$ e^{i\theta} = \cos\theta + i\sin\theta $$(or multiline block)
Table cell merge markers
>: horizontal merge (colspan) — the marker cell is absorbed into the nearest right non-marker cell, which gains the colspan^: vertical merge (rowspan) to the nearest upper non-marker cell
|header1|header2|header3|
|:------|:-----:|------:|
|hoge |> |piyo |
|hoge |^ |^ |
|hoge |^ |^ |
|hoge | |piyo |
|^ |^ |piyo |Inline superscript
30^th^Inline subscript
H~2~OInline mark highlight
This is ==important== text.Zenn-style Directives
Supports Zenn-style message box and details box with support for recursive nesting:
:::message info
This is an info message.
:::
:::details Title here
:::message warning
This is a nested warning message inside details.
:::
:::Notes
- goldmark's GFM strikethrough only recognizes double tildes (
~~text~~), so single-tilde~text~is reserved for subscript. - Double-tilde strikethrough (
~~text~~) remains available via GFM.
License
MIT License
