# diff2html [![Codacy Quality Badge](https://api.codacy.com/project/badge/Grade/06412dc3f5a14f568778d0db8a1f7dc8)](https://www.codacy.com/app/rtfpessoa/diff2html?utm_source=github.com&utm_medium=referral&utm_content=rtfpessoa/diff2html&utm_campaign=Badge_Grade) [![Codacy Coverage Badge](https://api.codacy.com/project/badge/Coverage/06412dc3f5a14f568778d0db8a1f7dc8)](https://www.codacy.com/app/rtfpessoa/diff2html?utm_source=github.com&utm_medium=referral&utm_content=rtfpessoa/diff2html&utm_campaign=Badge_Coverage) [![CircleCI](https://circleci.com/gh/rtfpessoa/diff2html.svg?style=svg)](https://circleci.com/gh/rtfpessoa/diff2html) [![npm](https://img.shields.io/npm/v/diff2html.svg)](https://www.npmjs.com/package/diff2html) [![Dependency Status](https://david-dm.org/rtfpessoa/diff2html.svg)](https://david-dm.org/rtfpessoa/diff2html) [![devDependency Status](https://david-dm.org/rtfpessoa/diff2html/dev-status.svg)](https://david-dm.org/rtfpessoa/diff2html#info=devDependencies) [![cdnjs](https://img.shields.io/cdnjs/v/diff2html)](https://cdnjs.com/libraries/diff2html) [![node](https://img.shields.io/node/v/diff2html.svg)]() [![npm](https://img.shields.io/npm/l/diff2html.svg)]() [![npm](https://img.shields.io/npm/dm/diff2html.svg)](https://www.npmjs.com/package/diff2html) [![All Contributors](https://img.shields.io/badge/all_contributors-22-orange.svg?style=flat-square)](#contributors-) [![Gitter](https://badges.gitter.im/rtfpessoa/diff2html.svg)](https://gitter.im/rtfpessoa/diff2html?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) diff2html generates pretty HTML diffs from git diff or unified diff output. [![NPM](https://nodei.co/npm/diff2html.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/diff2html/) ## Features - Supports git and unified diffs - Line by line and Side by side diff - New and old line numbers - Inserted and removed lines - GitHub like visual style - Code syntax highlight - Line similarity matching - Easy code selection ## Online Example > Go to [diff2html](https://diff2html.xyz/) ## Distributions - [WebJar](http://www.webjars.org/) - [Node Library](https://www.npmjs.org/package/diff2html) - [NPM CLI](https://www.npmjs.org/package/diff2html-cli) - Manually download and import: - Browser / Bundle - Parser and HTML Generator - [bundles/js/diff2html.min.js](./bundles/js/diff2html.min.js) - includes the diff parser and html generator - Wrapper and helper adding syntax highlight, synchronized scroll, and other nice features - [bundles/js/diff2html-ui.min.js](./bundles/js/diff2html-ui.min.js) - includes the wrapper of diff2html with highlight for all `highlight.js` supported languages - [bundles/js/diff2html-ui-slim.min.js](./bundles/js/diff2html-ui-slim.min.js) - includes the wrapper of diff2html with "the most common" `highlight.js` supported languages - [bundles/js/diff2html-ui-base.min.js](./bundles/js/diff2html-ui-base.min.js) - includes the wrapper of diff2html without including a `highlight.js` implementation. You can use it without syntax highlight or by passing your own implementation with the languages you prefer - NPM / Node.js library - ES5 - [lib/diff2html.js](./lib/diff2html.js) - includes the diff parser and html generator - [lib/ui/js/diff2html-ui.js](./lib/ui/js/diff2html-ui.js) - includes the wrapper of diff2html with highlight for all `highlight.js` supported languages - [lib/ui/js/diff2html-ui-slim.js](./lib/ui/js/diff2html-ui-slim.js) - includes the wrapper of diff2html with "the most common" `highlight.js` supported languages - [lib/ui/js/diff2html-ui-base.js](./lib/ui/js/diff2html-ui-base.js) - ES6 - [lib-esm/diff2html.js](./lib-esm/diff2html.js) - includes the diff parser and html generator - [lib/ui/js/diff2html-ui.js](./lib/ui/js/diff2html-ui.js) - includes the wrapper of diff2html with highlight for all `highlight.js` supported languages - [lib/ui/js/diff2html-ui-slim.js](./lib/ui/js/diff2html-ui-slim.js) - includes the wrapper of diff2html with "the most common" `highlight.js` supported languages - [lib/ui/js/diff2html-ui-base.js](./lib/ui/js/diff2html-ui-base.js) - includes the wrapper of diff2html without including a `highlight.js` implementation. You can use it without syntax highlight or by passing your own implementation with the languages you prefer ## Diff2Html Usage To load correctly in the Browser you always need to include the stylesheet in the final HTML. Import the stylesheet ```html ``` You can also refer to it from a CDN like [CDNJS](https://cdnjs.com/libraries/diff2html). ### Diff2Html API > JSON representation of the diff ```ts function parse(diffInput: string, configuration: Diff2HtmlConfig = {}): DiffFile[]; ``` > Pretty HTML representation of the diff ```ts function html(diffInput: string | DiffFile[], configuration: Diff2HtmlConfig = {}): string; ``` > Check out the [docs/demo.html](./docs/demo.html) for a demo example. ### Diff2Html Configuration The HTML output accepts a Javascript object with configuration. Possible options: - `outputFormat`: the format of the output data: `'line-by-line'` or `'side-by-side'`, default is `'line-by-line'` - `drawFileList`: show a file list before the diff: `true` or `false`, default is `false` - `diffStyle`: show differences level in each line: `word` or `char`, default is `word` - `matching`: matching level: `'lines'` for matching lines, `'words'` for matching lines and words or `'none'`, default is `none` - `matchWordsThreshold`: similarity threshold for word matching, default is 0.25 - `matchingMaxComparisons`: perform at most this much comparisons for line matching a block of changes, default is `2500` - `maxLineSizeInBlockForComparison`: maximum number os characters of the bigger line in a block to apply comparison, default is `200` - `maxLineLengthHighlight`: only perform diff changes highlight if lines are smaller than this, default is `10000` - `renderNothingWhenEmpty`: render nothing if the diff shows no change in its comparison: `true` or `false`, default is `false` - `compiledTemplates`: object with previously compiled templates to replace parts of the html - `rawTemplates`: object with raw not compiled templates to replace parts of the html > For more information regarding the possible templates look into > [src/templates](https://github.com/rtfpessoa/diff2html/tree/master/src/templates) ### Diff2Html Browser Import the stylesheet and the library code ```html ``` It will now be available as a global variable named `Diff2Html`. ```js document.addEventListener('DOMContentLoaded', () => { var diffHtml = global.Diff2Html.html('', { drawFileList: true, matching: 'lines', outputFormat: 'side-by-side', }); document.getElementById('destination-elem-id').innerHTML = diffHtml; }); ``` ### Diff2Html NPM / Node.js Library ```js const Diff2html = require('diff2html'); const diffJson = Diff2html.parse(''); const diffHtml = Diff2html.html(diffJson, { drawFileList: true }); document.getElementById('destination-elem-id').innerHTML = diffHtml; ``` ### Diff2Html Examples #### Diff2Html Angular Example - Typescript ```typescript import * as Diff2Html from 'diff2html'; import { Component, OnInit } from '@angular/core'; export class AppDiffComponent implements OnInit { outputHtml: string; constructor() { this.init(); } ngOnInit() {} init() { let strInput = '--- a/server/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go\n+++ b/server/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go\n@@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (\n \n // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n \n+func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {\n+\tr0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))\n+\tn = int(r0)\n+\tif e1 != 0 {\n+\t\terr = errnoErr(e1)\n+\t}\n+\treturn\n+}\n+\n+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n+\n func read(fd int, p []byte) (n int, err error) {\n \tvar _p0 unsafe.Pointer\n \tif len(p) > 0 {\n'; let outputHtml = Diff2Html.html(strInput, { drawFileList: true, matching: 'lines' }); this.outputHtml = outputHtml; } } ``` - HTML ```html diff2html
``` - `.angular-cli.json` - Add styles ```json "styles": [ "diff2html.min.css" ] ``` #### Diff2Html Vue.js Example ```vue ``` ## Diff2HtmlUI > Simple wrapper to ease simple tasks in the browser such as: code highlight and js effects - Invoke Diff2html - Inject output in DOM element - Enable collapsible file summary list - Enable syntax highlight of the code in the diffs ### Diff2HtmlUI API > Create a Diff2HtmlUI instance ```ts constructor(target: HTMLElement, diffInput?: string | DiffFile[]) // diff2html-ui, diff2html-ui-slim constructor(target: HTMLElement, diffInput?: string | DiffFile[], config: Diff2HtmlUIConfig = {}, hljs?: HighlightJS) // diff2html-ui-base ``` > Generate and inject in the document the Pretty HTML representation of the diff ```ts draw(): void ``` > Enable extra features ```ts synchronisedScroll(): void fileListToggle(startVisible: boolean): void highlightCode(): void smartSelection(): void ``` > Check out the [docs/demo.html](./docs/demo.html) for a demo example. ### Diff2HtmlUI Configuration - `synchronisedScroll`: scroll both panes in side-by-side mode: `true` or `false`, default is `true` - `highlight`: syntax highlight the code on the diff: `true` or `false`, default is `true` - `fileListToggle`: allow the file summary list to be toggled: `true` or `false`, default is `true` - `fileListStartVisible`: choose if the file summary list starts visible: `true` or `false`, default is `false` - `smartSelection`: allow selection of the code without including line numbers of line prefixes: `true` or `false`, default is `true` > NOTE: All the options from Diff2Html are also valid configurations in Diff2HtmlUI ### Diff2HtmlUI Browser #### Mandatory HTML resource imports ```html ``` #### Init ```js const targetElement = document.getElementById('destination-elem-id'); const configuration = { drawFileList: true, matching: 'lines' }; const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration); // or const diff2htmlUi = new Diff2HtmlUI(targetElement, diffJson, configuration); ``` #### Draw ```js diff2htmlUi.draw(); ``` #### Syntax Highlight ```html ``` > Pass the option `highlight` with value true or invoke `diff2htmlUi.highlightCode()` after `diff2htmlUi.draw()`. ```js document.addEventListener('DOMContentLoaded', () => { const diffString = `diff --git a/sample.js b/sample.js index 0000001..0ddf2ba --- a/sample.js +++ b/sample.js @@ -1 +1 @@ -console.log("Hello World!") +console.log("Hello from Diff2Html!")`; const targetElement = document.getElementById('myDiffElement'); const configuration = { inputFormat: 'json', drawFileList: true, matching: 'lines', highlight: true }; const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration); diff2htmlUi.draw(); diff2htmlUi.highlightCode(); }); ``` #### Collapsable File Summary List > Add the dependencies. ```html ``` > Invoke the Diff2HtmlUI helper Pass the option `fileListToggle` with value true or invoke > `diff2htmlUi.fileListToggle()` after `diff2htmlUi.draw()`. ```js document.addEventListener('DOMContentLoaded', () => { const targetElement = document.getElementById('myDiffElement'); var diff2htmlUi = new Diff2HtmlUI(targetElement, lineDiffExample, { drawFileList: true, matching: 'lines' }); diff2htmlUi.draw(); diff2htmlUi.fileListToggle(false); }); ``` ## Troubleshooting ### 1. Out of memory or Slow execution #### Causes: - Big files - Big lines #### Fix: - Disable the line matching algorithm, by setting the option `{"matching": "none"}` when invoking diff2html ## Contributions This is a developer friendly project, all the contributions are welcome. To contribute just send a pull request with your changes following the guidelines described in `CONTRIBUTING.md`. I will try to review them as soon as possible. ## Contributors ✨ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

