@bobfrankston/mdview 0.1.3 → 0.1.4

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 CHANGED
@@ -29,39 +29,56 @@ cat foo.md | mdview -stream [options] [-- <host-flags>...]
29
29
 
30
30
  ### Options
31
31
 
32
+ **Window:**
33
+
34
+ | Flag | Description |
35
+ |---|---|
36
+ | `-pos x,y[,s]` | Window position (screen index `s` is optional, Windows only). |
37
+ | `-size w,h` | Window size in pixels. |
38
+ | `-ontop` | Keep window above others. |
39
+ | `-zoom <percent>` | Initial zoom (e.g. `-zoom 150`). |
40
+
41
+ **Behavior:**
42
+
32
43
  | Flag | Description |
33
44
  |---|---|
34
- | `-host msger\|msgview` | Backend host. Default: `msger`. Persisted to `~/.mdview.json` so you don't have to re-specify. |
35
- | `-w`, `-watch` | Re-render and reload when the file changes on disk. (File mode only.) |
45
+ | `-host msger\|msgview` | Backend host. Default: `msger`. Persisted to `~/.mdview.json`. |
46
+ | `-w`, `-watch` | Re-render and reload when the file changes on disk. Implies `-nodetach`. |
36
47
  | `-stream` | Read markdown from stdin instead of a file. |
37
48
  | `-save <file>` | Render to `<file>` (HTML) and exit; don't open a window. |
49
+ | `-nodetach` | Wait for the window to close before exiting. Default is **detach** (mdview returns immediately). |
50
+ | `-dev` | Open developer tools on startup. |
38
51
  | `-h`, `-help` | Show help. |
39
52
 
40
53
  Both `-foo` and `--foo` forms are accepted.
41
54
 
42
55
  ### Host pass-through flags
43
56
 
44
- Anything after `--` is forwarded to the host:
57
+ Anything after `--` is forwarded to the host. Needed only for flags mdview doesn't expose directly:
45
58
 
46
59
  ```bash
47
- mdview README.md -- -size 900,700 -ontop
60
+ mdview README.md -- -reset
48
61
  ```
49
62
 
50
- For msger: a small subset (`-size`, `-pos`, `-zoom`, `-ontop`, `-dev`) is parsed and translated to the API. Unknown flags are dropped with a warning.
51
-
52
- For msgview: passthrough is forwarded verbatim to the `msgview` CLI.
63
+ mdview's own `-pos`, `-size`, `-ontop`, `-zoom`, `-dev` are translated for both hosts natively. Passthrough flags override top-level (last-write-wins) if you specify both.
53
64
 
54
65
  ## Examples
55
66
 
56
67
  ```bash
57
- # Default (msger), one-shot
68
+ # Default (msger), one-shot — shell returns immediately (detach is the default)
58
69
  mdview README.md
59
70
 
60
71
  # Switch to msgview and remember the choice
61
72
  mdview -host msgview notes.md
62
73
  mdview notes.md # subsequent runs use msgview until you switch back
63
74
 
64
- # Watch mode reloads on save
75
+ # Pin position/size/ontop directly (no `--` needed)
76
+ mdview README.md -pos 100,100 -size 1000,800 -ontop
77
+
78
+ # Wait for the window to close (scripting)
79
+ mdview README.md -nodetach
80
+
81
+ # Watch mode — reloads on save, stays attached
65
82
  mdview -w draft.md
66
83
 
67
84
  # Render and save HTML, no window
@@ -70,9 +87,6 @@ mdview README.md -save out.html
70
87
  # Pipe from stdin
71
88
  cat foo.md | mdview -stream
72
89
  gh pr view --json body -q .body | mdview -stream
73
-
74
- # Pin position/size for the window
75
- mdview README.md -- -pos 100,100 -size 1000,800 -ontop
76
90
  ```
77
91
 
78
92
  ## How it works
@@ -86,7 +100,7 @@ mdview README.md -- -pos 100,100 -size 1000,800 -ontop
86
100
 
