@timvir/mdx 0.1.29

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.
Files changed (3) hide show
  1. package/index.d.ts +1 -0
  2. package/index.js +117 -0
  3. package/package.json +21 -0
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export function remarkPlugin(options: any): (tree: any, file: any) => void;
package/index.js ADDED
@@ -0,0 +1,117 @@
1
+ import * as fs from "fs";
2
+ import { fromMarkdown } from "mdast-util-from-markdown";
3
+ import { mdxFromMarkdown } from "mdast-util-mdx";
4
+ import { mdxjs } from "micromark-extension-mdxjs";
5
+ import * as crypto from "crypto";
6
+ import * as path from "path";
7
+ import { visit } from "unist-util-visit";
8
+
9
+ export function remarkPlugin(options) {
10
+ let counter = 0;
11
+
12
+ return (tree, file) => {
13
+ const filename = file.history[0];
14
+
15
+ visit(tree, "mdxJsxFlowElement", (node) => {
16
+ if (node.name === "Sample") {
17
+ const { attributes: attrs } = node;
18
+
19
+ const component = findAttrValue(attrs, "component") || "..";
20
+ const variant = findAttrValue(attrs, "variant");
21
+
22
+ const as = findAttrValue(attrs, "as") || "component";
23
+ const props = findAttrValue(attrs, "props");
24
+
25
+ const otherAttributes = attrs.filter(
26
+ ({ type, name }) => type === "mdxJsxAttribute" && !(name in { component: 1, variant: 1, as: 1, props: 1 })
27
+ );
28
+
29
+ /*
30
+ * The module which holds the sample.
31
+ */
32
+ const module = path.join(path.dirname(filename), component, "samples", variant);
33
+
34
+ ({
35
+ component: () => {
36
+ /*
37
+ * Genrate a unique name that will be used to hold the reference
38
+ * to the sample component.
39
+ */
40
+ const name = `C${genName(filename, component, variant, "" + counter)}`;
41
+ counter = counter + 1;
42
+
43
+ /*
44
+ * Construct the import declaration and insert into the very
45
+ * beginning of the tree.
46
+ */
47
+ const { children } = fromMarkdown(`import ${name} from "${module}";`, {
48
+ extensions: [mdxjs()],
49
+ mdastExtensions: [mdxFromMarkdown()],
50
+ });
51
+ tree.children.unshift(...children);
52
+
53
+ /*
54
+ * Update the mdxJsxFlowElement node:
55
+ *
56
+ * - Update name (no longer <Sample> but the generated name).
57
+ * - Tweak props.
58
+ */
59
+ node.name = name;
60
+ node.attributes = [...otherAttributes];
61
+ if (props?.value) {
62
+ node.attributes.push({ type: "mdxJsxExpressionAttribute", value: `...${props.value}` });
63
+ }
64
+ },
65
+ source: () => {
66
+ const source = (() => {
67
+ if (fs.existsSync(module)) {
68
+ return fs.readFileSync(module, "utf8");
69
+ } else {
70
+ return fs.readFileSync(module + ".tsx", "utf8");
71
+ }
72
+ })();
73
+
74
+ const { children } = fromMarkdown(`{${JSON.stringify(source)}}`, {
75
+ extensions: [mdxjs()],
76
+ mdastExtensions: [mdxFromMarkdown()],
77
+ });
78
+
79
+ for (const [k] of Object.keys(node)) {
80
+ delete node[k];
81
+ }
82
+
83
+ for (const [k, v] of Object.entries(children[0])) {
84
+ node[k] = v;
85
+ }
86
+ },
87
+ }[as]());
88
+ }
89
+ });
90
+ };
91
+ }
92
+
93
+ const matchAttr =
94
+ (t, n) =>
95
+ ({ type, name }) =>
96
+ type === t && name === n;
97
+
98
+ const findAttrValue = (attrs, n) => {
99
+ return attrs.find(matchAttr("mdxJsxAttribute", n))?.value;
100
+ };
101
+
102
+ const genName = (...buffers) => {
103
+ const hash = crypto.createHash("sha256");
104
+ for (const buffer of buffers) {
105
+ hash.update(buffer);
106
+ }
107
+ const ret = hash.digest();
108
+ const alpha = (x) => {
109
+ if (x < 26) return x + 65;
110
+ if (x < 52) return x - 26 + 97;
111
+ throw new Error(`alnum: value out of range: ${x}`);
112
+ };
113
+ for (const [index, value] of ret.entries()) {
114
+ ret[index] = alpha(value % 52);
115
+ }
116
+ return ret.toString("utf8");
117
+ };
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "type": "module",
3
+ "name": "@timvir/mdx",
4
+ "version": "0.1.29",
5
+ "license": "MIT",
6
+ "sideEffects": false,
7
+ "exports": {
8
+ ".": "./index.js"
9
+ },
10
+ "dependencies": {
11
+ "mdast-util-from-markdown": "^1.2.0",
12
+ "mdast-util-mdx": "^2.0.0",
13
+ "micromark-extension-mdxjs": "^1.0.0",
14
+ "unist-util-visit": "^4.1.0"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "ssh://git@github.com:timvir/timvir.git",
19
+ "directory": "pkg/mdx"
20
+ }
21
+ }