mikel-markdown 0.26.0 → 0.26.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 +52 -30
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -25,28 +25,42 @@ const render = (tag, props = {}, content = "") => {
25
25
  // @description all available expressions
26
26
  const allExpressions = {
27
27
  pre: {
28
- regex: /(?:^```(?:[^\n]*)\n([\s\S]*?)\n``` *$)/gm,
29
- replace: (args, cn) => render("pre", {class: cn.pre}, escape(args[1])),
28
+ regex: /(?:^``` *([^\n]*)\n([\s\S]*?)\n``` *$)/gm,
29
+ replace: (args, opt) => {
30
+ const code = typeof opt?.highlight === "function" ? opt.highlight(args[2], args[1]) : escape(args[2]);
31
+ return render("pre", {class: opt.classNames?.pre}, code);
32
+ },
30
33
  },
31
34
  code: {
32
35
  regex: /`([^`]*?)`/g,
33
- replace: (args, cn) => render("code", {class: cn.code}, escape(args[1])),
36
+ replace: (args, opt) => {
37
+ return render("code", {class: opt.classNames?.code}, escape(args[1]));
38
+ },
34
39
  },
35
40
  heading: {
36
41
  regex: /^(#+)\s+(.*)/gm,
37
- replace: (args, cn) => render("h" + args[1].length, {class: cn.heading}, args[2]),
42
+ replace: (args, opt) => {
43
+ const level = args[1].length;
44
+ const cn = [opt.classNames?.heading, opt.classNames?.["heading" + level]];
45
+ return render("h" + level, {class: cn.filter(Boolean).join(" ")}, args[2]);
46
+ },
38
47
  },
39
48
  blockquote: {
40
49
  regex: /^[\s]*>\s(.*)/gm,
41
- replace: (args, cn) => render("blockquote", {class: cn.blockquote}, args[1]),
50
+ replace: (args, opt) => {
51
+ return render("blockquote", {class: opt.classNames?.blockquote}, args[1]);
52
+ },
42
53
  },
43
54
  image: {
44
55
  regex: /\!\[([^\]]*?)\]\(([^)]*?)\)/g,
45
- replace: (args, cn) => render("img", {class: cn.image, alt: args[1], src: args[2]}),
56
+ replace: (args, opt) => {
57
+ return render("img", {class: opt.classNames?.image, alt: args[1], src: args[2]});
58
+ },
46
59
  },
47
60
  table: {
48
61
  regex: /^\|((?: +[^\n|]+ +\|?)+)\| *\n\|((?: *[:]?[-]+[:]? *\|?)+)\| *\n((?:^\|(?: +[^\n|]+ +\|?)+\| *\n)+)\n/gm,
49
- replace: (args, cn) => {
62
+ replace: (args, opt) => {
63
+ const cn = opt.classNames || {};
50
64
  // args[1] --> table header
51
65
  // args[3] --> table body
52
66
  const head = args[1].trim().split("|").map(c => {
@@ -69,55 +83,63 @@ const allExpressions = {
69
83
  },
70
84
  link: {
71
85
  regex: /\[(.*?)\]\(([^\t\n\s]*?)\)/gm,
72
- replace: (args, cn) => render("a", {class: cn.link, href: args[2]}, args[1]),
86
+ replace: (args, opt) => {
87
+ return render("a", {class: opt.classNames?.link, href: args[2]}, args[1]);
88
+ },
73
89
  },
74
90
  rule: {
75
91
  regex: /^.*?(?:---|-\s-\s-|\*\s\*\s\*)/gm,
76
- replace: (args, cn) => render("hr", {class: cn.rule}),
92
+ replace: (args, opt) => render("hr", {class: opt.classNames?.rule}),
77
93
  },
78
94
  list: {
79
95
  regex: /^[\t\s]*?(?:-|\+|\*)\s(.*)/gm,
80
- replace: (args, cn) => {
81
- return render("ul", {class: cn.list}, render("li", {class: cn.listItem}, args[1]));
96
+ replace: (args, opt) => {
97
+ return render("ul", {class: opt.classNames?.list}, render("li", {class: opt.classNames?.listItem}, args[1]));
82
98
  },
83
- afterRegex: /(<\/ul>\n(?:.*)<ul ?(?:class=".*")?>*)+/g
99
+ afterRegex: /(<\/ul>\n(?:.*)<ul ?(?:class="[^"]*")?>*)+/g
84
100
  },
85
101
  orderedList: {
86
102
  regex: /^[\t\s]*?(?:\d(?:\)|\.))\s(.*)/gm,
87
- replace: (args, cn) => {
88
- return render("ol", {class: cn.list}, render("li", {class: cn.listItem}, args[1]));
103
+ replace: (args, opt) => {
104
+ return render("ol", {class: opt.classNames?.list}, render("li", {class: opt.classNames?.listItem}, args[1]));
89
105
  },
90
- afterRegex: /(<\/ol>\n(?:.*)<ol ?(?:class=".*")?>*)+/g
106
+ afterRegex: /(<\/ol>\n(?:.*)<ol ?(?:class="[^"]*")?>*)+/g
91
107
  },
92
108
  strong: {
93
109
  regex: /(?:\*\*|__)([^\n]+?)(?:\*\*|__)/g,
94
- replace: (args, cn) => render("strong", {class: cn.strong}, args[1]),
110
+ replace: (args, opt) => {
111
+ return render("strong", {class: opt.classNames?.strong}, args[1]);
112
+ },
95
113
  },
96
114
  emphasis: {
97
115
  regex: /(?:\*|_)([^\n]+?)(?:\*|_)/g,
98
- replace: (args, cn) => render("em", {class: cn.emphasis}, args[1]),
116
+ replace: (args, opt) => {
117
+ return render("em", {class: opt.classNames?.emphasis}, args[1]);
118
+ },
99
119
  },
100
120
  paragraph: {
101
121
  regex: /^((?:.+(?:\n|$))+)/gm,
102
- replace: (args, cn) => {
122
+ replace: (args, opt) => {
103
123
  const line = args[0].trim();
104
- // check if the line starts with a block tag
105
- if (/^\<(\/? *(ul|ol|bl|h\d|p|di|st|sc|t)|!--)/.test(line.slice(0, 4)) === true) {
124
+ // check if the line starts with a block tag or is an empty line
125
+ if (!line || /^\<(\/? *(ul|ol|bl|h\d|p|div|sty|scr|t)|!--)/.test(line.slice(0, 4))) {
106
126
  return line;
107
127
  }
108
- return render("p", {class: cn.paragraph}, line.replace(/\n/g, ""));
109
- }
110
- }
128
+ return render("p", {class: opt.classNames?.paragraph}, line.replace(/\n/g, ""));
129
+ },
130
+ },
111
131
  };
112
132
 
113
- // @description inline expressions
114
- const inlineExpressions = Object.fromEntries(["code", "link", "strong", "emphasis"].map(key => {
115
- return [key, allExpressions[key]];
116
- }));
133
+ // @description get only inline expressions
134
+ const getInlineExpressions = expressions => {
135
+ const fields = ["code", "link", "strong", "emphasis", "image"].filter(key => !!expressions[key]);
136
+ return Object.fromEntries(fields.map(key => {
137
+ return [key, expressions[key]];
138
+ }));
139
+ };
117
140
 
118
141
  // @description markdown parser
119
142
  const parser = (str = "", options = {}) => {
120
- const classNames = options?.classNames || {}; // custom classNames
121
143
  const expressions = options?.expressions || allExpressions; // custom expressions
122
144
  const ignoredBlocks = []; // chunks to ignore
123
145
  str = str.replace(/\r\n/g, "\n");
@@ -130,7 +152,7 @@ const parser = (str = "", options = {}) => {
130
152
  // replace all expressions
131
153
  Object.keys(expressions).forEach(key => {
132
154
  str = str.replace(expressions[key].regex, (...args) => {
133
- const value = expressions[key].replace(args, classNames);
155
+ const value = expressions[key].replace(args, options);
134
156
  if (key === "pre" || key === "code") {
135
157
  ignoredBlocks.push(value);
136
158
  return `<!--HTML-BLOCK-${(ignoredBlocks.length - 1)}-->`;
@@ -160,8 +182,8 @@ const markdownPlugin = (options = {}) => {
160
182
  },
161
183
  inlineMarkdown: params => {
162
184
  return parser(params.fn(params.data) || "", {
163
- expressions: inlineExpressions,
164
185
  ...options,
186
+ expressions: getInlineExpressions(options.expressions || allExpressions),
165
187
  });
166
188
  },
167
189
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mikel-markdown",
3
3
  "description": "A mikel helper for parsing markdown content.",
4
- "version": "0.26.0",
4
+ "version": "0.26.2",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": {