diff --git a/src/builder/parsers/markdown/index.js b/src/builder/parsers/markdown/index.js index 270bdcf..cec78dd 100644 --- a/src/builder/parsers/markdown/index.js +++ b/src/builder/parsers/markdown/index.js @@ -2,7 +2,7 @@ import MarkdownIt from 'markdown-it' import matter from 'gray-matter' import { DOMParser } from '@xmldom/xmldom' -import JSON5 from 'json5' +import YAML from 'js-yaml' import htmlTags from 'html-tags' import voidHtmlTags from 'html-tags/void.js' @@ -70,7 +70,7 @@ const nodeToVnode = (node, env) => { const attribute = node.attributes[i] try { - attributes[attribute.name] = JSON5.parse(attribute.value) + attributes[attribute.name] = YAML.load(attribute.value) } catch (e) { attributes[attribute.name] = attribute.value } diff --git a/src/runtime/components/NuxtContent.vue b/src/runtime/components/NuxtContent.vue index de8f6ee..6ff31c5 100644 --- a/src/runtime/components/NuxtContent.vue +++ b/src/runtime/components/NuxtContent.vue @@ -6,17 +6,41 @@ const isArr = Array.isArray const isObj = item => typeof item == 'object' const isPobj = item => isObj(item) && !isArr(item) -const toNode = node => isArr(node) ? toComp(node) : node -const toArgs = item => isArr(item) ? item.map(toNode) : item -const toSlot = item => isPobj(item) ? item : (() => item) +const toNode = ctx => node => isArr(node) ? toComp(node, ctx) : node +const toArgs = ctx => item => isArr(item) ? item.map(toNode(ctx)) : item +const toSlot = ctx => item => isPobj(item) ? toProp(item, ctx) : (() => item) -const toComp = ([tag, ...props]) => { +const toComp = ([tag, ...attrs], ctx) => { const comp = /nuxt-?link/i.test(tag) ? NuxtLink : resolveDynamicComponent(tag) - const args = isObj(comp) ? props.map(toArgs).map(toSlot) : props.map(toArgs) + const args = isObj(comp) ? attrs.map(toArgs(ctx)).map(toSlot(ctx)) : attrs.map(toArgs(ctx)) return h(comp, ...args) } +const getVal = (obj, path) => path.split('.') + .reduce((o, i) => Object(o)[i], obj) + +const toProp = (value, ctx) => { + if (isPobj(value)) { + return Object.keys(value).reduce((obj, key) => { + obj[key] = toProp(value[key], ctx) + return obj + }, {}) + } + + if (typeof value == 'string') { + if (value == '$doc' || value.startsWith('$doc.')) { + return getVal({ $doc: ctx.document }, value) + } + + if (value == '$ctx' || value.startsWith('$ctx.')) { + return getVal({ $ctx: ctx.context }, value) + } + } + + return value +} + export default { name: 'NuxtContent', props: { @@ -24,6 +48,10 @@ export default { type: String, default: 'div' }, + context: { + type: Object, + default: () => ({}) + }, document: { type: Object, required: true @@ -33,7 +61,7 @@ export default { const body = this.document.body if (isArr(body)) { - return h(this.tag, body.map(toNode)) + return h(this.tag, body.map(toNode(this))) } else { return h(this.tag, { innerHTML: body }) }