import marked from 'marked' import Prism from 'prismjs' import * as tpl from './tpl' import * as event from './event' import * as polyfill from './polyfill' import { genTree, getRoute, isMobile, slugify, merge, emojify } from './util' let markdown = marked let toc = [] const CACHE = {} const originTitle = document.title const renderTo = function (dom, content) { dom = typeof dom === 'object' ? dom : document.querySelector(dom) dom.innerHTML = content slugify.clear() return dom } /** * init render */ export function init () { const renderer = new marked.Renderer() /** * render anchor tag * @link https://github.com/chjj/marked#overriding-renderer-methods */ renderer.heading = function (text, level) { const slug = slugify(text) let route = '' route = `#/${getRoute()}` toc.push({ level, slug: `${route}#${encodeURIComponent(slug)}`, title: text }) return `${text}` } // highlight code renderer.code = function (code, lang = '') { const hl = Prism.highlight(code, Prism.languages[lang] || Prism.languages.markup) return `
${hl}
` } renderer.link = function (href, title, text) { if (!/:|(\/{2})/.test(href)) { href = `#/${href}`.replace(/\/+/g, '/') } return `${text}` } renderer.paragraph = function (text) { if (/^!>/.test(text)) { return tpl.helper('tip', text) } else if (/^\?>/.test(text)) { return tpl.helper('warn', text) } return `

${text}

` } renderer.image = function (href, title, text) { const url = /:|(\/{2})/.test(href) ? href : ($docsify.basePath + href).replace(/\/+/g, '/') const titleHTML = title ? ` title="${title}"` : '' return `${text}` } if (typeof $docsify.markdown === 'function') { markdown = $docsify.markdown.call(this, markdown, renderer) } else { if ($docsify.markdown && $docsify.markdown.renderer) { $docsify.markdown.renderer = merge(renderer, $docsify.markdown.renderer) } markdown.setOptions(merge({ renderer }, $docsify.markdown)) } const md = markdown markdown = text => emojify(md(text)) window.Docsify.utils.marked = text => { const result = markdown(text) toc = [] return result } } /** * App */ export function renderApp (dom, replace) { const nav = document.querySelector('nav') || document.createElement('nav') const body = document.body const head = document.head if (!$docsify.repo) nav.classList.add('no-badge') dom[replace ? 'outerHTML' : 'innerHTML'] = tpl.corner($docsify.repo) + ($docsify.coverpage ? tpl.cover() : '') + tpl.main() body.insertBefore(nav, body.children[0]) // theme color if ($docsify.themeColor) { head.innerHTML += tpl.theme($docsify.themeColor) polyfill.cssVars() } // render name if ($docsify.name) { const aside = document.querySelector('.sidebar') aside.innerHTML = `

${$docsify.name}

` + aside.innerHTML } // bind toggle event.bindToggle('button.sidebar-toggle') // bind sticky effect if ($docsify.coverpage) { !isMobile() && window.addEventListener('scroll', event.sticky) } else { body.classList.add('sticky') } } /** * article */ export function renderArticle (content) { const hook = window.Docsify.hook const renderFn = function (data) { renderTo('article', data) if (!$docsify.loadSidebar) renderSidebar() if (data && typeof Vue !== 'undefined') { CACHE.vm && CACHE.vm.$destroy() const script = [].slice.call( document.body.querySelectorAll('article>script')) .filter(script => !/template/.test(script.type) )[0] const code = script ? script.innerText.trim() : null script && script.remove() CACHE.vm = code ? new Function(`return ${code}`)() : new Vue({ el: 'main' }) // eslint-disable-line CACHE.vm && CACHE.vm.$nextTick(_ => event.scrollActiveSidebar()) } if ($docsify.auto2top) setTimeout(() => event.scroll2Top($docsify.auto2top), 0) } hook.emit('before', content, result => { const html = result ? markdown(result) : '' hook.emit('after', html, result => renderFn(result || 'not found')) }) } /** * navbar */ export function renderNavbar (content) { if (CACHE.navbar && CACHE.navbar === content) return CACHE.navbar = content if (content) renderTo('nav', markdown(content)) event.activeLink('nav') } /** * sidebar */ export function renderSidebar (content) { let html if (content) { html = markdown(content) // find url tag html = html.match(/]*>([\s\S]+)<\/ul>/g)[0] } else { html = tpl.tree(genTree(toc, $docsify.maxLevel), '