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/README.md ADDED
@@ -0,0 +1,1053 @@
1
+ # node-plantuml-2
2
+
3
+ > **Pure Node.js PlantUML Renderer - No Java Required!**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/node-plantuml-2)](https://www.npmjs.com/package/node-plantuml-2)
6
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D12-green.svg)](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
+ [![npm version](https://img.shields.io/npm/v/node-plantuml-2)](https://www.npmjs.com/package/node-plantuml-2)
551
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
552
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D12-green.svg)](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**