markdown-maker 1.10.0 → 1.10.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdown-maker",
3
- "version": "1.10.0",
3
+ "version": "1.10.1",
4
4
  "description": "",
5
5
  "main": "src/cltool.ts",
6
6
  "bin": {
@@ -52,6 +52,7 @@
52
52
  "colors": "^1.4.0",
53
53
  "colors.ts": "^1.0.20",
54
54
  "marked": "^2.0.1",
55
+ "node-html-parser": "^6.1.13",
55
56
  "require-runtime": "^2.0.0",
56
57
  "ws": "^8.8.1"
57
58
  },
package/src/commands.ts CHANGED
@@ -3,6 +3,7 @@ import Parser from "./parse";
3
3
  import * as fs from "fs";
4
4
  import templates, { new_template } from "./templates";
5
5
  import requireRuntime from "require-runtime";
6
+ import * as nodeHtmlParser from "node-html-parser";
6
7
 
7
8
  export class MDMError extends Error {
8
9
  match: RegExpMatchArray;
@@ -207,12 +208,65 @@ new Command(
207
208
  CommandType.PARSE
208
209
  );
209
210
 
211
+ /* mdmaketoc */
210
212
  new Command(
211
213
  /#mdmaketoc(?:<>)?/,
212
214
  (match, parser) => parser.gen_toc(),
213
215
  CommandType.POSTPARSE
214
216
  );
215
217
 
218
+ /* basic mdhook */
219
+ new Command(
220
+ /#mdhook<(\w+)>/,
221
+ (match, parser) => {
222
+ if (parser.opts.hooks[match[1]]) {
223
+ return parser.opts.hooks[match[1]]();
224
+ }
225
+ },
226
+ CommandType.POSTPARSE
227
+ );
228
+
229
+ /* mdadvhook */
230
+ new Command(
231
+ /\#mdadvhook<(\w+)>([\w\W]+?)\#mdendhook/,
232
+ (match, parser) => {
233
+ if (parser.opts.adv_hooks[match[1]]) {
234
+ const innerElements = match[2].trim();
235
+ /* Find tagNames in innerElements */
236
+ const re = /<(\w+)[\s=\w\"\'-]*>/g;
237
+ const tags = [];
238
+ innerElements.match(re)?.forEach((tag) => {
239
+ tags.push(tag.slice(1, -1).split(" ")[0]);
240
+ });
241
+ /* Evil type hack */
242
+ const root = nodeHtmlParser.parse(innerElements, {
243
+ voidTag: {
244
+ tags,
245
+ closingSlash: true,
246
+ },
247
+ }) as any as HTMLElement;
248
+
249
+ const helper = (node: HTMLElement) => {
250
+ /* */
251
+ const map: { [tag: string]: HTMLElement } = {};
252
+ for (let tag of tags) {
253
+ const el = node.getElementsByTagName(tag)[0];
254
+ const dataTag = el.toString().match(/data-tag="([\w-]+)"/);
255
+ if (!dataTag || dataTag[1] == undefined) continue;
256
+ el.tagName = dataTag[1];
257
+ el.removeAttribute("data-tag");
258
+ map[tag] = el;
259
+ }
260
+ return map;
261
+ };
262
+
263
+ const hooked = parser.opts.adv_hooks[match[1]](root, helper(root));
264
+ return hooked.toString();
265
+ }
266
+ },
267
+ CommandType.POSTPARSE
268
+ );
269
+
216
270
  const loaded_extentions: fs.PathLike[] = [];
217
271
 
218
272
  function load_extension(parser: Parser, file: fs.PathLike) {
package/src/parse.ts CHANGED
@@ -1,9 +1,10 @@
1
- const fs = require("fs"); /* for handling reading of files */
2
- const path = require("path"); /* for handling file paths */
1
+ import fs from "fs"; /* for handling reading of files */
2
+ import path from "path"; /* for handling file paths */
3
3
 
4
4
  import Colors = require("colors.ts"); /* for adding colours to strings */
5
5
  Colors.enable();
6
- const marked = require("marked");
6
+ import marked from "marked";
7
+
7
8
  import { Command, commands, load_extensions, MDMError } from "./commands";
8
9
 
9
10
  enum TargetType {
@@ -43,6 +44,13 @@ class Parser {
43
44
  targetType: TargetType | undefined;
44
45
  only_warn: boolean;
45
46
  parent?: Parser;
47
+ hooks: { [key: string]: () => string };
48
+ adv_hooks: {
49
+ [key: string]: (
50
+ tree: HTMLElement,
51
+ map: { [tag: string]: HTMLElement }
52
+ ) => HTMLElement;
53
+ };
46
54
  isFileCallback: (s: string) => false | string;
47
55
  };
48
56
  raw: string;
@@ -89,6 +97,8 @@ class Parser {
89
97
  targetType: undefined,
90
98
  only_warn: false,
91
99
  parent: undefined,
100
+ hooks: {},
101
+ adv_hooks: {},
92
102
  isFileCallback: (f) => {
93
103
  if (!fs.existsSync(f)) return false;
94
104
  return fs.readFileSync(f, "utf-8") + "\n";
@@ -237,13 +247,27 @@ class Parser {
237
247
  const link = this.titleId(title);
238
248
 
239
249
  let __line =
240
- hor.repeat(Math.max(sec.level - 1, 0)) + beg + `[${title}](#${link})`;
250
+ hor.repeat(Math.max(sec.level - 1, 0)) +
251
+ beg +
252
+ `[${title}](#${link})`;
241
253
 
242
254
  __blob.push(__line);
243
255
  });
244
256
  return __blob.join("\n");
245
257
  }
246
258
 
259
+ add_hook(name: string, hook: () => string) {
260
+ if (this.opts.hooks[name] != undefined)
261
+ throw new Error(`Hook ${name} already exists!`);
262
+ this.opts.hooks[name] = hook;
263
+ }
264
+
265
+ add_adv_hook(name: string, hook: (tree: HTMLElement) => HTMLElement) {
266
+ if (this.opts.hooks[name] != undefined)
267
+ throw new Error(`Hook ${name} already exists!`);
268
+ this.opts.adv_hooks[name] = hook;
269
+ }
270
+
247
271
  line_num_from_index(index: number) {
248
272
  return this.raw.substring(0, index).split("\n").length + 1;
249
273
  }
@@ -258,7 +282,7 @@ class Parser {
258
282
  /* output the parsed document to bundle */
259
283
  to(bundleName: string, callback: (fileName: string) => void) {
260
284
  const dir = path.dirname(bundleName);
261
- if (callback === undefined) callback = () => { };
285
+ if (callback === undefined) callback = () => {};
262
286
 
263
287
  if (!fs.existsSync(dir)) {
264
288
  fs.mkdirSync(dir, { recursive: true });
@@ -268,11 +292,11 @@ class Parser {
268
292
  this.get(TargetType.MARKDOWN, (blob) => {
269
293
  fs.writeFile(bundleName, blob, () => callback(bundleName));
270
294
  });
271
- }
272
-
273
- else {
295
+ } else {
274
296
  const htmlFileName = bundleName.replace(".md", ".html");
275
- fs.writeFile(htmlFileName, this.html(), () => callback(htmlFileName));
297
+ fs.writeFile(htmlFileName, this.html(), () =>
298
+ callback(htmlFileName)
299
+ );
276
300
  }
277
301
  }
278
302
 
@@ -301,7 +325,7 @@ class Parser {
301
325
  let blob = this.parse();
302
326
  this.opts.targetType = undefined;
303
327
  if (callback) callback(blob);
304
- return blob
328
+ return blob;
305
329
  } catch (error) {
306
330
  /* Compile a traceback of error */
307
331
  let traceback = "";
@@ -312,7 +336,9 @@ class Parser {
312
336
  traceback += `\n...on line ${p.line_num_from_index(
313
337
  error.match.index
314
338
  )} in ${p.file}`.grey(15);
315
- else traceback += `\n...on line ${p.line_num} in ${p.file}`.grey(15);
339
+ else
340
+ traceback +=
341
+ `\n...on line ${p.line_num} in ${p.file}`.grey(15);
316
342
  if (p.parent) p = p.parent;
317
343
  } while (p.parent);
318
344
 
@@ -353,7 +379,8 @@ marked.use({
353
379
  const id = args.filter((arg) => arg.startsWith("#"));
354
380
 
355
381
  const classNames = classes.map((c) => c.slice(1));
356
- const classText = classes.length > 0 ? `class="${classNames.join(" ")}"` : "";
382
+ const classText =
383
+ classes.length > 0 ? `class="${classNames.join(" ")}"` : "";
357
384
  const idText = id.length > 0 ? `id="${id[0].slice(1)}"` : "";
358
385
 
359
386
  /* remove the ending from the quote */
@@ -1,4 +1,3 @@
1
- const path = require("path");
2
1
  const util = require("./tester.test.js");
3
2
 
4
3
  describe("Basic features", () => {
@@ -1,5 +1,4 @@
1
1
  const util = require("./tester.test.js");
2
- const fs = require("fs");
3
2
 
4
3
  describe("Error handling", () => {
5
4
  it("should dissallow undefined templates", () => {
package/test/hooks.js CHANGED
@@ -2,7 +2,7 @@ const fs = require("fs");
2
2
 
3
3
  exports.mochaHooks = {
4
4
  beforeEach(done) {
5
- fs.rmdirSync("test/test-files", { recursive: true });
5
+ fs.rmSync("test/test-files", { recursive: true });
6
6
  fs.mkdirSync("test/test-files");
7
7
  done();
8
8
  },
@@ -0,0 +1,114 @@
1
+ const util = require("./tester.test.js");
2
+
3
+ describe("Use of markdown hooks for SSR", () => {
4
+ it("should allow a simple hook to be used", () => {
5
+ util.put("#mdhook<test>", "sample1.md");
6
+
7
+ const parser = new util.Parser("test/test-files/sample1.md");
8
+ parser.add_hook("test", () => "hello");
9
+ const output = parser.get();
10
+
11
+ util.assert.strictEqual(output, "hello\n\n");
12
+ });
13
+ it("should allow advanced hooks to be used", () => {
14
+ util.put(
15
+ "#mdadvhook<test>\n<b>Bold</b>\n<p>Paragraph</p>\n#mdendhook",
16
+ "sample1.md"
17
+ );
18
+
19
+ const replacer = (arg) => {
20
+ const elem = new util.html.HTMLElement("p", {});
21
+ elem.set_content("complete");
22
+ return elem;
23
+ };
24
+
25
+ const parser = new util.Parser("test/test-files/sample1.md");
26
+ parser.opts.allow_undefined = true;
27
+ parser.add_adv_hook("test", replacer);
28
+ const output = parser.get();
29
+
30
+ util.assert.strictEqual(output, "<p>complete</p>\n\n");
31
+ });
32
+ it("should allow for hooks to be used in HTML", () => {
33
+ util.put("<html><body>#mdhook<test></body></html>", "sample1.html");
34
+
35
+ const parser = new util.Parser("test/test-files/sample1.html");
36
+ parser.opts.allow_undefined = true;
37
+ parser.add_hook("test", () => "hello");
38
+ const output = parser.get();
39
+
40
+ util.assert.strictEqual(output, "<html><body>hello</body></html>\n\n");
41
+ });
42
+ it("should allow for hooks to be used in HTML with advanced hooks", () => {
43
+ util.put(
44
+ "<html><body>#mdadvhook<test>\n<b>Bold</b>\n<p>Paragraph</p>\n#mdendhook</body></html>",
45
+ "sample1.html"
46
+ );
47
+
48
+ const replacer = (arg) => {
49
+ const elem = new util.html.HTMLElement("p", {});
50
+ elem.set_content("complete");
51
+ return elem;
52
+ };
53
+
54
+ const parser = new util.Parser("test/test-files/sample1.html");
55
+ parser.opts.allow_undefined = true;
56
+ parser.add_adv_hook("test", replacer);
57
+ const output = parser.get();
58
+
59
+ util.assert.strictEqual(
60
+ output,
61
+ "<html><body><p>complete</p></body></html>\n\n"
62
+ );
63
+ });
64
+ it("should allow for extracting a node from the document as a template manually with ids", () => {
65
+ util.put(
66
+ `<html><body>#mdadvhook<template><name id="b"></name><class id="p"></class>#mdendhook</body></html>`,
67
+ "sample1.html"
68
+ );
69
+
70
+ const replacer = (elem) => {
71
+ const nameElem = elem.getElementsByTagName("name")[0];
72
+ nameElem.tagName = nameElem.id;
73
+ nameElem.removeAttribute("id");
74
+ nameElem.set_content("bold");
75
+ const classElem = elem.getElementsByTagName("class")[0];
76
+ classElem.tagName = classElem.id;
77
+ classElem.removeAttribute("id");
78
+ classElem.set_content("paragraph");
79
+ return elem;
80
+ };
81
+
82
+ const parser = new util.Parser("test/test-files/sample1.html");
83
+ parser.opts.allow_undefined = true;
84
+ parser.add_adv_hook("template", replacer);
85
+ const output = parser.get();
86
+
87
+ util.assert.strictEqual(
88
+ output,
89
+ "<html><body><b>bold</b><p>paragraph</p></body></html>\n\n"
90
+ );
91
+ });
92
+ it("should allow for extracting a node from the document as a template using map and data-tags", () => {
93
+ util.put(
94
+ `<html><body>#mdadvhook<template><name data-tag="b"></name><class data-tag="p"></class>#mdendhook</body></html>`,
95
+ "sample1.html"
96
+ );
97
+
98
+ const replacer = (elem, map) => {
99
+ map["name"].set_content("bold");
100
+ map["class"].set_content("paragraph");
101
+ return elem;
102
+ };
103
+
104
+ const parser = new util.Parser("test/test-files/sample1.html");
105
+ parser.opts.allow_undefined = true;
106
+ parser.add_adv_hook("template", replacer);
107
+ const output = parser.get();
108
+
109
+ util.assert.strictEqual(
110
+ output,
111
+ "<html><body><b>bold</b><p>paragraph</p></body></html>\n\n"
112
+ );
113
+ });
114
+ });
package/test/line.test.js CHANGED
@@ -3,7 +3,7 @@ const util = require("./tester.test");
3
3
  describe("Managing blank lines", () => {
4
4
  it("should always end with 2 blank lines, even with no input", () => {
5
5
  const output = new util.Parser("").get();
6
- util.assert.strictEqual(output, "\n\n")
6
+ util.assert.strictEqual(output, "\n\n");
7
7
  });
8
8
 
9
9
  it("should reduce blank lines to 2", () => {
@@ -16,8 +16,6 @@ describe("Managing blank lines", () => {
16
16
 
17
17
  it("should allow words when removing blank lines", () => {
18
18
  const output = new util.Parser("hii\n\n\n").get();
19
- util.assert.strictEqual(output, "hii\n\n")
19
+ util.assert.strictEqual(output, "hii\n\n");
20
20
  });
21
21
  });
22
-
23
-
@@ -1,35 +1,43 @@
1
1
  const util = require("./tester.test.js");
2
2
 
3
3
  describe("Target specific functionality", () => {
4
-
5
- describe("HTML", () => {
6
- it("Should include `#mdlabel` command, when compiling HTML", () => {
7
- const parser = new util.Parser("#mdlabel<0,Cool!>");
8
- const html = parser.get(util.TargetType.HTML);
9
-
10
- util.assert.strictEqual(html, '<span id="cool"></span>\n\n')
11
- });
12
-
13
- it("Should link to sections with #mdref", () => {
14
- const parser = new util.Parser("#mdlabel<0,Cool!>\n#mdlabel<1,coolzz>\n#mdref<Cool!>");
15
- const html = parser.get(util.TargetType.HTML);
16
-
17
- util.assert.strictEqual(html, '<span id="cool"></span>\n<span id="coolzz"></span>\n<a href="#cool">Cool!</a>\n\n');
18
- })
19
- });
20
-
21
- describe("Markdown", () => {
22
- it("Should not include `#mdlabel` command, when compiling Markdown", () => {
23
- const parser = new util.Parser("#mdlabel<0,Cool!>");
24
-
25
- const md = parser.get(util.TargetType.MARKDOWN);
26
- util.assert.strictEqual(md, '\n\n')
27
- });
28
- it("Should include #mdref to title elements in markdown", () => {
29
- const output = new util.Parser("# Some Title!\n#mdref<Some Title!>").get();
30
-
31
- util.assert.strictEqual(output, '# Some Title!\n[Some Title!](#some-title)\n\n')
32
- });
33
-
34
- })
35
- });
4
+ describe("HTML", () => {
5
+ it("Should include `#mdlabel` command, when compiling HTML", () => {
6
+ const parser = new util.Parser("#mdlabel<0,Cool!>");
7
+ const html = parser.get(util.TargetType.HTML);
8
+
9
+ util.assert.strictEqual(html, '<span id="cool"></span>\n\n');
10
+ });
11
+
12
+ it("Should link to sections with #mdref", () => {
13
+ const parser = new util.Parser(
14
+ "#mdlabel<0,Cool!>\n#mdlabel<1,coolzz>\n#mdref<Cool!>"
15
+ );
16
+ const html = parser.get(util.TargetType.HTML);
17
+
18
+ util.assert.strictEqual(
19
+ html,
20
+ '<span id="cool"></span>\n<span id="coolzz"></span>\n<a href="#cool">Cool!</a>\n\n'
21
+ );
22
+ });
23
+ });
24
+
25
+ describe("Markdown", () => {
26
+ it("Should not include `#mdlabel` command, when compiling Markdown", () => {
27
+ const parser = new util.Parser("#mdlabel<0,Cool!>");
28
+
29
+ const md = parser.get(util.TargetType.MARKDOWN);
30
+ util.assert.strictEqual(md, "\n\n");
31
+ });
32
+ it("Should include #mdref to title elements in markdown", () => {
33
+ const output = new util.Parser(
34
+ "# Some Title!\n#mdref<Some Title!>"
35
+ ).get();
36
+
37
+ util.assert.strictEqual(
38
+ output,
39
+ "# Some Title!\n[Some Title!](#some-title)\n\n"
40
+ );
41
+ });
42
+ });
43
+ });
@@ -2,6 +2,7 @@ const fs = require("fs");
2
2
  const assert = require("assert");
3
3
  const Parser = require("../build/parse");
4
4
  const path = require("path");
5
+ const html = require("node-html-parser");
5
6
 
6
7
  /* make folder for temporary files, if it doesn't exist */
7
8
  if (
@@ -29,8 +30,9 @@ const TargetType = {
29
30
  };
30
31
 
31
32
  module.exports = {
32
- fs,
33
33
  assert,
34
+ fs,
35
+ html,
34
36
  path,
35
37
  Parser,
36
38
  put,
package/test/vars.test.js CHANGED
@@ -1,57 +1,49 @@
1
- const util = require("./tester.test");
1
+ const util = require("./tester.test.js");
2
2
 
3
3
  describe("Use variables", () => {
4
- it('should replace var with the value', () => {
4
+ it("should replace var with the value", () => {
5
5
  const output = new util.Parser("#mddef<hi=yo>\n#mdvar<hi>").get();
6
6
 
7
- util.assert.strictEqual(output, "\nyo\n\n")
7
+ util.assert.strictEqual(output, "\nyo\n\n");
8
8
  });
9
- it('should use variable shorthand', () => {
9
+ it("should use variable shorthand", () => {
10
10
  const output = new util.Parser("#mddef<hi=yo>\n<hi>").get();
11
11
 
12
- util.assert.strictEqual(output, "\nyo\n\n")
12
+ util.assert.strictEqual(output, "\nyo\n\n");
13
13
  });
14
- it('should use variables across files', () => {
14
+ it("should use variables across files", () => {
15
15
  util.put("#mddef<hi=yo>\n#mdinclude<sample2.md>", "sample1.md");
16
16
  util.put("<hi>", "sample2.md");
17
17
 
18
18
  const output = new util.Parser("test/test-files/sample1.md").get();
19
19
 
20
- util.assert.strictEqual(output, "\nyo\n\n")
21
- })
22
- it('should throw if undefined variable', () => {
23
-
20
+ util.assert.strictEqual(output, "\nyo\n\n");
21
+ });
22
+ it("should throw if undefined variable", () => {
24
23
  const parser = new util.Parser("<yo>");
25
24
 
26
25
  let e;
27
26
  /* should throw an error */
28
- util.assert.throws(
29
- () => {
30
- try {
31
- parser.get();
32
- } catch (_e) {
33
- e = _e;
34
- throw _e;
35
- }
27
+ util.assert.throws(() => {
28
+ try {
29
+ parser.get();
30
+ } catch (_e) {
31
+ e = _e;
32
+ throw _e;
36
33
  }
37
- );
38
-
39
-
40
-
34
+ });
41
35
  });
42
36
 
43
- it('should preserve whatever comes after', () => {
37
+ it("should preserve whatever comes after", () => {
44
38
  const output = new util.Parser("#mddef<hi=yo>\n<hi>,").get();
45
39
  util.assert.strictEqual(output, "\nyo,\n\n");
46
40
  });
47
41
 
48
- it('should replace underscore with space', () => {
49
- const output = new util.Parser("#mddef<name=Mr_Sir>\n#mdvar<name>").get();
42
+ it("should replace underscore with space", () => {
43
+ const output = new util.Parser(
44
+ "#mddef<name=Mr_Sir>\n#mdvar<name>"
45
+ ).get();
50
46
 
51
- util.assert.strictEqual(output, "\nMr Sir\n\n")
47
+ util.assert.strictEqual(output, "\nMr Sir\n\n");
52
48
  });
53
-
54
49
  });
55
-
56
-
57
-
package/build/cltool.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare const argParser: any;