markdown-maker 1.7.11 → 1.9.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.
- package/.github/workflows/node.js.yml +13 -8
- package/README.md +1 -0
- package/doc/.mdmconfig.json +3 -2
- package/package.json +10 -8
- 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 +103 -112
- 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
| @@ -3,11 +3,7 @@ | |
| 3 3 |  | 
| 4 4 | 
             
            name: Mocha
         | 
| 5 5 |  | 
| 6 | 
            -
            on:
         | 
| 7 | 
            -
              push:
         | 
| 8 | 
            -
                branches: [ main ]
         | 
| 9 | 
            -
              pull_request:
         | 
| 10 | 
            -
                branches: [ main ]
         | 
| 6 | 
            +
            on: [push, pull_request]
         | 
| 11 7 |  | 
| 12 8 | 
             
            jobs:
         | 
| 13 9 | 
             
              build:
         | 
| @@ -25,6 +21,15 @@ jobs: | |
| 25 21 | 
             
                  uses: actions/setup-node@v1
         | 
| 26 22 | 
             
                  with:
         | 
| 27 23 | 
             
                    node-version: ${{ matrix.node-version }}
         | 
| 28 | 
            -
                -  | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 24 | 
            +
                - name: yarn install
         | 
| 25 | 
            +
                  uses: borales/actions-yarn@v3.0.0
         | 
| 26 | 
            +
                  with:
         | 
| 27 | 
            +
                    cmd: install # will run `yarn install` command
         | 
| 28 | 
            +
                - name: yarn build
         | 
| 29 | 
            +
                  uses: borales/actions-yarn@v3.0.0
         | 
| 30 | 
            +
                  with:
         | 
| 31 | 
            +
                    cmd: build # will run `yarn build` command
         | 
| 32 | 
            +
                - name: yarn test
         | 
| 33 | 
            +
                  uses: borales/actions-yarn@v3.0.0
         | 
| 34 | 
            +
                  with:
         | 
| 35 | 
            +
                    cmd: test # will run `yarn test` command
         | 
    
        package/README.md
    CHANGED
    
    | @@ -14,6 +14,7 @@ Currently supports the following features | |
| 14 14 | 
             
            * Automatic Table of Contents generation with `#mdmaketoc`
         | 
| 15 15 | 
             
            * HTML emitting with custom styling
         | 
| 16 16 | 
             
            * Easy extention of custom commands, see `src/commands.js` for implementations
         | 
| 17 | 
            +
            * Usage of templates with the `#mdtemplate<...>` command.
         | 
| 17 18 |  | 
| 18 19 | 
             
            ## Usage
         | 
