@diagrammo/dgmo 0.1.0 → 0.1.2
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 +41 -0
- package/dist/cli.cjs +87 -30
- package/package.json +3 -2
- package/src/cli.ts +102 -35
package/README.md
CHANGED
|
@@ -6,12 +6,53 @@ Write simple, readable `.dgmo` text files and render them as charts, diagrams, a
|
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
|
+
### As a library
|
|
10
|
+
|
|
9
11
|
```bash
|
|
10
12
|
npm install @diagrammo/dgmo
|
|
11
13
|
# or
|
|
12
14
|
pnpm add @diagrammo/dgmo
|
|
13
15
|
```
|
|
14
16
|
|
|
17
|
+
### As a CLI
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# via Homebrew (macOS)
|
|
21
|
+
brew tap diagrammo/dgmo
|
|
22
|
+
brew install dgmo
|
|
23
|
+
|
|
24
|
+
# or run directly via npx
|
|
25
|
+
npx @diagrammo/dgmo diagram.dgmo
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## CLI usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# First time with no args? Creates a sample.dgmo to get you started
|
|
32
|
+
dgmo
|
|
33
|
+
|
|
34
|
+
# Render to PNG (default)
|
|
35
|
+
dgmo diagram.dgmo # → diagram.png
|
|
36
|
+
|
|
37
|
+
# Render to SVG
|
|
38
|
+
dgmo diagram.dgmo -o output.svg
|
|
39
|
+
|
|
40
|
+
# Explicit PNG
|
|
41
|
+
dgmo diagram.dgmo -o output.png
|
|
42
|
+
|
|
43
|
+
# Pipe from stdin
|
|
44
|
+
cat diagram.dgmo | dgmo -o out.png
|
|
45
|
+
cat diagram.dgmo | dgmo > out.png # PNG to stdout
|
|
46
|
+
|
|
47
|
+
# With theme and palette options
|
|
48
|
+
dgmo diagram.dgmo --theme dark --palette catppuccin
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Option | Values | Default |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `--theme` | `light`, `dark`, `transparent` | `light` |
|
|
54
|
+
| `--palette` | `nord`, `solarized`, `catppuccin`, `rose-pine`, `gruvbox`, `tokyo-night`, `one-dark`, `bold` | `nord` |
|
|
55
|
+
|
|
15
56
|
## How it works
|
|
16
57
|
|
|
17
58
|
Every `.dgmo` file is plain text with a `chart: <type>` header followed by metadata and data. The library routes each chart type to the right framework and gives you either:
|
package/dist/cli.cjs
CHANGED
|
@@ -2459,6 +2459,7 @@ var init_renderer = __esm({
|
|
|
2459
2459
|
var import_node_fs = require("fs");
|
|
2460
2460
|
var import_node_path = require("path");
|
|
2461
2461
|
var import_jsdom = require("jsdom");
|
|
2462
|
+
var import_resvg_js = require("@resvg/resvg-js");
|
|
2462
2463
|
|
|
2463
2464
|
// src/d3.ts
|
|
2464
2465
|
var d3Scale = __toESM(require("d3-scale"), 1);
|
|
@@ -5056,13 +5057,15 @@ var PALETTES = [
|
|
|
5056
5057
|
];
|
|
5057
5058
|
var THEMES = ["light", "dark", "transparent"];
|
|
5058
5059
|
function printHelp() {
|
|
5059
|
-
console.log(`Usage: dgmo
|
|
5060
|
+
console.log(`Usage: dgmo <input> [options]
|
|
5061
|
+
cat input.dgmo | dgmo [options]
|
|
5060
5062
|
|
|
5061
|
-
|
|
5062
|
-
render <input> Render a .dgmo file to SVG
|
|
5063
|
+
Render a .dgmo file to PNG (default) or SVG.
|
|
5063
5064
|
|
|
5064
5065
|
Options:
|
|
5065
|
-
-o <file>
|
|
5066
|
+
-o <file> Output file (default: <input>.png in cwd)
|
|
5067
|
+
Format inferred from extension: .svg \u2192 SVG, else PNG
|
|
5068
|
+
With stdin and no -o, PNG is written to stdout
|
|
5066
5069
|
--theme <theme> Theme: ${THEMES.join(", ")} (default: light)
|
|
5067
5070
|
--palette <name> Palette: ${PALETTES.join(", ")} (default: nord)
|
|
5068
5071
|
--help Show this help
|
|
@@ -5076,7 +5079,6 @@ function printVersion() {
|
|
|
5076
5079
|
}
|
|
5077
5080
|
function parseArgs(argv) {
|
|
5078
5081
|
const result = {
|
|
5079
|
-
command: void 0,
|
|
5080
5082
|
input: void 0,
|
|
5081
5083
|
output: void 0,
|
|
5082
5084
|
theme: "light",
|
|
@@ -5117,9 +5119,6 @@ function parseArgs(argv) {
|
|
|
5117
5119
|
}
|
|
5118
5120
|
result.palette = val;
|
|
5119
5121
|
i++;
|
|
5120
|
-
} else if (!result.command) {
|
|
5121
|
-
result.command = arg;
|
|
5122
|
-
i++;
|
|
5123
5122
|
} else if (!result.input) {
|
|
5124
5123
|
result.input = arg;
|
|
5125
5124
|
i++;
|
|
@@ -5139,6 +5138,53 @@ function setupDom() {
|
|
|
5139
5138
|
Object.defineProperty(globalThis, "HTMLElement", { value: win.HTMLElement, configurable: true });
|
|
5140
5139
|
Object.defineProperty(globalThis, "SVGElement", { value: win.SVGElement, configurable: true });
|
|
5141
5140
|
}
|
|
5141
|
+
function inferFormat(outputPath) {
|
|
5142
|
+
if (outputPath && (0, import_node_path.extname)(outputPath).toLowerCase() === ".svg") {
|
|
5143
|
+
return "svg";
|
|
5144
|
+
}
|
|
5145
|
+
return "png";
|
|
5146
|
+
}
|
|
5147
|
+
function svgToPng(svg, background) {
|
|
5148
|
+
const resvg = new import_resvg_js.Resvg(svg, {
|
|
5149
|
+
fitTo: { mode: "zoom", value: 2 },
|
|
5150
|
+
...background ? { background } : {}
|
|
5151
|
+
});
|
|
5152
|
+
const rendered = resvg.render();
|
|
5153
|
+
return rendered.asPng();
|
|
5154
|
+
}
|
|
5155
|
+
function noInput() {
|
|
5156
|
+
const samplePath = (0, import_node_path.resolve)("sample.dgmo");
|
|
5157
|
+
if ((0, import_node_fs.existsSync)(samplePath)) {
|
|
5158
|
+
console.error("Error: No input file specified");
|
|
5159
|
+
console.error(`Try: dgmo ${(0, import_node_path.basename)(samplePath)}`);
|
|
5160
|
+
process.exit(1);
|
|
5161
|
+
}
|
|
5162
|
+
(0, import_node_fs.writeFileSync)(
|
|
5163
|
+
samplePath,
|
|
5164
|
+
[
|
|
5165
|
+
"chart: sequence",
|
|
5166
|
+
"activations: off",
|
|
5167
|
+
"",
|
|
5168
|
+
" Client -> API: POST /login",
|
|
5169
|
+
" API -> Auth: validate credentials",
|
|
5170
|
+
" Auth -> DB: SELECT user",
|
|
5171
|
+
" DB -> Auth: user record",
|
|
5172
|
+
" Auth -> API: JWT token",
|
|
5173
|
+
" API -> Client: 200 OK { token }",
|
|
5174
|
+
""
|
|
5175
|
+
].join("\n"),
|
|
5176
|
+
"utf-8"
|
|
5177
|
+
);
|
|
5178
|
+
console.error(`Created ${samplePath}`);
|
|
5179
|
+
console.error("");
|
|
5180
|
+
console.error(" Render it: dgmo sample.dgmo");
|
|
5181
|
+
console.error(" As SVG: dgmo sample.dgmo -o sample.svg");
|
|
5182
|
+
console.error("");
|
|
5183
|
+
console.error(
|
|
5184
|
+
"Edit sample.dgmo to make it your own, or run dgmo --help for all options."
|
|
5185
|
+
);
|
|
5186
|
+
process.exit(0);
|
|
5187
|
+
}
|
|
5142
5188
|
async function main() {
|
|
5143
5189
|
const opts = parseArgs(process.argv);
|
|
5144
5190
|
if (opts.help) {
|
|
@@ -5149,27 +5195,28 @@ async function main() {
|
|
|
5149
5195
|
printVersion();
|
|
5150
5196
|
return;
|
|
5151
5197
|
}
|
|
5152
|
-
if (opts.command !== "render") {
|
|
5153
|
-
if (opts.command) {
|
|
5154
|
-
console.error(`Error: Unknown command "${opts.command}"`);
|
|
5155
|
-
} else {
|
|
5156
|
-
console.error("Error: No command specified");
|
|
5157
|
-
}
|
|
5158
|
-
console.error('Run "dgmo --help" for usage');
|
|
5159
|
-
process.exit(1);
|
|
5160
|
-
}
|
|
5161
|
-
if (!opts.input) {
|
|
5162
|
-
console.error("Error: No input file specified");
|
|
5163
|
-
console.error("Usage: dgmo render <input> [-o output.svg]");
|
|
5164
|
-
process.exit(1);
|
|
5165
|
-
}
|
|
5166
|
-
const inputPath = (0, import_node_path.resolve)(opts.input);
|
|
5167
5198
|
let content;
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5199
|
+
let inputBasename;
|
|
5200
|
+
const stdinIsPiped = !process.stdin.isTTY;
|
|
5201
|
+
if (opts.input) {
|
|
5202
|
+
const inputPath = (0, import_node_path.resolve)(opts.input);
|
|
5203
|
+
try {
|
|
5204
|
+
content = (0, import_node_fs.readFileSync)(inputPath, "utf-8");
|
|
5205
|
+
} catch {
|
|
5206
|
+
console.error(`Error: Cannot read file "${inputPath}"`);
|
|
5207
|
+
process.exit(1);
|
|
5208
|
+
}
|
|
5209
|
+
const name = (0, import_node_path.basename)(opts.input);
|
|
5210
|
+
const ext = (0, import_node_path.extname)(name);
|
|
5211
|
+
inputBasename = ext ? name.slice(0, -ext.length) : name;
|
|
5212
|
+
} else if (stdinIsPiped) {
|
|
5213
|
+
try {
|
|
5214
|
+
content = (0, import_node_fs.readFileSync)(0, "utf-8");
|
|
5215
|
+
} catch {
|
|
5216
|
+
noInput();
|
|
5217
|
+
}
|
|
5218
|
+
} else {
|
|
5219
|
+
noInput();
|
|
5173
5220
|
}
|
|
5174
5221
|
setupDom();
|
|
5175
5222
|
const isDark = opts.theme === "dark";
|
|
@@ -5181,12 +5228,22 @@ async function main() {
|
|
|
5181
5228
|
);
|
|
5182
5229
|
process.exit(1);
|
|
5183
5230
|
}
|
|
5231
|
+
const format = inferFormat(opts.output);
|
|
5232
|
+
const pngBg = opts.theme === "transparent" ? void 0 : paletteColors.bg;
|
|
5184
5233
|
if (opts.output) {
|
|
5185
5234
|
const outputPath = (0, import_node_path.resolve)(opts.output);
|
|
5186
|
-
|
|
5235
|
+
if (format === "svg") {
|
|
5236
|
+
(0, import_node_fs.writeFileSync)(outputPath, svg, "utf-8");
|
|
5237
|
+
} else {
|
|
5238
|
+
(0, import_node_fs.writeFileSync)(outputPath, svgToPng(svg, pngBg));
|
|
5239
|
+
}
|
|
5240
|
+
console.error(`Wrote ${outputPath}`);
|
|
5241
|
+
} else if (inputBasename) {
|
|
5242
|
+
const outputPath = (0, import_node_path.resolve)(`${inputBasename}.png`);
|
|
5243
|
+
(0, import_node_fs.writeFileSync)(outputPath, svgToPng(svg, pngBg));
|
|
5187
5244
|
console.error(`Wrote ${outputPath}`);
|
|
5188
5245
|
} else {
|
|
5189
|
-
process.stdout.write(svg);
|
|
5246
|
+
process.stdout.write(svgToPng(svg, pngBg));
|
|
5190
5247
|
}
|
|
5191
5248
|
}
|
|
5192
5249
|
main().catch((err) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diagrammo/dgmo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "DGMO diagram markup language — parser, renderer, and color system",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"dev": "tsup --watch"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"@resvg/resvg-js": "^2.6.2",
|
|
36
37
|
"chart.js": "^4.4.8",
|
|
37
38
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
38
39
|
"d3-array": "^3.2.4",
|
|
@@ -44,12 +45,12 @@
|
|
|
44
45
|
"jsdom": "^26.0.0"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
|
-
"@types/jsdom": "^21.1.7",
|
|
48
48
|
"@types/d3-array": "^3.2.1",
|
|
49
49
|
"@types/d3-cloud": "^1.2.9",
|
|
50
50
|
"@types/d3-scale": "^4.0.8",
|
|
51
51
|
"@types/d3-selection": "^3.0.11",
|
|
52
52
|
"@types/d3-shape": "^3.1.7",
|
|
53
|
+
"@types/jsdom": "^21.1.7",
|
|
53
54
|
"tsup": "^8.5.1",
|
|
54
55
|
"typescript": "^5.7.3"
|
|
55
56
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { resolve, basename, extname } from 'node:path';
|
|
3
3
|
import { JSDOM } from 'jsdom';
|
|
4
|
+
import { Resvg } from '@resvg/resvg-js';
|
|
4
5
|
import { renderD3ForExport } from './d3';
|
|
5
6
|
import { getPalette } from './palettes/registry';
|
|
6
7
|
|
|
@@ -18,13 +19,15 @@ const PALETTES = [
|
|
|
18
19
|
const THEMES = ['light', 'dark', 'transparent'] as const;
|
|
19
20
|
|
|
20
21
|
function printHelp(): void {
|
|
21
|
-
console.log(`Usage: dgmo
|
|
22
|
+
console.log(`Usage: dgmo <input> [options]
|
|
23
|
+
cat input.dgmo | dgmo [options]
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
render <input> Render a .dgmo file to SVG
|
|
25
|
+
Render a .dgmo file to PNG (default) or SVG.
|
|
25
26
|
|
|
26
27
|
Options:
|
|
27
|
-
-o <file>
|
|
28
|
+
-o <file> Output file (default: <input>.png in cwd)
|
|
29
|
+
Format inferred from extension: .svg → SVG, else PNG
|
|
30
|
+
With stdin and no -o, PNG is written to stdout
|
|
28
31
|
--theme <theme> Theme: ${THEMES.join(', ')} (default: light)
|
|
29
32
|
--palette <name> Palette: ${PALETTES.join(', ')} (default: nord)
|
|
30
33
|
--help Show this help
|
|
@@ -39,7 +42,6 @@ function printVersion(): void {
|
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
function parseArgs(argv: string[]): {
|
|
42
|
-
command: string | undefined;
|
|
43
45
|
input: string | undefined;
|
|
44
46
|
output: string | undefined;
|
|
45
47
|
theme: (typeof THEMES)[number];
|
|
@@ -48,7 +50,6 @@ function parseArgs(argv: string[]): {
|
|
|
48
50
|
version: boolean;
|
|
49
51
|
} {
|
|
50
52
|
const result = {
|
|
51
|
-
command: undefined as string | undefined,
|
|
52
53
|
input: undefined as string | undefined,
|
|
53
54
|
output: undefined as string | undefined,
|
|
54
55
|
theme: 'light' as (typeof THEMES)[number],
|
|
@@ -92,9 +93,6 @@ function parseArgs(argv: string[]): {
|
|
|
92
93
|
}
|
|
93
94
|
result.palette = val;
|
|
94
95
|
i++;
|
|
95
|
-
} else if (!result.command) {
|
|
96
|
-
result.command = arg;
|
|
97
|
-
i++;
|
|
98
96
|
} else if (!result.input) {
|
|
99
97
|
result.input = arg;
|
|
100
98
|
i++;
|
|
@@ -119,6 +117,56 @@ function setupDom(): void {
|
|
|
119
117
|
Object.defineProperty(globalThis, 'SVGElement', { value: win.SVGElement, configurable: true });
|
|
120
118
|
}
|
|
121
119
|
|
|
120
|
+
function inferFormat(outputPath: string | undefined): 'svg' | 'png' {
|
|
121
|
+
if (outputPath && extname(outputPath).toLowerCase() === '.svg') {
|
|
122
|
+
return 'svg';
|
|
123
|
+
}
|
|
124
|
+
return 'png';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function svgToPng(svg: string, background?: string): Buffer {
|
|
128
|
+
const resvg = new Resvg(svg, {
|
|
129
|
+
fitTo: { mode: 'zoom', value: 2 },
|
|
130
|
+
...(background ? { background } : {}),
|
|
131
|
+
});
|
|
132
|
+
const rendered = resvg.render();
|
|
133
|
+
return rendered.asPng();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function noInput(): never {
|
|
137
|
+
const samplePath = resolve('sample.dgmo');
|
|
138
|
+
if (existsSync(samplePath)) {
|
|
139
|
+
console.error('Error: No input file specified');
|
|
140
|
+
console.error(`Try: dgmo ${basename(samplePath)}`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
writeFileSync(
|
|
144
|
+
samplePath,
|
|
145
|
+
[
|
|
146
|
+
'chart: sequence',
|
|
147
|
+
'activations: off',
|
|
148
|
+
'',
|
|
149
|
+
' Client -> API: POST /login',
|
|
150
|
+
' API -> Auth: validate credentials',
|
|
151
|
+
' Auth -> DB: SELECT user',
|
|
152
|
+
' DB -> Auth: user record',
|
|
153
|
+
' Auth -> API: JWT token',
|
|
154
|
+
' API -> Client: 200 OK { token }',
|
|
155
|
+
'',
|
|
156
|
+
].join('\n'),
|
|
157
|
+
'utf-8'
|
|
158
|
+
);
|
|
159
|
+
console.error(`Created ${samplePath}`);
|
|
160
|
+
console.error('');
|
|
161
|
+
console.error(' Render it: dgmo sample.dgmo');
|
|
162
|
+
console.error(' As SVG: dgmo sample.dgmo -o sample.svg');
|
|
163
|
+
console.error('');
|
|
164
|
+
console.error(
|
|
165
|
+
'Edit sample.dgmo to make it your own, or run dgmo --help for all options.'
|
|
166
|
+
);
|
|
167
|
+
process.exit(0);
|
|
168
|
+
}
|
|
169
|
+
|
|
122
170
|
async function main(): Promise<void> {
|
|
123
171
|
const opts = parseArgs(process.argv);
|
|
124
172
|
|
|
@@ -132,29 +180,33 @@ async function main(): Promise<void> {
|
|
|
132
180
|
return;
|
|
133
181
|
}
|
|
134
182
|
|
|
135
|
-
|
|
136
|
-
if (opts.command) {
|
|
137
|
-
console.error(`Error: Unknown command "${opts.command}"`);
|
|
138
|
-
} else {
|
|
139
|
-
console.error('Error: No command specified');
|
|
140
|
-
}
|
|
141
|
-
console.error('Run "dgmo --help" for usage');
|
|
142
|
-
process.exit(1);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (!opts.input) {
|
|
146
|
-
console.error('Error: No input file specified');
|
|
147
|
-
console.error('Usage: dgmo render <input> [-o output.svg]');
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const inputPath = resolve(opts.input);
|
|
183
|
+
// Determine input source
|
|
152
184
|
let content: string;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
185
|
+
let inputBasename: string | undefined;
|
|
186
|
+
const stdinIsPiped = !process.stdin.isTTY;
|
|
187
|
+
|
|
188
|
+
if (opts.input) {
|
|
189
|
+
// File argument provided
|
|
190
|
+
const inputPath = resolve(opts.input);
|
|
191
|
+
try {
|
|
192
|
+
content = readFileSync(inputPath, 'utf-8');
|
|
193
|
+
} catch {
|
|
194
|
+
console.error(`Error: Cannot read file "${inputPath}"`);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
// Strip extension for default output name
|
|
198
|
+
const name = basename(opts.input);
|
|
199
|
+
const ext = extname(name);
|
|
200
|
+
inputBasename = ext ? name.slice(0, -ext.length) : name;
|
|
201
|
+
} else if (stdinIsPiped) {
|
|
202
|
+
// Read from stdin
|
|
203
|
+
try {
|
|
204
|
+
content = readFileSync(0, 'utf-8');
|
|
205
|
+
} catch {
|
|
206
|
+
noInput();
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
noInput();
|
|
158
210
|
}
|
|
159
211
|
|
|
160
212
|
// Set up jsdom before any d3/renderer code runs
|
|
@@ -174,12 +226,27 @@ async function main(): Promise<void> {
|
|
|
174
226
|
process.exit(1);
|
|
175
227
|
}
|
|
176
228
|
|
|
229
|
+
// Determine output format and destination
|
|
230
|
+
const format = inferFormat(opts.output);
|
|
231
|
+
const pngBg = opts.theme === 'transparent' ? undefined : paletteColors.bg;
|
|
232
|
+
|
|
177
233
|
if (opts.output) {
|
|
234
|
+
// Explicit output path
|
|
178
235
|
const outputPath = resolve(opts.output);
|
|
179
|
-
|
|
236
|
+
if (format === 'svg') {
|
|
237
|
+
writeFileSync(outputPath, svg, 'utf-8');
|
|
238
|
+
} else {
|
|
239
|
+
writeFileSync(outputPath, svgToPng(svg, pngBg));
|
|
240
|
+
}
|
|
241
|
+
console.error(`Wrote ${outputPath}`);
|
|
242
|
+
} else if (inputBasename) {
|
|
243
|
+
// File input, no -o → write <basename>.png in cwd
|
|
244
|
+
const outputPath = resolve(`${inputBasename}.png`);
|
|
245
|
+
writeFileSync(outputPath, svgToPng(svg, pngBg));
|
|
180
246
|
console.error(`Wrote ${outputPath}`);
|
|
181
247
|
} else {
|
|
182
|
-
|
|
248
|
+
// Stdin input, no -o → write PNG to stdout
|
|
249
|
+
process.stdout.write(svgToPng(svg, pngBg));
|
|
183
250
|
}
|
|
184
251
|
}
|
|
185
252
|
|