mikel 0.9.0 → 0.9.2

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 (2) hide show
  1. package/index.js +65 -0
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const tags = /\{\{|\}\}/;
2
+ const endl = "\n";
2
3
  const escapedChars = {
3
4
  "&": "&",
4
5
  "<": "&lt;",
@@ -18,6 +19,68 @@ const parse = (v, context = {}, vars = {}) => {
18
19
  return (v || "").startsWith("@") ? get(vars, v.slice(1)) : get(context, v || ".");
19
20
  };
20
21
 
22
+ // @description tiny yaml parser
23
+ const yamlParser = (str = "") => {
24
+ const lines = str.split(endl), result = {}, levels = [{ctx: result, indent: 0}];
25
+ let level = 0, i = 0;
26
+ while (i < lines.length) {
27
+ const line = lines[i] || "";
28
+ if (!!line.trim() && !line.trim().startsWith("#")) {
29
+ const indent = (line.match(/^( *)/m)?.[0] || "").length;
30
+ while(level > 0 && indent < levels[level].indent) {
31
+ levels.pop();
32
+ level = level - 1;
33
+ }
34
+ const isArrayItem = line.trim().startsWith("-");
35
+ // TODO: improve the regex to capture the line structure
36
+ let [_, key, value] = (line.trim().match(/^([^:"]*):(.*)$/m) || ["", line]).map(v => v.trim());
37
+ // Check if is a new item of the array
38
+ if (isArrayItem) {
39
+ key = key.replace(/^(- *)/m, "");
40
+ if (typeof value === "undefined") {
41
+ value = key;
42
+ }
43
+ else {
44
+ const newIndent = (line.slice(0, line.indexOf(key))).length;
45
+ levels[level].ctx.push({});
46
+ levels.push({ctx: levels[level].ctx[levels[level].ctx.length - 1], indent: newIndent});
47
+ level = level + 1;
48
+ }
49
+ }
50
+ // Check for empty value --> entering into a nested object or array
51
+ if (!value) {
52
+ const nextLine = lines[i + 1] || "";
53
+ const nextIndent = (nextLine.match(/^( *)/m)?.[0] || "").length;
54
+ levels[level].ctx[key] = nextLine.trim().startsWith("-") ? [] : {};
55
+ if (nextIndent > levels[level].indent) {
56
+ levels.push({ctx: levels[level].ctx[key], indent: nextIndent});
57
+ level = level + 1;
58
+ }
59
+ }
60
+ else if(value && Array.isArray(levels[level].ctx)) {
61
+ levels[level].ctx.push(JSON.parse(value));
62
+ }
63
+ else if (value) {
64
+ levels[level].ctx[key] = JSON.parse(value);
65
+ }
66
+ }
67
+ i = i + 1;
68
+ }
69
+ return result;
70
+ };
71
+
72
+ // @description tiny front-matter parser
73
+ const frontmatter = (str = "", parser = null) => {
74
+ let body = (str || "").trim(), data = {};
75
+ const matches = Array.from(body.matchAll(/^(--- *)/gm))
76
+ if (matches?.length === 2 && matches[0].index === 0) {
77
+ const front = body.substring(0 + matches[0][1].length, matches[1].index).trim();
78
+ body = body.substring(matches[1].index + matches[1][1].length).trim();
79
+ data = typeof parser === "function" ? parser(front) : yamlParser(front);
80
+ }
81
+ return {body, data};
82
+ };
83
+
21
84
  const defaultHelpers = {
22
85
  "each": (value, opt) => {
23
86
  return (typeof value === "object" ? Object.entries(value || {}) : [])
@@ -111,5 +174,7 @@ const mikel = (str, context = {}, opt = {}, output = []) => {
111
174
  mikel.escape = escape;
112
175
  mikel.get = get;
113
176
  mikel.parse = parse;
177
+ mikel.yaml = yamlParser;
178
+ mikel.frontmatter = frontmatter;
114
179
 
115
180
  export default mikel;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mikel",
3
3
  "description": "Micro templating library with zero dependencies",
4
- "version": "0.9.0",
4
+ "version": "0.9.2",
5
5
  "type": "module",
6
6
  "author": {
7
7
  "name": "Josemi Juanes",