87
101
  ## Limits
88
102
 
89
- - **Watch mode** respawns the window — geometry resets each reload. Pin it with `-- -pos x,y -size w,h`.
103
+ - **Watch mode** respawns the window — geometry resets each reload. Pin it with `-pos x,y -size w,h`.
90
104
  - **msgview + huge HTML** can hit the 8k cmd.exe arg limit on Windows. Switch to msger if rendering is silently truncated.
91
105
  - **Cross-file `[x](other.md)` links** navigate to the raw `.md` file, not the rendered version. The host loads it as text. (Future: intercept `.md` navigation and re-render.)
92
106
  - **Explicit refresh** is editor-driven via watch mode — `touch` the file to force a reload without changing it.
package/mdview.js CHANGED
@@ -13,6 +13,10 @@
13
13
  // - msgview: spawn the `msgview` CLI with `-raw -html <html>`. The Windows
14
14
  // cmd.exe wrapper imposes an ~8k char limit on the full command;
15
15
  // very large markdown files may be truncated. Use msger for big docs.
16
+ //
17
+ // Defaults: detach. `mdview foo.md` returns immediately, window stays open
18
+ // until the user closes it. -w (watch) implies attached — mdview must stay
19
+ // alive to watch + respawn. -nodetach forces attached for scripting.
16
20
  import { spawn } from 'child_process';
17
21
  import fs from 'fs';
18
22
  import os from 'os';
@@ -26,18 +30,26 @@ Usage:
26
30
  mdview [options] <file.md> [-- <host-flags>...]
27
31
  cat foo.md | mdview -stream [options] [-- <host-flags>...]
28
32
 
29
- Options:
33
+ Window options:
34
+ -pos x,y[,s] Window position (screen index s optional, Windows only)
35
+ -size w,h Window size in pixels
36
+ -ontop Keep window above others
37
+ -zoom <percent> Initial zoom (100=100%, 150=150%, ...)
38
+
39
+ Behavior:
30
40
  -host msger|msgview Backend host (default: msger; remembered for next run)
31
- -w, -watch Reload when the file changes on disk (file mode only)
41
+ -w, -watch Reload when the file changes on disk (implies -nodetach)
32
42
  -stream Read markdown from stdin instead of a file
33
- -save <file> Render to <file>.html and exit; don't open a window
43
+ -save <file> Render to <file> (HTML) and exit; don't open a window
44
+ -nodetach Wait for the window to close before exiting
45
+ (default: detach — mdview returns immediately)
46
+ -dev Open developer tools on startup (debugging)
34
47
  -h, -help Show this help
35
48
 
36
49
  Single- and double-dash forms are accepted (-host == --host).
37
50
 
