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/.github/workflows/node.js.yml +13 -8
- package/README.md +1 -0
- package/doc/.mdmconfig.json +3 -2
- package/package.json +9 -7
- package/prettierrc.yaml +1 -1
- package/re-test.js +10 -0
- package/src/cltool.ts +35 -22
- package/src/commands.ts +145 -73
- package/src/parse.ts +107 -111
- package/src/templates/mathjax.js +3 -0
- package/src/templates/presentation.js +3 -0
- package/src/templates.ts +18 -0
- package/test/advanced.test.js +35 -0
- package/test/basic.test.js +4 -9
- package/test/clargs.test.js +2 -2
- package/test/errors.test.js +14 -53
- package/test/marked.test.js +43 -0
- package/test/target.test.js +2 -4
- package/test/tester.test.js +16 -14
- package/tsconfig.json +1 -1
- package/argparsetest.js +0 -11
- package/build/cltool.d.ts +0 -1
- package/build/cltool.js +0 -141
- package/build/commands.d.ts +0 -9
- package/build/commands.js +0 -140
- package/build/parse.d.ts +0 -57
- package/build/parse.js +0 -298
package/tsconfig.json
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
|
15
15
|
"declaration": true /* Generates corresponding '.d.ts' file. */,
|
16
16
|
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
17
|
-
|
17
|
+
"sourceMap": true, /* Generates corresponding '.map' file. */
|
18
18
|
// "outFile": "./", /* Concatenate and emit output to single file. */
|
19
19
|
"outDir": "./build" /* Redirect output structure to the directory. */,
|
20
20
|
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
package/argparsetest.js
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
const { ArgumentParser } = require("argparse");
|
2
|
-
const argParser = new ArgumentParser();
|
3
|
-
|
4
|
-
argParser.add_argument("src");
|
5
|
-
argParser.add_argument("-o", "--output");
|
6
|
-
|
7
|
-
console.log(process.argv);
|
8
|
-
|
9
|
-
const args = argParser.parse_args(["-o", "output", "hi"]);
|
10
|
-
|
11
|
-
console.log(args);
|
package/build/cltool.d.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export declare const argParser: any;
|
package/build/cltool.js
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.argParser = void 0;
|
7
|
-
var fs = require("fs"); /* for handling reading of files */
|
8
|
-
var path = require("path"); /* for handling file paths */
|
9
|
-
var Colors = require("colors.ts"); /* for adding colours to strings */
|
10
|
-
var parse_1 = __importDefault(require("./parse"));
|
11
|
-
Colors.enable();
|
12
|
-
var ArgumentParser = require("argparse").ArgumentParser; /* for parsing clargs */
|
13
|
-
var version = require("../package.json").version; /* package version number */
|
14
|
-
var choki = require("chokidar");
|
15
|
-
exports.argParser = new ArgumentParser({
|
16
|
-
description: "Markdown bundler, with extra options",
|
17
|
-
prog: process.argv[0].split(path.sep).pop(),
|
18
|
-
});
|
19
|
-
var configFileName = ".mdmconfig.json";
|
20
|
-
//#region command line args
|
21
|
-
exports.argParser.add_argument("src", {
|
22
|
-
help: "file to be parsed. If this is a directory, it looks for entry point in the directory, see --entry",
|
23
|
-
});
|
24
|
-
exports.argParser.add_argument("--version", { action: "version", version: version });
|
25
|
-
exports.argParser.add_argument("-v", "--verbose", {
|
26
|
-
action: "store_true",
|
27
|
-
help: "enable verbose output",
|
28
|
-
});
|
29
|
-
exports.argParser.add_argument("-db", "--debug", {
|
30
|
-
action: "store_true",
|
31
|
-
help: "enable debugging information",
|
32
|
-
});
|
33
|
-
exports.argParser.add_argument("-o", "--output", {
|
34
|
-
help: "destination of bundle, by default is 'dist/bundle.md'",
|
35
|
-
default: "dist/bundle.md",
|
36
|
-
});
|
37
|
-
exports.argParser.add_argument("-d", "--max-depth", {
|
38
|
-
help: "maximum recursion depth, by default is 15",
|
39
|
-
default: 15,
|
40
|
-
type: "int",
|
41
|
-
});
|
42
|
-
exports.argParser.add_argument("-e", "--entry", {
|
43
|
-
help: "assign entry point in directory, by default is 'main.md'",
|
44
|
-
default: "main.md",
|
45
|
-
});
|
46
|
-
exports.argParser.add_argument("-w", "--watch", {
|
47
|
-
action: "store_true",
|
48
|
-
help: "recompile after a change in target target file or directory.",
|
49
|
-
});
|
50
|
-
exports.argParser.add_argument("-uu", "--use-underscore", {
|
51
|
-
action: "store_true",
|
52
|
-
help: "set the parser to use '_' as seperator in ids for Table of Content. If the links in the table does not work, this is likely to be the issue.",
|
53
|
-
});
|
54
|
-
exports.argParser.add_argument("--toc-level", {
|
55
|
-
help: "the section level of the table of contents, by default is 3",
|
56
|
-
default: 3,
|
57
|
-
type: "int",
|
58
|
-
});
|
59
|
-
exports.argParser.add_argument("--html", {
|
60
|
-
action: "store_true",
|
61
|
-
help: "compile HTML from the parsed markdown",
|
62
|
-
});
|
63
|
-
exports.argParser.add_argument("--allow-undef", "-au", {
|
64
|
-
action: "store_true",
|
65
|
-
help: "allow undefined variables. Mostly useful for typing inline html tags, and other non-strictly markdown related uses",
|
66
|
-
});
|
67
|
-
//#endregion
|
68
|
-
function main() {
|
69
|
-
// var server: refreshServer | undefined;
|
70
|
-
var clargs;
|
71
|
-
if (fs.existsSync(configFileName)) {
|
72
|
-
var data = JSON.parse(fs.readFileSync(configFileName)).opts;
|
73
|
-
var args_1 = [];
|
74
|
-
Object.entries(data).forEach(function (_a) {
|
75
|
-
var key = _a[0], value = _a[1];
|
76
|
-
if (key != "src")
|
77
|
-
args_1.push("--" + key);
|
78
|
-
if (typeof value != "boolean")
|
79
|
-
args_1.push(value);
|
80
|
-
});
|
81
|
-
args_1.push(data.src);
|
82
|
-
exports.argParser.parse_args(args_1);
|
83
|
-
}
|
84
|
-
else
|
85
|
-
clargs = exports.argParser.parse_args();
|
86
|
-
/* helper method for calling parser */
|
87
|
-
var compile = function (source, output, cb) {
|
88
|
-
/* load data from file, if it exists,
|
89
|
-
* otherwise, interpret as string */
|
90
|
-
var parser = new parse_1.default(source, clargs);
|
91
|
-
parser.to(output, function (file) {
|
92
|
-
console.log(("Compiled " + file).green);
|
93
|
-
if (cb)
|
94
|
-
cb();
|
95
|
-
});
|
96
|
-
return parser;
|
97
|
-
};
|
98
|
-
var internalCooldown = 1000;
|
99
|
-
function watcher(event, path) {
|
100
|
-
var now = Date.now();
|
101
|
-
if (!this.time)
|
102
|
-
this.time = now;
|
103
|
-
if (now - this.time < internalCooldown)
|
104
|
-
return;
|
105
|
-
console.log(path);
|
106
|
-
console.log("Detected change in " + path + "...");
|
107
|
-
try {
|
108
|
-
compile(clargs.src, clargs.output, function () {
|
109
|
-
// if (server.refresh) server.refresh();
|
110
|
-
});
|
111
|
-
}
|
112
|
-
catch (e) {
|
113
|
-
console.log(e.message);
|
114
|
-
}
|
115
|
-
this.time = now;
|
116
|
-
}
|
117
|
-
/* in case source is a directory, look for entry in directory */
|
118
|
-
if (fs.existsSync(clargs.src) && fs.lstatSync(clargs.src).isDirectory()) {
|
119
|
-
clargs.src = path.join(clargs.src, clargs.entry);
|
120
|
-
}
|
121
|
-
var srcDirName = path.dirname(clargs.src);
|
122
|
-
if (clargs.debug)
|
123
|
-
console.dir(clargs);
|
124
|
-
if (!clargs.watch)
|
125
|
-
compile(clargs.src, clargs.output);
|
126
|
-
if (clargs.watch) {
|
127
|
-
/* watch the folder of entry */
|
128
|
-
// server = wsServer();
|
129
|
-
console.log(("Watching " + srcDirName + " for changes...").yellow);
|
130
|
-
var _watcher = choki.watch(srcDirName).on("all", watcher);
|
131
|
-
try {
|
132
|
-
compile(clargs.src, clargs.output);
|
133
|
-
}
|
134
|
-
catch (e) {
|
135
|
-
console.log(e.message);
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}
|
139
|
-
/* main entrypoint */
|
140
|
-
if (require.main === module)
|
141
|
-
main();
|
package/build/commands.d.ts
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
import Parser from "./parse";
|
2
|
-
export declare class Command {
|
3
|
-
type: number;
|
4
|
-
validator: (token: string, parser: Parser) => boolean | RegExpMatchArray;
|
5
|
-
acter: (token: string, parser: Parser) => string | void;
|
6
|
-
constructor(type: any, validator: (token: string, parser: Parser) => boolean | RegExpMatchArray, acter: (token: string, parser: Parser) => string | void);
|
7
|
-
valid(token: any, parser: any): boolean | RegExpMatchArray;
|
8
|
-
act(token: any, parser: any): string | void;
|
9
|
-
}
|
package/build/commands.js
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
-
if (k2 === undefined) k2 = k;
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
-
}) : (function(o, m, k, k2) {
|
6
|
-
if (k2 === undefined) k2 = k;
|
7
|
-
o[k2] = m[k];
|
8
|
-
}));
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11
|
-
}) : function(o, v) {
|
12
|
-
o["default"] = v;
|
13
|
-
});
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
15
|
-
if (mod && mod.__esModule) return mod;
|
16
|
-
var result = {};
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18
|
-
__setModuleDefault(result, mod);
|
19
|
-
return result;
|
20
|
-
};
|
21
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
22
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
23
|
-
};
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
25
|
-
exports.Command = void 0;
|
26
|
-
var path = __importStar(require("path"));
|
27
|
-
var parse_1 = __importDefault(require("./parse"));
|
28
|
-
var commands = {
|
29
|
-
preparse: [],
|
30
|
-
parse: [],
|
31
|
-
postparse: [],
|
32
|
-
};
|
33
|
-
var CommandType = {
|
34
|
-
PREPARSE: 0,
|
35
|
-
PARSE: 1,
|
36
|
-
POSTPARSE: 2,
|
37
|
-
};
|
38
|
-
var TargetType;
|
39
|
-
(function (TargetType) {
|
40
|
-
TargetType[TargetType["HTML"] = 0] = "HTML";
|
41
|
-
TargetType[TargetType["MARKDOWN"] = 1] = "MARKDOWN";
|
42
|
-
})(TargetType || (TargetType = {}));
|
43
|
-
var Command = /** @class */ (function () {
|
44
|
-
function Command(type, validator, acter) {
|
45
|
-
this.type = type;
|
46
|
-
this.validator = validator;
|
47
|
-
this.acter = acter;
|
48
|
-
/* add this function to appropriate file */
|
49
|
-
switch (type) {
|
50
|
-
case CommandType.PARSE:
|
51
|
-
commands.parse.push(this);
|
52
|
-
break;
|
53
|
-
case CommandType.PREPARSE:
|
54
|
-
commands.preparse.push(this);
|
55
|
-
break;
|
56
|
-
case CommandType.POSTPARSE:
|
57
|
-
commands.postparse.push(this);
|
58
|
-
break;
|
59
|
-
}
|
60
|
-
}
|
61
|
-
Command.prototype.valid = function (token, parser) {
|
62
|
-
return this.validator(token, parser);
|
63
|
-
};
|
64
|
-
Command.prototype.act = function (token, parser) {
|
65
|
-
return this.acter(token, parser);
|
66
|
-
};
|
67
|
-
return Command;
|
68
|
-
}());
|
69
|
-
exports.Command = Command;
|
70
|
-
/* variable shorthand */
|
71
|
-
new Command(CommandType.PREPARSE, function (t, p) { return t.match(/(?:\s|^)<\w+>/); }, function (t, p) { return "#mdvar" + t; });
|
72
|
-
/* mddef */
|
73
|
-
new Command(CommandType.PARSE, function (t, p) { return t.match(/^#mddef<(\w+)=(\w+)>/); }, function (t, p) {
|
74
|
-
var m = t.match(/^#mddef<(\w+)=(\w+)>/);
|
75
|
-
p.opts.defs[m[1]] = m[2];
|
76
|
-
});
|
77
|
-
/* mdvar */
|
78
|
-
new Command(CommandType.PARSE, function (t, p) { return t.match(/^#mdvar<(\w+)>/) || t.match(/^<(\w+)>/); }, function (t, p) {
|
79
|
-
var match = t.match(/#mdvar<(\w+)>/);
|
80
|
-
var value = p.opts.defs[match[1]];
|
81
|
-
if (!value && !p.opts.allow_undef)
|
82
|
-
throw new Error("Undefined variable: " + match[1]);
|
83
|
-
value = value || "<" + match[1] + ">";
|
84
|
-
return t.replace(match[0], value.replace("_", " "));
|
85
|
-
});
|
86
|
-
/** mdinclude */
|
87
|
-
new Command(CommandType.PARSE, function (t, p) { return t.match(/^#mdinclude<([\w.\/-]+)(?:[,\s]+([\w]+))?>/); }, function (t, p) {
|
88
|
-
/* increase the current recursive depth */
|
89
|
-
p.opts.depth++;
|
90
|
-
if (p.opts.depth > p.opts.max_depth) {
|
91
|
-
throw new Error("max depth exceeded!");
|
92
|
-
}
|
93
|
-
/* get the matching group */
|
94
|
-
var match = t.match(/^#mdinclude<([\w.\/-]+)(?:[,\s]+([\w]+))?>/);
|
95
|
-
var _ = match[0], name = match[1], condition = match[2];
|
96
|
-
/* implement conditional imports */
|
97
|
-
if (condition && !p.opts.args.includes(condition))
|
98
|
-
return;
|
99
|
-
var recursiveParser = new parse_1.default(path.join(p.wd, name), p.opts, {
|
100
|
-
parent: p,
|
101
|
-
});
|
102
|
-
/* keep the options the same */
|
103
|
-
recursiveParser.opts = p.opts;
|
104
|
-
recursiveParser.parent = p;
|
105
|
-
var fileType = path.extname(recursiveParser.file);
|
106
|
-
var blob = fileType === ".md"
|
107
|
-
? recursiveParser.get(p.opts.targetType)
|
108
|
-
: recursiveParser.raw;
|
109
|
-
p.opts.depth--;
|
110
|
-
return blob;
|
111
|
-
});
|
112
|
-
new Command(CommandType.PREPARSE, function (t, p) { return t.match(/#mdlabel<(\d+),([\w\W]+)>/); }, function (t, p) {
|
113
|
-
if (p.opts.targetType !== TargetType.HTML)
|
114
|
-
return;
|
115
|
-
var match = t.match(/#mdlabel<([\d]+),([\w\W]+)>/);
|
116
|
-
var level = Number.parseInt(match[1]);
|
117
|
-
var title = match[2];
|
118
|
-
var link = p.titleId(title);
|
119
|
-
p.opts.secs.push({ level: level, title: title });
|
120
|
-
return "<span id=\"" + link + "\"></span>";
|
121
|
-
});
|
122
|
-
/* mdref */
|
123
|
-
new Command(CommandType.PARSE, function (t, p) { return t.match(/#mdref<([\w\W]+)>/); }, function (t, p) {
|
124
|
-
var match = t.match(/#mdref<([\w\W]+)>/);
|
125
|
-
for (var i = 0; i < p.opts.secs.length; i++) {
|
126
|
-
var title = p.opts.secs[i].title;
|
127
|
-
if (title === match[1])
|
128
|
-
break;
|
129
|
-
if (i === p.opts.secs.length - 1)
|
130
|
-
throw new Error("Reference to [" + match[1] + "] could not be resolved!");
|
131
|
-
}
|
132
|
-
match[1] = match[1].replace("_", " ");
|
133
|
-
var link = p.titleId(match[1]);
|
134
|
-
if (p.opts.targetType === TargetType.HTML)
|
135
|
-
return "<a href=\"#" + link + "\">" + match[1] + "</a>";
|
136
|
-
else if (p.opts.targetType === TargetType.MARKDOWN)
|
137
|
-
return "[" + match[1] + "](#" + link + ")";
|
138
|
-
});
|
139
|
-
new Command(CommandType.POSTPARSE, function (t, p) { return t.match(/#mdmaketoc/); }, function (t, p) { return p.gen_toc(); });
|
140
|
-
module.exports = commands;
|
package/build/parse.d.ts
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
declare enum TargetType {
|
2
|
-
HTML = 0,
|
3
|
-
MARKDOWN = 1
|
4
|
-
}
|
5
|
-
declare class Parser {
|
6
|
-
file: string;
|
7
|
-
parent?: Parser;
|
8
|
-
line_num: number;
|
9
|
-
wd: string;
|
10
|
-
blobs: {
|
11
|
-
[key: number]: string | undefined;
|
12
|
-
};
|
13
|
-
opts: {
|
14
|
-
defs: {
|
15
|
-
[key: string]: string;
|
16
|
-
};
|
17
|
-
secs: {
|
18
|
-
level: number;
|
19
|
-
title: string;
|
20
|
-
}[];
|
21
|
-
args: string[];
|
22
|
-
depth: number;
|
23
|
-
verbose: boolean;
|
24
|
-
debug: boolean;
|
25
|
-
max_depth: number;
|
26
|
-
use_underscore: boolean;
|
27
|
-
toc_level: number;
|
28
|
-
allow_undef: boolean;
|
29
|
-
html: boolean;
|
30
|
-
targetType: TargetType | undefined;
|
31
|
-
only_warn: boolean;
|
32
|
-
parent?: Parser;
|
33
|
-
isFileCallback: (s: string) => false | string;
|
34
|
-
};
|
35
|
-
raw: string;
|
36
|
-
static TOKEN: string;
|
37
|
-
constructor(filename: any, clargs: any, opts?: {
|
38
|
-
parent?: Parser;
|
39
|
-
isFileCallback?: (s: string) => false | string;
|
40
|
-
});
|
41
|
-
/**
|
42
|
-
* parse wrapper for handling
|
43
|
-
* preprocessing, parsing and postprocess
|
44
|
-
**/
|
45
|
-
parse(): any;
|
46
|
-
mainparse(blob: any): string;
|
47
|
-
parseToken(token: any): any;
|
48
|
-
preprocess(blob: any): string;
|
49
|
-
postprocess(blob: any): string;
|
50
|
-
titleId(title: string): string;
|
51
|
-
gen_toc(): string;
|
52
|
-
remove_double_blank_lines(blob: any): any;
|
53
|
-
to(bundleName: any, cb: any): void;
|
54
|
-
html(): any;
|
55
|
-
get(targetType: TargetType, callback?: any): any;
|
56
|
-
}
|
57
|
-
export default Parser;
|
package/build/parse.js
DELETED
@@ -1,298 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
var fs = require("fs"); /* for handling reading of files */
|
4
|
-
var path = require("path"); /* for handling file paths */
|
5
|
-
var Colors = require("colors.ts"); /* for adding colours to strings */
|
6
|
-
Colors.enable();
|
7
|
-
var marked = require("marked");
|
8
|
-
var commands = require("./commands.js");
|
9
|
-
var TargetType;
|
10
|
-
(function (TargetType) {
|
11
|
-
TargetType[TargetType["HTML"] = 0] = "HTML";
|
12
|
-
TargetType[TargetType["MARKDOWN"] = 1] = "MARKDOWN";
|
13
|
-
})(TargetType || (TargetType = {}));
|
14
|
-
/* parse some md
|
15
|
-
* recursively with extra options */
|
16
|
-
var Parser = /** @class */ (function () {
|
17
|
-
function Parser(filename, clargs, opts) {
|
18
|
-
/* this.working_directory */
|
19
|
-
this.file = filename;
|
20
|
-
if (!opts)
|
21
|
-
opts = {};
|
22
|
-
/* the parent parser */
|
23
|
-
this.parent = opts.parent;
|
24
|
-
this.line_num = 0;
|
25
|
-
this.wd = path.dirname(filename);
|
26
|
-
/* finished blob */
|
27
|
-
this.blobs = {};
|
28
|
-
/* all options */
|
29
|
-
this.opts = {
|
30
|
-
defs: {},
|
31
|
-
secs: [],
|
32
|
-
args: [],
|
33
|
-
depth: 0,
|
34
|
-
verbose: false,
|
35
|
-
debug: false,
|
36
|
-
max_depth: 5,
|
37
|
-
use_underscore: false,
|
38
|
-
toc_level: 3,
|
39
|
-
allow_undef: false,
|
40
|
-
html: false,
|
41
|
-
targetType: undefined,
|
42
|
-
only_warn: false,
|
43
|
-
parent: undefined,
|
44
|
-
isFileCallback: function (f) {
|
45
|
-
if (!fs.existsSync(f))
|
46
|
-
return false;
|
47
|
-
return fs.readFileSync(f, "utf-8") + "\n";
|
48
|
-
},
|
49
|
-
};
|
50
|
-
if (!clargs) {
|
51
|
-
clargs = {};
|
52
|
-
}
|
53
|
-
/* append all commandline arguments to this */
|
54
|
-
Object.assign(this.opts, clargs);
|
55
|
-
Object.assign(this.opts, opts);
|
56
|
-
this.raw = this.opts.isFileCallback(filename) || filename;
|
57
|
-
}
|
58
|
-
/**
|
59
|
-
* parse wrapper for handling
|
60
|
-
* preprocessing, parsing and postprocess
|
61
|
-
**/
|
62
|
-
Parser.prototype.parse = function () {
|
63
|
-
if (this.opts.verbose || this.opts.debug) {
|
64
|
-
console.log(Colors.colors("magenta", "parsing " + this.file + ": depth=" + this.opts.depth));
|
65
|
-
}
|
66
|
-
if (this.opts.debug) {
|
67
|
-
console.log("Parsing options:");
|
68
|
-
console.log(this.opts);
|
69
|
-
}
|
70
|
-
/* reset sections for beginning parse */
|
71
|
-
if (this.opts.depth === 0)
|
72
|
-
this.opts.secs = [];
|
73
|
-
var __blob;
|
74
|
-
/* apply preproccessing to raw file */
|
75
|
-
__blob = this.preprocess(this.raw);
|
76
|
-
/* main parser instance call */
|
77
|
-
__blob = this.mainparse(__blob);
|
78
|
-
/**
|
79
|
-
* apply postprocessing after */
|
80
|
-
__blob = this.postprocess(__blob);
|
81
|
-
return __blob;
|
82
|
-
};
|
83
|
-
Parser.prototype.mainparse = function (blob) {
|
84
|
-
var _this = this;
|
85
|
-
if (this.opts.verbose || this.opts.debug) {
|
86
|
-
console.debug(("beginning mainparse of '" + this.file + "'").blue);
|
87
|
-
}
|
88
|
-
var __blob = "";
|
89
|
-
/* main parser instance loop */
|
90
|
-
blob.split("\n").forEach(function (line, lnum) {
|
91
|
-
_this.line_num = lnum;
|
92
|
-
/* if line looks like a title */
|
93
|
-
var titleMatch = line.trim().match(/^(#+) (.+)$/);
|
94
|
-
if (titleMatch) {
|
95
|
-
if (_this.opts.verbose || _this.opts.debug)
|
96
|
-
console.log("found toc element: " + line);
|
97
|
-
/* implement toc level */
|
98
|
-
var level = titleMatch[1].length;
|
99
|
-
/**
|
100
|
-
* parse elements of title
|
101
|
-
* such as variables */
|
102
|
-
var title = titleMatch[2]
|
103
|
-
.trim()
|
104
|
-
.split(" ")
|
105
|
-
.map(function (s) {
|
106
|
-
return s.startsWith(Parser.TOKEN) ? _this.parseToken(s) : s;
|
107
|
-
})
|
108
|
-
.join("_");
|
109
|
-
_this.opts.secs.push({ level: level, title: title });
|
110
|
-
if (_this.opts.debug) {
|
111
|
-
console.log("updated sections:", { level: level, title: title });
|
112
|
-
}
|
113
|
-
}
|
114
|
-
var __line_tokens = [];
|
115
|
-
/* split line into tokens */
|
116
|
-
line.split(" ").forEach(function (token) {
|
117
|
-
/* if token is not #md token,
|
118
|
-
* just add it and continue */
|
119
|
-
if (token.startsWith(Parser.TOKEN)) {
|
120
|
-
token = _this.parseToken(token);
|
121
|
-
}
|
122
|
-
__line_tokens.push(token);
|
123
|
-
});
|
124
|
-
/* put line back properly */
|
125
|
-
__blob += __line_tokens.join(" ") + "\n";
|
126
|
-
});
|
127
|
-
return __blob;
|
128
|
-
};
|
129
|
-
Parser.prototype.parseToken = function (token) {
|
130
|
-
/* iterate over all commands,
|
131
|
-
* and if command is valid, execute it */
|
132
|
-
if (this.opts.verbose || this.opts.debug)
|
133
|
-
console.log("found mdtoken: " + token);
|
134
|
-
for (var i = 0; i < commands.parse.length; i++) {
|
135
|
-
var command = commands.parse[i];
|
136
|
-
if (command.valid(token, this)) {
|
137
|
-
return command.act(token, this);
|
138
|
-
}
|
139
|
-
}
|
140
|
-
/* check if the command is for later */
|
141
|
-
for (var i = 0; i < commands.postparse.length; i++) {
|
142
|
-
var command = commands.postparse[i];
|
143
|
-
if (command.valid(token, this)) {
|
144
|
-
return token;
|
145
|
-
}
|
146
|
-
}
|
147
|
-
throw new SyntaxError("Unknown token: " + token);
|
148
|
-
};
|
149
|
-
Parser.prototype.preprocess = function (blob) {
|
150
|
-
var _this = this;
|
151
|
-
if (this.opts.verbose || this.opts.debug) {
|
152
|
-
console.debug(("beginning preprocess of '" + this.file + "'").blue);
|
153
|
-
}
|
154
|
-
var __blob = "";
|
155
|
-
var lines = blob.split("\n");
|
156
|
-
lines.forEach(function (line) {
|
157
|
-
var __line_tokens = [];
|
158
|
-
line.split(" ").forEach(function (token) {
|
159
|
-
for (var _i = 0, _a = commands.preparse; _i < _a.length; _i++) {
|
160
|
-
var command = _a[_i];
|
161
|
-
if (command.valid(token, _this)) {
|
162
|
-
token = command.act(token, _this);
|
163
|
-
}
|
164
|
-
}
|
165
|
-
__line_tokens.push(token);
|
166
|
-
});
|
167
|
-
__blob += __line_tokens.join(" ") + "\n";
|
168
|
-
});
|
169
|
-
return __blob;
|
170
|
-
};
|
171
|
-
Parser.prototype.postprocess = function (blob) {
|
172
|
-
var _this = this;
|
173
|
-
if (this.opts.verbose || this.opts.debug) {
|
174
|
-
console.debug(("beginning postprocess of '" + this.file + "'").blue);
|
175
|
-
}
|
176
|
-
var __blob = "";
|
177
|
-
var lines = blob.split("\n");
|
178
|
-
lines.forEach(function (line) {
|
179
|
-
var __line_tokens = [];
|
180
|
-
line.split(" ").forEach(function (token) {
|
181
|
-
// only look
|
182
|
-
for (var _i = 0, _a = commands.postparse; _i < _a.length; _i++) {
|
183
|
-
var command = _a[_i];
|
184
|
-
if (command.valid(token, _this)) {
|
185
|
-
token = command.act(token, _this);
|
186
|
-
}
|
187
|
-
}
|
188
|
-
__line_tokens.push(token);
|
189
|
-
});
|
190
|
-
__blob += __line_tokens.join(" ") + "\n";
|
191
|
-
});
|
192
|
-
/* remove double empty lines */
|
193
|
-
__blob = this.remove_double_blank_lines(__blob);
|
194
|
-
return __blob;
|
195
|
-
};
|
196
|
-
Parser.prototype.titleId = function (title) {
|
197
|
-
var sep = this.opts.use_underscore ? "_" : "-";
|
198
|
-
title = title
|
199
|
-
.toLowerCase()
|
200
|
-
.replace(/[^\w\s]+/g, "")
|
201
|
-
.replace(/[\s_]+/g, sep);
|
202
|
-
return title;
|
203
|
-
};
|
204
|
-
Parser.prototype.gen_toc = function () {
|
205
|
-
var _this = this;
|
206
|
-
var __blob = [];
|
207
|
-
var tabSize = 2;
|
208
|
-
var beg = "* ";
|
209
|
-
var hor = " ".repeat(tabSize);
|
210
|
-
this.opts.secs.forEach(function (sec) {
|
211
|
-
if (sec.level > _this.opts.toc_level)
|
212
|
-
return;
|
213
|
-
var link = _this.titleId(sec.title);
|
214
|
-
var title = sec.title.replace(/_/g, " ");
|
215
|
-
var __line = hor.repeat(Math.max(sec.level - 1, 0)) +
|
216
|
-
beg +
|
217
|
-
("[" + title + "](#" + link + ")");
|
218
|
-
__blob.push(__line);
|
219
|
-
});
|
220
|
-
return __blob.join("\n");
|
221
|
-
};
|
222
|
-
Parser.prototype.remove_double_blank_lines = function (blob) {
|
223
|
-
/* replace all triple newlines, and EOF by double newline */
|
224
|
-
blob = blob.replace(/(\r\n|\n){3,}/g, "\n\n");
|
225
|
-
return blob;
|
226
|
-
};
|
227
|
-
/* output the parsed document to bundle */
|
228
|
-
Parser.prototype.to = function (bundleName, cb) {
|
229
|
-
var dir = path.dirname(bundleName);
|
230
|
-
var called = false;
|
231
|
-
if (!cb)
|
232
|
-
cb = function () { };
|
233
|
-
if (!fs.existsSync(dir)) {
|
234
|
-
fs.mkdirSync(dir);
|
235
|
-
}
|
236
|
-
this.get(TargetType.MARKDOWN, function (blob) {
|
237
|
-
fs.writeFile(bundleName, blob, function () {
|
238
|
-
if (!called)
|
239
|
-
cb(bundleName);
|
240
|
-
called = true;
|
241
|
-
});
|
242
|
-
});
|
243
|
-
if (this.opts.html) {
|
244
|
-
var htmlFileName_1 = bundleName.replace(".md", ".html");
|
245
|
-
fs.writeFile(htmlFileName_1, this.html(), function () {
|
246
|
-
if (!called)
|
247
|
-
cb(htmlFileName_1);
|
248
|
-
called = true;
|
249
|
-
});
|
250
|
-
}
|
251
|
-
};
|
252
|
-
Parser.prototype.html = function () {
|
253
|
-
var htmlFormatted = marked(this.get(TargetType.HTML));
|
254
|
-
return htmlFormatted;
|
255
|
-
};
|
256
|
-
Parser.prototype.get = function (targetType, callback) {
|
257
|
-
/* If target type is undefined, markdown is the default */
|
258
|
-
if (targetType == undefined)
|
259
|
-
targetType = TargetType.MARKDOWN;
|
260
|
-
if (this.blobs[targetType]) {
|
261
|
-
if (callback) {
|
262
|
-
callback(this.blobs[targetType]);
|
263
|
-
}
|
264
|
-
return this.blobs[targetType];
|
265
|
-
}
|
266
|
-
else {
|
267
|
-
try {
|
268
|
-
this.opts.targetType = targetType;
|
269
|
-
var blob = this.parse();
|
270
|
-
this.opts.targetType = undefined;
|
271
|
-
if (callback)
|
272
|
-
callback(blob);
|
273
|
-
return blob;
|
274
|
-
}
|
275
|
-
catch (error) {
|
276
|
-
var traceback = "";
|
277
|
-
var p = this;
|
278
|
-
do {
|
279
|
-
traceback += ("\n...on line " + (p.line_num + 1) + " in " + p.file).grey(15);
|
280
|
-
if (p.parent)
|
281
|
-
p = p.parent;
|
282
|
-
} while (p.parent);
|
283
|
-
error.message += traceback;
|
284
|
-
/* only interested in stacktrace, when debugging */
|
285
|
-
if (!this.opts.debug)
|
286
|
-
error.stack = "";
|
287
|
-
if (this.opts.only_warn)
|
288
|
-
console.error(error);
|
289
|
-
else
|
290
|
-
throw error;
|
291
|
-
}
|
292
|
-
}
|
293
|
-
};
|
294
|
-
Parser.TOKEN = "#md";
|
295
|
-
return Parser;
|
296
|
-
}());
|
297
|
-
module.exports = Parser;
|
298
|
-
exports.default = Parser;
|