diff --git a/package.json b/package.json index 968ad509c..f270102a8 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "@types/codemirror": "0.0.96", "@types/jest": "26.0.0", "@types/markdown-it": "10.0.1", + "@types/markdown-it-container": "^2.0.3", "@types/node": "12.12.47", "@types/node-sass": "4.11.1", "@types/react": "16.9.38", @@ -40,6 +41,7 @@ "markdown-it": "11.0.0", "markdown-it-abbr": "^1.0.4", "markdown-it-deflist": "^2.0.3", + "markdown-it-container": "^3.0.0", "markdown-it-emoji": "1.4.0", "markdown-it-ins": "^3.0.0", "markdown-it-mark": "^3.0.0", diff --git a/src/components/editor/markdown-preview/container-plugins/alert.ts b/src/components/editor/markdown-preview/container-plugins/alert.ts new file mode 100644 index 000000000..b459f697a --- /dev/null +++ b/src/components/editor/markdown-preview/container-plugins/alert.ts @@ -0,0 +1,15 @@ +import Renderer from 'markdown-it/lib/renderer' +import Token from 'markdown-it/lib/token' + +type RenderContainerReturn = (tokens: Token[], index: number, options: any, env: any, self: Renderer) => void; +type ValidAlertLevels = ('warning' | 'danger' | 'success' | 'info') +export const validAlertLevels: ValidAlertLevels[] = ['success', 'danger', 'info', 'warning'] + +export const createRenderContainer = (level: ValidAlertLevels): RenderContainerReturn => { + return (tokens: Token[], index: number, options: any, env: any, self: Renderer) => { + tokens[index].attrJoin('role', 'alert') + tokens[index].attrJoin('class', 'alert') + tokens[index].attrJoin('class', `alert-${level}`) + return self.renderToken(tokens, index, options) + } +} diff --git a/src/components/editor/markdown-preview/markdown-preview.scss b/src/components/editor/markdown-preview/markdown-preview.scss index e5a7d5ece..12267c020 100644 --- a/src/components/editor/markdown-preview/markdown-preview.scss +++ b/src/components/editor/markdown-preview/markdown-preview.scss @@ -3,4 +3,8 @@ .markdown-body { max-width: 758px; font-family: 'Source Sans Pro', "twemoji", sans-serif; + + .alert > p, .alert > ul { + margin-bottom: 0; + } } diff --git a/src/components/editor/markdown-preview/markdown-preview.tsx b/src/components/editor/markdown-preview/markdown-preview.tsx index 82ab8d659..41595c3bc 100644 --- a/src/components/editor/markdown-preview/markdown-preview.tsx +++ b/src/components/editor/markdown-preview/markdown-preview.tsx @@ -1,15 +1,17 @@ import MarkdownIt from 'markdown-it' -import emoji from 'markdown-it-emoji' -import markdownItRegex from 'markdown-it-regex' -import taskList from 'markdown-it-task-lists' import abbreviation from 'markdown-it-abbr' +import markdownItContainer from 'markdown-it-container' import definitionList from 'markdown-it-deflist' -import subscript from 'markdown-it-sub' -import superscript from 'markdown-it-sup' +import emoji from 'markdown-it-emoji' import inserted from 'markdown-it-ins' import marked from 'markdown-it-mark' +import markdownItRegex from 'markdown-it-regex' +import subscript from 'markdown-it-sub' +import superscript from 'markdown-it-sup' +import taskList from 'markdown-it-task-lists' import React, { ReactElement, useMemo } from 'react' import ReactHtmlParser, { convertNodeToElement, Transform } from 'react-html-parser' +import { createRenderContainer, validAlertLevels } from './container-plugins/alert' import { MarkdownItParserDebugger } from './markdown-it-plugins/parser-debugger' import './markdown-preview.scss' import { replaceGistLink } from './regex-plugins/replace-gist-link' @@ -57,6 +59,11 @@ const MarkdownPreview: React.FC = ({ content }) => { md.use(markdownItRegex, replaceVimeoLink) md.use(markdownItRegex, replaceGistLink) md.use(MarkdownItParserDebugger) + + validAlertLevels.forEach(level => { + md.use(markdownItContainer, level, { render: createRenderContainer(level) }) + }) + return md }, []) diff --git a/yarn.lock b/yarn.lock index af5123c81..69a0016a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1587,7 +1587,14 @@ resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-2.1.0.tgz#ea3dd64c4805597311790b61e872cbd1ed2cd806" integrity sha512-Q7DYAOi9O/+cLLhdaSvKdaumWyHbm7HAk/bFwwyTuU0arR5yyCeW5GOoqt4tJTpDRxhpx9Q8kQL6vMpuw9hDSw== -"@types/markdown-it@10.0.1": +"@types/markdown-it-container@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/markdown-it-container/-/markdown-it-container-2.0.3.tgz#436de4c019d7d71b60f759037fd4d03611569eb8" + integrity sha512-ouJluaEGWV7clX7NVMRjkQfS/a11hFXDG1U04l8vrS1P2UgAFPlgMpk1rAPgK0MWU1NhcBYWVW7w/SpgePLs0A== + dependencies: + "@types/markdown-it" "*" + +"@types/markdown-it@*", "@types/markdown-it@10.0.1": version "10.0.1" resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-10.0.1.tgz#94e252ab689c8e9ceb9aff2946e0a458390105eb" integrity sha512-L1ibTdA5IUe/cRBlf3N3syAOBQSN1WCMGtAWir6mKxibiRl4LmpZM4jLz+7zAqiMnhQuAP1sqZOF9wXgn2kpEg== @@ -7280,6 +7287,11 @@ markdown-it-deflist@^2.0.3: resolved "https://registry.yarnpkg.com/markdown-it-deflist/-/markdown-it-deflist-2.0.3.tgz#5727db04184d3cb2bc6ee4a9641e3a1091d5fd6f" integrity sha512-/BNZ8ksW42bflm1qQLnRI09oqU2847Z7MVavrR0MORyKLtiUYOMpwtlAfMSZAQU9UCvaUZMpgVAqoS3vpToJxw== +markdown-it-container@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-3.0.0.tgz#1d19b06040a020f9a827577bb7dbf67aa5de9a5b" + integrity sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw== + markdown-it-emoji@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc"