mdzjs 0.10.7 → 0.11.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 CHANGED
@@ -95,4 +95,12 @@ If you appreciate the project, kindly demonstrate your support by giving it a st
95
95
  <!--## Financial support-->
96
96
  # License
97
97
  This projet is licensed under the terms of MIT License
98
- <img src="https://img.shields.io/github/license/zakarialaoui10/mdzjs?color=rgb%2820%2C21%2C169%29" width="100" align="right">
98
+ <img src="https://img.shields.io/github/license/zakarialaoui10/mdzjs?color=rgb%2820%2C21%2C169%29" width="100" align="right"
99
+
100
+ <!--
101
+ To do
102
+ : fix fm
103
+ : add possibility of adding plugins
104
+ : add zod
105
+ : auto typing
106
+ -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdzjs",
3
- "version": "0.10.7",
3
+ "version": "0.11.0",
4
4
  "description": "markdown preprocessor for zikojs",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -12,8 +12,8 @@
12
12
  },
13
13
  "exports": {
14
14
  ".": "./src/index.js",
15
- "./vite": "./src/bundlers/vite.js",
16
- "./astro": "./src/bundlers/astro.js"
15
+ "./*": "./src/loaders/*/index.js"
16
+
17
17
  },
18
18
  "author": "zakaria elalaoui",
19
19
  "keywords": [
@@ -35,10 +35,13 @@
35
35
  "remark-gfm": "^4.0.0",
36
36
  "remark-mdx": "^3.1.0",
37
37
  "remark-parse": "^11.0.0",
38
+ "remark-toc": "^9.0.0",
38
39
  "rollup": "^4.24.0",
39
40
  "unified": "^11.0.5",
41
+ "vfile-matter": "^5.0.1",
42
+ "vfile-reporter": "^8.1.1",
40
43
  "yaml": "^2.6.1",
41
- "ziko": "^0.45.5",
44
+ "ziko": "^0.48.1",
42
45
  "ziko-wrapper": "^0.0.25"
43
46
  },
