comark-file-tree 0.7.5 → 0.8.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 +3 -3
- package/dist/{client-Djg5meKD.mjs → client-DcAHu-LK.mjs} +71 -12
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +1 -1
- package/dist/html.mjs +21 -3
- package/dist/index.mjs +1 -209
- package/dist/react.mjs +2 -2
- package/dist/src-PLku93wQ.mjs +211 -0
- package/dist/style.css +1 -1
- package/dist/vue.mjs +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -33,17 +33,17 @@ README.md
|
|
|
33
33
|
|
|
34
34
|
Indent each level by two spaces, or paste what `tree` prints. A trailing `/` makes a folder; `+`, `-`, and `~` mark an entry added, removed, or changed; ` # ` starts a note; and `...` stands for entries left out. Pass `iconResolver` from comark-icon's `createIcons()` to draw each file's icon; without it, entries get plain glyphs and nothing is fetched.
|
|
35
35
|
|
|
36
|
-
The plugin adds every problem to `meta.issues`, so a host can reject a document before publishing it
|
|
36
|
+
The plugin adds every problem to `meta.issues`, so a host can reject a document before publishing it, such as a Markdown list instead of a fence (a list turns `__init__.py` bold and drops `[id].vue`), content beside the fence, and an empty block.
|
|
37
37
|
|
|
38
38
|
## Renderers
|
|
39
39
|
|
|
40
40
|
| Renderer | Import |
|
|
41
41
|
| --- | --- |
|
|
42
|
-
| `@comark/html` | `comark-file-tree/html`: the styles are inlined
|
|
42
|
+
| `@comark/html` | `comark-file-tree/html`: the styles are inlined |
|
|
43
43
|
| `@comark/vue` | `comark-file-tree/vue` |
|
|
44
44
|
| `@comark/react` | `comark-file-tree/react` |
|
|
45
45
|
| `@comark/svelte` | `comark-file-tree/svelte` |
|
|
46
46
|
|
|
47
47
|
Each entry exports the parse plugin as `default` and the renderer's `components`. The Vue, React, and Svelte components add the styles when they mount; import `comark-file-tree/style.css` with your styles so a server-rendered page doesn't shift.
|
|
48
48
|
|
|
49
|
-
The styles follow shadcn/ui: they read its CSS variables, such as `--accent` and `--border`, when the page has them, and use its neutral theme otherwise. Set the shared `--comark-*` tokens to theme every plugin at once; the rules sit in a `comark` CSS layer, so any plain rule of your own wins, except the spacing that draws the tree: the margins, padding, and bullets of its lists, `details`, and `summary` are `!important
|
|
49
|
+
The styles follow shadcn/ui: they read its CSS variables, such as `--accent` and `--border`, when the page has them, and use its neutral theme otherwise. Set the shared `--comark-*` tokens to theme every plugin at once; the rules sit in a `comark` CSS layer, so any plain rule of your own wins, except the spacing that draws the tree: the margins, padding, and bullets of its lists, `details`, and `summary` are `!important`. Override those with `!important` too.
|
|
@@ -43,20 +43,72 @@ const tokens = [
|
|
|
43
43
|
"#737373"
|
|
44
44
|
]
|
|
45
45
|
];
|
|
46
|
-
const
|
|
46
|
+
const groups = {
|
|
47
|
+
status: Object.values({
|
|
48
|
+
success: [
|
|
49
|
+
"success",
|
|
50
|
+
"ui-success",
|
|
51
|
+
"success",
|
|
52
|
+
"#259f56",
|
|
53
|
+
"#59d38c"
|
|
54
|
+
],
|
|
55
|
+
danger: [
|
|
56
|
+
"danger",
|
|
57
|
+
"ui-error",
|
|
58
|
+
"destructive",
|
|
59
|
+
"#ee3533",
|
|
60
|
+
"#fd736d"
|
|
61
|
+
],
|
|
62
|
+
warning: [
|
|
63
|
+
"warning",
|
|
64
|
+
"ui-warning",
|
|
65
|
+
"",
|
|
66
|
+
"#d97706",
|
|
67
|
+
"#fbbf24"
|
|
68
|
+
],
|
|
69
|
+
info: [
|
|
70
|
+
"info",
|
|
71
|
+
"ui-info",
|
|
72
|
+
"",
|
|
73
|
+
"#2563eb",
|
|
74
|
+
"#60a5fa"
|
|
75
|
+
]
|
|
76
|
+
}),
|
|
77
|
+
shadow: [[
|
|
78
|
+
"shadow",
|
|
79
|
+
"",
|
|
80
|
+
"",
|
|
81
|
+
"0 4px 12px rgb(0 0 0/.12)",
|
|
82
|
+
"0 4px 12px rgb(0 0 0/.5)"
|
|
83
|
+
]]
|
|
84
|
+
};
|
|
85
|
+
const chain = (token, scheme) => {
|
|
86
|
+
const shadcn = token[2] ? `var(--${token[2]},${token[scheme]})` : token[scheme];
|
|
87
|
+
const nuxt = token[1] ? `var(--${token[1]},${shadcn})` : shadcn;
|
|
88
|
+
return `var(--comark-${token[0]},${nuxt})`;
|
|
89
|
+
};
|
|
90
|
+
const resolve = (list, scheme) => list.map((token) => `--_comark-${token[0]}:${chain(token, scheme)}`).join(";");
|
|
47
91
|
/**
|
|
48
92
|
* Resolves the `--comark-*` tokens on `selector`, falling back to Nuxt UI's variables, then shadcn/ui's, then shadcn's
|
|
49
93
|
* neutral theme. Nuxt UI's corners are twice its `--ui-radius`, so the radius halves shadcn's to double it back.
|
|
50
94
|
* They resolve on the component rather than `:root`, so a `.dark` class anywhere above it switches the theme, and a
|
|
51
95
|
* `--comark-*` set on any ancestor still inherits down. `:where()` keeps them at zero specificity.
|
|
96
|
+
*
|
|
97
|
+
* Every block gets the core tokens. Name `"status"` for `--comark-success`, `-danger`, `-warning`, and `-info`, and
|
|
98
|
+
* `"shadow"` for `--comark-shadow`, so a block that never draws them doesn't carry them.
|
|
52
99
|
*/
|
|
53
|
-
function theme(selector) {
|
|
100
|
+
function theme(selector, ...extras) {
|
|
54
101
|
const where = `:where(${selector})`;
|
|
55
|
-
|
|
102
|
+
const added = extras.flatMap((name) => groups[name]);
|
|
103
|
+
const list = [...tokens, ...added];
|
|
104
|
+
const classes = added.length ? `:where(.light,.light *)${where}{${resolve(added, 3)}}:where(.dark,.dark *)${where}{${resolve(added, 4)}}` : "";
|
|
105
|
+
return `${where}{${resolve(list, 3)};--_comark-radius:var(--comark-radius,calc(var(--ui-radius,calc(var(--radius,.625rem)/2))*2));--_comark-font:var(--comark-font,var(--font-sans,ui-sans-serif,system-ui,sans-serif))}@media (prefers-color-scheme:dark){${where}{${resolve(list, 4)}}}` + classes;
|
|
56
106
|
}
|
|
57
107
|
//#endregion
|
|
58
108
|
//#region ../../shared/disclosure.ts
|
|
59
|
-
const
|
|
109
|
+
const opening = ".25s cubic-bezier(.23,1,.32,1)";
|
|
110
|
+
const closing = ".18s cubic-bezier(.23,1,.32,1)";
|
|
111
|
+
const disclosureMotion = (selector, rules = "") => `@supports (interpolate-size:allow-keywords) and selector(::details-content){@media screen and (prefers-reduced-motion:no-preference){${selector}{interpolate-size:allow-keywords}${selector}::details-content{display:flow-root;block-size:0;opacity:0;overflow-y:clip;transition:block-size ${closing},opacity .12s ease-in,content-visibility .18s allow-discrete}${selector}[open]::details-content{block-size:auto;opacity:1;transition:block-size ${opening},opacity ${opening},content-visibility .25s allow-discrete}${rules}}}`;
|
|
60
112
|
//#endregion
|
|
61
113
|
//#region src/styles.ts
|
|
62
114
|
/**
|
|
@@ -66,9 +118,8 @@ const disclosureMotion = (selector) => `@supports (interpolate-size:allow-keywor
|
|
|
66
118
|
*/
|
|
67
119
|
const css = `@layer comark{${[
|
|
68
120
|
disclosureMotion(".cft details"),
|
|
69
|
-
theme(".cft"),
|
|
70
|
-
":where(.cft){--cft-added
|
|
71
|
-
"@media (prefers-color-scheme:dark){:where(.cft){--cft-added:#4ade80;--cft-removed:var(--destructive,#f87171);--cft-changed:#fbbf24}}",
|
|
121
|
+
theme(".cft", "status"),
|
|
122
|
+
":where(.cft){--cft-added:var(--_comark-success);--cft-removed:var(--_comark-danger);--cft-changed:var(--_comark-warning)}",
|
|
72
123
|
".cft{margin:1.5rem 0;padding:.75rem;overflow-x:auto;border:1px solid var(--_comark-border);border-radius:var(--_comark-radius);background:var(--_comark-background);color:var(--_comark-foreground);font:400 .8125rem/1.25rem ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}",
|
|
73
124
|
".cft ul{margin:0!important;padding:0!important;list-style:none!important}",
|
|
74
125
|
".cft ul ul{margin-inline-start:calc(.5rem - .5px)!important;padding-inline-start:.75rem!important;border-inline-start:1px solid var(--_comark-border)}",
|
|
@@ -90,15 +141,23 @@ const css = `@layer comark{${[
|
|
|
90
141
|
".cft [data-type='more']{padding:0 .25rem;color:var(--_comark-muted)}"
|
|
91
142
|
].join("")}}`;
|
|
92
143
|
//#endregion
|
|
93
|
-
//#region
|
|
94
|
-
/**
|
|
95
|
-
|
|
96
|
-
|
|
144
|
+
//#region ../../shared/styles.ts
|
|
145
|
+
/**
|
|
146
|
+
* Adds a package's styles to the page once, unless the page already carries them as a `style` or a `link` with
|
|
147
|
+
* `data-comark-<name>`, which is how the HTML renderer inlines them and how an app that imports `style.css` marks them.
|
|
148
|
+
*/
|
|
149
|
+
function addStyles$1(name, css) {
|
|
150
|
+
const attribute = `data-comark-${name}`;
|
|
151
|
+
if (document.querySelector(`style[${attribute}],link[${attribute}]`)) return;
|
|
97
152
|
const style = document.createElement("style");
|
|
98
|
-
style.
|
|
153
|
+
style.setAttribute(attribute, "");
|
|
99
154
|
style.textContent = css;
|
|
100
155
|
document.head.append(style);
|
|
101
156
|
}
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/client.ts
|
|
159
|
+
/** Adds the file tree styles to the page once. The Vue, React, and Svelte components call it when they mount. */
|
|
160
|
+
const addStyles = () => addStyles$1("file-tree", css);
|
|
102
161
|
/**
|
|
103
162
|
* Lucide's folder and file (ISC), each as one path, for entries without an icon. Every renderer draws them in the
|
|
104
163
|
* same `<svg>`, sized for a page without the styles.
|
package/dist/client.d.mts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const css: string;
|
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/client.d.ts
|
|
10
10
|
/** Adds the file tree styles to the page once. The Vue, React, and Svelte components call it when they mount. */
|
|
11
|
-
export declare
|
|
11
|
+
export declare const addStyles: () => void;
|
|
12
12
|
/**
|
|
13
13
|
* Lucide's folder and file (ISC), each as one path, for entries without an icon. Every renderer draws them in the
|
|
14
14
|
* same `<svg>`, sized for a page without the styles.
|
package/dist/client.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as addStyles, i as css, n as glyphs, r as marks } from "./client-
|
|
1
|
+
export { t as addStyles, i as css, n as glyphs, r as marks } from "./client-DcAHu-LK.mjs";
|
package/dist/html.mjs
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
import src_default from "./
|
|
2
|
-
import { i as css, n as glyphs, r as marks } from "./client-
|
|
1
|
+
import { t as src_default } from "./src-PLku93wQ.mjs";
|
|
2
|
+
import { i as css, n as glyphs, r as marks } from "./client-DcAHu-LK.mjs";
|
|
3
3
|
import { escapeHtml } from "comark/utils";
|
|
4
4
|
import { iconHtml, iconStyles } from "comark-icon/html";
|
|
5
|
+
//#region ../../shared/text.ts
|
|
6
|
+
/**
|
|
7
|
+
* A prop value as text. Comark writes strings, numbers, and booleans, so an object, array, function, or missing value
|
|
8
|
+
* is no text. The `typeof` check, unlike `instanceof`, can't throw on a revoked proxy.
|
|
9
|
+
*/
|
|
10
|
+
function scalar(value) {
|
|
11
|
+
switch (typeof value) {
|
|
12
|
+
case "string": return value;
|
|
13
|
+
case "number":
|
|
14
|
+
case "boolean":
|
|
15
|
+
case "bigint":
|
|
16
|
+
case "symbol": return String(value);
|
|
17
|
+
default: return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** A prop value as text exactly as written, or empty when it has none. */
|
|
21
|
+
const rawText = (value) => scalar(value) ?? "";
|
|
22
|
+
//#endregion
|
|
5
23
|
//#region src/html.ts
|
|
6
24
|
const styled = /* @__PURE__ */ new WeakSet();
|
|
7
|
-
const text = (value) =>
|
|
25
|
+
const text = (value) => escapeHtml(rawText(value));
|
|
8
26
|
const glyph = (d) => `<svg class="cft-glyph" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${d}"></path></svg>`;
|
|
9
27
|
const hasIcon = (node) => Array.isArray(node) && (Boolean(node[1]?.icon) || node.slice(2).some(hasIcon));
|
|
10
28
|
const fileTree = async (node, state) => {
|
package/dist/index.mjs
CHANGED
|
@@ -1,209 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { textContent } from "comark/utils";
|
|
3
|
-
//#region src/index.ts
|
|
4
|
-
const isElement = (node) => Array.isArray(node) && node[0] !== null;
|
|
5
|
-
const isContent = (node) => Array.isArray(node) ? node[0] !== null : node.trim() !== "";
|
|
6
|
-
const childrenOf = (node) => node.slice(2);
|
|
7
|
-
const clip = (value) => {
|
|
8
|
-
const words = value.trim().replace(/\s+/g, " ");
|
|
9
|
-
return words.length > 40 ? `${words.slice(0, 39)}…` : words;
|
|
10
|
-
};
|
|
11
|
-
const ICONS = {
|
|
12
|
-
folder: "vscode-icons:default-folder-opened",
|
|
13
|
-
file: "vscode-icons:default-file",
|
|
14
|
-
".ts": "vscode-icons:file-type-typescript-official",
|
|
15
|
-
".mts": "vscode-icons:file-type-typescript-official",
|
|
16
|
-
".cts": "vscode-icons:file-type-typescript-official",
|
|
17
|
-
".tsx": "vscode-icons:file-type-reactts",
|
|
18
|
-
".js": "vscode-icons:file-type-js-official",
|
|
19
|
-
".mjs": "vscode-icons:file-type-js-official",
|
|
20
|
-
".cjs": "vscode-icons:file-type-js-official",
|
|
21
|
-
".jsx": "vscode-icons:file-type-reactjs",
|
|
22
|
-
".json": "vscode-icons:file-type-json",
|
|
23
|
-
".md": "vscode-icons:file-type-markdown",
|
|
24
|
-
".mdx": "vscode-icons:file-type-mdx",
|
|
25
|
-
".vue": "vscode-icons:file-type-vue",
|
|
26
|
-
".svelte": "vscode-icons:file-type-svelte",
|
|
27
|
-
".astro": "vscode-icons:file-type-astro",
|
|
28
|
-
".css": "vscode-icons:file-type-css",
|
|
29
|
-
".scss": "vscode-icons:file-type-scss",
|
|
30
|
-
".html": "vscode-icons:file-type-html",
|
|
31
|
-
".yaml": "vscode-icons:file-type-yaml",
|
|
32
|
-
".yml": "vscode-icons:file-type-yaml",
|
|
33
|
-
".toml": "vscode-icons:file-type-toml",
|
|
34
|
-
".py": "vscode-icons:file-type-python",
|
|
35
|
-
".rs": "vscode-icons:file-type-rust",
|
|
36
|
-
".go": "vscode-icons:file-type-go",
|
|
37
|
-
".sh": "vscode-icons:file-type-shell",
|
|
38
|
-
".svg": "vscode-icons:file-type-svg",
|
|
39
|
-
".png": "vscode-icons:file-type-image",
|
|
40
|
-
".jpg": "vscode-icons:file-type-image",
|
|
41
|
-
".jpeg": "vscode-icons:file-type-image",
|
|
42
|
-
".gif": "vscode-icons:file-type-image",
|
|
43
|
-
".webp": "vscode-icons:file-type-image",
|
|
44
|
-
".txt": "vscode-icons:file-type-text",
|
|
45
|
-
".env": "vscode-icons:file-type-dotenv",
|
|
46
|
-
".gitignore": "vscode-icons:file-type-git",
|
|
47
|
-
"package.json": "vscode-icons:file-type-npm",
|
|
48
|
-
"tsconfig.json": "vscode-icons:file-type-tsconfig",
|
|
49
|
-
"pnpm-lock.yaml": "vscode-icons:file-type-pnpm",
|
|
50
|
-
"pnpm-workspace.yaml": "vscode-icons:file-type-pnpm",
|
|
51
|
-
dockerfile: "vscode-icons:file-type-docker",
|
|
52
|
-
license: "vscode-icons:file-type-license"
|
|
53
|
-
};
|
|
54
|
-
const STATES = /* @__PURE__ */ new Map([
|
|
55
|
-
["+", "added"],
|
|
56
|
-
["-", "removed"],
|
|
57
|
-
["~", "changed"]
|
|
58
|
-
]);
|
|
59
|
-
const BRANCHES = /^(?:[│|][\s ]{2,3}|[\s ])*(?:[├└|`+\\](?:──|--)[─-]*[\s ]?)?/u;
|
|
60
|
-
const NOTE = /\s+#\s+(.*)$/;
|
|
61
|
-
const SUMMARY = /^\d+ director(?:y|ies)(?:, \d+ files?)?$/;
|
|
62
|
-
function entry(source) {
|
|
63
|
-
let rest = source;
|
|
64
|
-
const note = NOTE.exec(rest);
|
|
65
|
-
if (note) rest = rest.slice(0, note.index);
|
|
66
|
-
rest = rest.trim();
|
|
67
|
-
const marker = /^([+~-])\s+/.exec(rest);
|
|
68
|
-
if (marker) rest = rest.slice(marker[0].length);
|
|
69
|
-
if (!rest) return void 0;
|
|
70
|
-
const attrs = {};
|
|
71
|
-
if (rest === "..." || rest === "…") attrs.type = "more";
|
|
72
|
-
else if (rest.endsWith("/")) {
|
|
73
|
-
attrs.type = "folder";
|
|
74
|
-
attrs.name = rest.replace(/\/+$/, "");
|
|
75
|
-
} else {
|
|
76
|
-
attrs.type = "file";
|
|
77
|
-
attrs.name = rest;
|
|
78
|
-
}
|
|
79
|
-
const state = STATES.get(marker?.[1] ?? "");
|
|
80
|
-
if (state) attrs.state = state;
|
|
81
|
-
if (note?.[1]?.trim()) attrs.note = note[1].trim();
|
|
82
|
-
return ["file-tree-item", attrs];
|
|
83
|
-
}
|
|
84
|
-
function readTree(source) {
|
|
85
|
-
const roots = [];
|
|
86
|
-
const open = [];
|
|
87
|
-
for (const raw of source.split("\n")) {
|
|
88
|
-
const line = raw.replace(/\s+$/, "");
|
|
89
|
-
const column = BRANCHES.exec(line)?.[0].length ?? 0;
|
|
90
|
-
if (SUMMARY.test(line.slice(column))) continue;
|
|
91
|
-
const item = entry(line.slice(column));
|
|
92
|
-
if (!item) continue;
|
|
93
|
-
while (open.length && (open.at(-1)?.column ?? 0) >= column) open.pop();
|
|
94
|
-
const parent = open.at(-1)?.item;
|
|
95
|
-
if (parent) {
|
|
96
|
-
if (parent[1].type === "file") parent[1].type = "folder";
|
|
97
|
-
parent.push(item);
|
|
98
|
-
} else roots.push(item);
|
|
99
|
-
if (item[1].type !== "more") open.push({
|
|
100
|
-
column,
|
|
101
|
-
item
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
const [only] = roots;
|
|
105
|
-
if (roots.length === 1 && only?.[1].name === ".") return childrenOf(only).filter(isElement);
|
|
106
|
-
return roots;
|
|
107
|
-
}
|
|
108
|
-
function iconKey(item, icons) {
|
|
109
|
-
const name = (item[1].name ?? "").toLowerCase();
|
|
110
|
-
if (item[1].type === "folder") return icons[`${name}/`] ?? icons.folder;
|
|
111
|
-
const dot = name.lastIndexOf(".");
|
|
112
|
-
return icons[name] ?? (dot >= 0 ? icons[name.slice(dot)] : void 0) ?? icons.file;
|
|
113
|
-
}
|
|
114
|
-
function* items(nodes) {
|
|
115
|
-
for (const node of nodes) {
|
|
116
|
-
if (!isElement(node)) continue;
|
|
117
|
-
if (node[0] === "file-tree-item") yield node;
|
|
118
|
-
yield* items(childrenOf(node));
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
const KINDS = /* @__PURE__ */ new Map([
|
|
122
|
-
["p", "paragraph"],
|
|
123
|
-
["ul", "list"],
|
|
124
|
-
["ol", "list"],
|
|
125
|
-
["blockquote", "quote"],
|
|
126
|
-
["table", "table"]
|
|
127
|
-
]);
|
|
128
|
-
function describe(node) {
|
|
129
|
-
if (!Array.isArray(node)) return `the text "${clip(node)}"`;
|
|
130
|
-
if (!isElement(node)) return "a comment";
|
|
131
|
-
const kind = KINDS.get(node[0]) ?? `\`${node[0]}\``;
|
|
132
|
-
const words = clip(textContent(node));
|
|
133
|
-
return `the ${kind}${words ? ` "${words}"` : ""}`;
|
|
134
|
-
}
|
|
135
|
-
function fileTree(node, name, issues) {
|
|
136
|
-
for (const key of Object.keys(node[1])) {
|
|
137
|
-
const prop = key.replace(/^:/, "");
|
|
138
|
-
if (prop !== "id" && prop !== "class") issues.push({
|
|
139
|
-
rule: "comark/file-tree/unknown-prop",
|
|
140
|
-
message: `${name}: \`${prop}\` isn't a prop of \`::file-tree\`, which takes none, so it's ignored. Remove it.`
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
const content = childrenOf(node).filter(isContent);
|
|
144
|
-
const [block] = content.filter((child) => isElement(child) && child[0] === "pre");
|
|
145
|
-
if (!isElement(block)) {
|
|
146
|
-
const list = content.find((child) => isElement(child) && /^[ou]l$/.test(child[0]));
|
|
147
|
-
issues.push(list ? {
|
|
148
|
-
rule: "comark/file-tree/list-instead-of-fence",
|
|
149
|
-
message: `${name} holds a Markdown list, which turns names like \`__init__.py\` bold and drops \`[id].vue\`. Write the tree in a fenced block.`
|
|
150
|
-
} : {
|
|
151
|
-
rule: "comark/file-tree/empty-tree",
|
|
152
|
-
message: `${name} has no tree. Write the tree in a fenced block inside it, one entry per line.`
|
|
153
|
-
});
|
|
154
|
-
return content;
|
|
155
|
-
}
|
|
156
|
-
for (const child of content) if (child !== block) issues.push({
|
|
157
|
-
rule: "comark/file-tree/content-dropped",
|
|
158
|
-
message: `${name}: only one fenced block goes inside, so ${describe(child)} doesn't render. Move it out of the block.`
|
|
159
|
-
});
|
|
160
|
-
const tree = readTree(textContent(block));
|
|
161
|
-
if (!tree.length) issues.push({
|
|
162
|
-
rule: "comark/file-tree/empty-tree",
|
|
163
|
-
message: `${name}'s fenced block is empty. Write one entry per line.`
|
|
164
|
-
});
|
|
165
|
-
node.splice(1, node.length - 1, {}, ...tree);
|
|
166
|
-
return [node];
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Turns `::file-tree` around a fenced block, one entry per line indented by two spaces or pasted from `tree`, into a
|
|
170
|
-
* tree of folders and files. A trailing `/` makes a folder, `+`, `-`, and `~` mark an entry added, removed, or
|
|
171
|
-
* changed, `# note` ends a line with a note, and `...` stands for entries left out. Problems are added to `meta.issues`.
|
|
172
|
-
*/
|
|
173
|
-
var src_default = defineComarkPlugin((options = {}) => {
|
|
174
|
-
const icons = Object.fromEntries(Object.entries({
|
|
175
|
-
...ICONS,
|
|
176
|
-
...options.icons
|
|
177
|
-
}).map(([key, icon]) => [key.toLowerCase(), icon]));
|
|
178
|
-
return {
|
|
179
|
-
name: "comark-file-tree",
|
|
180
|
-
async post(state) {
|
|
181
|
-
const { tree } = state;
|
|
182
|
-
const issues = [];
|
|
183
|
-
let count = 0;
|
|
184
|
-
const transform = (nodes) => nodes.flatMap((node) => {
|
|
185
|
-
if (!isElement(node)) return [node];
|
|
186
|
-
if (node[0] === "file-tree") return fileTree(node, `\`::file-tree\` ${++count}`, issues);
|
|
187
|
-
node.splice(2, node.length - 2, ...transform(childrenOf(node)));
|
|
188
|
-
return [node];
|
|
189
|
-
});
|
|
190
|
-
tree.nodes = transform(tree.nodes);
|
|
191
|
-
if (options.iconResolver) {
|
|
192
|
-
const all = [...items(tree.nodes)].filter((item) => item[1].type !== "more");
|
|
193
|
-
const keys = all.map((item) => iconKey(item, icons));
|
|
194
|
-
const resolved = await options.iconResolver.resolve(keys.filter((key) => Boolean(key)));
|
|
195
|
-
for (const [at, item] of all.entries()) {
|
|
196
|
-
const icon = resolved.get(keys[at] ?? "");
|
|
197
|
-
if (icon && "src" in icon) item[1].icon = icon;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
tree.meta.issues = [...tree.meta.issues ?? [], ...issues.map((issue) => issue.message)];
|
|
201
|
-
tree.meta.issueRules = {
|
|
202
|
-
...tree.meta.issueRules,
|
|
203
|
-
...Object.fromEntries(issues.map((issue) => [issue.message, issue.rule]))
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
});
|
|
208
|
-
//#endregion
|
|
209
|
-
export { src_default as default };
|
|
1
|
+
export { t as default } from "./src-PLku93wQ.mjs";
|
package/dist/react.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import src_default from "./
|
|
2
|
-
import { n as glyphs, r as marks, t as addStyles } from "./client-
|
|
1
|
+
import { t as src_default } from "./src-PLku93wQ.mjs";
|
|
2
|
+
import { n as glyphs, r as marks, t as addStyles } from "./client-DcAHu-LK.mjs";
|
|
3
3
|
import { Icon } from "comark-icon/react";
|
|
4
4
|
import { createElement, useEffect } from "react";
|
|
5
5
|
//#region src/react.ts
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { defineComarkPlugin } from "comark";
|
|
2
|
+
import { textContent } from "comark/utils";
|
|
3
|
+
//#region ../../shared/nodes.ts
|
|
4
|
+
const isElement = (node) => Array.isArray(node) && node[0] !== null;
|
|
5
|
+
const childrenOf = ([, , ...rest]) => rest;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/index.ts
|
|
8
|
+
const isContent = (node) => Array.isArray(node) ? node[0] !== null : node.trim() !== "";
|
|
9
|
+
const clip = (value) => {
|
|
10
|
+
const words = value.trim().replace(/\s+/g, " ");
|
|
11
|
+
return words.length > 40 ? `${words.slice(0, 39)}…` : words;
|
|
12
|
+
};
|
|
13
|
+
const ICONS = {
|
|
14
|
+
folder: "vscode-icons:default-folder-opened",
|
|
15
|
+
file: "vscode-icons:default-file",
|
|
16
|
+
".ts": "vscode-icons:file-type-typescript-official",
|
|
17
|
+
".mts": "vscode-icons:file-type-typescript-official",
|
|
18
|
+
".cts": "vscode-icons:file-type-typescript-official",
|
|
19
|
+
".tsx": "vscode-icons:file-type-reactts",
|
|
20
|
+
".js": "vscode-icons:file-type-js-official",
|
|
21
|
+
".mjs": "vscode-icons:file-type-js-official",
|
|
22
|
+
".cjs": "vscode-icons:file-type-js-official",
|
|
23
|
+
".jsx": "vscode-icons:file-type-reactjs",
|
|
24
|
+
".json": "vscode-icons:file-type-json",
|
|
25
|
+
".md": "vscode-icons:file-type-markdown",
|
|
26
|
+
".mdx": "vscode-icons:file-type-mdx",
|
|
27
|
+
".vue": "vscode-icons:file-type-vue",
|
|
28
|
+
".svelte": "vscode-icons:file-type-svelte",
|
|
29
|
+
".astro": "vscode-icons:file-type-astro",
|
|
30
|
+
".css": "vscode-icons:file-type-css",
|
|
31
|
+
".scss": "vscode-icons:file-type-scss",
|
|
32
|
+
".html": "vscode-icons:file-type-html",
|
|
33
|
+
".yaml": "vscode-icons:file-type-yaml",
|
|
34
|
+
".yml": "vscode-icons:file-type-yaml",
|
|
35
|
+
".toml": "vscode-icons:file-type-toml",
|
|
36
|
+
".py": "vscode-icons:file-type-python",
|
|
37
|
+
".rs": "vscode-icons:file-type-rust",
|
|
38
|
+
".go": "vscode-icons:file-type-go",
|
|
39
|
+
".sh": "vscode-icons:file-type-shell",
|
|
40
|
+
".svg": "vscode-icons:file-type-svg",
|
|
41
|
+
".png": "vscode-icons:file-type-image",
|
|
42
|
+
".jpg": "vscode-icons:file-type-image",
|
|
43
|
+
".jpeg": "vscode-icons:file-type-image",
|
|
44
|
+
".gif": "vscode-icons:file-type-image",
|
|
45
|
+
".webp": "vscode-icons:file-type-image",
|
|
46
|
+
".txt": "vscode-icons:file-type-text",
|
|
47
|
+
".env": "vscode-icons:file-type-dotenv",
|
|
48
|
+
".gitignore": "vscode-icons:file-type-git",
|
|
49
|
+
"package.json": "vscode-icons:file-type-npm",
|
|
50
|
+
"tsconfig.json": "vscode-icons:file-type-tsconfig",
|
|
51
|
+
"pnpm-lock.yaml": "vscode-icons:file-type-pnpm",
|
|
52
|
+
"pnpm-workspace.yaml": "vscode-icons:file-type-pnpm",
|
|
53
|
+
dockerfile: "vscode-icons:file-type-docker",
|
|
54
|
+
license: "vscode-icons:file-type-license"
|
|
55
|
+
};
|
|
56
|
+
const STATES = /* @__PURE__ */ new Map([
|
|
57
|
+
["+", "added"],
|
|
58
|
+
["-", "removed"],
|
|
59
|
+
["~", "changed"]
|
|
60
|
+
]);
|
|
61
|
+
const BRANCHES = /^(?:[│|][\s ]{2,3}|[\s ])*(?:[├└|`+\\](?:──|--)[─-]*[\s ]?)?/u;
|
|
62
|
+
const NOTE = /\s+#\s+(.*)$/;
|
|
63
|
+
const SUMMARY = /^\d+ director(?:y|ies)(?:, \d+ files?)?$/;
|
|
64
|
+
function entry(source) {
|
|
65
|
+
let rest = source;
|
|
66
|
+
const note = NOTE.exec(rest);
|
|
67
|
+
if (note) rest = rest.slice(0, note.index);
|
|
68
|
+
rest = rest.trim();
|
|
69
|
+
const marker = /^([+~-])\s+/.exec(rest);
|
|
70
|
+
if (marker) rest = rest.slice(marker[0].length);
|
|
71
|
+
if (!rest) return void 0;
|
|
72
|
+
const attrs = {};
|
|
73
|
+
if (rest === "..." || rest === "…") attrs.type = "more";
|
|
74
|
+
else if (rest.endsWith("/")) {
|
|
75
|
+
attrs.type = "folder";
|
|
76
|
+
attrs.name = rest.replace(/\/+$/, "");
|
|
77
|
+
} else {
|
|
78
|
+
attrs.type = "file";
|
|
79
|
+
attrs.name = rest;
|
|
80
|
+
}
|
|
81
|
+
const state = STATES.get(marker?.[1] ?? "");
|
|
82
|
+
if (state) attrs.state = state;
|
|
83
|
+
if (note?.[1]?.trim()) attrs.note = note[1].trim();
|
|
84
|
+
return ["file-tree-item", attrs];
|
|
85
|
+
}
|
|
86
|
+
function readTree(source) {
|
|
87
|
+
const roots = [];
|
|
88
|
+
const open = [];
|
|
89
|
+
for (const raw of source.split("\n")) {
|
|
90
|
+
const line = raw.replace(/\s+$/, "");
|
|
91
|
+
const column = BRANCHES.exec(line)?.[0].length ?? 0;
|
|
92
|
+
if (SUMMARY.test(line.slice(column))) continue;
|
|
93
|
+
const item = entry(line.slice(column));
|
|
94
|
+
if (!item) continue;
|
|
95
|
+
while (open.length && (open.at(-1)?.column ?? 0) >= column) open.pop();
|
|
96
|
+
const parent = open.at(-1)?.item;
|
|
97
|
+
if (parent) {
|
|
98
|
+
if (parent[1].type === "file") parent[1].type = "folder";
|
|
99
|
+
parent.push(item);
|
|
100
|
+
} else roots.push(item);
|
|
101
|
+
if (item[1].type !== "more") open.push({
|
|
102
|
+
column,
|
|
103
|
+
item
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const [only] = roots;
|
|
107
|
+
if (roots.length === 1 && only?.[1].name === ".") return childrenOf(only).filter(isElement);
|
|
108
|
+
return roots;
|
|
109
|
+
}
|
|
110
|
+
function iconKey(item, icons) {
|
|
111
|
+
const name = (item[1].name ?? "").toLowerCase();
|
|
112
|
+
if (item[1].type === "folder") return icons[`${name}/`] ?? icons.folder;
|
|
113
|
+
const dot = name.lastIndexOf(".");
|
|
114
|
+
return icons[name] ?? (dot >= 0 ? icons[name.slice(dot)] : void 0) ?? icons.file;
|
|
115
|
+
}
|
|
116
|
+
function* items(nodes) {
|
|
117
|
+
for (const node of nodes) {
|
|
118
|
+
if (!isElement(node)) continue;
|
|
119
|
+
if (node[0] === "file-tree-item") yield node;
|
|
120
|
+
yield* items(childrenOf(node));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const KINDS = /* @__PURE__ */ new Map([
|
|
124
|
+
["p", "paragraph"],
|
|
125
|
+
["ul", "list"],
|
|
126
|
+
["ol", "list"],
|
|
127
|
+
["blockquote", "quote"],
|
|
128
|
+
["table", "table"]
|
|
129
|
+
]);
|
|
130
|
+
function describe(node) {
|
|
131
|
+
if (!Array.isArray(node)) return `the text "${clip(node)}"`;
|
|
132
|
+
if (!isElement(node)) return "a comment";
|
|
133
|
+
const kind = KINDS.get(node[0]) ?? `\`${node[0]}\``;
|
|
134
|
+
const words = clip(textContent(node));
|
|
135
|
+
return `the ${kind}${words ? ` "${words}"` : ""}`;
|
|
136
|
+
}
|
|
137
|
+
function fileTree(node, name, issues) {
|
|
138
|
+
for (const key of Object.keys(node[1])) {
|
|
139
|
+
const prop = key.replace(/^:/, "");
|
|
140
|
+
if (prop !== "id" && prop !== "class") issues.push({
|
|
141
|
+
rule: "comark/file-tree/unknown-prop",
|
|
142
|
+
message: `${name}: \`${prop}\` isn't a prop of \`::file-tree\`, which takes none, so it's ignored. Remove it.`
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
const content = childrenOf(node).filter(isContent);
|
|
146
|
+
const [block] = content.filter((child) => isElement(child) && child[0] === "pre");
|
|
147
|
+
if (!isElement(block)) {
|
|
148
|
+
const list = content.find((child) => isElement(child) && /^[ou]l$/.test(child[0]));
|
|
149
|
+
issues.push(list ? {
|
|
150
|
+
rule: "comark/file-tree/list-instead-of-fence",
|
|
151
|
+
message: `${name} holds a Markdown list, which turns names like \`__init__.py\` bold and drops \`[id].vue\`. Write the tree in a fenced block.`
|
|
152
|
+
} : {
|
|
153
|
+
rule: "comark/file-tree/empty-tree",
|
|
154
|
+
message: `${name} has no tree. Write the tree in a fenced block inside it, one entry per line.`
|
|
155
|
+
});
|
|
156
|
+
return content;
|
|
157
|
+
}
|
|
158
|
+
for (const child of content) if (child !== block) issues.push({
|
|
159
|
+
rule: "comark/file-tree/content-dropped",
|
|
160
|
+
message: `${name}: only one fenced block goes inside, so ${describe(child)} doesn't render. Move it out of the block.`
|
|
161
|
+
});
|
|
162
|
+
const tree = readTree(textContent(block));
|
|
163
|
+
if (!tree.length) issues.push({
|
|
164
|
+
rule: "comark/file-tree/empty-tree",
|
|
165
|
+
message: `${name}'s fenced block is empty. Write one entry per line.`
|
|
166
|
+
});
|
|
167
|
+
node.splice(1, node.length - 1, {}, ...tree);
|
|
168
|
+
return [node];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Turns `::file-tree` around a fenced block, one entry per line indented by two spaces or pasted from `tree`, into a
|
|
172
|
+
* tree of folders and files. A trailing `/` makes a folder, `+`, `-`, and `~` mark an entry added, removed, or
|
|
173
|
+
* changed, `# note` ends a line with a note, and `...` stands for entries left out. Problems are added to `meta.issues`.
|
|
174
|
+
*/
|
|
175
|
+
var src_default = defineComarkPlugin((options = {}) => {
|
|
176
|
+
const icons = Object.fromEntries(Object.entries({
|
|
177
|
+
...ICONS,
|
|
178
|
+
...options.icons
|
|
179
|
+
}).map(([key, icon]) => [key.toLowerCase(), icon]));
|
|
180
|
+
return {
|
|
181
|
+
name: "comark-file-tree",
|
|
182
|
+
async post(state) {
|
|
183
|
+
const { tree } = state;
|
|
184
|
+
const issues = [];
|
|
185
|
+
let count = 0;
|
|
186
|
+
const transform = (nodes) => nodes.flatMap((node) => {
|
|
187
|
+
if (!isElement(node)) return [node];
|
|
188
|
+
if (node[0] === "file-tree") return fileTree(node, `\`::file-tree\` ${++count}`, issues);
|
|
189
|
+
node.splice(2, node.length - 2, ...transform(childrenOf(node)));
|
|
190
|
+
return [node];
|
|
191
|
+
});
|
|
192
|
+
tree.nodes = transform(tree.nodes);
|
|
193
|
+
if (options.iconResolver) {
|
|
194
|
+
const all = [...items(tree.nodes)].filter((item) => item[1].type !== "more");
|
|
195
|
+
const keys = all.map((item) => iconKey(item, icons));
|
|
196
|
+
const resolved = await options.iconResolver.resolve(keys.filter((key) => Boolean(key)));
|
|
197
|
+
for (const [at, item] of all.entries()) {
|
|
198
|
+
const icon = resolved.get(keys[at] ?? "");
|
|
199
|
+
if (icon && "src" in icon) item[1].icon = icon;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
tree.meta.issues = [...tree.meta.issues ?? [], ...issues.map((issue) => issue.message)];
|
|
203
|
+
tree.meta.issueRules = {
|
|
204
|
+
...tree.meta.issueRules,
|
|
205
|
+
...Object.fromEntries(issues.map((issue) => [issue.message, issue.rule]))
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
//#endregion
|
|
211
|
+
export { src_default as t };
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer comark{@supports (interpolate-size:allow-keywords) and selector(::details-content){@media screen and (prefers-reduced-motion:no-preference){.cft details{interpolate-size:allow-keywords}.cft details::details-content{display:flow-root;block-size:0;overflow-y:clip;transition:block-size .
|
|
1
|
+
@layer comark{@supports (interpolate-size:allow-keywords) and selector(::details-content){@media screen and (prefers-reduced-motion:no-preference){.cft details{interpolate-size:allow-keywords}.cft details::details-content{display:flow-root;block-size:0;opacity:0;overflow-y:clip;transition:block-size .18s cubic-bezier(.23,1,.32,1),opacity .12s ease-in,content-visibility .18s allow-discrete}.cft details[open]::details-content{block-size:auto;opacity:1;transition:block-size .25s cubic-bezier(.23,1,.32,1),opacity .25s cubic-bezier(.23,1,.32,1),content-visibility .25s allow-discrete}}}:where(.cft){--_comark-background:var(--comark-background,var(--ui-bg,var(--background,#fff)));--_comark-foreground:var(--comark-foreground,var(--ui-text-highlighted,var(--foreground,#0a0a0a)));--_comark-muted:var(--comark-muted,var(--ui-text-muted,var(--muted-foreground,#737373)));--_comark-border:var(--comark-border,var(--ui-border,var(--border,#e5e5e5)));--_comark-accent:var(--comark-accent,var(--ui-bg-elevated,var(--accent,#f5f5f5)));--_comark-ring:var(--comark-ring,var(--ui-primary,var(--ring,#a1a1a1)));--_comark-success:var(--comark-success,var(--ui-success,var(--success,#259f56)));--_comark-danger:var(--comark-danger,var(--ui-error,var(--destructive,#ee3533)));--_comark-warning:var(--comark-warning,var(--ui-warning,#d97706));--_comark-info:var(--comark-info,var(--ui-info,#2563eb));--_comark-radius:var(--comark-radius,calc(var(--ui-radius,calc(var(--radius,.625rem)/2))*2));--_comark-font:var(--comark-font,var(--font-sans,ui-sans-serif,system-ui,sans-serif))}@media (prefers-color-scheme:dark){:where(.cft){--_comark-background:var(--comark-background,var(--ui-bg,var(--background,#0a0a0a)));--_comark-foreground:var(--comark-foreground,var(--ui-text-highlighted,var(--foreground,#fafafa)));--_comark-muted:var(--comark-muted,var(--ui-text-muted,var(--muted-foreground,#a1a1a1)));--_comark-border:var(--comark-border,var(--ui-border,var(--border,rgb(255 255 255/.1))));--_comark-accent:var(--comark-accent,var(--ui-bg-elevated,var(--accent,#262626)));--_comark-ring:var(--comark-ring,var(--ui-primary,var(--ring,#737373)));--_comark-success:var(--comark-success,var(--ui-success,var(--success,#59d38c)));--_comark-danger:var(--comark-danger,var(--ui-error,var(--destructive,#fd736d)));--_comark-warning:var(--comark-warning,var(--ui-warning,#fbbf24));--_comark-info:var(--comark-info,var(--ui-info,#60a5fa))}}:where(.light,.light *):where(.cft){--_comark-success:var(--comark-success,var(--ui-success,var(--success,#259f56)));--_comark-danger:var(--comark-danger,var(--ui-error,var(--destructive,#ee3533)));--_comark-warning:var(--comark-warning,var(--ui-warning,#d97706));--_comark-info:var(--comark-info,var(--ui-info,#2563eb))}:where(.dark,.dark *):where(.cft){--_comark-success:var(--comark-success,var(--ui-success,var(--success,#59d38c)));--_comark-danger:var(--comark-danger,var(--ui-error,var(--destructive,#fd736d)));--_comark-warning:var(--comark-warning,var(--ui-warning,#fbbf24));--_comark-info:var(--comark-info,var(--ui-info,#60a5fa))}:where(.cft){--cft-added:var(--_comark-success);--cft-removed:var(--_comark-danger);--cft-changed:var(--_comark-warning)}.cft{margin:1.5rem 0;padding:.75rem;overflow-x:auto;border:1px solid var(--_comark-border);border-radius:var(--_comark-radius);background:var(--_comark-background);color:var(--_comark-foreground);font:400 .8125rem/1.25rem ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.cft ul{margin:0!important;padding:0!important;list-style:none!important}.cft ul ul{margin-inline-start:calc(.5rem - .5px)!important;padding-inline-start:.75rem!important;border-inline-start:1px solid var(--_comark-border)}.cft li{margin:0!important;padding:0!important}.cft details{margin:0!important;padding:0!important}.cft summary{display:block;margin:0!important;padding:0!important;list-style:none;border-radius:calc(var(--_comark-radius) - 4px);cursor:pointer}.cft summary::-webkit-details-marker{display:none}.cft summary:hover{background:var(--_comark-accent)}.cft summary:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--_comark-ring) 50%,transparent)}.cft-entry{display:flex;align-items:center;gap:.375rem;padding:.125rem .25rem;white-space:nowrap}.cft-glyph{flex:none;width:1rem;height:1rem;color:var(--_comark-muted)}.cft-entry .ci{flex:none;font-size:1rem}.cft-note{margin-inline-start:.75rem;color:var(--_comark-muted);font-family:var(--_comark-font);white-space:normal}.cft-mark{font-weight:600}.cft [data-state='added']>.cft-entry,.cft [data-state='added']>details>summary>.cft-entry{color:var(--cft-added)}.cft [data-state='removed']>.cft-entry,.cft [data-state='removed']>details>summary>.cft-entry{color:var(--cft-removed)}.cft [data-state='removed'] .cft-name{text-decoration:line-through}.cft [data-state='changed']>.cft-entry,.cft [data-state='changed']>details>summary>.cft-entry{color:var(--cft-changed)}.cft [data-type='more']{padding:0 .25rem;color:var(--_comark-muted)}}
|
package/dist/vue.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import src_default from "./
|
|
2
|
-
import { n as glyphs, r as marks, t as addStyles } from "./client-
|
|
1
|
+
import { t as src_default } from "./src-PLku93wQ.mjs";
|
|
2
|
+
import { n as glyphs, r as marks, t as addStyles } from "./client-DcAHu-LK.mjs";
|
|
3
3
|
import { defineComponent, h, onMounted } from "vue";
|
|
4
4
|
import { Icon } from "comark-icon/vue";
|
|
5
5
|
//#region src/vue.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "comark-file-tree",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A project's folders and files from an indented list or pasted tree output, with added, removed, and changed entries marked. A Comark plugin.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"comark",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"provenance": true
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"comark-icon": "^0.
|
|
48
|
+
"comark-icon": "^0.8.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@comark/html": "^0.8.1",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"react-dom": "^19.3.1",
|
|
59
59
|
"svelte": "^5.57.2",
|
|
60
60
|
"vue": "^3.5.44",
|
|
61
|
-
"comark-zoom": "0.
|
|
61
|
+
"comark-zoom": "0.8.0"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"@comark/html": "^0.8.0",
|