445 lines
41 KiB
HTML
445 lines
41 KiB
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title> a post with code diff | Vinicius F. Silva </title> <meta name="author" content="Vinicius F. Silva"> <meta name="description" content="this is how you can display code diffs"> <meta name="keywords" content="jekyll, jekyll-theme, academic-website, portfolio-website"> <link rel="stylesheet" href="/al-folio/assets/css/bootstrap.min.css?a4b3f509e79c54a512b890d73235ef04"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mdbootstrap@4.20.0/css/mdb.min.css" integrity="sha256-jpjYvU3G3N6nrrBwXJoVEYI/0zw8htfFnhT9ljN3JJw=" crossorigin="anonymous"> <link defer rel="stylesheet" href="/al-folio/assets/css/academicons.min.css?f0b7046b84e425c55f3463ac249818f5"> <link defer rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Roboto+Slab:100,300,400,500,700|Material+Icons&display=swap"> <link defer rel="stylesheet" href="/al-folio/assets/css/jekyll-pygments-themes-github.css?591dab5a4e56573bf4ef7fd332894c99" media="" id="highlight_theme_light"> <link rel="shortcut icon" href="data:image/svg+xml,<svg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%20100%20100%22><text%20y=%22.9em%22%20font-size=%2290%22>%F0%9F%91%A9%F0%9F%8F%BB%E2%80%8D%F0%9F%92%BB</text></svg>"> <link rel="stylesheet" href="/al-folio/assets/css/main.css?d41d8cd98f00b204e9800998ecf8427e"> <link rel="canonical" href="https://alshedivat.github.io/al-folio/blog/2024/code-diff/"> <script src="/al-folio/assets/js/theme.js?9a0c749ec5240d9cda97bc72359a72c0"></script> <link defer rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/github.min.css" integrity="sha256-Oppd74ucMR5a5Dq96FxjEzGF7tTw2fZ/6ksAqDCM8GY=" crossorigin="anonymous" media="screen and (prefers-color-scheme: light)"> <link defer rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/github-dark.min.css" integrity="sha256-nyCNAiECsdDHrr/s2OQsp5l9XeY2ZJ0rMepjCT2AkBk=" crossorigin="anonymous" media="screen and (prefers-color-scheme: dark)"> <link defer rel="stylesheet" href="https://cdn.jsdelivr.net/npm/diff2html@3.4.47/bundles/css/diff2html.min.css" integrity="sha256-IMBK4VNZp0ivwefSn51bswdsrhk0HoMTLc2GqFHFBXg=" crossorigin="anonymous"> </head> <body class="fixed-top-nav "> <header> <nav id="navbar" class="navbar navbar-light navbar-expand-sm fixed-top" role="navigation"> <div class="container"> <a class="navbar-brand title font-weight-lighter" href="/al-folio/"> <span class="font-weight-bold">Vinicius</span> F. Silva </a> <button class="navbar-toggler collapsed ml-auto" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar top-bar"></span> <span class="icon-bar middle-bar"></span> <span class="icon-bar bottom-bar"></span> </button> <div class="collapse navbar-collapse text-right" id="navbarNav"> <ul class="navbar-nav ml-auto flex-nowrap"> <li class="nav-item "> <a class="nav-link" href="/al-folio/">about </a> </li> <li class="nav-item "> <a class="nav-link" href="/al-folio/education/">education </a> </li> <li class="nav-item "> <a class="nav-link" href="/al-folio/experience/">experience </a> </li> <li class="nav-item "> <a class="nav-link" href="/al-folio/works/">works </a> </li> <li class="nav-item "> <a class="nav-link" href="/al-folio/projects/">projects </a> </li> <li class="nav-item "> <a class="nav-link" href="/al-folio/certificates/">certificates </a> </li> <li class="nav-item "> <a class="nav-link" href="/al-folio/cv/">cv </a> </li> <li class="nav-item "> <a class="nav-link" href="/al-folio/glo/index.html">talk with me </a> </li> <li class="nav-item"> <button id="search-toggle" title="Search" onclick="openSearchModal()"> <span class="nav-link">ctrl k <i class="ti ti-search"></i></span> </button> </li> </ul> </div> </div> </nav> <progress id="progress" value="0"> <div class="progress-container"> <span class="progress-bar"></span> </div> </progress> </header> <div class="container mt-5" role="main"> <div class="post"> <header class="post-header"> <h1 class="post-title">a post with code diff</h1> <p class="post-meta"> Created in January 27, 2024 </p> <p class="post-tags"> <a href="/al-folio/blog/2024"> <i class="fa-solid fa-calendar fa-sm"></i> 2024 </a> · <a href="/al-folio/blog/tag/formatting"> <i class="fa-solid fa-hashtag fa-sm"></i> formatting</a> <a href="/al-folio/blog/tag/code"> <i class="fa-solid fa-hashtag fa-sm"></i> code</a> · <a href="/al-folio/blog/category/sample-posts"> <i class="fa-solid fa-tag fa-sm"></i> sample-posts</a> </p> </header> <article class="post-content"> <div id="markdown-content"> <p>You can display diff code by using the regular markdown syntax:</p> <div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">```</span><span class="nl">diff
|
||
</span><span class="gh">diff --git a/sample.js b/sample.js
|
||
index 0000001..0ddf2ba
|
||
</span><span class="gd">--- a/sample.js
|
||
</span><span class="gi">+++ b/sample.js
|
||
</span><span class="p">@@ -1 +1 @@</span>
|
||
<span class="gd">-console.log("Hello World!")
|
||
</span><span class="gi">+console.log("Hello from Diff2Html!")</span>
|
||
<span class="p">```</span>
|
||
</code></pre></div></div> <p>Which generates:</p> <div class="language-diff highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh">diff --git a/sample.js b/sample.js
|
||
index 0000001..0ddf2ba
|
||
</span><span class="gd">--- a/sample.js
|
||
</span><span class="gi">+++ b/sample.js
|
||
</span><span class="p">@@ -1 +1 @@</span>
|
||
<span class="gd">-console.log("Hello World!")
|
||
</span><span class="gi">+console.log("Hello from Diff2Html!")
|
||
</span></code></pre></div></div> <p>But this is difficult to read, specially if you have a large diff. You can use <a href="https://diff2html.xyz/" rel="external nofollow noopener" target="_blank">diff2html</a> to display a more readable version of the diff. For this, just use <code class="language-plaintext highlighter-rouge">diff2html</code> instead of <code class="language-plaintext highlighter-rouge">diff</code> for the code block language:</p> <div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">```</span><span class="nl">diff2html
|
||
</span><span class="sb">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!")</span>
|
||
<span class="p">```</span>
|
||
</code></pre></div></div> <p>If we use a longer example, for example <a href="https://github.com/rtfpessoa/diff2html/commit/c2c253d3e3f8b8b267f551e659f72b44ca2ac927" rel="external nofollow noopener" target="_blank">this commit from diff2html</a>, it will generate the following output:</p> <pre><code class="language-diff2html">From 2aaae31cc2a37bfff83430c2c914b140bee59b6a Mon Sep 17 00:00:00 2001
|
||
From: Rodrigo Fernandes <rtfrodrigo@gmail.com>
|
||
Date: Sun, 9 Oct 2016 16:41:54 +0100
|
||
Subject: [PATCH 1/2] Initial template override support
|
||
|
||
---
|
||
scripts/hulk.js | 4 ++--
|
||
src/diff2html.js | 3 +--
|
||
src/file-list-printer.js | 11 ++++++++---
|
||
src/hoganjs-utils.js | 29 +++++++++++++++++------------
|
||
src/html-printer.js | 6 ++++++
|
||
src/line-by-line-printer.js | 6 +++++-
|
||
src/side-by-side-printer.js | 6 +++++-
|
||
test/file-list-printer-tests.js | 2 +-
|
||
test/hogan-cache-tests.js | 18 +++++++++++++++---
|
||
test/line-by-line-tests.js | 3 +--
|
||
test/side-by-side-printer-tests.js | 3 +--
|
||
11 files changed, 62 insertions(+), 29 deletions(-)
|
||
|
||
diff --git a/scripts/hulk.js b/scripts/hulk.js
|
||
index 5a793c18..a4b1a4d5 100755
|
||
--- a/scripts/hulk.js
|
||
+++ b/scripts/hulk.js
|
||
@@ -173,11 +173,11 @@ function namespace(name) {
|
||
// write a template foreach file that matches template extension
|
||
templates = extractFiles(options.argv.remain)
|
||
.map(function(file) {
|
||
- var openedFile = fs.readFileSync(file, 'utf-8');
|
||
+ var openedFile = fs.readFileSync(file, 'utf-8').trim();
|
||
var name;
|
||
if (!openedFile) return;
|
||
name = namespace(path.basename(file).replace(/\..*$/, ''));
|
||
- openedFile = removeByteOrderMark(openedFile.trim());
|
||
+ openedFile = removeByteOrderMark(openedFile);
|
||
openedFile = wrap(file, name, openedFile);
|
||
if (!options.outputdir) return openedFile;
|
||
fs.writeFileSync(path.join(options.outputdir, name + '.js')
|
||
diff --git a/src/diff2html.js b/src/diff2html.js
|
||
index 21b0119e..64e138f5 100644
|
||
--- a/src/diff2html.js
|
||
+++ b/src/diff2html.js
|
||
@@ -7,7 +7,6 @@
|
||
|
||
(function() {
|
||
var diffParser = require('./diff-parser.js').DiffParser;
|
||
- var fileLister = require('./file-list-printer.js').FileListPrinter;
|
||
var htmlPrinter = require('./html-printer.js').HtmlPrinter;
|
||
|
||
function Diff2Html() {
|
||
@@ -43,7 +42,7 @@
|
||
|
||
var fileList = '';
|
||
if (configOrEmpty.showFiles === true) {
|
||
- fileList = fileLister.generateFileList(diffJson, configOrEmpty);
|
||
+ fileList = htmlPrinter.generateFileListSummary(diffJson, configOrEmpty);
|
||
}
|
||
|
||
var diffOutput = '';
|
||
diff --git a/src/file-list-printer.js b/src/file-list-printer.js
|
||
index e408d9b2..1e0a2c61 100644
|
||
--- a/src/file-list-printer.js
|
||
+++ b/src/file-list-printer.js
|
||
@@ -8,11 +8,16 @@
|
||
(function() {
|
||
var printerUtils = require('./printer-utils.js').PrinterUtils;
|
||
|
||
- var hoganUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
||
+ var hoganUtils;
|
||
+
|
||
var baseTemplatesPath = 'file-summary';
|
||
var iconsBaseTemplatesPath = 'icon';
|
||
|
||
- function FileListPrinter() {
|
||
+ function FileListPrinter(config) {
|
||
+ this.config = config;
|
||
+
|
||
+ var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
||
+ hoganUtils = new HoganJsUtils(config);
|
||
}
|
||
|
||
FileListPrinter.prototype.generateFileList = function(diffFiles) {
|
||
@@ -38,5 +43,5 @@
|
||
});
|
||
};
|
||
|
||
- module.exports.FileListPrinter = new FileListPrinter();
|
||
+ module.exports.FileListPrinter = FileListPrinter;
|
||
})();
|
||
diff --git a/src/hoganjs-utils.js b/src/hoganjs-utils.js
|
||
index 9949e5fa..0dda08d7 100644
|
||
--- a/src/hoganjs-utils.js
|
||
+++ b/src/hoganjs-utils.js
|
||
@@ -8,18 +8,19 @@
|
||
(function() {
|
||
var fs = require('fs');
|
||
var path = require('path');
|
||
-
|
||
var hogan = require('hogan.js');
|
||
|
||
var hoganTemplates = require('./templates/diff2html-templates.js');
|
||
|
||
- var templatesPath = path.resolve(__dirname, 'templates');
|
||
+ var extraTemplates;
|
||
|
||
- function HoganJsUtils() {
|
||
+ function HoganJsUtils(configuration) {
|
||
+ this.config = configuration || {};
|
||
+ extraTemplates = this.config.templates || {};
|
||
}
|
||
|
||
- HoganJsUtils.prototype.render = function(namespace, view, params, configuration) {
|
||
- var template = this.template(namespace, view, configuration);
|
||
+ HoganJsUtils.prototype.render = function(namespace, view, params) {
|
||
+ var template = this.template(namespace, view);
|
||
if (template) {
|
||
return template.render(params);
|
||
}
|
||
@@ -27,17 +28,16 @@
|
||
return null;
|
||
};
|
||
|
||
- HoganJsUtils.prototype.template = function(namespace, view, configuration) {
|
||
- var config = configuration || {};
|
||
+ HoganJsUtils.prototype.template = function(namespace, view) {
|
||
var templateKey = this._templateKey(namespace, view);
|
||
|
||
- return this._getTemplate(templateKey, config);
|
||
+ return this._getTemplate(templateKey);
|
||
};
|
||
|
||
- HoganJsUtils.prototype._getTemplate = function(templateKey, config) {
|
||
+ HoganJsUtils.prototype._getTemplate = function(templateKey) {
|
||
var template;
|
||
|
||
- if (!config.noCache) {
|
||
+ if (!this.config.noCache) {
|
||
template = this._readFromCache(templateKey);
|
||
}
|
||
|
||
@@ -53,6 +53,7 @@
|
||
|
||
try {
|
||
if (fs.readFileSync) {
|
||
+ var templatesPath = path.resolve(__dirname, 'templates');
|
||
var templatePath = path.join(templatesPath, templateKey);
|
||
var templateContent = fs.readFileSync(templatePath + '.mustache', 'utf8');
|
||
template = hogan.compile(templateContent);
|
||
@@ -66,12 +67,16 @@
|
||
};
|
||
|
||
HoganJsUtils.prototype._readFromCache = function(templateKey) {
|
||
- return hoganTemplates[templateKey];
|
||
+ return extraTemplates[templateKey] || hoganTemplates[templateKey];
|
||
};
|
||
|
||
HoganJsUtils.prototype._templateKey = function(namespace, view) {
|
||
return namespace + '-' + view;
|
||
};
|
||
|
||
- module.exports.HoganJsUtils = new HoganJsUtils();
|
||
+ HoganJsUtils.prototype.compile = function(templateStr) {
|
||
+ return hogan.compile(templateStr);
|
||
+ };
|
||
+
|
||
+ module.exports.HoganJsUtils = HoganJsUtils;
|
||
})();
|
||
diff --git a/src/html-printer.js b/src/html-printer.js
|
||
index 585d5b66..13f83047 100644
|
||
--- a/src/html-printer.js
|
||
+++ b/src/html-printer.js
|
||
@@ -8,6 +8,7 @@
|
||
(function() {
|
||
var LineByLinePrinter = require('./line-by-line-printer.js').LineByLinePrinter;
|
||
var SideBySidePrinter = require('./side-by-side-printer.js').SideBySidePrinter;
|
||
+ var FileListPrinter = require('./file-list-printer.js').FileListPrinter;
|
||
|
||
function HtmlPrinter() {
|
||
}
|
||
@@ -22,5 +23,10 @@
|
||
return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles);
|
||
};
|
||
|
||
+ HtmlPrinter.prototype.generateFileListSummary = function(diffJson, config) {
|
||
+ var fileListPrinter = new FileListPrinter(config);
|
||
+ return fileListPrinter.generateFileList(diffJson);
|
||
+ };
|
||
+
|
||
module.exports.HtmlPrinter = new HtmlPrinter();
|
||
})();
|
||
diff --git a/src/line-by-line-printer.js b/src/line-by-line-printer.js
|
||
index b07eb53c..d230bedd 100644
|
||
--- a/src/line-by-line-printer.js
|
||
+++ b/src/line-by-line-printer.js
|
||
@@ -11,7 +11,8 @@
|
||
var utils = require('./utils.js').Utils;
|
||
var Rematch = require('./rematch.js').Rematch;
|
||
|
||
- var hoganUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
||
+ var hoganUtils;
|
||
+
|
||
var genericTemplatesPath = 'generic';
|
||
var baseTemplatesPath = 'line-by-line';
|
||
var iconsBaseTemplatesPath = 'icon';
|
||
@@ -19,6 +20,9 @@
|
||
|
||
function LineByLinePrinter(config) {
|
||
this.config = config;
|
||
+
|
||
+ var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
||
+ hoganUtils = new HoganJsUtils(config);
|
||
}
|
||
|
||
LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) {
|
||
diff --git a/src/side-by-side-printer.js b/src/side-by-side-printer.js
|
||
index bbf1dc8d..5e3033b3 100644
|
||
--- a/src/side-by-side-printer.js
|
||
+++ b/src/side-by-side-printer.js
|
||
@@ -11,7 +11,8 @@
|
||
var utils = require('./utils.js').Utils;
|
||
var Rematch = require('./rematch.js').Rematch;
|
||
|
||
- var hoganUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
||
+ var hoganUtils;
|
||
+
|
||
var genericTemplatesPath = 'generic';
|
||
var baseTemplatesPath = 'side-by-side';
|
||
var iconsBaseTemplatesPath = 'icon';
|
||
@@ -26,6 +27,9 @@
|
||
|
||
function SideBySidePrinter(config) {
|
||
this.config = config;
|
||
+
|
||
+ var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
||
+ hoganUtils = new HoganJsUtils(config);
|
||
}
|
||
|
||
SideBySidePrinter.prototype.makeDiffHtml = function(file, diffs) {
|
||
diff --git a/test/file-list-printer-tests.js b/test/file-list-printer-tests.js
|
||
index a502a46f..60ea3208 100644
|
||
--- a/test/file-list-printer-tests.js
|
||
+++ b/test/file-list-printer-tests.js
|
||
@@ -1,6 +1,6 @@
|
||
var assert = require('assert');
|
||
|
||
-var fileListPrinter = require('../src/file-list-printer.js').FileListPrinter;
|
||
+var fileListPrinter = new (require('../src/file-list-printer.js').FileListPrinter)();
|
||
|
||
describe('FileListPrinter', function() {
|
||
describe('generateFileList', function() {
|
||
diff --git a/test/hogan-cache-tests.js b/test/hogan-cache-tests.js
|
||
index 190bf6f8..3bb754ac 100644
|
||
--- a/test/hogan-cache-tests.js
|
||
+++ b/test/hogan-cache-tests.js
|
||
@@ -1,6 +1,6 @@
|
||
var assert = require('assert');
|
||
|
||
-var HoganJsUtils = require('../src/hoganjs-utils.js').HoganJsUtils;
|
||
+var HoganJsUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)();
|
||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
||
|
||
describe('HoganJsUtils', function() {
|
||
@@ -21,16 +21,28 @@ describe('HoganJsUtils', function() {
|
||
});
|
||
assert.equal(emptyDiffHtml, result);
|
||
});
|
||
+
|
||
it('should render view without cache', function() {
|
||
var result = HoganJsUtils.render('generic', 'empty-diff', {
|
||
contentClass: 'd2h-code-line',
|
||
diffParser: diffParser
|
||
}, {noCache: true});
|
||
- assert.equal(emptyDiffHtml + '\n', result);
|
||
+ assert.equal(emptyDiffHtml, result);
|
||
});
|
||
+
|
||
it('should return null if template is missing', function() {
|
||
- var result = HoganJsUtils.render('generic', 'missing-template', {}, {noCache: true});
|
||
+ var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)({noCache: true});
|
||
+ var result = hoganUtils.render('generic', 'missing-template', {});
|
||
assert.equal(null, result);
|
||
});
|
||
+
|
||
+ it('should allow templates to be overridden', function() {
|
||
+ var emptyDiffTemplate = HoganJsUtils.compile('<p></p>');
|
||
+
|
||
+ var config = {templates: {'generic-empty-diff': emptyDiffTemplate}};
|
||
+ var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config);
|
||
+ var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'});
|
||
+ assert.equal('<p>Rodrigo Fernandes</p>', result);
|
||
+ });
|
||
});
|
||
});
|
||
diff --git a/test/line-by-line-tests.js b/test/line-by-line-tests.js
|
||
index 1cd92073..8869b3df 100644
|
||
--- a/test/line-by-line-tests.js
|
||
+++ b/test/line-by-line-tests.js
|
||
@@ -14,7 +14,7 @@ describe('LineByLinePrinter', function() {
|
||
' File without changes\n' +
|
||
' </div>\n' +
|
||
' </td>\n' +
|
||
- '</tr>\n';
|
||
+ '</tr>';
|
||
|
||
assert.equal(expected, fileHtml);
|
||
});
|
||
@@ -422,7 +422,6 @@ describe('LineByLinePrinter', function() {
|
||
' </div>\n' +
|
||
' </td>\n' +
|
||
'</tr>\n' +
|
||
- '\n' +
|
||
' </tbody>\n' +
|
||
' </table>\n' +
|
||
' </div>\n' +
|
||
diff --git a/test/side-by-side-printer-tests.js b/test/side-by-side-printer-tests.js
|
||
index 76625f8e..771daaa5 100644
|
||
--- a/test/side-by-side-printer-tests.js
|
||
+++ b/test/side-by-side-printer-tests.js
|
||
@@ -14,7 +14,7 @@ describe('SideBySidePrinter', function() {
|
||
' File without changes\n' +
|
||
' </div>\n' +
|
||
' </td>\n' +
|
||
- '</tr>\n';
|
||
+ '</tr>';
|
||
|
||
assert.equal(expectedRight, fileHtml.right);
|
||
assert.equal(expectedLeft, fileHtml.left);
|
||
@@ -324,7 +324,6 @@ describe('SideBySidePrinter', function() {
|
||
' </div>\n' +
|
||
' </td>\n' +
|
||
'</tr>\n' +
|
||
- '\n' +
|
||
' </tbody>\n' +
|
||
' </table>\n' +
|
||
' </div>\n' +
|
||
|
||
From f3cadb96677d0eb82fc2752dc3ffbf35ca9b5bdb Mon Sep 17 00:00:00 2001
|
||
From: Rodrigo Fernandes <rtfrodrigo@gmail.com>
|
||
Date: Sat, 15 Oct 2016 13:21:22 +0100
|
||
Subject: [PATCH 2/2] Allow uncompiled templates
|
||
|
||
---
|
||
README.md | 3 +++
|
||
src/hoganjs-utils.js | 7 +++++++
|
||
test/hogan-cache-tests.js | 24 +++++++++++++++++++++++-
|
||
3 files changed, 33 insertions(+), 1 deletion(-)
|
||
|
||
diff --git a/README.md b/README.md
|
||
index 132c8a28..46909f25 100644
|
||
--- a/README.md
|
||
+++ b/README.md
|
||
@@ -98,6 +98,9 @@ The HTML output accepts a Javascript object with configuration. Possible options
|
||
- `synchronisedScroll`: scroll both panes in side-by-side mode: `true` or `false`, default is `false`
|
||
- `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`
|
||
+ - `templates`: 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)
|
||
|
||
## Diff2HtmlUI Helper
|
||
|
||
diff --git a/src/hoganjs-utils.js b/src/hoganjs-utils.js
|
||
index 0dda08d7..b2e9c275 100644
|
||
--- a/src/hoganjs-utils.js
|
||
+++ b/src/hoganjs-utils.js
|
||
@@ -17,6 +17,13 @@
|
||
function HoganJsUtils(configuration) {
|
||
this.config = configuration || {};
|
||
extraTemplates = this.config.templates || {};
|
||
+
|
||
+ var rawTemplates = this.config.rawTemplates || {};
|
||
+ for (var templateName in rawTemplates) {
|
||
+ if (rawTemplates.hasOwnProperty(templateName)) {
|
||
+ if (!extraTemplates[templateName]) extraTemplates[templateName] = this.compile(rawTemplates[templateName]);
|
||
+ }
|
||
+ }
|
||
}
|
||
|
||
HoganJsUtils.prototype.render = function(namespace, view, params) {
|
||
diff --git a/test/hogan-cache-tests.js b/test/hogan-cache-tests.js
|
||
index 3bb754ac..a34839c0 100644
|
||
--- a/test/hogan-cache-tests.js
|
||
+++ b/test/hogan-cache-tests.js
|
||
@@ -36,7 +36,7 @@ describe('HoganJsUtils', function() {
|
||
assert.equal(null, result);
|
||
});
|
||
|
||
- it('should allow templates to be overridden', function() {
|
||
+ it('should allow templates to be overridden with compiled templates', function() {
|
||
var emptyDiffTemplate = HoganJsUtils.compile('<p></p>');
|
||
|
||
var config = {templates: {'generic-empty-diff': emptyDiffTemplate}};
|
||
@@ -44,5 +44,27 @@ describe('HoganJsUtils', function() {
|
||
var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'});
|
||
assert.equal('<p>Rodrigo Fernandes</p>', result);
|
||
});
|
||
+
|
||
+ it('should allow templates to be overridden with uncompiled templates', function() {
|
||
+ var emptyDiffTemplate = '<p></p>';
|
||
+
|
||
+ var config = {rawTemplates: {'generic-empty-diff': emptyDiffTemplate}};
|
||
+ var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config);
|
||
+ var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'});
|
||
+ assert.equal('<p>Rodrigo Fernandes</p>', result);
|
||
+ });
|
||
+
|
||
+ it('should allow templates to be overridden giving priority to compiled templates', function() {
|
||
+ var emptyDiffTemplate = HoganJsUtils.compile('<p></p>');
|
||
+ var emptyDiffTemplateUncompiled = '<p>Not used!</p>';
|
||
+
|
||
+ var config = {
|
||
+ templates: {'generic-empty-diff': emptyDiffTemplate},
|
||
+ rawTemplates: {'generic-empty-diff': emptyDiffTemplateUncompiled}
|
||
+ };
|
||
+ var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config);
|
||
+ var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'});
|
||
+ assert.equal('<p>Rodrigo Fernandes</p>', result);
|
||
+ });
|
||
});
|
||
});
|
||
</code></pre> </div> </article> <br> <hr> <br> <ul class="list-disc pl-8"></ul> <h2 class="text-3xl font-semibold mb-4 mt-12">Enjoy Reading This Article?</h2> <p class="mb-2">Here are some more articles you might like to read next:</p> <li class="my-2"> <a class="text-pink-700 underline font-semibold hover:text-pink-800" href="/al-folio/blog/2024/google-gemini-updates-flash-15-gemma-2-and-project-astra/">Google Gemini updates: Flash 1.5, Gemma 2 and Project Astra</a> </li> <li class="my-2"> <a class="text-pink-700 underline font-semibold hover:text-pink-800" href="/al-folio/blog/2022/displaying-external-posts-on-your-al-folio-blog/">Displaying External Posts on Your al-folio Blog</a> </li> <li class="my-2"> <a class="text-pink-700 underline font-semibold hover:text-pink-800" href="/al-folio/blog/2024/tabs/">a post with tabs</a> </li> <li class="my-2"> <a class="text-pink-700 underline font-semibold hover:text-pink-800" href="/al-folio/blog/2024/typograms/">a post with typograms</a> </li> <li class="my-2"> <a class="text-pink-700 underline font-semibold hover:text-pink-800" href="/al-folio/blog/2024/post-citation/">a post that can be cited</a> </li> </div> </div> <footer class="fixed-bottom" role="contentinfo"> <div class="container mt-0"> © Copyright 2024 Vinicius F. Silva. Powered by <a href="https://jekyllrb.com/" target="_blank" rel="external nofollow noopener">Jekyll</a> with <a href="https://github.com/alshedivat/al-folio" rel="external nofollow noopener" target="_blank">al-folio</a> theme. Hosted by <a href="https://pages.github.com/" target="_blank" rel="external nofollow noopener">GitHub Pages</a>. Photos from <a href="https://unsplash.com" target="_blank" rel="external nofollow noopener">Unsplash</a>. </div> </footer> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <script src="/al-folio/assets/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/mdbootstrap@4.20.0/js/mdb.min.js" integrity="sha256-NdbiivsvWt7VYCt6hYNT3h/th9vSTL4EDWeGs5SN3DA=" crossorigin="anonymous"></script> <script defer src="https://cdn.jsdelivr.net/npm/masonry-layout@4.2.2/dist/masonry.pkgd.min.js" integrity="sha256-Nn1q/fx0H7SNLZMQ5Hw5JLaTRZp0yILA/FRexe19VdI=" crossorigin="anonymous"></script> <script defer src="https://cdn.jsdelivr.net/npm/imagesloaded@5.0.0/imagesloaded.pkgd.min.js" integrity="sha256-htrLFfZJ6v5udOG+3kNLINIKh2gvoKqwEhHYfTTMICc=" crossorigin="anonymous"></script> <script defer src="/al-folio/assets/js/masonry.js" type="text/javascript"></script> <script src="https://cdn.jsdelivr.net/npm/diff2html@3.4.47/bundles/js/diff2html-ui.min.js" integrity="sha256-eU2TVHX633T1o/bTQp6iIJByYJEtZThhF9bKz/DcbbY=" crossorigin="anonymous"></script> <script>let diff2HtmlTheme=determineComputedTheme();document.addEventListener("readystatechange",()=>{"complete"===document.readyState&&document.querySelectorAll("pre>code.language-diff2html").forEach(e=>{const t=e.textContent,d=e.parentElement;d.classList.add("unloaded");let l=document.createElement("div");l.classList.add("diff2html"),d.after(l),new Diff2HtmlUI(l,t,{colorScheme:diff2HtmlTheme,drawFileList:!0,highlight:!0,matching:"lines"}).draw()})});</script> <script defer src="https://cdn.jsdelivr.net/npm/medium-zoom@1.1.0/dist/medium-zoom.min.js" integrity="sha256-ZgMyDAIYDYGxbcpJcfUnYwNevG/xi9OHKaR/8GK+jWc=" crossorigin="anonymous"></script> <script defer src="/al-folio/assets/js/zoom.js?85ddb88934d28b74e78031fd54cf8308"></script> <script src="/al-folio/assets/js/no_defer.js?2781658a0a2b13ed609542042a859126"></script> <script defer src="/al-folio/assets/js/common.js?e0514a05c5c95ac1a93a8dfd5249b92e"></script> <script defer src="/al-folio/assets/js/copy_code.js?12775fdf7f95e901d7119054556e495f" type="text/javascript"></script> <script defer src="/al-folio/assets/js/jupyter_new_tab.js?d9f17b6adc2311cbabd747f4538bb15f"></script> <script async src="https://d1bxh8uas1mnw7.cloudfront.net/assets/embed.js"></script> <script async src="https://badge.dimensions.ai/badge.js"></script> <script type="text/javascript">window.MathJax={tex:{tags:"ams"}};</script> <script defer type="text/javascript" id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-mml-chtml.js" integrity="sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI=" crossorigin="anonymous"></script> <script defer src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6" crossorigin="anonymous"></script> <script type="text/javascript">function progressBarSetup(){"max"in document.createElement("progress")?(initializeProgressElement(),$(document).on("scroll",function(){progressBar.attr({value:getCurrentScrollPosition()})}),$(window).on("resize",initializeProgressElement)):(resizeProgressBar(),$(document).on("scroll",resizeProgressBar),$(window).on("resize",resizeProgressBar))}function getCurrentScrollPosition(){return $(window).scrollTop()}function initializeProgressElement(){let e=$("#navbar").outerHeight(!0);$("body").css({"padding-top":e}),$("progress-container").css({"padding-top":e}),progressBar.css({top:e}),progressBar.attr({max:getDistanceToScroll(),value:getCurrentScrollPosition()})}function getDistanceToScroll(){return $(document).height()-$(window).height()}function resizeProgressBar(){progressBar.css({width:getWidthPercentage()+"%"})}function getWidthPercentage(){return getCurrentScrollPosition()/getDistanceToScroll()*100}const progressBar=$("#progress");window.onload=function(){setTimeout(progressBarSetup,50)};</script> <script src="/al-folio/assets/js/vanilla-back-to-top.min.js?f40d453793ff4f64e238e420181a1d17"></script> <script>addBackToTop();</script> <script type="module" src="/al-folio/assets/js/search/ninja-keys.min.js?601a2d3465e2a52bec38b600518d5f70"></script> <ninja-keys hidebreadcrumbs noautoloadmdicons placeholder="Type to start searching"></ninja-keys> <script>let searchTheme=determineComputedTheme();const ninjaKeys=document.querySelector("ninja-keys");"dark"===searchTheme?ninjaKeys.classList.add("dark"):ninjaKeys.classList.remove("dark");const openSearchModal=()=>{const e=$("#navbarNav");e.hasClass("show")&&e.collapse("hide"),ninjaKeys.open()};</script> <script>const ninja=document.querySelector("ninja-keys");ninja.data=[{id:"nav-about",title:"about",section:"Navigation",handler:()=>{window.location.href="/al-folio/"}},{id:"nav-education",title:"education",description:"",section:"Navigation",handler:()=>{window.location.href="/al-folio/education/"}},{id:"nav-experience",title:"experience",description:"",section:"Navigation",handler:()=>{window.location.href="/al-folio/experience/"}},{id:"nav-works",title:"works",description:"",section:"Navigation",handler:()=>{window.location.href="/al-folio/works/"}},{id:"nav-projects",title:"projects",description:"",section:"Navigation",handler:()=>{window.location.href="/al-folio/projects/"}},{id:"nav-certificates",title:"certificates",description:"",section:"Navigation",handler:()=>{window.location.href="/al-folio/certificates/"}},{id:"nav-cv",title:"cv",description:"",section:"Navigation",handler:()=>{window.location.href="/al-folio/cv/"}},{id:"nav-talk-with-me",title:"talk with me",description:"",section:"Navigation",handler:()=>{window.location.href="/al-folio/glo/index.html"}},{id:"post-google-gemini-updates-flash-1-5-gemma-2-and-project-astra",title:'Google Gemini updates: Flash 1.5, Gemma 2 and Project Astra <svg width="1.2rem" height="1.2rem" top=".5rem" viewbox="0 0 40 40" xmlns="http://www.w3.org/2000/svg"><path d="M17 13.5v6H5v-12h6m3-3h6v6m0-6-9 9" class="icon_svg-stroke" stroke="#999" stroke-width="1.5" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg>',description:"We\u2019re sharing updates across our Gemini family of models and a glimpse of Project Astra, our vision for the future of AI assistants.",section:"Posts",handler:()=>{window.open("https://blog.google/technology/ai/google-gemini-update-flash-ai-assistant-io-2024/","_blank")}},{id:"post-a-post-with-tabs",title:"a post with tabs",description:"this is what included tabs in a post could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/tabs/"}},{id:"post-a-post-with-typograms",title:"a post with typograms",description:"this is what included typograms code could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/typograms/"}},{id:"post-a-post-that-can-be-cited",title:"a post that can be cited",description:"this is what a post that can be cited looks like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/post-citation/"}},{id:"post-a-post-with-pseudo-code",title:"a post with pseudo code",description:"this is what included pseudo code could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/pseudocode/"}},{id:"post-a-post-with-code-diff",title:"a post with code diff",description:"this is how you can display code diffs",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/code-diff/"}},{id:"post-a-post-with-advanced-image-components",title:"a post with advanced image components",description:"this is what advanced image components could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/advanced-images/"}},{id:"post-a-post-with-vega-lite",title:"a post with vega lite",description:"this is what included vega lite code could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/vega-lite/"}},{id:"post-a-post-with-geojson",title:"a post with geojson",description:"this is what included geojson code could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/geojson-map/"}},{id:"post-a-post-with-echarts",title:"a post with echarts",description:"this is what included echarts code could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/echarts/"}},{id:"post-a-post-with-chart-js",title:"a post with chart.js",description:"this is what included chart.js code could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2024/chartjs/"}},{id:"post-a-post-with-tikzjax",title:"a post with TikZJax",description:"this is what included TikZ code could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/tikzjax/"}},{id:"post-a-post-with-bibliography",title:"a post with bibliography",description:"an example of a blog post with bibliography",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/post-bibliography/"}},{id:"post-a-post-with-jupyter-notebook",title:"a post with jupyter notebook",description:"an example of a blog post with jupyter notebook",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/jupyter-notebook/"}},{id:"post-a-post-with-custom-blockquotes",title:"a post with custom blockquotes",description:"an example of a blog post with custom blockquotes",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/custom-blockquotes/"}},{id:"post-a-post-with-table-of-contents-on-a-sidebar",title:"a post with table of contents on a sidebar",description:"an example of a blog post with table of contents on a sidebar",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/sidebar-table-of-contents/"}},{id:"post-a-post-with-audios",title:"a post with audios",description:"this is what included audios could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/audios/"}},{id:"post-a-post-with-videos",title:"a post with videos",description:"this is what included videos could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/videos/"}},{id:"post-displaying-beautiful-tables-with-bootstrap-tables",title:"displaying beautiful tables with Bootstrap Tables",description:"an example of how to use Bootstrap Tables",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/tables/"}},{id:"post-a-post-with-table-of-contents",title:"a post with table of contents",description:"an example of a blog post with table of contents",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2023/table-of-contents/"}},{id:"post-a-post-with-giscus-comments",title:"a post with giscus comments",description:"an example of a blog post with giscus comments",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2022/giscus-comments/"}},{id:"post-displaying-external-posts-on-your-al-folio-blog",title:'Displaying External Posts on Your al-folio Blog <svg width="1.2rem" height="1.2rem" top=".5rem" viewbox="0 0 40 40" xmlns="http://www.w3.org/2000/svg"><path d="M17 13.5v6H5v-12h6m3-3h6v6m0-6-9 9" class="icon_svg-stroke" stroke="#999" stroke-width="1.5" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg>',description:"",section:"Posts",handler:()=>{window.open("https://medium.com/@al-folio/displaying-external-posts-on-your-al-folio-blog-b60a1d241a0a?source=rss-17feae71c3c4------2","_blank")}},{id:"post-a-post-with-redirect",title:"a post with redirect",description:"you can also redirect to assets like pdf",section:"Posts",handler:()=>{window.location.href="/al-folio/assets/pdf/example_pdf.pdf"}},{id:"post-a-post-with-diagrams",title:"a post with diagrams",description:"an example of a blog post with diagrams",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2021/diagrams/"}},{id:"post-a-distill-style-blog-post",title:"a distill-style blog post",description:"an example of a distill-style blog post and main elements",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2021/distill/"}},{id:"post-a-post-with-github-metadata",title:"a post with github metadata",description:"a quick run down on accessing github metadata.",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2020/github-metadata/"}},{id:"post-a-post-with-twitter",title:"a post with twitter",description:"an example of a blog post with twitter",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2020/twitter/"}},{id:"post-a-post-with-disqus-comments",title:"a post with disqus comments",description:"an example of a blog post with disqus comments",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2015/disqus-comments/"}},{id:"post-a-post-with-math",title:"a post with math",description:"an example of a blog post with some math",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2015/math/"}},{id:"post-a-post-with-code",title:"a post with code",description:"an example of a blog post with some code",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2015/code/"}},{id:"post-a-post-with-images",title:"a post with images",description:"this is what included images could look like",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2015/images/"}},{id:"post-a-post-with-formatting-and-links",title:"a post with formatting and links",description:"march & april, looking forward to summer",section:"Posts",handler:()=>{window.location.href="/al-folio/blog/2015/formatting-and-links/"}},{id:"news-a-simple-inline-announcement",title:"A simple inline announcement.",description:"",section:"News"},{id:"news-a-long-announcement-with-details",title:"A long announcement with details",description:"",section:"News",handler:()=>{window.location.href="/al-folio/news/announcement_2/"}},{id:"news-a-simple-inline-announcement-with-markdown-emoji-sparkles-smile",title:'A simple inline announcement with Markdown emoji! <img class="emoji" title=":sparkles:" alt=":sparkles:" src="https://github.githubassets.com/images/icons/emoji/unicode/2728.png" height="20" width="20"> <img class="emoji" title=":smile:" alt=":smile:" src="https://github.githubassets.com/images/icons/emoji/unicode/1f604.png" height="20" width="20">',description:"",section:"News"},{id:"projects-project-1",title:"project 1",description:"with background image",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/1_project/"}},{id:"projects-project-2",title:"project 2",description:"a project with a background image and giscus comments",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/2_project/"}},{id:"projects-project-3-with-very-long-name",title:"project 3 with very long name",description:"a project that redirects to another website",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/3_project/"}},{id:"projects-project-4",title:"project 4",description:"another without an image",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/4_project/"}},{id:"projects-project-5",title:"project 5",description:"a project with a background image",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/5_project/"}},{id:"projects-project-6",title:"project 6",description:"a project with no image",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/6_project/"}},{id:"projects-project-7",title:"project 7",description:"with background image",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/7_project/"}},{id:"projects-project-8",title:"project 8",description:"an other project with a background image and giscus comments",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/8_project/"}},{id:"projects-project-9",title:"project 9",description:"another project with an image \ud83c\udf89",section:"Projects",handler:()=>{window.location.href="/al-folio/projects/9_project/"}},{id:"socials-email",title:"Send email",section:"Socials",handler:()=>{window.open("mailto:%73%69%6C%76%61.%76%69%6E%69%63%69%75%73@%64%63%63.%75%66%6D%67.%62%72, %76%69%6E%69%63%69%75%73%64%61%73%69%6C%76%61@%75%66%6D%67.%62%72","_blank")}},{id:"socials-orcid",title:"ORCID",section:"Socials",handler:()=>{window.open("https://orcid.org/0009-0008-9063-8804","_blank")}},{id:"socials-lattes",title:"Lattes",section:"Socials",handler:()=>{window.open("http://lattes.cnpq.br/7926652029249045","_blank")}},{id:"socials-researchgate",title:"ResearchGate",section:"Socials",handler:()=>{window.open("https://www.researchgate.net/profile/Vinicius-Silva-42/","_blank")}},{id:"socials-github",title:"GitHub",section:"Socials",handler:()=>{window.open("https://github.com/viniciusfdasilva","_blank")}},{id:"socials-linkedin",title:"LinkedIn",section:"Socials",handler:()=>{window.open("https://www.linkedin.com/in/viniciusfsilva","_blank")}}];</script> <script src="/al-folio/assets/js/shortcut-key.js?6f508d74becd347268a7f822bca7309d"></script> </body> </html> |