@sytone/markdown-snippet-injector
Version:
The MarkDown snippet injector generates MD code snippets by extracting them from the source code of your projects.
193 lines • 7.72 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Snippet = exports.snippetProperties = exports.snippetName = exports.snippetToken = exports.hideToken = exports.snippetEndPrefix = exports.snippetStartPrefix = exports.whitespaceNewline = exports.whitespace = void 0;
/* eslint-disable max-params */
/* eslint-disable import/extensions */
const os = __importStar(require("node:os"));
const log_1 = require("./log");
// Old Version: const ws = '[\\t ]*';
// const ws = '[^\\S\\r\\n]*';
// REGEX Refactor
// export const snippetExpressions = {
// name: '([a-z][a-zA-Z0-9-_?=&/\\\\\\.]*)',
// properties: '(?:&?[^=&]*=[^=&]*)*', // &prop1=value1&prop2=value2
// hide: '\\(hide\\)' + ws,
// start: '>>' + ws,
// end: '<<' + ws,
// };
exports.whitespace = /[^\S\r\n]/;
exports.whitespaceNewline = new RegExp(exports.whitespace.source + '\\r?\\n');
exports.snippetStartPrefix = new RegExp('>>' + exports.whitespace.source);
exports.snippetEndPrefix = new RegExp('<<' + exports.whitespace.source);
exports.hideToken = /\(hide\)/;
exports.snippetToken = /id='([a-z][\w-]*)'[^\S\r\n]*(?:options='(.*)')?/;
exports.snippetName = /([a-z][\w-?=&/\\.]*)/;
exports.snippetProperties = new RegExp('(?:&?[^=&]*=[^=&]*)*' + exports.whitespace.source);
// MD Regex: const regex = new RegExp(`${this.placeholderPrefix}${whitespace.source}*snippet${whitespace.source}+id=['"]([a-z][a-zA-Z0-9-_]*)['"]${whitespace.source}*(?:options=['"](.*)['"])?[\\S\\s]${this.placeholderSuffix}[\\S\\s]*?${this.placeholderPrefix}\\/snippet${this.placeholderSuffix}`, 'g');
// REGEX Refactor
// export const snippetExpressionsV2 = {
// name: '([a-z][a-zA-Z0-9-_?=&/\\\\\\.]*)',
// snippet: 'id=\'([a-z][a-zA-Z0-9-_]*)\'[^\\S\\r\\n]*(?:options=\'(.*)\')?',
// hide: '\\(hide\\)' + ws,
// start: />>/.source + /\s*/.source,
// end: /<</.source + /\s*/.source,
// whitespace: /\s*/,
// };
class Snippet {
programOptions;
token;
fileExtension;
sourceFile;
spec;
value;
id;
options;
endOfLineValue = '\n';
constructor(programOptions, token, fileExtension, sourceFile, spec) {
this.programOptions = programOptions;
this.token = token;
this.fileExtension = fileExtension;
this.sourceFile = sourceFile;
this.spec = spec;
this.value = '';
const match = sourceFile.openRegExp.exec(token);
if (programOptions.useOsEol) {
this.endOfLineValue = os.EOL;
}
log_1.log.debug('Snippet Token', token);
log_1.log.debug('Snippet Start Regex', sourceFile.openRegExp);
if (match) {
log_1.log.debug('Snippet ID:', match[1]);
log_1.log.debug('Snippet Options:', match[2]);
this.id = match[1];
this.options = match[2];
}
}
get originalValue() {
return this.value;
}
get file() {
return this.getOptionsValue('file');
}
get header() {
return this.getOptionsValue('header');
}
get footer() {
return this.getOptionsValue('footer');
}
getOptionsValue(key) {
if (this.options) {
const value = this.options.split('&').find(p => p.startsWith(key + '='));
if (value) {
return value.split('=')[1];
}
}
return '';
}
get processedValue() {
let snippet = this.value
.replace(this.sourceFile.openReplacerRegExp, '')
.replace(this.sourceFile.closeReplacerRegExp, '');
snippet = this.trimWhiteSpaces(snippet);
if (this.spec.postProcess) {
snippet = this.spec.postProcess(snippet);
}
snippet = this.removeHiddenBlocks(snippet, this.spec);
return snippet;
}
test() {
log_1.log.info('Snippet test');
}
trimWhiteSpaces(snippet) {
// Const hasText = (str: string) => /\S/;
snippet = snippet.replaceAll('\t', ' '); // Replace tabs with 4 spaces
const lines = snippet.split(/\r?\n/);
// Remove lines that has no text at start of snippet
while (lines.length > 0 && !this.lineHasText(lines[0])) {
lines.shift();
}
// Remove lines that has no text at end of snippet
while (lines.length > 0 && !this.lineHasText(lines.at(-1))) {
lines.pop();
}
// Get starting spaces
let minStartingSpaces = Number.POSITIVE_INFINITY;
for (const line of lines) {
if (/\S/.test(line)) {
const spaces = /^ */.exec(line);
if (spaces) {
const spacesOnLeft = spaces[0].length;
minStartingSpaces = Math.min(minStartingSpaces, spacesOnLeft);
}
}
}
// Remove starting spaces
if (minStartingSpaces !== Number.POSITIVE_INFINITY && minStartingSpaces > 0) {
for (let i = 0; i < lines.length; i++) {
if (/\S/.test(lines[i])) {
lines[i] = lines[i].slice(minStartingSpaces);
}
}
}
return lines.join(this.endOfLineValue);
}
lineHasText(line) {
if (line !== undefined) {
return /\S/.test(line);
}
return false;
}
removeHiddenBlocks(snippet, spec) {
const startExp = new RegExp(spec.commentStart + exports.snippetStartPrefix.source + exports.hideToken.source + spec.commentEnd, 'g');
const endExp = new RegExp(spec.commentStart + exports.snippetEndPrefix.source + exports.hideToken.source + spec.commentEnd, 'g');
// eslint-disable-next-line @typescript-eslint/ban-types
let match;
const startMatches = new Array();
const endMatches = new Array();
// eslint-disable-next-line no-cond-assign
while (match = startExp.exec(snippet)) {
startMatches.push(match);
}
// eslint-disable-next-line no-cond-assign
while (match = endExp.exec(snippet)) {
endMatches.push(match);
}
// Validate
if (startMatches.length !== endMatches.length) {
throw new Error('Start and end match blocks don\'t match for snippet: ' + snippet);
}
for (let i = startMatches.length - 1; i >= 0; i--) {
const start = startMatches[i];
const end = endMatches[i];
if (start.index && end.index) {
snippet = snippet.slice(0, Math.max(0, start.index)) + snippet.slice(Math.max(0, end.index + end[0].length));
}
}
return snippet;
}
}
exports.Snippet = Snippet;
//# sourceMappingURL=snippet.js.map