diff options
Diffstat (limited to 'imports/codemirror/mode/xmlpure')
-rw-r--r-- | imports/codemirror/mode/xmlpure/index.html | 58 | ||||
-rw-r--r-- | imports/codemirror/mode/xmlpure/xmlpure.js | 490 |
2 files changed, 0 insertions, 548 deletions
diff --git a/imports/codemirror/mode/xmlpure/index.html b/imports/codemirror/mode/xmlpure/index.html deleted file mode 100644 index 0fdac7e5..00000000 --- a/imports/codemirror/mode/xmlpure/index.html +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | <!doctype html> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>CodeMirror: Pure XML mode</title> | ||
5 | <link rel="stylesheet" href="../../lib/codemirror.css"> | ||
6 | <script src="../../lib/codemirror.js"></script> | ||
7 | <script src="xmlpure.js"></script> | ||
8 | <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style> | ||
9 | <link rel="stylesheet" href="../../doc/docs.css"> | ||
10 | </head> | ||
11 | <body> | ||
12 | <h1>CodeMirror: XML mode</h1> | ||
13 | <form><textarea id="code" name="code"> | ||
14 | <?xml version="1.0" encoding="UTF-8" standalone="no" ?> | ||
15 | |||
16 | <!-- This is the pure XML mode, | ||
17 | and we're inside a comment! --> | ||
18 | |||
19 | <catalog> | ||
20 | <books> | ||
21 | <book id="bk01"> | ||
22 | <title>Lord of Light</title> | ||
23 | <author>Roger Zelazny</author> | ||
24 | <year>1967</year> | ||
25 | <description><![CDATA[This is a great book, really!!]]></description> | ||
26 | </book> | ||
27 | </books> | ||
28 | </catalog> | ||
29 | </textarea></form> | ||
30 | <script> | ||
31 | var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: {name: "xmlpure"}}); | ||
32 | </script> | ||
33 | |||
34 | <p>This is my XML parser, based on the original:</p> | ||
35 | <ul> | ||
36 | <li>No html mode - this is pure xml</li> | ||
37 | <li>Illegal attributes and element names are errors</li> | ||
38 | <li>Attributes must have a value</li> | ||
39 | <li>XML declaration supported (e.g.: <b><?xml version="1.0" encoding="utf-8" standalone="no" ?></b>)</li> | ||
40 | <li>CDATA and comment blocks are not indented (except for their start-tag)</li> | ||
41 | <li>Better handling of errors per line with the state object - provides good infrastructure for extending it</li> | ||
42 | </ul> | ||
43 | |||
44 | <p>What's missing:</p> | ||
45 | <ul> | ||
46 | <li>Make sure only a single root element exists at the document level</li> | ||
47 | <li>Multi-line attributes should NOT indent</li> | ||
48 | <li>Start tags are not painted red when they have no matching end tags (is this really wrong?)</li> | ||
49 | </ul> | ||
50 | |||
51 | <p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/xml</code>.</p> | ||
52 | |||
53 | <p><b>@author</b>: Dror BG (<i>deebug.dev[at]gmail.com</i>)<br/> | ||
54 | <p><b>@date</b>: August, 2011<br/> | ||
55 | <p><b>@github</b>: <a href='https://github.com/deebugger/CodeMirror2' target='blank'>https://github.com/deebugger/CodeMirror2</a></p> | ||
56 | |||
57 | </body> | ||
58 | </html> | ||
diff --git a/imports/codemirror/mode/xmlpure/xmlpure.js b/imports/codemirror/mode/xmlpure/xmlpure.js deleted file mode 100644 index 18d710cf..00000000 --- a/imports/codemirror/mode/xmlpure/xmlpure.js +++ /dev/null | |||
@@ -1,490 +0,0 @@ | |||
1 | /** | ||
2 | * xmlpure.js | ||
3 | * | ||
4 | * Building upon and improving the CodeMirror 2 XML parser | ||
5 | * @author: Dror BG (deebug.dev@gmail.com) | ||
6 | * @date: August, 2011 | ||
7 | */ | ||
8 | |||
9 | CodeMirror.defineMode("xmlpure", function(config, parserConfig) { | ||
10 | // constants | ||
11 | var STYLE_ERROR = "error"; | ||
12 | var STYLE_INSTRUCTION = "comment"; | ||
13 | var STYLE_COMMENT = "comment"; | ||
14 | var STYLE_ELEMENT_NAME = "tag"; | ||
15 | var STYLE_ATTRIBUTE = "attribute"; | ||
16 | var STYLE_WORD = "string"; | ||
17 | var STYLE_TEXT = "atom"; | ||
18 | var STYLE_ENTITIES = "string"; | ||
19 | |||
20 | var TAG_INSTRUCTION = "!instruction"; | ||
21 | var TAG_CDATA = "!cdata"; | ||
22 | var TAG_COMMENT = "!comment"; | ||
23 | var TAG_TEXT = "!text"; | ||
24 | |||
25 | var doNotIndent = { | ||
26 | "!cdata": true, | ||
27 | "!comment": true, | ||
28 | "!text": true, | ||
29 | "!instruction": true | ||
30 | }; | ||
31 | |||
32 | // options | ||
33 | var indentUnit = config.indentUnit; | ||
34 | |||
35 | /////////////////////////////////////////////////////////////////////////// | ||
36 | // helper functions | ||
37 | |||
38 | // chain a parser to another parser | ||
39 | function chain(stream, state, parser) { | ||
40 | state.tokenize = parser; | ||
41 | return parser(stream, state); | ||
42 | } | ||
43 | |||
44 | // parse a block (comment, CDATA or text) | ||
45 | function inBlock(style, terminator, nextTokenize) { | ||
46 | return function(stream, state) { | ||
47 | while (!stream.eol()) { | ||
48 | if (stream.match(terminator)) { | ||
49 | popContext(state); | ||
50 | state.tokenize = nextTokenize; | ||
51 | break; | ||
52 | } | ||
53 | stream.next(); | ||
54 | } | ||
55 | return style; | ||
56 | }; | ||
57 | } | ||
58 | |||
59 | // go down a level in the document | ||
60 | // (hint: look at who calls this function to know what the contexts are) | ||
61 | function pushContext(state, tagName) { | ||
62 | var noIndent = doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.doIndent); | ||
63 | var newContext = { | ||
64 | tagName: tagName, | ||
65 | prev: state.context, | ||
66 | indent: state.context ? state.context.indent + indentUnit : 0, | ||
67 | lineNumber: state.lineNumber, | ||
68 | indented: state.indented, | ||
69 | noIndent: noIndent | ||
70 | }; | ||
71 | state.context = newContext; | ||
72 | } | ||
73 | |||
74 | // go up a level in the document | ||
75 | function popContext(state) { | ||
76 | if (state.context) { | ||
77 | var oldContext = state.context; | ||
78 | state.context = oldContext.prev; | ||
79 | return oldContext; | ||
80 | } | ||
81 | |||
82 | // we shouldn't be here - it means we didn't have a context to pop | ||
83 | return null; | ||
84 | } | ||
85 | |||
86 | // return true if the current token is seperated from the tokens before it | ||
87 | // which means either this is the start of the line, or there is at least | ||
88 | // one space or tab character behind the token | ||
89 | // otherwise returns false | ||
90 | function isTokenSeparated(stream) { | ||
91 | return stream.sol() || | ||
92 | stream.string.charAt(stream.start - 1) == " " || | ||
93 | stream.string.charAt(stream.start - 1) == "\t"; | ||
94 | } | ||
95 | |||
96 | /////////////////////////////////////////////////////////////////////////// | ||
97 | // context: document | ||
98 | // | ||
99 | // an XML document can contain: | ||
100 | // - a single declaration (if defined, it must be the very first line) | ||
101 | // - exactly one root element | ||
102 | // @todo try to actually limit the number of root elements to 1 | ||
103 | // - zero or more comments | ||
104 | function parseDocument(stream, state) { | ||
105 | if(stream.eat("<")) { | ||
106 | if(stream.eat("?")) { | ||
107 | // processing instruction | ||
108 | pushContext(state, TAG_INSTRUCTION); | ||
109 | state.tokenize = parseProcessingInstructionStartTag; | ||
110 | return STYLE_INSTRUCTION; | ||
111 | } else if(stream.match("!--")) { | ||
112 | // new context: comment | ||
113 | pushContext(state, TAG_COMMENT); | ||
114 | return chain(stream, state, inBlock(STYLE_COMMENT, "-->", parseDocument)); | ||
115 | } else if(stream.eatSpace() || stream.eol() ) { | ||
116 | stream.skipToEnd(); | ||
117 | return STYLE_ERROR; | ||
118 | } else { | ||
119 | // element | ||
120 | state.tokenize = parseElementTagName; | ||
121 | return STYLE_ELEMENT_NAME; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | // error on line | ||
126 | stream.skipToEnd(); | ||
127 | return STYLE_ERROR; | ||
128 | } | ||
129 | |||
130 | /////////////////////////////////////////////////////////////////////////// | ||
131 | // context: XML element start-tag or end-tag | ||
132 | // | ||
133 | // - element start-tag can contain attributes | ||
134 | // - element start-tag may self-close (or start an element block if it doesn't) | ||
135 | // - element end-tag can contain only the tag name | ||
136 | function parseElementTagName(stream, state) { | ||
137 | // get the name of the tag | ||
138 | var startPos = stream.pos; | ||
139 | if(stream.match(/^[a-zA-Z_:][-a-zA-Z0-9_:.]*/)) { | ||
140 | // element start-tag | ||
141 | var tagName = stream.string.substring(startPos, stream.pos); | ||
142 | pushContext(state, tagName); | ||
143 | state.tokenize = parseElement; | ||
144 | return STYLE_ELEMENT_NAME; | ||
145 | } else if(stream.match(/^\/[a-zA-Z_:][-a-zA-Z0-9_:.]*( )*>/)) { | ||
146 | // element end-tag | ||
147 | var endTagName = stream.string.substring(startPos + 1, stream.pos - 1).trim(); | ||
148 | var oldContext = popContext(state); | ||
149 | state.tokenize = state.context == null ? parseDocument : parseElementBlock; | ||
150 | if(oldContext == null || endTagName != oldContext.tagName) { | ||
151 | // the start and end tag names should match - error | ||
152 | return STYLE_ERROR; | ||
153 | } | ||
154 | return STYLE_ELEMENT_NAME; | ||
155 | } else { | ||
156 | // no tag name - error | ||
157 | state.tokenize = state.context == null ? parseDocument : parseElementBlock; | ||
158 | stream.eatWhile(/[^>]/); | ||
159 | stream.eat(">"); | ||
160 | return STYLE_ERROR; | ||
161 | } | ||
162 | |||
163 | stream.skipToEnd(); | ||