38
51
  Host flags after \`--\` are forwarded (msger: parsed and translated; msgview:
39
- passed through to the CLI). Example:
40
- mdview README.md -- -size 900,700 -ontop
52
+ passed through to the CLI) for anything not exposed above.
41
53
 
42
54
  Defaults:
43
55
  Host preference is saved to ~/.mdview.json on first explicit -host and
@@ -61,8 +73,27 @@ function saveDefaultHost(host) {
61
73
  console.warn(`mdview: could not save default host: ${e.message}`);
62
74
  }
63
75
  }
76
+ function parseSize(v) {
77
+ const [w, h] = v.split(',').map(s => parseInt(s.trim(), 10));
78
+ if (isNaN(w) || isNaN(h))
79
+ throw new Error(`-size needs w,h (got ${v})`);
80
+ return { width: w, height: h };
81
+ }
82
+ function parsePos(v) {
83
+ const parts = v.split(',').map(s => parseInt(s.trim(), 10));
84
+ if (isNaN(parts[0]) || isNaN(parts[1]))
85
+ throw new Error(`-pos needs x,y[,s] (got ${v})`);
86
+ const pos = { x: parts[0], y: parts[1] };
87
+ if (!isNaN(parts[2]))
88
+ pos.screen = parts[2];
89
+ return pos;
90
+ }
64
91
  function parseArgs(argv) {
65
- const out = { file: null, host: null, watch: false, stream: false, save: null, passthrough: [], help: false };
92
+ const out = {
93
+ file: null, host: null, watch: false, stream: false, save: null,
94
+ detach: true, ontop: false, pos: null, size: null, zoom: null, dev: false,
95
+ passthrough: [], help: false
96
+ };
66
97
  const args = [...argv];
67
98
  const norm = (s) => s.replace(/^--/, '-'); // accept both -foo and --foo
68
99
  while (args.length > 0) {
@@ -90,8 +121,22 @@ function parseArgs(argv) {
90
121
  throw new Error('-save requires a file path');
91
122
  out.save = v;
92
123
  }
124
+ else if (a === '-nodetach')
125
+ out.detach = false;
126
+ else if (a === '-detach')
127
+ out.detach = true; // redundant but explicit
128
+ else if (a === '-ontop' || a === '-alwaysontop')
129
+ out.ontop = true;
130
+ else if (a === '-pos')
131
+ out.pos = parsePos(args.shift());
132
+ else if (a === '-size')
133
+ out.size = parseSize(args.shift());
134
+ else if (a === '-zoom')
135
+ out.zoom = parseFloat(args.shift());
136
+ else if (a === '-dev')
137
+ out.dev = true;
93
138
  else if (a.startsWith('-'))
94
- throw new Error(`Unknown option: ${raw} (put host flags after --)`);
139
+ throw new Error(`Unknown option: ${raw} (put host-specific flags after --)`);
95
140
  else if (!out.file)
96
141
  out.file = raw;
97
142
  else
@@ -121,29 +166,19 @@ function renderSource(args) {
121
166
  const baseHref = pathToFileURL(baseDir + path.sep).href;
122
167
  return { html: renderMarkdown(md, title, baseHref), title };
123
168
  }
124
- // Translate a tiny subset of common passthrough flags into MessageBoxOptions.
125
- // Anything unrecognised is dropped with a warning full parity with msger CLI
126
- // isn't a goal; for rich flag control, invoke msger directly with -raw -html.
127
- // Returns a loosely-typed bag that gets spread into MessageBoxOptions at the
128
- // call site; exhaustive typing here would duplicate msger's option interface.
169
+ // Translate post-`--` passthrough flags that aren't first-class in mdview.
170
+ // Top-level -pos/-size/-ontop/-zoom/-dev are already in `args`; this is for
171
+ // anything else a user wants to forward to the host.
129
172
  function passthroughToOptions(passthrough) {
130
173
  const opts = {};
131
174
  for (let i = 0; i < passthrough.length; i++) {
132
175
  const a = passthrough[i];
133
176
  if (a === '-ontop' || a === '--ontop' || a === '-alwaysontop' || a === '--alwaysontop')
134
177
  opts.alwaysOnTop = true;
135
- else if ((a === '-size' || a === '--size') && passthrough[i + 1]) {
136
- const [w, h] = passthrough[++i].split(',').map(s => parseInt(s.trim(), 10));
137
- if (!isNaN(w) && !isNaN(h))
138
- opts.size = { width: w, height: h };
139
- }
140
- else if ((a === '-pos' || a === '--pos') && passthrough[i + 1]) {
141
- const parts = passthrough[++i].split(',').map(s => parseInt(s.trim(), 10));
142
- const pos = { x: parts[0], y: parts[1] };
143
- if (!isNaN(parts[2]))
144
- pos.screen = parts[2];
145
- opts.pos = pos;
146
- }
178
+ else if ((a === '-size' || a === '--size') && passthrough[i + 1])
179
+ opts.size = parseSize(passthrough[++i]);
180
+ else if ((a === '-pos' || a === '--pos') && passthrough[i + 1])
181
+ opts.pos = parsePos(passthrough[++i]);
147
182
  else if ((a === '-zoom' || a === '--zoom') && passthrough[i + 1])
148
183
  opts.zoom = parseFloat(passthrough[++i]);
149
184
  else if (a === '-dev' || a === '--dev')
@@ -153,14 +188,53 @@ function passthroughToOptions(passthrough) {
153
188
  }
154
189
  return opts;
155
190
  }
156
- async function launchMsger(html, title, passthrough) {
191
+ function argsToMsgerOptions(args, title, html, detach) {
192
+ const opts = { title, html, rawHtml: true };
193
+ if (args.ontop)
194
+ opts.alwaysOnTop = true;
195
+ if (args.pos)
196
+ opts.pos = args.pos;
197
+ if (args.size)
198
+ opts.size = args.size;
199
+ if (args.zoom !== null)
200
+ opts.zoom = args.zoom;
201
+ if (args.dev)
202
+ opts.dev = true;
203
+ if (detach)
204
+ opts.detach = true;
205
+ // Passthrough overrides top-level (last-write-wins) so -- flags trump.
206
+ return { ...opts, ...passthroughToOptions(args.passthrough) };
207
+ }
208
+ function argsToMsgviewArgs(args, title, html, detach) {
209
+ const out = ['-raw', '-title', title, '-html', html];
210
+ if (args.ontop)
211
+ out.push('-ontop');
212
+ if (args.pos)
213
+ out.push('-pos', [args.pos.x, args.pos.y, args.pos.screen].filter(v => v !== undefined).join(','));
214
+ if (args.size)
215
+ out.push('-size', `${args.size.width},${args.size.height}`);
216
+ if (args.zoom !== null)
217
+ out.push('-zoom', String(args.zoom));
218
+ if (args.dev)
219
+ out.push('-dev');
220
+ if (detach)
221
+ out.push('-detach');
222
+ out.push(...args.passthrough);
223
+ return out;
224
+ }
225
+ async function launchMsger(args, html, title, detach) {
157
226
  const msger = await import('@bobfrankston/msger');
158
- const opts = { title, html, rawHtml: true, ...passthroughToOptions(passthrough) };
159
- return msger.showMessageBoxEx(opts);
227
+ return msger.showMessageBoxEx(argsToMsgerOptions(args, title, html, detach));
160
228
  }
161
- function launchMsgview(html, title, passthrough) {
162
- const args = ['-raw', '-title', title, '-html', html, ...passthrough];
163
- return spawn('msgview', args, { stdio: ['ignore', 'inherit', 'inherit'], shell: true });
229
+ function launchMsgview(args, html, title, detach) {
230
+ const child = spawn('msgview', argsToMsgviewArgs(args, title, html, detach), {
231
+ stdio: ['ignore', 'inherit', 'inherit'],
232
+ shell: true,
233
+ detached: detach
234
+ });
235
+ if (detach)
236
+ child.unref();
237
+ return child;
164
238
  }
165
239
  async function main() {
166
240
  let args;
@@ -211,15 +285,21 @@ async function main() {
211
285
  process.exit(1);
212
286
  }
213
287
  }
214
- // One-shot: render, show, exit when host exits.
288
+ // Watch mode forces attached mdview must stay alive to watch + respawn.
289
+ const detach = args.detach && !args.watch;
290
+ // One-shot launch. Detached: fire and forget. Attached: wait for close.
215
291
  if (!args.watch) {
216
292
  if (host === 'msger') {
217
- const handle = await launchMsger(rendered.html, rendered.title, args.passthrough);
293
+ const handle = await launchMsger(args, rendered.html, rendered.title, detach);
294
+ if (detach)
295
+ process.exit(0);
218
296
  await handle.result;
219
297
  process.exit(0);
220
298
  }
221
299
  else {
222
- const child = launchMsgview(rendered.html, rendered.title, args.passthrough);
300
+ const child = launchMsgview(args, rendered.html, rendered.title, detach);
301
+ if (detach)
302
+ process.exit(0);
223
303
  child.on('exit', (code) => process.exit(code ?? 0));
224
304
  }
225
305
  return;
@@ -235,12 +315,12 @@ async function main() {
235
315
  if (host === 'msger') {
236
316
  if (msgerHandle && !msgerHandle.closed)
237
317
  msgerHandle.close();
238
- msgerHandle = await launchMsger(r.html, r.title, args.passthrough);
318
+ msgerHandle = await launchMsger(args, r.html, r.title, false);
239
319
  }
240
320
  else {
241
321
  if (msgviewChild && !msgviewChild.killed)
242
322
  msgviewChild.kill();
243
- msgviewChild = launchMsgview(r.html, r.title, args.passthrough);
323
+ msgviewChild = launchMsgview(args, r.html, r.title, false);
244
324
  msgviewChild.on('exit', () => { msgviewChild = null; });
245
325
  }
246
326
  }
@@ -250,9 +330,9 @@ async function main() {
250
330
  };
251
331
  // Initial launch uses the already-rendered HTML to avoid a redundant read.
252
332
  if (host === 'msger')
253
- msgerHandle = await launchMsger(rendered.html, rendered.title, args.passthrough);
333
+ msgerHandle = await launchMsger(args, rendered.html, rendered.title, false);
254
334
  else
255
- msgviewChild = launchMsgview(rendered.html, rendered.title, args.passthrough);
335
+ msgviewChild = launchMsgview(args, rendered.html, rendered.title, false);
256
336
  fs.watch(absPath, { persistent: true }, () => {
257
337
  if (reloadTimer)
258
338
  clearTimeout(reloadTimer);
package/mdview.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mdview.js","sourceRoot":"","sources":["mdview.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mdview.js","sourceRoot":"","sources":["mdview.ts"],"names":[],"mappings":"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"}
package/mdview.ts CHANGED
@@ -13,6 +13,10 @@
13
13
  // - msgview: spawn the `msgview` CLI with `-raw -html <html>`. The Windows
14
14
  // cmd.exe wrapper imposes an ~8k char limit on the full command;
15
15
  // very large markdown files may be truncated. Use msger for big docs.
16
+ //
17
+ // Defaults: detach. `mdview foo.md` returns immediately, window stays open
18
+ // until the user closes it. -w (watch) implies attached — mdview must stay
19
+ // alive to watch + respawn. -nodetach forces attached for scripting.
16
20
 
17
21
  import { spawn, ChildProcess } from 'child_process';
18
22
  import fs from 'fs';
@@ -22,12 +26,21 @@ import { pathToFileURL } from 'url';
22
26
  import { renderMarkdown } from '@bobfrankston/msgcommon/markdown';
23
27
  import { MessageBoxHandle } from '@bobfrankston/msger';
24
28
 
29
+ interface Position { x: number; y: number; screen?: number; }
30
+ interface Size { width: number; height: number; }
31
+
25
32
  interface Args {
26
- file: string; // null when -stream is used
33
+ file: string;
27
34
  host: 'msger' | 'msgview'; // null = use persisted default from config
28
35
  watch: boolean;
29
36
  stream: boolean;
30
- save: string; // null when not saving
37
+ save: string;
38
+ detach: boolean; // default true; -nodetach sets false
39
+ ontop: boolean;
40
+ pos: Position;
41
+ size: Size;
42
+ zoom: number;
43
+ dev: boolean;
31
44
  passthrough: string[];
32
45
  help: boolean;
33
46
  }
@@ -39,18 +52,26 @@ Usage:
39
52
  mdview [options] <file.md> [-- <host-flags>...]
40
53
  cat foo.md | mdview -stream [options] [-- <host-flags>...]
41
54
 
42
- Options:
55
+ Window options:
56
+ -pos x,y[,s] Window position (screen index s optional, Windows only)
57
+ -size w,h Window size in pixels
58
+ -ontop Keep window above others
59
+ -zoom <percent> Initial zoom (100=100%, 150=150%, ...)
60
+
61
+ Behavior:
43
62
  -host msger|msgview Backend host (default: msger; remembered for next run)
44
- -w, -watch Reload when the file changes on disk (file mode only)
63
+ -w, -watch Reload when the file changes on disk (implies -nodetach)
45
64
  -stream Read markdown from stdin instead of a file
46
- -save <file> Render to <file>.html and exit; don't open a window
65
+ -save <file> Render to <file> (HTML) and exit; don't open a window
66
+ -nodetach Wait for the window to close before exiting
67
+ (default: detach — mdview returns immediately)
68
+ -dev Open developer tools on startup (debugging)
47
69
  -h, -help Show this help
48
70
 
49
71
  Single- and double-dash forms are accepted (-host == --host).
50
72
 
51
73
  Host flags after \`--\` are forwarded (msger: parsed and translated; msgview:
52
- passed through to the CLI). Example:
53
- mdview README.md -- -size 900,700 -ontop
74
+ passed through to the CLI) for anything not exposed above.
54
75
 
55
76
  Defaults:
56
77
  Host preference is saved to ~/.mdview.json on first explicit -host and
@@ -72,8 +93,26 @@ function saveDefaultHost(host: 'msger' | 'msgview'): void {
72
93
  catch (e: any) { console.warn(`mdview: could not save default host: ${e.message}`); }
73
94
  }
74
95
 
96
+ function parseSize(v: string): Size {
97
+ const [w, h] = v.split(',').map(s => parseInt(s.trim(), 10));
98
+ if (isNaN(w) || isNaN(h)) throw new Error(`-size needs w,h (got ${v})`);
99
+ return { width: w, height: h };
100
+ }
101
+
102
+ function parsePos(v: string): Position {
103
+ const parts = v.split(',').map(s => parseInt(s.trim(), 10));
104
+ if (isNaN(parts[0]) || isNaN(parts[1])) throw new Error(`-pos needs x,y[,s] (got ${v})`);
105
+ const pos: Position = { x: parts[0], y: parts[1] };
106
+ if (!isNaN(parts[2])) pos.screen = parts[2];
107
+ return pos;
108
+ }
109
+
75
110
  function parseArgs(argv: string[]): Args {
76
- const out: Args = { file: null, host: null, watch: false, stream: false, save: null, passthrough: [], help: false };
111
+ const out: Args = {
112
+ file: null, host: null, watch: false, stream: false, save: null,
113
+ detach: true, ontop: false, pos: null, size: null, zoom: null, dev: false,
114
+ passthrough: [], help: false
115
+ };
77
116
  const args = [...argv];
78
117
  const norm = (s: string) => s.replace(/^--/, '-'); // accept both -foo and --foo
79
118
  while (args.length > 0) {
@@ -93,7 +132,14 @@ function parseArgs(argv: string[]): Args {
93
132
  if (!v) throw new Error('-save requires a file path');
94
133
  out.save = v;
95
134
  }
96
- else if (a.startsWith('-')) throw new Error(`Unknown option: ${raw} (put host flags after --)`);
135
+ else if (a === '-nodetach') out.detach = false;
136
+ else if (a === '-detach') out.detach = true; // redundant but explicit
137
+ else if (a === '-ontop' || a === '-alwaysontop') out.ontop = true;
138
+ else if (a === '-pos') out.pos = parsePos(args.shift());
139
+ else if (a === '-size') out.size = parseSize(args.shift());
140
+ else if (a === '-zoom') out.zoom = parseFloat(args.shift());
141
+ else if (a === '-dev') out.dev = true;
142
+ else if (a.startsWith('-')) throw new Error(`Unknown option: ${raw} (put host-specific flags after --)`);
97
143
  else if (!out.file) out.file = raw;
98
144
  else throw new Error(`Unexpected extra argument: ${raw}`);
99
145
  }
@@ -122,26 +168,16 @@ function renderSource(args: Args) {
122
168
  return { html: renderMarkdown(md, title, baseHref), title };
123
169
  }
124
170
 
125
- // Translate a tiny subset of common passthrough flags into MessageBoxOptions.
126
- // Anything unrecognised is dropped with a warning full parity with msger CLI
127
- // isn't a goal; for rich flag control, invoke msger directly with -raw -html.
128
- // Returns a loosely-typed bag that gets spread into MessageBoxOptions at the
129
- // call site; exhaustive typing here would duplicate msger's option interface.
171
+ // Translate post-`--` passthrough flags that aren't first-class in mdview.
172
+ // Top-level -pos/-size/-ontop/-zoom/-dev are already in `args`; this is for
173
+ // anything else a user wants to forward to the host.
130
174
  function passthroughToOptions(passthrough: string[]) {
131
175
  const opts: Record<string, unknown> = {};
132
176
  for (let i = 0; i < passthrough.length; i++) {
133
177
  const a = passthrough[i];
134
178
  if (a === '-ontop' || a === '--ontop' || a === '-alwaysontop' || a === '--alwaysontop') opts.alwaysOnTop = true;
135
- else if ((a === '-size' || a === '--size') && passthrough[i + 1]) {
136
- const [w, h] = passthrough[++i].split(',').map(s => parseInt(s.trim(), 10));
137
- if (!isNaN(w) && !isNaN(h)) opts.size = { width: w, height: h };
138
- }
139
- else if ((a === '-pos' || a === '--pos') && passthrough[i + 1]) {
140
- const parts = passthrough[++i].split(',').map(s => parseInt(s.trim(), 10));
141
- const pos: Record<string, number> = { x: parts[0], y: parts[1] };
142
- if (!isNaN(parts[2])) pos.screen = parts[2];
143
- opts.pos = pos;
144
- }
179
+ else if ((a === '-size' || a === '--size') && passthrough[i + 1]) opts.size = parseSize(passthrough[++i]);
180
+ else if ((a === '-pos' || a === '--pos') && passthrough[i + 1]) opts.pos = parsePos(passthrough[++i]);
145
181
  else if ((a === '-zoom' || a === '--zoom') && passthrough[i + 1]) opts.zoom = parseFloat(passthrough[++i]);
146
182
  else if (a === '-dev' || a === '--dev') opts.dev = true;
147
183
  else console.warn(`mdview: dropping unsupported passthrough flag: ${a}`);
@@ -149,15 +185,43 @@ function passthroughToOptions(passthrough: string[]) {
149
185
  return opts;
150
186
  }
151
187
 
152
- async function launchMsger(html: string, title: string, passthrough: string[]): Promise<MessageBoxHandle> {
188
+ function argsToMsgerOptions(args: Args, title: string, html: string, detach: boolean) {
189
+ const opts: Record<string, unknown> = { title, html, rawHtml: true };
190
+ if (args.ontop) opts.alwaysOnTop = true;
191
+ if (args.pos) opts.pos = args.pos;
192
+ if (args.size) opts.size = args.size;
193
+ if (args.zoom !== null) opts.zoom = args.zoom;
194
+ if (args.dev) opts.dev = true;
195
+ if (detach) opts.detach = true;
196
+ // Passthrough overrides top-level (last-write-wins) so -- flags trump.
197
+ return { ...opts, ...passthroughToOptions(args.passthrough) };
198
+ }
199
+
200
+ function argsToMsgviewArgs(args: Args, title: string, html: string, detach: boolean): string[] {
201
+ const out = ['-raw', '-title', title, '-html', html];
202
+ if (args.ontop) out.push('-ontop');
203
+ if (args.pos) out.push('-pos', [args.pos.x, args.pos.y, args.pos.screen].filter(v => v !== undefined).join(','));
204
+ if (args.size) out.push('-size', `${args.size.width},${args.size.height}`);
205
+ if (args.zoom !== null) out.push('-zoom', String(args.zoom));
206
+ if (args.dev) out.push('-dev');
207
+ if (detach) out.push('-detach');
208
+ out.push(...args.passthrough);
209
+ return out;
210
+ }
211
+
212
+ async function launchMsger(args: Args, html: string, title: string, detach: boolean): Promise<MessageBoxHandle> {
153
213
  const msger = await import('@bobfrankston/msger');
154
- const opts = { title, html, rawHtml: true, ...passthroughToOptions(passthrough) };
155
- return msger.showMessageBoxEx(opts);
214
+ return msger.showMessageBoxEx(argsToMsgerOptions(args, title, html, detach));
156
215
  }
157
216
 
158
- function launchMsgview(html: string, title: string, passthrough: string[]): ChildProcess {
159
- const args = ['-raw', '-title', title, '-html', html, ...passthrough];
160
- return spawn('msgview', args, { stdio: ['ignore', 'inherit', 'inherit'], shell: true });
217
+ function launchMsgview(args: Args, html: string, title: string, detach: boolean): ChildProcess {
218
+ const child = spawn('msgview', argsToMsgviewArgs(args, title, html, detach), {
219
+ stdio: ['ignore', 'inherit', 'inherit'],
220
+ shell: true,
221
+ detached: detach
222
+ });
223
+ if (detach) child.unref();
224
+ return child;
161
225
  }
162
226
 
163
227
  async function main(): Promise<void> {
@@ -186,14 +250,19 @@ async function main(): Promise<void> {
186
250
  } catch (e: any) { console.error(`mdview: failed to save ${args.save}: ${e.message}`); process.exit(1); }
187
251
  }
188
252
 
189
- // One-shot: render, show, exit when host exits.
253
+ // Watch mode forces attached mdview must stay alive to watch + respawn.
254
+ const detach = args.detach && !args.watch;
255
+
256
+ // One-shot launch. Detached: fire and forget. Attached: wait for close.
190
257
  if (!args.watch) {
191
258
  if (host === 'msger') {
192
- const handle = await launchMsger(rendered.html, rendered.title, args.passthrough);
259
+ const handle = await launchMsger(args, rendered.html, rendered.title, detach);
260
+ if (detach) process.exit(0);
193
261
  await handle.result;
194
262
  process.exit(0);
195
263
  } else {
196
- const child = launchMsgview(rendered.html, rendered.title, args.passthrough);
264
+ const child = launchMsgview(args, rendered.html, rendered.title, detach);
265
+ if (detach) process.exit(0);
197
266
  child.on('exit', (code) => process.exit(code ?? 0));
198
267
  }
199
268
  return;
@@ -210,18 +279,18 @@ async function main(): Promise<void> {
210
279
  const r = renderSource(args);
211
280
  if (host === 'msger') {
212
281
  if (msgerHandle && !msgerHandle.closed) msgerHandle.close();
213
- msgerHandle = await launchMsger(r.html, r.title, args.passthrough);
282
+ msgerHandle = await launchMsger(args, r.html, r.title, false);
214
283
  } else {
215
284
  if (msgviewChild && !msgviewChild.killed) msgviewChild.kill();
216
- msgviewChild = launchMsgview(r.html, r.title, args.passthrough);
285
+ msgviewChild = launchMsgview(args, r.html, r.title, false);
217
286
  msgviewChild.on('exit', () => { msgviewChild = null; });
218
287
  }
219
288
  } catch (e: any) { console.error(`mdview: render failed: ${e.message}`); }
220
289
  };
221
290
 
222
291
  // Initial launch uses the already-rendered HTML to avoid a redundant read.
223
- if (host === 'msger') msgerHandle = await launchMsger(rendered.html, rendered.title, args.passthrough);
224
- else msgviewChild = launchMsgview(rendered.html, rendered.title, args.passthrough);
292
+ if (host === 'msger') msgerHandle = await launchMsger(args, rendered.html, rendered.title, false);
293
+ else msgviewChild = launchMsgview(args, rendered.html, rendered.title, false);
225
294
 
226
295
  fs.watch(absPath, { persistent: true }, () => {
227
296
  if (reloadTimer) clearTimeout(reloadTimer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mdview",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Render a markdown file and display it via msger or msgview",
5
5
  "type": "module",
6
6
  "main": "mdview.js",