Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

embeds #246

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions src/components/UniLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@ export default {

props: ['openInNewTab', 'externalLinkIcon'],

render(
h,
{
data,
children,
props: {openInNewTab, externalLinkIcon}
}
) {
render(h, {data, children, props: {openInNewTab, externalLinkIcon}}) {
const attrs = {...data.attrs}
const {to} = attrs

Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import versionsPlugin from './plugins/versions'
import bannerFooter from './plugins/banner-footer'
import darkThemeToggler from './plugins/dark-theme-toggler'
import searchPlugin from './plugins/search'
import embedPlugin from './plugins/embed'

Vue.component(ImageZoom.name, ImageZoom)
Vue.component(Badge.name, Badge)
Expand Down Expand Up @@ -55,6 +56,7 @@ class Docute {
})

const plugins = [
embedPlugin,
i18nPlugin,
evaluateContentPlugin,
versionsPlugin,
Expand Down
66 changes: 66 additions & 0 deletions src/plugins/embed/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {getFilenameByPath, getFileUrl, isExternalLink} from '../../utils'
import inlineRender from '../../utils/inlineRender'

const SCAN = /#embed\(.*?\)(?!`)/g

async function getFile(url, api, type) {
if (!isExternalLink(url)) {
let filename = getFilenameByPath(url)
if (type) {
filename = filename.replace('.md', '')
}
const file = getFileUrl(api.store.getters.config.sourcePath, filename)
const res = await fetch(file)
return res.text()
}
return url
}

function compileMedia(type, url, api, codeType = '') {
switch (type) {
case 'fragment':
return getFile(url, api).then(inlineRender)
case 'code':
return getFile(url, api, type)
.then(x => `\`\`\`${codeType}\n${x}\n\`\`\``)
.then(inlineRender)
default:
return 'Missing embed kind'
}
}

async function replaceAsync(str, regex, asyncFn) {
const promises = []
str.replace(regex, (match, ...args) => {
const promise = asyncFn(match, ...args)
promises.push(promise)
})
const data = await Promise.all(promises)
return str.replace(regex, () => data.shift())
}

function transformEmbeds(markdown, api) {
function process(match) {
const params = match
.replace('#embed(', '')
.replace(')', '')
.split(' ')
const href = params[0]
const type = params[1]
const codeType = params[2]
const embed = compileMedia(type, href, api, codeType, params.slice(3))
return embed
}
return replaceAsync(markdown, SCAN, process)
}

const embedPlugin = {
name: 'embed',
extend(api) {
api.processMarkdown(async markdown => {
return transformEmbeds(markdown, api)
})
}
}

export default embedPlugin
22 changes: 22 additions & 0 deletions src/utils/inlineRender.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import hooks from '../hooks'
import markedRenderer from './markedRenderer'
import marked from './marked'
import highlight from './highlight'

async function inlineRender(iContent) {
let content = await hooks.processPromise('processMarkdown', iContent)
const env = {
headings: [],
mixins: [],
config: {}
}
content = marked(content, {
renderer: markedRenderer(hooks),
highlight,
env
})
content = await hooks.processPromise('processHTML', content)
return content
}

export default inlineRender
2 changes: 2 additions & 0 deletions website/docs/exampleEmbeds/embedjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const a = 1
const b = a? a: 0
3 changes: 3 additions & 0 deletions website/docs/exampleEmbeds/fragment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Title from fragment

*fragment body*
15 changes: 15 additions & 0 deletions website/docs/guide/embed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Embed

Embeds let you display items from different files.

## Demonstrations
Some of these describe defaults, and caveats.

### Code

#embed(/exampleEmbeds/embedjs.js code js)

### Fragment
Note that the titles from fragment aren't visible in sidebar. Titles of second and third level are suppose to be shown there with the first level used as browser tab title.

#embed(/exampleEmbeds/fragment.md fragment)
4 changes: 4 additions & 0 deletions website/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ new Docute({
title: 'Plugin',
link: '/guide/plugin'
},
{
title: 'Embed',
link: '/guide/embed'
},
{
title: 'Deployment',
link: '/guide/deployment'
Expand Down