Variables

- added variables `$varname` and system variables `$$varname`
- renamed CommandParser to preformatter because it also handles variables and stuff
- added global variable definition
develop
Trivernis 5 years ago
parent ee316c6c24
commit 2826341e4e

@ -16,3 +16,4 @@
- support for `mdconf.json`config file
- MathJax script to html
- `mdconfig.json` extensions with `extends: "name"`
- variables prefixed with `$` and system variables prefixed with `$$`

@ -74,6 +74,32 @@ You can include your own stylesheet. It is applied after the default style. The
[!stylesheet]: path/to/style.css
```
## Variables
Variables are prefixed with `$`.
You can define and use variables like this:
Defining:
```
$varname = value
$fruit = apple
```
Using:
```
I'm eating an $fruit.
```
There are system variables that are prefixed with `$$`.
Currently you can use
variable | value | example value
---------|-----------------|--------------
$now | current datetime| 31.07.2019 21:03:47
$date | current date | 31.07.2019
$time | current time | 21:03:47
## Configuration file
You can also define plugins, stylesheets and other stuff by using a `mdconf.json` file in the same directory as the main markdown file. Example config:

15
package-lock.json generated

@ -954,6 +954,11 @@
"whatwg-url": "^7.0.0"
}
},
"date-format": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
"integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA=="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -3448,6 +3453,11 @@
"resolved": "https://registry.npmjs.org/markdown-it-imsize/-/markdown-it-imsize-2.0.1.tgz",
"integrity": "sha1-zKBCeQXQUziiR8ucqdloxc3dUXA="
},
"markdown-it-inline-comments": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/markdown-it-inline-comments/-/markdown-it-inline-comments-1.0.1.tgz",
"integrity": "sha1-F26r5jGj4IElvXOVAPQ8UfUliW0="
},
"markdown-it-ins": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-2.0.0.tgz",
@ -3476,6 +3486,11 @@
"resolved": "https://registry.npmjs.org/markdown-it-mathjax/-/markdown-it-mathjax-2.0.0.tgz",
"integrity": "sha1-ritPTFxxmgP55HXGZPeyaFIx2ek="
},
"markdown-it-modify-token": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/markdown-it-modify-token/-/markdown-it-modify-token-1.0.2.tgz",
"integrity": "sha1-VCRxoyMnClwQKmNbB/47R8J47qA="
},
"markdown-it-multimd-table": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/markdown-it-multimd-table/-/markdown-it-multimd-table-3.2.2.tgz",

@ -30,6 +30,7 @@
"@types/puppeteer": "^1.19.0",
"argparse": "^1.0.10",
"chokidar": "^3.0.2",
"date-format": "^2.1.0",
"fs-extra": "^8.1.0",
"jsdom": "^15.1.1",
"line-by-line": "^0.1.6",
@ -46,11 +47,13 @@
"markdown-it-highlightjs": "^3.0.0",
"markdown-it-implicit-figures": "^0.9.0",
"markdown-it-imsize": "^2.0.1",
"markdown-it-inline-comments": "^1.0.1",
"markdown-it-ins": "^2.0.0",
"markdown-it-kbd": "^2.0.0",
"markdown-it-mark": "^2.0.0",
"markdown-it-math": "^4.1.1",
"markdown-it-mathjax": "^2.0.0",
"markdown-it-modify-token": "^1.0.2",
"markdown-it-multimd-table": "^3.2.2",
"markdown-it-plantuml": "^1.4.1",
"markdown-it-smartarrows": "^1.0.1",

@ -22,6 +22,7 @@
"header-sections",
"task-checkbox",
"underline",
"implicit-figures"
"implicit-figures",
"inline-comments"
]
}

@ -6,11 +6,13 @@ import {pageFormats} from "./formats";
import {PDFFormat} from "puppeteer";
import {getMarkdownPlugin} from "./utils";
import {logger} from "./logger";
import {globalVariables} from "./globvars";
export class CommandParser {
export class PreFormatter {
public projectFiles: string[];
public pageFormat: PDFFormat;
public stylesheets: string[];
public variables: any;
private readonly resolvePath: {path: string, lines: number}[];
@ -18,6 +20,7 @@ export class CommandParser {
this.projectFiles = [];
this.resolvePath = [];
this.stylesheets = [];
this.variables = Object.assign({}, globalVariables);
}
async processCommands(doc: string, docpath: string, renderer: Renderer) {
@ -44,25 +47,26 @@ export class CommandParser {
currentFile = this.resolvePath[this.resolvePath.length - 1];
}
}
let match: RegExpExecArray = /\[ *!(\w+) *\]:? *(.*)/gu.exec(inputLine.replace(/\s/, ''));
let commandMatch: RegExpExecArray = /\[ *!(\w+) *\]:? *(.*)/g.exec(inputLine);
let variableMatch: RegExpExecArray = /\$(\w+) *= *(.*?) *$/g.exec(inputLine);
if (match && match[0]) { // TODO: stylesheets
switch(match[1]) {
if (commandMatch && commandMatch[0]) {
switch(commandMatch[1]) {
case 'use':
let plugins = match[2].split(',');
logger.verbose(`Adding plugins: ${match[2]}`);
let plugins = commandMatch[2].split(',');
logger.verbose(`Adding plugins: ${commandMatch[2]}`);
for (let mdPlugin of plugins) {
renderer.addPlugin(getMarkdownPlugin(mdPlugin.replace(/^ *| *$/g, '')));
}
break;
case 'include':
try {
if (!this.resolvePath.find(x => x.path === match[2])) { // if the include is in the path, it is a circular reference
let included = await this.getInclude(match[2], mainDir);
if (!this.resolvePath.find(x => x.path === commandMatch[2])) { // if the include is in the path, it is a circular reference
let included = await this.getInclude(commandMatch[2], mainDir);
inputLines.unshift(...included);
this.resolvePath.push({path: match[2], lines: included.length});
this.resolvePath.push({path: commandMatch[2], lines: included.length});
} else {
logger.warning(`Circular reference detected. Skipping include ${match[2]}`);
logger.warning(`Circular reference detected. Skipping include ${commandMatch[2]}`);
}
} catch (err) {
logger.error(err.message);
@ -70,28 +74,40 @@ export class CommandParser {
}
break;
case 'format':
if (!this.pageFormat && Object.values(pageFormats).includes(match[2]))
if (!this.pageFormat && Object.values(pageFormats).includes(commandMatch[2]))
// @ts-ignore
this.pageFormat = match[2];
this.pageFormat = commandMatch[2];
else
logger.warning('Invalid page format or format already set: ' + match[2]);
logger.warning('Invalid page format or format already set: ' + commandMatch[2]);
break;
case 'newpage':
renderer.addPlugin(getMarkdownPlugin(markdownPlugins.div));
outputLines.push('::: .newpage \n:::');
break;
case 'stylesheet':
await this.addStylesheet(match[2], mainDir);
await this.addStylesheet(commandMatch[2], mainDir);
break;
default:
outputLines.push(inputLine);
}
} else if (variableMatch) {
this.variables[variableMatch[1]] = variableMatch[2];
logger.debug(`Added variable: "${variableMatch[1]}": "${variableMatch[2]}"`);
} else {
outputLines.push(inputLine);
}
}
return outputLines.join('\n');
let documentContent = outputLines.join('\n');
// replacing all variables with their values.
for (let [key, value] of Object.entries(this.variables)) {
let varReplacer: RegExp = new RegExp(`\\$${key}`, "gi");
if (typeof value === "function")
value = await value();
// @ts-ignore
documentContent = documentContent.replace(varReplacer, value);
}
return documentContent;
}
/**

@ -4,7 +4,7 @@ import * as path from 'path';
import * as chokidar from 'chokidar';
import * as puppeteer from 'puppeteer';
import {JSDOM} from 'jsdom';
import {CommandParser} from "./CommandParser";
import {PreFormatter} from "./PreFormatter";
import {EventEmitter} from "events";
import {PDFFormat} from "puppeteer";
import {MarkdownConfig} from "./MarkdownConfig";
@ -15,7 +15,7 @@ export class Renderer extends EventEmitter {
private md: MarkdownIt;
private readonly beforeRendering: Function[];
private readonly afterRendering: Function[];
private commandParser: CommandParser;
private commandParser: PreFormatter;
private config: MarkdownConfig;
constructor(config?: MarkdownConfig) {
@ -24,7 +24,7 @@ export class Renderer extends EventEmitter {
this.md = new MarkdownIt();
this.beforeRendering = [];
this.afterRendering = [];
this.commandParser = new CommandParser();
this.commandParser = new PreFormatter();
this.configure();
}

@ -70,5 +70,8 @@ export const markdownPlugins: any = {
options: {
figcaption: true
}
},
'inline-comments': {
module: 'markdown-it-inline-comments'
}
};

@ -36,6 +36,9 @@ figcaption
margin: 0.5em
font-style: italic
.footnote-backref
display: none
.page
page-break-before: always
page-break-after: always

Loading…
Cancel
Save