@hpcc-js/markdown-it-plugins 1.5.5 → 1.5.6
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/LICENSE +43 -43
- package/README.md +47 -47
- package/dist/assets/hpcc-systems-dark.svg +78 -78
- package/dist/assets/hpcc-systems.svg +68 -68
- package/dist/ecl-lang.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs.map +1 -1
- package/dist/loader.node.js.map +1 -1
- package/package.json +4 -4
- package/src/__package__.ts +3 -3
- package/src/ecl-lang/ecl-configuration.json +163 -163
- package/src/ecl-lang/ecl.tmLanguage.json +347 -347
- package/src/ecl-lang/index.ts +12 -12
- package/src/fence.ts +59 -59
- package/src/index.ts +47 -47
- package/src/loader.ts +154 -154
- package/src/render.ts +63 -63
- package/src/template-literal.ts +113 -113
- package/src/util.ts +81 -81
- package/src/vitepress/RenderComponent.vue +32 -32
- package/src/vitepress/card.css +43 -43
- package/src/vitepress/global.css +284 -284
- package/src/vitepress/grid.css +82 -82
- package/src/vitepress/inspector.css +193 -193
- package/src/vitepress/layout.css +684 -684
- package/src/vitepress/note.css +80 -80
- package/src/vitepress/plot.css +6 -6
- package/src/vitepress/style.css +113 -113
- package/src/vitepress/styles.ts +8 -8
package/src/render.ts
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
import { Runtime, Library, Inspector as BaseInspector } from "@observablehq/runtime";
|
|
2
|
-
import { compile, type ohq } from "@hpcc-js/observablehq-compiler";
|
|
3
|
-
import { FenceInfo, renderExecutedSrc } from "./util.ts";
|
|
4
|
-
|
|
5
|
-
class Inspector extends BaseInspector {
|
|
6
|
-
|
|
7
|
-
constructor(protected placeholder: HTMLElement) {
|
|
8
|
-
super(placeholder);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
pending() {
|
|
12
|
-
super.pending();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
fulfilled(value: any, _name?: string) {
|
|
16
|
-
switch (typeof value) {
|
|
17
|
-
case "string":
|
|
18
|
-
this.placeholder.innerText = value;
|
|
19
|
-
break;
|
|
20
|
-
default:
|
|
21
|
-
super.fulfilled(value);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
rejected(error: Error) {
|
|
26
|
-
super.rejected(error);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface RenderNode extends FenceInfo {
|
|
31
|
-
id: string;
|
|
32
|
-
content: string;
|
|
33
|
-
innerHTML?: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export async function render(nodes: RenderNode[]) {
|
|
37
|
-
const displayIndex: { [key: string]: boolean } = {};
|
|
38
|
-
const nb: ohq.Notebook = { nodes: [], files: [] };
|
|
39
|
-
for (const node of nodes) {
|
|
40
|
-
nb.nodes.push({
|
|
41
|
-
id: node.id,
|
|
42
|
-
name: node.id,
|
|
43
|
-
mode: "js",
|
|
44
|
-
value: node.content
|
|
45
|
-
});
|
|
46
|
-
displayIndex[node.id] = renderExecutedSrc(node);
|
|
47
|
-
}
|
|
48
|
-
const define = await compile(nb);
|
|
49
|
-
const runtime = new Runtime(new Library());
|
|
50
|
-
runtime.module(define, () => {
|
|
51
|
-
define(runtime, (_name: string | undefined, id: string | number) => {
|
|
52
|
-
const placeholder = globalThis?.document?.getElementById("" + id);
|
|
53
|
-
if (placeholder && displayIndex[id]) {
|
|
54
|
-
return new Inspector(placeholder);
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
pending() { },
|
|
58
|
-
fulfilled(_value: any, _name?: string) { },
|
|
59
|
-
rejected(_error: any, _name?: string) { }
|
|
60
|
-
};
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
}
|
|
1
|
+
import { Runtime, Library, Inspector as BaseInspector } from "@observablehq/runtime";
|
|
2
|
+
import { compile, type ohq } from "@hpcc-js/observablehq-compiler";
|
|
3
|
+
import { FenceInfo, renderExecutedSrc } from "./util.ts";
|
|
4
|
+
|
|
5
|
+
class Inspector extends BaseInspector {
|
|
6
|
+
|
|
7
|
+
constructor(protected placeholder: HTMLElement) {
|
|
8
|
+
super(placeholder);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
pending() {
|
|
12
|
+
super.pending();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
fulfilled(value: any, _name?: string) {
|
|
16
|
+
switch (typeof value) {
|
|
17
|
+
case "string":
|
|
18
|
+
this.placeholder.innerText = value;
|
|
19
|
+
break;
|
|
20
|
+
default:
|
|
21
|
+
super.fulfilled(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
rejected(error: Error) {
|
|
26
|
+
super.rejected(error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface RenderNode extends FenceInfo {
|
|
31
|
+
id: string;
|
|
32
|
+
content: string;
|
|
33
|
+
innerHTML?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function render(nodes: RenderNode[]) {
|
|
37
|
+
const displayIndex: { [key: string]: boolean } = {};
|
|
38
|
+
const nb: ohq.Notebook = { nodes: [], files: [] };
|
|
39
|
+
for (const node of nodes) {
|
|
40
|
+
nb.nodes.push({
|
|
41
|
+
id: node.id,
|
|
42
|
+
name: node.id,
|
|
43
|
+
mode: "js",
|
|
44
|
+
value: node.content
|
|
45
|
+
});
|
|
46
|
+
displayIndex[node.id] = renderExecutedSrc(node);
|
|
47
|
+
}
|
|
48
|
+
const define = await compile(nb);
|
|
49
|
+
const runtime = new Runtime(new Library());
|
|
50
|
+
runtime.module(define, () => {
|
|
51
|
+
define(runtime, (_name: string | undefined, id: string | number) => {
|
|
52
|
+
const placeholder = globalThis?.document?.getElementById("" + id);
|
|
53
|
+
if (placeholder && displayIndex[id]) {
|
|
54
|
+
return new Inspector(placeholder);
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
pending() { },
|
|
58
|
+
fulfilled(_value: any, _name?: string) { },
|
|
59
|
+
rejected(_error: any, _name?: string) { }
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
package/src/template-literal.ts
CHANGED
|
@@ -1,113 +1,113 @@
|
|
|
1
|
-
import type MarkdownIt from "markdown-it";
|
|
2
|
-
import type { Options } from "markdown-it";
|
|
3
|
-
import type Token from "markdown-it/lib/token.mjs";
|
|
4
|
-
import type Renderer from "markdown-it/lib/renderer.mjs";
|
|
5
|
-
import type { RuleCore } from "markdown-it/lib/parser_core.mjs";
|
|
6
|
-
import type { RuleInline } from "markdown-it/lib/parser_inline.mjs";
|
|
7
|
-
import { generatePlaceholders } from "./util.ts";
|
|
8
|
-
|
|
9
|
-
function renderObservable(tokens: Token[], idx: number, _options: Options, env: any, _self: Renderer) {
|
|
10
|
-
return generatePlaceholders(tokens[idx].content, { type: "js", exec: true }, env);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const DOLLAR = 0x24;
|
|
14
|
-
const CURLEY_OPEN = 0x7B;
|
|
15
|
-
const CURLEY_CLOSE = 0x7D;
|
|
16
|
-
|
|
17
|
-
function* parsePlaceholderInline(src: string, pos: number = 0, posMax: number = src.length) {
|
|
18
|
-
if (src.charCodeAt(pos) === DOLLAR && src.charCodeAt(pos + 1) === CURLEY_OPEN) {
|
|
19
|
-
pos += 2;
|
|
20
|
-
|
|
21
|
-
const observableStart = pos;
|
|
22
|
-
let nestedCurly = 0;
|
|
23
|
-
let done = false;
|
|
24
|
-
while (!done && pos < posMax) {
|
|
25
|
-
switch (src.charCodeAt(pos)) {
|
|
26
|
-
case CURLEY_OPEN:
|
|
27
|
-
nestedCurly++;
|
|
28
|
-
break;
|
|
29
|
-
case CURLEY_CLOSE:
|
|
30
|
-
if (nestedCurly === 0) {
|
|
31
|
-
done = true;
|
|
32
|
-
--pos;
|
|
33
|
-
} else {
|
|
34
|
-
nestedCurly--;
|
|
35
|
-
}
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
pos++;
|
|
39
|
-
}
|
|
40
|
-
const observableEnd = pos;
|
|
41
|
-
if (pos >= posMax || observableStart == observableEnd) return;
|
|
42
|
-
if (src.charCodeAt(pos) !== CURLEY_CLOSE) return;
|
|
43
|
-
pos++;
|
|
44
|
-
|
|
45
|
-
const observableJs = src.slice(observableStart, observableEnd).trim();
|
|
46
|
-
yield { type: "placeholder", content: observableJs, pos };
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function* parsePlaceholderBlock(src: string) {
|
|
51
|
-
let pos = 0;
|
|
52
|
-
let prevPos = 0;
|
|
53
|
-
const posMax = src.length;
|
|
54
|
-
while (pos < posMax) {
|
|
55
|
-
if (src.charCodeAt(pos) === DOLLAR && src.charCodeAt(pos + 1) === CURLEY_OPEN) {
|
|
56
|
-
yield ({ type: "html_block", content: src.slice(prevPos, pos) });
|
|
57
|
-
for (const placeholder of parsePlaceholderInline(src, pos, posMax)) {
|
|
58
|
-
yield placeholder;
|
|
59
|
-
pos = placeholder.pos;
|
|
60
|
-
prevPos = pos;
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
pos++;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (pos > prevPos) {
|
|
67
|
-
yield ({ type: "html_block", content: src.slice(prevPos, pos) });
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const transformPlaceholderInline: RuleInline = (state, silent) => {
|
|
72
|
-
if (silent || state.pos + 2 > state.posMax) return false;
|
|
73
|
-
const marker1 = state.src.charCodeAt(state.pos);
|
|
74
|
-
const marker2 = state.src.charCodeAt(state.pos + 1);
|
|
75
|
-
if (marker1 !== DOLLAR || marker2 !== CURLEY_OPEN) return false;
|
|
76
|
-
for (const { type, content, pos } of parsePlaceholderInline(state.src, state.pos, state.posMax)) {
|
|
77
|
-
if (type !== "placeholder") break;
|
|
78
|
-
const token = state.push(type, "", 0);
|
|
79
|
-
token.content = content;
|
|
80
|
-
state.pos = pos;
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
return false;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const transformPlaceholderCore: RuleCore = (state) => {
|
|
87
|
-
const { tokens } = state;
|
|
88
|
-
for (let i = 0, n = tokens.length; i < n; ++i) {
|
|
89
|
-
const token = tokens[i];
|
|
90
|
-
if (token.type === "html_block") {
|
|
91
|
-
const children: Token[] = [];
|
|
92
|
-
for (const { type, content } of parsePlaceholderBlock(token.content)) {
|
|
93
|
-
const child = new state.Token(type, "", 0);
|
|
94
|
-
child.content = content;
|
|
95
|
-
children.push(child);
|
|
96
|
-
}
|
|
97
|
-
if (children.length === 1 && children[0].type === "html_block") {
|
|
98
|
-
tokens[i].content = children[0].content;
|
|
99
|
-
} else {
|
|
100
|
-
const inline = new state.Token("inline", "", 0);
|
|
101
|
-
inline.children = children;
|
|
102
|
-
tokens[i] = inline;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export function hookTemplateLiterals(md: MarkdownIt) {
|
|
109
|
-
md.inline.ruler.push("placeholder", transformPlaceholderInline);
|
|
110
|
-
md.core.ruler.after("inline", "placeholder", transformPlaceholderCore);
|
|
111
|
-
md.renderer.rules.placeholder = (tokens: Token[], idx: number, options: any, env: any, self: Renderer) => renderObservable(tokens, idx, options, env, self);
|
|
112
|
-
}
|
|
113
|
-
|
|
1
|
+
import type MarkdownIt from "markdown-it";
|
|
2
|
+
import type { Options } from "markdown-it";
|
|
3
|
+
import type Token from "markdown-it/lib/token.mjs";
|
|
4
|
+
import type Renderer from "markdown-it/lib/renderer.mjs";
|
|
5
|
+
import type { RuleCore } from "markdown-it/lib/parser_core.mjs";
|
|
6
|
+
import type { RuleInline } from "markdown-it/lib/parser_inline.mjs";
|
|
7
|
+
import { generatePlaceholders } from "./util.ts";
|
|
8
|
+
|
|
9
|
+
function renderObservable(tokens: Token[], idx: number, _options: Options, env: any, _self: Renderer) {
|
|
10
|
+
return generatePlaceholders(tokens[idx].content, { type: "js", exec: true }, env);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const DOLLAR = 0x24;
|
|
14
|
+
const CURLEY_OPEN = 0x7B;
|
|
15
|
+
const CURLEY_CLOSE = 0x7D;
|
|
16
|
+
|
|
17
|
+
function* parsePlaceholderInline(src: string, pos: number = 0, posMax: number = src.length) {
|
|
18
|
+
if (src.charCodeAt(pos) === DOLLAR && src.charCodeAt(pos + 1) === CURLEY_OPEN) {
|
|
19
|
+
pos += 2;
|
|
20
|
+
|
|
21
|
+
const observableStart = pos;
|
|
22
|
+
let nestedCurly = 0;
|
|
23
|
+
let done = false;
|
|
24
|
+
while (!done && pos < posMax) {
|
|
25
|
+
switch (src.charCodeAt(pos)) {
|
|
26
|
+
case CURLEY_OPEN:
|
|
27
|
+
nestedCurly++;
|
|
28
|
+
break;
|
|
29
|
+
case CURLEY_CLOSE:
|
|
30
|
+
if (nestedCurly === 0) {
|
|
31
|
+
done = true;
|
|
32
|
+
--pos;
|
|
33
|
+
} else {
|
|
34
|
+
nestedCurly--;
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
pos++;
|
|
39
|
+
}
|
|
40
|
+
const observableEnd = pos;
|
|
41
|
+
if (pos >= posMax || observableStart == observableEnd) return;
|
|
42
|
+
if (src.charCodeAt(pos) !== CURLEY_CLOSE) return;
|
|
43
|
+
pos++;
|
|
44
|
+
|
|
45
|
+
const observableJs = src.slice(observableStart, observableEnd).trim();
|
|
46
|
+
yield { type: "placeholder", content: observableJs, pos };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function* parsePlaceholderBlock(src: string) {
|
|
51
|
+
let pos = 0;
|
|
52
|
+
let prevPos = 0;
|
|
53
|
+
const posMax = src.length;
|
|
54
|
+
while (pos < posMax) {
|
|
55
|
+
if (src.charCodeAt(pos) === DOLLAR && src.charCodeAt(pos + 1) === CURLEY_OPEN) {
|
|
56
|
+
yield ({ type: "html_block", content: src.slice(prevPos, pos) });
|
|
57
|
+
for (const placeholder of parsePlaceholderInline(src, pos, posMax)) {
|
|
58
|
+
yield placeholder;
|
|
59
|
+
pos = placeholder.pos;
|
|
60
|
+
prevPos = pos;
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
pos++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (pos > prevPos) {
|
|
67
|
+
yield ({ type: "html_block", content: src.slice(prevPos, pos) });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const transformPlaceholderInline: RuleInline = (state, silent) => {
|
|
72
|
+
if (silent || state.pos + 2 > state.posMax) return false;
|
|
73
|
+
const marker1 = state.src.charCodeAt(state.pos);
|
|
74
|
+
const marker2 = state.src.charCodeAt(state.pos + 1);
|
|
75
|
+
if (marker1 !== DOLLAR || marker2 !== CURLEY_OPEN) return false;
|
|
76
|
+
for (const { type, content, pos } of parsePlaceholderInline(state.src, state.pos, state.posMax)) {
|
|
77
|
+
if (type !== "placeholder") break;
|
|
78
|
+
const token = state.push(type, "", 0);
|
|
79
|
+
token.content = content;
|
|
80
|
+
state.pos = pos;
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const transformPlaceholderCore: RuleCore = (state) => {
|
|
87
|
+
const { tokens } = state;
|
|
88
|
+
for (let i = 0, n = tokens.length; i < n; ++i) {
|
|
89
|
+
const token = tokens[i];
|
|
90
|
+
if (token.type === "html_block") {
|
|
91
|
+
const children: Token[] = [];
|
|
92
|
+
for (const { type, content } of parsePlaceholderBlock(token.content)) {
|
|
93
|
+
const child = new state.Token(type, "", 0);
|
|
94
|
+
child.content = content;
|
|
95
|
+
children.push(child);
|
|
96
|
+
}
|
|
97
|
+
if (children.length === 1 && children[0].type === "html_block") {
|
|
98
|
+
tokens[i].content = children[0].content;
|
|
99
|
+
} else {
|
|
100
|
+
const inline = new state.Token("inline", "", 0);
|
|
101
|
+
inline.children = children;
|
|
102
|
+
tokens[i] = inline;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export function hookTemplateLiterals(md: MarkdownIt) {
|
|
109
|
+
md.inline.ruler.push("placeholder", transformPlaceholderInline);
|
|
110
|
+
md.core.ruler.after("inline", "placeholder", transformPlaceholderCore);
|
|
111
|
+
md.renderer.rules.placeholder = (tokens: Token[], idx: number, options: any, env: any, self: Renderer) => renderObservable(tokens, idx, options, env, self);
|
|
112
|
+
}
|
|
113
|
+
|
package/src/util.ts
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
import { ojs2notebook } from "@hpcc-js/observablehq-compiler";
|
|
2
|
-
import { RenderNode } from "./render.ts";
|
|
3
|
-
|
|
4
|
-
export interface FenceInfo {
|
|
5
|
-
type: "js" | "javascript" | string;
|
|
6
|
-
exec?: boolean;
|
|
7
|
-
echo?: boolean;
|
|
8
|
-
hide?: boolean;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const fenceInfoDefaults: Readonly<FenceInfo> = {
|
|
12
|
-
type: "js",
|
|
13
|
-
exec: false,
|
|
14
|
-
echo: undefined,
|
|
15
|
-
hide: undefined
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export function showSrc(fetchInfo: FenceInfo): boolean {
|
|
19
|
-
if (fetchInfo.exec === true) {
|
|
20
|
-
return fetchInfo.echo === true;
|
|
21
|
-
}
|
|
22
|
-
return fetchInfo.echo !== false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function executeSrc(fenceInfo: FenceInfo): boolean {
|
|
26
|
-
return fenceInfo.exec === true;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function renderExecutedSrc(fetchInfo: FenceInfo): boolean {
|
|
30
|
-
return fetchInfo.exec == true && fetchInfo.hide !== true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let idx = 0;
|
|
34
|
-
export function createId(suffix?: string | number): string {
|
|
35
|
-
return `fence-${++idx}${suffix ? `-${suffix}` : ""}`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function calcPlaceholders(content: string, fenceInfo: FenceInfo): RenderNode[] {
|
|
39
|
-
const retVal: RenderNode[] = [];
|
|
40
|
-
try {
|
|
41
|
-
const cellNb = ojs2notebook(content);
|
|
42
|
-
for (let i = 0; i < cellNb.nodes.length; ++i) {
|
|
43
|
-
const id = createId(i + 1);
|
|
44
|
-
const content = cellNb.nodes[i].value;
|
|
45
|
-
retVal.push({
|
|
46
|
-
...fenceInfo,
|
|
47
|
-
id,
|
|
48
|
-
content,
|
|
49
|
-
innerHTML: `\
|
|
50
|
-
<span id="${id}" >
|
|
51
|
-
${renderExecutedSrc(fenceInfo) ? "..." : ""}
|
|
52
|
-
</span>`
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
} catch (e: any) {
|
|
56
|
-
const id = `fence-${idx}-error`;
|
|
57
|
-
retVal.push({
|
|
58
|
-
...fenceInfo,
|
|
59
|
-
id,
|
|
60
|
-
content: JSON.stringify(e),
|
|
61
|
-
innerHTML: `\
|
|
62
|
-
<span id="${id}" class="red">
|
|
63
|
-
${JSON.stringify(e)}
|
|
64
|
-
</span>`
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return retVal;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export const ENV_KEY = "ENV_OBSERVABLE";
|
|
71
|
-
|
|
72
|
-
export function generatePlaceholders(content: string, fenceInfo: FenceInfo, env: any): string {
|
|
73
|
-
if (!env[ENV_KEY]) {
|
|
74
|
-
env[ENV_KEY] = [];
|
|
75
|
-
}
|
|
76
|
-
return calcPlaceholders(content, fenceInfo).reduce((acc, cur) => {
|
|
77
|
-
env[ENV_KEY]!.push({ ...cur, innerHTML: undefined });
|
|
78
|
-
return acc + cur.innerHTML;
|
|
79
|
-
}, "");
|
|
80
|
-
}
|
|
81
|
-
|
|
1
|
+
import { ojs2notebook } from "@hpcc-js/observablehq-compiler";
|
|
2
|
+
import { RenderNode } from "./render.ts";
|
|
3
|
+
|
|
4
|
+
export interface FenceInfo {
|
|
5
|
+
type: "js" | "javascript" | string;
|
|
6
|
+
exec?: boolean;
|
|
7
|
+
echo?: boolean;
|
|
8
|
+
hide?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const fenceInfoDefaults: Readonly<FenceInfo> = {
|
|
12
|
+
type: "js",
|
|
13
|
+
exec: false,
|
|
14
|
+
echo: undefined,
|
|
15
|
+
hide: undefined
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function showSrc(fetchInfo: FenceInfo): boolean {
|
|
19
|
+
if (fetchInfo.exec === true) {
|
|
20
|
+
return fetchInfo.echo === true;
|
|
21
|
+
}
|
|
22
|
+
return fetchInfo.echo !== false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function executeSrc(fenceInfo: FenceInfo): boolean {
|
|
26
|
+
return fenceInfo.exec === true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function renderExecutedSrc(fetchInfo: FenceInfo): boolean {
|
|
30
|
+
return fetchInfo.exec == true && fetchInfo.hide !== true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let idx = 0;
|
|
34
|
+
export function createId(suffix?: string | number): string {
|
|
35
|
+
return `fence-${++idx}${suffix ? `-${suffix}` : ""}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function calcPlaceholders(content: string, fenceInfo: FenceInfo): RenderNode[] {
|
|
39
|
+
const retVal: RenderNode[] = [];
|
|
40
|
+
try {
|
|
41
|
+
const cellNb = ojs2notebook(content);
|
|
42
|
+
for (let i = 0; i < cellNb.nodes.length; ++i) {
|
|
43
|
+
const id = createId(i + 1);
|
|
44
|
+
const content = cellNb.nodes[i].value;
|
|
45
|
+
retVal.push({
|
|
46
|
+
...fenceInfo,
|
|
47
|
+
id,
|
|
48
|
+
content,
|
|
49
|
+
innerHTML: `\
|
|
50
|
+
<span id="${id}" >
|
|
51
|
+
${renderExecutedSrc(fenceInfo) ? "..." : ""}
|
|
52
|
+
</span>`
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
} catch (e: any) {
|
|
56
|
+
const id = `fence-${idx}-error`;
|
|
57
|
+
retVal.push({
|
|
58
|
+
...fenceInfo,
|
|
59
|
+
id,
|
|
60
|
+
content: JSON.stringify(e),
|
|
61
|
+
innerHTML: `\
|
|
62
|
+
<span id="${id}" class="red">
|
|
63
|
+
${JSON.stringify(e)}
|
|
64
|
+
</span>`
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return retVal;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const ENV_KEY = "ENV_OBSERVABLE";
|
|
71
|
+
|
|
72
|
+
export function generatePlaceholders(content: string, fenceInfo: FenceInfo, env: any): string {
|
|
73
|
+
if (!env[ENV_KEY]) {
|
|
74
|
+
env[ENV_KEY] = [];
|
|
75
|
+
}
|
|
76
|
+
return calcPlaceholders(content, fenceInfo).reduce((acc, cur) => {
|
|
77
|
+
env[ENV_KEY]!.push({ ...cur, innerHTML: undefined });
|
|
78
|
+
return acc + cur.innerHTML;
|
|
79
|
+
}, "");
|
|
80
|
+
}
|
|
81
|
+
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
</div>
|
|
4
|
-
</template>
|
|
5
|
-
|
|
6
|
-
<script>
|
|
7
|
-
import { render } from "@hpcc-js/markdown-it-plugins";
|
|
8
|
-
|
|
9
|
-
export default {
|
|
10
|
-
name: 'RenderComponent',
|
|
11
|
-
props: {
|
|
12
|
-
content: {
|
|
13
|
-
type: String,
|
|
14
|
-
required: true
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
data() {
|
|
18
|
-
return {
|
|
19
|
-
loading: true
|
|
20
|
-
};
|
|
21
|
-
},
|
|
22
|
-
async created() {
|
|
23
|
-
setTimeout(() => {
|
|
24
|
-
this.loading = false;
|
|
25
|
-
render(JSON.parse(decodeURI(this.content)));
|
|
26
|
-
}, 0);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
</script>
|
|
30
|
-
|
|
31
|
-
<style scoped>
|
|
32
|
-
/* Add your styles here */
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
</div>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<script>
|
|
7
|
+
import { render } from "@hpcc-js/markdown-it-plugins";
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
name: 'RenderComponent',
|
|
11
|
+
props: {
|
|
12
|
+
content: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: true
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
data() {
|
|
18
|
+
return {
|
|
19
|
+
loading: true
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
async created() {
|
|
23
|
+
setTimeout(() => {
|
|
24
|
+
this.loading = false;
|
|
25
|
+
render(JSON.parse(decodeURI(this.content)));
|
|
26
|
+
}, 0);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<style scoped>
|
|
32
|
+
/* Add your styles here */
|
|
33
33
|
</style>
|
package/src/vitepress/card.css
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
div.card {
|
|
2
|
-
background: var(--theme-background-alt);
|
|
3
|
-
border: solid 1px var(--theme-foreground-faintest);
|
|
4
|
-
border-radius: 0.75rem;
|
|
5
|
-
padding: 1rem;
|
|
6
|
-
margin: 1rem 0;
|
|
7
|
-
font: 14px var(--sans-serif);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.grid>div.card {
|
|
11
|
-
margin: 0;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
div.card> :first-child,
|
|
15
|
-
div.card> :first-child> :first-child {
|
|
16
|
-
margin-top: 0;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
div.card> :last-child,
|
|
20
|
-
div.card> :last-child> :last-child {
|
|
21
|
-
margin-bottom: 0;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
div.card h2,
|
|
25
|
-
div.card h3 {
|
|
26
|
-
font-size: inherit;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
div.card h2 {
|
|
30
|
-
font-weight: 500;
|
|
31
|
-
font-size: 15px;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
div.card h3 {
|
|
35
|
-
font-weight: 400;
|
|
36
|
-
color: var(--theme-foreground-muted);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
div.card h2~svg,
|
|
40
|
-
div.card h3~svg,
|
|
41
|
-
div.card h2~p,
|
|
42
|
-
div.card h3~p {
|
|
43
|
-
margin-top: 1rem;
|
|
1
|
+
div.card {
|
|
2
|
+
background: var(--theme-background-alt);
|
|
3
|
+
border: solid 1px var(--theme-foreground-faintest);
|
|
4
|
+
border-radius: 0.75rem;
|
|
5
|
+
padding: 1rem;
|
|
6
|
+
margin: 1rem 0;
|
|
7
|
+
font: 14px var(--sans-serif);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.grid>div.card {
|
|
11
|
+
margin: 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
div.card> :first-child,
|
|
15
|
+
div.card> :first-child> :first-child {
|
|
16
|
+
margin-top: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
div.card> :last-child,
|
|
20
|
+
div.card> :last-child> :last-child {
|
|
21
|
+
margin-bottom: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
div.card h2,
|
|
25
|
+
div.card h3 {
|
|
26
|
+
font-size: inherit;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
div.card h2 {
|
|
30
|
+
font-weight: 500;
|
|
31
|
+
font-size: 15px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
div.card h3 {
|
|
35
|
+
font-weight: 400;
|
|
36
|
+
color: var(--theme-foreground-muted);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
div.card h2~svg,
|
|
40
|
+
div.card h3~svg,
|
|
41
|
+
div.card h2~p,
|
|
42
|
+
div.card h3~p {
|
|
43
|
+
margin-top: 1rem;
|
|
44
44
|
}
|