Rodrigo Fernandes

πŸ’»

stockmind

πŸ’»

Ivan Vorontsov

πŸ’»

Nick Brewer

πŸ’»

Matt Wade

πŸ›

Rafael CortΓͺs

πŸ’»

Nuno Teixeira

πŸ’»

Koki Oyatsu

πŸ›

James Monger

πŸ“–

Wessel van der Pal

πŸ›‘οΈ

jk-kim

πŸ’»

Sergey Semenov

πŸ›

Nick Mitchell

πŸ›

Samir Aguiar

πŸ“–

pubkey

πŸ“–

Илья

πŸ“–

Mohamed Akram

πŸ›

Eugene Marcotte

πŸ’»

Dima Sabanin

🚧

Ben Abbott

πŸ“–

εΌ˜ζ ‘@ι˜Ώι‡Œ

πŸ›

Mikko Rantanen

πŸ›

Ann

πŸ“–

escitalopram

πŸ› πŸ’»

dependabot[bot]

πŸ›‘οΈ 🚧

Josh Goldberg

πŸ’»
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! ## License Copyright 2014-present Rodrigo Fernandes. Released under the terms of the MIT license. ## Thanks This project is inspired in [pretty-diff](https://github.com/scottgonzalez/pretty-diff) by [Scott GonzΓ‘lez](https://github.com/scottgonzalez). ---