@react-x11/components 0.1.0 → 0.2.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 +979 -21
- package/dist/ansi/cast.d.ts +48 -0
- package/dist/ansi/cast.d.ts.map +1 -0
- package/dist/ansi/cast.js +135 -0
- package/dist/ansi/cast.js.map +1 -0
- package/dist/ansi/index.d.ts +10 -0
- package/dist/ansi/index.d.ts.map +1 -0
- package/dist/ansi/index.js +27 -0
- package/dist/ansi/index.js.map +1 -0
- package/dist/ansi/palette.d.ts +79 -0
- package/dist/ansi/palette.d.ts.map +1 -0
- package/dist/ansi/palette.js +155 -0
- package/dist/ansi/palette.js.map +1 -0
- package/dist/ansi/parse.d.ts +114 -0
- package/dist/ansi/parse.d.ts.map +1 -0
- package/dist/ansi/parse.js +687 -0
- package/dist/ansi/parse.js.map +1 -0
- package/dist/ansi/sgr.d.ts +87 -0
- package/dist/ansi/sgr.d.ts.map +1 -0
- package/dist/ansi/sgr.js +302 -0
- package/dist/ansi/sgr.js.map +1 -0
- package/dist/ansi/utf8.d.ts +15 -0
- package/dist/ansi/utf8.d.ts.map +1 -0
- package/dist/ansi/utf8.js +82 -0
- package/dist/ansi/utf8.js.map +1 -0
- package/dist/calendar/Calendar.d.ts +136 -0
- package/dist/calendar/Calendar.d.ts.map +1 -0
- package/dist/calendar/Calendar.js +460 -0
- package/dist/calendar/Calendar.js.map +1 -0
- package/dist/calendar/DatePicker.d.ts +52 -0
- package/dist/calendar/DatePicker.d.ts.map +1 -0
- package/dist/calendar/DatePicker.js +257 -0
- package/dist/calendar/DatePicker.js.map +1 -0
- package/dist/calendar/dates.d.ts +90 -0
- package/dist/calendar/dates.d.ts.map +1 -0
- package/dist/calendar/dates.js +236 -0
- package/dist/calendar/dates.js.map +1 -0
- package/dist/calendar/index.d.ts +8 -0
- package/dist/calendar/index.d.ts.map +1 -0
- package/dist/calendar/index.js +15 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/charts/components.d.ts +141 -0
- package/dist/charts/components.d.ts.map +1 -0
- package/dist/charts/components.js +580 -0
- package/dist/charts/components.js.map +1 -0
- package/dist/charts/data.d.ts +198 -0
- package/dist/charts/data.d.ts.map +1 -0
- package/dist/charts/data.js +616 -0
- package/dist/charts/data.js.map +1 -0
- package/dist/charts/hx.d.ts +21 -0
- package/dist/charts/hx.d.ts.map +1 -0
- package/dist/charts/hx.js +15 -0
- package/dist/charts/hx.js.map +1 -0
- package/dist/charts/index.d.ts +27 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +38 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/node.d.ts +96 -0
- package/dist/charts/node.d.ts.map +1 -0
- package/dist/charts/node.js +720 -0
- package/dist/charts/node.js.map +1 -0
- package/dist/charts/render.d.ts +153 -0
- package/dist/charts/render.d.ts.map +1 -0
- package/dist/charts/render.js +762 -0
- package/dist/charts/render.js.map +1 -0
- package/dist/charts/scale.d.ts +42 -0
- package/dist/charts/scale.d.ts.map +1 -0
- package/dist/charts/scale.js +173 -0
- package/dist/charts/scale.js.map +1 -0
- package/dist/charts/spec.d.ts +91 -0
- package/dist/charts/spec.d.ts.map +1 -0
- package/dist/charts/spec.js +33 -0
- package/dist/charts/spec.js.map +1 -0
- package/dist/charts/timers.d.ts +6 -0
- package/dist/charts/timers.d.ts.map +1 -0
- package/dist/charts/timers.js +14 -0
- package/dist/charts/timers.js.map +1 -0
- package/dist/code/hx.d.ts +24 -0
- package/dist/code/hx.d.ts.map +1 -0
- package/dist/code/hx.js +25 -0
- package/dist/code/hx.js.map +1 -0
- package/dist/code/index.d.ts +45 -0
- package/dist/code/index.d.ts.map +1 -0
- package/dist/code/index.js +93 -0
- package/dist/code/index.js.map +1 -0
- package/dist/code-editor/completion.d.ts +26 -0
- package/dist/code-editor/completion.d.ts.map +1 -0
- package/dist/code-editor/completion.js +129 -0
- package/dist/code-editor/completion.js.map +1 -0
- package/dist/code-editor/doc.d.ts +35 -0
- package/dist/code-editor/doc.d.ts.map +1 -0
- package/dist/code-editor/doc.js +162 -0
- package/dist/code-editor/doc.js.map +1 -0
- package/dist/code-editor/hx.d.ts +13 -0
- package/dist/code-editor/hx.d.ts.map +1 -0
- package/dist/code-editor/hx.js +10 -0
- package/dist/code-editor/hx.js.map +1 -0
- package/dist/code-editor/index.d.ts +88 -0
- package/dist/code-editor/index.d.ts.map +1 -0
- package/dist/code-editor/index.js +401 -0
- package/dist/code-editor/index.js.map +1 -0
- package/dist/code-editor/node.d.ts +343 -0
- package/dist/code-editor/node.d.ts.map +1 -0
- package/dist/code-editor/node.js +1521 -0
- package/dist/code-editor/node.js.map +1 -0
- package/dist/code-language/hljs.d.ts +47 -0
- package/dist/code-language/hljs.d.ts.map +1 -0
- package/dist/code-language/hljs.js +211 -0
- package/dist/code-language/hljs.js.map +1 -0
- package/dist/code-language/index.d.ts +22 -0
- package/dist/code-language/index.d.ts.map +1 -0
- package/dist/code-language/index.js +20 -0
- package/dist/code-language/index.js.map +1 -0
- package/dist/code-language/languages/glsl.d.ts +4 -0
- package/dist/code-language/languages/glsl.d.ts.map +1 -0
- package/dist/code-language/languages/glsl.js +99 -0
- package/dist/code-language/languages/glsl.js.map +1 -0
- package/dist/code-language/languages/javascript.d.ts +10 -0
- package/dist/code-language/languages/javascript.d.ts.map +1 -0
- package/dist/code-language/languages/javascript.js +360 -0
- package/dist/code-language/languages/javascript.js.map +1 -0
- package/dist/code-language/languages/json.d.ts +4 -0
- package/dist/code-language/languages/json.d.ts.map +1 -0
- package/dist/code-language/languages/json.js +68 -0
- package/dist/code-language/languages/json.js.map +1 -0
- package/dist/code-language/languages/shell.d.ts +4 -0
- package/dist/code-language/languages/shell.d.ts.map +1 -0
- package/dist/code-language/languages/shell.js +189 -0
- package/dist/code-language/languages/shell.js.map +1 -0
- package/dist/code-language/languages/sql.d.ts +11 -0
- package/dist/code-language/languages/sql.d.ts.map +1 -0
- package/dist/code-language/languages/sql.js +133 -0
- package/dist/code-language/languages/sql.js.map +1 -0
- package/dist/code-language/lezer.d.ts +24 -0
- package/dist/code-language/lezer.d.ts.map +1 -0
- package/dist/code-language/lezer.js +148 -0
- package/dist/code-language/lezer.js.map +1 -0
- package/dist/code-language/registry.d.ts +19 -0
- package/dist/code-language/registry.d.ts.map +1 -0
- package/dist/code-language/registry.js +56 -0
- package/dist/code-language/registry.js.map +1 -0
- package/dist/code-language/runs.d.ts +35 -0
- package/dist/code-language/runs.d.ts.map +1 -0
- package/dist/code-language/runs.js +88 -0
- package/dist/code-language/runs.js.map +1 -0
- package/dist/code-language/stream.d.ts +70 -0
- package/dist/code-language/stream.d.ts.map +1 -0
- package/dist/code-language/stream.js +243 -0
- package/dist/code-language/stream.js.map +1 -0
- package/dist/code-language/textmate.d.ts +27 -0
- package/dist/code-language/textmate.d.ts.map +1 -0
- package/dist/code-language/textmate.js +86 -0
- package/dist/code-language/textmate.js.map +1 -0
- package/dist/code-language/theme.d.ts +26 -0
- package/dist/code-language/theme.d.ts.map +1 -0
- package/dist/code-language/theme.js +108 -0
- package/dist/code-language/theme.js.map +1 -0
- package/dist/code-language/timers.d.ts +7 -0
- package/dist/code-language/timers.d.ts.map +1 -0
- package/dist/code-language/timers.js +22 -0
- package/dist/code-language/timers.js.map +1 -0
- package/dist/code-language/types.d.ts +173 -0
- package/dist/code-language/types.d.ts.map +1 -0
- package/dist/code-language/types.js +41 -0
- package/dist/code-language/types.js.map +1 -0
- package/dist/codeblock/index.d.ts +69 -0
- package/dist/codeblock/index.d.ts.map +1 -0
- package/dist/codeblock/index.js +85 -0
- package/dist/codeblock/index.js.map +1 -0
- package/dist/color-picker/ColorField.d.ts +39 -0
- package/dist/color-picker/ColorField.d.ts.map +1 -0
- package/dist/color-picker/ColorField.js +239 -0
- package/dist/color-picker/ColorField.js.map +1 -0
- package/dist/color-picker/ColorPicker.d.ts +109 -0
- package/dist/color-picker/ColorPicker.d.ts.map +1 -0
- package/dist/color-picker/ColorPicker.js +757 -0
- package/dist/color-picker/ColorPicker.js.map +1 -0
- package/dist/color-picker/color.d.ts +105 -0
- package/dist/color-picker/color.d.ts.map +1 -0
- package/dist/color-picker/color.js +313 -0
- package/dist/color-picker/color.js.map +1 -0
- package/dist/color-picker/index.d.ts +8 -0
- package/dist/color-picker/index.d.ts.map +1 -0
- package/dist/color-picker/index.js +19 -0
- package/dist/color-picker/index.js.map +1 -0
- package/dist/desktop-calendar/eds.d.ts +102 -0
- package/dist/desktop-calendar/eds.d.ts.map +1 -0
- package/dist/desktop-calendar/eds.js +356 -0
- package/dist/desktop-calendar/eds.js.map +1 -0
- package/dist/desktop-calendar/ical.d.ts +63 -0
- package/dist/desktop-calendar/ical.d.ts.map +1 -0
- package/dist/desktop-calendar/ical.js +57 -0
- package/dist/desktop-calendar/ical.js.map +1 -0
- package/dist/desktop-calendar/index.d.ts +72 -0
- package/dist/desktop-calendar/index.d.ts.map +1 -0
- package/dist/desktop-calendar/index.js +213 -0
- package/dist/desktop-calendar/index.js.map +1 -0
- package/dist/embed/client.d.ts +121 -0
- package/dist/embed/client.d.ts.map +1 -0
- package/dist/embed/client.js +203 -0
- package/dist/embed/client.js.map +1 -0
- package/dist/embed/host.d.ts +96 -0
- package/dist/embed/host.d.ts.map +1 -0
- package/dist/embed/host.js +266 -0
- package/dist/embed/host.js.map +1 -0
- package/dist/embed/index.d.ts +5 -0
- package/dist/embed/index.d.ts.map +1 -0
- package/dist/embed/index.js +13 -0
- package/dist/embed/index.js.map +1 -0
- package/dist/embed/timers.d.ts +6 -0
- package/dist/embed/timers.d.ts.map +1 -0
- package/dist/embed/timers.js +16 -0
- package/dist/embed/timers.js.map +1 -0
- package/dist/flow/draw.d.ts +45 -0
- package/dist/flow/draw.d.ts.map +1 -0
- package/dist/flow/draw.js +295 -0
- package/dist/flow/draw.js.map +1 -0
- package/dist/flow/index.d.ts +64 -0
- package/dist/flow/index.d.ts.map +1 -0
- package/dist/flow/index.js +306 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/flow/model.d.ts +158 -0
- package/dist/flow/model.d.ts.map +1 -0
- package/dist/flow/model.js +566 -0
- package/dist/flow/model.js.map +1 -0
- package/dist/flow/node.d.ts +429 -0
- package/dist/flow/node.d.ts.map +1 -0
- package/dist/flow/node.js +3025 -0
- package/dist/flow/node.js.map +1 -0
- package/dist/flow/paths.d.ts +43 -0
- package/dist/flow/paths.d.ts.map +1 -0
- package/dist/flow/paths.js +327 -0
- package/dist/flow/paths.js.map +1 -0
- package/dist/flow/types.d.ts +561 -0
- package/dist/flow/types.d.ts.map +1 -0
- package/dist/flow/types.js +2 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/formula/hx.d.ts +24 -0
- package/dist/formula/hx.d.ts.map +1 -0
- package/dist/formula/hx.js +25 -0
- package/dist/formula/hx.js.map +1 -0
- package/dist/formula/index.d.ts +74 -0
- package/dist/formula/index.d.ts.map +1 -0
- package/dist/formula/index.js +155 -0
- package/dist/formula/index.js.map +1 -0
- package/dist/formula/katex.d.ts +78 -0
- package/dist/formula/katex.d.ts.map +1 -0
- package/dist/formula/katex.js +130 -0
- package/dist/formula/katex.js.map +1 -0
- package/dist/formula/layout.d.ts +103 -0
- package/dist/formula/layout.d.ts.map +1 -0
- package/dist/formula/layout.js +716 -0
- package/dist/formula/layout.js.map +1 -0
- package/dist/formula/node.d.ts +50 -0
- package/dist/formula/node.d.ts.map +1 -0
- package/dist/formula/node.js +351 -0
- package/dist/formula/node.js.map +1 -0
- package/dist/html/controls.d.ts +48 -0
- package/dist/html/controls.d.ts.map +1 -0
- package/dist/html/controls.js +195 -0
- package/dist/html/controls.js.map +1 -0
- package/dist/html/css/cascade.d.ts +51 -0
- package/dist/html/css/cascade.d.ts.map +1 -0
- package/dist/html/css/cascade.js +552 -0
- package/dist/html/css/cascade.js.map +1 -0
- package/dist/html/css/parse.d.ts +74 -0
- package/dist/html/css/parse.d.ts.map +1 -0
- package/dist/html/css/parse.js +464 -0
- package/dist/html/css/parse.js.map +1 -0
- package/dist/html/css/style.d.ts +142 -0
- package/dist/html/css/style.d.ts.map +1 -0
- package/dist/html/css/style.js +1145 -0
- package/dist/html/css/style.js.map +1 -0
- package/dist/html/css/ua.d.ts +5 -0
- package/dist/html/css/ua.d.ts.map +1 -0
- package/dist/html/css/ua.js +171 -0
- package/dist/html/css/ua.js.map +1 -0
- package/dist/html/css/values.d.ts +78 -0
- package/dist/html/css/values.d.ts.map +1 -0
- package/dist/html/css/values.js +330 -0
- package/dist/html/css/values.js.map +1 -0
- package/dist/html/dom.d.ts +112 -0
- package/dist/html/dom.d.ts.map +1 -0
- package/dist/html/dom.js +374 -0
- package/dist/html/dom.js.map +1 -0
- package/dist/html/hx.d.ts +24 -0
- package/dist/html/hx.d.ts.map +1 -0
- package/dist/html/hx.js +29 -0
- package/dist/html/hx.js.map +1 -0
- package/dist/html/index.d.ts +137 -0
- package/dist/html/index.d.ts.map +1 -0
- package/dist/html/index.js +339 -0
- package/dist/html/index.js.map +1 -0
- package/dist/html/layout/block.d.ts +58 -0
- package/dist/html/layout/block.d.ts.map +1 -0
- package/dist/html/layout/block.js +724 -0
- package/dist/html/layout/block.js.map +1 -0
- package/dist/html/layout/boxes.d.ts +261 -0
- package/dist/html/layout/boxes.d.ts.map +1 -0
- package/dist/html/layout/boxes.js +725 -0
- package/dist/html/layout/boxes.js.map +1 -0
- package/dist/html/layout/flex.d.ts +16 -0
- package/dist/html/layout/flex.d.ts.map +1 -0
- package/dist/html/layout/flex.js +242 -0
- package/dist/html/layout/flex.js.map +1 -0
- package/dist/html/layout/floats.d.ts +50 -0
- package/dist/html/layout/floats.d.ts.map +1 -0
- package/dist/html/layout/floats.js +110 -0
- package/dist/html/layout/floats.js.map +1 -0
- package/dist/html/layout/inline.d.ts +44 -0
- package/dist/html/layout/inline.d.ts.map +1 -0
- package/dist/html/layout/inline.js +700 -0
- package/dist/html/layout/inline.js.map +1 -0
- package/dist/html/layout/table.d.ts +5 -0
- package/dist/html/layout/table.d.ts.map +1 -0
- package/dist/html/layout/table.js +340 -0
- package/dist/html/layout/table.js.map +1 -0
- package/dist/html/node.d.ts +149 -0
- package/dist/html/node.d.ts.map +1 -0
- package/dist/html/node.js +861 -0
- package/dist/html/node.js.map +1 -0
- package/dist/html/paint.d.ts +48 -0
- package/dist/html/paint.d.ts.map +1 -0
- package/dist/html/paint.js +495 -0
- package/dist/html/paint.js.map +1 -0
- package/dist/html/resources.d.ts +48 -0
- package/dist/html/resources.d.ts.map +1 -0
- package/dist/html/resources.js +156 -0
- package/dist/html/resources.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/heights.d.ts +81 -0
- package/dist/internal/heights.d.ts.map +1 -0
- package/dist/internal/heights.js +193 -0
- package/dist/internal/heights.js.map +1 -0
- package/dist/internal/hx.d.ts +24 -0
- package/dist/internal/hx.d.ts.map +1 -0
- package/dist/internal/hx.js +27 -0
- package/dist/internal/hx.js.map +1 -0
- package/dist/internal/text.d.ts +6 -0
- package/dist/internal/text.d.ts.map +1 -0
- package/dist/internal/text.js +44 -0
- package/dist/internal/text.js.map +1 -0
- package/dist/internal/timers.d.ts +8 -0
- package/dist/internal/timers.d.ts.map +1 -0
- package/dist/internal/timers.js +22 -0
- package/dist/internal/timers.js.map +1 -0
- package/dist/internal/widget.d.ts +40 -0
- package/dist/internal/widget.d.ts.map +1 -0
- package/dist/internal/widget.js +44 -0
- package/dist/internal/widget.js.map +1 -0
- package/dist/markdown/ast.d.ts +126 -0
- package/dist/markdown/ast.d.ts.map +1 -0
- package/dist/markdown/ast.js +8 -0
- package/dist/markdown/ast.js.map +1 -0
- package/dist/markdown/hx.d.ts +24 -0
- package/dist/markdown/hx.d.ts.map +1 -0
- package/dist/markdown/hx.js +25 -0
- package/dist/markdown/hx.js.map +1 -0
- package/dist/markdown/index.d.ts +90 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +413 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/parse.d.ts +8 -0
- package/dist/markdown/parse.d.ts.map +1 -0
- package/dist/markdown/parse.js +911 -0
- package/dist/markdown/parse.js.map +1 -0
- package/dist/markdown/spans.d.ts +20 -0
- package/dist/markdown/spans.d.ts.map +1 -0
- package/dist/markdown/spans.js +96 -0
- package/dist/markdown/spans.js.map +1 -0
- package/dist/media-player/backends.d.ts +64 -0
- package/dist/media-player/backends.d.ts.map +1 -0
- package/dist/media-player/backends.js +110 -0
- package/dist/media-player/backends.js.map +1 -0
- package/dist/media-player/control.d.ts +40 -0
- package/dist/media-player/control.d.ts.map +1 -0
- package/dist/media-player/control.js +44 -0
- package/dist/media-player/control.js.map +1 -0
- package/dist/media-player/hx.d.ts +24 -0
- package/dist/media-player/hx.d.ts.map +1 -0
- package/dist/media-player/hx.js +25 -0
- package/dist/media-player/hx.js.map +1 -0
- package/dist/media-player/index.d.ts +107 -0
- package/dist/media-player/index.d.ts.map +1 -0
- package/dist/media-player/index.js +219 -0
- package/dist/media-player/index.js.map +1 -0
- package/dist/media-player/mpv.d.ts +4 -0
- package/dist/media-player/mpv.d.ts.map +1 -0
- package/dist/media-player/mpv.js +120 -0
- package/dist/media-player/mpv.js.map +1 -0
- package/dist/media-player/vlc.d.ts +8 -0
- package/dist/media-player/vlc.d.ts.map +1 -0
- package/dist/media-player/vlc.js +83 -0
- package/dist/media-player/vlc.js.map +1 -0
- package/dist/richtext/index.d.ts +19 -0
- package/dist/richtext/index.d.ts.map +1 -0
- package/dist/richtext/index.js +4 -0
- package/dist/richtext/index.js.map +1 -0
- package/dist/richtext/links.d.ts +12 -0
- package/dist/richtext/links.d.ts.map +1 -0
- package/dist/richtext/links.js +64 -0
- package/dist/richtext/links.js.map +1 -0
- package/dist/richtext/menu.d.ts +11 -0
- package/dist/richtext/menu.d.ts.map +1 -0
- package/dist/richtext/menu.js +43 -0
- package/dist/richtext/menu.js.map +1 -0
- package/dist/richtext/node.d.ts +151 -0
- package/dist/richtext/node.d.ts.map +1 -0
- package/dist/richtext/node.js +255 -0
- package/dist/richtext/node.js.map +1 -0
- package/dist/richtext/runs.d.ts +92 -0
- package/dist/richtext/runs.d.ts.map +1 -0
- package/dist/richtext/runs.js +158 -0
- package/dist/richtext/runs.js.map +1 -0
- package/dist/table/hx.d.ts +24 -0
- package/dist/table/hx.d.ts.map +1 -0
- package/dist/table/hx.js +25 -0
- package/dist/table/hx.js.map +1 -0
- package/dist/table/index.d.ts +169 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/table/index.js +844 -0
- package/dist/table/index.js.map +1 -0
- package/dist/table/rows.d.ts +136 -0
- package/dist/table/rows.d.ts.map +1 -0
- package/dist/table/rows.js +146 -0
- package/dist/table/rows.js.map +1 -0
- package/dist/terminal/backends.d.ts +105 -0
- package/dist/terminal/backends.d.ts.map +1 -0
- package/dist/terminal/backends.js +185 -0
- package/dist/terminal/backends.js.map +1 -0
- package/dist/terminal/hx.d.ts +24 -0
- package/dist/terminal/hx.d.ts.map +1 -0
- package/dist/terminal/hx.js +25 -0
- package/dist/terminal/hx.js.map +1 -0
- package/dist/terminal/index.d.ts +160 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +344 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/title.d.ts +24 -0
- package/dist/terminal/title.d.ts.map +1 -0
- package/dist/terminal/title.js +129 -0
- package/dist/terminal/title.js.map +1 -0
- package/dist/terminal/vt/colors.d.ts +63 -0
- package/dist/terminal/vt/colors.d.ts.map +1 -0
- package/dist/terminal/vt/colors.js +203 -0
- package/dist/terminal/vt/colors.js.map +1 -0
- package/dist/terminal/vt/diff.d.ts +117 -0
- package/dist/terminal/vt/diff.d.ts.map +1 -0
- package/dist/terminal/vt/diff.js +358 -0
- package/dist/terminal/vt/diff.js.map +1 -0
- package/dist/terminal/vt/fonts.d.ts +92 -0
- package/dist/terminal/vt/fonts.d.ts.map +1 -0
- package/dist/terminal/vt/fonts.js +178 -0
- package/dist/terminal/vt/fonts.js.map +1 -0
- package/dist/terminal/vt/index.d.ts +78 -0
- package/dist/terminal/vt/index.d.ts.map +1 -0
- package/dist/terminal/vt/index.js +312 -0
- package/dist/terminal/vt/index.js.map +1 -0
- package/dist/terminal/vt/keys.d.ts +74 -0
- package/dist/terminal/vt/keys.d.ts.map +1 -0
- package/dist/terminal/vt/keys.js +309 -0
- package/dist/terminal/vt/keys.js.map +1 -0
- package/dist/terminal/vt/mouse.d.ts +44 -0
- package/dist/terminal/vt/mouse.d.ts.map +1 -0
- package/dist/terminal/vt/mouse.js +106 -0
- package/dist/terminal/vt/mouse.js.map +1 -0
- package/dist/terminal/vt/node.d.ts +246 -0
- package/dist/terminal/vt/node.d.ts.map +1 -0
- package/dist/terminal/vt/node.js +1068 -0
- package/dist/terminal/vt/node.js.map +1 -0
- package/dist/terminal/vt/pty.d.ts +81 -0
- package/dist/terminal/vt/pty.d.ts.map +1 -0
- package/dist/terminal/vt/pty.js +201 -0
- package/dist/terminal/vt/pty.js.map +1 -0
- package/dist/terminal/vt/renderer.d.ts +179 -0
- package/dist/terminal/vt/renderer.d.ts.map +1 -0
- package/dist/terminal/vt/renderer.js +357 -0
- package/dist/terminal/vt/renderer.js.map +1 -0
- package/dist/terminal/vt/timers.d.ts +6 -0
- package/dist/terminal/vt/timers.d.ts.map +1 -0
- package/dist/terminal/vt/timers.js +16 -0
- package/dist/terminal/vt/timers.js.map +1 -0
- package/dist/terminal/vt/xterm.d.ts +142 -0
- package/dist/terminal/vt/xterm.d.ts.map +1 -0
- package/dist/terminal/vt/xterm.js +32 -0
- package/dist/terminal/vt/xterm.js.map +1 -0
- package/dist/terminal-output/hx.d.ts +24 -0
- package/dist/terminal-output/hx.d.ts.map +1 -0
- package/dist/terminal-output/hx.js +25 -0
- package/dist/terminal-output/hx.js.map +1 -0
- package/dist/terminal-output/index.d.ts +92 -0
- package/dist/terminal-output/index.d.ts.map +1 -0
- package/dist/terminal-output/index.js +179 -0
- package/dist/terminal-output/index.js.map +1 -0
- package/dist/terminal-output/runs.d.ts +27 -0
- package/dist/terminal-output/runs.d.ts.map +1 -0
- package/dist/terminal-output/runs.js +66 -0
- package/dist/terminal-output/runs.js.map +1 -0
- package/dist/three/canvas.d.ts +46 -0
- package/dist/three/canvas.d.ts.map +1 -0
- package/dist/three/canvas.js +305 -0
- package/dist/three/canvas.js.map +1 -0
- package/dist/three/events.d.ts +64 -0
- package/dist/three/events.d.ts.map +1 -0
- package/dist/three/events.js +146 -0
- package/dist/three/events.js.map +1 -0
- package/dist/three/geometries.d.ts +89 -0
- package/dist/three/geometries.d.ts.map +1 -0
- package/dist/three/geometries.js +345 -0
- package/dist/three/geometries.js.map +1 -0
- package/dist/three/globals.d.ts +7 -0
- package/dist/three/globals.d.ts.map +1 -0
- package/dist/three/globals.js +20 -0
- package/dist/three/globals.js.map +1 -0
- package/dist/three/hx.d.ts +9 -0
- package/dist/three/hx.d.ts.map +1 -0
- package/dist/three/hx.js +10 -0
- package/dist/three/hx.js.map +1 -0
- package/dist/three/index.d.ts +22 -0
- package/dist/three/index.d.ts.map +1 -0
- package/dist/three/index.js +24 -0
- package/dist/three/index.js.map +1 -0
- package/dist/three/jsx-dev-runtime.d.ts +19 -0
- package/dist/three/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/three/jsx-dev-runtime.js +2 -0
- package/dist/three/jsx-dev-runtime.js.map +1 -0
- package/dist/three/jsx-runtime.d.ts +19 -0
- package/dist/three/jsx-runtime.d.ts.map +1 -0
- package/dist/three/jsx-runtime.js +2 -0
- package/dist/three/jsx-runtime.js.map +1 -0
- package/dist/three/jsx.d.ts +198 -0
- package/dist/three/jsx.d.ts.map +1 -0
- package/dist/three/jsx.js +2 -0
- package/dist/three/jsx.js.map +1 -0
- package/dist/three/materials.d.ts +125 -0
- package/dist/three/materials.d.ts.map +1 -0
- package/dist/three/materials.js +229 -0
- package/dist/three/materials.js.map +1 -0
- package/dist/three/math.d.ts +146 -0
- package/dist/three/math.d.ts.map +1 -0
- package/dist/three/math.js +464 -0
- package/dist/three/math.js.map +1 -0
- package/dist/three/objects.d.ts +185 -0
- package/dist/three/objects.d.ts.map +1 -0
- package/dist/three/objects.js +309 -0
- package/dist/three/objects.js.map +1 -0
- package/dist/three/passes.d.ts +54 -0
- package/dist/three/passes.d.ts.map +1 -0
- package/dist/three/passes.js +78 -0
- package/dist/three/passes.js.map +1 -0
- package/dist/three/postprocess.d.ts +85 -0
- package/dist/three/postprocess.d.ts.map +1 -0
- package/dist/three/postprocess.js +503 -0
- package/dist/three/postprocess.js.map +1 -0
- package/dist/three/raycast.d.ts +24 -0
- package/dist/three/raycast.d.ts.map +1 -0
- package/dist/three/raycast.js +138 -0
- package/dist/three/raycast.js.map +1 -0
- package/dist/three/reconciler.d.ts +48 -0
- package/dist/three/reconciler.d.ts.map +1 -0
- package/dist/three/reconciler.js +416 -0
- package/dist/three/reconciler.js.map +1 -0
- package/dist/three/renderer-direct.d.ts +102 -0
- package/dist/three/renderer-direct.d.ts.map +1 -0
- package/dist/three/renderer-direct.js +782 -0
- package/dist/three/renderer-direct.js.map +1 -0
- package/dist/three/renderer-indirect.d.ts +68 -0
- package/dist/three/renderer-indirect.d.ts.map +1 -0
- package/dist/three/renderer-indirect.js +438 -0
- package/dist/three/renderer-indirect.js.map +1 -0
- package/dist/three/store.d.ts +81 -0
- package/dist/three/store.d.ts.map +1 -0
- package/dist/three/store.js +110 -0
- package/dist/three/store.js.map +1 -0
- package/dist/timeline/hx.d.ts +18 -0
- package/dist/timeline/hx.d.ts.map +1 -0
- package/dist/timeline/hx.js +10 -0
- package/dist/timeline/hx.js.map +1 -0
- package/dist/timeline/index.d.ts +152 -0
- package/dist/timeline/index.d.ts.map +1 -0
- package/dist/timeline/index.js +383 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/tray-host/hx.d.ts +24 -0
- package/dist/tray-host/hx.d.ts.map +1 -0
- package/dist/tray-host/hx.js +25 -0
- package/dist/tray-host/hx.js.map +1 -0
- package/dist/tray-host/index.d.ts +110 -0
- package/dist/tray-host/index.d.ts.map +1 -0
- package/dist/tray-host/index.js +191 -0
- package/dist/tray-host/index.js.map +1 -0
- package/dist/tray-host/manager.d.ts +137 -0
- package/dist/tray-host/manager.d.ts.map +1 -0
- package/dist/tray-host/manager.js +462 -0
- package/dist/tray-host/manager.js.map +1 -0
- package/dist/tray-host/notify.d.ts +22 -0
- package/dist/tray-host/notify.d.ts.map +1 -0
- package/dist/tray-host/notify.js +74 -0
- package/dist/tray-host/notify.js.map +1 -0
- package/dist/tray-host/protocol.d.ts +106 -0
- package/dist/tray-host/protocol.d.ts.map +1 -0
- package/dist/tray-host/protocol.js +191 -0
- package/dist/tray-host/protocol.js.map +1 -0
- package/dist/tree/hx.d.ts +24 -0
- package/dist/tree/hx.d.ts.map +1 -0
- package/dist/tree/hx.js +25 -0
- package/dist/tree/hx.js.map +1 -0
- package/dist/tree/index.d.ts +221 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +716 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/internal.d.ts +18 -0
- package/dist/tree/internal.d.ts.map +1 -0
- package/dist/tree/internal.js +66 -0
- package/dist/tree/internal.js.map +1 -0
- package/dist/tree/rows.d.ts +177 -0
- package/dist/tree/rows.d.ts.map +1 -0
- package/dist/tree/rows.js +179 -0
- package/dist/tree/rows.js.map +1 -0
- package/package.json +166 -12
- package/src/ansi/cast.ts +159 -0
- package/src/ansi/index.ts +53 -0
- package/src/ansi/palette.ts +226 -0
- package/src/ansi/parse.ts +780 -0
- package/src/ansi/sgr.ts +380 -0
- package/src/ansi/utf8.ts +84 -0
- package/src/calendar/Calendar.ts +744 -0
- package/src/calendar/DatePicker.ts +368 -0
- package/src/calendar/dates.ts +307 -0
- package/src/calendar/index.ts +51 -0
- package/src/charts/components.ts +864 -0
- package/src/charts/data.ts +776 -0
- package/src/charts/hx.ts +39 -0
- package/src/charts/index.ts +99 -0
- package/src/charts/node.ts +932 -0
- package/src/charts/render.ts +982 -0
- package/src/charts/scale.ts +214 -0
- package/src/charts/spec.ts +122 -0
- package/src/charts/timers.ts +24 -0
- package/src/code/hx.ts +51 -0
- package/src/code/index.ts +174 -0
- package/src/code-editor/completion.ts +161 -0
- package/src/code-editor/doc.ts +198 -0
- package/src/code-editor/hx.ts +26 -0
- package/src/code-editor/index.ts +615 -0
- package/src/code-editor/node.ts +1926 -0
- package/src/code-language/hljs.ts +302 -0
- package/src/code-language/index.ts +51 -0
- package/src/code-language/languages/glsl.ts +120 -0
- package/src/code-language/languages/javascript.ts +419 -0
- package/src/code-language/languages/json.ts +72 -0
- package/src/code-language/languages/shell.ts +221 -0
- package/src/code-language/languages/sql.ts +165 -0
- package/src/code-language/lezer.ts +190 -0
- package/src/code-language/registry.ts +66 -0
- package/src/code-language/runs.ts +128 -0
- package/src/code-language/stream.ts +306 -0
- package/src/code-language/textmate.ts +134 -0
- package/src/code-language/theme.ts +124 -0
- package/src/code-language/timers.ts +36 -0
- package/src/code-language/types.ts +252 -0
- package/src/codeblock/index.ts +146 -0
- package/src/color-picker/ColorField.ts +333 -0
- package/src/color-picker/ColorPicker.ts +1069 -0
- package/src/color-picker/color.ts +399 -0
- package/src/color-picker/index.ts +50 -0
- package/src/desktop-calendar/eds.ts +484 -0
- package/src/desktop-calendar/ical.ts +119 -0
- package/src/desktop-calendar/index.ts +287 -0
- package/src/embed/client.ts +311 -0
- package/src/embed/host.ts +432 -0
- package/src/embed/index.ts +33 -0
- package/src/embed/timers.ts +32 -0
- package/src/flow/draw.ts +418 -0
- package/src/flow/index.ts +473 -0
- package/src/flow/model.ts +687 -0
- package/src/flow/node.ts +3694 -0
- package/src/flow/paths.ts +403 -0
- package/src/flow/types.ts +634 -0
- package/src/formula/hx.ts +51 -0
- package/src/formula/index.ts +243 -0
- package/src/formula/katex.ts +209 -0
- package/src/formula/layout.ts +876 -0
- package/src/formula/node.ts +467 -0
- package/src/html/controls.ts +244 -0
- package/src/html/css/cascade.ts +606 -0
- package/src/html/css/parse.ts +500 -0
- package/src/html/css/style.ts +1371 -0
- package/src/html/css/ua.ts +174 -0
- package/src/html/css/values.ts +358 -0
- package/src/html/dom.ts +410 -0
- package/src/html/hx.ts +55 -0
- package/src/html/index.ts +545 -0
- package/src/html/layout/block.ts +876 -0
- package/src/html/layout/boxes.ts +981 -0
- package/src/html/layout/flex.ts +297 -0
- package/src/html/layout/floats.ts +125 -0
- package/src/html/layout/inline.ts +870 -0
- package/src/html/layout/table.ts +380 -0
- package/src/html/node.ts +967 -0
- package/src/html/paint.ts +605 -0
- package/src/html/resources.ts +214 -0
- package/src/index.ts +638 -0
- package/src/internal/heights.ts +211 -0
- package/src/internal/hx.ts +53 -0
- package/src/internal/text.ts +44 -0
- package/src/internal/timers.ts +44 -0
- package/src/internal/widget.ts +92 -0
- package/src/markdown/ast.ts +163 -0
- package/src/markdown/hx.ts +51 -0
- package/src/markdown/index.ts +686 -0
- package/src/markdown/parse.ts +1037 -0
- package/src/markdown/spans.ts +143 -0
- package/src/media-player/backends.ts +155 -0
- package/src/media-player/control.ts +70 -0
- package/src/media-player/hx.ts +51 -0
- package/src/media-player/index.ts +378 -0
- package/src/media-player/mpv.ts +146 -0
- package/src/media-player/vlc.ts +97 -0
- package/src/richtext/index.ts +42 -0
- package/src/richtext/links.ts +78 -0
- package/src/richtext/menu.ts +49 -0
- package/src/richtext/node.ts +406 -0
- package/src/richtext/runs.ts +253 -0
- package/src/table/hx.ts +51 -0
- package/src/table/index.ts +1219 -0
- package/src/table/rows.ts +275 -0
- package/src/terminal/backends.ts +242 -0
- package/src/terminal/hx.ts +51 -0
- package/src/terminal/index.ts +574 -0
- package/src/terminal/title.ts +172 -0
- package/src/terminal/vt/colors.ts +247 -0
- package/src/terminal/vt/diff.ts +467 -0
- package/src/terminal/vt/fonts.ts +233 -0
- package/src/terminal/vt/index.ts +443 -0
- package/src/terminal/vt/keys.ts +369 -0
- package/src/terminal/vt/mouse.ts +144 -0
- package/src/terminal/vt/node.ts +1242 -0
- package/src/terminal/vt/pty.ts +334 -0
- package/src/terminal/vt/renderer.ts +555 -0
- package/src/terminal/vt/timers.ts +31 -0
- package/src/terminal/vt/xterm.ts +193 -0
- package/src/terminal-output/hx.ts +51 -0
- package/src/terminal-output/index.ts +340 -0
- package/src/terminal-output/runs.ts +79 -0
- package/src/three/canvas.ts +451 -0
- package/src/three/events.ts +197 -0
- package/src/three/geometries.ts +429 -0
- package/src/three/globals.ts +34 -0
- package/src/three/hx.ts +22 -0
- package/src/three/index.ts +98 -0
- package/src/three/jsx-dev-runtime.ts +27 -0
- package/src/three/jsx-runtime.ts +38 -0
- package/src/three/jsx.ts +275 -0
- package/src/three/materials.ts +270 -0
- package/src/three/math.ts +585 -0
- package/src/three/objects.ts +397 -0
- package/src/three/passes.ts +90 -0
- package/src/three/postprocess.ts +677 -0
- package/src/three/raycast.ts +189 -0
- package/src/three/react-reconciler.d.ts +50 -0
- package/src/three/reconciler.ts +624 -0
- package/src/three/renderer-direct.ts +1055 -0
- package/src/three/renderer-indirect.ts +570 -0
- package/src/three/store.ts +207 -0
- package/src/timeline/hx.ts +31 -0
- package/src/timeline/index.ts +603 -0
- package/src/tray-host/hx.ts +51 -0
- package/src/tray-host/index.ts +331 -0
- package/src/tray-host/manager.ts +639 -0
- package/src/tray-host/notify.ts +102 -0
- package/src/tray-host/protocol.ts +235 -0
- package/src/tree/hx.ts +51 -0
- package/src/tree/index.ts +1087 -0
- package/src/tree/internal.ts +87 -0
- package/src/tree/rows.ts +334 -0
- package/src/index.d.ts +0 -2
- package/src/index.js +0 -9
- package/src/sparkline/index.d.ts +0 -29
- package/src/sparkline/index.js +0 -50
- package/src/sparkline/node.js +0 -72
|
@@ -0,0 +1,1037 @@
|
|
|
1
|
+
// Markdown → AST, written for this component rather than adapted from a
|
|
2
|
+
// DOM-shaped pipeline. GFM-flavoured CommonMark: headings (ATX and setext),
|
|
3
|
+
// paragraphs, fenced and indented code, blockquotes with lazy continuation,
|
|
4
|
+
// nested ordered/bullet/task lists with the tight/loose distinction, tables,
|
|
5
|
+
// thematic breaks; inline emphasis with the real flanking and rule-of-three
|
|
6
|
+
// algorithm, code spans, links, images, autolinks, hard breaks, entities.
|
|
7
|
+
//
|
|
8
|
+
// The deliberate deviations, all in the direction LLM output wants:
|
|
9
|
+
//
|
|
10
|
+
// - **Streaming tolerance is in the parser, not a repair pre-pass.** The
|
|
11
|
+
// behavioural spec is Streamdown's `remend` package (the handlers were
|
|
12
|
+
// read, not imported): unclosed `**`/`*`/`~~`/`` ` `` reaching the end of
|
|
13
|
+
// a partial document close implicitly, `[text](partial-url` renders its
|
|
14
|
+
// text link-styled with `href: null`, half-arrived images vanish, a bare
|
|
15
|
+
// trailing `**`, `#` or `---` is held back until it can be read. Doing it
|
|
16
|
+
// during the parse means one pass over the text instead of
|
|
17
|
+
// repair-then-reparse, and none of remend's "was that backtick inside a
|
|
18
|
+
// fence?" re-scans.
|
|
19
|
+
// - **Single `~` is never strikethrough** (GFM allows it): `~~` only, so
|
|
20
|
+
// "20~25" needs no escaping heuristic.
|
|
21
|
+
// - **Reference links (`[text][ref]`) stay literal.** They need a
|
|
22
|
+
// definitions pass over the whole document, and streamed model output
|
|
23
|
+
// essentially never uses them.
|
|
24
|
+
// - **Raw HTML is literal text.** There is no HTML pass anywhere in this
|
|
25
|
+
// component, by design; `<Component />` syntax is reserved for a future
|
|
26
|
+
// MDX extension (see `ComponentInline` in ast.ts).
|
|
27
|
+
import type {
|
|
28
|
+
BlockNode,
|
|
29
|
+
Document,
|
|
30
|
+
InlineNode,
|
|
31
|
+
ListBlock,
|
|
32
|
+
ListItem,
|
|
33
|
+
ParseOptions,
|
|
34
|
+
TableAlign,
|
|
35
|
+
} from './ast.js';
|
|
36
|
+
|
|
37
|
+
// --- line-level regexes, compiled once -------------------------------------
|
|
38
|
+
|
|
39
|
+
const RE_BLANK = /^[ \t]*$/;
|
|
40
|
+
const RE_ATX = /^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/;
|
|
41
|
+
const RE_ATX_STUB = /^ {0,3}#{1,6}$/;
|
|
42
|
+
const RE_FENCE_OPEN = /^( {0,3})(`{3,}|~{3,})[ \t]*(.*)$/;
|
|
43
|
+
const RE_HR = /^ {0,3}([*_-])[ \t]*(?:\1[ \t]*){2,}$/;
|
|
44
|
+
const RE_SETEXT = /^ {0,3}(=+|-+)[ \t]*$/;
|
|
45
|
+
const RE_QUOTE = /^ {0,3}>[ ]?(.*)$/;
|
|
46
|
+
const RE_LIST = /^( {0,3})([-+*]|\d{1,9}[.)])(?:([ \t]+)(.*))?$/;
|
|
47
|
+
const RE_TASK = /^\[([ xX])\][ \t]+/;
|
|
48
|
+
const RE_INDENT_CODE = /^(?: {4}|\t)/;
|
|
49
|
+
// a complete GFM delimiter row: | :---: | --- |
|
|
50
|
+
const RE_TABLE_DELIM =
|
|
51
|
+
/^ {0,3}\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
|
|
52
|
+
// a plausible prefix of one, for the streaming case ("| :--" mid-arrival)
|
|
53
|
+
const RE_TABLE_DELIM_PREFIX = /^ {0,3}\|[ \t:|-]*$/;
|
|
54
|
+
|
|
55
|
+
/** Would this line open something other than a paragraph? The test lazy
|
|
56
|
+
* continuation and list/quote termination share. */
|
|
57
|
+
function isBlockStart(line: string): boolean {
|
|
58
|
+
return (
|
|
59
|
+
RE_ATX.test(line) ||
|
|
60
|
+
RE_FENCE_OPEN.test(line) ||
|
|
61
|
+
RE_HR.test(line) ||
|
|
62
|
+
RE_QUOTE.test(line) ||
|
|
63
|
+
RE_LIST.test(line)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Leading tabs advance to 4-column stops; content tabs are left alone. */
|
|
68
|
+
function expandLeadingTabs(line: string): string {
|
|
69
|
+
let i = 0;
|
|
70
|
+
let col = 0;
|
|
71
|
+
while (i < line.length) {
|
|
72
|
+
const ch = line.charCodeAt(i);
|
|
73
|
+
if (ch === 32) col += 1;
|
|
74
|
+
else if (ch === 9) col += 4 - (col % 4);
|
|
75
|
+
else break;
|
|
76
|
+
i += 1;
|
|
77
|
+
}
|
|
78
|
+
if (col === i) return line; // no tabs in the indent
|
|
79
|
+
return ' '.repeat(col) + line.slice(i);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function indentOf(line: string): number {
|
|
83
|
+
let i = 0;
|
|
84
|
+
while (i < line.length && line.charCodeAt(i) === 32) i += 1;
|
|
85
|
+
return i;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// --- entry -----------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
export function parse(source: string, options: ParseOptions = {}): Document {
|
|
91
|
+
const partial = options.partial !== false;
|
|
92
|
+
const normalized = source.replace(/\r\n?/g, '\n');
|
|
93
|
+
const lines = normalized.split('\n').map(expandLeadingTabs);
|
|
94
|
+
const blocks: BlockNode[] = [];
|
|
95
|
+
const ranges: Array<[number, number]> = [];
|
|
96
|
+
parseBlocks(lines, partial, blocks, ranges);
|
|
97
|
+
return {
|
|
98
|
+
blocks,
|
|
99
|
+
raws: ranges.map(([a, b]) => lines.slice(a, b).join('\n')),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// --- block layer -----------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Parse a run of lines into blocks. `tailOpen` says the end of `lines` is
|
|
107
|
+
* the live end of a streaming document — the license for every "complete it
|
|
108
|
+
* anyway" rule. `ranges`, when given, receives each block's [start, endExcl)
|
|
109
|
+
* line range (only the top-level call wants them, for the streaming cache).
|
|
110
|
+
*/
|
|
111
|
+
function parseBlocks(
|
|
112
|
+
lines: string[],
|
|
113
|
+
tailOpen: boolean,
|
|
114
|
+
out: BlockNode[],
|
|
115
|
+
ranges?: Array<[number, number]>,
|
|
116
|
+
): void {
|
|
117
|
+
let i = 0;
|
|
118
|
+
const n = lines.length;
|
|
119
|
+
|
|
120
|
+
let paraStart = -1;
|
|
121
|
+
const para: string[] = [];
|
|
122
|
+
|
|
123
|
+
const commit = (block: BlockNode, start: number, end: number): void => {
|
|
124
|
+
out.push(block);
|
|
125
|
+
ranges?.push([start, end]);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const flushPara = (end: number): void => {
|
|
129
|
+
if (para.length === 0) return;
|
|
130
|
+
const text = para.join('\n');
|
|
131
|
+
const start = paraStart;
|
|
132
|
+
para.length = 0;
|
|
133
|
+
paraStart = -1;
|
|
134
|
+
// the paragraph owns the live tail iff its last line is the document's
|
|
135
|
+
const children = parseInline(text, tailOpen && end === n);
|
|
136
|
+
if (children.length > 0)
|
|
137
|
+
commit({ type: 'paragraph', children }, start, end);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
while (i < n) {
|
|
141
|
+
const line = lines[i];
|
|
142
|
+
const isLast = i === n - 1;
|
|
143
|
+
const held = tailOpen && isLast; // "might still grow" applies
|
|
144
|
+
|
|
145
|
+
if (RE_BLANK.test(line)) {
|
|
146
|
+
flushPara(i);
|
|
147
|
+
i += 1;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Setext underline closes an open paragraph — unless it is the live
|
|
152
|
+
// tail, where "Title\n---" might still become a rule, a list item or
|
|
153
|
+
// plain text ("--- more"), so the line is held back for one round.
|
|
154
|
+
if (para.length > 0) {
|
|
155
|
+
const setext = RE_SETEXT.exec(line);
|
|
156
|
+
if (setext) {
|
|
157
|
+
if (held) {
|
|
158
|
+
i += 1;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const text = para.join('\n');
|
|
162
|
+
const start = paraStart;
|
|
163
|
+
para.length = 0;
|
|
164
|
+
paraStart = -1;
|
|
165
|
+
commit(
|
|
166
|
+
{
|
|
167
|
+
type: 'heading',
|
|
168
|
+
depth: setext[1][0] === '=' ? 1 : 2,
|
|
169
|
+
children: parseInline(text, false),
|
|
170
|
+
},
|
|
171
|
+
start,
|
|
172
|
+
i + 1,
|
|
173
|
+
);
|
|
174
|
+
i += 1;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Ambiguous live tails, hidden until they commit to being something:
|
|
180
|
+
// a bare marker run (`---`, `***` — rule? setext? bold opener?) or a
|
|
181
|
+
// content-less ATX stub (`##`).
|
|
182
|
+
if (
|
|
183
|
+
held &&
|
|
184
|
+
para.length === 0 &&
|
|
185
|
+
(RE_SETEXT.test(line) || RE_HR.test(line) || RE_ATX_STUB.test(line))
|
|
186
|
+
) {
|
|
187
|
+
i += 1;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Thematic break — before list, so `- - -` is a rule and not a list.
|
|
192
|
+
if (RE_HR.test(line)) {
|
|
193
|
+
flushPara(i);
|
|
194
|
+
commit({ type: 'rule' }, i, i + 1);
|
|
195
|
+
i += 1;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const atx = RE_ATX.exec(line);
|
|
200
|
+
if (atx) {
|
|
201
|
+
flushPara(i);
|
|
202
|
+
commit(
|
|
203
|
+
{
|
|
204
|
+
type: 'heading',
|
|
205
|
+
depth: atx[1].length,
|
|
206
|
+
children: parseInline(atx[2] ?? '', held),
|
|
207
|
+
},
|
|
208
|
+
i,
|
|
209
|
+
i + 1,
|
|
210
|
+
);
|
|
211
|
+
i += 1;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const fence = RE_FENCE_OPEN.exec(line);
|
|
216
|
+
// an info string on a backtick fence cannot itself contain a backtick
|
|
217
|
+
if (fence && !(fence[2][0] === '`' && fence[3].includes('`'))) {
|
|
218
|
+
flushPara(i);
|
|
219
|
+
const start = i;
|
|
220
|
+
const fenceIndent = fence[1].length;
|
|
221
|
+
const marker = fence[2];
|
|
222
|
+
const lang = (fence[3].trim().split(/[ \t]/, 1)[0] ?? '').toLowerCase();
|
|
223
|
+
const body: string[] = [];
|
|
224
|
+
let closed = false;
|
|
225
|
+
i += 1;
|
|
226
|
+
while (i < n) {
|
|
227
|
+
const l = lines[i];
|
|
228
|
+
const close = RE_FENCE_OPEN.exec(l);
|
|
229
|
+
if (
|
|
230
|
+
close &&
|
|
231
|
+
close[2][0] === marker[0] &&
|
|
232
|
+
close[2].length >= marker.length &&
|
|
233
|
+
close[3] === ''
|
|
234
|
+
) {
|
|
235
|
+
closed = true;
|
|
236
|
+
i += 1;
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
// content dedents by at most the opening fence's indent
|
|
240
|
+
body.push(
|
|
241
|
+
indentOf(l) >= fenceIndent
|
|
242
|
+
? l.slice(fenceIndent)
|
|
243
|
+
: l.replace(/^ +/, ''),
|
|
244
|
+
);
|
|
245
|
+
i += 1;
|
|
246
|
+
}
|
|
247
|
+
commit({ type: 'code', lang, text: body.join('\n'), closed }, start, i);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const quote = RE_QUOTE.exec(line);
|
|
252
|
+
if (quote) {
|
|
253
|
+
flushPara(i);
|
|
254
|
+
const start = i;
|
|
255
|
+
const inner: string[] = [];
|
|
256
|
+
inner.push(quote[1]);
|
|
257
|
+
i += 1;
|
|
258
|
+
// further `>` lines, plus lazy continuation of a trailing paragraph
|
|
259
|
+
while (i < n) {
|
|
260
|
+
const l = lines[i];
|
|
261
|
+
const q = RE_QUOTE.exec(l);
|
|
262
|
+
if (q) {
|
|
263
|
+
inner.push(q[1]);
|
|
264
|
+
i += 1;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (
|
|
268
|
+
!RE_BLANK.test(l) &&
|
|
269
|
+
!isBlockStart(l) &&
|
|
270
|
+
inner.length > 0 &&
|
|
271
|
+
!RE_BLANK.test(inner[inner.length - 1])
|
|
272
|
+
) {
|
|
273
|
+
inner.push(l); // lazy: "> a\nb" keeps b in the quote
|
|
274
|
+
i += 1;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
const children: BlockNode[] = [];
|
|
280
|
+
parseBlocks(inner, tailOpen && i === n, children);
|
|
281
|
+
if (children.length > 0) commit({ type: 'quote', children }, start, i);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const list = RE_LIST.exec(line);
|
|
286
|
+
// an empty item cannot interrupt a paragraph ("foo\n-" is not a list…),
|
|
287
|
+
// and while streaming the very last line gets the same benefit of doubt
|
|
288
|
+
if (list && !(para.length > 0 && !list[4]) && !(held && !list[4])) {
|
|
289
|
+
flushPara(i);
|
|
290
|
+
const start = i;
|
|
291
|
+
const block = parseList(lines, i, tailOpen);
|
|
292
|
+
i = block.end;
|
|
293
|
+
commit(block.list, start, i);
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// GFM table: a header row whose next line is the delimiter row. While
|
|
298
|
+
// streaming, a delimiter row still arriving ("| :--") is accepted too.
|
|
299
|
+
if (para.length === 0 && line.includes('|')) {
|
|
300
|
+
const next = i + 1 < n ? lines[i + 1] : null;
|
|
301
|
+
const headerCells = splitRow(line);
|
|
302
|
+
// a complete delimiter row with agreeing column count is the real
|
|
303
|
+
// thing; while streaming, a still-arriving one ("| :-" as the last
|
|
304
|
+
// line) is accepted with the header's column count and no alignment
|
|
305
|
+
const fullDelim =
|
|
306
|
+
next !== null &&
|
|
307
|
+
next.includes('-') &&
|
|
308
|
+
RE_TABLE_DELIM.test(next) &&
|
|
309
|
+
splitRow(next).length === headerCells.length;
|
|
310
|
+
const partialDelim =
|
|
311
|
+
!fullDelim &&
|
|
312
|
+
tailOpen &&
|
|
313
|
+
i + 1 === n - 1 &&
|
|
314
|
+
next !== null &&
|
|
315
|
+
RE_TABLE_DELIM_PREFIX.test(next);
|
|
316
|
+
const arrivingDelim = tailOpen && i === n - 1;
|
|
317
|
+
if (headerCells.length > 0 && (fullDelim || partialDelim)) {
|
|
318
|
+
const start = i;
|
|
319
|
+
const align: TableAlign[] = fullDelim
|
|
320
|
+
? splitRow(next).map(alignOf)
|
|
321
|
+
: headerCells.map(() => null);
|
|
322
|
+
i += 2;
|
|
323
|
+
const rows: InlineNode[][][] = [];
|
|
324
|
+
while (i < n) {
|
|
325
|
+
const l = lines[i];
|
|
326
|
+
if (RE_BLANK.test(l) || !l.includes('|') || isBlockStart(l)) break;
|
|
327
|
+
rows.push(
|
|
328
|
+
normalizeRow(splitRow(l), align.length, tailOpen && i === n - 1),
|
|
329
|
+
);
|
|
330
|
+
i += 1;
|
|
331
|
+
}
|
|
332
|
+
commit(
|
|
333
|
+
{
|
|
334
|
+
type: 'table',
|
|
335
|
+
align,
|
|
336
|
+
header: normalizeRow(headerCells, align.length, false),
|
|
337
|
+
rows,
|
|
338
|
+
},
|
|
339
|
+
start,
|
|
340
|
+
i,
|
|
341
|
+
);
|
|
342
|
+
continue;
|
|
343
|
+
} else if (
|
|
344
|
+
arrivingDelim &&
|
|
345
|
+
headerCells.length > 1 &&
|
|
346
|
+
line.trimStart().startsWith('|')
|
|
347
|
+
) {
|
|
348
|
+
// the header row itself is the live tail — hold it rather than
|
|
349
|
+
// flashing "| a | b |" as literal text for one frame
|
|
350
|
+
i += 1;
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// indented code cannot interrupt a paragraph
|
|
356
|
+
if (para.length === 0 && RE_INDENT_CODE.test(line)) {
|
|
357
|
+
const start = i;
|
|
358
|
+
const body: string[] = [];
|
|
359
|
+
while (i < n) {
|
|
360
|
+
const l = lines[i];
|
|
361
|
+
if (RE_INDENT_CODE.test(l)) {
|
|
362
|
+
body.push(l.startsWith('\t') ? l.slice(1) : l.slice(4));
|
|
363
|
+
i += 1;
|
|
364
|
+
} else if (RE_BLANK.test(l)) {
|
|
365
|
+
body.push('');
|
|
366
|
+
i += 1;
|
|
367
|
+
} else break;
|
|
368
|
+
}
|
|
369
|
+
while (body.length > 0 && body[body.length - 1] === '') body.pop();
|
|
370
|
+
commit(
|
|
371
|
+
{ type: 'code', lang: '', text: body.join('\n'), closed: true },
|
|
372
|
+
start,
|
|
373
|
+
i,
|
|
374
|
+
);
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (para.length === 0) paraStart = i;
|
|
379
|
+
// only the lead is trimmed: trailing spaces are the hard-break syntax
|
|
380
|
+
para.push(line.trimStart());
|
|
381
|
+
i += 1;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
flushPara(n);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// --- lists -----------------------------------------------------------------
|
|
388
|
+
|
|
389
|
+
interface ParsedList {
|
|
390
|
+
list: ListBlock;
|
|
391
|
+
end: number;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function parseList(
|
|
395
|
+
lines: string[],
|
|
396
|
+
from: number,
|
|
397
|
+
tailOpen: boolean,
|
|
398
|
+
): ParsedList {
|
|
399
|
+
const n = lines.length;
|
|
400
|
+
const first = RE_LIST.exec(lines[from]);
|
|
401
|
+
// caller matched — this is the narrowing, not a runtime possibility
|
|
402
|
+
if (!first) throw new Error('parseList called off a list marker');
|
|
403
|
+
const marker = first[2];
|
|
404
|
+
const ordered = marker.length > 1;
|
|
405
|
+
const markerType = ordered ? marker[marker.length - 1] : marker; // ')' '.' '-' '+' '*'
|
|
406
|
+
const start = ordered ? parseInt(marker, 10) : 1;
|
|
407
|
+
|
|
408
|
+
const items: ListItem[] = [];
|
|
409
|
+
let loose = false;
|
|
410
|
+
let i = from;
|
|
411
|
+
let sawBlank = false;
|
|
412
|
+
|
|
413
|
+
while (i < n) {
|
|
414
|
+
const m = RE_LIST.exec(lines[i]);
|
|
415
|
+
const sameKind =
|
|
416
|
+
m &&
|
|
417
|
+
(ordered
|
|
418
|
+
? /\d/.test(m[2][0]) && m[2][m[2].length - 1] === markerType
|
|
419
|
+
: m[2] === markerType);
|
|
420
|
+
if (!sameKind) break;
|
|
421
|
+
if (sawBlank && items.length > 0) loose = true;
|
|
422
|
+
sawBlank = false;
|
|
423
|
+
|
|
424
|
+
const indent = m[1].length;
|
|
425
|
+
const afterMarker = m[3] ?? '';
|
|
426
|
+
const rest = m[4] ?? '';
|
|
427
|
+
// content column: marker + one space, or the actual spacing when ≤ 4
|
|
428
|
+
const pad =
|
|
429
|
+
afterMarker.length === 0 || afterMarker.length > 4
|
|
430
|
+
? 1
|
|
431
|
+
: afterMarker.length;
|
|
432
|
+
const contentIndent = indent + m[2].length + pad;
|
|
433
|
+
|
|
434
|
+
const inner: string[] = [rest];
|
|
435
|
+
i += 1;
|
|
436
|
+
let pendingBlanks = 0;
|
|
437
|
+
while (i < n) {
|
|
438
|
+
const l = lines[i];
|
|
439
|
+
if (RE_BLANK.test(l)) {
|
|
440
|
+
pendingBlanks += 1;
|
|
441
|
+
if (pendingBlanks > 1) break;
|
|
442
|
+
i += 1;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
if (indentOf(l) >= contentIndent) {
|
|
446
|
+
if (pendingBlanks > 0) {
|
|
447
|
+
inner.push('');
|
|
448
|
+
loose = true;
|
|
449
|
+
pendingBlanks = 0;
|
|
450
|
+
}
|
|
451
|
+
inner.push(l.slice(contentIndent));
|
|
452
|
+
i += 1;
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (pendingBlanks === 0 && !isBlockStart(l) && !RE_BLANK.test(l)) {
|
|
456
|
+
inner.push(l); // lazy paragraph continuation
|
|
457
|
+
i += 1;
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
if (pendingBlanks > 0) sawBlank = true;
|
|
463
|
+
|
|
464
|
+
// GFM task marker sits at the head of the item's first line
|
|
465
|
+
let checked: boolean | null = null;
|
|
466
|
+
const task = RE_TASK.exec(inner[0]);
|
|
467
|
+
if (task) {
|
|
468
|
+
checked = task[1] !== ' ';
|
|
469
|
+
inner[0] = inner[0].slice(task[0].length);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const children: BlockNode[] = [];
|
|
473
|
+
parseBlocks(inner, tailOpen && i >= n, children);
|
|
474
|
+
items.push({ checked, children });
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
return {
|
|
478
|
+
list: { type: 'list', ordered, start, tight: !loose, items },
|
|
479
|
+
end: i,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// --- tables ----------------------------------------------------------------
|
|
484
|
+
|
|
485
|
+
/** Split a row on unescaped pipes; `\|` stays literal in the cell. */
|
|
486
|
+
function splitRow(line: string): string[] {
|
|
487
|
+
const trimmed = line.trim();
|
|
488
|
+
const cells: string[] = [];
|
|
489
|
+
let cur = '';
|
|
490
|
+
for (let i = 0; i < trimmed.length; i += 1) {
|
|
491
|
+
const ch = trimmed[i];
|
|
492
|
+
if (ch === '\\' && trimmed[i + 1] === '|') {
|
|
493
|
+
cur += '|';
|
|
494
|
+
i += 1;
|
|
495
|
+
} else if (ch === '|') {
|
|
496
|
+
cells.push(cur.trim());
|
|
497
|
+
cur = '';
|
|
498
|
+
} else cur += ch;
|
|
499
|
+
}
|
|
500
|
+
cells.push(cur.trim());
|
|
501
|
+
if (cells.length > 0 && cells[0] === '' && trimmed.startsWith('|'))
|
|
502
|
+
cells.shift();
|
|
503
|
+
if (
|
|
504
|
+
cells.length > 0 &&
|
|
505
|
+
cells[cells.length - 1] === '' &&
|
|
506
|
+
trimmed.endsWith('|')
|
|
507
|
+
)
|
|
508
|
+
cells.pop();
|
|
509
|
+
return cells;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function alignOf(cell: string): TableAlign {
|
|
513
|
+
const left = cell.startsWith(':');
|
|
514
|
+
const right = cell.endsWith(':');
|
|
515
|
+
if (left && right) return 'center';
|
|
516
|
+
if (right) return 'right';
|
|
517
|
+
if (left) return 'left';
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function normalizeRow(
|
|
522
|
+
cells: string[],
|
|
523
|
+
width: number,
|
|
524
|
+
rowIsLiveTail: boolean,
|
|
525
|
+
): InlineNode[][] {
|
|
526
|
+
const row: InlineNode[][] = [];
|
|
527
|
+
for (let c = 0; c < width; c += 1) {
|
|
528
|
+
const text = cells[c] ?? '';
|
|
529
|
+
row.push(
|
|
530
|
+
parseInline(
|
|
531
|
+
text,
|
|
532
|
+
rowIsLiveTail && c === Math.min(cells.length, width) - 1,
|
|
533
|
+
),
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
return row;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// --- inline layer ----------------------------------------------------------
|
|
540
|
+
|
|
541
|
+
// A mutable working item: finished inline nodes interleaved with unresolved
|
|
542
|
+
// delimiter runs, resolved in place by the emphasis pass.
|
|
543
|
+
type Item =
|
|
544
|
+
| { kind: 'node'; node: InlineNode }
|
|
545
|
+
| {
|
|
546
|
+
kind: 'delim';
|
|
547
|
+
char: '*' | '_' | '~';
|
|
548
|
+
length: number;
|
|
549
|
+
canOpen: boolean;
|
|
550
|
+
canClose: boolean;
|
|
551
|
+
}
|
|
552
|
+
| { kind: 'bracket'; image: boolean };
|
|
553
|
+
|
|
554
|
+
const RE_UNI_WS = /\s/u;
|
|
555
|
+
const RE_UNI_PUNCT = /[\p{P}\p{S}]/u;
|
|
556
|
+
const RE_AUTOLINK = /^<([a-zA-Z][a-zA-Z0-9+.-]{1,31}:[^<>\s]*)>/;
|
|
557
|
+
const RE_AUTOEMAIL = /^<([^<>\s@]+@[^<>\s@]+\.[^<>\s@]+)>/;
|
|
558
|
+
const RE_ENTITY =
|
|
559
|
+
/&(?:#(\d{1,7})|#[xX]([0-9a-fA-F]{1,6})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
|
|
560
|
+
|
|
561
|
+
const NAMED_ENTITIES: Record<string, string> = {
|
|
562
|
+
amp: '&',
|
|
563
|
+
lt: '<',
|
|
564
|
+
gt: '>',
|
|
565
|
+
quot: '"',
|
|
566
|
+
apos: "'",
|
|
567
|
+
nbsp: ' ',
|
|
568
|
+
copy: '©',
|
|
569
|
+
reg: '®',
|
|
570
|
+
trade: '™',
|
|
571
|
+
hellip: '…',
|
|
572
|
+
mdash: '—',
|
|
573
|
+
ndash: '–',
|
|
574
|
+
laquo: '«',
|
|
575
|
+
raquo: '»',
|
|
576
|
+
times: '×',
|
|
577
|
+
middot: '·',
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
function decodeEntities(text: string): string {
|
|
581
|
+
if (!text.includes('&')) return text;
|
|
582
|
+
return text.replace(RE_ENTITY, (whole, dec, hex, named) => {
|
|
583
|
+
if (dec) {
|
|
584
|
+
const cp = parseInt(dec, 10);
|
|
585
|
+
return cp > 0 && cp <= 0x10ffff ? String.fromCodePoint(cp) : '�';
|
|
586
|
+
}
|
|
587
|
+
if (hex) {
|
|
588
|
+
const cp = parseInt(hex, 16);
|
|
589
|
+
return cp > 0 && cp <= 0x10ffff ? String.fromCodePoint(cp) : '�';
|
|
590
|
+
}
|
|
591
|
+
return NAMED_ENTITIES[named] ?? whole;
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function classify(ch: string | undefined): 'ws' | 'punct' | 'other' {
|
|
596
|
+
if (ch === undefined) return 'ws'; // string boundaries count as whitespace
|
|
597
|
+
if (RE_UNI_WS.test(ch)) return 'ws';
|
|
598
|
+
if (RE_UNI_PUNCT.test(ch)) return 'punct';
|
|
599
|
+
return 'other';
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Parse inline markdown. `atDocEnd` marks text whose end is the live end of
|
|
604
|
+
* a streaming document — only then do the implicit-close rules apply.
|
|
605
|
+
*/
|
|
606
|
+
export function parseInline(text: string, atDocEnd: boolean): InlineNode[] {
|
|
607
|
+
const items: Item[] = [];
|
|
608
|
+
let buf = '';
|
|
609
|
+
|
|
610
|
+
const flushText = (): void => {
|
|
611
|
+
if (buf.length === 0) return;
|
|
612
|
+
items.push({
|
|
613
|
+
kind: 'node',
|
|
614
|
+
node: { type: 'text', text: decodeEntities(buf) },
|
|
615
|
+
});
|
|
616
|
+
buf = '';
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
const len = text.length;
|
|
620
|
+
let i = 0;
|
|
621
|
+
while (i < len) {
|
|
622
|
+
const ch = text[i];
|
|
623
|
+
|
|
624
|
+
if (ch === '\\') {
|
|
625
|
+
const next = text[i + 1];
|
|
626
|
+
if (next === '\n') {
|
|
627
|
+
// hard break by trailing backslash
|
|
628
|
+
flushText();
|
|
629
|
+
items.push({ kind: 'node', node: { type: 'break' } });
|
|
630
|
+
i += 2;
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
if (next !== undefined && RE_UNI_PUNCT.test(next)) {
|
|
634
|
+
buf += next;
|
|
635
|
+
i += 2;
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
buf += ch;
|
|
639
|
+
i += 1;
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (ch === '\n') {
|
|
644
|
+
const hard = buf.endsWith(' ');
|
|
645
|
+
buf = buf.replace(/[ \t]+$/, '');
|
|
646
|
+
flushText();
|
|
647
|
+
items.push({
|
|
648
|
+
kind: 'node',
|
|
649
|
+
node: hard ? { type: 'break' } : { type: 'text', text: ' ' },
|
|
650
|
+
});
|
|
651
|
+
i += 1;
|
|
652
|
+
while (text[i] === ' ' || text[i] === '\t') i += 1;
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (ch === '`') {
|
|
657
|
+
let run = 1;
|
|
658
|
+
while (text[i + run] === '`') run += 1;
|
|
659
|
+
// the closing run must be exactly as long, and not part of a longer one
|
|
660
|
+
let j = i + run;
|
|
661
|
+
let close = -1;
|
|
662
|
+
while (j < len) {
|
|
663
|
+
if (text[j] === '`') {
|
|
664
|
+
let r = 1;
|
|
665
|
+
while (text[j + r] === '`') r += 1;
|
|
666
|
+
if (r === run) {
|
|
667
|
+
close = j;
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
j += r;
|
|
671
|
+
} else j += 1;
|
|
672
|
+
}
|
|
673
|
+
if (close !== -1) {
|
|
674
|
+
flushText();
|
|
675
|
+
items.push({
|
|
676
|
+
kind: 'node',
|
|
677
|
+
node: {
|
|
678
|
+
type: 'code',
|
|
679
|
+
text: codeSpanText(text.slice(i + run, close)),
|
|
680
|
+
},
|
|
681
|
+
});
|
|
682
|
+
i = close + run;
|
|
683
|
+
continue;
|
|
684
|
+
}
|
|
685
|
+
if (atDocEnd) {
|
|
686
|
+
// `remend`'s inlineCode rule: an open span at the live end closes
|
|
687
|
+
// itself — unless nothing follows the backticks yet, then hide them
|
|
688
|
+
const rest = text.slice(i + run);
|
|
689
|
+
flushText();
|
|
690
|
+
if (rest.length > 0)
|
|
691
|
+
items.push({
|
|
692
|
+
kind: 'node',
|
|
693
|
+
node: { type: 'code', text: codeSpanText(rest) },
|
|
694
|
+
});
|
|
695
|
+
i = len;
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
buf += text.slice(i, i + run);
|
|
699
|
+
i += run;
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
if (ch === '<') {
|
|
704
|
+
const rest = text.slice(i);
|
|
705
|
+
const auto = RE_AUTOLINK.exec(rest) ?? RE_AUTOEMAIL.exec(rest);
|
|
706
|
+
if (auto) {
|
|
707
|
+
flushText();
|
|
708
|
+
const target = auto[1];
|
|
709
|
+
const href = RE_AUTOLINK.test(auto[0]) ? target : `mailto:${target}`;
|
|
710
|
+
items.push({
|
|
711
|
+
kind: 'node',
|
|
712
|
+
node: {
|
|
713
|
+
type: 'link',
|
|
714
|
+
href,
|
|
715
|
+
image: false,
|
|
716
|
+
children: [{ type: 'text', text: target }],
|
|
717
|
+
},
|
|
718
|
+
});
|
|
719
|
+
i += auto[0].length;
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
buf += ch;
|
|
723
|
+
i += 1;
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
if (ch === '[' || (ch === '!' && text[i + 1] === '[')) {
|
|
728
|
+
const image = ch === '!';
|
|
729
|
+
flushText();
|
|
730
|
+
items.push({ kind: 'bracket', image });
|
|
731
|
+
i += image ? 2 : 1;
|
|
732
|
+
continue;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
if (ch === ']') {
|
|
736
|
+
const openIdx = lastBracket(items);
|
|
737
|
+
if (openIdx === -1) {
|
|
738
|
+
buf += ch;
|
|
739
|
+
i += 1;
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
const suffix = parseLinkSuffix(text, i + 1);
|
|
743
|
+
if (suffix) {
|
|
744
|
+
flushText();
|
|
745
|
+
closeLink(items, openIdx, suffix.href);
|
|
746
|
+
i = suffix.end;
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
if (atDocEnd && text[i + 1] === '(' && !text.includes(')', i + 1)) {
|
|
750
|
+
// `[text](partial-url` at the live end: keep the text, link-styled,
|
|
751
|
+
// with nowhere to go yet. A half-arrived image vanishes instead.
|
|
752
|
+
flushText();
|
|
753
|
+
const bracket = items[openIdx] as { kind: 'bracket'; image: boolean };
|
|
754
|
+
if (bracket.image) items.splice(openIdx);
|
|
755
|
+
else closeLink(items, openIdx, null);
|
|
756
|
+
i = len;
|
|
757
|
+
continue;
|
|
758
|
+
}
|
|
759
|
+
// no destination: not a link (reference links stay literal)
|
|
760
|
+
flushText();
|
|
761
|
+
items.splice(openIdx, 1, {
|
|
762
|
+
kind: 'node',
|
|
763
|
+
node: {
|
|
764
|
+
type: 'text',
|
|
765
|
+
text: (items[openIdx] as { image: boolean }).image ? '![' : '[',
|
|
766
|
+
},
|
|
767
|
+
});
|
|
768
|
+
buf += ch;
|
|
769
|
+
i += 1;
|
|
770
|
+
continue;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
if (ch === '*' || ch === '_' || ch === '~') {
|
|
774
|
+
let run = 1;
|
|
775
|
+
while (text[i + run] === ch) run += 1;
|
|
776
|
+
const before = classify(text[i - 1]);
|
|
777
|
+
const after = classify(text[i + run]);
|
|
778
|
+
const leftFlank =
|
|
779
|
+
after !== 'ws' && (after !== 'punct' || before !== 'other');
|
|
780
|
+
const rightFlank =
|
|
781
|
+
before !== 'ws' && (before !== 'punct' || after !== 'other');
|
|
782
|
+
let canOpen = leftFlank;
|
|
783
|
+
let canClose = rightFlank;
|
|
784
|
+
if (ch === '_') {
|
|
785
|
+
// intraword `_` never opens or closes: snake_case stays literal
|
|
786
|
+
canOpen = leftFlank && (!rightFlank || before === 'punct');
|
|
787
|
+
canClose = rightFlank && (!leftFlank || after === 'punct');
|
|
788
|
+
}
|
|
789
|
+
if (ch === '~' && run !== 2) {
|
|
790
|
+
buf += text.slice(i, i + run);
|
|
791
|
+
i += run;
|
|
792
|
+
continue;
|
|
793
|
+
}
|
|
794
|
+
// a fresh opener with nothing after it yet, at the live end of the
|
|
795
|
+
// document — `text **` — is hidden rather than shown as raw markers
|
|
796
|
+
if (atDocEnd && i + run === len && before !== 'other') {
|
|
797
|
+
i = len;
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
if (!canOpen && !canClose) {
|
|
801
|
+
buf += text.slice(i, i + run);
|
|
802
|
+
i += run;
|
|
803
|
+
continue;
|
|
804
|
+
}
|
|
805
|
+
flushText();
|
|
806
|
+
items.push({ kind: 'delim', char: ch, length: run, canOpen, canClose });
|
|
807
|
+
i += run;
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
buf += ch;
|
|
812
|
+
i += 1;
|
|
813
|
+
}
|
|
814
|
+
flushText();
|
|
815
|
+
|
|
816
|
+
processEmphasis(items, atDocEnd);
|
|
817
|
+
|
|
818
|
+
// leftover brackets: a live-tail `[still typing…` renders link-styled,
|
|
819
|
+
// a dead one is the literal character it always was
|
|
820
|
+
for (let k = items.length - 1; k >= 0; k -= 1) {
|
|
821
|
+
const it = items[k];
|
|
822
|
+
if (it.kind !== 'bracket') continue;
|
|
823
|
+
if (atDocEnd) {
|
|
824
|
+
if (it.image) items.splice(k);
|
|
825
|
+
else closeLink(items, k, null);
|
|
826
|
+
} else {
|
|
827
|
+
items.splice(k, 1, {
|
|
828
|
+
kind: 'node',
|
|
829
|
+
node: { type: 'text', text: it.image ? '![' : '[' },
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
return finish(items);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/** CommonMark's code-span rule: newlines become spaces, and one space is
|
|
838
|
+
* shaved off each end when both ends have one and content remains. */
|
|
839
|
+
function codeSpanText(raw: string): string {
|
|
840
|
+
const flat = raw.replace(/\n/g, ' ');
|
|
841
|
+
if (
|
|
842
|
+
flat.length >= 2 &&
|
|
843
|
+
flat.startsWith(' ') &&
|
|
844
|
+
flat.endsWith(' ') &&
|
|
845
|
+
flat.trim() !== ''
|
|
846
|
+
)
|
|
847
|
+
return flat.slice(1, -1);
|
|
848
|
+
return flat;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
function lastBracket(items: Item[]): number {
|
|
852
|
+
for (let k = items.length - 1; k >= 0; k -= 1)
|
|
853
|
+
if (items[k].kind === 'bracket') return k;
|
|
854
|
+
return -1;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
interface LinkSuffix {
|
|
858
|
+
href: string;
|
|
859
|
+
end: number;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/** `](dest "title")` — destination in `<>` or bare with balanced parens.
|
|
863
|
+
* The title is tolerated and dropped: nothing here renders one. */
|
|
864
|
+
function parseLinkSuffix(text: string, from: number): LinkSuffix | null {
|
|
865
|
+
if (text[from] !== '(') return null;
|
|
866
|
+
let i = from + 1;
|
|
867
|
+
const len = text.length;
|
|
868
|
+
while (i < len && (text[i] === ' ' || text[i] === '\n')) i += 1;
|
|
869
|
+
let href = '';
|
|
870
|
+
if (text[i] === '<') {
|
|
871
|
+
const close = text.indexOf('>', i + 1);
|
|
872
|
+
if (close === -1) return null;
|
|
873
|
+
href = text.slice(i + 1, close);
|
|
874
|
+
if (href.includes('\n')) return null;
|
|
875
|
+
i = close + 1;
|
|
876
|
+
} else {
|
|
877
|
+
let depth = 0;
|
|
878
|
+
while (i < len) {
|
|
879
|
+
const ch = text[i];
|
|
880
|
+
if (ch === '\\' && i + 1 < len) {
|
|
881
|
+
href += text[i + 1];
|
|
882
|
+
i += 2;
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
if (ch === '(') depth += 1;
|
|
886
|
+
if (ch === ')') {
|
|
887
|
+
if (depth === 0) break;
|
|
888
|
+
depth -= 1;
|
|
889
|
+
}
|
|
890
|
+
if (ch === ' ' || ch === '\n' || ch === '\t') break;
|
|
891
|
+
href += ch;
|
|
892
|
+
i += 1;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
while (i < len && (text[i] === ' ' || text[i] === '\n' || text[i] === '\t'))
|
|
896
|
+
i += 1;
|
|
897
|
+
// an optional title in any of the three quote styles
|
|
898
|
+
const q = text[i];
|
|
899
|
+
if (q === '"' || q === "'" || q === '(') {
|
|
900
|
+
const closer = q === '(' ? ')' : q;
|
|
901
|
+
let j = i + 1;
|
|
902
|
+
while (j < len && text[j] !== closer) j += 1;
|
|
903
|
+
if (j >= len) return null;
|
|
904
|
+
i = j + 1;
|
|
905
|
+
while (i < len && (text[i] === ' ' || text[i] === '\n' || text[i] === '\t'))
|
|
906
|
+
i += 1;
|
|
907
|
+
}
|
|
908
|
+
if (text[i] !== ')') return null;
|
|
909
|
+
return { href: decodeEntities(href), end: i + 1 };
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
/** Fold everything after the bracket opener at `openIdx` into a link node. */
|
|
913
|
+
function closeLink(items: Item[], openIdx: number, href: string | null): void {
|
|
914
|
+
const bracket = items[openIdx] as { kind: 'bracket'; image: boolean };
|
|
915
|
+
const inner = items.splice(openIdx);
|
|
916
|
+
inner.shift();
|
|
917
|
+
// emphasis inside the link text resolves within the link's own scope
|
|
918
|
+
processEmphasis(inner, href === null);
|
|
919
|
+
items.push({
|
|
920
|
+
kind: 'node',
|
|
921
|
+
node: { type: 'link', href, image: bracket.image, children: finish(inner) },
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* The CommonMark delimiter algorithm over `items`, in place: walk closers
|
|
927
|
+
* left to right, match each to the nearest compatible opener, wrap. The
|
|
928
|
+
* "rule of three" guards `**foo*` against eating the wrong marker. With
|
|
929
|
+
* `implicitClose` (the live tail), openers left standing afterwards close
|
|
930
|
+
* at the end of the text — that is `remend`'s bold/italic/strikethrough
|
|
931
|
+
* behaviour — unless nothing follows them, in which case they vanish.
|
|
932
|
+
*/
|
|
933
|
+
function processEmphasis(items: Item[], implicitClose: boolean): void {
|
|
934
|
+
let closer = 0;
|
|
935
|
+
while (closer < items.length) {
|
|
936
|
+
const c = items[closer];
|
|
937
|
+
if (c.kind !== 'delim' || !c.canClose) {
|
|
938
|
+
closer += 1;
|
|
939
|
+
continue;
|
|
940
|
+
}
|
|
941
|
+
let opener = -1;
|
|
942
|
+
for (let k = closer - 1; k >= 0; k -= 1) {
|
|
943
|
+
const o = items[k];
|
|
944
|
+
if (o.kind === 'bracket') break; // emphasis cannot cross a link boundary
|
|
945
|
+
if (o.kind !== 'delim' || o.char !== c.char || !o.canOpen) continue;
|
|
946
|
+
// rule of three
|
|
947
|
+
if (
|
|
948
|
+
(o.canClose || c.canOpen) &&
|
|
949
|
+
(o.length + c.length) % 3 === 0 &&
|
|
950
|
+
(o.length % 3 !== 0 || c.length % 3 !== 0)
|
|
951
|
+
)
|
|
952
|
+
continue;
|
|
953
|
+
opener = k;
|
|
954
|
+
break;
|
|
955
|
+
}
|
|
956
|
+
if (opener === -1) {
|
|
957
|
+
if (!c.canOpen) {
|
|
958
|
+
items.splice(closer, 1, delimToText(c));
|
|
959
|
+
}
|
|
960
|
+
closer += 1;
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
const o = items[opener] as Extract<Item, { kind: 'delim' }>;
|
|
965
|
+
const use = c.char === '~' ? 2 : Math.min(2, o.length, c.length);
|
|
966
|
+
const type = c.char === '~' ? 'del' : use === 2 ? 'strong' : 'em';
|
|
967
|
+
const inner = items.splice(opener + 1, closer - opener - 1);
|
|
968
|
+
const node: InlineNode = { type, children: finish(inner) };
|
|
969
|
+
o.length -= use;
|
|
970
|
+
c.length -= use;
|
|
971
|
+
items.splice(opener + 1, 0, { kind: 'node', node });
|
|
972
|
+
closer = opener + 2;
|
|
973
|
+
if (o.length === 0) {
|
|
974
|
+
items.splice(opener, 1);
|
|
975
|
+
closer -= 1;
|
|
976
|
+
}
|
|
977
|
+
if (c.length === 0) items.splice(closer, 1);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
if (implicitClose) {
|
|
981
|
+
// leftmost surviving opener wraps the rest; repeats handle `**a *b`
|
|
982
|
+
for (let k = 0; k < items.length; k += 1) {
|
|
983
|
+
const o = items[k];
|
|
984
|
+
if (o.kind !== 'delim' || !o.canOpen) continue;
|
|
985
|
+
const rest = items.splice(k + 1);
|
|
986
|
+
const restNodes = finish(rest);
|
|
987
|
+
if (restNodes.length === 0) {
|
|
988
|
+
items.splice(k, 1);
|
|
989
|
+
k -= 1;
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
let node: InlineNode;
|
|
993
|
+
if (o.char === '~') node = { type: 'del', children: restNodes };
|
|
994
|
+
else if (o.length >= 3)
|
|
995
|
+
node = {
|
|
996
|
+
type: 'strong',
|
|
997
|
+
children: [{ type: 'em', children: restNodes }],
|
|
998
|
+
};
|
|
999
|
+
else if (o.length === 2) node = { type: 'strong', children: restNodes };
|
|
1000
|
+
else node = { type: 'em', children: restNodes };
|
|
1001
|
+
items.splice(k, 1, { kind: 'node', node });
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// whatever survives was never emphasis — restore the literal characters
|
|
1006
|
+
for (let k = 0; k < items.length; k += 1) {
|
|
1007
|
+
const it = items[k];
|
|
1008
|
+
if (it.kind === 'delim') items.splice(k, 1, delimToText(it));
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
function delimToText(d: Extract<Item, { kind: 'delim' }>): Item {
|
|
1013
|
+
return {
|
|
1014
|
+
kind: 'node',
|
|
1015
|
+
node: { type: 'text', text: d.char.repeat(d.length) },
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/** Collapse a fully-resolved item list to nodes, merging adjacent texts. */
|
|
1020
|
+
function finish(items: Item[]): InlineNode[] {
|
|
1021
|
+
const out: InlineNode[] = [];
|
|
1022
|
+
for (const it of items) {
|
|
1023
|
+
const node =
|
|
1024
|
+
it.kind === 'node'
|
|
1025
|
+
? it.node
|
|
1026
|
+
: it.kind === 'delim'
|
|
1027
|
+
? ({ type: 'text', text: it.char.repeat(it.length) } as InlineNode)
|
|
1028
|
+
: ({ type: 'text', text: it.image ? '![' : '[' } as InlineNode);
|
|
1029
|
+
const prev = out[out.length - 1];
|
|
1030
|
+
if (node.type === 'text' && prev?.type === 'text') {
|
|
1031
|
+
prev.text += node.text;
|
|
1032
|
+
} else if (!(node.type === 'text' && node.text === '')) {
|
|
1033
|
+
out.push(node);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
return out;
|
|
1037
|
+
}
|