node-plantuml-2 1.0.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 +1053 -0
- package/index.js +8 -0
- package/lib/node-plantuml-cmd.js +110 -0
- package/lib/node-plantuml.js +446 -0
- package/lib/plantuml-executor-wasm.js +295 -0
- package/lib/plantuml-executor.js +165 -0
- package/lib/plantuml-syntax-fixer.js +545 -0
- package/nail/plantumlnail.jar +0 -0
- package/package.json +66 -0
- package/resources/classic.puml +31 -0
- package/resources/monochrome.puml +1 -0
- package/scripts/download.js +95 -0
- package/scripts/get-vizjs.js +51 -0
- package/vendor/plantuml.jar +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,1053 @@
|
|
|
1
|
+
# node-plantuml-2
|
|
2
|
+
|
|
3
|
+
> **Pure Node.js PlantUML Renderer - No Java Required!**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/node-plantuml-2)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
|
|
9
|
+
A powerful Node.js module and CLI for running [PlantUML](http://plantuml.sourceforge.net/) with **pure Node.js support**. This project is a fork and enhancement of [node-plantuml](https://github.com/markushedvall/node-plantuml), featuring WebAssembly-based execution that eliminates the need for Java runtime.
|
|
10
|
+
|
|
11
|
+
<div align="center">
|
|
12
|
+
|
|
13
|
+
**[English](#english) | [中文](#中文)**
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
<a name="english"></a>
|
|
20
|
+
|
|
21
|
+
## ✨ Key Features
|
|
22
|
+
|
|
23
|
+
- 🚀 **Pure Node.js Environment** - No Java installation required! Uses pre-compiled WebAssembly module
|
|
24
|
+
- 📦 **Zero Configuration** - Just `npm install` and start using
|
|
25
|
+
- 🎨 **Multiple Output Formats** - Support for PNG, SVG, EPS, ASCII, and Unicode text
|
|
26
|
+
- 🌏 **Multi-language Support** - Perfect rendering for Chinese, Japanese, Korean, and other CJK characters with automatic font detection
|
|
27
|
+
- ⚡ **Fast Startup** - WebAssembly execution is faster than JVM
|
|
28
|
+
- 🔄 **Automatic Fallback** - Falls back to Java executor if Wasm is unavailable
|
|
29
|
+
- 📝 **CLI & API** - Both command-line interface and programmatic API
|
|
30
|
+
- 🎯 **Based on PlantUML** - Full compatibility with PlantUML syntax
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 📦 Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install node-plantuml-2
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**That's it!** No Java, no configuration, no build steps required.
|
|
41
|
+
|
|
42
|
+
For global CLI installation:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install node-plantuml-2 -g
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 🚀 Quick Start
|
|
51
|
+
|
|
52
|
+
### Basic Usage
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
const plantuml = require('node-plantuml-2')
|
|
56
|
+
const fs = require('fs')
|
|
57
|
+
|
|
58
|
+
// Generate PNG diagram
|
|
59
|
+
const gen = plantuml.generate('@startuml\nA -> B: Hello\n@enduml', { format: 'png' })
|
|
60
|
+
gen.out.pipe(fs.createWriteStream('output.png'))
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Multiple Output Formats
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
// PNG (default)
|
|
67
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'png' })
|
|
68
|
+
|
|
69
|
+
// SVG (vector graphics)
|
|
70
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'svg' })
|
|
71
|
+
|
|
72
|
+
// EPS (PostScript)
|
|
73
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'eps' })
|
|
74
|
+
|
|
75
|
+
// ASCII text
|
|
76
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'ascii' })
|
|
77
|
+
|
|
78
|
+
// Unicode text
|
|
79
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'unicode' })
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Multi-language Support
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
// Full UTF-8 support for Chinese, Japanese, Korean, and other CJK languages
|
|
86
|
+
// Automatic font detection and configuration
|
|
87
|
+
const gen = plantuml.generate('@startuml\n用户 -> 系统: 登录\n@enduml', { format: 'png' })
|
|
88
|
+
gen.out.pipe(fs.createWriteStream('output.png'))
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 📚 API Documentation
|
|
94
|
+
|
|
95
|
+
### `plantuml.generate(input, options?)`
|
|
96
|
+
|
|
97
|
+
Generate a diagram from PlantUML source.
|
|
98
|
+
|
|
99
|
+
**Parameters:**
|
|
100
|
+
|
|
101
|
+
- `input`: `string | undefined` - PlantUML source code, file path, or undefined (for stdin)
|
|
102
|
+
- `options`: `object` (optional)
|
|
103
|
+
- `format`: `'png' | 'svg' | 'eps' | 'ascii' | 'unicode'` - Output format (default: `'png'`)
|
|
104
|
+
- `config`: `string` - Path to config file or template name (`'classic'`, `'monochrome'`)
|
|
105
|
+
- `dot`: `string` - Path to Graphviz dot executable
|
|
106
|
+
- `include`: `string` - Include path for PlantUML files
|
|
107
|
+
- `charset`: `string` - Character set (default: UTF-8)
|
|
108
|
+
- `autoFix`: `boolean` - Enable automatic syntax fixing and formatting (default: `false`)
|
|
109
|
+
- Automatically fixes common syntax errors like unquoted text with special characters
|
|
110
|
+
- Adds quotes around labels, class names, participant names, etc. that contain special characters
|
|
111
|
+
- Logs warnings to console when fixes are applied
|
|
112
|
+
- `warnOnFix`: `boolean` - Show console warnings when auto-fixes are applied (default: `true`)
|
|
113
|
+
- `normalizeWhitespace`: `boolean` - Normalize whitespace (remove trailing spaces, normalize blank lines) (default: `true` when autoFix is enabled)
|
|
114
|
+
|
|
115
|
+
**Returns:**
|
|
116
|
+
|
|
117
|
+
- `object` with:
|
|
118
|
+
- `in`: `stream.Writable` - Input stream (if no input provided)
|
|
119
|
+
- `out`: `stream.Readable` - Output stream (diagram data)
|
|
120
|
+
|
|
121
|
+
**Examples:**
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
// From file
|
|
125
|
+
const gen = plantuml.generate('diagram.puml', { format: 'svg' })
|
|
126
|
+
gen.out.pipe(fs.createWriteStream('diagram.svg'))
|
|
127
|
+
|
|
128
|
+
// From text
|
|
129
|
+
const gen = plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'png' })
|
|
130
|
+
gen.out.pipe(fs.createWriteStream('output.png'))
|
|
131
|
+
|
|
132
|
+
// From stdin
|
|
133
|
+
const gen = plantuml.generate({ format: 'png' })
|
|
134
|
+
process.stdin.pipe(gen.in)
|
|
135
|
+
gen.out.pipe(process.stdout)
|
|
136
|
+
|
|
137
|
+
// With automatic syntax fixing
|
|
138
|
+
const gen = plantuml.generate('@startuml\nA -> B: label with <special> chars\n@enduml', {
|
|
139
|
+
format: 'png',
|
|
140
|
+
autoFix: true // Automatically fixes unquoted text with special characters
|
|
141
|
+
})
|
|
142
|
+
gen.out.pipe(fs.createWriteStream('output.png'))
|
|
143
|
+
// Console will show: [PlantUML Syntax Fixer] Applied 1 fix(es): - Fixed unquoted arrow label
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `plantuml.encode(input, options?, callback?)`
|
|
147
|
+
|
|
148
|
+
Encode PlantUML source to URL-safe format.
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
plantuml.encode('@startuml\nA -> B\n@enduml', (err, encoded) => {
|
|
152
|
+
console.log(encoded) // URL-safe encoded string
|
|
153
|
+
})
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### `plantuml.decode(encoded, callback?)`
|
|
157
|
+
|
|
158
|
+
Decode URL-encoded PlantUML source.
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
const decode = plantuml.decode('SrJGjLDmibBmICt9oGS0')
|
|
162
|
+
decode.out.pipe(process.stdout)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### `plantuml.fixSyntax(code, options?, callback?)`
|
|
166
|
+
|
|
167
|
+
Standalone syntax fixing service. Checks if PlantUML code has syntax errors by attempting to render it, and if errors are detected, automatically fixes common syntax issues.
|
|
168
|
+
|
|
169
|
+
**Key Features:**
|
|
170
|
+
- ✅ **Safe by default** - Only fixes code if syntax errors are detected
|
|
171
|
+
- ✅ **Non-destructive** - Returns original code unchanged if no errors found
|
|
172
|
+
- ✅ **Automatic detection** - Uses actual rendering to detect real syntax errors
|
|
173
|
+
- ✅ **Comprehensive fixes** - Fixes unquoted text with special characters, missing quotes, etc.
|
|
174
|
+
|
|
175
|
+
**Parameters:**
|
|
176
|
+
- `code`: `string` - PlantUML source code to check and fix
|
|
177
|
+
- `options`: `object` (optional)
|
|
178
|
+
- `warnOnFix`: `boolean` - Show console warnings when fixes are applied (default: `true`)
|
|
179
|
+
- `normalizeWhitespace`: `boolean` - Normalize whitespace (default: `true`)
|
|
180
|
+
- `callback`: `Function` - Callback with `(error, fixedCode, wasFixed)`
|
|
181
|
+
- `error`: `Error | null` - Error if check failed
|
|
182
|
+
- `fixedCode`: `string` - Fixed code (or original if no errors)
|
|
183
|
+
- `wasFixed`: `boolean` - Whether code was actually fixed
|
|
184
|
+
|
|
185
|
+
**Examples:**
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
// Fix syntax errors automatically
|
|
189
|
+
plantuml.fixSyntax('@startuml\nA -> B: label with <special> chars\n@enduml', (err, fixed, wasFixed) => {
|
|
190
|
+
if (err) {
|
|
191
|
+
console.error('Error:', err)
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
if (wasFixed) {
|
|
195
|
+
console.log('Code was fixed:', fixed)
|
|
196
|
+
} else {
|
|
197
|
+
console.log('Code is valid, no changes needed')
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
// With options
|
|
202
|
+
plantuml.fixSyntax(code, {
|
|
203
|
+
warnOnFix: false, // Don't show warnings
|
|
204
|
+
normalizeWhitespace: true
|
|
205
|
+
}, (err, fixed, wasFixed) => {
|
|
206
|
+
// Use fixed code
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
// Valid code remains unchanged
|
|
210
|
+
plantuml.fixSyntax('@startuml\nA -> B\n@enduml', (err, fixed, wasFixed) => {
|
|
211
|
+
// wasFixed will be false, fixed === original code
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**How it works:**
|
|
216
|
+
1. Attempts to render the code as SVG
|
|
217
|
+
2. Checks for syntax errors in the output
|
|
218
|
+
3. If errors detected, applies automatic fixes
|
|
219
|
+
4. Verifies the fixed code works
|
|
220
|
+
5. Returns fixed code or original if no errors
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 🖥️ Command Line Interface
|
|
225
|
+
|
|
226
|
+
### Basic Commands
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Generate PNG from file
|
|
230
|
+
puml generate diagram.puml -o diagram.png
|
|
231
|
+
|
|
232
|
+
# Generate SVG
|
|
233
|
+
puml generate diagram.puml -s -o diagram.svg
|
|
234
|
+
|
|
235
|
+
# Generate ASCII text
|
|
236
|
+
puml generate diagram.puml -a
|
|
237
|
+
|
|
238
|
+
# Generate Unicode text
|
|
239
|
+
puml generate diagram.puml -u
|
|
240
|
+
|
|
241
|
+
# From stdin
|
|
242
|
+
cat diagram.puml | puml generate > output.png
|
|
243
|
+
|
|
244
|
+
# One-liner
|
|
245
|
+
puml generate --text "@startuml\nA -> B\n@enduml" -o output.png
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### All CLI Options
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
Usage: puml [options] [command]
|
|
252
|
+
|
|
253
|
+
Commands:
|
|
254
|
+
generate [options] [file] Generate an UML diagram from PlantUML source
|
|
255
|
+
encode [options] [file] Encodes PlantUML source
|
|
256
|
+
decode <url> Decodes PlantUML source
|
|
257
|
+
testdot Test the installation of Graphviz dot
|
|
258
|
+
|
|
259
|
+
Options:
|
|
260
|
+
-h, --help output usage information
|
|
261
|
+
-V, --version output the version number
|
|
262
|
+
|
|
263
|
+
Generate Options:
|
|
264
|
+
-p, --png output as PNG image (default)
|
|
265
|
+
-s, --svg output as SVG image
|
|
266
|
+
-e, --eps output as EPS image
|
|
267
|
+
-u, --unicode output as Unicode text
|
|
268
|
+
-a, --ascii output as ASCII text
|
|
269
|
+
-o, --output [file] output file path
|
|
270
|
+
-c, --config [file] config file or template (classic, monochrome)
|
|
271
|
+
-t, --text [text] PlantUML text to generate from
|
|
272
|
+
-d, --dot [file] Graphviz dot executable path
|
|
273
|
+
-i, --include [path] include path for PlantUML files
|
|
274
|
+
-C, --charset [charset] charset of PlantUML source
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## 🎨 Output Formats
|
|
280
|
+
|
|
281
|
+
### PNG (Default)
|
|
282
|
+
|
|
283
|
+
Raster image format, perfect for sharing and embedding.
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'png' })
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### SVG
|
|
290
|
+
|
|
291
|
+
Vector graphics format, scalable and perfect for web.
|
|
292
|
+
|
|
293
|
+
```javascript
|
|
294
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'svg' })
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### EPS
|
|
298
|
+
|
|
299
|
+
PostScript format, ideal for print and LaTeX documents.
|
|
300
|
+
|
|
301
|
+
```javascript
|
|
302
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'eps' })
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### ASCII Text
|
|
306
|
+
|
|
307
|
+
Plain ASCII text representation.
|
|
308
|
+
|
|
309
|
+
```javascript
|
|
310
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'ascii' })
|
|
311
|
+
// Output:
|
|
312
|
+
// +---+ +---+
|
|
313
|
+
// | A | --> | B |
|
|
314
|
+
// +---+ +---+
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Unicode Text
|
|
318
|
+
|
|
319
|
+
Unicode text with box-drawing characters.
|
|
320
|
+
|
|
321
|
+
```javascript
|
|
322
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'unicode' })
|
|
323
|
+
// Output:
|
|
324
|
+
// ┌───┐ ┌───┐
|
|
325
|
+
// │ A │ ──> │ B │
|
|
326
|
+
// └───┘ └───┘
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 🌏 Multi-language & UTF-8 Support
|
|
332
|
+
|
|
333
|
+
Full UTF-8 support with automatic font configuration for multiple languages. The library automatically detects and configures appropriate fonts for:
|
|
334
|
+
|
|
335
|
+
- **Chinese (中文)** - Simplified and Traditional
|
|
336
|
+
- **Japanese (日本語)** - Hiragana, Katakana, Kanji
|
|
337
|
+
- **Korean (한국어)** - Hangul characters
|
|
338
|
+
- **Other CJK languages** - With fallback to system fonts
|
|
339
|
+
|
|
340
|
+
**Automatic Font Selection:**
|
|
341
|
+
- Windows: Microsoft YaHei (Chinese/Japanese), Malgun Gothic (Korean)
|
|
342
|
+
- macOS: PingFang SC (Chinese/Japanese), AppleGothic (Korean)
|
|
343
|
+
- Linux: Noto Sans CJK SC (all CJK languages)
|
|
344
|
+
|
|
345
|
+
**Examples:**
|
|
346
|
+
|
|
347
|
+
```javascript
|
|
348
|
+
// Chinese
|
|
349
|
+
const gen = plantuml.generate(`
|
|
350
|
+
@startuml
|
|
351
|
+
用户 -> 系统: 发送请求
|
|
352
|
+
系统 -> 数据库: 查询数据
|
|
353
|
+
数据库 --> 系统: 返回结果
|
|
354
|
+
系统 --> 用户: 响应数据
|
|
355
|
+
@enduml
|
|
356
|
+
`, { format: 'png' })
|
|
357
|
+
|
|
358
|
+
// Japanese
|
|
359
|
+
const gen2 = plantuml.generate(`
|
|
360
|
+
@startuml
|
|
361
|
+
ユーザー -> システム: リクエスト送信
|
|
362
|
+
システム -> データベース: データ照会
|
|
363
|
+
@enduml
|
|
364
|
+
`, { format: 'png' })
|
|
365
|
+
|
|
366
|
+
// Korean
|
|
367
|
+
const gen3 = plantuml.generate(`
|
|
368
|
+
@startuml
|
|
369
|
+
사용자 -> 시스템: 요청 전송
|
|
370
|
+
시스템 -> 데이터베이스: 데이터 조회
|
|
371
|
+
@enduml
|
|
372
|
+
`, { format: 'png' })
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
The font configuration is automatically added when CJK characters are detected in your PlantUML code.
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## ⚙️ Advanced Usage
|
|
380
|
+
|
|
381
|
+
### Using Config Templates
|
|
382
|
+
|
|
383
|
+
```javascript
|
|
384
|
+
// Classic black and white style
|
|
385
|
+
plantuml.generate('diagram.puml', {
|
|
386
|
+
format: 'png',
|
|
387
|
+
config: 'classic'
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
// Monochrome style
|
|
391
|
+
plantuml.generate('diagram.puml', {
|
|
392
|
+
format: 'png',
|
|
393
|
+
config: 'monochrome'
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
// Custom config file
|
|
397
|
+
plantuml.generate('diagram.puml', {
|
|
398
|
+
format: 'png',
|
|
399
|
+
config: './my-config.puml'
|
|
400
|
+
})
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Web Server Example
|
|
404
|
+
|
|
405
|
+
```javascript
|
|
406
|
+
const express = require('express')
|
|
407
|
+
const plantuml = require('node-plantuml-2')
|
|
408
|
+
|
|
409
|
+
const app = express()
|
|
410
|
+
|
|
411
|
+
app.get('/png/:uml', (req, res) => {
|
|
412
|
+
res.set('Content-Type', 'image/png')
|
|
413
|
+
const decode = plantuml.decode(req.params.uml)
|
|
414
|
+
const gen = plantuml.generate({ format: 'png' })
|
|
415
|
+
decode.out.pipe(gen.in)
|
|
416
|
+
gen.out.pipe(res)
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
app.get('/svg/:uml', (req, res) => {
|
|
420
|
+
res.set('Content-Type', 'image/svg+xml')
|
|
421
|
+
const decode = plantuml.decode(req.params.uml)
|
|
422
|
+
const gen = plantuml.generate({ format: 'svg' })
|
|
423
|
+
decode.out.pipe(gen.in)
|
|
424
|
+
gen.out.pipe(res)
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
app.listen(8080)
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Force Java Executor (Optional)
|
|
431
|
+
|
|
432
|
+
If you prefer to use Java executor (requires Java installed):
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
PLANTUML_USE_JAVA=true node your-script.js
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## 🏗️ Architecture
|
|
441
|
+
|
|
442
|
+
This project uses a **hybrid execution model**:
|
|
443
|
+
|
|
444
|
+
1. **Primary: WebAssembly Executor** (Pure Node.js)
|
|
445
|
+
- Pre-compiled Wasm module included in npm package
|
|
446
|
+
- Fast startup, low memory footprint
|
|
447
|
+
- No Java required
|
|
448
|
+
|
|
449
|
+
2. **Fallback: Java Executor** (Optional)
|
|
450
|
+
- Automatic fallback if Wasm unavailable
|
|
451
|
+
- Requires Java runtime
|
|
452
|
+
- Full compatibility with original node-plantuml
|
|
453
|
+
|
|
454
|
+
### Execution Flow
|
|
455
|
+
|
|
456
|
+
```
|
|
457
|
+
User Code
|
|
458
|
+
↓
|
|
459
|
+
plantuml.generate()
|
|
460
|
+
↓
|
|
461
|
+
Check Wasm Availability
|
|
462
|
+
├─ Available → Use Wasm Executor ✅ (Pure Node)
|
|
463
|
+
└─ Unavailable → Use Java Executor (Fallback)
|
|
464
|
+
↓
|
|
465
|
+
Generate Diagram
|
|
466
|
+
↓
|
|
467
|
+
Return Stream
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## 📋 System Requirements
|
|
473
|
+
|
|
474
|
+
- **Node.js 12+** (recommended 20+ for stable WASI support)
|
|
475
|
+
- **No Java required** ✅ (Wasm executor works out of the box)
|
|
476
|
+
- **Graphviz** (optional, for advanced diagram types)
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## 🧪 Testing
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
# Run all tests
|
|
484
|
+
npm test
|
|
485
|
+
|
|
486
|
+
# Batch conversion test
|
|
487
|
+
npm run test:batch
|
|
488
|
+
|
|
489
|
+
# Test specific format
|
|
490
|
+
npm run test:batch:svg
|
|
491
|
+
npm run test:batch:png
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
## 📝 Changelog
|
|
497
|
+
|
|
498
|
+
### v0.9.0
|
|
499
|
+
|
|
500
|
+
- ✨ **Pure Node.js Support** - WebAssembly-based execution, no Java required
|
|
501
|
+
- 🌏 **Multi-language Support** - Perfect rendering for Chinese, Japanese, Korean with automatic font detection
|
|
502
|
+
- 📦 **Auto-update** - Automatic PlantUML JAR updates from GitHub Releases
|
|
503
|
+
- 🎨 **Multiple Formats** - PNG, SVG, EPS, ASCII, Unicode support
|
|
504
|
+
- 🔄 **Smart Fallback** - Automatic fallback to Java if Wasm unavailable
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## 🤝 Contributing
|
|
509
|
+
|
|
510
|
+
Contributions are welcome! Please feel free to submit issues and pull requests.
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## 📄 License
|
|
515
|
+
|
|
516
|
+
MIT License
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## 🙏 Acknowledgments
|
|
521
|
+
|
|
522
|
+
This project is based on:
|
|
523
|
+
|
|
524
|
+
- **[PlantUML](http://plantuml.sourceforge.net/)** - The powerful diagramming tool
|
|
525
|
+
- **[node-plantuml](https://github.com/markushedvall/node-plantuml)** - Original Node.js wrapper by Markus Hedvall
|
|
526
|
+
- **[Bytecoder](https://github.com/mirkosertic/Bytecoder)** - Java to WebAssembly compiler
|
|
527
|
+
|
|
528
|
+
Special thanks to the PlantUML community and all contributors!
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
**Made with ❤️ for developers who need PlantUML in pure Node.js**
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
<a name="中文"></a>
|
|
537
|
+
|
|
538
|
+
<div align="center">
|
|
539
|
+
|
|
540
|
+
**[English](#english) | [中文](#中文)**
|
|
541
|
+
|
|
542
|
+
</div>
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
# node-plantuml-2
|
|
547
|
+
|
|
548
|
+
> **纯 Node.js PlantUML 渲染器 - 无需 Java!**
|
|
549
|
+
|
|
550
|
+
[](https://www.npmjs.com/package/node-plantuml-2)
|
|
551
|
+
[](LICENSE)
|
|
552
|
+
[](https://nodejs.org/)
|
|
553
|
+
|
|
554
|
+
一个强大的 Node.js 模块和 CLI,用于运行 [PlantUML](http://plantuml.sourceforge.net/),支持**纯 Node.js 环境**。本项目基于 [node-plantuml](https://github.com/markushedvall/node-plantuml) Fork 并增强,采用 WebAssembly 执行,无需 Java 运行时。
|
|
555
|
+
|
|
556
|
+
## ✨ 核心特性
|
|
557
|
+
|
|
558
|
+
- 🚀 **纯 Node.js 环境** - 无需安装 Java!使用预编译的 WebAssembly 模块
|
|
559
|
+
- 📦 **零配置** - 只需 `npm install` 即可使用
|
|
560
|
+
- 🎨 **多种输出格式** - 支持 PNG、SVG、EPS、ASCII 和 Unicode 文本
|
|
561
|
+
- 🌏 **多语言支持** - 完美支持中文、日文、韩文等多种 CJK 字符渲染,自动字体检测和配置
|
|
562
|
+
- ⚡ **快速启动** - WebAssembly 执行比 JVM 更快
|
|
563
|
+
- 🔄 **自动降级** - Wasm 不可用时自动降级到 Java 执行器
|
|
564
|
+
- 📝 **CLI 和 API** - 同时提供命令行界面和编程 API
|
|
565
|
+
- 🎯 **基于 PlantUML** - 完全兼容 PlantUML 语法
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## 📦 安装
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
npm install node-plantuml-2
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
**就这么简单!** 无需 Java,无需配置,无需构建步骤。
|
|
576
|
+
|
|
577
|
+
全局安装 CLI:
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
npm install node-plantuml-2 -g
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
## 🚀 快速开始
|
|
586
|
+
|
|
587
|
+
### 基础用法
|
|
588
|
+
|
|
589
|
+
```javascript
|
|
590
|
+
const plantuml = require('node-plantuml-2')
|
|
591
|
+
const fs = require('fs')
|
|
592
|
+
|
|
593
|
+
// 生成 PNG 图表
|
|
594
|
+
const gen = plantuml.generate('@startuml\nA -> B: Hello\n@enduml', { format: 'png' })
|
|
595
|
+
gen.out.pipe(fs.createWriteStream('output.png'))
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### 多种输出格式
|
|
599
|
+
|
|
600
|
+
```javascript
|
|
601
|
+
// PNG(默认)
|
|
602
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'png' })
|
|
603
|
+
|
|
604
|
+
// SVG(矢量图形)
|
|
605
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'svg' })
|
|
606
|
+
|
|
607
|
+
// EPS(PostScript)
|
|
608
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'eps' })
|
|
609
|
+
|
|
610
|
+
// ASCII 文本
|
|
611
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'ascii' })
|
|
612
|
+
|
|
613
|
+
// Unicode 文本
|
|
614
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'unicode' })
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### 多语言支持
|
|
618
|
+
|
|
619
|
+
```javascript
|
|
620
|
+
// 完整 UTF-8 支持,支持中文、日文、韩文等多种 CJK 语言
|
|
621
|
+
// 自动字体检测和配置
|
|
622
|
+
const gen = plantuml.generate('@startuml\n用户 -> 系统: 登录\n@enduml', { format: 'png' })
|
|
623
|
+
gen.out.pipe(fs.createWriteStream('output.png'))
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
## 📚 API 文档
|
|
629
|
+
|
|
630
|
+
### `plantuml.generate(input, options?)`
|
|
631
|
+
|
|
632
|
+
从 PlantUML 源码生成图表。
|
|
633
|
+
|
|
634
|
+
**参数:**
|
|
635
|
+
|
|
636
|
+
- `input`: `string | undefined` - PlantUML 源码、文件路径或 undefined(用于 stdin)
|
|
637
|
+
- `options`: `object` (可选)
|
|
638
|
+
- `format`: `'png' | 'svg' | 'eps' | 'ascii' | 'unicode'` - 输出格式(默认:`'png'`)
|
|
639
|
+
- `config`: `string` - 配置文件路径或模板名称(`'classic'`, `'monochrome'`)
|
|
640
|
+
- `dot`: `string` - Graphviz dot 可执行文件路径
|
|
641
|
+
- `include`: `string` - PlantUML 文件的包含路径
|
|
642
|
+
- `charset`: `string` - 字符集(默认:UTF-8)
|
|
643
|
+
|
|
644
|
+
**返回值:**
|
|
645
|
+
|
|
646
|
+
- `object` 包含:
|
|
647
|
+
- `in`: `stream.Writable` - 输入流(如果未提供输入)
|
|
648
|
+
- `out`: `stream.Readable` - 输出流(图表数据)
|
|
649
|
+
|
|
650
|
+
**示例:**
|
|
651
|
+
|
|
652
|
+
```javascript
|
|
653
|
+
// 从文件
|
|
654
|
+
const gen = plantuml.generate('diagram.puml', { format: 'svg' })
|
|
655
|
+
gen.out.pipe(fs.createWriteStream('diagram.svg'))
|
|
656
|
+
|
|
657
|
+
// 从文本
|
|
658
|
+
const gen = plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'png' })
|
|
659
|
+
gen.out.pipe(fs.createWriteStream('output.png'))
|
|
660
|
+
|
|
661
|
+
// 从标准输入
|
|
662
|
+
const gen = plantuml.generate({ format: 'png' })
|
|
663
|
+
process.stdin.pipe(gen.in)
|
|
664
|
+
gen.out.pipe(process.stdout)
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
### `plantuml.encode(input, options?, callback?)`
|
|
668
|
+
|
|
669
|
+
将 PlantUML 源码编码为 URL 安全格式。
|
|
670
|
+
|
|
671
|
+
```javascript
|
|
672
|
+
plantuml.encode('@startuml\nA -> B\n@enduml', (err, encoded) => {
|
|
673
|
+
console.log(encoded) // URL 安全编码字符串
|
|
674
|
+
})
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
### `plantuml.decode(encoded, callback?)`
|
|
678
|
+
|
|
679
|
+
解码 URL 编码的 PlantUML 源码。
|
|
680
|
+
|
|
681
|
+
```javascript
|
|
682
|
+
const decode = plantuml.decode('SrJGjLDmibBmICt9oGS0')
|
|
683
|
+
decode.out.pipe(process.stdout)
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
### `plantuml.fixSyntax(code, options?, callback?)`
|
|
687
|
+
|
|
688
|
+
独立的语法修复服务。通过实际渲染来检测 PlantUML 代码是否有语法错误,如果检测到错误,则自动修复常见的语法问题。
|
|
689
|
+
|
|
690
|
+
**核心特性:**
|
|
691
|
+
- ✅ **默认安全** - 仅在检测到语法错误时才修复
|
|
692
|
+
- ✅ **非破坏性** - 如果没有错误,返回原始代码不变
|
|
693
|
+
- ✅ **自动检测** - 使用实际渲染来检测真正的语法错误
|
|
694
|
+
- ✅ **全面修复** - 修复包含特殊字符的未加引号文本、缺少引号等问题
|
|
695
|
+
|
|
696
|
+
**参数:**
|
|
697
|
+
- `code`: `string` - 要检查和修复的 PlantUML 源码
|
|
698
|
+
- `options`: `object` (可选)
|
|
699
|
+
- `warnOnFix`: `boolean` - 应用修复时显示控制台警告(默认:`true`)
|
|
700
|
+
- `normalizeWhitespace`: `boolean` - 规范化空白字符(默认:`true`)
|
|
701
|
+
- `callback`: `Function` - 回调函数 `(error, fixedCode, wasFixed)`
|
|
702
|
+
- `error`: `Error | null` - 检查失败时的错误
|
|
703
|
+
- `fixedCode`: `string` - 修复后的代码(如果没有错误则返回原始代码)
|
|
704
|
+
- `wasFixed`: `boolean` - 代码是否实际被修复
|
|
705
|
+
|
|
706
|
+
**示例:**
|
|
707
|
+
|
|
708
|
+
```javascript
|
|
709
|
+
// 自动修复语法错误
|
|
710
|
+
plantuml.fixSyntax('@startuml\nA -> B: label with <special> chars\n@enduml', (err, fixed, wasFixed) => {
|
|
711
|
+
if (err) {
|
|
712
|
+
console.error('错误:', err)
|
|
713
|
+
return
|
|
714
|
+
}
|
|
715
|
+
if (wasFixed) {
|
|
716
|
+
console.log('代码已修复:', fixed)
|
|
717
|
+
} else {
|
|
718
|
+
console.log('代码有效,无需更改')
|
|
719
|
+
}
|
|
720
|
+
})
|
|
721
|
+
|
|
722
|
+
// 带选项
|
|
723
|
+
plantuml.fixSyntax(code, {
|
|
724
|
+
warnOnFix: false, // 不显示警告
|
|
725
|
+
normalizeWhitespace: true
|
|
726
|
+
}, (err, fixed, wasFixed) => {
|
|
727
|
+
// 使用修复后的代码
|
|
728
|
+
})
|
|
729
|
+
|
|
730
|
+
// 有效代码保持不变
|
|
731
|
+
plantuml.fixSyntax('@startuml\nA -> B\n@enduml', (err, fixed, wasFixed) => {
|
|
732
|
+
// wasFixed 将为 false,fixed === 原始代码
|
|
733
|
+
})
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
**工作原理:**
|
|
737
|
+
1. 尝试将代码渲染为 SVG
|
|
738
|
+
2. 检查输出中的语法错误
|
|
739
|
+
3. 如果检测到错误,应用自动修复
|
|
740
|
+
4. 验证修复后的代码是否有效
|
|
741
|
+
5. 返回修复后的代码,如果没有错误则返回原始代码
|
|
742
|
+
|
|
743
|
+
---
|
|
744
|
+
|
|
745
|
+
## 🖥️ 命令行界面
|
|
746
|
+
|
|
747
|
+
### 基础命令
|
|
748
|
+
|
|
749
|
+
```bash
|
|
750
|
+
# 从文件生成 PNG
|
|
751
|
+
puml generate diagram.puml -o diagram.png
|
|
752
|
+
|
|
753
|
+
# 生成 SVG
|
|
754
|
+
puml generate diagram.puml -s -o diagram.svg
|
|
755
|
+
|
|
756
|
+
# 生成 ASCII 文本
|
|
757
|
+
puml generate diagram.puml -a
|
|
758
|
+
|
|
759
|
+
# 生成 Unicode 文本
|
|
760
|
+
puml generate diagram.puml -u
|
|
761
|
+
|
|
762
|
+
# 从标准输入
|
|
763
|
+
cat diagram.puml | puml generate > output.png
|
|
764
|
+
|
|
765
|
+
# 一行命令
|
|
766
|
+
puml generate --text "@startuml\nA -> B\n@enduml" -o output.png
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
### 所有 CLI 选项
|
|
770
|
+
|
|
771
|
+
```bash
|
|
772
|
+
用法: puml [选项] [命令]
|
|
773
|
+
|
|
774
|
+
命令:
|
|
775
|
+
generate [选项] [文件] 从 PlantUML 源码生成 UML 图表
|
|
776
|
+
encode [选项] [文件] 编码 PlantUML 源码
|
|
777
|
+
decode <url> 解码 PlantUML 源码
|
|
778
|
+
testdot 测试 Graphviz dot 安装
|
|
779
|
+
|
|
780
|
+
选项:
|
|
781
|
+
-h, --help 显示帮助信息
|
|
782
|
+
-V, --version 显示版本号
|
|
783
|
+
|
|
784
|
+
生成选项:
|
|
785
|
+
-p, --png 输出为 PNG 图片(默认)
|
|
786
|
+
-s, --svg 输出为 SVG 图片
|
|
787
|
+
-e, --eps 输出为 EPS 图片
|
|
788
|
+
-u, --unicode 输出为 Unicode 文本
|
|
789
|
+
-a, --ascii 输出为 ASCII 文本
|
|
790
|
+
-o, --output [文件] 输出文件路径
|
|
791
|
+
-c, --config [文件] 配置文件或模板(classic, monochrome)
|
|
792
|
+
-t, --text [文本] 要生成的 PlantUML 文本
|
|
793
|
+
-d, --dot [文件] Graphviz dot 可执行文件路径
|
|
794
|
+
-i, --include [路径] PlantUML 文件的包含路径
|
|
795
|
+
-C, --charset [字符集] PlantUML 源码的字符集
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
---
|
|
799
|
+
|
|
800
|
+
## 🎨 输出格式
|
|
801
|
+
|
|
802
|
+
### PNG(默认)
|
|
803
|
+
|
|
804
|
+
位图格式,适合分享和嵌入。
|
|
805
|
+
|
|
806
|
+
```javascript
|
|
807
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'png' })
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
### SVG
|
|
811
|
+
|
|
812
|
+
矢量图形格式,可缩放,适合网页使用。
|
|
813
|
+
|
|
814
|
+
```javascript
|
|
815
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'svg' })
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
### EPS
|
|
819
|
+
|
|
820
|
+
PostScript 格式,适合打印和 LaTeX 文档。
|
|
821
|
+
|
|
822
|
+
```javascript
|
|
823
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'eps' })
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### ASCII 文本
|
|
827
|
+
|
|
828
|
+
纯 ASCII 文本表示。
|
|
829
|
+
|
|
830
|
+
```javascript
|
|
831
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'ascii' })
|
|
832
|
+
// 输出:
|
|
833
|
+
// +---+ +---+
|
|
834
|
+
// | A | --> | B |
|
|
835
|
+
// +---+ +---+
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
### Unicode 文本
|
|
839
|
+
|
|
840
|
+
使用框线字符的 Unicode 文本。
|
|
841
|
+
|
|
842
|
+
```javascript
|
|
843
|
+
plantuml.generate('@startuml\nA -> B\n@enduml', { format: 'unicode' })
|
|
844
|
+
// 输出:
|
|
845
|
+
// ┌───┐ ┌───┐
|
|
846
|
+
// │ A │ ──> │ B │
|
|
847
|
+
// └───┘ └───┘
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
## 🌏 多语言和 UTF-8 支持
|
|
853
|
+
|
|
854
|
+
完整 UTF-8 支持,自动为多种语言配置合适的字体。库会自动检测并配置以下语言的字体:
|
|
855
|
+
|
|
856
|
+
- **中文** - 简体中文和繁体中文
|
|
857
|
+
- **日文(日本語)** - 平假名、片假名、汉字
|
|
858
|
+
- **韩文(한국어)** - 韩文字符
|
|
859
|
+
- **其他 CJK 语言** - 使用系统字体作为后备方案
|
|
860
|
+
|
|
861
|
+
**自动字体选择:**
|
|
862
|
+
- Windows: Microsoft YaHei(中文/日文)、Malgun Gothic(韩文)
|
|
863
|
+
- macOS: PingFang SC(中文/日文)、AppleGothic(韩文)
|
|
864
|
+
- Linux: Noto Sans CJK SC(所有 CJK 语言)
|
|
865
|
+
|
|
866
|
+
**示例:**
|
|
867
|
+
|
|
868
|
+
```javascript
|
|
869
|
+
// 中文
|
|
870
|
+
const gen = plantuml.generate(`
|
|
871
|
+
@startuml
|
|
872
|
+
用户 -> 系统: 发送请求
|
|
873
|
+
系统 -> 数据库: 查询数据
|
|
874
|
+
数据库 --> 系统: 返回结果
|
|
875
|
+
系统 --> 用户: 响应数据
|
|
876
|
+
@enduml
|
|
877
|
+
`, { format: 'png' })
|
|
878
|
+
|
|
879
|
+
// 日文
|
|
880
|
+
const gen2 = plantuml.generate(`
|
|
881
|
+
@startuml
|
|
882
|
+
ユーザー -> システム: リクエスト送信
|
|
883
|
+
システム -> データベース: データ照会
|
|
884
|
+
@enduml
|
|
885
|
+
`, { format: 'png' })
|
|
886
|
+
|
|
887
|
+
// 韩文
|
|
888
|
+
const gen3 = plantuml.generate(`
|
|
889
|
+
@startuml
|
|
890
|
+
사용자 -> 시스템: 요청 전송
|
|
891
|
+
시스템 -> 데이터베이스: 데이터 조회
|
|
892
|
+
@enduml
|
|
893
|
+
`, { format: 'png' })
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
当检测到 PlantUML 代码中包含 CJK 字符时,会自动添加字体配置。
|
|
897
|
+
|
|
898
|
+
---
|
|
899
|
+
|
|
900
|
+
## ⚙️ 高级用法
|
|
901
|
+
|
|
902
|
+
### 使用配置模板
|
|
903
|
+
|
|
904
|
+
```javascript
|
|
905
|
+
// 经典黑白风格
|
|
906
|
+
plantuml.generate('diagram.puml', {
|
|
907
|
+
format: 'png',
|
|
908
|
+
config: 'classic'
|
|
909
|
+
})
|
|
910
|
+
|
|
911
|
+
// 单色风格
|
|
912
|
+
plantuml.generate('diagram.puml', {
|
|
913
|
+
format: 'png',
|
|
914
|
+
config: 'monochrome'
|
|
915
|
+
})
|
|
916
|
+
|
|
917
|
+
// 自定义配置文件
|
|
918
|
+
plantuml.generate('diagram.puml', {
|
|
919
|
+
format: 'png',
|
|
920
|
+
config: './my-config.puml'
|
|
921
|
+
})
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
### Web 服务器示例
|
|
925
|
+
|
|
926
|
+
```javascript
|
|
927
|
+
const express = require('express')
|
|
928
|
+
const plantuml = require('node-plantuml-2')
|
|
929
|
+
|
|
930
|
+
const app = express()
|
|
931
|
+
|
|
932
|
+
app.get('/png/:uml', (req, res) => {
|
|
933
|
+
res.set('Content-Type', 'image/png')
|
|
934
|
+
const decode = plantuml.decode(req.params.uml)
|
|
935
|
+
const gen = plantuml.generate({ format: 'png' })
|
|
936
|
+
decode.out.pipe(gen.in)
|
|
937
|
+
gen.out.pipe(res)
|
|
938
|
+
})
|
|
939
|
+
|
|
940
|
+
app.get('/svg/:uml', (req, res) => {
|
|
941
|
+
res.set('Content-Type', 'image/svg+xml')
|
|
942
|
+
const decode = plantuml.decode(req.params.uml)
|
|
943
|
+
const gen = plantuml.generate({ format: 'svg' })
|
|
944
|
+
decode.out.pipe(gen.in)
|
|
945
|
+
gen.out.pipe(res)
|
|
946
|
+
})
|
|
947
|
+
|
|
948
|
+
app.listen(8080)
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
### 强制使用 Java 执行器(可选)
|
|
952
|
+
|
|
953
|
+
如果希望使用 Java 执行器(需要安装 Java):
|
|
954
|
+
|
|
955
|
+
```bash
|
|
956
|
+
PLANTUML_USE_JAVA=true node your-script.js
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
---
|
|
960
|
+
|
|
961
|
+
## 🏗️ 架构
|
|
962
|
+
|
|
963
|
+
本项目采用**混合执行模型**:
|
|
964
|
+
|
|
965
|
+
1. **主要:WebAssembly 执行器**(纯 Node.js)
|
|
966
|
+
- npm 包中包含预编译的 Wasm 模块
|
|
967
|
+
- 快速启动,低内存占用
|
|
968
|
+
- 无需 Java
|
|
969
|
+
|
|
970
|
+
2. **降级:Java 执行器**(可选)
|
|
971
|
+
- Wasm 不可用时自动降级
|
|
972
|
+
- 需要 Java 运行时
|
|
973
|
+
- 与原始 node-plantuml 完全兼容
|
|
974
|
+
|
|
975
|
+
### 执行流程
|
|
976
|
+
|
|
977
|
+
```
|
|
978
|
+
用户代码
|
|
979
|
+
↓
|
|
980
|
+
plantuml.generate()
|
|
981
|
+
↓
|
|
982
|
+
检查 Wasm 可用性
|
|
983
|
+
├─ 可用 → 使用 Wasm 执行器 ✅ (纯 Node)
|
|
984
|
+
└─ 不可用 → 使用 Java 执行器 (降级)
|
|
985
|
+
↓
|
|
986
|
+
生成图表
|
|
987
|
+
↓
|
|
988
|
+
返回流
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
---
|
|
992
|
+
|
|
993
|
+
## 📋 系统要求
|
|
994
|
+
|
|
995
|
+
- **Node.js 12+**(推荐 20+ 以获得稳定的 WASI 支持)
|
|
996
|
+
- **无需 Java** ✅(Wasm 执行器开箱即用)
|
|
997
|
+
- **Graphviz**(可选,用于高级图表类型)
|
|
998
|
+
|
|
999
|
+
---
|
|
1000
|
+
|
|
1001
|
+
## 🧪 测试
|
|
1002
|
+
|
|
1003
|
+
```bash
|
|
1004
|
+
# 运行所有测试
|
|
1005
|
+
npm test
|
|
1006
|
+
|
|
1007
|
+
# 批量转换测试
|
|
1008
|
+
npm run test:batch
|
|
1009
|
+
|
|
1010
|
+
# 测试特定格式
|
|
1011
|
+
npm run test:batch:svg
|
|
1012
|
+
npm run test:batch:png
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
---
|
|
1016
|
+
|
|
1017
|
+
## 📝 更新日志
|
|
1018
|
+
|
|
1019
|
+
### v0.9.0
|
|
1020
|
+
|
|
1021
|
+
- ✨ **纯 Node.js 支持** - 基于 WebAssembly 的执行,无需 Java
|
|
1022
|
+
- 🌏 **多语言支持** - 完美支持中文、日文、韩文等多种语言,自动字体检测
|
|
1023
|
+
- 📦 **自动更新** - 从 GitHub Releases 自动更新 PlantUML JAR
|
|
1024
|
+
- 🎨 **多种格式** - PNG、SVG、EPS、ASCII、Unicode 支持
|
|
1025
|
+
- 🔄 **智能降级** - Wasm 不可用时自动降级到 Java
|
|
1026
|
+
|
|
1027
|
+
---
|
|
1028
|
+
|
|
1029
|
+
## 🤝 贡献
|
|
1030
|
+
|
|
1031
|
+
欢迎贡献!请随时提交 Issue 和 Pull Request。
|
|
1032
|
+
|
|
1033
|
+
---
|
|
1034
|
+
|
|
1035
|
+
## 📄 许可证
|
|
1036
|
+
|
|
1037
|
+
MIT License
|
|
1038
|
+
|
|
1039
|
+
---
|
|
1040
|
+
|
|
1041
|
+
## 🙏 致谢
|
|
1042
|
+
|
|
1043
|
+
本项目基于:
|
|
1044
|
+
|
|
1045
|
+
- **[PlantUML](http://plantuml.sourceforge.net/)** - 强大的图表工具
|
|
1046
|
+
- **[node-plantuml](https://github.com/markushedvall/node-plantuml)** - Markus Hedvall 的原始 Node.js 包装器
|
|
1047
|
+
- **[Bytecoder](https://github.com/mirkosertic/Bytecoder)** - Java 到 WebAssembly 编译器
|
|
1048
|
+
|
|
1049
|
+
特别感谢 PlantUML 社区和所有贡献者!
|
|
1050
|
+
|
|
1051
|
+
---
|
|
1052
|
+
|
|
1053
|
+
**Made with ❤️ for developers who need PlantUML in pure Node.js**
|