markdownfly 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/dist/cli.js +2756 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +217 -0
- package/dist/index.js +2653 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MarkdownFly Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# MarkdownFly (mfly) 🚀
|
|
2
|
+
|
|
3
|
+
> **Markdown to PowerPoint (.pptx) CLI tool designed for developers.**
|
|
4
|
+
> Write in Markdown with syntax-highlighted code and embedded diagrams; generate beautiful, editable slides in seconds.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## ✨ Features
|
|
9
|
+
|
|
10
|
+
- 📑 **Markdown to PowerPoint**: Convert standard Markdown to editable 16:9 widescreen `.pptx` slides.
|
|
11
|
+
- 🎨 **Syntax Highlighting**: Token-level code highlighting powered by [Shiki](https://shiki.style/) (Python, TypeScript, Go, Rust, Java, C++, Bash, SQL, and 20+ languages).
|
|
12
|
+
- 📊 **Built-in Diagram Rendering (Zero native binary dependencies)**:
|
|
13
|
+
- **Mermaid**: Flowcharts, sequence diagrams, state diagrams, class diagrams.
|
|
14
|
+
- **Graphviz / DOT**: Network graphs, finite state machines, architecture topologies (via WASM).
|
|
15
|
+
- **ECharts**: Bar charts, line charts, pie charts directly from JSON options (via ECharts SSR).
|
|
16
|
+
- 🖼️ **Image Embedding**: Local file paths, remote URLs (`http://`/`https://`), and base64 Data URIs.
|
|
17
|
+
- 📐 **Automatic Layout Detection**: Title slides, section dividers, code spotlights, quotes, and content slides.
|
|
18
|
+
- ⚡ **Batch Conversion**: Convert multiple files with glob support (`mfly *.md`).
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 📦 Installation
|
|
23
|
+
|
|
24
|
+
Requires Node.js 20+.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Install globally from npm (preferred)
|
|
28
|
+
npm install -g markdownfly
|
|
29
|
+
|
|
30
|
+
# Or run without installing
|
|
31
|
+
npx markdownfly@latest slides.md
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Develop from source:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Clone and install dependencies
|
|
38
|
+
git clone https://github.com/Kyvin-Guan/markdownFly.git
|
|
39
|
+
cd markdownFly
|
|
40
|
+
pnpm install
|
|
41
|
+
pnpm build
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Link locally for global CLI access:
|
|
45
|
+
```bash
|
|
46
|
+
pnpm link --global
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 🚀 Quick Start
|
|
52
|
+
|
|
53
|
+
### Basic Usage
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Convert a single file (named after the input: slides.md → slides.pptx)
|
|
57
|
+
mfly slides.md
|
|
58
|
+
|
|
59
|
+
# Specify theme (clean, academic, dark, business, warm, aurora, neon, nord, dracula, beige, ink)
|
|
60
|
+
mfly slides.md -t dark
|
|
61
|
+
|
|
62
|
+
# Specify custom output path
|
|
63
|
+
mfly slides.md -t academic -o presentation.pptx
|
|
64
|
+
|
|
65
|
+
# Batch convert multiple Markdown files
|
|
66
|
+
mfly docs/*.md
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
If the default output name already exists, a timestamped name is used
|
|
70
|
+
(`slides-20260907-131500.pptx`) instead of overwriting. With `-o` the target
|
|
71
|
+
is overwritten without prompting.
|
|
72
|
+
|
|
73
|
+
### Automation (`--quiet` / `--json`)
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Machine-readable result (one JSON line on stdout; diagnostics on stderr)
|
|
77
|
+
mfly slides.md --json
|
|
78
|
+
|
|
79
|
+
# Suppress per-file progress lines
|
|
80
|
+
mfly docs/*.md --quiet
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- `--json` prints a single JSON object to stdout:
|
|
84
|
+
`{"ok":true,"durationMs":1234,"files":[{"input":"slides.md","output":"C:/abs/slides.pptx","ok":true}]}`.
|
|
85
|
+
Per-file failures set `ok:false` with an `error` field.
|
|
86
|
+
- Exit code is `0` only when **every** file converts successfully; if any file
|
|
87
|
+
fails the process exits `1` (a summary line is printed to stderr).
|
|
88
|
+
- `-t` with an unknown theme name fails with exit `1` (theme names in markdown
|
|
89
|
+
frontmatter fall back to `clean` with a warning).
|
|
90
|
+
- Progress lines go to stderr; errors and warnings always go to stderr.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 🎨 Built-in Themes
|
|
95
|
+
|
|
96
|
+
| Theme | Style / Mood | Primary Colors | Best For |
|
|
97
|
+
| :--- | :--- | :--- | :--- |
|
|
98
|
+
| **`clean`** *(default)* | Modern clean tech | White `#FFFFFF` / Blue `#2563EB` | General developer presentations & tech sharing |
|
|
99
|
+
| **`academic`** | Scholarly LaTeX Beamer | White `#FFFFFF` / Prussian Blue `#003366` | Papers, algorithms, research defenses |
|
|
100
|
+
| **`dark`** | Dark mode geek | Dark Slate `#0F172A` / Cyan `#38BDF8` | Developer meetups, terminal & coding decks |
|
|
101
|
+
| **`business`** | Professional corporate | Soft Slate `#F8FAFC` / Deep Navy `#1E3A8A` | Business reviews, executive pitches & reports |
|
|
102
|
+
| **`warm`** | Warm paper / Marp Gaia | Warm Sand `#FDFBF7` / Forest Green `#065F46` | Keynotes, design retrospectives & narratives |
|
|
103
|
+
| **`aurora`** | Dark neon gradient | Deep Navy `#06091C` / Mint-Blue `#7AA2FF` | Product launches, creative & futuristic decks |
|
|
104
|
+
| **`neon`** | High-contrast cyber | Black `#121212` / Cyan `#00E5FF` + Magenta `#FF4081` | Tech demos, cyberpunk-style sharing |
|
|
105
|
+
| **`nord`** | Arctic Frost | Dark `#2E3440` / Frost Blue `#88C0D0` | Cold & calm dev/design decks |
|
|
106
|
+
| **`dracula`** | Dracula dark | Charcoal `#282A36` / Purple `#BD93F9` + Pink `#FF79C6` | Code-heavy dark presentations |
|
|
107
|
+
| **`beige`** | Warm paper minimal | Beige `#F7F3DE` / Bronze `#8B6F3D` + Terracotta `#C0563C` | Editorial, workshop, organics |
|
|
108
|
+
| **`ink`** | Chinese ink-wash | Rice Paper `#F7F4EC` / Ink `#2F3530` + Vermilion `#C0272D` | Culture, humanities, Chinese-style decks |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 📝 Markdown Syntax Guide
|
|
113
|
+
|
|
114
|
+
### Slide Splitting Rules
|
|
115
|
+
|
|
116
|
+
- `---` (Horizontal Rule): Primary slide separator.
|
|
117
|
+
- `# Heading 1`: Creates a new slide with **Title** (cover) layout.
|
|
118
|
+
- `## Heading 2`: Creates a new slide with **Content** or **Section** layout.
|
|
119
|
+
|
|
120
|
+
### Frontmatter
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
---
|
|
124
|
+
theme: dark # Options: clean, academic, dark, business, warm, aurora, neon, nord, dracula, beige, ink
|
|
125
|
+
author: "Your Name"
|
|
126
|
+
footer: "Confidential - {page} / {total}" # {page}/{total}/{section}/{title}
|
|
127
|
+
resource_dir: ./assets # Base directory for relative image paths
|
|
128
|
+
layout: code # Optional default layout for content slides
|
|
129
|
+
---
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### In-Slide Layout (Grid)
|
|
133
|
+
|
|
134
|
+
Split a slide into columns and rows with standalone lines — no extra markup:
|
|
135
|
+
|
|
136
|
+
```markdown
|
|
137
|
+
## 架构概览
|
|
138
|
+
|
|
139
|
+
### 架构图
|
|
140
|
+
```mermaid
|
|
141
|
+
graph LR
|
|
142
|
+
A[Client] --> B[API]
|
|
143
|
+
```
|
|
144
|
+
<-> <!-- 左右分栏:左边放图 -->
|
|
145
|
+
|
|
146
|
+
### 关键点
|
|
147
|
+
- 低延迟
|
|
148
|
+
- 可扩展
|
|
149
|
+
- 成本可控
|
|
150
|
+
=== <!-- 上下分块:下面是另一行内容 -->
|
|
151
|
+
|
|
152
|
+
### 总结
|
|
153
|
+
> [!TIP]
|
|
154
|
+
> `===` 让一页拆成上下块,适合前后对比。
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- `<->` (standalone line): horizontal separator → **columns** (side-by-side).
|
|
158
|
+
- `===` (standalone line): vertical separator → **rows** (stacked).
|
|
159
|
+
- Combine both for grids. Markers inside code blocks are never rewritten.
|
|
160
|
+
|
|
161
|
+
### Slide Directives `@(...)`
|
|
162
|
+
|
|
163
|
+
A standalone `@(key=value, ...)` line at the bottom of a slide sets per-slide options:
|
|
164
|
+
|
|
165
|
+
```markdown
|
|
166
|
+
## 表格变图表
|
|
167
|
+
|
|
168
|
+
| 季度 | 订单量 |
|
|
169
|
+
| :--- | :--- |
|
|
170
|
+
| Q1 | 320 |
|
|
171
|
+
| Q2 | 580 |
|
|
172
|
+
|
|
173
|
+
@(chart=bar, notes=这里口头展开Q1-2数据)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
| Directive | Value | Effect |
|
|
177
|
+
| :--- | :--- | :--- |
|
|
178
|
+
| `layout` | `title` / `section` / `content` / `code` / `quote` | Override auto-detected layout |
|
|
179
|
+
| `notes` | text | Speaker notes for this slide |
|
|
180
|
+
| `chart` | `bar` / `line` / `pie` | Render the first table as a chart |
|
|
181
|
+
| `highlight` | `2-4,6` | Highlight lines in the slide's code block |
|
|
182
|
+
| `background` | URL/path | Slide background image |
|
|
183
|
+
| `steps` | `true` | Progressive reveal (reserved) |
|
|
184
|
+
|
|
185
|
+
### Callouts
|
|
186
|
+
|
|
187
|
+
```markdown
|
|
188
|
+
> [!NOTE]
|
|
189
|
+
> Important point to remember.
|
|
190
|
+
|
|
191
|
+
> [!TIP]
|
|
192
|
+
> Helpful suggestion.
|
|
193
|
+
|
|
194
|
+
> [!WARNING]
|
|
195
|
+
> Watch out for this.
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Supported variants: `NOTE` / `INFO` / `TIP` / `SUCCESS` / `WARNING` / `CAUTION` / `DANGER` — rendered as theme-styled accent cards.
|
|
199
|
+
|
|
200
|
+
### Task Lists
|
|
201
|
+
|
|
202
|
+
```markdown
|
|
203
|
+
- [x] Completed item
|
|
204
|
+
- [ ] Upcoming item
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Images
|
|
208
|
+
|
|
209
|
+
A standalone image line renders as a slide element (aspect ratio preserved, centered in its column). Paths are resolved relative to the markdown file, or relative to `resource_dir` (which itself is resolved relative to the markdown file, never the current working directory); remote URLs (`http/https`) and base64 data URIs also work. A missing or failed image is skipped with a warning on stderr — the deck is still generated.
|
|
210
|
+
|
|
211
|
+
```markdown
|
|
212
|
+
{w=6in,align=center}
|
|
213
|
+
{w=60%}
|
|
214
|
+
{width=120px,height=40mm,align=right}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
- Keys: `w`/`width`, `h`/`height`, `align` (`left`/`center`/`right`, default `center`)
|
|
218
|
+
- Units: `px` (default), `pt`, `cm`, `mm`, `in`/`inch`, `%` (relative to the column; single value preserves aspect ratio)
|
|
219
|
+
- Invalid params are silently ignored — the image still renders
|
|
220
|
+
- ⚠ Security: image paths (`` and `@(background=...)`) are resolved without restrictions — only convert markdown you own or trust.
|
|
221
|
+
|
|
222
|
+
### Code Blocks with Syntax Highlighting
|
|
223
|
+
|
|
224
|
+
````markdown
|
|
225
|
+
```typescript
|
|
226
|
+
interface User {
|
|
227
|
+
id: string;
|
|
228
|
+
name: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function greet(user: User): string {
|
|
232
|
+
return `Hello, ${user.name}!`;
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
````
|
|
236
|
+
|
|
237
|
+
````markdown
|
|
238
|
+
```python
|
|
239
|
+
def quick_sort(arr): ...
|
|
240
|
+
```
|
|
241
|
+
@(highlight=1,3-4) <!-- highlight specific lines -->
|
|
242
|
+
````
|
|
243
|
+
|
|
244
|
+
### Diagram Code Blocks
|
|
245
|
+
|
|
246
|
+
````markdown
|
|
247
|
+
```mermaid
|
|
248
|
+
graph TD
|
|
249
|
+
A[Client] --> B[API Gateway]
|
|
250
|
+
B --> C[Auth Service]
|
|
251
|
+
B --> D[Data Service]
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
```dot
|
|
255
|
+
digraph Architecture {
|
|
256
|
+
rankdir=LR;
|
|
257
|
+
node [shape=box, style=filled, fillcolor=lightblue];
|
|
258
|
+
Frontend -> Backend -> Database;
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
```echarts
|
|
263
|
+
{
|
|
264
|
+
"xAxis": { "type": "category", "data": ["Q1", "Q2", "Q3", "Q4"] },
|
|
265
|
+
"yAxis": { "type": "value" },
|
|
266
|
+
"series": [{ "data": [150, 230, 224, 218], "type": "bar" }]
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
````
|
|
270
|
+
|
|
271
|
+
### Footnotes
|
|
272
|
+
|
|
273
|
+
- A standalone `===` always means a row break — setext-style headlines (`Title` + `===`) are `# Headings` in mfly.
|
|
274
|
+
- A standalone `<->` always means a column break; use `***text***` for bold italic (the moffee convention of `<->bold and italic<->` is deliberately not adopted to avoid ambiguity).
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 🧪 Testing
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# Run all unit and integration tests
|
|
282
|
+
pnpm test
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## 📄 License
|
|
288
|
+
|
|
289
|
+
MIT License © 2026 MarkdownFly Contributors
|