jsmdcui 0.3.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/CHANGELOG.md +76 -0
- package/LICENSE +22 -0
- package/README.md +285 -0
- package/package.json +17 -0
- package/project_structure.txt +35 -0
- package/runmd.mjs +240 -0
- package/runtime/colorschemes/atom-dark.micro +33 -0
- package/runtime/colorschemes/bubblegum.micro +31 -0
- package/runtime/colorschemes/cmc-16.micro +47 -0
- package/runtime/colorschemes/cmc-tc.micro +43 -0
- package/runtime/colorschemes/darcula.micro +34 -0
- package/runtime/colorschemes/default.micro +1 -0
- package/runtime/colorschemes/dracula-tc.micro +49 -0
- package/runtime/colorschemes/dukedark-tc.micro +38 -0
- package/runtime/colorschemes/dukelight-tc.micro +38 -0
- package/runtime/colorschemes/dukeubuntu-tc.micro +38 -0
- package/runtime/colorschemes/geany.micro +29 -0
- package/runtime/colorschemes/gotham.micro +29 -0
- package/runtime/colorschemes/gruvbox-tc.micro +29 -0
- package/runtime/colorschemes/gruvbox.micro +26 -0
- package/runtime/colorschemes/material-tc.micro +36 -0
- package/runtime/colorschemes/monokai-dark.micro +28 -0
- package/runtime/colorschemes/monokai.micro +34 -0
- package/runtime/colorschemes/one-dark.micro +39 -0
- package/runtime/colorschemes/railscast.micro +37 -0
- package/runtime/colorschemes/simple.micro +33 -0
- package/runtime/colorschemes/solarized-tc.micro +31 -0
- package/runtime/colorschemes/solarized.micro +30 -0
- package/runtime/colorschemes/sunny-day.micro +29 -0
- package/runtime/colorschemes/twilight.micro +40 -0
- package/runtime/colorschemes/zenburn.micro +30 -0
- package/runtime/help/actions.md +161 -0
- package/runtime/help/cdp.md +119 -0
- package/runtime/help/colors.md +421 -0
- package/runtime/help/commands.md +161 -0
- package/runtime/help/copypaste.md +149 -0
- package/runtime/help/defaultkeys.md +148 -0
- package/runtime/help/help.md +285 -0
- package/runtime/help/keybindings.md +355 -0
- package/runtime/help/linter.md +90 -0
- package/runtime/help/options.md +709 -0
- package/runtime/help/plugins.md +544 -0
- package/runtime/help/tutorial.md +112 -0
- package/runtime/jsplugins/cdp/cdp-server.js +1161 -0
- package/runtime/jsplugins/cdp/cdp.js +192 -0
- package/runtime/jsplugins/chapter/chapter.js +108 -0
- package/runtime/jsplugins/diff/diff.js +46 -0
- package/runtime/jsplugins/example/example.js +110 -0
- package/runtime/jsplugins/linter/linter.js +281 -0
- package/runtime/plugins/autoclose/autoclose.lua +75 -0
- package/runtime/plugins/ftoptions/ftoptions.lua +17 -0
- package/runtime/plugins/literate/README.md +5 -0
- package/runtime/plugins/literate/literate.lua +55 -0
- package/runtime/plugins/status/help/status.md +21 -0
- package/runtime/plugins/status/status.lua +62 -0
- package/runtime/syntax/LICENSE +22 -0
- package/runtime/syntax/PowerShell.yaml +128 -0
- package/runtime/syntax/README.md +63 -0
- package/runtime/syntax/ada.yaml +43 -0
- package/runtime/syntax/apacheconf.yaml +59 -0
- package/runtime/syntax/arduino.yaml +101 -0
- package/runtime/syntax/asciidoc.yaml +51 -0
- package/runtime/syntax/asm.yaml +123 -0
- package/runtime/syntax/ats.yaml +99 -0
- package/runtime/syntax/awk.yaml +44 -0
- package/runtime/syntax/b.yaml +87 -0
- package/runtime/syntax/bat.yaml +57 -0
- package/runtime/syntax/c.yaml +60 -0
- package/runtime/syntax/caddyfile.yaml +23 -0
- package/runtime/syntax/cake.yaml +7 -0
- package/runtime/syntax/clojure.yaml +38 -0
- package/runtime/syntax/cmake.yaml +42 -0
- package/runtime/syntax/coffeescript.yaml +56 -0
- package/runtime/syntax/colortest.yaml +19 -0
- package/runtime/syntax/conky.yaml +17 -0
- package/runtime/syntax/cpp.yaml +91 -0
- package/runtime/syntax/crontab.yaml +36 -0
- package/runtime/syntax/crystal.yaml +72 -0
- package/runtime/syntax/csharp.yaml +52 -0
- package/runtime/syntax/css.yaml +44 -0
- package/runtime/syntax/csx.yaml +8 -0
- package/runtime/syntax/cuda.yaml +68 -0
- package/runtime/syntax/cython.yaml +52 -0
- package/runtime/syntax/d.yaml +121 -0
- package/runtime/syntax/dart.yaml +46 -0
- package/runtime/syntax/default.yaml +10 -0
- package/runtime/syntax/dockerfile.yaml +36 -0
- package/runtime/syntax/dot.yaml +29 -0
- package/runtime/syntax/elixir.yaml +30 -0
- package/runtime/syntax/elm.yaml +38 -0
- package/runtime/syntax/erb.yaml +42 -0
- package/runtime/syntax/erlang.yaml +45 -0
- package/runtime/syntax/fish.yaml +48 -0
- package/runtime/syntax/forth.yaml +34 -0
- package/runtime/syntax/fortran.yaml +64 -0
- package/runtime/syntax/freebsd-kernel.yaml +14 -0
- package/runtime/syntax/fsharp.yaml +48 -0
- package/runtime/syntax/gdscript.yaml +61 -0
- package/runtime/syntax/gemini.yaml +19 -0
- package/runtime/syntax/gentoo-ebuild.yaml +48 -0
- package/runtime/syntax/gentoo-etc-portage.yaml +23 -0
- package/runtime/syntax/git-commit.yaml +35 -0
- package/runtime/syntax/git-config.yaml +14 -0
- package/runtime/syntax/git-rebase-todo.yaml +19 -0
- package/runtime/syntax/gleam.yaml +69 -0
- package/runtime/syntax/glsl.yaml +26 -0
- package/runtime/syntax/gnuplot.yaml +15 -0
- package/runtime/syntax/go.yaml +62 -0
- package/runtime/syntax/godoc.yaml +17 -0
- package/runtime/syntax/golo.yaml +73 -0
- package/runtime/syntax/gomod.yaml +31 -0
- package/runtime/syntax/graphql.yaml +47 -0
- package/runtime/syntax/groff.yaml +30 -0
- package/runtime/syntax/groovy.yaml +111 -0
- package/runtime/syntax/haml.yaml +16 -0
- package/runtime/syntax/hare.yaml +52 -0
- package/runtime/syntax/haskell.yaml +52 -0
- package/runtime/syntax/hc.yaml +52 -0
- package/runtime/syntax/html.yaml +70 -0
- package/runtime/syntax/html4.yaml +25 -0
- package/runtime/syntax/html5.yaml +25 -0
- package/runtime/syntax/ini.yaml +23 -0
- package/runtime/syntax/inputrc.yaml +14 -0
- package/runtime/syntax/java.yaml +37 -0
- package/runtime/syntax/javascript.yaml +124 -0
- package/runtime/syntax/jinja2.yaml +19 -0
- package/runtime/syntax/json.yaml +39 -0
- package/runtime/syntax/jsonnet.yaml +92 -0
- package/runtime/syntax/julia.yaml +57 -0
- package/runtime/syntax/justfile.yaml +40 -0
- package/runtime/syntax/keymap.yaml +27 -0
- package/runtime/syntax/kickstart.yaml +16 -0
- package/runtime/syntax/kotlin.yaml +66 -0
- package/runtime/syntax/kvlang.yaml +67 -0
- package/runtime/syntax/ledger.yaml +14 -0
- package/runtime/syntax/lfe.yaml +17 -0
- package/runtime/syntax/lilypond.yaml +26 -0
- package/runtime/syntax/lisp.yaml +17 -0
- package/runtime/syntax/log.yaml +92 -0
- package/runtime/syntax/lua.yaml +111 -0
- package/runtime/syntax/mail.yaml +25 -0
- package/runtime/syntax/makefile.yaml +38 -0
- package/runtime/syntax/man.yaml +12 -0
- package/runtime/syntax/markdown.yaml +49 -0
- package/runtime/syntax/mc.yaml +23 -0
- package/runtime/syntax/meson.yaml +51 -0
- package/runtime/syntax/micro.yaml +34 -0
- package/runtime/syntax/mpdconf.yaml +13 -0
- package/runtime/syntax/msbuild.yaml +6 -0
- package/runtime/syntax/nanorc.yaml +16 -0
- package/runtime/syntax/nftables.yaml +30 -0
- package/runtime/syntax/nginx.yaml +22 -0
- package/runtime/syntax/nim.yaml +27 -0
- package/runtime/syntax/nix.yaml +32 -0
- package/runtime/syntax/nu.yaml +114 -0
- package/runtime/syntax/objc.yaml +60 -0
- package/runtime/syntax/ocaml.yaml +43 -0
- package/runtime/syntax/octave.yaml +83 -0
- package/runtime/syntax/odin.yaml +64 -0
- package/runtime/syntax/pascal.yaml +45 -0
- package/runtime/syntax/patch.yaml +14 -0
- package/runtime/syntax/peg.yaml +16 -0
- package/runtime/syntax/perl.yaml +58 -0
- package/runtime/syntax/php.yaml +60 -0
- package/runtime/syntax/pkg-config.yaml +12 -0
- package/runtime/syntax/po.yaml +12 -0
- package/runtime/syntax/pony.yaml +37 -0
- package/runtime/syntax/pov.yaml +21 -0
- package/runtime/syntax/privoxy-action.yaml +14 -0
- package/runtime/syntax/privoxy-config.yaml +10 -0
- package/runtime/syntax/privoxy-filter.yaml +12 -0
- package/runtime/syntax/proto.yaml +40 -0
- package/runtime/syntax/prql.yaml +84 -0
- package/runtime/syntax/puppet.yaml +22 -0
- package/runtime/syntax/python2.yaml +60 -0
- package/runtime/syntax/python3.yaml +80 -0
- package/runtime/syntax/r.yaml +32 -0
- package/runtime/syntax/raku.yaml +42 -0
- package/runtime/syntax/reST.yaml +18 -0
- package/runtime/syntax/renpy.yaml +15 -0
- package/runtime/syntax/rpmspec.yaml +43 -0
- package/runtime/syntax/ruby.yaml +73 -0
- package/runtime/syntax/rust.yaml +78 -0
- package/runtime/syntax/sage.yaml +60 -0
- package/runtime/syntax/scad.yaml +53 -0
- package/runtime/syntax/scala.yaml +33 -0
- package/runtime/syntax/sed.yaml +13 -0
- package/runtime/syntax/sh.yaml +69 -0
- package/runtime/syntax/sls.yaml +15 -0
- package/runtime/syntax/smalltalk.yaml +55 -0
- package/runtime/syntax/solidity.yaml +41 -0
- package/runtime/syntax/sql.yaml +35 -0
- package/runtime/syntax/stata.yaml +67 -0
- package/runtime/syntax/svelte.yaml +27 -0
- package/runtime/syntax/swift.yaml +103 -0
- package/runtime/syntax/systemd.yaml +16 -0
- package/runtime/syntax/tcl.yaml +18 -0
- package/runtime/syntax/terraform.yaml +87 -0
- package/runtime/syntax/tex.yaml +32 -0
- package/runtime/syntax/toml.yaml +56 -0
- package/runtime/syntax/twig.yaml +55 -0
- package/runtime/syntax/typescript.yaml +49 -0
- package/runtime/syntax/v.yaml +80 -0
- package/runtime/syntax/vala.yaml +26 -0
- package/runtime/syntax/verilog.yaml +60 -0
- package/runtime/syntax/vhdl.yaml +37 -0
- package/runtime/syntax/vi.yaml +31 -0
- package/runtime/syntax/vue.yaml +64 -0
- package/runtime/syntax/xml.yaml +37 -0
- package/runtime/syntax/xresources.yaml +14 -0
- package/runtime/syntax/yaml.yaml +34 -0
- package/runtime/syntax/yum.yaml +12 -0
- package/runtime/syntax/zig.yaml +52 -0
- package/runtime/syntax/zscript.yaml +72 -0
- package/runtime/syntax/zsh.yaml +52 -0
- package/single-exe/README.md +80 -0
- package/single-exe/assetsHelper.js +90 -0
- package/single-exe/assetsLoader.mjs +85 -0
- package/single-exe/compiled.js +149 -0
- package/single-exe/entry.mjs +9 -0
- package/single-exe/packAssets.sh +7 -0
- package/src/buffer/backup.js +160 -0
- package/src/buffer/buffer.js +126 -0
- package/src/buffer/fixed3-codec.js +140 -0
- package/src/buffer/loc.js +38 -0
- package/src/buffer/message.js +29 -0
- package/src/config/clean.js +172 -0
- package/src/config/colorscheme.js +99 -0
- package/src/config/config.js +122 -0
- package/src/config/defaults.js +109 -0
- package/src/cui/rpc.mjs +259 -0
- package/src/cui/server.mjs +116 -0
- package/src/display/ansi-style.js +60 -0
- package/src/highlight/highlighter.js +243 -0
- package/src/highlight/parser.js +225 -0
- package/src/index.js +8009 -0
- package/src/lua/engine.js +71 -0
- package/src/platform/archive.js +50 -0
- package/src/platform/clipboard.js +278 -0
- package/src/platform/commands.js +137 -0
- package/src/plugins/js-bridge.js +983 -0
- package/src/plugins/manager.js +674 -0
- package/src/runtime/assets.js +90 -0
- package/src/runtime/compiled.js +25 -0
- package/src/runtime/encodings.js +10 -0
- package/src/runtime/registry.js +134 -0
- package/src/screen/cell-buffer.js +81 -0
- package/src/screen/events.js +263 -0
- package/src/screen/screen.js +142 -0
- package/src/screen/vt100.js +571 -0
- package/src/shell/shell.js +70 -0
- package/testapp.md +55 -0
- package/tests/backup.test.js +133 -0
- package/tests/cmphex3b64.js +95 -0
- package/tests/pty-demo.js +492 -0
- package/tests/wv-client.js +96 -0
- package/tui +5 -0
- package/wui +5 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable user-visible changes to jsmdcui are documented here.
|
|
4
|
+
|
|
5
|
+
## [0.3.0] - 2026-07-16
|
|
6
|
+
|
|
7
|
+
Initial usable release, based on the bunmicro terminal editor.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Open local Markdown files as interactive, read-only terminal interfaces while
|
|
12
|
+
retaining navigation, selection, search, copy, mouse support, and automatic
|
|
13
|
+
reflow when the terminal is resized.
|
|
14
|
+
- Open HTTP(S) Markdown files in the terminal without generating local
|
|
15
|
+
companion files or executing their `javascript:` links.
|
|
16
|
+
- Start a browser interface with `--wui [FILE.md]`. Browser pages support normal
|
|
17
|
+
links, clickable `javascript:` actions, heading anchors, and task checkboxes
|
|
18
|
+
that can be toggled for the current page session.
|
|
19
|
+
- Build interactive Markdown apps with `js front`, `js back`, and
|
|
20
|
+
`javascript:` links. Frontend actions can use `alert`, `confirm`, `prompt`,
|
|
21
|
+
and call published backend functions through `rpc`.
|
|
22
|
+
- Activate local terminal actions with `Enter`, `Space`, or a left click, with
|
|
23
|
+
visible reporting for synchronous and asynchronous frontend errors.
|
|
24
|
+
- Generate five companion files beside each local Markdown source:
|
|
25
|
+
`.front.js`, `.back.js`, `.html`, `-rpc.js`, and `-server.js`.
|
|
26
|
+
- Print terminal output with `--cat`, print the bundled example source with
|
|
27
|
+
`--testapp.md`, and choose a WUI port with the `PORT` environment variable.
|
|
28
|
+
- Provide the `jsmdcui`, `tui`, and `wui` launchers, Bun scripts for common
|
|
29
|
+
development tasks, bundled runtime assets, and experimental single-executable
|
|
30
|
+
build commands.
|
|
31
|
+
- Retain the normal bunmicro-based editor for non-Markdown buffers, including
|
|
32
|
+
file editing, syntax highlighting, search and replace, undo and redo, tabs,
|
|
33
|
+
split panes, clipboard support, themes, and shell commands.
|
|
34
|
+
- Show this README as the built-in `Ctrl-G` help page.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- Local `.md` files now enter read-only Markdown UI mode automatically. Starting
|
|
39
|
+
jsmdcui without a file still opens the normal terminal editor.
|
|
40
|
+
- Opening or rendering a local Markdown file regenerates its five companion
|
|
41
|
+
files in terminal, `--cat`, and `--wui` modes.
|
|
42
|
+
- Running `--wui` without a file uses `testapp.md` in the current directory when
|
|
43
|
+
present, otherwise the bundled demo, and writes generated files in the current
|
|
44
|
+
directory.
|
|
45
|
+
- Every WUI start prints a fresh UUID-based page URL. Requests without the
|
|
46
|
+
trailing slash redirect to the canonical page URL.
|
|
47
|
+
- `js front` and `js back` blocks are removed from the displayed Markdown and
|
|
48
|
+
written to their generated modules.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- Preserved Markdown ANSI colors in the terminal UI and prevented the rendered
|
|
53
|
+
document background from obscuring the editor theme.
|
|
54
|
+
- Correctly detected links at the active terminal cell and loaded the matching
|
|
55
|
+
generated frontend module.
|
|
56
|
+
- Restored terminal display state after `alert`, `confirm`, and `prompt`.
|
|
57
|
+
- Reported frontend errors instead of letting them crash or silently fail.
|
|
58
|
+
- Corrected generated module paths and imports, supported bundled runtime
|
|
59
|
+
templates, and removed redundant file generation.
|
|
60
|
+
- Made JavaScript plugin commands available through command lookup and
|
|
61
|
+
completion, and added `js`, `py`, and `sh` choices for `eval` completion.
|
|
62
|
+
|
|
63
|
+
### Security
|
|
64
|
+
|
|
65
|
+
- Browser RPC discovery and calls expose only exported backend functions whose
|
|
66
|
+
exported names do not begin with `_`. This restriction applies to WUI RPC;
|
|
67
|
+
the local TUI imports the backend module directly.
|
|
68
|
+
- WUI pages use a fresh UUID path on each start. This reduces accidental
|
|
69
|
+
discovery but is not authentication or authorization.
|
|
70
|
+
- The WUI has no login or HTTPS, may be reachable through the machine's network
|
|
71
|
+
interfaces, and permits cross-origin RPC responses. Anyone who can reach it
|
|
72
|
+
and obtains the complete URL can call every backend function published by the
|
|
73
|
+
Markdown app.
|
|
74
|
+
- Frontend code runs in the browser, while terminal frontend code and backend
|
|
75
|
+
code can run with the permissions of the jsmdcui process. Only open or serve
|
|
76
|
+
Markdown apps from trusted sources.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016-2020: Zachary Yedidia, et al.
|
|
4
|
+
Copyright (c) 2026 Dr. John (醫者小智)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Introduction
|
|
2
|
+
- jsmdcui stands for:
|
|
3
|
+
- JavaScript Markdown Cross-environment User Interface
|
|
4
|
+
- The goal is to use Markdown as a Common UI for Terminals and Web Browsers
|
|
5
|
+
* TUI = Terminal User Interface
|
|
6
|
+
* WUI = Web User Interface
|
|
7
|
+
- .
|
|
8
|
+
- It's based on bunmicro, a terminal text editor derived from the Micro text editor
|
|
9
|
+
|
|
10
|
+
- Original projects:
|
|
11
|
+
- https://github.com/jjtseng93/bunmicro
|
|
12
|
+
- https://github.com/micro-editor/micro
|
|
13
|
+
|
|
14
|
+
## Quick start
|
|
15
|
+
|
|
16
|
+
jsmdcui requires [Bun](https://bun.com). On Android, install it in Termux:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm install -g bun
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
On other platforms, follow the [official Bun installation guide](https://bun.com/docs/installation).
|
|
23
|
+
|
|
24
|
+
Choose either of these two ways to run jsmdcui.
|
|
25
|
+
|
|
26
|
+
> **Important:** Opening or rendering a local `.md` file writes or overwrites
|
|
27
|
+
> five generated files beside it. Starting `--wui` without a file writes the
|
|
28
|
+
> five files generated from `testapp.md` in the current directory. The source
|
|
29
|
+
> Markdown is not changed, but you should run the demo in a directory where
|
|
30
|
+
> overwriting generated files is safe.
|
|
31
|
+
|
|
32
|
+
### Route 1: Run with npx
|
|
33
|
+
|
|
34
|
+
This route requires both `npx` and `bun` on your `PATH`; no source checkout is
|
|
35
|
+
required. Open the normal terminal editor:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
npx jsmdcui
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Or start the default browser demo:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npx jsmdcui --wui
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If the current directory already contains `testapp.md`, that local file is used
|
|
48
|
+
instead of the bundled demo. To open your own Markdown UI, pass its path:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npx jsmdcui app.md
|
|
52
|
+
npx jsmdcui --wui app.md
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Route 2: Clone the source
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
git clone https://github.com/jjtseng93/jsmdcui.git
|
|
59
|
+
cd jsmdcui
|
|
60
|
+
bun src/index.js testapp.md
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The last command opens the included demo in the terminal. Use the arrow keys to
|
|
64
|
+
move, `Enter` or `Space` to activate an item, and `Ctrl-Q` to quit. To open the
|
|
65
|
+
same demo in a browser instead:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
bun src/index.js --wui testapp.md
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
After starting `--wui`, open the last printed `http://...` URL in a browser.
|
|
72
|
+
Keep the command running while using the page, and press `Ctrl-C` in that
|
|
73
|
+
terminal to stop the server.
|
|
74
|
+
|
|
75
|
+
The command table below uses the cloned-source form. If you use npx, replace
|
|
76
|
+
`bun src/index.js` with `npx jsmdcui`.
|
|
77
|
+
|
|
78
|
+
| Command | Result |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `bun src/index.js app.md` | Render `app.md` as a read-only terminal UI and write five generated files beside it. |
|
|
81
|
+
| `bun src/index.js --cat app.md` | Render the terminal version to stdout, write five generated files beside it, and exit. |
|
|
82
|
+
| `bun src/index.js --testapp.md` | Write the bundled `testapp.md` source to stdout and exit. |
|
|
83
|
+
| `bun src/index.js --wui` | Use local `testapp.md` when present, otherwise use the bundled demo; write five generated files in the current directory, then print and serve a random URL. |
|
|
84
|
+
| `bun src/index.js --wui app.md` | Write five generated files beside `app.md`, then print and serve a random URL. |
|
|
85
|
+
| `PORT=8080 bun src/index.js --wui app.md` | Start the browser UI on another port. |
|
|
86
|
+
| `bun src/index.js` | Open the normal terminal editor with an empty buffer. |
|
|
87
|
+
|
|
88
|
+
Run `npx jsmdcui --help` or `bun src/index.js --help` for all command-line
|
|
89
|
+
options.
|
|
90
|
+
|
|
91
|
+
## Write a Markdown UI
|
|
92
|
+
|
|
93
|
+
Create `app.md`:
|
|
94
|
+
|
|
95
|
+
````md
|
|
96
|
+
# My app
|
|
97
|
+
|
|
98
|
+
- [Say hello](javascript:sayHello())
|
|
99
|
+
- [Get server time](javascript:showServerTime())
|
|
100
|
+
|
|
101
|
+
```js front
|
|
102
|
+
export function sayHello() {
|
|
103
|
+
const name = prompt("Your name:", "World");
|
|
104
|
+
if (name) alert(`Hello, ${name}!`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function showServerTime() {
|
|
108
|
+
const time = await rpc.getServerTime();
|
|
109
|
+
alert(time);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```js back
|
|
114
|
+
export function getServerTime() {
|
|
115
|
+
return new Date().toISOString();
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
````
|
|
119
|
+
|
|
120
|
+
Open it in either UI:
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
bun src/index.js app.md
|
|
124
|
+
bun src/index.js --wui app.md
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The three UI building blocks are:
|
|
128
|
+
|
|
129
|
+
- Regular Markdown provides headings, text, lists, task checkboxes, code, and
|
|
130
|
+
links.
|
|
131
|
+
- A `js front` block contains UI code. Exported functions can use
|
|
132
|
+
`alert`, `confirm`, `prompt`, and the generated `rpc` client.
|
|
133
|
+
- A `js back` block exports trusted backend functions. In the browser WUI,
|
|
134
|
+
`rpc` publishes only exported functions whose exported names do not start
|
|
135
|
+
with `_`. Call a published function from the front end with
|
|
136
|
+
`await rpc.functionName(arg1, arg2)`.
|
|
137
|
+
|
|
138
|
+
> An `_` prefix only hides a function from the browser WUI RPC interface. The
|
|
139
|
+
> local terminal UI imports the backend module directly, so `_` is a naming
|
|
140
|
+
> convention, not authentication or a security boundary. Use a name without
|
|
141
|
+
> `_` for a function that must work through RPC in both UIs.
|
|
142
|
+
|
|
143
|
+
Use a `javascript:` Markdown link to run front-end code:
|
|
144
|
+
|
|
145
|
+
```md
|
|
146
|
+
[Button label](javascript:exportedFunction())
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The front and back code blocks are extracted and are not shown in the rendered
|
|
150
|
+
UI. In the terminal, `rpc` calls the generated backend module directly. In the
|
|
151
|
+
browser, it sends the call to the relative `rpc` endpoint under the printed
|
|
152
|
+
UUID URL (`/<uuid>/rpc`).
|
|
153
|
+
|
|
154
|
+
## Terminal interaction
|
|
155
|
+
|
|
156
|
+
Markdown files automatically use `mdcui` mode. The rendered buffer is
|
|
157
|
+
read-only, but navigation, selection, search, and copy remain available.
|
|
158
|
+
|
|
159
|
+
| Input | Result |
|
|
160
|
+
| --- | --- |
|
|
161
|
+
| Arrow keys, `Home`, `End`, `PageUp`, `PageDown` | Move through the rendered UI. |
|
|
162
|
+
| `Enter` or `Space` | Activate the cell under the cursor. Put the cursor on a `javascript:` link to run it. |
|
|
163
|
+
| Left click | Move to and activate the clicked cell. A `javascript:` link runs immediately. |
|
|
164
|
+
| Mouse wheel | Scroll three rows at a time. |
|
|
165
|
+
| `Shift` + arrow keys | Select rendered text. |
|
|
166
|
+
| `Ctrl-C` | Copy the selection, or the current line when nothing is selected. |
|
|
167
|
+
| `Ctrl-A` | Select all rendered text. |
|
|
168
|
+
| `Ctrl-F` | Search; use `Ctrl-N` and `Ctrl-P` for the next and previous match. |
|
|
169
|
+
| `Ctrl-G` | Open the editor help. |
|
|
170
|
+
| `Alt-G` | Show or hide the shortcut bar. |
|
|
171
|
+
| `Ctrl-Q` or `Alt-Q` | Close the current UI. |
|
|
172
|
+
|
|
173
|
+
The terminal automatically reflows the Markdown when its width changes.
|
|
174
|
+
Only `javascript:` links execute in the TUI; ordinary web links behave as
|
|
175
|
+
normal links in the browser.
|
|
176
|
+
|
|
177
|
+
## Browser interaction
|
|
178
|
+
|
|
179
|
+
The WUI uses normal browser mouse and keyboard behavior. Clicking a
|
|
180
|
+
`javascript:` link calls its front-end function, regular links navigate
|
|
181
|
+
normally, and task checkboxes can be toggled. `alert`, `confirm`, and `prompt`
|
|
182
|
+
use the browser's built-in dialogs. Checkbox changes exist only in the current
|
|
183
|
+
page: refreshing does not preserve them and does not update the Markdown file.
|
|
184
|
+
|
|
185
|
+
The WUI uses port `3000` by default and accepts connections through the
|
|
186
|
+
machine's available network interfaces. The printed `localhost` URL is for the
|
|
187
|
+
same machine. From another device on the same network, replace `localhost` with
|
|
188
|
+
the server machine's IP address and keep the same port and full path.
|
|
189
|
+
|
|
190
|
+
Each server start prints a new random path. The old URL stops working after the
|
|
191
|
+
server is stopped or restarted. Keep the process running while using the page,
|
|
192
|
+
and press `Ctrl-C` in its terminal to stop it.
|
|
193
|
+
|
|
194
|
+
## Generated files
|
|
195
|
+
|
|
196
|
+
Opening a local Markdown UI generates these files beside the source file:
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
app.md.front.js
|
|
200
|
+
app.md.back.js
|
|
201
|
+
app.md.html
|
|
202
|
+
app.md-rpc.js
|
|
203
|
+
app.md-server.js
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
They are regenerated from `app.md`, so edit the Markdown source rather than the
|
|
207
|
+
generated files. The source directory must be writable.
|
|
208
|
+
|
|
209
|
+
## Security
|
|
210
|
+
|
|
211
|
+
A Markdown UI is an executable application, not a passive document. Starting a
|
|
212
|
+
WUI loads its backend module, loading the page runs its frontend module, and
|
|
213
|
+
activating a local terminal `javascript:` link runs frontend code. Backend and
|
|
214
|
+
terminal code can read or change files, start programs, access the network, and
|
|
215
|
+
read environment data with the permissions of the jsmdcui process. Only open
|
|
216
|
+
or serve Markdown UI files that you trust.
|
|
217
|
+
|
|
218
|
+
### WUI network exposure
|
|
219
|
+
|
|
220
|
+
> **Warning:** The WUI is intended for local or trusted-network use. It is not
|
|
221
|
+
> a production web server.
|
|
222
|
+
|
|
223
|
+
- There is no login, per-user authorization, or HTTPS. Traffic and results are
|
|
224
|
+
sent over plain HTTP.
|
|
225
|
+
- The server may be reachable from other devices through the machine's network
|
|
226
|
+
interfaces, even though the printed URL says `localhost`.
|
|
227
|
+
- The random path makes the URL harder to guess, but it is not a password.
|
|
228
|
+
Anyone who can reach the server and obtains the complete URL can load the
|
|
229
|
+
page and call every backend function published through WUI RPC, using
|
|
230
|
+
arguments they choose.
|
|
231
|
+
- A backend RPC function runs with the same operating-system permissions as
|
|
232
|
+
jsmdcui. Its code determines what files, commands, network services, or
|
|
233
|
+
secrets a visitor may be able to reach.
|
|
234
|
+
- Do not share the complete URL, forward the port to the public internet, or
|
|
235
|
+
run the WUI on an untrusted network. Use a firewall when needed and stop the
|
|
236
|
+
server with `Ctrl-C` as soon as you finish.
|
|
237
|
+
- Prefixing a backend export with `_` keeps it out of WUI RPC discovery and
|
|
238
|
+
calls, but it does not protect the backend module from trusted local code and
|
|
239
|
+
is not a substitute for authentication.
|
|
240
|
+
|
|
241
|
+
## Development
|
|
242
|
+
|
|
243
|
+
```sh
|
|
244
|
+
npm run tui
|
|
245
|
+
npm run wui
|
|
246
|
+
npm run check
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`testapp.md` is the main working example.
|
|
250
|
+
|
|
251
|
+
testapp.md
|
|
252
|
+
│
|
|
253
|
+
┌──────────────┴──────────────┐
|
|
254
|
+
│ │
|
|
255
|
+
▼ ▼
|
|
256
|
+
Browser HTML TUI ANSI
|
|
257
|
+
│ │
|
|
258
|
+
javascript:foo() extract javascript:
|
|
259
|
+
│ │
|
|
260
|
+
▼ ▼
|
|
261
|
+
window.frontFunc() evalFront(frontMod, text)
|
|
262
|
+
│ │
|
|
263
|
+
└──────────────┬──────────────┘
|
|
264
|
+
▼
|
|
265
|
+
testapp.md.front.js
|
|
266
|
+
│
|
|
267
|
+
rpc.someFunc()
|
|
268
|
+
┌───────────┴───────────┐
|
|
269
|
+
│ │
|
|
270
|
+
Browser TUI
|
|
271
|
+
│ │
|
|
272
|
+
RPC Proxy client import * as rpc
|
|
273
|
+
│ from back module
|
|
274
|
+
▼ │
|
|
275
|
+
fetch rpc │
|
|
276
|
+
│ │
|
|
277
|
+
▼ │
|
|
278
|
+
server.mjs │
|
|
279
|
+
│ │
|
|
280
|
+
▼ │
|
|
281
|
+
evalBack(backMod, reqjson) │
|
|
282
|
+
│ │
|
|
283
|
+
└───────────┬───────────┘
|
|
284
|
+
▼
|
|
285
|
+
testapp.md.back.js
|
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jsmdcui",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Markdown as a Common UI for Terminals and Web Browsers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"bin": {
|
|
9
|
+
"jsmdcui": "./src/index.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"start": "bun ./src/index.js",
|
|
13
|
+
"tui": "bun ./src/index.js ./testapp.md",
|
|
14
|
+
"wui": "bun ./runmd.mjs",
|
|
15
|
+
"check": "node --check ./src/index.js"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
testapp.md
|
|
2
|
+
│
|
|
3
|
+
┌──────────────┴──────────────┐
|
|
4
|
+
│ │
|
|
5
|
+
▼ ▼
|
|
6
|
+
Browser HTML TUI ANSI
|
|
7
|
+
│ │
|
|
8
|
+
javascript:foo() extract javascript:
|
|
9
|
+
│ │
|
|
10
|
+
▼ ▼
|
|
11
|
+
window.frontFunc() evalFront(frontMod, text)
|
|
12
|
+
│ │
|
|
13
|
+
└──────────────┬──────────────┘
|
|
14
|
+
▼
|
|
15
|
+
testapp.md.front.js
|
|
16
|
+
│
|
|
17
|
+
rpc.someFunc()
|
|
18
|
+
┌───────────┴───────────┐
|
|
19
|
+
│ │
|
|
20
|
+
Browser TUI
|
|
21
|
+
│ │
|
|
22
|
+
RPC Proxy client import * as rpc
|
|
23
|
+
│ from back module
|
|
24
|
+
▼ │
|
|
25
|
+
fetch rpc │
|
|
26
|
+
│ │
|
|
27
|
+
▼ │
|
|
28
|
+
server.mjs │
|
|
29
|
+
│ │
|
|
30
|
+
▼ │
|
|
31
|
+
evalBack(backMod, reqjson) │
|
|
32
|
+
│ │
|
|
33
|
+
└───────────┬───────────┘
|
|
34
|
+
▼
|
|
35
|
+
testapp.md.back.js
|
package/runmd.mjs
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { pathToFileURL } from 'node:url'
|
|
5
|
+
import { readInternalAssetText } from './src/runtime/assets.js'
|
|
6
|
+
import { REPO_ROOT } from './single-exe/compiled.js'
|
|
7
|
+
|
|
8
|
+
const csl=console.log
|
|
9
|
+
const mda=Bun.markdown.ansi
|
|
10
|
+
const mdh=Bun.markdown.html
|
|
11
|
+
const jss=JSON.stringify
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const TEST_ROW=9
|
|
15
|
+
const TEST_COL=5
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
function logWroteFile(label,path)
|
|
19
|
+
{
|
|
20
|
+
csl(mda(`- Wrote to ${label} file: ${path}`))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function readTemplate(pathname)
|
|
24
|
+
{
|
|
25
|
+
return readInternalAssetText(pathname) ??
|
|
26
|
+
await Bun.file(path.join(REPO_ROOT, pathname)).text()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function readMarkdownInput(mdpath)
|
|
30
|
+
{
|
|
31
|
+
const file = Bun.file(mdpath);
|
|
32
|
+
if (await file.exists()) return await file.text();
|
|
33
|
+
const assetName = path.basename(mdpath);
|
|
34
|
+
const internalText = readInternalAssetText(assetName);
|
|
35
|
+
if (internalText != null) return internalText;
|
|
36
|
+
const fallbackPath = path.join(REPO_ROOT, assetName);
|
|
37
|
+
const fallback = Bun.file(fallbackPath);
|
|
38
|
+
if (await fallback.exists()) return await fallback.text();
|
|
39
|
+
throw new Error(`md file not found: ${mdpath}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
export async function main(tuiWidth=30)
|
|
44
|
+
{
|
|
45
|
+
const mdpath = process.argv.filter(i=>i.endsWith('.md'))[0] || 'testapp.md'
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
// 1. Read markdown file
|
|
49
|
+
console.error('Reading:',mdpath)
|
|
50
|
+
let md = await readMarkdownInput(mdpath)
|
|
51
|
+
|
|
52
|
+
// 2. Extract js files
|
|
53
|
+
md = await extractJs(md,mdpath);
|
|
54
|
+
|
|
55
|
+
// 3. Create Terminal UI
|
|
56
|
+
let tui = createTui(md,tuiWidth)
|
|
57
|
+
csl(mda("\n# TUI"))
|
|
58
|
+
csl(tui)
|
|
59
|
+
csl(mda('## TUI raw'))
|
|
60
|
+
csl(jss(tui))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
// 4. Create Web UI
|
|
64
|
+
let wui = await createWui(md,mdpath)
|
|
65
|
+
csl(mda('\n# HTML'))
|
|
66
|
+
csl(wui)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
// 5. Get character from point for TUI
|
|
70
|
+
let ch = charFromPoint(tui,TEST_ROW,TEST_COL)
|
|
71
|
+
|
|
72
|
+
csl(mda(
|
|
73
|
+
'# Slicing row,col: '+TEST_ROW+','+TEST_COL
|
|
74
|
+
))
|
|
75
|
+
|
|
76
|
+
csl(jss(ch))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
const serverPath = mdpath + "-server.js"
|
|
80
|
+
const svmod = await import(pathToFileURL(path.resolve(serverPath)).href)
|
|
81
|
+
|
|
82
|
+
csl("\n\n"+mda('# Server'))
|
|
83
|
+
svmod.main();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
// Exports
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
export async function extractJs(md,mdpath)
|
|
91
|
+
{
|
|
92
|
+
const mdb = path.basename(mdpath)
|
|
93
|
+
|
|
94
|
+
let sctagsp = mdpath + ".front.js"
|
|
95
|
+
let sctags = ""
|
|
96
|
+
// Gather frontend script tags
|
|
97
|
+
let reJs = /```js front[^]+?```/g //
|
|
98
|
+
md = md.replace( reJs,
|
|
99
|
+
i=>{
|
|
100
|
+
sctags+=i.slice(11,-3)+'\n\n'
|
|
101
|
+
|
|
102
|
+
return '';
|
|
103
|
+
return i
|
|
104
|
+
.replace('```js front',"<scr"+"ipt>")
|
|
105
|
+
.slice(0,-3)+"</scr"+"ipt>"
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
sctags = "#!/usr/bin/env bun" + `
|
|
110
|
+
|
|
111
|
+
import { rpc as wuiRpcClient } from "./${mdb}-rpc.js";
|
|
112
|
+
let rpc = "${mdb}"
|
|
113
|
+
if(globalThis.process)
|
|
114
|
+
rpc = await import("./"+rpc+".back.js") ;
|
|
115
|
+
else
|
|
116
|
+
rpc = wuiRpcClient ;
|
|
117
|
+
|
|
118
|
+
` + sctags + `
|
|
119
|
+
|
|
120
|
+
if (typeof window !== "undefined")
|
|
121
|
+
{
|
|
122
|
+
// Browser
|
|
123
|
+
setTimeout( () => {
|
|
124
|
+
import("./${mdb}.front.js").then(mod=>{
|
|
125
|
+
Object.assign(window,mod);
|
|
126
|
+
})
|
|
127
|
+
}, 0 ) ;
|
|
128
|
+
}
|
|
129
|
+
` ;
|
|
130
|
+
|
|
131
|
+
await Bun.write(sctagsp,sctags);
|
|
132
|
+
logWroteFile("front", sctagsp)
|
|
133
|
+
|
|
134
|
+
sctagsp = mdpath + ".back.js"
|
|
135
|
+
sctags = "#!/usr/bin/env bun\n\n"
|
|
136
|
+
// Gather backend script tags
|
|
137
|
+
reJs = /```js back[^]+?```/g //
|
|
138
|
+
md = md.replace( reJs,
|
|
139
|
+
i=>{
|
|
140
|
+
sctags+=i.slice(10,-3)+'\n\n'
|
|
141
|
+
|
|
142
|
+
return '';
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
await Bun.write(sctagsp,sctags);
|
|
147
|
+
logWroteFile("back", sctagsp)
|
|
148
|
+
|
|
149
|
+
await writeRuntimeFiles(mdpath)
|
|
150
|
+
|
|
151
|
+
return md
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export async function writeRuntimeFiles(mdpath)
|
|
155
|
+
{
|
|
156
|
+
const mdb = path.basename(mdpath)
|
|
157
|
+
const rpcPath = mdpath + "-rpc.js"
|
|
158
|
+
const serverPath = mdpath + "-server.js"
|
|
159
|
+
const rpcSource = await readTemplate("src/cui/rpc.mjs")
|
|
160
|
+
const serverSource = (await readTemplate("src/cui/server.mjs"))
|
|
161
|
+
.replaceAll("./rpc.mjs", `./${mdb}-rpc.js`)
|
|
162
|
+
.replaceAll("testapp.md", mdb)
|
|
163
|
+
|
|
164
|
+
await Bun.write(rpcPath, rpcSource)
|
|
165
|
+
logWroteFile("rpc", rpcPath)
|
|
166
|
+
await Bun.write(serverPath, serverSource)
|
|
167
|
+
logWroteFile("server", serverPath)
|
|
168
|
+
|
|
169
|
+
return serverPath
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
export function createTui(md,TERMINAL_WIDTH=30) // ANSI Colors
|
|
174
|
+
{
|
|
175
|
+
md = ( Bun?.markdown?.ansi?.(
|
|
176
|
+
md,{
|
|
177
|
+
hyperlinks:true,
|
|
178
|
+
columns:TERMINAL_WIDTH
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
|| md )+'' ;
|
|
182
|
+
|
|
183
|
+
return md ;
|
|
184
|
+
|
|
185
|
+
return Bun.wrapAnsi(
|
|
186
|
+
md,
|
|
187
|
+
TERMINAL_WIDTH
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export async function createWui(md,mdpath) // HTML
|
|
192
|
+
{
|
|
193
|
+
|
|
194
|
+
const opts = {
|
|
195
|
+
headings: { ids: true }
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
md = (Bun?.markdown?.html?.(md,opts) || md)+'' ;
|
|
199
|
+
|
|
200
|
+
// Restore single quotes
|
|
201
|
+
let reHrefs = /href="[^"]*?"/g // "
|
|
202
|
+
md = md.replace( reHrefs,
|
|
203
|
+
i=>i.replaceAll(''',"'")
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
md = md.replaceAll(
|
|
208
|
+
'class="task-list-item-checkbox" disabled',
|
|
209
|
+
'class="task-list-item-checkbox"'
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
const mdb = path.basename(mdpath);
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
md += `
|
|
216
|
+
|
|
217
|
+
<scr`+`ipt type="module" src="./${mdb}.front.js">
|
|
218
|
+
</scr`+`ipt>
|
|
219
|
+
|
|
220
|
+
`;
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
await Bun.write(mdpath+".html",md)
|
|
224
|
+
logWroteFile("html", mdpath+".html")
|
|
225
|
+
|
|
226
|
+
return md;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function charFromPoint(tui,row,col)
|
|
230
|
+
{
|
|
231
|
+
tui = tui.split('\n')[row-1] || ""
|
|
232
|
+
return Bun.sliceAnsi(tui,col-1,col)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
if(import.meta.main)
|
|
237
|
+
main().catch(e=>{
|
|
238
|
+
console.error(e?.message || e)
|
|
239
|
+
process.exit(127)
|
|
240
|
+
});
|