Skip to content

Commit b09c3b5

Browse files
authored
Merge pull request #2 from wflixu/dev
v1.1.0
2 parents d0f3388 + 7d5750b commit b09c3b5

27 files changed

+5106
-101
lines changed

.claude/settings.local.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,18 @@
2020
"Bash(cargo run:*)",
2121
"Bash(../target/debug/mdz pack:*)",
2222
"Bash(../target/debug/mdz:*)",
23-
"Bash(cargo clippy:*)"
23+
"Bash(cargo clippy:*)",
24+
"Bash(git tag:*)",
25+
"Bash(git push:*)",
26+
"Bash(npm install)",
27+
"Bash(pnpm install:*)",
28+
"Bash(pnpm run compile:*)",
29+
"Bash(pnpm add:*)",
30+
"Bash(npm install:*)",
31+
"Bash(npx @vscode/vsce package:*)",
32+
"Bash(pnpm exec vsce:*)",
33+
"Bash(ls:*)",
34+
"Bash(unzip:*)"
2435
]
2536
}
2637
}

CLAUDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ cargo test -p mdz-rs it_works
7373
- `assets/files/`: 其他附件文件(PDFs, 文档等)
7474

7575
### 资源引用方式
76-
- 在 Markdown 中使用 `assets://<asset-id>` 引用资源
77-
- 资源 ID 在 manifest.json 中定义
76+
- 在 Markdown 中使用相对路径 `./assets/<category>/<filename>` 引用资源
77+
- 资源按类型组织在 assets 目录的子目录中
7878

7979
## 依赖项
8080

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mdz-rs/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[package]
22
name = "mdz-rs"
3-
version = "1.0.0"
3+
version = "1.1.0"
44
edition = "2024"
5-
description = "A Rust library and CLI tool for defining, packaging, and unpacking a custom Markdown-based file format with embedded resources"
5+
description = "A Rust library for creating and working with MDZ (Markdown Zip) files - self-contained archives that bundle Markdown documents with embedded assets"
66
license = "MIT"
77
repository = "https://github.com/wflixu/mdz"
88
homepage = "https://github.com/wflixu/mdz"
9-
documentation = "https://github.com/wflixu/mdz#readme"
9+
documentation = "https://docs.rs/mdz-rs"
1010
keywords = ["markdown", "zip", "archive", "mdz", "packaging"]
1111
categories = ["compression", "command-line-utilities", "text-processing"]
1212

