Browse Source

feat: html code highlighter

Nicolas Giard 6 years ago
parent
commit
578ea577f0

+ 108 - 5
client/themes/default/scss/app.scss

@@ -4,9 +4,9 @@
   color: mc('grey', '800');
 
   h1 {
-    padding-left: 16px;
+    padding-left: 24px;
     color: mc('blue', '800');
-    margin-top: 16px;
+    margin-top: 1rem;
     position: relative;
 
     &::after {
@@ -19,12 +19,12 @@
       background: linear-gradient(to right, mc('theme', 'primary'), rgba(mc('theme', 'primary'), 0));
     }
 
-    & + h2 {
+    & + h2, & + h3 {
       margin-top: 8px;
     }
   }
   h2 {
-    margin-left: 16px;
+    margin-left: 24px;
     padding: 8px 0 0 0;
     color: mc('grey', '800');
     position: relative;
@@ -38,11 +38,114 @@
       height: 1px;
       background: linear-gradient(to right, mc('grey', '700'), rgba(mc('grey', '700'), 0));
     }
+
+    & + h3 {
+      margin-top: 8px;
+    }
+  }
+  h3 {
+    margin-left: 24px;
+    padding: 8px 0 0 0;
+    color: mc('grey', '700');
+    position: relative;
+
+    &::after {
+      content: '';
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      width: 100%;
+      height: 1px;
+      background: linear-gradient(to right, mc('grey', '500'), rgba(mc('grey', '500'), 0));
+    }
   }
 
   p {
-    padding: 16px 16px 0 16px;
+    padding: 1rem 24px 0 24px;
     margin: 0;
     text-align: justify;
   }
+
+  code {
+    background-color: transparent;
+    font-family: 'Source Code Pro', monospace;
+    font-weight: normal;
+    font-size: 1rem;
+
+    &::before, &::after {
+      display: none;
+    }
+  }
+
+  .hljs{
+    display: block;
+    overflow-x: auto;
+    padding: 1rem;
+    background: #232323;
+    color: #e6e1dc;
+    margin: 1rem 24px;
+    border-radius: .5rem;
+  }
+  .hljs-comment,.hljs-quote{
+      color:#bc9458;
+      font-style:italic
+  }
+  .hljs-keyword,.hljs-selector-tag{
+      color:#c26230
+  }
+  .hljs-string,.hljs-number,.hljs-regexp,.hljs-variable,.hljs-template-variable{
+      color:#a5c261
+  }
+  .hljs-subst{
+      color:#519f50
+  }
+  .hljs-tag,.hljs-name{
+      color:#e8bf6a
+  }
+  .hljs-type{
+      color:#da4939
+  }
+  .hljs-symbol,.hljs-bullet,.hljs-built_in,.hljs-builtin-name,.hljs-attr,.hljs-link{
+      color:#6d9cbe
+  }
+  .hljs-params{
+      color:#d0d0ff
+  }
+  .hljs-attribute{
+      color:#cda869
+  }
+  .hljs-meta{
+      color:#9b859d
+  }
+  .hljs-title,.hljs-section{
+      color:#ffc66d
+  }
+  .hljs-addition{
+      background-color:#144212;
+      color:#e6e1dc;
+      display:inline-block;
+      width:100%
+  }
+  .hljs-deletion{
+      background-color:#600;
+      color:#e6e1dc;
+      display:inline-block;
+      width:100%
+  }
+  .hljs-selector-class{
+      color:#9b703f
+  }
+  .hljs-selector-id{
+      color:#8b98ab
+  }
+  .hljs-emphasis{
+      font-style:italic
+  }
+  .hljs-strong{
+      font-weight:bold
+  }
+  .hljs-link{
+      text-decoration:underline
+  }
+
 }

+ 1 - 0
package.json

@@ -75,6 +75,7 @@
     "graphql": "14.0.2",
     "graphql-list-fields": "2.0.2",
     "graphql-tools": "3.1.1",
+    "highlight.js": "9.12.0",
     "i18next": "11.7.0",
     "i18next-express-middleware": "1.3.2",
     "i18next-localstorage-cache": "1.1.1",

+ 12 - 2
server/models/pages.js

@@ -129,7 +129,12 @@ module.exports = class Page extends Model {
       publishStartDate: opts.publishStartDate,
       title: opts.title
     })
