UNPKG

markdown-diff

Version:

Generate a diff between two markdown files in markdown format

154 lines 9.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Generator = void 0; /* tslint:disable:max-line-length */ const marked_1 = require("marked"); const type_to_string_1 = require("./type-to-string"); const type_mapping_1 = require("./type-mapping"); const jsdiff_util_1 = require("./jsdiff.util"); var Renderer = marked_1.marked.Renderer; class Generator { constructor() { this.rendered = new Renderer(); } /** * exec */ exec(oldString, newString) { const oldLexer = new marked_1.marked.Lexer(); const tokens = oldLexer.lex(oldString); const newLexer = new marked_1.marked.Lexer(); const newTokens = newLexer.lex(newString); const output = this.walkTokens(newTokens, tokens); return output.join(Generator.newLine); } walkTokens(newTokens, oldTokens) { const output = []; let i = 0; const innerNew = newTokens || []; const innerOld = oldTokens || []; for (i; i < innerOld.length && i < innerNew.length; i += 1) { output.push(...this.handleToken(innerNew[i], innerOld[i])); } for (i; i < innerOld.length; i += 1) { output.push(...this.handleToken(null, innerOld[i])); } for (i; i < innerNew.length; i += 1) { output.push(...this.handleToken(innerNew[i], null)); } return output; } handleToken(newToken, oldToken) { const output = []; if ((oldToken === null || type_mapping_1.TypeMapping.isList(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isList(newToken))) { const prefixOld = oldToken && oldToken.ordered ? oldToken.start : null; const prefixNew = newToken && newToken.ordered ? newToken.start : null; let prefix = prefixNew || prefixOld; const oldItems = oldToken ? oldToken.items.map((e) => e.text) : []; const newItems = newToken ? newToken.items.map((e) => e.text) : []; // tslint:disable-next-line:no-increment-decrement const res = jsdiff_util_1.JsDiffUtil.diffArrayByIndex(newItems, oldItems).map((e) => { if (prefix) { const result = `${prefix}. ${e}`; prefix += 1; return result; } return `* ${e}`; }); output.push(...res); return output; } if ((oldToken === null || type_mapping_1.TypeMapping.isLink(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isLink(newToken))) { if ((oldToken === null || oldToken === void 0 ? void 0 : oldToken.text) !== (newToken === null || newToken === void 0 ? void 0 : newToken.text) || (oldToken === null || oldToken === void 0 ? void 0 : oldToken.href) !== (newToken === null || newToken === void 0 ? void 0 : newToken.href) || (oldToken === null || oldToken === void 0 ? void 0 : oldToken.title) !== (newToken === null || newToken === void 0 ? void 0 : newToken.title)) { if (oldToken) { output.push(type_to_string_1.TypeToString.link(oldToken, 'del')); } if (newToken) { output.push(type_to_string_1.TypeToString.link(newToken, 'ins')); } } else { output.push(type_to_string_1.TypeToString.link(newToken, '')); } return output; // Skip children } if ((oldToken === null || type_mapping_1.TypeMapping.isTable(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isTable(newToken))) { const headers = jsdiff_util_1.JsDiffUtil.diffArrayByIndex(newToken === null || newToken === void 0 ? void 0 : newToken.header.map((e) => e.text), oldToken === null || oldToken === void 0 ? void 0 : oldToken.header.map((e) => e.text)); output.push(`|${headers.join('|')}|`); const alignment = newToken || oldToken; output.push(type_to_string_1.TypeToString.tableAlign(alignment)); const content = jsdiff_util_1.JsDiffUtil.doubleStringArrayDiff(newToken === null || newToken === void 0 ? void 0 : newToken.rows.map((e) => e.map((i) => i.text)), oldToken === null || oldToken === void 0 ? void 0 : oldToken.rows.map((e) => e.map((i) => i.text))); for (let i = 0; i < content.length; i += 1) { output.push(`|${content[i].join('|')}|`); } return output; // Skip children } if ((oldToken === null || type_mapping_1.TypeMapping.isHeading(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isHeading(newToken))) { const count = newToken ? newToken.depth : oldToken.depth; const depth = '#'.repeat(count); output.push(`${depth} ${jsdiff_util_1.JsDiffUtil.diffWords(newToken === null || newToken === void 0 ? void 0 : newToken.text, oldToken === null || oldToken === void 0 ? void 0 : oldToken.text)}`); return output; // Skip children } if ((oldToken === null || type_mapping_1.TypeMapping.isCode(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isCode(newToken))) { output.push(`\`\`\`${oldToken === null || oldToken === void 0 ? void 0 : oldToken.lang}`); const content = jsdiff_util_1.JsDiffUtil.diffCodeLines(newToken === null || newToken === void 0 ? void 0 : newToken.text.split(Generator.newLine), oldToken === null || oldToken === void 0 ? void 0 : oldToken.text.split(Generator.newLine)); output.push(content); output.push('```'); return output; // Skip children } if ((oldToken === null || type_mapping_1.TypeMapping.isCodespan(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isCodespan(newToken))) { let res = ''; if ((oldToken === null || oldToken === void 0 ? void 0 : oldToken.text) !== (newToken === null || newToken === void 0 ? void 0 : newToken.text)) { if (oldToken) { res += `<del>\`${oldToken.text}\`</del>`; } if (newToken) { res += `<ins>\`${newToken.text}\`</ins>`; } } else { res = `\`${newToken.text}\``; } output.push(res); return output; // Skip children } if ((oldToken === null || type_mapping_1.TypeMapping.isBlockQuote(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isBlockQuote(newToken))) { const newVals = newToken === null || newToken === void 0 ? void 0 : newToken.tokens.map((e) => (type_mapping_1.TypeMapping.isSpace(e) ? '' : e.raw)); const oldVals = oldToken === null || oldToken === void 0 ? void 0 : oldToken.tokens.map((e) => (type_mapping_1.TypeMapping.isSpace(e) ? '' : e.raw)); const res = jsdiff_util_1.JsDiffUtil.diffArrayByIndex(newVals, oldVals); output.push(...res.map((e) => `> ${e}`)); return output; } if ((oldToken === null || type_mapping_1.TypeMapping.isStrong(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isStrong(newToken))) { output.push(`**${jsdiff_util_1.JsDiffUtil.diffWords(newToken === null || newToken === void 0 ? void 0 : newToken.text, oldToken === null || oldToken === void 0 ? void 0 : oldToken.text)}**`); return output; } if ((oldToken === null || type_mapping_1.TypeMapping.isEm(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isEm(newToken))) { output.push(`*${jsdiff_util_1.JsDiffUtil.diffWords(newToken === null || newToken === void 0 ? void 0 : newToken.text, oldToken === null || oldToken === void 0 ? void 0 : oldToken.text)}*`); return output; } if ((oldToken === null || type_mapping_1.TypeMapping.isBr(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isBr(newToken))) { let res = ''; if (oldToken && !newToken) { res = '<del></del>'; } if (!oldToken && newToken) { res = '<ins></ins>'; } output.push(res + this.rendered.br()); } if ((oldToken === null || type_mapping_1.TypeMapping.isText(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.isText(newToken))) { output.push(jsdiff_util_1.JsDiffUtil.diffWords(newToken === null || newToken === void 0 ? void 0 : newToken.text, oldToken === null || oldToken === void 0 ? void 0 : oldToken.text)); } if ((oldToken === null || type_mapping_1.TypeMapping.hasTokens(oldToken)) && (newToken === null || type_mapping_1.TypeMapping.hasTokens(newToken))) { output.push(this.walkTokens(newToken === null || newToken === void 0 ? void 0 : newToken.tokens, oldToken === null || oldToken === void 0 ? void 0 : oldToken.tokens).join('')); } return output; } } exports.Generator = Generator; Generator.newLine = '\n'; //# sourceMappingURL=generator.js.map