mdz-rs/README.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# mdz-rs
2+
3+
[![Crates.io](https://img.shields.io/crates/v/mdz-rs.svg)](https://crates.io/crates/mdz-rs)
4+
[![Documentation](https://docs.rs/mdz-rs/badge.svg)](https://docs.rs/mdz-rs)
5+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6+
7+
A powerful Rust library for creating and working with **MDZ (Markdown Zip)** files - self-contained archives that bundle Markdown documents with embedded assets.
8+
9+
## 🚀 Quick Start
10+
11+
Add this to your `Cargo.toml`:
12+
13+
```toml
14+
[dependencies]
15+
mdz-rs = "1.1.0"
16+
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
17+
```
18+
19+
## 📖 Basic Usage
20+
21+
```rust
22+
use mdz_rs::{pack, unpack};
23+
24+
#[tokio::main]
25+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
26+
// Pack a markdown file with assets
27+
pack("document.md", "document.mdz").await?;
28+
29+
// Unpack MDZ file to extract content and assets
30+
unpack("document.mdz", Some("output/"))?;
31+
32+
Ok(())
33+
}
34+
```
35+
36+
## ✨ Features
37+
38+
- 🗜️ **Packaging**: Bundle Markdown with images, videos, audio, and other files
39+
- 🌐 **Smart Downloads**: Automatically download network images with UUID filenames
40+
- 📁 **Local Files**: Intelligently copy local assets with conflict resolution
41+
- 🔗 **Relative Links**: Use relative paths for maximum compatibility
42+
-**Backward Compatible**: Handle legacy MDZ files seamlessly
43+
- 📊 **Rich Metadata**: Complete manifest with document and asset information
44+
45+
## 🏗️ MDZ Format Structure
46+
47+
```
48+
document.mdz (ZIP archive)
49+
├── index.md # Updated markdown with relative asset links
50+
├── manifest.json # Metadata and asset mapping
51+
└── assets/ # Organized asset files
52+
├── images/
53+
├── videos/
54+
├── audio/
55+
└── files/
56+
```
57+
58+
## 🔧 API Reference
59+
60+
### Core Functions
61+
62+
#### `pack(markdown_file: &str, output_file: &str) -> Result<()>`
63+
Pack a markdown file and its assets into an MDZ archive.
64+
65+
```rust
66+
use mdz_rs::pack;
67+
68+
#[tokio::main]
69+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
70+
pack("report.md", "report.mdz").await?;
71+
println!("Successfully packed report.mdz");
72+
Ok(())
73+
}
74+
```
75+
76+
#### `unpack(input_file: &str, output_dir: Option<&str>) -> Result<()>`
77+
Unpack an MDZ archive to extract the markdown file and assets.
78+
79+
```rust
80+
use mdz_rs::unpack;
81+
82+
fn main() -> Result<(), Box<dyn std::error::Error>> {
83+
unpack("report.mdz", Some("extracted/"))?;
84+
println!("Successfully unpacked to extracted/");
85+
Ok(())
86+
}
87+
```
88+
89+
### Utility Functions
90+
91+
#### `is_url(path: &str) -> bool`
92+
Check if a path is a URL or local file path.
93+
94+
```rust
95+
use mdz_rs::is_url;
96+
97+
assert!(is_url("https://example.com/image.jpg"));
98+
assert!(!is_url("./local/image.png"));
99+
```
100+
101+
## 📦 Dependencies
102+
103+
- **zip**: ZIP archive creation and extraction
104+
- **serde + serde_json**: JSON serialization for manifest files
105+
- **reqwest**: HTTP client for downloading network images
106+
- **tokio**: Async runtime for network operations
107+
- **anyhow**: Error handling
108+
- **url**: URL parsing and manipulation
109+
- **regex**: Markdown link processing
110+
111+
## 🎯 Use Cases
112+
113+
- **Document Sharing**: Create self-contained documents with embedded images
114+
- **Static Site Generation**: Package blog posts with assets
115+
- **Documentation Systems**: Bundle documentation with media files
116+
- **Content Management**: Archive markdown content with resources
117+
- **Educational Materials**: Share lessons with embedded media
118+
119+
## 🧪 Examples
120+
121+
### Example 1: Basic Packing
122+
123+
```rust
124+
use mdz_rs::pack;
125+
126+
#[tokio::main]
127+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
128+
// Create a markdown file
129+
std::fs::write("example.md", r#"
130+
# My Document
131+
132+
![Local Image](./images/photo.jpg)
133+
![Remote Image](https://example.com/banner.png)
134+
135+
This is a sample document with both local and remote images.
136+
"#)?;
137+
138+
// Pack it into MDZ
139+
pack("example.md", "example.mdz").await?;
140+
println!("Created example.mdz");
141+
142+
Ok(())
143+
}
144+
```
145+
146+
### Example 2: Custom Unpacking
147+
148+
```rust
149+
use mdz_rs::unpack;
150+
151+
fn main() -> Result<(), Box<dyn std::error::Error>> {
152+
// Unpack to specific directory
153+
unpack("example.mdz", Some("my_docs/"))?;
154+
155+
// Check extracted files
156+
let markdown = std::fs::read_to_string("my_docs/example.md")?;
157+
println!("Extracted markdown: {}", markdown);
158+
159+
Ok(())
160+
}
161+
```
162+
163+
### Example 3: Asset Processing
164+
165+
```rust
166+
use mdz_rs::pack;
167+
use std::path::Path;
168+
169+
#[tokio::main]
170+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
171+
let md_file = "portfolio.md";
172+
let output_file = "portfolio.mdz";
173+
174+
// The pack function will:
175+
// 1. Parse the markdown for image links
176+
// 2. Download remote images with UUID names
177+
// 3. Copy local images to assets directory
178+
// 4. Update links to use relative paths
179+
// 5. Create manifest.json with metadata
180+
// 6. Bundle everything into a ZIP file
181+
182+
pack(md_file, output_file).await?;
183+
184+
println!("✅ Created self-contained document!");
185+
println!("📁 Assets are organized in the archive");
186+
println!("🔗 Links use relative paths for compatibility");
187+
188+
Ok(())
189+
}
190+
```
191+
192+
## 🔍 Advanced Usage
193+
194+
### Error Handling
195+
196+
```rust
197+
use mdz_rs::{pack, unpack};
198+
use anyhow::Result;
199+
200+
#[tokio::main]
201+
async fn main() -> Result<()> {
202+
match pack("missing.md", "output.mdz").await {
203+
Ok(_) => println!("Packing successful"),
204+
Err(e) => eprintln!("Packing failed: {}", e),
205+
}
206+
207+
Ok(())
208+
}
209+
```
210+
211+
### Asset Detection
212+
213+
The library automatically detects and processes:
214+
215+
- **Images**: PNG, JPG, JPEG, SVG, GIF, WEBP, etc.
216+
- **Videos**: MP4, WEBM, AVI, MOV, etc.
217+
- **Audio**: MP3, WAV, OGG, M4A, etc.
218+
- **Files**: PDF, DOCX, TXT, and any other file types
219+
220+
## 📄 License
221+
222+
This project is licensed under the MIT License - see the [LICENSE](../LICENSE) file for details.
223+
224+
## 🤝 Contributing
225+
226+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
227+
228+
## 📚 Documentation
229+
230+
For complete API documentation, visit [docs.rs/mdz-rs](https://docs.rs/mdz-rs).
231+
232+
For the MDZ format specification, see the main project [README](../README.md).

mdz-rs/assets/images/test.png

-128 Bytes
Loading

0 commit comments

Comments
 (0)