yaml-frontmatter.js 2.4 KB

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