From 3e303fe722d3852f27a5f8ce86cbe0cc15584649 Mon Sep 17 00:00:00 2001 From: cel Date: Tue, 27 Jun 2017 16:25:55 -1000 Subject: Highlight code in markdown and git files --- lib/render.js | 20 ++++++++++++++++++++ lib/serve.js | 22 ++++++++++++++++------ package.json | 1 + 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lib/render.js b/lib/render.js index ee8ce01..e9d4889 100644 --- a/lib/render.js +++ b/lib/render.js @@ -10,6 +10,7 @@ var qs = require('querystring') var u = require('./util') var multicb = require('multicb') var RenderMsg = require('./render-msg') +var Highlight = require('highlight.js') module.exports = Render @@ -83,6 +84,7 @@ function Render(app, opts) { smartypants: false, emoji: lexerRenderEmoji, renderer: new MdRenderer(this), + highlight: this.highlight.bind(this), } } @@ -368,3 +370,21 @@ Render.prototype.npmAuthorLink = function (author) { secondaryLink ? [' (', secondaryLink, ')'] : '' ] } + +// auto-highlight is slow +var useAutoHighlight = false + +Render.prototype.highlight = function (code, lang) { + if (code.length > 100000) return u.escapeHTML(code) + if (!lang && /^#!\/bin\/[^\/]*sh$/m.test(code)) lang = 'sh' + try { + return lang + ? Highlight.highlight(lang, code).value + : useAutoHighlight + ? Highlight.highlightAuto(code).value + : u.escapeHTML(code) + } catch(e) { + if (!/^Unknown language/.test(e.message)) console.trace(e) + return u.escapeHTML(code) + } +} diff --git a/lib/serve.js b/lib/serve.js index 19b0ac8..5f4abff 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -25,6 +25,7 @@ var jpeg = require('jpeg-autorotate') module.exports = Serve var emojiDir = path.join(require.resolve('emoji-named-characters'), '../pngs') +var hlCssDir = path.join(require.resolve('highlight.js'), '../../styles') var urlIdRegex = /^(?:\/+(([%&@]|%25)(?:[A-Za-z0-9\/+]|%2[Ff]|%2[Bb]){43}(?:=|%3D)\.(?:sha256|ed25519))(?:\.([^?]*))?|(\/.*?))(?:\?(.*))?$/ @@ -296,6 +297,7 @@ Serve.prototype.path = function (url) { case '/links': return this.links(m[2]) case '/static': return this.static(m[2]) case '/emoji': return this.emoji(m[2]) + case '/highlight': return this.highlight(m[2]) case '/contacts': return this.contacts(m[2]) case '/about': return this.about(m[2]) case '/git': return this.git(m[2]) @@ -1061,6 +1063,10 @@ Serve.prototype.emoji = function (emoji) { serveEmoji(this.req, this.res, emoji) } +Serve.prototype.highlight = function (dirs) { + this.file(path.join(hlCssDir, dirs)) +} + Serve.prototype.blob = function (id) { var self = this var blobs = self.app.sbot.blobs @@ -1311,7 +1317,8 @@ Serve.prototype.wrapPage = function (title, searchQ) { h('title', title), h('meta', {name: 'viewport', content: 'width=device-width,initial-scale=1'}), h('link', {rel: 'icon', href: render.toUrl('/static/hermie.ico'), type: 'image/x-icon'}), - h('style', styles()) + h('style', styles()), + h('link', {rel: 'stylesheet', href: render.toUrl('/highlight/foundation.css')}) ), h('body', h('nav.nav-bar', h('form', {action: render.toUrl('/search'), method: 'get'}, @@ -1754,8 +1761,10 @@ Serve.prototype.gitTree = function (rev) { ph('td', u.escapeHTML(item.hash)), ph('td', 'missing') ]) + var ext = item.name.replace(/.*\./, '') var path = '/git/' + item.type + '/' + item.hash + '?msg=' + encodeURIComponent(item.msg.key) + + (ext ? '&ext=' + ext : '') var fileDate = new Date(item.msg.value.timestamp) return ph('tr', [ ph('td', @@ -1828,7 +1837,8 @@ Serve.prototype.gitBlob = function (rev) { self.app.git.readObject(obj), self.wrapBinary({ rawUrl: self.app.render.toUrl('/git/raw/' + rev - + '?msg=' + encodeURIComponent(msg.key)) + + '?msg=' + encodeURIComponent(msg.key)), + ext: self.query.ext }) ), ]), @@ -1865,9 +1875,11 @@ Serve.prototype.gitObjectLinks = function (headMsgId, type) { // wrap a binary source and render it or turn into an embed Serve.prototype.wrapBinary = function (opts) { var self = this + var ext = opts.ext return function (read) { var readRendered, type - read = ident(function (ext) { + read = ident(function (_ext) { + if (_ext) ext = _ext type = ext && mime.lookup(ext) || 'text/plain' })(read) return function (abort, cb) { @@ -1891,9 +1903,7 @@ Serve.prototype.wrapBinary = function (opts) { }) } return ph('pre', pull.map(function (buf) { - return h('div', - self.app.render.linkify(buf.toString('utf8')) - ).innerHTML + return self.app.render.highlight(buf.toString('utf8'), ext) })(read)) } } diff --git a/package.json b/package.json index b4260f4..ad452f6 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "emoji-named-characters": "^1.0.2", "emoji-server": "^1.0.0", "hashlru": "^2.1.0", + "highlight.js": "^9.12.0", "human-time": "^0.0.1", "hyperscript": "^2.0.2", "jpeg-autorotate": "^3.0.0", -- cgit v1.2.3