markdown-maker 1.10.0 → 1.10.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.
@@ -4,31 +4,13 @@
4
4
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
5
  "version": "0.2.0",
6
6
  "configurations": [
7
- {
8
- "name": "Compile main",
9
- "request": "launch",
10
- "runtimeArgs": [
11
- "run-script",
12
- "main"
13
- ],
14
- "runtimeExecutable": "npm",
15
- "skipFiles": [
16
- "<node_internals>/**"
17
- ],
18
- "type": "pwa-node"
19
- },
20
7
  {
21
8
  "name": "Run test",
22
9
  "request": "launch",
23
- "runtimeArgs": [
24
- "run-script",
25
- "test"
26
- ],
10
+ "runtimeArgs": ["run-script", "test"],
27
11
  "runtimeExecutable": "npm",
28
- "skipFiles": [
29
- "<node_internals>/**"
30
- ],
31
- "type": "pwa-node"
12
+ "skipFiles": ["<node_internals>/**"],
13
+ "type": "node"
32
14
  }
33
15
  ]
34
- }
16
+ }
package/package.json CHANGED
@@ -1,64 +1,41 @@
1
1
  {
2
2
  "name": "markdown-maker",
3
- "version": "1.10.0",
4
- "description": "",
5
- "main": "src/cltool.ts",
3
+ "version": "1.10.2",
4
+ "description": "A superset-compiler for markdown using marked",
5
+ "main": "src/main.ts",
6
6
  "bin": {
7
- "mdparse": "build/cltool.js"
8
- },
9
- "pkg": {
10
- "assets": [
11
- "node_modules/argparse/*",
12
- "node_modules/chokidar/*",
13
- "node_modules/colors/*",
14
- "node_modules/colors./*",
15
- "node_modules/marked/*",
16
- "build/cltool.js",
17
- "src/templates/*"
18
- ],
19
- "targets": [
20
- "node12-macos-x64",
21
- "node12-win-x64",
22
- "node12-linux-x64"
23
- ]
7
+ "mdparse": "bundle/main.js"
24
8
  },
25
9
  "scripts": {
26
10
  "test": "mocha --require test/hooks.js",
27
11
  "test:yarn": "mocha",
28
12
  "bundle": "tsc --project tsconfig.json",
29
- "main": "node build/cltool.js document/main.md -o dist/bundle.md --debug",
30
- "debug": "node src/cltool.js -db document/main.md -o dist/bundle.md",
31
- "build": "npm run bundle && pkg --output bin/mdparse .",
32
- "build:yarn": "yarn bundle && pkg --output bin/mdparse .",
33
- "clear": "rm -rf dist",
34
- "premac-deploy": "npm run build",
35
- "mac-deploy": "mv bin/mdparse-macos ~/Documents/commands/mdparse",
36
- "prewin-deploy": "npm run build",
37
- "win-deploy": "mv bin/mdparse-win.exe ../../commands/mdparse.exe",
13
+ "main": "node bundle/main.js document/main.md -o dist/bundle.md --debug",
14
+ "debug": "node src/main.js -db document/main.md -o dist/bundle.md",
15
+ "clear": "rm -rf bundle bin",
38
16
  "pretest": "npm run bundle",
39
- "pretest:yarn": "yarn bundle",
40
- "prepare": "npm run build"
17
+ "pretest:yarn": "yarn bundle"
41
18
  },
42
19
  "keywords": [],
43
20
  "author": "blitzher",
44
21
  "license": "MIT",
45
22
  "dependencies": {
46
- "@types/chokidar": "^2.1.3",
47
- "@types/colors": "^1.2.1",
48
- "@types/node": "^15.6.1",
49
- "@types/ws": "^8.5.3",
50
23
  "argparse": "^2.0.1",
51
24
  "chokidar": "^3.5.1",
52
- "colors": "^1.4.0",
53
25
  "colors.ts": "^1.0.20",
54
26
  "marked": "^2.0.1",
27
+ "node-html-parser": "^6.1.13",
55
28
  "require-runtime": "^2.0.0",
56
29
  "ws": "^8.8.1"
57
30
  },
58
31
  "devDependencies": {
32
+ "@types/argparse": "^2.0.16",
33
+ "@types/chokidar": "^2.1.3",
34
+ "@types/colors": "^1.2.1",
35
+ "@types/node": "^15.6.1",
36
+ "@types/ws": "^8.5.3",
59
37
  "cloc": "^2.7.0",
60
38
  "mocha": "^8.3.1",
61
- "pkg": "^4.4.9",
62
39
  "prettier": "^2.3.0",
63
40
  "typescript": "^4.3.2"
64
41
  }
package/src/cltool.ts CHANGED
@@ -2,21 +2,19 @@ const fs = require("fs"); /* for handling reading of files */
2
2
  const path = require("path"); /* for handling file paths */
3
3
 
4
4
  import Colors = require("colors.ts"); /* for adding colours to strings */
5
- import Parser from "./parse";
6
- import { WebSocketServer } from "ws";
5
+ import { TargetType } from "./commands";
6
+ import Parser from "./parser";
7
7
 
8
8
  Colors.enable();
9
- const { ArgumentParser } = require("argparse"); /* for parsing clargs */
9
+ import { ArgumentParser } from "argparse"; /* for parsing clargs */
10
10
  const { version } = require("../package.json"); /* package version number */
11
- const choki = require("chokidar");
12
11
 
13
12
  export const argParser = new ArgumentParser({
14
- description: "Markdown bundler, with extra options. Extension file is loaded from ./extensions.js, if it exists",
13
+ description:
14
+ "Markdown bundler, with extra options. Extension file is loaded from ./extensions.js, if it exists",
15
15
  prog: "mdparse",
16
16
  });
17
17
 
18
- const configFileName = ".mdmconfig.json";
19
-
20
18
  //#region command line args
21
19
  argParser.add_argument("src", {
22
20
  help: "file to be parsed. If this is a directory, it looks for entry point in the directory, see --entry",
@@ -66,103 +64,47 @@ argParser.add_argument("--allow-undefined", "-A", {
66
64
  });
67
65
  //#endregion
68
66
 
69
- function main() {
70
- let clargs, fileargs;
71
- let server: WebSocketServer | undefined;
72
-
73
- /* Read config file or parse args from cmd-line */
74
- if (fs.existsSync(configFileName)) {
75
- let data: { [key: string]: string | boolean | number } = JSON.parse(fs.readFileSync(configFileName)).opts;
76
-
77
- let args: (string | number)[] = [];
78
- Object.entries(data).forEach(([key, value]) => {
79
- if (key != "src" && value !== false) {
80
- args.push("--" + key);
81
- }
82
- if (typeof value != "boolean") {
83
- args.push(value);
84
- }
85
- });
86
-
87
- /* We skip [0] and [1], as it is the binary and source file, even when compiled*/
88
- for (let i = 2; i < process.argv.length; i++) args.push(process.argv[i]);
89
-
90
- clargs = argParser.parse_args(args);
91
- } else {
92
- clargs = argParser.parse_args();
93
- }
94
-
95
- /* if src is init, create config file and exit */
96
- if (clargs.src == "init") {
97
- const template = fs.readFileSync(path.join(__dirname, "..", "src", "templates", "configTemplate.json"));
98
- fs.writeFileSync(configFileName, template);
99
- fs.writeFileSync("main.md", "# Main\n");
100
- return;
101
- }
102
-
103
- /* helper method for calling parser */
104
- const compile = (source, output, cb?) => {
105
- /* load data from file, if it exists,
106
- * otherwise, interpret as string */
107
-
108
- const parser = new Parser(source, clargs);
109
- parser.to(output, (file) => {
110
- console.log(`Compiled ${file}`.green);
111
- if (cb) cb();
112
- });
113
- return parser;
67
+ export type CLArgs = {
68
+ src: string;
69
+ output: string;
70
+ verbose: boolean;
71
+ debug: boolean;
72
+ max_depth: number;
73
+ entry: string;
74
+ watch: boolean;
75
+ use_underscore: boolean;
76
+ toc_level: number;
77
+ html: boolean;
78
+ allow_undefined: boolean;
79
+ };
80
+
81
+ export type ParserOptions = {
82
+ defs: {
83
+ [key: string]: string;
114
84
  };
115
-
116
- const internalCooldown = 1000;
117
- function watcher(event, path) {
118
- const now = Date.now();
119
-
120
- if (!this.time) this.time = now;
121
-
122
- if (now - this.time < internalCooldown) return;
123
-
124
- console.log(path);
125
-
126
- console.log(`Detected change in ${path}...`);
127
-
128
- try {
129
- compile(clargs.src, clargs.output, () => {
130
- /* after compile, send refresh command to clients */
131
- server.clients.forEach((client) => {
132
- if (client.OPEN) client.send("refresh");
133
- });
134
- });
135
- } catch (e) {
136
- console.log(e.message);
137
- }
138
-
139
- this.time = now;
140
- }
141
-
142
- /* in case source is a directory, look for entry in directory */
143
- if (fs.existsSync(clargs.src) && fs.lstatSync(clargs.src).isDirectory()) {
144
- clargs.src = path.join(clargs.src, clargs.entry);
145
- }
146
-
147
- if (clargs.debug) console.dir(clargs);
148
-
149
- /* compile once */
150
- if (!clargs.watch) compile(clargs.src, clargs.output);
151
- /* watch the folder and recompile on change */
152
- else {
153
- const srcDirName = path.dirname(clargs.src);
154
- console.log(`Watching ${srcDirName} for changes...`.yellow);
155
- server = new WebSocketServer({ port: 7788 });
156
-
157
- const _watcher = choki.watch(srcDirName).on("all", watcher);
158
- try {
159
- compile(clargs.src, clargs.output);
160
- } catch (e) {
161
- console.log(e.message);
162
- }
163
- }
164
-
165
- }
166
-
167
- /* main entrypoint */
168
- if (require.main === module) main();
85
+ secs: {
86
+ level: number;
87
+ title: string;
88
+ }[];
89
+ args: string[];
90
+ depth: number;
91
+ verbose: boolean;
92
+ debug: boolean;
93
+ max_depth: number;
94
+ use_underscore: boolean;
95
+ toc_level: number;
96
+ allow_undefined: boolean;
97
+ html: boolean;
98
+ watch: boolean;
99
+ targetType: TargetType | undefined;
100
+ only_warn: boolean;
101
+ parent?: Parser;
102
+ hooks: { [key: string]: () => string };
103
+ adv_hooks: {
104
+ [key: string]: (
105
+ tree: HTMLElement,
106
+ map: { [tag: string]: HTMLElement }
107
+ ) => HTMLElement;
108
+ };
109
+ isFileCallback: (s: string) => false | string;
110
+ };
package/src/commands.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as path from "path";
2
- import Parser from "./parse";
2
+ import Parser from "./parser";
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;
@@ -128,7 +129,7 @@ new Command(
128
129
 
129
130
  const recursiveParser = new Parser(
130
131
  path.join(parser.wd, name),
131
- parser.opts,
132
+ parser.clargs,
132
133
  {
133
134
  parent: parser,
134
135
  }
@@ -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/main.ts ADDED
@@ -0,0 +1,122 @@
1
+ import path from "path";
2
+ import { WebSocketServer } from "ws";
3
+ import Parser from "./parser";
4
+ import * as fs from "fs";
5
+ const choki = require("chokidar");
6
+
7
+ import { argParser, CLArgs as CommmandLineArgs, ParserOptions } from "./cltool";
8
+ const configFileName = ".mdmconfig.json";
9
+
10
+ function main() {
11
+ let clargs: CommmandLineArgs;
12
+ let server: WebSocketServer | undefined;
13
+
14
+ /* Read config file or parse args from cmd-line */
15
+ if (fs.existsSync(configFileName)) {
16
+ let data: CommmandLineArgs = JSON.parse(
17
+ fs.readFileSync(configFileName).toString()
18
+ ).opts;
19
+
20
+ let args: (string | number)[] = [];
21
+ Object.entries(data).forEach(([key, value]) => {
22
+ if (key != "src" && value !== false) {
23
+ args.push("--" + key);
24
+ }
25
+ if (typeof value != "boolean") {
26
+ args.push(value);
27
+ }
28
+ });
29
+
30
+ /* We skip [0] and [1], as it is the binary and source file, even when compiled*/
31
+ for (let i = 2; i < process.argv.length; i++)
32
+ args.push(process.argv[i]);
33
+
34
+ clargs = argParser.parse_args(args.map((x) => x.toString()));
35
+ } else {
36
+ clargs = argParser.parse_args();
37
+ }
38
+
39
+ /* if src is init, create config file and exit */
40
+ if (clargs.src == "init") {
41
+ const template = fs.readFileSync(
42
+ path.join(
43
+ __dirname,
44
+ "..",
45
+ "src",
46
+ "templates",
47
+ "configTemplate.json"
48
+ )
49
+ );
50
+ fs.writeFileSync(configFileName, template);
51
+ fs.writeFileSync("main.md", "# Main\n");
52
+ return;
53
+ }
54
+
55
+ /* helper method for calling parser */
56
+ const compile = (source, output, cb?) => {
57
+ /* load data from file, if it exists,
58
+ * otherwise, interpret as string */
59
+
60
+ const parser = new Parser(source, clargs);
61
+ parser.to(output, (file) => {
62
+ console.log(`Compiled ${file}`.green);
63
+ if (cb) cb();
64
+ });
65
+ return parser;
66
+ };
67
+
68
+ const internalCooldown = 1000;
69
+ function watcher(event, path) {
70
+ const now = Date.now();
71
+
72
+ if (!this.time) this.time = now;
73
+
74
+ if (now - this.time < internalCooldown) return;
75
+
76
+ console.log(path);
77
+
78
+ console.log(`Detected change in ${path}...`);
79
+
80
+ try {
81
+ compile(clargs.src, clargs.output, () => {
82
+ /* after compile, send refresh command to clients */
83
+ server.clients.forEach((client) => {
84
+ if (client.OPEN) client.send("refresh");
85
+ });
86
+ });
87
+ } catch (e) {
88
+ console.log(e.message);
89
+ }
90
+
91
+ this.time = now;
92
+ }
93
+
94
+ /* in case source is a directory, look for entry in directory */
95
+ if (fs.existsSync(clargs.src) && fs.lstatSync(clargs.src).isDirectory()) {
96
+ clargs.src = path.join(clargs.src, clargs.entry);
97
+ }
98
+
99
+ if (clargs.debug) console.dir(clargs);
100
+
101
+ /* compile once */
102
+ if (!clargs.watch) compile(clargs.src, clargs.output);
103
+ /* watch the folder and recompile on change */ else {
104
+ const srcDirName = path.dirname(clargs.src);
105
+ console.log(`Watching ${srcDirName} for changes...`.yellow);
106
+ server = new WebSocketServer({ port: 7788 });
107
+
108
+ const _watcher = choki.watch(srcDirName).on("all", watcher);
109
+ try {
110
+ compile(clargs.src, clargs.output);
111
+ } catch (e) {
112
+ console.log(e.message);
113
+ }
114
+ }
115
+ }
116
+ export default {
117
+ Parser,
118
+ };
119
+ /* main entrypoint */
120
+ if (require.main === module) {
121
+ main();
122
+ }
@@ -1,10 +1,12 @@
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";
9
+ import { argParser, CLArgs as CommandLineArgs, ParserOptions } from "./cltool";
8
10
 
9
11
  enum TargetType {
10
12
  HTML,
@@ -22,36 +24,15 @@ class Parser {
22
24
  blobs: {
23
25
  [key: number]: string | undefined;
24
26
  };
25
- opts: {
26
- defs: {
27
- [key: string]: string;
28
- };
29
- secs: {
30
- level: number;
31
- title: string;
32
- }[];
33
- args: string[];
34
- depth: number;
35
- verbose: boolean;
36
- debug: boolean;
37
- max_depth: number;
38
- use_underscore: boolean;
39
- toc_level: number;
40
- allow_undefined: boolean;
41
- html: boolean;
42
- watch: boolean;
43
- targetType: TargetType | undefined;
44
- only_warn: boolean;
45
- parent?: Parser;
46
- isFileCallback: (s: string) => false | string;
47
- };
27
+ opts: ParserOptions;
28
+ clargs: CommandLineArgs;
48
29
  raw: string;
49
30
 
50
31
  static TOKEN = "#md";
51
32
 
52
33
  constructor(
53
- filename,
54
- clargs,
34
+ filename: string,
35
+ clargs?: CommandLineArgs,
55
36
  opts?: {
56
37
  parent?: Parser;
57
38
  isFileCallback?: (s: string) => false | string;
@@ -73,6 +54,7 @@ class Parser {
73
54
  this.blobs = {};
74
55
 
75
56
  /* all options */
57
+ this.clargs = clargs;
76
58
  this.opts = {
77
59
  defs: {},
78
60
  secs: [],
@@ -89,6 +71,8 @@ class Parser {
89
71
  targetType: undefined,
90
72
  only_warn: false,
91
73
  parent: undefined,
74
+ hooks: {},
75
+ adv_hooks: {},
92
76
  isFileCallback: (f) => {
93
77
  if (!fs.existsSync(f)) return false;
94
78
  return fs.readFileSync(f, "utf-8") + "\n";
@@ -96,7 +80,7 @@ class Parser {
96
80
  };
97
81
 
98
82
  if (!clargs) {
99
- clargs = {};
83
+ clargs = argParser.parse_args([filename]);
100
84
  }
101
85
 
102
86
  /* append all commandline arguments to this */
@@ -237,13 +221,27 @@ class Parser {
237
221
  const link = this.titleId(title);
238
222
 
239
223
  let __line =
240
- hor.repeat(Math.max(sec.level - 1, 0)) + beg + `[${title}](#${link})`;
224
+ hor.repeat(Math.max(sec.level - 1, 0)) +
225
+ beg +
226
+ `[${title}](#${link})`;
241
227
 
242
228
  __blob.push(__line);
243
229
  });
244
230
  return __blob.join("\n");
245
231
  }
246
232
 
233
+ add_hook(name: string, hook: () => string) {
234
+ if (this.opts.hooks[name] != undefined)
235
+ throw new Error(`Hook ${name} already exists!`);
236
+ this.opts.hooks[name] = hook;
237
+ }
238
+
239
+ add_adv_hook(name: string, hook: (tree: HTMLElement) => HTMLElement) {
240
+ if (this.opts.hooks[name] != undefined)
241
+ throw new Error(`Hook ${name} already exists!`);
242
+ this.opts.adv_hooks[name] = hook;
243
+ }
244
+
247
245
  line_num_from_index(index: number) {
248
246
  return this.raw.substring(0, index).split("\n").length + 1;
249
247
  }
@@ -258,7 +256,7 @@ class Parser {
258
256
  /* output the parsed document to bundle */
259
257
  to(bundleName: string, callback: (fileName: string) => void) {
260
258
  const dir = path.dirname(bundleName);
261
- if (callback === undefined) callback = () => { };
259
+ if (callback === undefined) callback = () => {};
262
260
 
263
261
  if (!fs.existsSync(dir)) {
264
262
  fs.mkdirSync(dir, { recursive: true });
@@ -268,11 +266,11 @@ class Parser {
268
266
  this.get(TargetType.MARKDOWN, (blob) => {
269
267
  fs.writeFile(bundleName, blob, () => callback(bundleName));
270
268
  });
271
- }
272
-
273
- else {
269
+ } else {
274
270
  const htmlFileName = bundleName.replace(".md", ".html");
275
- fs.writeFile(htmlFileName, this.html(), () => callback(htmlFileName));
271
+ fs.writeFile(htmlFileName, this.html(), () =>
272
+ callback(htmlFileName)
273
+ );
276
274
  }
277
275
  }
278
276
 
@@ -301,7 +299,7 @@ class Parser {
301
299
  let blob = this.parse();
302
300
  this.opts.targetType = undefined;
303
301
  if (callback) callback(blob);
304
- return blob
302
+ return blob;
305
303
  } catch (error) {
306
304
  /* Compile a traceback of error */
307
305
  let traceback = "";
@@ -312,7 +310,9 @@ class Parser {
312
310
  traceback += `\n...on line ${p.line_num_from_index(
313
311
  error.match.index
314
312
  )} in ${p.file}`.grey(15);
315
- else traceback += `\n...on line ${p.line_num} in ${p.file}`.grey(15);
313
+ else
314
+ traceback +=
315
+ `\n...on line ${p.line_num} in ${p.file}`.grey(15);
316
316
  if (p.parent) p = p.parent;
317
317
  } while (p.parent);
318
318
 
@@ -353,7 +353,8 @@ marked.use({
353
353
  const id = args.filter((arg) => arg.startsWith("#"));
354
354
 
355
355
  const classNames = classes.map((c) => c.slice(1));
356
- const classText = classes.length > 0 ? `class="${classNames.join(" ")}"` : "";
356
+ const classText =
357
+ classes.length > 0 ? `class="${classNames.join(" ")}"` : "";
357
358
  const idText = id.length > 0 ? `id="${id[0].slice(1)}"` : "";
358
359
 
359
360
  /* remove the ending from the quote */
@@ -10,7 +10,6 @@ const putTemplate = () => {
10
10
  describe("Use of templates", () => {
11
11
  beforeEach(putTemplate);
12
12
  it("should import presentation template as expected", () => {
13
- putTemplate();
14
13
  const output = new util.Parser("#mdtemplate<presentation>").get();
15
14
  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>`;
16
15
 
@@ -18,7 +17,6 @@ describe("Use of templates", () => {
18
17
  });
19
18
 
20
19
  it("should use custom templates from project extensions.js file", () => {
21
- putTemplate();
22
20
  util.put("#mdtemplate<hi>", "sample1.md");
23
21
 
24
22
  util.assert.strictEqual(
@@ -28,7 +26,6 @@ describe("Use of templates", () => {
28
26
  });
29
27
 
30
28
  it("should use custom commands from project extensions.js file", () => {
31
- putTemplate();
32
29
  util.put("#test_cmd", "sample1.md");
33
30
 
34
31
  const parser = new util.Parser("test/test-files/sample1.md");