# mdforge
`mdforge` は、拡張 Markdown を**定義してから扱う**ための Rust ライブラリです。
LLM が生成したテキストを、型付き引数・構文ルール・診断情報で安全に扱い、DOM 風の中間表現 (`VNode`) へ変換できます。
## 特徴
- 拡張ブロック / インライン構文を `ForgeBuilder` で宣言
- 引数型 (`Int` / `String` / `StaticEnum` / `DynamicEnum`) を定義して検証
- `parse -> validate -> eval -> render_dom` のパイプライン API
- `Diagnostic` (`ErrorCode`, `Span`, `suggestion`) によるエラー収集
- LLM 指示向けの仕様文字列 (`signature`) を生成
## インストール
`Cargo.toml` に追加してください。
```toml
[dependencies]
mdforge = "0.1.0"
```
## クイックスタート
```rust
use mdforge::{ArgType, EvalContext, Forge, VNode};
let forge = Forge::builder()
.block("card")
.arg("title", ArgType::String.required())
.arg("level", ArgType::Int.optional())
.body_markdown()
.register()
.inline("badge")
.arg("level", ArgType::Int.required())
.register()
.build();
let input = ":::card title=hello level=1\ntext {badge level=2}\n:::\n";
let doc = forge.parse(input).expect("parse");
forge.validate(&doc).expect("validate");
let ctx = forge.eval(&doc, &EvalContext::default()).expect("eval");
struct NoopRenderer;
impl mdforge::forge::DomRenderer for NoopRenderer {
fn render_block(
&self,
_block: &mdforge::BlockNode,
_ctx: &EvalContext,
children: Vec<VNode>,
) -> VNode {
VNode::Text(format!("block children={} ", children.len()))
}
fn render_inline(&self, _inline: &mdforge::InlineExt, _ctx: &EvalContext) -> VNode {
VNode::Text("inline".to_string())
}
}
let nodes = forge
.render_dom(&doc, &ctx, &NoopRenderer)
.expect("render_dom");
println!("nodes: {}", nodes.len());
println!("signature:\n{}", forge.signature());
```
## 主要 API
- `Forge::builder()` / `ForgeBuilder`
- `Forge::parse`
- `Forge::validate`
- `Forge::eval`
- `Forge::render_dom`
- `Forge::signature`
## テスト
通常のテストは外部 API に接続せず、OpenAI 連携部分もモックで検証します。
```sh
cargo test
```
実際に OpenAI API へ 1 回だけリクエストするライブテストは、明示的に有効化した場合だけ実行されます。
```sh
OPENAI_API_KEY=... MDFORGE_RUN_OPENAI_TESTS=1 cargo test ai_pipeline_can_call_openai_when_enabled --test openai_pipeline
```
モデルは既定で `gpt-4.1-mini` を使います。必要なら `OPENAI_MODEL` で変更できます。
## デモ Web アプリ
料理レシピ生成デモの Recipe Lab を起動できます。
```sh
cargo run --example recipe_lab
```
ブラウザで `http://127.0.0.1:3000` を開くと、手入力した mdforge Markdown を HTML プレビューできます。OpenAI 生成も試す場合は、`.env` に API キーを設定してから起動してください。
```env
OPENAI_API_KEY=...
```
Recipe Lab では、`recipe` / `step` / `tip` ブロックと、`ingredient` / `needed` / `timer` / `badge` インラインを使います。各 `step` には必須の `minutes`、各食材マークアップには必須の `amount` を持たせ、食材参照は `DynamicEnum("ingredients")` で検証します。
詳しい使い方は以下を参照:
- `docs/user_guide.md`
- `docs/design_v0.1.md`
## ライセンス
このプロジェクトは [MIT License](./LICENSE) のもとで提供されます。