yaml-frontmatter.js 2.9 KB

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