diff --git a/.gitignore b/.gitignore index a23a04d..42ee49f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules/ lib/ .mocharc.yml *.pdf +test/*.actual diff --git a/README.md b/README.md index 575f8cb..c4a733e 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ Usage: pandiff [OPTIONS] FILE1 FILE2 -t, --to=FORMAT -v, --version --wrap=STRING + --metadata ``` ### Git integration diff --git a/src/cli.ts b/src/cli.ts index df2f5a7..f4c2ff4 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -54,6 +54,7 @@ const optionDefinitions: commandLineArgs.OptionDefinition[] = [ {name: 'version', alias: 'v', type: Boolean}, {name: 'wrap', type: String}, {name: 'files', multiple: true, defaultOption: true}, + {name: 'metadata', type: String}, ]; function help() { diff --git a/src/index.spec.ts b/src/index.spec.ts index 78c91a4..998f391 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -159,3 +159,84 @@ describe('Misc', () => { expectWithFallback(output, expected, 'test/diff-table.html'); }); }); + +describe('Metadata', () => { + it('keep metadata from old document', async () => { + const output = await pandiff( + 'test/old-metadata.md', + 'test/new-metadata.md', + { + files: true, + metadata: 'old', + to: 'markdown', + } + ); + const expected = fs.readFileSync('test/keep-old-metadata-diff.md', 'utf8'); + expect(output, expected); + }); + it('keep metadata from new document', async () => { + const output = await pandiff( + 'test/old-metadata.md', + 'test/new-metadata.md', + { + files: true, + metadata: 'new', + to: 'markdown', + } + ); + const expected = fs.readFileSync('test/keep-new-metadata-diff.md', 'utf8'); + expect(output, expected); + }); + it('keep metadata from no document', async () => { + const output = await pandiff( + 'test/old-metadata.md', + 'test/new-metadata.md', + { + files: true, + metadata: 'none', + to: 'markdown', + } + ); + const expected = fs.readFileSync('test/keep-no-metadata-diff.md', 'utf8'); + expect(output, expected); + }); + it('keep metadata from old document without metadata', async () => { + const output = await pandiff('test/old.md', 'test/new.md', { + files: true, + metadata: 'old', + to: 'markdown', + }); + const expected = fs.readFileSync('test/diff.md', 'utf8'); + expect(output, expected); + }); + it('keep metadata from new document without metadata', async () => { + const output = await pandiff('test/old.md', 'test/new.md', { + files: true, + metadata: 'new', + to: 'markdown', + }); + const expected = fs.readFileSync('test/diff.md', 'utf8'); + expect(output, expected); + }); + it('keep metadata none document without metadata', async () => { + const output = await pandiff('test/old.md', 'test/new.md', { + files: true, + metadata: 'none', + to: 'markdown', + }); + const expected = fs.readFileSync('test/diff.md', 'utf8'); + expect(output, expected); + }); + it('keep no metadata if metadata is not specified', async () => { + const output = await pandiff( + 'test/old-metadata.md', + 'test/new-metadata.md', + { + files: true, + to: 'markdown', + } + ); + const expected = fs.readFileSync('test/keep-no-metadata-diff.md', 'utf8'); + expect(output, expected); + }); +}); diff --git a/src/index.ts b/src/index.ts index f6203a3..8b336ce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -263,11 +263,38 @@ async function convert(source: string, opts: pandiff.Options = {}) { return html; } +async function extractMetadata(source: string) { + const file = fs.readFileSync(source, 'utf8'); + const lines = file.split('\n'); + if (lines[0].trim() !== '---') return ''; + + const metadata = [lines[0]]; + for (let i = 1; i < lines.length; i++) { + metadata.push(lines[i]); + if (lines[i].trim() === '---') break; + } + + return metadata.join('\n') + '\n'; +} + async function pandiff( source1: string, source2: string, opts: pandiff.Options = {} ): Promise { + let metadata = ''; + switch (opts.metadata) { + case 'old': + opts.standalone = true; + metadata = await extractMetadata(source1); + break; + case 'new': + opts.standalone = true; + metadata = await extractMetadata(source2); + break; + default: + break; + } const html1 = await convert(source1, opts); const html2 = await convert(source2, opts); const html = htmldiff(html1, html2); @@ -282,7 +309,7 @@ async function pandiff( ); return null; } else { - return render(html, opts); + return render(html, opts, metadata); } } @@ -319,7 +346,7 @@ const regex = { }, }; -async function render(html: string, opts: pandiff.Options = {}) { +async function render(html: string, opts: pandiff.Options = {}, metadata = '') { html = postprocess(html); const args = buildArgs(opts, 'reference-links'); args.push('--wrap=none'); @@ -357,7 +384,7 @@ async function render(html: string, opts: pandiff.Options = {}) { } } const text = lines.join('\n'); - return postrender(text, opts); + return postrender(text, opts, metadata); } const criticHTML = (text: string) => @@ -411,8 +438,12 @@ const pandocOptionsHTML = [ '--standalone', ]; -async function postrender(text: string, opts: pandiff.Options = {}) { - if (!opts.output && !opts.to) return text; +async function postrender( + text: string, + opts: pandiff.Options = {}, + metadata = '' +) { + if (!opts.output && !opts.to) return `${metadata}${text}`; if (!('highlight-style' in opts)) opts['highlight-style'] = 'kate'; let args = buildArgs( @@ -446,19 +477,21 @@ async function postrender(text: string, opts: pandiff.Options = {}) { if (opts.standalone) args = args.concat(pandocOptionsHTML); } + if (opts.standalone) args = args.concat('-s'); + if (opts.output) { - await sh.pandoc(...args).end(text); + await sh.pandoc(...args).end(`${metadata}${text}`); return null; } else { return sh .pandoc(...args) - .end(text) + .end(`${metadata}${text}`) .toString(); } } export = pandiff; -namespace pandiff { // eslint-disable-line + namespace pandiff { // eslint-disable-line export type File = string; export type Format = string; export type Path = string; @@ -484,6 +517,7 @@ namespace pandiff { // eslint-disable-line version?: boolean; wrap?: 'auto' | 'none' | 'preserve'; files?: boolean; + metadata?: 'new' | 'old' | 'none'; } /* eslint-disable no-inner-declarations */ export async function trackChanges( diff --git a/test/keep-new-metadata-diff.md b/test/keep-new-metadata-diff.md new file mode 100644 index 0000000..2c766f0 --- /dev/null +++ b/test/keep-new-metadata-diff.md @@ -0,0 +1,15 @@ +--- +title: New Title +--- + +# {\~~Some~\>Differnt\~\~} Text + +Lorem {--ipsum --}dolor sit {~~amet,\~\>amet test,~~} consetetur +sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et +dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et +justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea +takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit +amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor +invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At +vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd +gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. diff --git a/test/keep-no-metadata-diff.md b/test/keep-no-metadata-diff.md new file mode 100644 index 0000000..01bd4aa --- /dev/null +++ b/test/keep-no-metadata-diff.md @@ -0,0 +1,11 @@ +# {\~~Some~\>Differnt\~\~} Text + +Lorem {--ipsum --}dolor sit {~~amet,\~\>amet test,~~} consetetur +sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et +dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et +justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea +takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit +amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor +invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At +vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd +gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. diff --git a/test/keep-old-metadata-diff.md b/test/keep-old-metadata-diff.md new file mode 100644 index 0000000..8b79450 --- /dev/null +++ b/test/keep-old-metadata-diff.md @@ -0,0 +1,15 @@ +--- +title: Old Title +--- + +# {\~~Some~\>Differnt\~\~} Text + +Lorem {--ipsum --}dolor sit {~~amet,\~\>amet test,~~} consetetur +sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et +dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et +justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea +takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit +amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor +invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At +vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd +gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. diff --git a/test/new-metadata.md b/test/new-metadata.md new file mode 100644 index 0000000..1ad7d0f --- /dev/null +++ b/test/new-metadata.md @@ -0,0 +1,6 @@ +--- +title: New Title +--- + +# Differnt Text +Lorem dolor sit amet test, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. diff --git a/test/old-metadata.md b/test/old-metadata.md new file mode 100644 index 0000000..6887d41 --- /dev/null +++ b/test/old-metadata.md @@ -0,0 +1,6 @@ +--- +title: Old Title +--- + +# Some Text +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.