scripts/CodeMirror/mode/yaml-frontmatter/yaml-frontmatter.js (view raw)
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://codemirror.net/LICENSE
3
4(function (mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../yaml/yaml"))
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../yaml/yaml"], mod)
9 else // Plain browser env
10 mod(CodeMirror)
11})(function (CodeMirror) {
12
13 var START = 0, FRONTMATTER = 1, BODY = 2
14
15 // a mixed mode for Markdown text with an optional YAML front matter
16 CodeMirror.defineMode("yaml-frontmatter", function (config, parserConfig) {
17 var yamlMode = CodeMirror.getMode(config, "yaml")
18 var innerMode = CodeMirror.getMode(config, parserConfig && parserConfig.base || "gfm")
19
20 function curMode(state) {
21 return state.state == BODY ? innerMode : yamlMode
22 }
23
24 return {
25 startState: function () {
26 return {
27 state: START,
28 inner: CodeMirror.startState(yamlMode)
29 }
30 },
31 copyState: function (state) {
32 return {
33 state: state.state,
34 inner: CodeMirror.copyState(curMode(state), state.inner)
35 }
36 },
37 token: function (stream, state) {
38 if (state.state == START) {
39 if (stream.match(/---/, false)) {
40 state.state = FRONTMATTER
41 return yamlMode.token(stream, state.inner)
42 } else {
43 state.state = BODY
44 state.inner = CodeMirror.startState(innerMode)
45 return innerMode.token(stream, state.inner)
46 }
47 } else if (state.state == FRONTMATTER) {
48 var end = stream.sol() && stream.match(/(---|\.\.\.)/, false)
49 var style = yamlMode.token(stream, state.inner)
50 if (end) {
51 state.state = BODY
52 state.inner = CodeMirror.startState(innerMode)
53 }
54 return style
55 } else {
56 return innerMode.token(stream, state.inner)
57 }
58 },
59 innerMode: function (state) {
60 return {mode: curMode(state), state: state.inner}
61 },
62 blankLine: function (state) {
63 var mode = curMode(state)
64 if (mode.blankLine) return mode.blankLine(state.inner)
65 }
66 }
67 })
68});