@stacksjs/stx 0.2.148 → 0.2.149
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/dist/cli.js +516 -516
- package/dist/craft.js +252 -252
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/markdown-view.d.ts +25 -0
- package/dist/markdown-view.js +39 -0
- package/dist/render.d.ts +1 -0
- package/dist/render.js +12 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -228,5 +228,6 @@ export {
|
|
|
228
228
|
validated,
|
|
229
229
|
withDefaults,
|
|
230
230
|
} from './props';
|
|
231
|
+
export { isMarkdownPath, type MarkdownRenderer, type MarkdownView, protectCodeBlocks, renderMarkdownView } from './markdown-view';
|
|
231
232
|
// Default export for the stx module
|
|
232
233
|
export default {};
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Whether a path should be treated as a markdown view. */
|
|
2
|
+
export declare function isMarkdownPath(filePath: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Wrap code blocks so the stx pass leaves their contents alone.
|
|
5
|
+
*
|
|
6
|
+
* Applies to `<pre>` (fenced blocks) and to any `<code>` not already inside
|
|
7
|
+
* one (inline spans). Without this, a page documenting a directive executes it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function protectCodeBlocks(html: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Turn markdown source into HTML the stx pipeline can process.
|
|
12
|
+
*
|
|
13
|
+
* Frontmatter is returned rather than injected, so the caller decides how it
|
|
14
|
+
* merges with the rest of the render context.
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderMarkdownView(source: string, options?: MarkdownViewOptions): Promise<MarkdownView>;
|
|
17
|
+
export declare interface MarkdownViewOptions {
|
|
18
|
+
renderer?: MarkdownRenderer
|
|
19
|
+
}
|
|
20
|
+
export declare interface MarkdownView {
|
|
21
|
+
html: string
|
|
22
|
+
frontmatter: Record<string, any>
|
|
23
|
+
}
|
|
24
|
+
/** Converts markdown source to HTML. */
|
|
25
|
+
export type MarkdownRenderer = (source: string) => string | Promise<string>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { parseFrontmatter, parseMarkdown } from "./internal-markdown.js";
|
|
2
|
+
export function isMarkdownPath(filePath) {
|
|
3
|
+
return filePath.endsWith(".md") || filePath.endsWith(".markdown");
|
|
4
|
+
}
|
|
5
|
+
export function protectCodeBlocks(html) {
|
|
6
|
+
const protectedRanges = [];
|
|
7
|
+
collect(/<pre\b[^>]*>[\s\S]*?<\/pre>/gi);
|
|
8
|
+
const preRanges = [...protectedRanges];
|
|
9
|
+
collect(/<code\b[^>]*>[\s\S]*?<\/code>/gi, preRanges);
|
|
10
|
+
function collect(re, skipWithin) {
|
|
11
|
+
let m;
|
|
12
|
+
while ((m = re.exec(html)) !== null) {
|
|
13
|
+
const start = m.index, end = start + m[0].length;
|
|
14
|
+
if (skipWithin?.some((r) => start >= r.start && end <= r.end))
|
|
15
|
+
continue;
|
|
16
|
+
protectedRanges.push({ start, end });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (protectedRanges.length === 0)
|
|
20
|
+
return html;
|
|
21
|
+
protectedRanges.sort((a, b) => a.start - b.start);
|
|
22
|
+
let out = "", cursor = 0;
|
|
23
|
+
for (const range of protectedRanges) {
|
|
24
|
+
if (range.start < cursor)
|
|
25
|
+
continue;
|
|
26
|
+
out += html.slice(cursor, range.start);
|
|
27
|
+
out += `@raw${html.slice(range.start, range.end)}@endraw`;
|
|
28
|
+
cursor = range.end;
|
|
29
|
+
}
|
|
30
|
+
out += html.slice(cursor);
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
export async function renderMarkdownView(source, options = {}) {
|
|
34
|
+
const { data, content } = parseFrontmatter(source), html = await (options.renderer ?? ((md) => parseMarkdown(md)))(content);
|
|
35
|
+
return {
|
|
36
|
+
html: protectCodeBlocks(html),
|
|
37
|
+
frontmatter: data ?? {}
|
|
38
|
+
};
|
|
39
|
+
}
|
package/dist/render.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export declare function renderTemplateString(content: string, filePath: string,
|
|
|
42
42
|
// Types
|
|
43
43
|
// ============================================================================
|
|
44
44
|
export declare interface RenderOptions {
|
|
45
|
+
markdownRenderer?: (source: string) => string | Promise<string>
|
|
45
46
|
context?: Record<string, unknown>
|
|
46
47
|
options?: Partial<StxOptions>
|
|
47
48
|
processClientScripts?: boolean
|
package/dist/render.js
CHANGED
|
@@ -4,6 +4,7 @@ import { extractVariables } from "./variable-extractor.js";
|
|
|
4
4
|
import { injectRouterScript, processDirectives } from "./process.js";
|
|
5
5
|
import { extractBridgeData, processClientScript } from "./client-script.js";
|
|
6
6
|
import { findSfcTemplateBlock } from "./sfc-template.js";
|
|
7
|
+
import { isMarkdownPath, renderMarkdownView } from "./markdown-view.js";
|
|
7
8
|
function parseTemplate(content) {
|
|
8
9
|
let workingContent = content;
|
|
9
10
|
const templateBlock = findSfcTemplateBlock(content);
|
|
@@ -69,7 +70,17 @@ export async function renderTemplate(filePath, renderOptions = {}) {
|
|
|
69
70
|
const resolvedPath = resolve(filePath), file = Bun.file(resolvedPath);
|
|
70
71
|
if (!await file.exists())
|
|
71
72
|
throw Error(`Template file not found: ${resolvedPath}`);
|
|
72
|
-
|
|
73
|
+
let content = await file.text(), markdownFrontmatter = null;
|
|
74
|
+
if (isMarkdownPath(resolvedPath)) {
|
|
75
|
+
const view = await renderMarkdownView(content, { renderer: renderOptions.markdownRenderer });
|
|
76
|
+
content = view.html;
|
|
77
|
+
markdownFrontmatter = view.frontmatter;
|
|
78
|
+
}
|
|
79
|
+
if (markdownFrontmatter)
|
|
80
|
+
renderOptions = {
|
|
81
|
+
...renderOptions,
|
|
82
|
+
context: { ...markdownFrontmatter, ...renderOptions.context || {} }
|
|
83
|
+
};
|
|
73
84
|
if (renderOptions.layout) {
|
|
74
85
|
const layoutPath = resolve(renderOptions.layout), layoutFile = Bun.file(layoutPath);
|
|
75
86
|
if (!await layoutFile.exists())
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/stx",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.149",
|
|
5
5
|
"description": "A performant UI Framework. Powered by Bun.",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -117,12 +117,12 @@
|
|
|
117
117
|
"dependencies": {
|
|
118
118
|
"@cwcss/crosswind": "^0.2.14",
|
|
119
119
|
"@stacksjs/clapp": "^0.2.0",
|
|
120
|
-
"@stacksjs/desktop": "0.2.
|
|
121
|
-
"@stacksjs/sanitizer": "0.2.
|
|
120
|
+
"@stacksjs/desktop": "0.2.149",
|
|
121
|
+
"@stacksjs/sanitizer": "0.2.149",
|
|
122
122
|
"@stacksjs/ts-i18n": "^0.1.11",
|
|
123
|
-
"bun-plugin-stx": "0.2.
|
|
123
|
+
"bun-plugin-stx": "0.2.149",
|
|
124
124
|
"bunfig": "^0.15.17",
|
|
125
|
-
"stx-router": "0.2.
|
|
125
|
+
"stx-router": "0.2.149",
|
|
126
126
|
"ts-broadcasting": "^0.0.9",
|
|
127
127
|
"ts-images": "^0.1.9",
|
|
128
128
|
"ts-syntax-highlighter": "^0.2.1"
|