123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- // CodeMirror, copyright (c) by Marijn Haverbeke and others
- // Distributed under an MIT license: https://codemirror.net/LICENSE
- /*
- * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de)
- * Licence: MIT
- */
- ;(function (mod) {
- if (typeof exports == 'object' && typeof module == 'object')
- // CommonJS
- mod(require('../../lib/codemirror'))
- else if (typeof define == 'function' && define.amd)
- // AMD
- define(['../../lib/codemirror'], mod)
- // Plain browser env
- else mod(CodeMirror)
- })(function (CodeMirror) {
- 'use strict'
- CodeMirror.defineMode('stex', function (_config, parserConfig) {
- 'use strict'
- function pushCommand(state, command) {
- state.cmdState.push(command)
- }
- function peekCommand(state) {
- if (state.cmdState.length > 0) {
- return state.cmdState[state.cmdState.length - 1]
- } else {
- return null
- }
- }
- function popCommand(state) {
- var plug = state.cmdState.pop()
- if (plug) {
- plug.closeBracket()
- }
- }
- // returns the non-default plugin closest to the end of the list
- function getMostPowerful(state) {
- var context = state.cmdState
- for (var i = context.length - 1; i >= 0; i--) {
- var plug = context[i]
- if (plug.name == 'DEFAULT') {
- continue
- }
- return plug
- }
- return {
- styleIdentifier: function () {
- return null
- },
- }
- }
- function addPluginPattern(pluginName, cmdStyle, styles) {
- return function () {
- this.name = pluginName
- this.bracketNo = 0
- this.style = cmdStyle
- this.styles = styles
- this.argument = null // \begin and \end have arguments that follow. These are stored in the plugin
- this.styleIdentifier = function () {
- return this.styles[this.bracketNo - 1] || null
- }
- this.openBracket = function () {
- this.bracketNo++
- return 'bracket'
- }
- this.closeBracket = function () {}
- }
- }
- var plugins = {}
- plugins['importmodule'] = addPluginPattern('importmodule', 'tag', ['string', 'builtin'])
- plugins['documentclass'] = addPluginPattern('documentclass', 'tag', ['', 'atom'])
- plugins['usepackage'] = addPluginPattern('usepackage', 'tag', ['atom'])
- plugins['begin'] = addPluginPattern('begin', 'tag', ['atom'])
- plugins['end'] = addPluginPattern('end', 'tag', ['atom'])
- plugins['label'] = addPluginPattern('label', 'tag', ['atom'])
- plugins['ref'] = addPluginPattern('ref', 'tag', ['atom'])
- plugins['eqref'] = addPluginPattern('eqref', 'tag', ['atom'])
- plugins['cite'] = addPluginPattern('cite', 'tag', ['atom'])
- plugins['bibitem'] = addPluginPattern('bibitem', 'tag', ['atom'])
- plugins['Bibitem'] = addPluginPattern('Bibitem', 'tag', ['atom'])
- plugins['RBibitem'] = addPluginPattern('RBibitem', 'tag', ['atom'])
- plugins['DEFAULT'] = function () {
- this.name = 'DEFAULT'
- this.style = 'tag'
- this.styleIdentifier = this.openBracket = this.closeBracket = function () {}
- }
- function setState(state, f) {
- state.f = f
- }
- // called when in a normal (no environment) context
- function normal(source, state) {
- var plug
- // Do we look like '\command' ? If so, attempt to apply the plugin 'command'
- if (source.match(/^\\[a-zA-Z@]+/)) {
- var cmdName = source.current().slice(1)
- plug = plugins.hasOwnProperty(cmdName) ? plugins[cmdName] : plugins['DEFAULT']
- plug = new plug()
- pushCommand(state, plug)
- setState(state, beginParams)
- return plug.style
- }
- // escape characters
- if (source.match(/^\\[$&%#{}_]/)) {
- return 'tag'
- }
- // white space control characters
- if (source.match(/^\\[,;!\/\\]/)) {
- return 'tag'
- }
- // find if we're starting various math modes
- if (source.match('\\[')) {
- setState(state, function (source, state) {
- return inMathMode(source, state, '\\]')
- })
- return 'keyword'
- }
- if (source.match('\\(')) {
- setState(state, function (source, state) {
- return inMathMode(source, state, '\\)')
- })
- return 'keyword'
- }
- if (source.match('$$')) {
- setState(state, function (source, state) {
- return inMathMode(source, state, '$$')
- })
- return 'keyword'
- }
- if (source.match('$')) {
- setState(state, function (source, state) {
- return inMathMode(source, state, '$')
- })
- return 'keyword'
- }
- var ch = source.next()
- if (ch == '%') {
- source.skipToEnd()
- return 'comment'
- } else if (ch == '}' || ch == ']') {
- plug = peekCommand(state)
- if (plug) {
- plug.closeBracket(ch)
- setState(state, beginParams)
- } else {
- return 'error'
- }
- return 'bracket'
- } else if (ch == '{' || ch == '[') {
- plug = plugins['DEFAULT']
- plug = new plug()
- pushCommand(state, plug)
- return 'bracket'
- } else if (/\d/.test(ch)) {
- source.eatWhile(/[\w.%]/)
- return 'atom'
- } else {
- source.eatWhile(/[\w\-_]/)
- plug = getMostPowerful(state)
- if (plug.name == 'begin') {
- plug.argument = source.current()
- }
- return plug.styleIdentifier()
- }
- }
- function inMathMode(source, state, endModeSeq) {
- if (source.eatSpace()) {
- return null
- }
- if (endModeSeq && source.match(endModeSeq)) {
- setState(state, normal)
- return 'keyword'
- }
- if (source.match(/^\\[a-zA-Z@]+/)) {
- return 'tag'
- }
- if (source.match(/^[a-zA-Z]+/)) {
- return 'variable-2'
- }
- // escape characters
- if (source.match(/^\\[$&%#{}_]/)) {
- return 'tag'
- }
- // white space control characters
- if (source.match(/^\\[,;!\/]/)) {
- return 'tag'
- }
- // special math-mode characters
- if (source.match(/^[\^_&]/)) {
- return 'tag'
- }
- // non-special characters
- if (source.match(/^[+\-<>|=,\/@!*:;'"`~#?]/)) {
- return null
- }
- if (source.match(/^(\d+\.\d*|\d*\.\d+|\d+)/)) {
- return 'number'
- }
- var ch = source.next()
- if (ch == '{' || ch == '}' || ch == '[' || ch == ']' || ch == '(' || ch == ')') {
- return 'bracket'
- }
- if (ch == '%') {
- source.skipToEnd()
- return 'comment'
- }
- return 'error'
- }
- function beginParams(source, state) {
- var ch = source.peek(),
- lastPlug
- if (ch == '{' || ch == '[') {
- lastPlug = peekCommand(state)
- lastPlug.openBracket(ch)
- source.eat(ch)
- setState(state, normal)
- return 'bracket'
- }
- if (/[ \t\r]/.test(ch)) {
- source.eat(ch)
- return null
- }
- setState(state, normal)
- popCommand(state)
- return normal(source, state)
- }
- return {
- startState: function () {
- var f = parserConfig.inMathMode
- ? function (source, state) {
- return inMathMode(source, state)
- }
- : normal
- return {
- cmdState: [],
- f: f,
- }
- },
- copyState: function (s) {
- return {
- cmdState: s.cmdState.slice(),
- f: s.f,
- }
- },
- token: function (stream, state) {
- return state.f(stream, state)
- },
- blankLine: function (state) {
- state.f = normal
- state.cmdState.length = 0
- },
- lineComment: '%',
- }
- })
- CodeMirror.defineMIME('text/x-stex', 'stex')
- CodeMirror.defineMIME('text/x-latex', 'stex')
- })
|