markdown-maker 1.7.11 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
package/src/parse.ts CHANGED
@@ -4,7 +4,7 @@ const path = require("path"); /* for handling file paths */
4
4
  import Colors = require("colors.ts"); /* for adding colours to strings */
5
5
  Colors.enable();
6
6
  const marked = require("marked");
7
- const commands = require("./commands.js");
7
+ import { Command, commands, load_extensions, MDMError } from "./commands";
8
8
 
9
9
  enum TargetType {
10
10
  HTML,
@@ -18,6 +18,7 @@ class Parser {
18
18
  parent?: Parser;
19
19
  line_num: number;
20
20
  wd: string;
21
+ wd_full: string;
21
22
  blobs: {
22
23
  [key: number]: string | undefined;
23
24
  };
@@ -36,8 +37,9 @@ class Parser {
36
37
  max_depth: number;
37
38
  use_underscore: boolean;
38
39
  toc_level: number;
39
- allow_undef: boolean;
40
+ allow_undefined: boolean;
40
41
  html: boolean;
42
+ watch: boolean;
41
43
  targetType: TargetType | undefined;
42
44
  only_warn: boolean;
43
45
  parent?: Parser;
@@ -53,7 +55,7 @@ class Parser {
53
55
  opts?: {
54
56
  parent?: Parser;
55
57
  isFileCallback?: (s: string) => false | string;
56
- }
58
+ },
57
59
  ) {
58
60
  /* this.working_directory */
59
61
  this.file = filename;
@@ -65,6 +67,7 @@ class Parser {
65
67
 
66
68
  this.line_num = 0;
67
69
  this.wd = path.dirname(filename);
70
+ this.wd_full = path.resolve(this.wd);
68
71
 
69
72
  /* finished blob */
70
73
  this.blobs = {};
@@ -80,8 +83,9 @@ class Parser {
80
83
  max_depth: 5,
81
84
  use_underscore: false,
82
85
  toc_level: 3,
83
- allow_undef: false,
86
+ allow_undefined: false,
84
87
  html: false,
88
+ watch: false,
85
89
  targetType: undefined,
86
90
  only_warn: false,
87
91
  parent: undefined,
@@ -107,12 +111,13 @@ class Parser {
107
111
  * preprocessing, parsing and postprocess
108
112
  **/
109
113
  parse() {
114
+ load_extensions(this);
110
115
  if (this.opts.verbose || this.opts.debug) {
111
116
  console.log(
112
117
  Colors.colors(
113
118
  "magenta",
114
- "parsing " + this.file + ": depth=" + this.opts.depth
115
- )
119
+ "parsing " + this.file + ": depth=" + this.opts.depth,
120
+ ),
116
121
  );
117
122
  }
118
123
 
@@ -138,11 +143,10 @@ class Parser {
138
143
  return __blob;
139
144
  }
140
145
 
141
- mainparse(blob) {
146
+ mainparse(blob: string) {
142
147
  if (this.opts.verbose || this.opts.debug) {
143
148
  console.debug(`beginning mainparse of '${this.file}'`.blue);
144
149
  }
145
- let __blob = "";
146
150
 
147
151
  /* main parser instance loop */
148
152
  blob.split("\n").forEach((line, lnum) => {
@@ -157,17 +161,7 @@ class Parser {
157
161
 
158
162
  /* implement toc level */
159
163
  let level = titleMatch[1].length;
160
-
161
- /**
162
- * parse elements of title
163
- * such as variables */
164
- let title = titleMatch[2]
165
- .trim()
166
- .split(" ")
167
- .map((s) =>
168
- s.startsWith(Parser.TOKEN) ? this.parseToken(s) : s
169
- )
170
- .join("_");
164
+ let title = titleMatch[2];
171
165
 
172
166
  this.opts.secs.push({ level, title });
173
167
 
@@ -175,101 +169,49 @@ class Parser {
175
169
  console.log("updated sections:", { level, title });
176
170
  }
177
171
  }
178
-
179
- let __line_tokens = [];
180
- /* split line into tokens */
181
- line.split(" ").forEach((token) => {
182
- /* if token is not #md token,
183
- * just add it and continue */
184
- if (token.startsWith(Parser.TOKEN)) {
185
- token = this.parseToken(token);
186
- }
187
-
188
- __line_tokens.push(token);
189
- });
190
- /* put line back properly */
191
- __blob += __line_tokens.join(" ") + "\n";
192
172
  });
193
173
 
194
- return __blob;
174
+ return this.parse_commands(blob, commands.parse);
195
175
  }
196
176
 
197
- parseToken(token) {
198
- /* iterate over all commands,
199
- * and if command is valid, execute it */
200
-
201
- if (this.opts.verbose || this.opts.debug)
202
- console.log("found mdtoken: " + token);
203
-
204
- for (let i = 0; i < commands.parse.length; i++) {
205
- const command = commands.parse[i];
206
-
207
- if (command.valid(token, this)) {
208
- return command.act(token, this);
209
- }
210
- }
211
-
212
- /* check if the command is for later */
213
- for (let i = 0; i < commands.postparse.length; i++) {
214
- const command = commands.postparse[i];
215
-
216
- if (command.valid(token, this)) {
217
- return token;
218
- }
219
- }
220
-
221
- throw new SyntaxError(`Unknown token: ${token}`);
222
- }
223
-
224
- preprocess(blob) {
177
+ preprocess(blob: string) {
225
178
  if (this.opts.verbose || this.opts.debug) {
226
179
  console.debug(`beginning preprocess of '${this.file}'`.blue);
227
180
  }
228
- let __blob = "";
229
- const lines = blob.split("\n");
230
-
231
- lines.forEach((line) => {
232
- let __line_tokens = [];
233
- line.split(" ").forEach((token) => {
234
- for (const command of commands.preparse) {
235
- if (command.valid(token, this)) {
236
- token = command.act(token, this);
237
- }
238
- }
239
181
 
240
- __line_tokens.push(token);
241
- });
242
- __blob += __line_tokens.join(" ") + "\n";
243
- });
244
- return __blob;
182
+ return this.parse_commands(blob, commands.preparse);
245
183
  }
246
184
 
247
- postprocess(blob) {
185
+ postprocess(blob: string) {
248
186
  if (this.opts.verbose || this.opts.debug) {
249
187
  console.debug(`beginning postprocess of '${this.file}'`.blue);
250
188
  }
251
- let __blob = "";
252
- const lines = blob.split("\n");
253
-
254
- lines.forEach((line) => {
255
- let __line_tokens = [];
256
- line.split(" ").forEach((token) => {
257
- // only look
258
-
259
- for (const command of commands.postparse) {
260
- if (command.valid(token, this)) {
261
- token = command.act(token, this);
262
- }
263
- }
264
189
 
265
- __line_tokens.push(token);
266
- });
267
- __blob += __line_tokens.join(" ") + "\n";
268
- });
190
+ blob = this.parse_commands(blob, commands.postparse);
269
191
 
270
192
  /* remove double empty lines */
271
- __blob = this.remove_double_blank_lines(__blob);
272
- return __blob;
193
+ blob = this.remove_double_blank_lines(blob);
194
+ blob = blob.trimEnd() + "\n\n";
195
+ return blob;
196
+ }
197
+
198
+ parse_commands(blob: string, commands: Command[]) {
199
+ commands.forEach((command) => {
200
+ /* Add global flag to RegExp */
201
+ const re = new RegExp(
202
+ command.validator.source,
203
+ (command.validator.flags || "") + "g",
204
+ );
205
+ blob = blob.replace(re, (...args) => command.act(args, this) || "");
206
+ });
207
+ return blob;
208
+ }
209
+
210
+ parse_all_commands(blob: string, commands: { [key: string]: Command[] }) {
211
+ Object.keys(commands).forEach((key) => {
212
+ blob = this.parse_commands(blob, commands[key]);
213
+ });
214
+ return blob;
273
215
  }
274
216
 
275
217
  titleId(title: string) {
@@ -290,18 +232,24 @@ class Parser {
290
232
 
291
233
  this.opts.secs.forEach((sec) => {
292
234
  if (sec.level > this.opts.toc_level) return;
293
- const link = this.titleId(sec.title);
294
- const title = sec.title.replace(/_/g, " ");
235
+ let title = sec.title.replace(/_/g, " ");
236
+ title = this.parse_all_commands(title, commands);
237
+ const link = this.titleId(title);
295
238
 
296
239
  let __line =
297
240
  hor.repeat(Math.max(sec.level - 1, 0)) +
298
241
  beg +
299
242
  `[${title}](#${link})`;
243
+
300
244
  __blob.push(__line);
301
245
  });
302
246
  return __blob.join("\n");
303
247
  }
304
248
 
249
+ line_num_from_index(index: number) {
250
+ return this.raw.substring(0, index).split("\n").length + 1;
251
+ }
252
+
305
253
  remove_double_blank_lines(blob) {
306
254
  /* replace all triple newlines, and EOF by double newline */
307
255
  blob = blob.replace(/(\r\n|\n){3,}/g, "\n\n");
@@ -310,25 +258,27 @@ class Parser {
310
258
  }
311
259
 
312
260
  /* output the parsed document to bundle */
313
- to(bundleName, cb) {
261
+ to(bundleName: string, callback: (fileName: string) => void) {
314
262
  const dir = path.dirname(bundleName);
315
263
  var called = false;
316
- if (!cb) cb = () => {};
264
+ if (callback === undefined) callback = () => {};
317
265
 
318
266
  if (!fs.existsSync(dir)) {
319
267
  fs.mkdirSync(dir);
320
268
  }
321
269
  this.get(TargetType.MARKDOWN, (blob) => {
322
270
  fs.writeFile(bundleName, blob, () => {
323
- if (!called) cb(bundleName);
324
- called = true;
271
+ if (!this.opts.html) {
272
+ callback(bundleName);
273
+ called = true;
274
+ }
325
275
  });
326
276
  });
327
277
 
328
278
  if (this.opts.html) {
329
279
  const htmlFileName = bundleName.replace(".md", ".html");
330
280
  fs.writeFile(htmlFileName, this.html(), () => {
331
- if (!called) cb(htmlFileName);
281
+ if (!called) callback(htmlFileName);
332
282
  called = true;
333
283
  });
334
284
  }
@@ -336,13 +286,18 @@ class Parser {
336
286
 
337
287
  html() {
338
288
  const htmlFormatted = marked(this.get(TargetType.HTML));
339
-
289
+ if (this.opts.watch) {
290
+ return (
291
+ `<script>w=new WebSocket("ws:localhost:7788");w.addEventListener("message",(e)=>{if(e.data=="refresh")location.reload();});</script>\n` +
292
+ htmlFormatted
293
+ );
294
+ }
340
295
  return htmlFormatted;
341
296
  }
342
297
 
343
- get(targetType: TargetType, callback?) {
298
+ get(targetType?: TargetType, callback?) {
344
299
  /* If target type is undefined, markdown is the default */
345
- if (targetType == undefined) targetType = TargetType.MARKDOWN;
300
+ if (targetType === undefined) targetType = TargetType.MARKDOWN;
346
301
  if (this.blobs[targetType]) {
347
302
  if (callback) {
348
303
  callback(this.blobs[targetType]);
@@ -361,9 +316,13 @@ class Parser {
361
316
  let p: Parser = this;
362
317
 
363
318
  do {
364
- traceback += `\n...on line ${p.line_num + 1} in ${
365
- p.file
366
- }`.grey(15);
319
+ if (error instanceof MDMError)
320
+ traceback += `\n...on line ${p.line_num_from_index(
321
+ error.match.index,
322
+ )} in ${p.file}`.grey(15);
323
+ else
324
+ traceback +=
325
+ `\n...on line ${p.line_num} in ${p.file}`.grey(15);
367
326
  if (p.parent) p = p.parent;
368
327
  } while (p.parent);
369
328
 
@@ -379,6 +338,43 @@ class Parser {
379
338
  }
380
339
  }
381
340
 
341
+ export function splice(
342
+ str: string,
343
+ startIndex: number,
344
+ width: number,
345
+ newSubStr: string,
346
+ ) {
347
+ const start = str.slice(0, startIndex);
348
+ const end = str.slice(startIndex + width);
349
+ return start + newSubStr + end;
350
+ }
351
+
352
+ /* add extention to marked */
353
+ marked.use({
354
+ renderer: {
355
+ blockquote(quote) {
356
+ /* find the ending, and if not, return the default */
357
+ const ending = quote.match(/\{(.+)\}\s*<\/p>/);
358
+ if (!ending) return `<blockquote>${quote}</blockquote>`;
359
+
360
+ const args = ending[1].split(" ");
361
+
362
+ const classes = args.filter((arg) => arg.startsWith("."));
363
+ const id = args.filter((arg) => arg.startsWith("#"));
364
+
365
+ const classNames = classes.map((c) => c.slice(1));
366
+ const classText =
367
+ classes.length > 0 ? `class="${classNames.join(" ")}"` : "";
368
+ const idText = id.length > 0 ? `id="${id[0].slice(1)}"` : "";
369
+
370
+ /* remove the ending from the quote */
371
+ quote = quote.replace(/\{(.+)\}\s*<\/p>/, "</p>");
372
+
373
+ return `<blockquote ${classText} ${idText}>\n${quote.trim()}</blockquote>`;
374
+ },
375
+ },
376
+ });
377
+
382
378
  module.exports = Parser;
383
379
 
384
380
  export default Parser;
@@ -0,0 +1,3 @@
1
+ const template = `<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script><script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>`;
2
+
3
+ module.exports = template;
@@ -0,0 +1,3 @@
1
+ const template = `<style>html {width: 100vw;height: 100vh;}.slide {padding: 5%;border-radius: 25px;margin: 0;}div > .slide-num {position: absolute;top: 12.5%;right: 15%;/* font-size: 150%; */}body {margin: 5% 15%;}img {max-width: 100%;max-height: 40vh;}</style><script>document.addEventListener("DOMContentLoaded", () => {let current_slide = 0;const all_slides = document.querySelectorAll("div.slide");const num_slides = all_slides.length;all_slides.forEach((slide) => {const num_elem = document.createElement("p");num_elem.classList.add("slide-num");slide.appendChild(num_elem);});onkeydown = (ev) => {if (ev.key == "ArrowRight" && current_slide < all_slides.length - 1)update_slide(++current_slide);else if (ev.key == "ArrowLeft" && current_slide > 0)update_slide(--current_slide);};const update_slide = (index) => {all_slides.forEach((slide) => (slide.style.display = "none"));all_slides[current_slide].style.display = "block";all_slides[current_slide].lastChild.textContent = \`\${current_slide + 1} / \${num_slides}\`;};update_slide(current_slide);});</script>`;
2
+
3
+ module.exports = template;
@@ -0,0 +1,18 @@
1
+ const templates: { [key: string]: string } = {};
2
+
3
+ /**
4
+ * Function to add a template to the templates object. Similar to definitions and variables, but reside as an extension.
5
+ * @param name The name of the template
6
+ * @param content The replacement string
7
+ */
8
+ export function new_template(name: string, content: string) {
9
+ templates[name] = content;
10
+ }
11
+
12
+ /* initialize default templates */
13
+ const presentation_template = require("../src/templates/presentation.js");
14
+ const mathjax_template = require("../src/templates/mathjax.js");
15
+ new_template("presentation", presentation_template);
16
+ new_template("mathjax", mathjax_template);
17
+
18
+ export default templates;
@@ -0,0 +1,35 @@
1
+ const util = require("./tester.test.js");
2
+
3
+ util.put(
4
+ "module.exports = {main: (new_template, new_command) => {new_template('hi', 'hello'); new_command(/#test_cmd/, (t,p) => 'yeet', 0);}};",
5
+ "extensions.js"
6
+ );
7
+
8
+ describe("Use of templates", () => {
9
+ it("should import presentation template as expected", () => {
10
+ const output = new util.Parser("#mdtemplate<presentation>").get();
11
+ const template = `<style>html {width: 100vw;height: 100vh;}.slide {padding: 5%;border-radius: 25px;margin: 0;}div > .slide-num {position: absolute;top: 12.5%;right: 15%;/* font-size: 150%; */}body {margin: 5% 15%;}img {max-width: 100%;max-height: 40vh;}</style><script>document.addEventListener("DOMContentLoaded", () => {let current_slide = 0;const all_slides = document.querySelectorAll("div.slide");const num_slides = all_slides.length;all_slides.forEach((slide) => {const num_elem = document.createElement("p");num_elem.classList.add("slide-num");slide.appendChild(num_elem);});onkeydown = (ev) => {if (ev.key == "ArrowRight" && current_slide < all_slides.length - 1)update_slide(++current_slide);else if (ev.key == "ArrowLeft" && current_slide > 0)update_slide(--current_slide);};const update_slide = (index) => {all_slides.forEach((slide) => (slide.style.display = "none"));all_slides[current_slide].style.display = "block";all_slides[current_slide].lastChild.textContent = \`\${current_slide + 1} / \${num_slides}\`;};update_slide(current_slide);});</script>`;
12
+
13
+ util.assert.strictEqual(output, template + "\n\n");
14
+ });
15
+
16
+ it("should use custom templates from project extensions.js file", () => {
17
+ util.put("#mdtemplate<hi>", "sample1.md");
18
+
19
+ util.assert.strictEqual(
20
+ new util.Parser("test/test-files/sample1.md").get(),
21
+ "hello\n\n"
22
+ );
23
+
24
+ /* make sure to remove after, to not mess with future tests */
25
+ });
26
+
27
+ it("should use custom commands from project extensions.js file", () => {
28
+ util.put("#test_cmd", "sample1.md");
29
+
30
+ const parser = new util.Parser("test/test-files/sample1.md");
31
+ util.assert.strictEqual(parser.get(), "yeet\n\n");
32
+
33
+ /* make sure to remove after, to not mess with future tests */
34
+ });
35
+ });
@@ -1,11 +1,6 @@
1
1
  const util = require("./tester.test.js");
2
2
 
3
3
  describe("Basic features", () => {
4
- it("should raise an error if invalid token", () => {
5
- util.assert.throws(() => {
6
- const output = new util.Parser("#mdNON<>").get();
7
- }, SyntaxError);
8
- });
9
4
  it("should join two files with include", () => {
10
5
  util.put("hello\n#mdinclude<sample2.md>", "sample1.md");
11
6
  util.put("there", "sample2.md");
@@ -35,12 +30,12 @@ describe("Basic features", () => {
35
30
  );
36
31
  });
37
32
  it("should allow variables in toc", () => {
38
- const parser = new util.Parser(
39
- "#mddef<name=Foobar>\n# mr. #mdvar<name>\n#mdmaketoc<>"
40
- );
33
+ const output = new util.Parser(
34
+ "#mddef<name= Foobar>\n# mr. #mdvar<name>\n#mdmaketoc<>"
35
+ ).get();
41
36
 
42
37
  util.assert.strictEqual(
43
- parser.get(),
38
+ output,
44
39
  "\n# mr. Foobar\n* [mr. Foobar](#mr-foobar)\n\n"
45
40
  );
46
41
  });
@@ -20,14 +20,14 @@ describe("Command Line Arguments", () => {
20
20
  });
21
21
  it("--allow-undef should not throw when variable is not defined", () => {
22
22
  const output = new util.Parser("#mdvar<zum>", {
23
- allow_undef: true,
23
+ allow_undefined: true,
24
24
  }).get();
25
25
 
26
26
  util.assert.strictEqual(output, "<zum>\n\n");
27
27
  });
28
28
  describe("Conditional imports", () => {
29
29
  it("should be able to conditionally import documents", () => {
30
- util.put("hello\n#mdinclude<sample2.md,YES>", "sample1.md");
30
+ util.put("hello\n#mdinclude<sample2.md, YES>", "sample1.md");
31
31
  util.put("there", "sample2.md");
32
32
 
33
33
  const parser = new util.Parser("test/test-files/sample1.md");
@@ -1,65 +1,26 @@
1
+ const { Parser } = require("marked");
1
2
  const util = require("./tester.test.js");
2
3
 
3
4
  describe("Error handling", () => {
4
- it("should provide basic traceback", () => {
5
- util.put("hi there\n\n\n#mdNON\n\n", "sample1.md");
5
+ it("should dissallow undefined templates", () => {
6
+ util.put("#mdtemplate<UNDEF>", "sample1.md");
6
7
 
7
8
  const parser = new util.Parser("test/test-files/sample1.md");
8
9
 
9
10
  let e;
10
- /* should throw an error */
11
- util.assert.throws(
12
- () => {
13
- try {
14
- parser.get();
15
- } catch (_e) {
16
- e = _e;
17
- throw _e;
18
- }
11
+ util.assert.throws(() => {
12
+ try {
13
+ parser.get();
14
+ } catch (_e) {
15
+ e = _e;
16
+ throw _e;
19
17
  }
20
- )
18
+ }, Error);
21
19
 
22
- /**
23
- * ..and error message should provide
24
- * info as to where the error occured
25
- */
26
- util.assert.strictEqual(
27
- e.message,
28
- "Unknown token: #mdNON" +
29
- "\n...on line 4 in test/test-files/sample1.md".grey(15)
30
- )
20
+ let answer =
21
+ 'Template "UNDEF" not found!' +
22
+ "\n...on line 1 in test/test-files/sample1.md".grey(15);
31
23
 
32
- });
33
- it("should traceback across file includes", () => {
34
- util.put("\n#mdinclude<sample2.md>", "sample1.md");
35
- util.put("#mdNON", "sample2.md");
36
-
37
- const parser = new util.Parser("test/test-files/sample1.md");
38
-
39
- let e;
40
-
41
- /* should throw SyntaxError */
42
- util.assert.throws(
43
- /* run parser, but store error for further inspection */
44
- () => {
45
- try {
46
- parser.get();
47
- } catch (_e) {
48
- e = _e;
49
- throw _e;
50
- }
51
- },
52
- SyntaxError
53
- );
54
-
55
- /* ...where the error message is the traceback on line 2 -> */
56
- let answer = "Unknown token: #mdNON" +
57
- "\n...on line 1 in test/test-files/sample2.md".grey(15) +
58
- "\n...on line 2 in test/test-files/sample1.md".grey(15);
59
-
60
- util.assert.strictEqual(
61
- e.message.replace(/(\\)+/g, "/"),
62
- answer
63
- );
24
+ util.assert.strictEqual(e.message.replace(/(\\)+/g, "/"), answer);
64
25
  });
65
26
  });
@@ -0,0 +1,43 @@
1
+ const util = require("./tester.test.js");
2
+
3
+ describe("Marked extentions", () => {
4
+ it("should add a single class to blockquotes", () => {
5
+ const parser = new util.Parser("> hello {.one}", {
6
+ use_underscore: true,
7
+ html: true,
8
+ });
9
+
10
+ const output = parser.html();
11
+
12
+ util.assert.strictEqual(
13
+ output,
14
+ '<blockquote class="one" >\n<p>hello </p></blockquote>'
15
+ );
16
+ });
17
+ it("should add multiple class to blockquotes", () => {
18
+ const parser = new util.Parser("> hello {.one .two}", {
19
+ use_underscore: true,
20
+ html: true,
21
+ });
22
+
23
+ const output = parser.html();
24
+
25
+ util.assert.strictEqual(
26
+ output,
27
+ '<blockquote class="one two" >\n<p>hello </p></blockquote>'
28
+ );
29
+ });
30
+ it("should add a single class and id to blockquotes", () => {
31
+ const parser = new util.Parser("> hello {.one #myid}", {
32
+ use_underscore: true,
33
+ html: true,
34
+ });
35
+
36
+ const output = parser.html();
37
+
38
+ util.assert.strictEqual(
39
+ output,
40
+ '<blockquote class="one" id="myid">\n<p>hello </p></blockquote>'
41
+ );
42
+ });
43
+ });
@@ -26,11 +26,9 @@ describe("Target specific functionality", () => {
26
26
  util.assert.strictEqual(md, '\n\n')
27
27
  });
28
28
  it("Should include #mdref to title elements in markdown", () => {
29
- const parser = new util.Parser("# Some Title!\n#mdref<Some_Title!>");
29
+ const output = new util.Parser("# Some Title!\n#mdref<Some Title!>").get();
30
30
 
31
- const md = parser.get(util.TargetType.MARKDOWN);
32
-
33
- util.assert.strictEqual(md, '# Some Title!\n[Some Title!](#some-title)\n\n')
31
+ util.assert.strictEqual(output, '# Some Title!\n[Some Title!](#some-title)\n\n')
34
32
  });
35
33
 
36
34
  })
@@ -1,28 +1,30 @@
1
- const fs = require('fs');
2
- const assert = require('assert');
3
- const Parser = require('../build/parse');
1
+ const fs = require("fs");
2
+ const assert = require("assert");
3
+ const Parser = require("../build/parse");
4
+
5
+
4
6
 
5
7
  /* make folder for temporary files, if it doesn't exist */
6
8
  if (
7
- !fs.existsSync('test/test-files') ||
8
- !fs.lstatSync('test/test-files').isDirectory()
9
+ !fs.existsSync("test/test-files") ||
10
+ !fs.lstatSync("test/test-files").isDirectory()
9
11
  ) {
10
- fs.mkdirSync('test/test-files');
12
+ fs.mkdirSync("test/test-files");
11
13
  }
12
14
 
13
15
  function put(text, file) {
14
- fs.writeFileSync('test/test-files/' + file, text);
16
+ fs.writeFileSync("test/test-files/" + file, text);
15
17
  }
16
18
 
17
19
  const TargetType = {
18
- HTML: 0,
19
- MARKDOWN: 1,
20
+ HTML: 0,
21
+ MARKDOWN: 1,
20
22
  };
21
23
 
22
24
  module.exports = {
23
- fs,
24
- assert,
25
- Parser,
26
- put,
27
- TargetType,
25
+ fs,
26
+ assert,
27
+ Parser,
28
+ put,
29
+ TargetType,
28
30
  };