From 7dd4f50e9ea01d2414d318153063fb6b9f9a3c4a Mon Sep 17 00:00:00 2001 From: Bobby Date: Thu, 5 May 2022 12:55:21 +0700 Subject: [PATCH] feat: allow markdown in album description --- controllers/utilsController.js | 26 ++++++++++++++++++++++++++ package.json | 1 + routes/album.js | 1 + views/album.njk | 4 ++-- yarn.lock | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/controllers/utilsController.js b/controllers/utilsController.js index 972ee75..3794829 100644 --- a/controllers/utilsController.js +++ b/controllers/utilsController.js @@ -1,6 +1,7 @@ const { promisify } = require('util') const fetch = require('node-fetch') const ffmpeg = require('fluent-ffmpeg') +const MarkdownIt = require('markdown-it') const path = require('path') const sharp = require('sharp') const si = require('systeminformation') @@ -25,6 +26,15 @@ const self = { maxSize: (parseInt(config.uploads.scan.maxSize) * 1e6) || null, passthrough: config.uploads.scan.clamPassthrough }, + md: { + instance: new MarkdownIt({ + // https://markdown-it.github.io/markdown-it/#MarkdownIt.new + html: false, + breaks: true, + linkify: true + }), + defaultRenderers: {} + }, gitHash: null, idSet: null, @@ -45,6 +55,22 @@ const self = { timezoneOffset: new Date().getTimezoneOffset() } +// Remember old renderer, if overridden, or proxy to default renderer +self.md.defaultRenderers.link_open = self.md.instance.renderer.rules.link_open || function (tokens, idx, options, env, that) { + return that.renderToken(tokens, idx, options) +} + +// Add target="_blank" to URLs if applicable +self.md.instance.renderer.rules.link_open = function (tokens, idx, options, env, that) { + const aIndex = tokens[idx].attrIndex('target') + if (aIndex < 0) { + tokens[idx].attrPush(['target', '_blank']) + } else { + tokens[idx].attrs[aIndex][1] = '_blank' + } + return self.md.defaultRenderers.link_open(tokens, idx, options, env, that) +} + const statsData = { system: { title: 'System', diff --git a/package.json b/package.json index bdd90d2..add801b 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "helmet": "~5.0.2", "jszip": "~3.9.1", "knex": "~0.21.21", + "markdown-it": "~13.0.1", "multer": "~1.4.4", "node-fetch": "~2.6.7", "nunjucks": "~3.2.3", diff --git a/routes/album.js b/routes/album.js index f1bc8c9..85b03c9 100644 --- a/routes/album.js +++ b/routes/album.js @@ -76,6 +76,7 @@ routes.get('/a/:identifier', async (req, res, next) => { : `api/album/zip/${album.identifier}?v=${album.editedAt}` album.url = `a/${album.identifier}` + album.description = utils.md.instance.render(album.description) return res.render('album', { config, diff --git a/views/album.njk b/views/album.njk index e3795e2..c80ca54 100644 --- a/views/album.njk +++ b/views/album.njk @@ -97,8 +97,8 @@ {% if album.description -%} -
- {{ album.description | nl2br | safe }} +
+ {{ album.description | safe }}
{%- endif %}
diff --git a/yarn.lock b/yarn.lock index 9924479..c1456da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1925,6 +1925,11 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +entities@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" + integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== + env-paths@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" @@ -3931,6 +3936,13 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +linkify-it@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" + integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== + dependencies: + uc.micro "^1.0.1" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -4083,6 +4095,17 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +markdown-it@~13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" + integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q== + dependencies: + argparse "^2.0.1" + entities "~3.0.1" + linkify-it "^4.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + matchdep@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" @@ -4103,6 +4126,11 @@ mdn-data@2.0.14: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -6870,6 +6898,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"