-    const page = await WIKI.models.pages.getPageFromDb(opts)
+    const page = await WIKI.models.pages.getPageFromDb({
+      path: opts.path,
+      locale: opts.locale,
+      userId: opts.authorId,
+      isPrivate: opts.isPrivate
+    })
     await WIKI.models.pages.renderPage(page)
     await WIKI.models.storage.pageEvent({
       event: 'created',
@@ -153,7 +158,12 @@ module.exports = class Page extends Model {
       publishStartDate: opts.publishStartDate,
       title: opts.title
     }).where('id', ogPage.id)
-    const page = await WIKI.models.pages.getPageFromDb(opts)
+    const page = await WIKI.models.pages.getPageFromDb({
+      path: ogPage.path,
+      locale: ogPage.localeCode,
+      userId: ogPage.authorId,
+      isPrivate: ogPage.isPrivate
+    })
     await WIKI.models.pages.renderPage(page)
     await WIKI.models.storage.pageEvent({
       event: 'updated',

+ 5 - 1
server/modules/rendering/html-asciinema/renderer.js

@@ -1 +1,5 @@
-module.exports = {}
+module.exports = {
+  init($, config) {
+
+  }
+}

+ 5 - 1
server/modules/rendering/html-blockquotes/renderer.js

@@ -1 +1,5 @@
-module.exports = {}
+module.exports = {
+  init($, config) {
+
+  }
+}

+ 17 - 0
server/modules/rendering/html-codehighlighter/renderer.js

@@ -0,0 +1,17 @@
+const hljs = require('highlight.js')
+
+module.exports = {
+  async init($, config) {
+    $('pre > code').each((idx, elm) => {
+      const lang = $(elm).attr('lang')
+      if (lang) {
+        $(elm).html(hljs.highlight(lang, $(elm).text(), true).value)
+      } else {
+        const result = hljs.highlightAuto($(elm).text())
+        $(elm).html(result.value)
+        $(elm).attr('lang', result.language)
+      }
+      $(elm).parent().addClass('hljs')
+    })
+  }
+}

+ 15 - 1
server/modules/rendering/html-core/renderer.js

@@ -1,5 +1,19 @@
+const _ = require('lodash')
+const cheerio = require('cheerio')
+
 module.exports = {
   async render() {
-    return this.input
+    const $ = cheerio.load(this.input)
+
+    if ($.root().children().length < 1) {
+      return ''
+    }
+
+    for (let child of this.children) {
+      const renderer = require(`../${_.kebabCase(child.key)}/renderer.js`)
+      renderer.init($, child.config)
+    }
+
+    return $.html()
   }
 }

+ 1 - 5
server/modules/rendering/html-mathjax/mathjax.js

@@ -23,11 +23,7 @@ const mathRegex = [
 ]
 
 module.exports = {
-  key: 'common/mathjax',
-  title: 'Mathjax',
-  dependsOn: [],
-  props: [],
-  init (conf) {
+  init ($, config) {
     mathjax.config({
       MathJax: {
         jax: ['input/TeX', 'input/MathML', 'output/SVG'],

+ 1 - 1
server/modules/rendering/html-mediaplayers/definition.yml

@@ -1,4 +1,4 @@
-key: htmlMedia
+key: htmlMediaplayers
 title: Media Players
 description: Embed players such as Youtube, Vimeo, Soundcloud, etc.
 author: requarks.io

+ 5 - 1
server/modules/rendering/html-mediaplayers/renderer.js

@@ -1 +1,5 @@
-module.exports = {}
+module.exports = {
+  init($, config) {
+
+  }
+}

+ 5 - 1
server/modules/rendering/html-mermaid/renderer.js

@@ -1 +1,5 @@
-module.exports = {}
+module.exports = {
+  init($, config) {
+
+  }
+}

+ 5 - 1
server/modules/rendering/html-plantuml/renderer.js

@@ -1 +1,5 @@
-module.exports = {}
+module.exports = {
+  init($, config) {
+
+  }
+}

+ 5 - 1
server/modules/rendering/html-security/renderer.js

@@ -1 +1,5 @@
-module.exports = {}
+module.exports = {
+  init($, config) {
+
+  }
+}

+ 1 - 2
server/modules/rendering/markdown-core/renderer.js

@@ -25,12 +25,11 @@ module.exports = {
       typographer: this.config.typographer,
       quotes: _.get(quoteStyles, this.config.quotes, quoteStyles.English),
       highlight(str, lang) {
-        return '<pre><code>' + _.escape(str) + '</code></pre>'
+        return `<pre><code lang="${lang}">${_.escape(str)}</code></pre>`
       }
     })
 
     for (let child of this.children) {
-      console.info(child)
       const renderer = require(`../${_.kebabCase(child.key)}/renderer.js`)
       renderer.init(mkdown, child.config)
     }

+ 4 - 0
yarn.lock

@@ -5753,6 +5753,10 @@ hex-color-regex@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
 
+highlight.js@9.12.0:
+  version "9.12.0"
+  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
+
 hmac-drbg@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"