mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-12 17:26:17 +00:00
218 lines
6.2 KiB
JavaScript
218 lines
6.2 KiB
JavaScript
(function(mod) {
|
|
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
mod(require("../codemirror/lib/codemirror"), require("../codemirror/mode/gfm/gfm"), require("../codemirror/mode/yaml-frontmatter/yaml-frontmatter"))
|
|
else if (typeof define == "function" && define.amd) // AMD
|
|
define(["../codemirror/lib/codemirror", "../codemirror/mode/gfm/gfm", "../codemirror/mode/yaml-frontmatter/yaml-frontmatter"], mod)
|
|
else // Plain browser env
|
|
mod(CodeMirror)
|
|
})(function(CodeMirror) {
|
|
'use strict'
|
|
|
|
const fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]+)?(?:\(((?:\s*\w[-\w]*(?:=(?:'(?:.*?[^\\])?'|"(?:.*?[^\\])?"|(?:[^'"][^\s]*)))?)*)\))?(?::([^:]*)(?::(\d+))?)?\s*$/
|
|
|
|
function getMode(name, params, config, cm) {
|
|
if (!name) {
|
|
return null
|
|
}
|
|
|
|
const parameters = {}
|
|
if (params) {
|
|
const regex = /(\w[-\w]*)(?:=(?:'(.*?[^\\])?'|"(.*?[^\\])?"|([^'"][^\s]*)))?/g
|
|
|
|
let match
|
|
while ((match = regex.exec(params))) {
|
|
parameters[match[1]] = match[2] || match[3] || match[4] || null
|
|
}
|
|
}
|
|
|
|
if (name === 'chart') {
|
|
name = parameters.hasOwnProperty('yaml') ? 'yaml' : 'json'
|
|
}
|
|
|
|
const found = CodeMirror.findModeByName(name)
|
|
if (!found) {
|
|
return null
|
|
}
|
|
|
|
if (CodeMirror.modes.hasOwnProperty(found.mode)) {
|
|
const mode = CodeMirror.getMode(config, found.mode)
|
|
|
|
return mode.name === 'null' ? null : mode
|
|
} else {
|
|
CodeMirror.requireMode(found.mode, () => {
|
|
cm.setOption('mode', cm.getOption('mode'))
|
|
})
|
|
}
|
|
}
|
|
|
|
CodeMirror.defineMode('bfm', function (config, baseConfig) {
|
|
baseConfig.name = 'yaml-frontmatter'
|
|
const baseMode = CodeMirror.getMode(config, baseConfig)
|
|
|
|
return {
|
|
startState: function() {
|
|
return {
|
|
baseState: CodeMirror.startState(baseMode),
|
|
|
|
basePos: 0,
|
|
baseCur: null,
|
|
overlayPos: 0,
|
|
overlayCur: null,
|
|
streamSeen: null,
|
|
|
|
fencedEndRE: null,
|
|
|
|
inTable: false,
|
|
rowIndex: 0
|
|
}
|
|
},
|
|
copyState: function(s) {
|
|
return {
|
|
baseState: CodeMirror.copyState(baseMode, s.baseState),
|
|
|
|
basePos: s.basePos,
|
|
baseCur: null,
|
|
overlayPos: s.overlayPos,
|
|
overlayCur: null,
|
|
|
|
fencedMode: s.fencedMode,
|
|
fencedState: s.fencedMode ? CodeMirror.copyState(s.fencedMode, s.fencedState) : null,
|
|
|
|
fencedEndRE: s.fencedEndRE,
|
|
|
|
inTable: s.inTable,
|
|
rowIndex: s.rowIndex
|
|
}
|
|
},
|
|
token: function(stream, state) {
|
|
const initialPos = stream.pos
|
|
|
|
if (state.fencedEndRE) {
|
|
if (stream.match(state.fencedEndRE)) {
|
|
state.fencedEndRE = null
|
|
state.fencedMode = null
|
|
state.fencedState = null
|
|
|
|
stream.pos = initialPos
|
|
} else if (state.fencedMode) {
|
|
return state.fencedMode.token(stream, state.fencedState)
|
|
} else {
|
|
state.overlayCur = this.overlayToken(stream, state)
|
|
state.overlayPos = stream.pos
|
|
|
|
return state.overlayCur
|
|
}
|
|
}
|
|
else {
|
|
const match = stream.match(fencedCodeRE, true)
|
|
if (match) {
|
|
state.fencedEndRE = new RegExp(match[1] + '+ *$')
|
|
|
|
state.fencedMode = getMode(match[2], match[3], config, stream.lineOracle.doc.cm)
|
|
if (state.fencedMode) {
|
|
state.fencedState = CodeMirror.startState(state.fencedMode)
|
|
}
|
|
|
|
stream.pos = initialPos
|
|
}
|
|
}
|
|
|
|
if (stream != state.streamSeen || Math.min(state.basePos, state.overlayPos) < stream.start) {
|
|
state.streamSeen = stream
|
|
state.basePos = state.overlayPos = stream.start
|
|
}
|
|
|
|
if (stream.start == state.basePos) {
|
|
state.baseCur = baseMode.token(stream, state.baseState)
|
|
state.basePos = stream.pos
|
|
}
|
|
if (stream.start == state.overlayPos) {
|
|
stream.pos = stream.start
|
|
state.overlayCur = this.overlayToken(stream, state)
|
|
state.overlayPos = stream.pos
|
|
}
|
|
stream.pos = Math.min(state.basePos, state.overlayPos)
|
|
|
|
if (state.overlayCur == null) {
|
|
return state.baseCur
|
|
}
|
|
else if (state.baseCur != null && state.combineTokens) {
|
|
return state.baseCur + ' ' + state.overlayCur
|
|
}
|
|
else {
|
|
return state.overlayCur
|
|
}
|
|
},
|
|
overlayToken: function(stream, state) {
|
|
state.combineTokens = false
|
|
|
|
if (state.localMode) {
|
|
return state.localMode.token(stream, state.localState) || ''
|
|
}
|
|
|
|
state.combineTokens = true
|
|
|
|
if (state.inTable) {
|
|
if (stream.match(/^\|/)) {
|
|
++state.rowIndex
|
|
|
|
stream.skipToEnd()
|
|
|
|
if (state.rowIndex === 1) {
|
|
return 'table table-separator'
|
|
} else if (state.rowIndex % 2 === 0) {
|
|
return 'table table-row table-row-even'
|
|
} else {
|
|
return 'table table-row table-row-odd'
|
|
}
|
|
} else {
|
|
state.inTable = false
|
|
|
|
stream.skipToEnd()
|
|
return null
|
|
}
|
|
} else if (stream.match(/^\|/)) {
|
|
state.inTable = true
|
|
state.rowIndex = 0
|
|
|
|
stream.skipToEnd()
|
|
return 'table table-header'
|
|
}
|
|
|
|
stream.skipToEnd()
|
|
return null
|
|
},
|
|
electricChars: baseMode.electricChars,
|
|
innerMode: function(state) {
|
|
if (state.fencedMode) {
|
|
return {
|
|
mode: state.fencedMode,
|
|
state: state.fencedState
|
|
}
|
|
} else {
|
|
return {
|
|
mode: baseMode,
|
|
state: state.baseState
|
|
}
|
|
}
|
|
},
|
|
blankLine: function(state) {
|
|
state.inTable = false
|
|
|
|
if (state.fencedMode) {
|
|
return state.fencedMode.blankLine && state.fencedMode.blankLine(state.fencedState)
|
|
} else {
|
|
return baseMode.blankLine(state.baseState)
|
|
}
|
|
}
|
|
}
|
|
}, 'yaml-frontmatter')
|
|
|
|
CodeMirror.defineMIME('text/x-bfm', 'bfm')
|
|
|
|
CodeMirror.modeInfo.push({
|
|
name: "Boost Flavored Markdown",
|
|
mime: "text/x-bfm",
|
|
mode: "bfm"
|
|
})
|
|
}) |