diff --git a/resources/edit.html b/resources/edit.html
index 8c286ef..6325934 100644
--- a/resources/edit.html
+++ b/resources/edit.html
@@ -10,6 +10,7 @@
+
diff --git a/resources/public/js/highlight.js b/resources/public/js/highlight.js
new file mode 100644
index 0000000..88bfdca
--- /dev/null
+++ b/resources/public/js/highlight.js
@@ -0,0 +1,157 @@
+/**
+ * Highlight Module
+ *
+ *
+ * High Level API:
+ *
+ * // Load basic dependencies and language support for present code tags
+ *
+ * highlight.init()
+ *
+ *
+ * // Function that loads additional languages support
+ * // Useful when markdown has been parsed again
+ * // and new language occurred in the output for example
+ *
+ * highlight.update();
+ *
+ *
+ * Hooks To:
+ *
+ * 'document:loaded' ~> highlight.init();
+ * 'content:rendered' ~> highlight.update();
+ *
+ */
+(function (global) {
+
+ // Simplified debounce version (no args support)
+ function debounce(callback, milliseconds) {
+ var timeout;
+
+ return function () {
+ clearTimeout(timeout);
+
+ timeout = setTimeout(function () {
+ callback();
+ }, milliseconds);
+ };
+ }
+
+ // Converts arguments-like / querySelector results data to a simple array
+ function toArray(data) {
+ return [].slice.call(data);
+ }
+
+ // Highlight callback
+ function highlight() {
+ if (!('Prism' in global)) {
+ throw new Error(
+ '[Highlight] Prism not detected. Please run `highlight.init` to load all dependencies'
+ );
+ }
+
+ global.Prism.highlightAll();
+ }
+
+ // Debounced highlight callback
+ var debouncedHighlight = debounce(highlight, 300);
+
+ // Collect a list of unique langages to be highlighted
+ function collectLanguages() {
+ return []
+ .concat(toArray(document.querySelectorAll('code[class*="lang-"]')))
+ .concat(toArray(document.querySelectorAll('code[class*="language-"]')))
+ .map(function (element) {
+ // Collect languages from code elements, e.g. `lang-css`, `language-javascript`
+ // and then remove `lang-` and `language-` parts
+ return (element.className.match(/lang(uage)?\-\w+/g) || [])
+ .map(function (languageClass) {
+ return languageClass.replace(/lang(uage)?\-/g, '').trim();
+ })
+ .map(function (language) {
+ // Common language abbreviations mapped to full language names
+ var mappings = {
+ js: 'javascript',
+ };
+
+ return mappings[language] || language;
+ });
+ })
+ .reduce(function (uniqueLanguages, elementLanguages) {
+ elementLanguages.forEach(function (language) {
+ // Add language to the pool if not detected already
+ if (uniqueLanguages.indexOf(language) === -1) {
+ uniqueLanguages.push(language);
+ }
+ });
+
+ return uniqueLanguages;
+ }, []);
+ }
+
+ // Load scripts for additional languages support
+ function loadAdditionalLanguageSupport() {
+ collectLanguages()
+ .forEach(function (language) {
+ var resource = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/components/prism-%s.min.js'
+ .replace('%s', language);
+
+ // Escape early if language support is already loaded
+ if (document.querySelector('script[src="' + resource + '"]')) {
+ debouncedHighlight();
+ return;
+ }
+
+ // Load language support file otherwise
+ var script = document.createElement('script');
+
+ script.src = resource;
+
+ script.addEventListener('load', debouncedHighlight);
+ script.addEventListener('error', function (event) {
+ // Remove element that wasn't successful
+ document.body.removeChild(event.srcElement);
+
+ // Highlight code anyway
+ debouncedHighlight();
+ });
+
+ document.body.appendChild(script);
+ });
+ }
+
+ // Load minimal requirements
+ function loadInitialScriptsAndStyles() {
+ var link = document.createElement('link');
+ var script = document.createElement('script');
+
+ link.rel = 'stylesheet';
+ link.href = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/themes/prism.min.css';
+ script.src = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/prism.min.js';
+
+ script.addEventListener('load', global.highlight.update);
+
+ document.head.appendChild(link);
+ document.body.appendChild(script);
+ }
+
+ // High Level API
+ global.highlight = global.highlight || {
+
+ init: function () {
+ loadInitialScriptsAndStyles();
+ },
+
+ update: function () {
+ loadAdditionalLanguageSupport();
+ },
+
+ };
+
+ // Hooks
+ if ('events' in global) {
+ events.subscribe('document:loaded', global.highlight.init);
+ events.subscribe('content:rendered', global.highlight.update);
+ }
+
+}(window));
diff --git a/resources/template.html b/resources/template.html
index c88ce88..01c8461 100644
--- a/resources/template.html
+++ b/resources/template.html
@@ -14,6 +14,7 @@
%FOOTER%
+