UNPKG

@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
"use strict"; 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