From 076aeaf749f6373c8c3d199e329349b6b2c849cb Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Fri, 23 Nov 2018 21:10:24 -0500 Subject: [PATCH] feat: markdown rendering --- client/components/editor.vue | 4 + client/components/editor/editor-markdown.vue | 8 +- client/scss/app.scss | 1 - client/scss/components/markdown-content.scss | 100 ----------------- client/themes/default/scss/app.scss | 103 +++++++++++++++++- .../rendering/markdown-core/renderer.js | 3 + .../rendering/markdown-tasklists/renderer.js | 2 +- 7 files changed, 115 insertions(+), 106 deletions(-) delete mode 100644 client/scss/components/markdown-content.scss diff --git a/client/components/editor.vue b/client/components/editor.vue index d5683d64..c3145f7d 100644 --- a/client/components/editor.vue +++ b/client/components/editor.vue @@ -22,6 +22,7 @@ outline color='red' :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }' + @click.native.stop='exit' ) v-icon(color='red', :left='$vuetify.breakpoint.lgAndUp') close span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('common:actions.discard') }} @@ -285,6 +286,9 @@ export default { }) } this.hideProgressDialog() + }, + exit() { + } } } diff --git a/client/components/editor/editor-markdown.vue b/client/components/editor/editor-markdown.vue index 09e56fb5..132f5449 100644 --- a/client/components/editor/editor-markdown.vue +++ b/client/components/editor/editor-markdown.vue @@ -58,7 +58,7 @@ transition(name='editor-code-preview') .editor-code-preview(v-if='previewShown') .editor-code-preview-title(@click='previewShown = false') Preview - .editor-code-preview-content.markdown-content(ref='editorPreview', v-html='previewHTML') + .editor-code-preview-content.contents(ref='editorPreview', v-html='previewHTML') v-speed-dial(v-model='fabInsertMenu', :open-on-hover='true', direction='top', transition='slide-y-reverse-transition', fixed, left, bottom) v-btn(color='blue', fab, dark, v-model='fabInsertMenu', slot='activator') @@ -97,6 +97,7 @@ import 'codemirror/addon/search/match-highlighter.js' // Markdown-it import MarkdownIt from 'markdown-it' +import mdAttrs from 'markdown-it-attrs' import mdEmoji from 'markdown-it-emoji' import mdTaskLists from 'markdown-it-task-lists' import mdExpandTabs from 'markdown-it-expand-tabs' @@ -126,8 +127,9 @@ const md = new MarkdownIt({ return `
${str}
` } }) + .use(mdAttrs) .use(mdEmoji) - .use(mdTaskLists) + .use(mdTaskLists, {label: true, labelAfter: true}) .use(mdExpandTabs) .use(mdAbbr) .use(mdSup) @@ -323,7 +325,7 @@ export default { &-content { height: calc(100vh - 112px); overflow-y: scroll; - padding: 30px 1rem 1rem 1rem; + padding: 1rem 1rem 1rem 0; width: calc(100% + 1rem + 17px) // -ms-overflow-style: none; diff --git a/client/scss/app.scss b/client/scss/app.scss index 0cfefd0f..5df054c6 100644 --- a/client/scss/app.scss +++ b/client/scss/app.scss @@ -6,7 +6,6 @@ @import "../libs/animate/animate"; @import '~vue2-animate/src/sass/vue2-animate'; -@import 'components/markdown-content'; @import 'components/v-btn'; @import 'components/v-data-table'; @import 'components/v-dialog'; diff --git a/client/scss/components/markdown-content.scss b/client/scss/components/markdown-content.scss deleted file mode 100644 index e758dc13..00000000 --- a/client/scss/components/markdown-content.scss +++ /dev/null @@ -1,100 +0,0 @@ -.markdown-content { - font-size: 1rem; - color: mc('blue-grey', '800'); - - // -------------------------------------------- - // Headers - // -------------------------------------------- - - h1, h2, h3, h4, h5, h6 { - color: mc('blue-grey', '700'); - font-weight: 500; - } - - > * + h1, > * + h2, > * + h3, > * + h4 { - margin-top: 3rem; - } - h1 { - font-size: 1.5rem; - border-bottom: 2px solid mc('blue-grey', '100'); - margin-bottom: 1rem; - } - h2 { - font-size: 1.25rem; - border-bottom: 1px solid mc('blue-grey', '100'); - margin-bottom: .75rem; - } - h3 { - font-size: 1.15rem; - border-bottom: 1px dotted mc('blue-grey', '100'); - margin-bottom: .5rem; - color: mc('blue-grey', '500'); - } - h4 { - font-size: 1.1rem; - } - h5 { - font-size: 1.05rem; - } - h6 { - font-size: 1.025rem; - } - - // -------------------------------------------- - // Paragraphs - // -------------------------------------------- - p + p { - margin-top: 1rem; - } - - // -------------------------------------------- - // Lists - // -------------------------------------------- - ul, ol { - & + p { - margin-top: .5rem; - } - } - - ul { - list-style-type: square; - list-style-position: inside; - } - - ol { - list-style-type: decimal; - list-style-position: inside; - } - - // -------------------------------------------- - // Code Blocks - // -------------------------------------------- - > pre { - border: none; - border-radius: 5px; - box-shadow: initial; - background-color: mc('blue-grey', '900'); - padding: 1rem 1rem 1rem 3rem; - - > code { - box-shadow: initial; - display: block; - font-size: .85rem; - font-family: 'Source Code Pro', monospace; - - &:after, &:before { - content: initial; - letter-spacing: initial; - } - } - } - - .task-list-item { - display: flex; - align-items: center; - - &-checkbox { - margin-right: .5rem; - } - } -} diff --git a/client/themes/default/scss/app.scss b/client/themes/default/scss/app.scss index 0b4078e2..77ee021e 100644 --- a/client/themes/default/scss/app.scss +++ b/client/themes/default/scss/app.scss @@ -4,6 +4,10 @@ color: mc('grey', '800'); padding-bottom: 50px; + // --------------------------------- + // HEADERS + // --------------------------------- + h1, h2, h3, h4, h5, h6 { position: relative; @@ -81,14 +85,74 @@ } } + // --------------------------------- + // PARAGRAPHS + // --------------------------------- + p { padding: 1rem 24px 0 24px; margin: 0; text-align: justify; } + blockquote { + padding: 0 0 1rem 0; + border: 1px solid mc('blue', '500'); + border-radius: .5rem; + margin: 1rem; + + &.is-info { + background-color: mc('blue', '50'); + background-image: radial-gradient(ellipse at top, mc('blue', '50'), lighten(mc('blue', '50'), 5%)); + border-color: mc('blue', '100'); + box-shadow: 0 0 2px 0 mc('blue', '100'); + + code { + background-color: mc('blue', '50'); + color: mc('blue', '800'); + } + } + &.is-warning { + background-color: mc('orange', '50'); + background-image: radial-gradient(ellipse at top, mc('orange', '50'), lighten(mc('orange', '50'), 5%)); + border-color: mc('orange', '100'); + box-shadow: 0 0 2px 0 mc('orange', '100'); + + code { + background-color: mc('orange', '50'); + color: mc('orange', '800'); + } + } + &.is-danger { + background-color: mc('red', '50'); + background-image: radial-gradient(ellipse at top, mc('red', '50'), lighten(mc('red', '50'), 5%)); + border-color: mc('red', '100'); + box-shadow: 0 0 2px 0 mc('red', '100'); + + code { + background-color: mc('red', '50'); + color: mc('red', '800'); + } + } + &.is-success { + background-color: mc('green', '50'); + background-image: radial-gradient(ellipse at top, mc('green', '50'), lighten(mc('green', '50'), 5%)); + border-color: mc('green', '100'); + box-shadow: 0 0 2px 0 mc('green', '100'); + + code { + background-color: mc('green', '50'); + color: mc('green', '800'); + } + } + } + + // --------------------------------- + // CODE + // --------------------------------- + code { - background-color: rgba(mc('indigo', '50'), 1); + background-color: mc('indigo', '50'); padding: 0 5px; color: mc('indigo', '800'); font-family: 'Source Code Pro', monospace; @@ -134,4 +198,41 @@ } } + // --------------------------------- + // TASK LISTS + // --------------------------------- + + .task-list-item { + position: relative; + + &-checkbox[disabled] { + display: none; + + & + label { + padding-left: 1.4rem; + } + + & + label::before { + position: absolute; + left: 1rem; + top: 2px; + content: ' '; + display: block; + width: 1.1rem; + height: 1.1rem; + background-color: #FFF; + border: 1px solid mc('grey', '400'); + border-radius: 2px; + font-weight: bold; + font-size: .8rem; + line-height: 1rem; + text-align: center; + } + + &[checked] + label::before { + content: '✓'; + } + } + } + } diff --git a/server/modules/rendering/markdown-core/renderer.js b/server/modules/rendering/markdown-core/renderer.js index 2db52790..44523ea2 100644 --- a/server/modules/rendering/markdown-core/renderer.js +++ b/server/modules/rendering/markdown-core/renderer.js @@ -1,5 +1,6 @@ const md = require('markdown-it') const mdAnchor = require('markdown-it-anchor') +const mdAttrs = require('markdown-it-attrs') const _ = require('lodash') const uslug = require('uslug') @@ -39,6 +40,8 @@ module.exports = { permalinkBefore: true }) + mkdown.use(mdAttrs) + for (let child of this.children) { const renderer = require(`../${_.kebabCase(child.key)}/renderer.js`) renderer.init(mkdown, child.config) diff --git a/server/modules/rendering/markdown-tasklists/renderer.js b/server/modules/rendering/markdown-tasklists/renderer.js index 937158e4..5548e01f 100644 --- a/server/modules/rendering/markdown-tasklists/renderer.js +++ b/server/modules/rendering/markdown-tasklists/renderer.js @@ -6,6 +6,6 @@ const mdTaskLists = require('markdown-it-task-lists') module.exports = { init (md, conf) { - md.use(mdTaskLists) + md.use(mdTaskLists, {label: true, labelAfter: true}) } }