| 19 20 | 
             
            Download the [latest release](https://github.com/blitzher/markdown-maker/releases), and write your document.
         | 
    
        package/doc/.mdmconfig.json
    CHANGED
    
    
    
        package/package.json
    CHANGED
    
    | @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            {
         | 
| 2 2 | 
             
                "name": "markdown-maker",
         | 
| 3 | 
            -
                "version": "1. | 
| 3 | 
            +
                "version": "1.9.2",
         | 
| 4 4 | 
             
                "description": "",
         | 
| 5 5 | 
             
                "main": "src/cltool.ts",
         | 
| 6 6 | 
             
                "bin": {
         | 
| 7 | 
            -
                    " | 
| 7 | 
            +
                    "mdparse": "build/cltool.js"
         | 
| 8 8 | 
             
                },
         | 
| 9 9 | 
             
                "pkg": {
         | 
| 10 10 | 
             
                    "assets": [
         | 
| @@ -13,8 +13,8 @@ | |
| 13 13 | 
             
                        "node_modules/colors/*",
         | 
| 14 14 | 
             
                        "node_modules/colors./*",
         | 
| 15 15 | 
             
                        "node_modules/marked/*",
         | 
| 16 | 
            -
                        " | 
| 17 | 
            -
                        " | 
| 16 | 
            +
                        "build/cltool.js",
         | 
| 17 | 
            +
                        "src/templates/*"
         | 
| 18 18 | 
             
                    ],
         | 
| 19 19 | 
             
                    "targets": [
         | 
| 20 20 | 
             
                        "node12-macos-x64",
         | 
| @@ -26,7 +26,7 @@ | |
| 26 26 | 
             
                    "test": "mocha",
         | 
| 27 27 | 
             
                    "test:yarn": "mocha",
         | 
| 28 28 | 
             
                    "bundle": "tsc --project tsconfig.json",
         | 
| 29 | 
            -
                    "main": "node build/cltool.js document/main.md -o dist/bundle.md",
         | 
| 29 | 
            +
                    "main": "node build/cltool.js document/main.md -o dist/bundle.md --debug",
         | 
| 30 30 | 
             
                    "debug": "node src/cltool.js -db document/main.md -o dist/bundle.md",
         | 
| 31 31 | 
             
                    "build": "npm run bundle && pkg --output bin/mdparse .",
         | 
| 32 32 | 
             
                    "build:yarn": "yarn bundle && pkg --output bin/mdparse .",
         | 
| @@ -46,18 +46,20 @@ | |
| 46 46 | 
             
                    "@types/chokidar": "^2.1.3",
         | 
| 47 47 | 
             
                    "@types/colors": "^1.2.1",
         | 
| 48 48 | 
             
                    "@types/node": "^15.6.1",
         | 
| 49 | 
            +
                    "@types/ws": "^8.5.3",
         | 
| 49 50 | 
             
                    "argparse": "^2.0.1",
         | 
| 50 51 | 
             
                    "chokidar": "^3.5.1",
         | 
| 51 52 | 
             
                    "colors": "^1.4.0",
         | 
| 52 53 | 
             
                    "colors.ts": "^1.0.20",
         | 
| 53 54 | 
             
                    "marked": "^2.0.1",
         | 
| 54 | 
            -
                    " | 
| 55 | 
            +
                    "require-runtime": "^2.0.0",
         | 
| 56 | 
            +
                    "ws": "^8.8.1"
         | 
| 55 57 | 
             
                },
         | 
| 56 58 | 
             
                "devDependencies": {
         | 
| 57 59 | 
             
                    "cloc": "^2.7.0",
         | 
| 58 60 | 
             
                    "mocha": "^8.3.1",
         | 
| 61 | 
            +
                    "pkg": "^4.4.9",
         | 
| 59 62 | 
             
                    "prettier": "^2.3.0",
         | 
| 60 | 
            -
                    "typescript": "^4.3.2" | 
| 61 | 
            -
                    "pkg": "^4.4.9"
         | 
| 63 | 
            +
                    "typescript": "^4.3.2"
         | 
| 62 64 | 
             
                }
         | 
| 63 65 | 
             
            }
         | 
    
        package/prettierrc.yaml
    CHANGED
    
    
    
        package/re-test.js
    ADDED
    
    
    
        package/src/cltool.ts
    CHANGED
    
    | @@ -2,8 +2,8 @@ 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 { symlinkSync } from "fs";
         | 
| 6 5 | 
             
            import Parser from "./parse";
         | 
| 6 | 
            +
            import { WebSocketServer } from "ws";
         | 
| 7 7 |  | 
| 8 8 | 
             
            Colors.enable();
         | 
| 9 9 | 
             
            const { ArgumentParser } = require("argparse"); /* for parsing clargs */
         | 
| @@ -12,7 +12,7 @@ const choki = require("chokidar"); | |
| 12 12 |  | 
| 13 13 | 
             
            export const argParser = new ArgumentParser({
         | 
| 14 14 | 
             
                description: "Markdown bundler, with extra options",
         | 
| 15 | 
            -
                prog:  | 
| 15 | 
            +
                prog: "mdparse",
         | 
| 16 16 | 
             
            });
         | 
| 17 17 |  | 
| 18 18 | 
             
            const configFileName = ".mdmconfig.json";
         | 
| @@ -26,7 +26,7 @@ argParser.add_argument("-v", "--verbose", { | |
| 26 26 | 
             
                action: "store_true",
         | 
| 27 27 | 
             
                help: "enable verbose output",
         | 
| 28 28 | 
             
            });
         | 
| 29 | 
            -
            argParser.add_argument("- | 
| 29 | 
            +
            argParser.add_argument("-D", "--debug", {
         | 
| 30 30 | 
             
                action: "store_true",
         | 
| 31 31 | 
             
                help: "enable debugging information",
         | 
| 32 32 | 
             
            });
         | 
| @@ -47,40 +47,50 @@ argParser.add_argument("-w", "--watch", { | |
| 47 47 | 
             
                action: "store_true",
         | 
| 48 48 | 
             
                help: "recompile after a change in target target file or directory.",
         | 
| 49 49 | 
             
            });
         | 
| 50 | 
            -
            argParser.add_argument("- | 
| 50 | 
            +
            argParser.add_argument("-u", "--use-underscore", {
         | 
| 51 51 | 
             
                action: "store_true",
         | 
| 52 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 53 | 
             
            });
         | 
| 54 | 
            -
            argParser.add_argument("--toc-level", {
         | 
| 54 | 
            +
            argParser.add_argument("-t", "--toc-level", {
         | 
| 55 55 | 
             
                help: "the section level of the table of contents, by default is 3",
         | 
| 56 56 | 
             
                default: 3,
         | 
| 57 57 | 
             
                type: "int",
         | 
| 58 58 | 
             
            });
         | 
| 59 | 
            -
            argParser.add_argument("--html", {
         | 
| 59 | 
            +
            argParser.add_argument("-H", "--html", {
         | 
| 60 60 | 
             
                action: "store_true",
         | 
| 61 61 | 
             
                help: "compile HTML from the parsed markdown",
         | 
| 62 62 | 
             
            });
         | 
| 63 | 
            -
            argParser.add_argument("--allow- | 
| 63 | 
            +
            argParser.add_argument("--allow-undefined", "-A", {
         | 
| 64 64 | 
             
                action: "store_true",
         | 
| 65 | 
            -
                help: "allow  | 
| 65 | 
            +
                help: "allow the use of the \"<thing>\" syntax, without raising an error when 'thing' is not a variable. Mostly useful when writing inline html tags, and other non-strictly markdown related uses",
         | 
| 66 66 | 
             
            });
         | 
| 67 67 | 
             
            //#endregion
         | 
| 68 68 |  | 
| 69 69 | 
             
            function main() {
         | 
| 70 | 
            -
                 | 
| 71 | 
            -
                let  | 
| 70 | 
            +
                let clargs, fileargs;
         | 
| 71 | 
            +
                let server: WebSocketServer | undefined;
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                /* Read config file or parse args from cmd-line */
         | 
| 72 74 | 
             
                if (fs.existsSync(configFileName)) {
         | 
| 73 | 
            -
                    let data = JSON.parse(fs.readFileSync(configFileName)).opts;
         | 
| 75 | 
            +
                    let data: { [key: string]: string | boolean | number } = JSON.parse(fs.readFileSync(configFileName)).opts;
         | 
| 74 76 |  | 
| 75 | 
            -
                    let args = [];
         | 
| 77 | 
            +
                    let args: (string | number)[] = [];
         | 
| 76 78 | 
             
                    Object.entries(data).forEach(([key, value]) => {
         | 
| 77 | 
            -
                        if (key != "src" | 
| 78 | 
            -
             | 
| 79 | 
            +
                        if (key != "src" && value !== false) {
         | 
| 80 | 
            +
                            args.push("--" + key);
         | 
| 81 | 
            +
                        }
         | 
| 82 | 
            +
                        if (typeof value != "boolean") {
         | 
| 83 | 
            +
                            args.push(value);
         | 
| 84 | 
            +
                        }
         | 
| 79 85 | 
             
                    });
         | 
| 80 | 
            -
                    args.push(data.src);
         | 
| 81 86 |  | 
| 82 | 
            -
                     | 
| 83 | 
            -
             | 
| 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 | 
            +
                }
         | 
| 84 94 |  | 
| 85 95 | 
             
                /* helper method for calling parser */
         | 
| 86 96 | 
             
                const compile = (source, output, cb?) => {
         | 
| @@ -109,7 +119,10 @@ function main() { | |
| 109 119 |  | 
| 110 120 | 
             
                    try {
         | 
| 111 121 | 
             
                        compile(clargs.src, clargs.output, () => {
         | 
| 112 | 
            -
                             | 
| 122 | 
            +
                            /* after compile, send refresh command to clients */
         | 
| 123 | 
            +
                            server.clients.forEach((client) => {
         | 
| 124 | 
            +
                                if (client.OPEN) client.send("refresh");
         | 
| 125 | 
            +
                            });
         | 
| 113 126 | 
             
                        });
         | 
| 114 127 | 
             
                    } catch (e) {
         | 
| 115 128 | 
             
                        console.log(e.message);
         | 
| @@ -123,16 +136,16 @@ function main() { | |
| 123 136 | 
             
                    clargs.src = path.join(clargs.src, clargs.entry);
         | 
| 124 137 | 
             
                }
         | 
| 125 138 |  | 
| 126 | 
            -
                const srcDirName = path.dirname(clargs.src);
         | 
| 127 | 
            -
             | 
| 128 139 | 
             
                if (clargs.debug) console.dir(clargs);
         | 
| 129 140 |  | 
| 141 | 
            +
                /* compile once */
         | 
| 130 142 | 
             
                if (!clargs.watch) compile(clargs.src, clargs.output);
         | 
| 131 143 |  | 
| 144 | 
            +
                /* watch the folder and recompile on change */
         | 
| 132 145 | 
             
                if (clargs.watch) {
         | 
| 133 | 
            -
                     | 
| 134 | 
            -
                    // server = wsServer();
         | 
| 146 | 
            +
                    const srcDirName = path.dirname(clargs.src);
         | 
| 135 147 | 
             
                    console.log(`Watching ${srcDirName} for changes...`.yellow);
         | 
| 148 | 
            +
                    server = new WebSocketServer({ port: 7788 });
         | 
| 136 149 |  | 
| 137 150 | 
             
                    const _watcher = choki.watch(srcDirName).on("all", watcher);
         | 
| 138 151 | 
             
                    try {
         | 
    
        package/src/commands.ts
    CHANGED
    
    | @@ -1,35 +1,48 @@ | |
| 1 1 | 
             
            import * as path from "path";
         | 
| 2 2 | 
             
            import Parser from "./parse";
         | 
| 3 | 
            +
            import * as fs from "fs";
         | 
| 4 | 
            +
            import templates, { new_template } from "./templates";
         | 
| 5 | 
            +
            import requireRuntime from "require-runtime";
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            export class MDMError extends Error {
         | 
| 8 | 
            +
                match: RegExpMatchArray;
         | 
| 9 | 
            +
                constructor(message: string, match: RegExpMatchArray) {
         | 
| 10 | 
            +
                    super(message);
         | 
| 11 | 
            +
                    this.name = "MDMError";
         | 
| 12 | 
            +
                    this.match = match;
         | 
| 13 | 
            +
                }
         | 
| 14 | 
            +
            }
         | 
| 3 15 |  | 
| 4 | 
            -
            const commands  | 
| 16 | 
            +
            export const commands: {
         | 
| 17 | 
            +
                preparse: Command[];
         | 
| 18 | 
            +
                parse: Command[];
         | 
| 19 | 
            +
                postparse: Command[];
         | 
| 20 | 
            +
            } = {
         | 
| 5 21 | 
             
                preparse: [],
         | 
| 6 22 | 
             
                parse: [],
         | 
| 7 23 | 
             
                postparse: [],
         | 
| 8 24 | 
             
            };
         | 
| 9 25 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
                PREPARSE | 
| 12 | 
            -
                PARSE | 
| 13 | 
            -
                POSTPARSE | 
| 14 | 
            -
            } | 
| 26 | 
            +
            export enum CommandType {
         | 
| 27 | 
            +
                PREPARSE,
         | 
| 28 | 
            +
                PARSE,
         | 
| 29 | 
            +
                POSTPARSE,
         | 
| 30 | 
            +
            }
         | 
| 15 31 |  | 
| 16 | 
            -
            enum TargetType {
         | 
| 32 | 
            +
            export enum TargetType {
         | 
| 17 33 | 
             
                HTML,
         | 
| 18 34 | 
             
                MARKDOWN,
         | 
| 19 35 | 
             
            }
         | 
| 20 36 |  | 
| 21 37 | 
             
            export class Command {
         | 
| 22 | 
            -
                 | 
| 23 | 
            -
                 | 
| 24 | 
            -
                 | 
| 38 | 
            +
                validator: RegExp;
         | 
| 39 | 
            +
                acter: (match: RegExpMatchArray, parser: Parser) => string | void;
         | 
| 40 | 
            +
                type: CommandType;
         | 
| 25 41 |  | 
| 26 42 | 
             
                constructor(
         | 
| 27 | 
            -
                     | 
| 28 | 
            -
                     | 
| 29 | 
            -
             | 
| 30 | 
            -
                        parser: Parser,
         | 
| 31 | 
            -
                    ) => boolean | RegExpMatchArray,
         | 
| 32 | 
            -
                    acter: (token: string, parser: Parser) => string | void,
         | 
| 43 | 
            +
                    validator: RegExp,
         | 
| 44 | 
            +
                    acter: (match: RegExpMatchArray, parser: Parser) => string | void,
         | 
| 45 | 
            +
                    type: CommandType,
         | 
| 33 46 | 
             
                ) {
         | 
| 34 47 | 
             
                    this.type = type;
         | 
| 35 48 | 
             
                    this.validator = validator;
         | 
| @@ -49,132 +62,191 @@ export class Command { | |
| 49 62 | 
             
                    }
         | 
| 50 63 | 
             
                }
         | 
| 51 64 |  | 
| 52 | 
            -
                 | 
| 53 | 
            -
                    return this. | 
| 54 | 
            -
                }
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                act(token, parser) {
         | 
| 57 | 
            -
                    return this.acter(token, parser);
         | 
| 65 | 
            +
                act(match, parser) {
         | 
| 66 | 
            +
                    return this.acter(match, parser);
         | 
| 58 67 | 
             
                }
         | 
| 59 68 | 
             
            }
         | 
| 60 69 |  | 
| 61 70 | 
             
            /* variable shorthand */
         | 
| 62 71 | 
             
            new Command(
         | 
| 72 | 
            +
                /(\s|^)<(.+)>/,
         | 
| 73 | 
            +
                (match, parser) => `${match[1]}#mdvar<${match[2]}>`,
         | 
| 63 74 | 
             
                CommandType.PREPARSE,
         | 
| 64 | 
            -
                (t, p) => t.match(/(?:\s|^)<\w+>/),
         | 
| 65 | 
            -
                (t, p) => `#mdvar` + t,
         | 
| 66 75 | 
             
            );
         | 
| 67 76 |  | 
| 68 77 | 
             
            /* mddef */
         | 
| 69 78 | 
             
            new Command(
         | 
| 70 | 
            -
                 | 
| 71 | 
            -
                ( | 
| 72 | 
            -
             | 
| 73 | 
            -
                    const m = t.match(/^#mddef<(\w+)=(\w+)>/);
         | 
| 74 | 
            -
                    p.opts.defs[m[1]] = m[2];
         | 
| 79 | 
            +
                /#mddef< *(.+?) *= *(.+?) *>/ /* first .+ is lazy so as to not match following spaces */,
         | 
| 80 | 
            +
                (match, parser) => {
         | 
| 81 | 
            +
                    parser.opts.defs[match[1]] = match[2].replace("_", " ");
         | 
| 75 82 | 
             
                },
         | 
| 83 | 
            +
                CommandType.PARSE,
         | 
| 76 84 | 
             
            );
         | 
| 77 85 |  | 
| 78 86 | 
             
            /* mdvar */
         | 
| 79 87 | 
             
            new Command(
         | 
| 80 | 
            -
                 | 
| 81 | 
            -
                ( | 
| 82 | 
            -
             | 
| 83 | 
            -
                     | 
| 84 | 
            -
                    let value = p.opts.defs[match[1]];
         | 
| 85 | 
            -
                    if (!value && !p.opts.allow_undef)
         | 
| 88 | 
            +
                /#mdvar<(.+?)>/,
         | 
| 89 | 
            +
                (match, parser) => {
         | 
| 90 | 
            +
                    let value = parser.opts.defs[match[1]];
         | 
| 91 | 
            +
                    if (!value && !parser.opts.allow_undefined)
         | 
| 86 92 | 
             
                        throw new Error(`Undefined variable: ${match[1]}`);
         | 
| 87 | 
            -
                    value = value || `<${match[1]} | 
| 88 | 
            -
                    return t.replace(match[0], value.replace("_", " "));
         | 
| 93 | 
            +
                    return (value = value || `<${match[1]}>`);
         | 
| 89 94 | 
             
                },
         | 
| 95 | 
            +
                CommandType.PARSE,
         | 
| 90 96 | 
             
            );
         | 
| 91 97 |  | 
| 92 98 | 
             
            /** mdinclude */
         | 
| 93 99 | 
             
            new Command(
         | 
| 94 | 
            -
                 | 
| 95 | 
            -
                ( | 
| 96 | 
            -
                (t, p) => {
         | 
| 100 | 
            +
                /#mdinclude<([\w.\/-]+)(?:[,\s]+([\w]+))?>/,
         | 
| 101 | 
            +
                (match, parser) => {
         | 
| 97 102 | 
             
                    /* increase the current recursive depth */
         | 
| 98 | 
            -
                     | 
| 103 | 
            +
                    parser.opts.depth++;
         | 
| 99 104 |  | 
| 100 | 
            -
                    if ( | 
| 105 | 
            +
                    if (parser.opts.depth > parser.opts.max_depth) {
         | 
| 101 106 | 
             
                        throw new Error("max depth exceeded!");
         | 
| 102 107 | 
             
                    }
         | 
| 103 108 |  | 
| 104 109 | 
             
                    /* get the matching group */
         | 
| 105 | 
            -
                    const match = t.match(/^#mdinclude<([\w.\/-]+)(?:[,\s]+([\w]+))?>/);
         | 
| 106 | 
            -
             | 
| 107 110 | 
             
                    const [_, name, condition] = match;
         | 
| 108 111 |  | 
| 109 112 | 
             
                    /* implement conditional imports */
         | 
| 110 | 
            -
                    if (condition && ! | 
| 113 | 
            +
                    if (condition && !parser.opts.args.includes(condition)) return;
         | 
| 111 114 |  | 
| 112 | 
            -
                    const recursiveParser = new Parser( | 
| 113 | 
            -
                         | 
| 114 | 
            -
             | 
| 115 | 
            +
                    const recursiveParser = new Parser(
         | 
| 116 | 
            +
                        path.join(parser.wd, name),
         | 
| 117 | 
            +
                        parser.opts,
         | 
| 118 | 
            +
                        {
         | 
| 119 | 
            +
                            parent: parser,
         | 
| 120 | 
            +
                        },
         | 
| 121 | 
            +
                    );
         | 
| 115 122 |  | 
| 116 123 | 
             
                    /* keep the options the same */
         | 
| 117 | 
            -
                    recursiveParser.opts =  | 
| 118 | 
            -
                    recursiveParser.parent =  | 
| 124 | 
            +
                    recursiveParser.opts = parser.opts;
         | 
| 125 | 
            +
                    recursiveParser.parent = parser;
         | 
| 119 126 |  | 
| 120 127 | 
             
                    const fileType = path.extname(recursiveParser.file);
         | 
| 121 128 |  | 
| 122 129 | 
             
                    const blob =
         | 
| 123 130 | 
             
                        fileType === ".md"
         | 
| 124 | 
            -
                            ? recursiveParser.get( | 
| 131 | 
            +
                            ? recursiveParser.get(parser.opts.targetType)
         | 
| 125 132 | 
             
                            : recursiveParser.raw;
         | 
| 126 133 |  | 
| 127 | 
            -
                     | 
| 134 | 
            +
                    parser.opts.depth--;
         | 
| 128 135 | 
             
                    return blob;
         | 
| 129 136 | 
             
                },
         | 
| 137 | 
            +
                CommandType.PARSE,
         | 
| 130 138 | 
             
            );
         | 
| 131 139 |  | 
| 140 | 
            +
            /* mdlabel */
         | 
| 132 141 | 
             
            new Command(
         | 
| 133 | 
            -
                 | 
| 134 | 
            -
                ( | 
| 135 | 
            -
             | 
| 136 | 
            -
                    if (p.opts.targetType !== TargetType.HTML) return;
         | 
| 142 | 
            +
                /#mdlabel<(\d+),\s?(.+)>/,
         | 
| 143 | 
            +
                (match, parser) => {
         | 
| 144 | 
            +
                    if (parser.opts.targetType !== TargetType.HTML) return "";
         | 
| 137 145 |  | 
| 138 | 
            -
                    const match = t.match(/#mdlabel<([\d]+),([\w\W]+)>/);
         | 
| 139 146 | 
             
                    const level = Number.parseInt(match[1]);
         | 
| 140 147 | 
             
                    const title = match[2];
         | 
| 141 | 
            -
                    const link =  | 
| 142 | 
            -
                     | 
| 148 | 
            +
                    const link = parser.titleId(title);
         | 
| 149 | 
            +
                    parser.opts.secs.push({ level, title });
         | 
| 143 150 | 
             
                    return `<span id="${link}"></span>`;
         | 
| 144 151 | 
             
                },
         | 
| 152 | 
            +
                CommandType.PREPARSE,
         | 
| 145 153 | 
             
            );
         | 
| 146 154 |  | 
| 147 155 | 
             
            /* mdref */
         | 
| 148 156 | 
             
            new Command(
         | 
| 149 | 
            -
                 | 
| 150 | 
            -
                (t, p) => t.match(/#mdref<([\w\W]+)>/),
         | 
| 157 | 
            +
                /#mdref<(.+)>/,
         | 
| 151 158 |  | 
| 152 | 
            -
                ( | 
| 153 | 
            -
                     | 
| 154 | 
            -
             | 
| 155 | 
            -
                    for (let i = 0; i < p.opts.secs.length; i++) {
         | 
| 156 | 
            -
                        let { title } = p.opts.secs[i];
         | 
| 159 | 
            +
                (match, parser) => {
         | 
| 160 | 
            +
                    for (let i = 0; i < parser.opts.secs.length; i++) {
         | 
| 161 | 
            +
                        let { title } = parser.opts.secs[i];
         | 
| 157 162 | 
             
                        if (title === match[1]) break;
         | 
| 158 163 |  | 
| 159 | 
            -
                        if (i ===  | 
| 164 | 
            +
                        if (i === parser.opts.secs.length - 1)
         | 
| 160 165 | 
             
                            throw new Error(
         | 
| 161 166 | 
             
                                `Reference to [${match[1]}] could not be resolved!`,
         | 
| 162 167 | 
             
                            );
         | 
| 163 168 | 
             
                    }
         | 
| 164 169 |  | 
| 165 170 | 
             
                    match[1] = match[1].replace("_", " ");
         | 
| 166 | 
            -
                    const link =  | 
| 167 | 
            -
                    if ( | 
| 171 | 
            +
                    const link = parser.titleId(match[1]);
         | 
| 172 | 
            +
                    if (parser.opts.targetType === TargetType.HTML)
         | 
| 168 173 | 
             
                        return `<a href="#${link}">${match[1]}</a>`;
         | 
| 169 | 
            -
                    else if ( | 
| 174 | 
            +
                    else if (parser.opts.targetType === TargetType.MARKDOWN)
         | 
| 170 175 | 
             
                        return `[${match[1]}](#${link})`;
         | 
| 171 176 | 
             
                },
         | 
| 177 | 
            +
                CommandType.PARSE,
         | 
| 178 | 
            +
            );
         | 
| 179 | 
            +
             | 
| 180 | 
            +
            /* mdtemplate */
         | 
| 181 | 
            +
            new Command(
         | 
| 182 | 
            +
                /#mdtemplate<([\w\W]+)>/,
         | 
| 183 | 
            +
                (match, parser) => {
         | 
| 184 | 
            +
                    const template = match[1];
         | 
| 185 | 
            +
                    const replacement = templates[template];
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                    if (replacement !== undefined) {
         | 
| 188 | 
            +
                        return replacement;
         | 
| 189 | 
            +
                    } else {
         | 
| 190 | 
            +
                        throw new MDMError(`Template \"${template}\" not found!`, match);
         | 
| 191 | 
            +
                    }
         | 
| 192 | 
            +
                },
         | 
| 193 | 
            +
                CommandType.PARSE,
         | 
| 172 194 | 
             
            );
         | 
| 173 195 |  | 
| 174 196 | 
             
            new Command(
         | 
| 197 | 
            +
                /#mdmaketoc(?:<>)?/,
         | 
| 198 | 
            +
                (match, parser) => parser.gen_toc(),
         | 
| 175 199 | 
             
                CommandType.POSTPARSE,
         | 
| 176 | 
            -
                (t, p) => t.match(/#mdmaketoc/),
         | 
| 177 | 
            -
                (t, p) => p.gen_toc(),
         | 
| 178 200 | 
             
            );
         | 
| 179 201 |  | 
| 180 | 
            -
             | 
| 202 | 
            +
            export function load_extensions(parser: Parser) {
         | 
| 203 | 
            +
                /* global extention */
         | 
| 204 | 
            +
                const global_extensions_path = path.join(process.cwd(), "extensions.js");
         | 
| 205 | 
            +
                if (fs.existsSync(global_extensions_path)) {
         | 
| 206 | 
            +
                    const extensions = requireRuntime(global_extensions_path);
         | 
| 207 | 
            +
                    extensions.main(new_template, new_command);
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                    if (parser.opts.verbose)
         | 
| 210 | 
            +
                        console.log(
         | 
| 211 | 
            +
                            `Loaded global extensions from ${global_extensions_path}`
         | 
| 212 | 
            +
                                .yellow,
         | 
| 213 | 
            +
                        );
         | 
| 214 | 
            +
                } else if (parser.opts.debug) {
         | 
| 215 | 
            +
                    console.log(
         | 
| 216 | 
            +
                        `No global extensions found at ${global_extensions_path}`.red,
         | 
| 217 | 
            +
                    );
         | 
| 218 | 
            +
                }
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                /* project extention */
         | 
| 221 | 
            +
                const project_extensions_path = path.join(parser.wd_full, "extensions.js");
         | 
| 222 | 
            +
                if (fs.existsSync(project_extensions_path)) {
         | 
| 223 | 
            +
                    const extensions = requireRuntime(project_extensions_path);
         | 
| 224 | 
            +
                    extensions.main(new_template, new_command);
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                    if (parser.opts.verbose)
         | 
| 227 | 
            +
                        console.log(
         | 
| 228 | 
            +
                            `Loaded project extensions from ${project_extensions_path}`
         | 
| 229 | 
            +
                                .yellow,
         | 
| 230 | 
            +
                        );
         | 
| 231 | 
            +
                } else if (parser.opts.debug) {
         | 
| 232 | 
            +
                    console.log(
         | 
| 233 | 
            +
                        `No project extensions found at ${project_extensions_path}!`.red,
         | 
| 234 | 
            +
                    );
         | 
| 235 | 
            +
                }
         | 
| 236 | 
            +
            }
         | 
| 237 | 
            +
             | 
| 238 | 
            +
            /**
         | 
| 239 | 
            +
             *
         | 
| 240 | 
            +
             * @param regex The regex to match the command
         | 
| 241 | 
            +
             * @param acter The function called when a match is found. Takes two arguments, `match` and `parser`. `match` is the result of the regex match, and `parser` is the parser instance. The function should return the replacement string.
         | 
| 242 | 
            +
             * @param type When the command should be run. Can be `CommandType.PREPARSE`, `CommandType.PARSE`, or `CommandType.POSTPARSE`. Defaults to `CommandType.PARSE`.
         | 
| 243 | 
            +
             */
         | 
| 244 | 
            +
            export function new_command(
         | 
| 245 | 
            +
                regex: RegExp,
         | 
| 246 | 
            +
                acter: (match: RegExpMatchArray, parser: Parser) => string,
         | 
| 247 | 
            +
                type?: CommandType,
         | 
| 248 | 
            +
            ) {
         | 
| 249 | 
            +
                new Command(regex, acter, type || CommandType.PARSE);
         | 
| 250 | 
            +
            }
         | 
| 251 | 
            +
             | 
| 252 | 
            +
            export default { commands, load_extensions };
         |