File: parsehtmlmixed.js

package info (click to toggle)
librdf-endpoint-perl 0.11-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 592 kB
  • sloc: javascript: 3,887; perl: 2,256; sh: 35; makefile: 8
file content (93 lines) | stat: -rw-r--r-- 2,727 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
var HTMLMixedParser = Editor.Parser = (function() {

  // tags that trigger seperate parsers
  var triggers = {
    "script": "JSParser",
    "style":  "CSSParser"
  };

  function checkDependencies() {
    var parsers = ['XMLParser'];
    for (var p in triggers) parsers.push(triggers[p]);
    for (var i in parsers) {
      if (!window[parsers[i]]) throw new Error(parsers[i] + " parser must be loaded for HTML mixed mode to work.");
    }
    XMLParser.configure({useHTMLKludges: true});
  }

  function parseMixed(stream) {
    checkDependencies();
    var htmlParser = XMLParser.make(stream), localParser = null, inTag = false;
    var iter = {next: top, copy: copy};

    function top() {
      var token = htmlParser.next();
      if (token.content == "<")
        inTag = true;
      else if (token.style == "xml-tagname" && inTag === true)
        inTag = token.content.toLowerCase();
      else if (token.content == ">") {
        if (triggers[inTag]) {
          var parser = window[triggers[inTag]];
          iter.next = local(parser, "</" + inTag);
        }
        inTag = false;
      }
      return token;
    }
    function local(parser, tag) {
      var baseIndent = htmlParser.indentation();
      localParser = parser.make(stream, baseIndent + indentUnit);
      return function() {
        if (stream.lookAhead(tag, false, false, true)) {
          localParser = null;
          iter.next = top;
          return top();
        }

        var token = localParser.next();
        var lt = token.value.lastIndexOf("<"), sz = Math.min(token.value.length - lt, tag.length);
        if (lt != -1 && token.value.slice(lt, lt + sz).toLowerCase() == tag.slice(0, sz) &&
            stream.lookAhead(tag.slice(sz), false, false, true)) {
          stream.push(token.value.slice(lt));
          token.value = token.value.slice(0, lt);
        }

        if (token.indentation) {
          var oldIndent = token.indentation;
          token.indentation = function(chars) {
            if (chars == "</")
              return baseIndent;
            else
              return oldIndent(chars);
          };
        }

        return token;
      };
    }

    function copy() {
      var _html = htmlParser.copy(), _local = localParser && localParser.copy(),
          _next = iter.next, _inTag = inTag;
      return function(_stream) {
        stream = _stream;
        htmlParser = _html(_stream);
        localParser = _local && _local(_stream);
        iter.next = _next;
        inTag = _inTag;
        return iter;
      };
    }
    return iter;
  }

  return {
    make: parseMixed,
    electricChars: "{}/:",
    configure: function(obj) {
      if (obj.triggers) triggers = obj.triggers;
    }
  };

})();