markdown-diff
Version:
Generate a diff between two markdown files in markdown format
154 lines • 9.23 kB
JavaScript
;
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