44
47
  "devDependencies": {
package/src/index.js CHANGED
@@ -1 +1,57 @@
1
- export * from "./transpiler/index.js"
1
+ import { unified } from 'unified';
2
+ import { reporter } from 'vfile-reporter'
3
+ import remarkParse from 'remark-parse';
4
+ import remarkMdx from 'remark-mdx'
5
+ import remarkFrontmatter from 'remark-frontmatter';
6
+ import remarkToc from 'remark-toc'
7
+ import remarkGFM from 'remark-gfm';
8
+ import { VFile } from 'vfile';
9
+ import {matter} from 'vfile-matter';
10
+
11
+
12
+ export async function parseMarkdown(markdown, ...plugins) {
13
+ const file = new VFile(markdown);
14
+ matter(file, { strip: true });
15
+
16
+ const preprocessor = unified()
17
+ .use(remarkParse)
18
+ .use(remarkGFM)
19
+ .use(remarkFrontmatter, ['yaml'])
20
+ .use(remarkToc)
21
+ .use(remarkMdx)
22
+
23
+ plugins.forEach(plugin => {
24
+ if (Array.isArray(plugin)) preprocessor.use(...plugin);
25
+ else preprocessor.use(plugin);
26
+ })
27
+ const ast = preprocessor.parse(String(file));
28
+ if(file.messages.length > 0 ) console.error(reporter(file))
29
+
30
+ return {
31
+ file,
32
+ frontmatter: file.data.matter,
33
+ ast,
34
+ };
35
+ }
36
+
37
+ // const inp = `
38
+ // ---
39
+ // a : 1
40
+ // b : 2
41
+ // MDZ.Props :
42
+ // - a : 1
43
+ // - c : 2
44
+ // ---
45
+
46
+ // // const {a, b}
47
+ // // = MDZ.Props
48
+
49
+ // ## Contents
50
+
51
+ // ## History
52
+
53
+ // ### Discovery
54
+ // `.trimStart()
55
+ // const out = await parseMarkdown(inp)
56
+
57
+ // console.log(JSON.stringify(out.ast.children, null, 2))
@@ -0,0 +1,31 @@
1
+ import { transpileMDZ } from "../../transpiler/index.js";
2
+
3
+ export default function ViteMDZ({ extensions = [".mdx"], plugins } = {}) {
4
+ return {
5
+ name: "mdz-loader",
6
+ async transform(src, id) {
7
+ if (id.endsWith(".mdz") || extensions.some((ext) => id.endsWith(ext))) {
8
+ const code = await transpileMDZ(src, {plugins});
9
+ return {
10
+ code,
11
+ map: null,
12
+ };
13
+ }
14
+ },
15
+
16
+ handleHotUpdate({ file, server }) {
17
+ if (file.endsWith(".mdz")) {
18
+ server.ws.send({
19
+ type: "custom",
20
+ event: "custom-update",
21
+ data: {
22
+ file,
23
+ timestamp: Date.now(),
24
+ },
25
+ });
26
+
27
+ return [file];
28
+ }
29
+ },
30
+ };
31
+ }
@@ -0,0 +1,57 @@
1
+ import { unified } from 'unified';
2
+ import { reporter } from 'vfile-reporter'
3
+ import remarkParse from 'remark-parse';
4
+ import remarkMdx from 'remark-mdx'
5
+ import remarkFrontmatter from 'remark-frontmatter';
6
+ import remarkToc from 'remark-toc'
7
+ import remarkGFM from 'remark-gfm';
8
+ import { VFile } from 'vfile';
9
+ import {matter} from 'vfile-matter';
10
+
11
+
12
+ export async function parseMDZ(markdown, ...plugins) {
13
+ const file = new VFile(markdown);
14
+ matter(file, { strip: true });
15
+
16
+ const preprocessor = unified()
17
+ .use(remarkParse)
18
+ .use(remarkGFM)
19
+ .use(remarkFrontmatter, ['yaml'])
20
+ .use(remarkToc)
21
+ .use(remarkMdx)
22
+
23
+ plugins.forEach(plugin => {
24
+ if (Array.isArray(plugin)) preprocessor.use(...plugin);
25
+ else preprocessor.use(plugin);
26
+ })
27
+ const ast = preprocessor.parse(String(file));
28
+ if(file.messages.length > 0 ) console.error(reporter(file))
29
+
30
+ return {
31
+ file,
32
+ frontmatter: file.data.matter,
33
+ ast,
34
+ };
35
+ }
36
+
37
+ // const inp = `
38
+ // ---
39
+ // a : 1
40
+ // b : 2
41
+ // MDZ.Props :
42
+ // - a : 1
43
+ // - c : 2
44
+ // ---
45
+
46
+ // // const {a, b}
47
+ // // = MDZ.Props
48
+
49
+ // ## Contents
50
+
51
+ // ## History
52
+
53
+ // ### Discovery
54
+ // `.trimStart()
55
+ // const out = await parseMarkdown(inp)
56
+
57
+ // console.log(JSON.stringify(out.ast.children, null, 2))
@@ -0,0 +1,148 @@
1
+ import {
2
+ componentType,
3
+ processAttribute,
4
+ // parseYml,
5
+ hyperscript
6
+ } from "../utils/index.js"
7
+ import hljs from "highlight.js"
8
+ const processMDZAST = (markdownAST) => {
9
+ let hasCode = false;
10
+ const transformNode = (node) => {
11
+ switch(node.type){
12
+ case 'mdxjsEsm' : {
13
+ return {
14
+ type : "script",
15
+ value : node.value
16
+ }
17
+ }
18
+ case 'text' : {
19
+ const text = node.value;
20
+ const escaped = text.replace(/"/g, '\\"');
21
+ return `"${escaped}"`;
22
+ }
23
+ case 'mdxTextExpression' : {
24
+ const {value} = node
25
+ return value
26
+ }
27
+ case 'mdxFlowExpression' : {
28
+ const {value} = node;
29
+ if(!node.parent || node.parent.type === 'root')
30
+ return hyperscript("p", "{}", value);
31
+ return value
32
+ }
33
+ case 'heading' : {
34
+ const childNodes = node.children.map(transformNode).join(', ');
35
+ return hyperscript(`h${node.depth}`,"{}", childNodes);
36
+ }
37
+ case 'paragraph' : {
38
+ const childNodes = node.children.map(transformNode).join(', ');
39
+ return hyperscript("p","{}", childNodes)
40
+ }
41
+ case 'strong': {
42
+ const childNodes = node.children.map(transformNode).join(', ');
43
+ return hyperscript("strong","{}", childNodes);
44
+ }
45
+ case 'emphasis': {
46
+ const childNodes = node.children.map(transformNode).join(', ');
47
+ return hyperscript("em","{}", childNodes);
48
+ }
49
+ case 'link': {
50
+ const childNodes = node.children.map(transformNode).join(', ');
51
+ return hyperscript("a", `{ href: "${node.url}" }`, childNodes);
52
+ }
53
+ case 'image': {
54
+ hyperscript("img", `{ src: "${node.url}", alt: "${node.alt || ''}`)
55
+ return `tags.img({ src: "${node.url}", alt: "${node.alt || ''}" })`;
56
+ }
57
+
58
+ case 'list': {
59
+ const listTag = node.ordered ? 'ol' : 'ul';
60
+ const childNodes = node.children.map(transformNode).join(', ');
61
+ return hyperscript(listTag, "{}", childNodes);
62
+ }
63
+
64
+ case 'listItem': {
65
+ const childNodes = node.children.map(transformNode).join(', ');
66
+ return hyperscript("li", "{}", childNodes);
67
+ }
68
+ case 'inlineCode' : {
69
+ return hyperscript("code", "{}", `"${node.value}"`)
70
+ }
71
+ case 'code': {
72
+ hasCode = true;
73
+ const highlightedCode = hljs.highlightAuto(node.value, [node.lang || '']).value;
74
+ const formatedCode = highlightedCode.replace(/(\r\n|\n|\r)/g, "<br>")
75
+ return `HTMLWrapper('<pre><code>${formatedCode}</code></pre>')`
76
+ }
77
+ case 'blockquote': {
78
+ const childNodes = node.children.map(transformNode).join(', ');
79
+ return hyperscript("blockquote", "{}", childNodes);
80
+ }
81
+ case 'thematicBreak': {
82
+ return `tags.hr({})`;
83
+ }
84
+ case 'table': {
85
+ const headerRows = node.children[0].children.map(transformNode).join(', ');
86
+ const bodyRows = node.children.slice(1).map(transformNode).join(', ');
87
+ const thead = hyperscript("thead", "{}", hyperscript("tr", "{}", headerRows));
88
+ const tbody = hyperscript("tbody", "{}", bodyRows);
89
+ return hyperscript("table", "{}", [thead, tbody].join(","))
90
+ }
91
+ case 'tableRow': {
92
+ const cells = node.children.map(transformNode).join(', ');
93
+ return `${hyperscript("tr", "{}", cells)}`
94
+ }
95
+ case 'tableCell': {
96
+ const childNodes = node.children.map(transformNode).join(', ');
97
+ return `${hyperscript("td", "{}", childNodes)}`
98
+ }
99
+ case 'mdxJsxTextElement': {
100
+ const {name, attributes, children} = node;
101
+ const childNodes = children.map(transformNode).join(', ');
102
+ const hasChildren = childNodes.length > 0;
103
+ return `tags.${name}(${processAttribute(attributes)}${hasChildren ?`, ${childNodes}`:""})`;
104
+ };
105
+ case 'mdxJsxFlowElement':{
106
+ const {name, attributes, children} = node;
107
+ const childNodes = children.map(transformNode).join(', ');
108
+ const hasChildren = childNodes.length > 0;
109
+ switch(componentType(name)){
110
+ case "jsx" : {
111
+ return `${name}(${processAttribute(attributes)}${hasChildren ?`, ${childNodes}`:""})`;
112
+ }
113
+ case "html" : return `tags.${name}(${processAttribute(attributes)}${hasChildren ?`, ${childNodes}`:""})`;
114
+ case "script" : {
115
+ const statements = [];
116
+ for(let i=0; i<node.children.length; i++) statements.push(node.children[i].children[0].value)
117
+ return {
118
+ type : "script",
119
+ isScript : true,
120
+ value : statements.join("\n")
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
126
+ return 'null';
127
+ };
128
+ let esm = [];
129
+ const statements = []
130
+ markdownAST.children.forEach((node) => {
131
+ switch(node.type){
132
+ case 'mdxjsEsm' : esm.push(node.value); break;
133
+ default : {
134
+ const Transformed = transformNode(node);
135
+ if(Transformed.isScript) statements.push(Transformed.value);
136
+ else statements.push(`__items__.push(${Transformed})`)
137
+ }
138
+ }
139
+ });
140
+ return {
141
+ esm,
142
+ statements,
143
+ hasCode
144
+ }
145
+ };
146
+ export {
147
+ processMDZAST
148
+ }
package/src/test.js CHANGED
@@ -1,49 +1,24 @@
1
- // import { cleanMD } from "./pre-parse/clean-md.js";
2
- import { parseMDZ, transpileMDZ } from "./transpiler/index.js";
3
- import { parseYml } from "./utils/parse-yml.js";
4
-
5
- const md = `---
6
- title : get started
7
- id : 1
8
- __props__ :
9
- color : red
10
- size : 10
1
+ import { parseMDZ } from "./parser/index.js";
2
+ import { processMDZAST } from "./processor/index.js";
3
+ import { transpileMDZ } from "./transpiler/index.js";
4
+ const inp = `
11
5
  ---
6
+ a : 1
7
+ b : 2
8
+ MDZ.Props :
9
+ - a : 3
10
+ - c : 2
11
+ ---
12
+ import A from 'B';
12
13
 
13
- <script>
14
- console.log(1)
15
- console.log(2)
16
-
17
- console.log(3)
18
- </script>
19
-
20
- import A from "./A"
21
- export const b = 10;
22
-
23
- Hello {name} mm {m} [mmmm](kkk)
24
-
25
- <B exp={1+1} str="kk">
26
- # hi
27
- # hi
28
- </B>
29
-
30
- # Hi
31
- ## HI {Ziko}
32
-
33
-
34
- |A|B|
35
- |-|-|
14
+ {A}
36
15
 
16
+ # Hello
37
17
  `
18
+ // const out = await parseMDZ(inp)
19
+ // const p = processMDZAST(out.ast)
20
+ const t = await transpileMDZ(inp)
38
21
 
39
- // const md = `---
40
- // title : Hi
41
- // ---
42
- // `
43
- const ast = parseMDZ(md)
44
- // console.log(ast.children.at(-1))
45
- const js = transpileMDZ(md)
46
- console.log(js)
47
- // console.log(JSON.stringify(ast, null, 2))
48
-
49
- // parseYml('a : 1\n__props__ : \n d : 2\n e : 1')
22
+ // console.log(out)
23
+ // console.log(p)
24
+ console.log(t)
@@ -1,3 +1,26 @@
1
- export { parseMarkdown } from "./parser.js";
2
- export { processMDZAST } from "./process.js";
3
- export { transpileMDZ } from "./transpile.js";
1
+ import { parseMDZ } from "../parser/index.js";
2
+ import { processMDZAST } from "../processor/index.js";
3
+ import { stringifyProps, transformeAttrs } from "../utils/index.js";
4
+
5
+ const transpileMDZ = async (Markdown, {plugins = []} = {})=>{
6
+ const {ast, frontmatter} = await parseMDZ(Markdown, ...plugins);
7
+ const {esm, statements, hasCode}= processMDZAST(ast);
8
+
9
+ const { 'MDZ.Props': props, ...attrs } = frontmatter;
10
+
11
+ const body = [
12
+ 'import {tags, HTMLWrapper} from "ziko"',
13
+ ...esm,
14
+ transformeAttrs(attrs),
15
+ `export default (${stringifyProps(props)})=>{`,
16
+ 'const __items__ = []',
17
+ ...statements,
18
+ "const UI = tags.div({class : 'mdz-wrapper'}, ...__items__).style({display : 'contents'})",
19
+ "return UI }"
20
+ ]
21
+ // if(hasCode) body.unshift(`import("highlight.js/styles/${CodeStyle}.css")`);
22
+ return body.join("\n");
23
+ }
24
+ export{
25
+ transpileMDZ
26
+ }
@@ -1,4 +1,5 @@
1
1
  export { componentType } from "./component-type.js";
2
2
  export { processAttribute } from "./process-attributes.js";
3
- export { parseYml } from "./parse-yml.js";
4
- export { hyperscript } from "./hyperscript.js"
3
+ export * from "./parse-yml.js";
4
+ export { hyperscript } from "./hyperscript.js"
5
+ export * from './transforme-attrs.js'
@@ -0,0 +1,10 @@
1
+ export const transformeAttrs = attrs => {
2
+ const HasAttributs = Object.keys(attrs).length > 0
3
+ return HasAttributs
4
+ ? [
5
+ `const {${Object.keys(attrs).join(",")}} = ${JSON.stringify(attrs,"",2)}`,
6
+ `export {${Object.keys(attrs).join(", ")}}`
7
+ ].join("\n")
8
+ : ''
9
+
10
+ }
@@ -0,0 +1 @@
1
+ export * from "./transpiler/index.js"
@@ -0,0 +1,49 @@
1
+ // import { cleanMD } from "./pre-parse/clean-md.js";
2
+ import { parseMDZ, transpileMDZ } from "./transpiler/index.js";
3
+ import { parseYml } from "./utils/parse-yml.js";
4
+
5
+ const md = `---
6
+ title : get started
7
+ id : 1
8
+ __props__ :
9
+ color : red
10
+ size : 10
11
+ ---
12
+
13
+ <script>
14
+ console.log(1)
15
+ console.log(2)
16
+
17
+ console.log(3)
18
+ </script>
19
+
20
+ import A from "./A"
21
+ export const b = 10;
22
+
23
+ Hello {name} mm {m} [mmmm](kkk)
24
+
25
+ <B exp={1+1} str="kk">
26
+ # hi
27
+ # hi
28
+ </B>
29
+
30
+ # Hi
31
+ ## HI {Ziko}
32
+
33
+
34
+ |A|B|
35
+ |-|-|
36
+
37
+ `
38
+
39
+ // const md = `---
40
+ // title : Hi
41
+ // ---
42
+ // `
43
+ const ast = parseMDZ(md)
44
+ // console.log(ast.children.at(-1))
45
+ const js = transpileMDZ(md)
46
+ console.log(js)
47
+ // console.log(JSON.stringify(ast, null, 2))
48
+
49
+ // parseYml('a : 1\n__props__ : \n d : 2\n e : 1')
@@ -0,0 +1,3 @@
1
+ export { parseMarkdown } from "./parser.js";
2
+ export { processMDZAST } from "./process.js";
3
+ export { transpileMDZ } from "./transpile.js";
@@ -0,0 +1,5 @@
1
+ export const componentType = tag => {
2
+ if(tag === "script") return "script";
3
+ if(tag.toLowerCase() !== tag || tag.includes(".")) return "jsx";
4
+ return "html"
5
+ }
@@ -0,0 +1,29 @@
1
+ export const hyperscript = (tag, attrs, children="") => {
2
+ const HasChildren = !!children;
3
+ if(tag){
4
+ children = ',""' + children + ',""'
5
+ const splitted = splitQuotedLines(children);
6
+ children = insertBetween(splitted, 'tags.br({})')
7
+ children[children.length - 1] = children.at(-1).slice(0, -3)
8
+ children[0] = children.at(0).slice(3)
9
+ }
10
+ return `tags.${tag}(${attrs}${HasChildren ?`, ${children}` : ""})`
11
+ }
12
+
13
+ function splitQuotedLines(str) {
14
+ return str
15
+ .slice(1, -1) // Remove the surrounding quotes
16
+ .split(/\r\n|\r|\n/) // Split by newline types
17
+ .map(line => `"${line}"`); // Re-wrap each line in quotes
18
+ }
19
+
20
+ function insertBetween(arr, value) {
21
+ const result = [];
22
+ for (let i = 0; i < arr.length; i++) {
23
+ result.push(arr[i]);
24
+ if (i < arr.length - 1) {
25
+ result.push(value);
26
+ }
27
+ }
28
+ return result;
29
+ }
@@ -0,0 +1,4 @@
1
+ export { componentType } from "./component-type.js";
2
+ export { processAttribute } from "./process-attributes.js";
3
+ export { parseYml } from "./parse-yml.js";
4
+ export { hyperscript } from "./hyperscript.js"
@@ -0,0 +1,23 @@
1
+ import { parse } from 'yaml';
2
+
3
+ const parseYml = yml => {
4
+ const {__props__, ...__attrs__} = yml ? parse(yml) : {__props__ : {}} ;
5
+ const HasAttributs = Object.keys(__attrs__).length > 0
6
+ return {
7
+ props : __props__,
8
+ attrs : HasAttributs
9
+ ?[
10
+ `const {${Object.keys(__attrs__).join(",")}} = ${JSON.stringify(__attrs__,"",2)}`,
11
+ `export {${Object.keys(__attrs__).join(", ")}}`
12
+ ].join("\n")
13
+ : "",
14
+ }
15
+ }
16
+
17
+ const stringifyProps = (props) =>{
18
+ return props
19
+ ?`{${Object.entries(props).map(([key, value]) => `${key} = ${JSON.stringify(value)}`).join(", ")}}={}`
20
+ :""
21
+ }
22
+
23
+ export {parseYml, stringifyProps}
@@ -0,0 +1,13 @@
1
+ export const processAttribute = (attributes) =>{
2
+ if(attributes.length === 0) return "{}"
3
+ let attr = []
4
+ for(let i=0; i<attributes.length ; i++){
5
+ let {name, value} = attributes[i]
6
+ attr.push({
7
+ name,
8
+ value : typeof value === "string" ? value : value.value,
9
+ isExpression : typeof value !== "string"
10
+ })
11
+ }
12
+ return `{${attr.map(({name, value, isExpression})=>`${name}:${isExpression ? value : `"${value}"`}`).join(", ")}}`
13
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes