667 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			667 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// CodeMirror, copyright (c) by Marijn Haverbeke and others
 | 
						|
// Distributed under an MIT license: http://codemirror.net/LICENSE
 | 
						|
 | 
						|
(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);
 | 
						|
  else // Plain browser env
 | 
						|
    mod(CodeMirror);
 | 
						|
})(function(CodeMirror) {
 | 
						|
"use strict";
 | 
						|
 | 
						|
CodeMirror.defineMode("prolog", function(cmConfig, parserConfig) {
 | 
						|
 | 
						|
  function chain(stream, state, f) {
 | 
						|
    state.tokenize = f;
 | 
						|
    return f(stream, state);
 | 
						|
  }
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	   CONFIG DATA		*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
  var config = { quasiQuotations: false,		/* {|Syntax||Quotation|} */
 | 
						|
	         dicts: false,			/* tag{k:v, ...} */
 | 
						|
		 unicodeEscape: true,		/* \uXXXX and \UXXXXXXXX */
 | 
						|
		 multiLineQuoted: true,		/* "...\n..." */
 | 
						|
		 groupedIntegers: false		/* 10 000 or 10_000 */
 | 
						|
	       };
 | 
						|
 | 
						|
  var quoteType = { '"': "string",
 | 
						|
		    "'": "qatom",
 | 
						|
		    "`": "bqstring"
 | 
						|
		  };
 | 
						|
 | 
						|
  var isSingleEscChar = /[abref\\'"nrtsv]/;
 | 
						|
  var isOctalDigit    = /[0-7]/;
 | 
						|
  var isHexDigit      = /[0-9a-fA-F]/;
 | 
						|
 | 
						|
  var isSymbolChar = /[-#$&*+./:<=>?@\\^~]/;	/* Prolog glueing symbols chars */
 | 
						|
  var isSoloChar   = /[[\]{}(),;|!]/;		/* Prolog solo chars */
 | 
						|
  var isNeck       = /^(:-|-->)$/;
 | 
						|
  var isControlOp  = /^(,|;|->|\*->|\\+|\|)$/;
 | 
						|
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	 CHARACTER ESCAPES	*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
  function readDigits(stream, re, count) {
 | 
						|
    if ( count > 0 ) {
 | 
						|
      while( count-- > 0 ) {
 | 
						|
	if ( !re.test(stream.next()) )
 | 
						|
	  return false;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      while ( re.test(stream.peek()) )
 | 
						|
	stream.next();
 | 
						|
    }
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  function readEsc(stream) {
 | 
						|
    var next = stream.next();
 | 
						|
    if ( isSingleEscChar.test(next) )
 | 
						|
      return true;
 | 
						|
    switch( next )
 | 
						|
    { case "u":
 | 
						|
	if ( config.unicodeEscape )
 | 
						|
	  return readDigits(stream, isHexDigit, 4); /* SWI */
 | 
						|
        return false;
 | 
						|
      case "U":
 | 
						|
	if ( config.unicodeEscape )
 | 
						|
	  return readDigits(stream, isHexDigit, 8); /* SWI */
 | 
						|
        return false;
 | 
						|
      case null: return true;			/* end of line */
 | 
						|
      case "c": stream.eatSpace(); return true;
 | 
						|
      case "x": return readDigits(stream, isHexDigit, 2);
 | 
						|
    }
 | 
						|
    if ( isOctalDigit.test(next) ) {
 | 
						|
      if ( !readDigits(stream, isOctalDigit, -1) )
 | 
						|
	return false;
 | 
						|
      if ( stream.peek() == "\\" )		/* SWI: optional closing \ */
 | 
						|
	stream.next();
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  function nextUntilUnescaped(stream, state, end) {
 | 
						|
    var next;
 | 
						|
    while ((next = stream.next()) != null) {
 | 
						|
      if ( next == end && end != stream.peek() )
 | 
						|
      { state.nesting.pop();
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
      if ( next == "\\" )
 | 
						|
      { if ( !readEsc(stream) )
 | 
						|
	  return false;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return config.multiLineQuoted;
 | 
						|
  }
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	CONTEXT NESTING		*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
  function nesting(state) {
 | 
						|
    return state.nesting.slice(-1)[0];
 | 
						|
  }
 | 
						|
 | 
						|
  /* Called on every non-comment token */
 | 
						|
  function setArg1(state) {
 | 
						|
    var nest = nesting(state);
 | 
						|
    if ( nest ) {
 | 
						|
      if ( nest.arg == 0 )		/* nested in a compound */
 | 
						|
	nest.arg = 1;
 | 
						|
      else if ( nest.type == "control" )
 | 
						|
	state.goalStart = false;
 | 
						|
    } else
 | 
						|
      state.goalStart = false;
 | 
						|
  }
 | 
						|
 | 
						|
  function setArgAlignment(state) {
 | 
						|
    var nest = nesting(state);
 | 
						|
    if ( nest && !nest.alignment && nest.arg != undefined ) {
 | 
						|
      if ( nest.arg == 0 )
 | 
						|
	nest.alignment = nest.leftCol ? nest.leftCol+4 : nest.column+4;
 | 
						|
      else
 | 
						|
	nest.alignment = nest.column+1;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function nextArg(state) {
 | 
						|
    var nest = nesting(state);
 | 
						|
    if ( nest ) {
 | 
						|
      if ( nest.arg )			/* nested in a compound */
 | 
						|
	nest.arg++;
 | 
						|
      else if ( nest.type == "control" )
 | 
						|
	state.goalStart = true;		/* FIXME: also needed for ; and -> */
 | 
						|
    } else
 | 
						|
      state.goalStart = true;
 | 
						|
  }
 | 
						|
 | 
						|
  function isControl(state) {		/* our terms are goals */
 | 
						|
    var nest = nesting(state);
 | 
						|
    if ( nest ) {
 | 
						|
      if ( nest.type == "control" ) {
 | 
						|
	return true;
 | 
						|
      }
 | 
						|
      return false;
 | 
						|
    } else
 | 
						|
      return state.inBody;
 | 
						|
  }
 | 
						|
 | 
						|
  // Used as scratch variables to communicate multiple values without
 | 
						|
  // consing up tons of objects.
 | 
						|
  var type, content;
 | 
						|
  function ret(tp, style, cont) {
 | 
						|
    type = tp; content = cont;
 | 
						|
    return style;
 | 
						|
  }
 | 
						|
 | 
						|
  function peekSpace(stream) {		/* TBD: handle block comment as space */
 | 
						|
    if ( stream.eol() ||
 | 
						|
	 /[\s%]/.test(stream.peek()) )
 | 
						|
      return true;
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	   SUB TOKENISERS	*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
  function plTokenBase(stream, state) {
 | 
						|
    var ch = stream.next();
 | 
						|
 | 
						|
    if ( ch == "(" ) {
 | 
						|
      if ( state.lastType == "functor" ) {
 | 
						|
	state.nesting.push({ functor: state.functorName,
 | 
						|
			     column: stream.column(),
 | 
						|
			     leftCol: state.functorColumn,
 | 
						|
			     arg: 0
 | 
						|
			   });
 | 
						|
	delete state.functorName;
 | 
						|
	delete state.functorColumn;
 | 
						|
      } else {
 | 
						|
	state.nesting.push({ type: "control",
 | 
						|
			     closeColumn: stream.column(),
 | 
						|
			     alignment: stream.column()+4
 | 
						|
			   });
 | 
						|
      }
 | 
						|
      return ret("solo", null, "(");
 | 
						|
    }
 | 
						|
 | 
						|
    if ( ch == "{" && state.lastType == "tag" ) {
 | 
						|
      state.nesting.push({ tag: state.tagName,
 | 
						|
			   column: stream.column(),
 | 
						|
			   leftCol: state.tagColumn,
 | 
						|
			   arg: 0
 | 
						|
			 });
 | 
						|
      delete state.tagName;
 | 
						|
      delete state.tagColumn;
 | 
						|
      return ret("dict_open", null);
 | 
						|
    }
 | 
						|
 | 
						|
    if ( ch == "/" && stream.eat("*") )
 | 
						|
      return chain(stream, state, plTokenComment);
 | 
						|
 | 
						|
    if ( ch == "%" ) {
 | 
						|
      stream.skipToEnd();
 | 
						|
      return ret("comment", "comment");
 | 
						|
    }
 | 
						|
 | 
						|
    setArg1(state);
 | 
						|
 | 
						|
    if ( isSoloChar.test(ch) ) {
 | 
						|
      switch ( ch )
 | 
						|
      { case ")":
 | 
						|
	  state.nesting.pop();
 | 
						|
	  break;
 | 
						|
	case "]":
 | 
						|
	  state.nesting.pop();
 | 
						|
	  return ret("list_close", null);
 | 
						|
	case "}":
 | 
						|
	{ var nest = nesting(state);
 | 
						|
	  var type = (nest && nest.tag) ? "dict_close" : "brace_term_close";
 | 
						|
 | 
						|
	  state.nesting.pop();
 | 
						|
	  return ret(type, null);
 | 
						|
	}
 | 
						|
	case ",":
 | 
						|
	  if ( stream.eol() )
 | 
						|
	    state.commaAtEOL = true;
 | 
						|
	  nextArg(state);
 | 
						|
          /*FALLTHROUGH*/
 | 
						|
	case ";":
 | 
						|
	  if ( isControl(state) )
 | 
						|
	    state.goalStart = true;
 | 
						|
	  break;
 | 
						|
	case "[":
 | 
						|
	  state.nesting.push({ type: "list",
 | 
						|
			       closeColumn: stream.column(),
 | 
						|
			       alignment: stream.column()+2
 | 
						|
			     });
 | 
						|
	  return ret("list_open", null);
 | 
						|
	  break;
 | 
						|
	case "{":
 | 
						|
	  if ( config.quasiQuotations && stream.eat("|") ) {
 | 
						|
	    state.nesting.push({ type: "quasi-quotation",
 | 
						|
			         alignment: stream.column()+1
 | 
						|
			       });
 | 
						|
	    return ret("qq_open", "qq_open");
 | 
						|
	  } else {
 | 
						|
	    state.nesting.push({ type: "curly",
 | 
						|
			         closeColumn: stream.column(),
 | 
						|
				 alignment: stream.column()+2
 | 
						|
			       });
 | 
						|
	    return ret("brace_term_open", null);
 | 
						|
	  }
 | 
						|
	  break;
 | 
						|
	case "|":
 | 
						|
	  if ( config.quasiQuotations ) {
 | 
						|
	    if ( stream.eat("|") ) {
 | 
						|
	      state.tokenize = plTokenQuasiQuotation;
 | 
						|
	      return ret("qq_sep", "qq_sep");
 | 
						|
	    } else if ( stream.eat("}") ) {
 | 
						|
	      state.nesting.pop();
 | 
						|
	      return ret("qq_close", "qq_close");
 | 
						|
	    }
 | 
						|
	  }
 | 
						|
	  if ( isControl(state) )
 | 
						|
	    state.goalStart = true;
 | 
						|
	  break;
 | 
						|
      }
 | 
						|
      return ret("solo", null, ch);
 | 
						|
    }
 | 
						|
 | 
						|
    if (ch == '"' || ch == "'" || ch == "`")
 | 
						|
    { state.nesting.push({ type: "quoted",
 | 
						|
			   alignment: stream.column()+1
 | 
						|
			 });
 | 
						|
      return chain(stream, state, plTokenString(ch));
 | 
						|
    }
 | 
						|
 | 
						|
    if ( ch == "0" ) {
 | 
						|
      if ( stream.eat(/x/i)) {
 | 
						|
	stream.eatWhile(/[\da-f]/i);
 | 
						|
	return ret("number", "number");
 | 
						|
      }
 | 
						|
      if ( stream.eat(/o/i)) {
 | 
						|
	stream.eatWhile(/[0-7]/i);
 | 
						|
	return ret("number", "number");
 | 
						|
      }
 | 
						|
      if ( stream.eat(/'/) ) {			/* 0' */
 | 
						|
	var next = stream.next();
 | 
						|
	if ( next == "\\" ) {
 | 
						|
	  if ( !readEsc(stream) )
 | 
						|
	    return ret("error", "error");
 | 
						|
	}
 | 
						|
	return ret("code", "code");
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if ( /\d/.test(ch) || /[+-]/.test(ch) && stream.eat(/\d/)) {
 | 
						|
      if ( config.groupedIntegers )
 | 
						|
	stream.match(/^\d*((_|\s+)\d+)*(?:\.\d+)?(?:[eE][+\-]?\d+)?/);
 | 
						|
      else
 | 
						|
	stream.match(/^\d*(?:\.\d+)?(?:[eE][+\-]?\d+)?/);
 | 
						|
      return ret(ch == "-" ? "neg-number" :
 | 
						|
		 ch == "+" ? "pos-number" :
 | 
						|
		 "number");
 | 
						|
    }
 | 
						|
 | 
						|
    if ( isSymbolChar.test(ch) ) {
 | 
						|
      stream.eatWhile(isSymbolChar);
 | 
						|
      var atom = stream.current();
 | 
						|
      if ( atom == "." && peekSpace(stream) ) {
 | 
						|
	if ( nesting(state) ) {
 | 
						|
	  return ret("fullstop", "error", atom);
 | 
						|
	} else {
 | 
						|
	} return ret("fullstop", "fullstop", atom);
 | 
						|
      } else if ( isNeck.test(atom) ) {
 | 
						|
	return ret("neck", "neck", atom);
 | 
						|
      } else if ( isControl(state) && isControlOp.test(atom) ) {
 | 
						|
	state.goalStart = true;
 | 
						|
	return ret("symbol", "operator", atom);
 | 
						|
      } else
 | 
						|
	return ret("symbol", "operator", atom);
 | 
						|
    }
 | 
						|
 | 
						|
    stream.eatWhile(/[\w_]/);
 | 
						|
    var word = stream.current();
 | 
						|
    if ( stream.peek() == "{" && config.dicts ) {
 | 
						|
      state.tagName = word;			/* tmp state extension */
 | 
						|
      state.tagColumn = stream.column();
 | 
						|
      return ret("tag", "tag", word);
 | 
						|
    } else if ( ch == "_" ) {
 | 
						|
      if ( word.length == 1 ) {
 | 
						|
	return ret("var", "anon", word);
 | 
						|
      } else {
 | 
						|
	var sec = word.charAt(1);
 | 
						|
	if ( sec == sec.toUpperCase() )
 | 
						|
	  return ret("var", "var-2", word);
 | 
						|
      }
 | 
						|
      return ret("var", "var", word);
 | 
						|
    } else if ( ch == ch.toUpperCase() ) {
 | 
						|
      return ret("var", "var", word);
 | 
						|
    } else if ( stream.peek() == "(" ) {
 | 
						|
      state.functorName = word;			/* tmp state extension */
 | 
						|
      state.functorColumn = stream.column();
 | 
						|
      return ret("functor", "functor", word);
 | 
						|
    } else
 | 
						|
      return ret("atom", "atom", word);
 | 
						|
  }
 | 
						|
 | 
						|
  function plTokenString(quote) {
 | 
						|
    return function(stream, state) {
 | 
						|
      if (!nextUntilUnescaped(stream, state, quote)) {
 | 
						|
        state.tokenize = plTokenBase;
 | 
						|
	if ( stream.peek() == "(" ) {		/* 'quoted functor'() */
 | 
						|
	  var word = stream.current();
 | 
						|
	  state.functorName = word;		/* tmp state extension */
 | 
						|
	  return ret("functor", "functor", word);
 | 
						|
	}
 | 
						|
	if ( stream.peek() == "{" && config.dicts ) { /* 'quoted tag'{} */
 | 
						|
	  var word = stream.current();
 | 
						|
	  state.tagName = word;			/* tmp state extension */
 | 
						|
	  return ret("tag", "tag", word);
 | 
						|
	}
 | 
						|
      }
 | 
						|
      return ret(quoteType[quote], quoteType[quote]);
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  function plTokenQuasiQuotation(stream, state) {
 | 
						|
    var maybeEnd = false, ch;
 | 
						|
    while (ch = stream.next()) {
 | 
						|
      if (ch == "}" && maybeEnd) {
 | 
						|
        state.tokenize = plTokenBase;
 | 
						|
	stream.backUp(2);
 | 
						|
	break;
 | 
						|
      }
 | 
						|
      maybeEnd = (ch == "|");
 | 
						|
    }
 | 
						|
    return ret("qq_content", "qq_content");
 | 
						|
  }
 | 
						|
 | 
						|
  function plTokenComment(stream, state) {
 | 
						|
    var maybeEnd = false, ch;
 | 
						|
    while (ch = stream.next()) {
 | 
						|
      if (ch == "/" && maybeEnd) {
 | 
						|
        state.tokenize = plTokenBase;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      maybeEnd = (ch == "*");
 | 
						|
    }
 | 
						|
    return ret("comment", "comment");
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  		 /*******************************
 | 
						|
  		 *	    ACTIVE KEYS		*
 | 
						|
  		 *******************************/
 | 
						|
 | 
						|
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
						|
  Support if-then-else layout like this:
 | 
						|
 | 
						|
  goal :-
 | 
						|
      (	Condition
 | 
						|
      ->  IfTrue
 | 
						|
      ;   IfFalse
 | 
						|
      ).
 | 
						|
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 | 
						|
 | 
						|
 | 
						|
    CodeMirror.commands.prologStartIfThenElse = function(cm) {
 | 
						|
      var start = cm.getCursor("start");
 | 
						|
      var token = cm.getTokenAt(start, true);
 | 
						|
 | 
						|
      if ( token.state.goalStart == true )
 | 
						|
      { cm.replaceSelection("(   ", "end");
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      return CodeMirror.Pass;
 | 
						|
    }
 | 
						|
 | 
						|
    CodeMirror.commands.prologStartThen = function(cm) {
 | 
						|
      var start = cm.getCursor("start");
 | 
						|
      var token = cm.getTokenAt(start, true);
 | 
						|
 | 
						|
      /* FIXME: These functions are copied from prolog.js.  How
 | 
						|
         can we reuse these?
 | 
						|
      */
 | 
						|
      function nesting(state) {
 | 
						|
        var len = state.nesting.length;
 | 
						|
        if ( len > 0 )
 | 
						|
  	return state.nesting[len-1];
 | 
						|
        return null;
 | 
						|
      }
 | 
						|
 | 
						|
      function isControl(state) {		/* our terms are goals */
 | 
						|
        var nest = nesting(state);
 | 
						|
        if ( nest ) {
 | 
						|
  	if ( nest.type == "control" ) {
 | 
						|
  	  return true;
 | 
						|
  	}
 | 
						|
  	return false;
 | 
						|
        } else
 | 
						|
  	return state.inBody;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( start.ch == token.end &&
 | 
						|
  	 token.type == "operator" &&
 | 
						|
  	 token.string == "-" &&
 | 
						|
  	 isControl(token.state) )
 | 
						|
      { cm.replaceSelection(">  ", "end");
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      return CodeMirror.Pass;
 | 
						|
    }
 | 
						|
 | 
						|
    CodeMirror.commands.prologStartElse = function(cm) {
 | 
						|
      var start = cm.getCursor("start");
 | 
						|
      var token = cm.getTokenAt(start, true);
 | 
						|
 | 
						|
      if ( token.start == 0 && start.ch == token.end &&
 | 
						|
  	 !/\S/.test(token.string) )
 | 
						|
      { cm.replaceSelection(";   ", "end");
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      return CodeMirror.Pass;
 | 
						|
    }
 | 
						|
 | 
						|
    CodeMirror.defineOption("prologKeys", null, function(cm, val, prev) {
 | 
						|
      if (prev && prev != CodeMirror.Init)
 | 
						|
        cm.removeKeyMap("prolog");
 | 
						|
      if ( val ) {
 | 
						|
        var map = { name:     "prolog",
 | 
						|
  		  "'('":    "prologStartIfThenElse",
 | 
						|
  		  "'>'":    "prologStartThen",
 | 
						|
  		  "';'":    "prologStartElse",
 | 
						|
  		  "Ctrl-L": "refreshHighlight"
 | 
						|
  		};
 | 
						|
        cm.addKeyMap(map);
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
  });
 | 
						|
  //Default (SWI-)Prolog operator table.   To be used later to enhance the
 | 
						|
  //offline experience.
 | 
						|
 | 
						|
    var ops = { "-->":   { p:1200, t:"xfx" },
 | 
						|
  	      ":-":    [ { p:1200, t:"xfx" },
 | 
						|
  			 { p:1200, t:"fx" }
 | 
						|
  		       ],
 | 
						|
  	      "?-":    { p:1200, t:"fx" },
 | 
						|
 | 
						|
  	      "dynamic":            { p:1150, t:"fx" },
 | 
						|
  	      "discontiguous":      { p:1150, t:"fx" },
 | 
						|
  	      "initialization":     { p:1150, t:"fx" },
 | 
						|
  	      "meta_predicate":     { p:1150, t:"fx" },
 | 
						|
  	      "module_transparent": { p:1150, t:"fx" },
 | 
						|
  	      "multifile":          { p:1150, t:"fx" },
 | 
						|
  	      "thread_local":       { p:1150, t:"fx" },
 | 
						|
  	      "volatile":           { p:1150, t:"fx" },
 | 
						|
 | 
						|
  	      ";":    { p:1100, t:"xfy" },
 | 
						|
  	      "|":    { p:1100, t:"xfy" },
 | 
						|
 | 
						|
  	      "->":   { p:1050, t:"xfy" },
 | 
						|
  	      "*->":  { p:1050, t:"xfy" },
 | 
						|
 | 
						|
  	      ",":    { p:1000, t:"xfy" },
 | 
						|
 | 
						|
  	      "\\+":  { p:900,  t:"fy" },
 | 
						|
 | 
						|
  	      "~":    { p:900,  t:"fx" },
 | 
						|
 | 
						|
  	      "<":    { p:700,  t:"xfx" },
 | 
						|
  	      "=":    { p:700,  t:"xfx" },
 | 
						|
  	      "=..":  { p:700,  t:"xfx" },
 | 
						|
  	      "=@=":  { p:700,  t:"xfx" },
 | 
						|
  	      "=:=":  { p:700,  t:"xfx" },
 | 
						|
  	      "=<":   { p:700,  t:"xfx" },
 | 
						|
  	      "==":   { p:700,  t:"xfx" },
 | 
						|
  	      "=\\=": { p:700,  t:"xfx" },
 | 
						|
  	      ">":    { p:700,  t:"xfx" },
 | 
						|
  	      ">=":   { p:700,  t:"xfx" },
 | 
						|
  	      "@<":   { p:700,  t:"xfx" },
 | 
						|
  	      "@=<":  { p:700,  t:"xfx" },
 | 
						|
  	      "@>":   { p:700,  t:"xfx" },
 | 
						|
  	      "@>=":  { p:700,  t:"xfx" },
 | 
						|
  	      "\\=":  { p:700,  t:"xfx" },
 | 
						|
  	      "\\==": { p:700,  t:"xfx" },
 | 
						|
  	      "is":   { p:700,  t:"xfx" },
 | 
						|
 | 
						|
  	      ":":    { p:600,  t:"xfy" },
 | 
						|
 | 
						|
                "+":    [ { p:500,  t:"yfx" },
 | 
						|
  			{ p:200,  t:"fy" }
 | 
						|
  		      ],
 | 
						|
                "-":    [ { p:500,  t:"yfx" },
 | 
						|
  			{ p:200,  t:"fy" }
 | 
						|
  		      ],
 | 
						|
                "/\\":  { p:500,  t:"yfx" },
 | 
						|
                "\\/":  { p:500,  t:"yfx" },
 | 
						|
                "xor":  { p:500,  t:"yfx" },
 | 
						|
 | 
						|
                "?":    { p:500,  t:"fx" },
 | 
						|
 | 
						|
                "*":    { p:400,  t:"yfx" },
 | 
						|
                "/":    { p:400,  t:"yfx" },
 | 
						|
                "//":   { p:400,  t:"yfx" },
 | 
						|
                "rdiv": { p:400,  t:"yfx" },
 | 
						|
                "<<":   { p:400,  t:"yfx" },
 | 
						|
                ">>":   { p:400,  t:"yfx" },
 | 
						|
                "mod":  { p:400,  t:"yfx" },
 | 
						|
                "rem":  { p:400,  t:"yfx" },
 | 
						|
 | 
						|
                "**":   { p:200,  t:"xfx" },
 | 
						|
                "^":    { p:200,  t:"xfy" },
 | 
						|
 | 
						|
                "\\":   { p:200,  t:"fy" }
 | 
						|
  	    };
 | 
						|
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	   RETURN OBJECT	*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
  return {
 | 
						|
    startState: function() {
 | 
						|
      return {
 | 
						|
        tokenize: plTokenBase,
 | 
						|
	inBody: false,
 | 
						|
	goalStart: false,
 | 
						|
	lastType: null,
 | 
						|
	nesting: new Array(),		/* ([{}]) nesting FIXME: copy this */
 | 
						|
	curTerm: null,			/* term index in metainfo */
 | 
						|
	curToken: null			/* token in term */
 | 
						|
      };
 | 
						|
    },
 | 
						|
 | 
						|
    token: function(stream, state) {
 | 
						|
      var nest;
 | 
						|
 | 
						|
      if ( state.curTerm == null && parserConfig.metainfo ) {
 | 
						|
	state.curTerm = 0;
 | 
						|
	state.curToken = 0;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( stream.sol() )
 | 
						|
	delete state.commaAtEOL;
 | 
						|
 | 
						|
      if ( state.tokenize == plTokenBase && stream.eatSpace() ) {
 | 
						|
	if ( stream.eol() )
 | 
						|
	  setArgAlignment(state);
 | 
						|
	return null;
 | 
						|
      }
 | 
						|
 | 
						|
      var style = state.tokenize(stream, state);
 | 
						|
 | 
						|
      if ( stream.eol() )
 | 
						|
	setArgAlignment(state);
 | 
						|
 | 
						|
      if ( type == "neck" ) {
 | 
						|
	state.inBody = true;
 | 
						|
	state.goalStart = true;
 | 
						|
      } else if ( type == "fullstop" ) {
 | 
						|
	state.inBody = false;
 | 
						|
	state.goalStart = false;
 | 
						|
      }
 | 
						|
 | 
						|
      state.lastType = type;
 | 
						|
 | 
						|
      if ( typeof(parserConfig.enrich) == "function" )
 | 
						|
	style = parserConfig.enrich(stream, state, type, content, style);
 | 
						|
 | 
						|
      return style;
 | 
						|
    },
 | 
						|
 | 
						|
    indent: function(state, textAfter) {
 | 
						|
      if (state.tokenize == plTokenComment) return CodeMirror.Pass;
 | 
						|
 | 
						|
      var nest;
 | 
						|
      if ( (nest=nesting(state)) ) {
 | 
						|
	if ( nest.closeColumn && !state.commaAtEOL )
 | 
						|
	  return nest.closeColumn;
 | 
						|
	return nest.alignment;
 | 
						|
      }
 | 
						|
      if ( !state.inBody )
 | 
						|
	return 0;
 | 
						|
 | 
						|
      return 4;
 | 
						|
    },
 | 
						|
 | 
						|
    theme: "prolog",
 | 
						|
 | 
						|
    blockCommentStart: "/*",		/* continuecomment.js support */
 | 
						|
    blockCommentEnd: "*/",
 | 
						|
    blockCommentContinue: " * ",
 | 
						|
    lineComment: "%",
 | 
						|
  };
 | 
						|
});
 | 
						|
 | 
						|
CodeMirror.defineMIME("text/x-prolog", "prolog");
 | 
						|
});
 | 
						|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
 | 
						|
// Distributed under an MIT license: http://codemirror.net/LICENSE
 | 
						|
 | 
						|
(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);
 | 
						|
  else // Plain browser env
 | 
						|
    mod(CodeMirror);
 | 
						|
})(function(CodeMirror) {
 | 
						|
"use strict";
 |