From c05448d50ce31f69a7f719e378da2d6ded5477a7 Mon Sep 17 00:00:00 2001
From: Evan You
Date: Fri, 6 Apr 2018 17:08:01 -0400
Subject: [PATCH] support using component at root level
---
README.md | 2 +
docs/.vuepress/components/OtherComponent.vue | 3 +
docs/.vuepress/components/demo-1.vue | 6 +-
docs/assets.md | 0
docs/test.md | 5 ++
docs/using-vue.md | 36 +++++++--
lib/default-theme/styles.css | 6 ++
lib/markdown/component.js | 81 ++++++++++++++++++++
lib/markdown/hoist.js | 3 +
lib/markdown/index.js | 6 +-
10 files changed, 136 insertions(+), 12 deletions(-)
create mode 100644 docs/.vuepress/components/OtherComponent.vue
create mode 100644 docs/assets.md
create mode 100644 docs/test.md
create mode 100644 lib/markdown/component.js
create mode 100644 lib/markdown/hoist.js
diff --git a/README.md b/README.md
index 376b6ed017..7ed6e15e4a 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,8 @@
- Vue-powered: the layout system is a Vue app. It's also pre-rendered into static HTML. And you can register and use Vue components inside markdown content.
+ - Deep markdown customization to make using Vue inside markdown a breeze.
+
- Docs first: most of your content will be in Markdown.
- Largely gitbook compatible: should be easy to migrate existing gitbook docs over, and maintain original URLs.
diff --git a/docs/.vuepress/components/OtherComponent.vue b/docs/.vuepress/components/OtherComponent.vue
new file mode 100644
index 0000000000..1d97c7ca8e
--- /dev/null
+++ b/docs/.vuepress/components/OtherComponent.vue
@@ -0,0 +1,3 @@
+
+ This is another component
+
diff --git a/docs/.vuepress/components/demo-1.vue b/docs/.vuepress/components/demo-1.vue
index 085af055ed..f1dfb581c5 100644
--- a/docs/.vuepress/components/demo-1.vue
+++ b/docs/.vuepress/components/demo-1.vue
@@ -1,14 +1,14 @@
-
+
+ -->
diff --git a/lib/default-theme/styles.css b/lib/default-theme/styles.css
index 0167c2140c..42487f6e46 100644
--- a/lib/default-theme/styles.css
+++ b/lib/default-theme/styles.css
@@ -40,6 +40,12 @@ div.danger {
background-color: red;
}
+p.demo {
+ padding: 1rem;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+}
+
/*
Copied from nprogress since it doens't
allow programmatic configuration of color
diff --git a/lib/markdown/component.js b/lib/markdown/component.js
new file mode 100644
index 0000000000..749adf43ed
--- /dev/null
+++ b/lib/markdown/component.js
@@ -0,0 +1,81 @@
+// Replacing the default htmlBlock rule to allow using custom components at
+// root level
+
+const blockNames = require('markdown-it/lib/common/htmlBlocks')
+const HTML_OPEN_CLOSE_TAG_RE = require('markdown-it/lib/common/html_re').HTML_OPEN_CLOSE_TAG_RE
+
+// An array of opening and corresponding closing sequences for html tags,
+// last argument defines whether it can terminate a paragraph or not
+const HTML_SEQUENCES = [
+ [/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true],
+ [/^/, true],
+ [/^<\?/, /\?>/, true],
+ [/^/, true],
+ [/^/, true],
+ // PascalCase Components
+ [/^<[A-Z]/, />/, true],
+ // custom elements with hyphens
+ [/^<\w+\-/, />/, true],
+ [new RegExp('^?(' + blockNames.join('|') + ')(?=(\\s|/?>|$))', 'i'), /^$/, true],
+ [new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + '\\s*$'), /^$/, false]
+]
+
+module.exports = md => {
+ md.block.ruler.at('htmlBlock', htmlBlock)
+}
+
+function htmlBlock (state, startLine, endLine, silent) {
+ let i, nextLine, lineText
+ let pos = state.bMarks[startLine] + state.tShift[startLine]
+ let max = state.eMarks[startLine]
+
+ // if it's indented more than 3 spaces, it should be a code block
+ if (state.sCount[startLine] - state.blkIndent >= 4) { return false }
+
+ if (!state.md.options.html) { return false }
+
+ if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false }
+
+ lineText = state.src.slice(pos, max)
+
+ for (i = 0; i < HTML_SEQUENCES.length; i++) {
+ if (HTML_SEQUENCES[i][0].test(lineText)) { break }
+ }
+
+ if (i === HTML_SEQUENCES.length) {
+ console.log(lineText)
+ return false
+ }
+
+ if (silent) {
+ // true if this sequence can be a terminator, false otherwise
+ return HTML_SEQUENCES[i][2]
+ }
+
+ nextLine = startLine + 1
+
+ // If we are here - we detected HTML block.
+ // Let's roll down till block end.
+ if (!HTML_SEQUENCES[i][1].test(lineText)) {
+ for (; nextLine < endLine; nextLine++) {
+ if (state.sCount[nextLine] < state.blkIndent) { break }
+
+ pos = state.bMarks[nextLine] + state.tShift[nextLine]
+ max = state.eMarks[nextLine]
+ lineText = state.src.slice(pos, max)
+
+ if (HTML_SEQUENCES[i][1].test(lineText)) {
+ if (lineText.length !== 0) { nextLine++ }
+ break
+ }
+ }
+ }
+
+ state.line = nextLine
+
+ const token = state.push('htmlBlock', '', 0)
+ token.map = [startLine, nextLine]
+ token.content = state.getLines(startLine, nextLine, state.blkIndent, true)
+
+ return true
+}
diff --git a/lib/markdown/hoist.js b/lib/markdown/hoist.js
new file mode 100644
index 0000000000..fb54163953
--- /dev/null
+++ b/lib/markdown/hoist.js
@@ -0,0 +1,3 @@
+module.exports = md => {
+
+}
diff --git a/lib/markdown/index.js b/lib/markdown/index.js
index 5895292545..9c1eaf8f73 100644
--- a/lib/markdown/index.js
+++ b/lib/markdown/index.js
@@ -1,5 +1,6 @@
const highlight = require('./highlight')
const highlightLines = require('./highlightLines')
+const component = require('./component')
const convertRouterLink = require('./link')
const emoji = require('markdown-it-emoji')
const anchor = require('markdown-it-anchor')
@@ -16,8 +17,11 @@ module.exports = ({ markdown = {}}) => {
typographer: true,
highlight
})
- .use(convertRouterLink)
+ // custom plugins
+ .use(component)
.use(highlightLines)
+ .use(convertRouterLink)
+ // 3rd party plugins
.use(emoji)
.use(anchor, Object.assign({ permalink: true, permalinkBefore: true }, markdown.anchor))
.use(toc, Object.assign({ includeLevel: [2, 3] }, markdown.toc))