liquid_cms 0.2.1.1 → 0.2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +7 -0
- data/README.rdoc +15 -1
- data/TODO.rdoc +0 -2
- data/app/controllers/cms/assets_controller.rb +20 -6
- data/app/controllers/cms/components_controller.rb +11 -3
- data/app/controllers/cms/pages_controller.rb +15 -4
- data/app/helpers/cms/common_helper.rb +31 -31
- data/app/liquid/cms_paperclip_extension.rb +75 -3
- data/app/models/cms/asset.rb +1 -1
- data/app/models/cms/component.rb +3 -3
- data/app/views/cms/assets/_form.html.erb +1 -1
- data/app/views/cms/assets/update.js.rjs +1 -0
- data/app/views/cms/components/update.js.rjs +1 -0
- data/app/views/cms/pages/_form.html.erb +1 -1
- data/app/views/cms/pages/update.js.rjs +1 -0
- data/app/views/layouts/cms.html.erb +4 -3
- data/generators/liquid_cms/liquid_cms_generator.rb +1 -0
- data/generators/liquid_cms/templates/config/locales/cms/en.yml +4 -0
- data/generators/liquid_cms/templates/migration_rev2.rb +13 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/LICENSE +16 -20
- data/generators/liquid_cms/templates/public/cms/codemirror/lib/codemirror.css +68 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/lib/codemirror.js +2197 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/lib/overlay.js +51 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/lib/runmode.js +27 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/clike/clike.js +247 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/clike/index.html +102 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/clojure/clojure.js +207 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/clojure/index.html +85 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/coffeescript/LICENSE +22 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/coffeescript/coffeescript.js +325 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/coffeescript/index.html +722 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/css/css.js +124 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/css/index.html +56 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/diff/diff.css +3 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/diff/diff.js +13 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/diff/index.html +99 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/haskell/haskell.js +242 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/haskell/index.html +60 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/htmlmixed/htmlmixed.js +79 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/htmlmixed/index.html +52 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/javascript/index.html +78 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/javascript/javascript.js +352 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/jinja2/index.html +38 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/jinja2/jinja2.js +42 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/lua/index.html +72 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/lua/lua.js +140 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/markdown/index.html +340 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/markdown/markdown.css +10 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/markdown/markdown.js +230 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/ntriples/index.html +33 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/ntriples/ntriples.js +172 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/pascal/LICENSE +7 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/pascal/index.html +49 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/pascal/pascal.js +138 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/php/index.html +49 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/php/php.js +116 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/plsql/index.html +63 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/plsql/plsql.js +217 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/python/LICENSE.txt +21 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/python/index.html +123 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/python/python.js +320 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/r/LICENSE +24 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/r/index.html +74 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/r/r.js +141 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/rst/index.html +526 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/rst/rst.css +75 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/rst/rst.js +333 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/ruby/LICENSE +24 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/ruby/index.html +172 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/ruby/ruby.js +195 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/scheme/index.html +65 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/scheme/scheme.js +202 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/smalltalk/index.html +56 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/smalltalk/smalltalk.js +122 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/sparql/index.html +41 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/sparql/sparql.js +143 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/stex/index.html +96 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/stex/stex.js +167 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/velocity/index.html +103 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/velocity/velocity.js +146 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/xml/index.html +42 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/xml/xml.js +231 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/xmlpure/index.html +60 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/xmlpure/xmlpure.js +481 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/yaml/index.html +68 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/mode/yaml/yaml.js +95 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/theme/cobalt.css +17 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/theme/default.css +19 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/theme/eclipse.css +24 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/theme/elegant.css +9 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/theme/neat.css +8 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/theme/night.css +20 -0
- data/generators/liquid_cms/templates/public/cms/javascripts/cms.js +1 -1
- data/generators/liquid_cms/templates/public/cms/javascripts/codemirror_custom.js +96 -0
- data/generators/liquid_cms/templates/public/cms/stylesheets/codemirror_changes.css +26 -0
- data/generators/liquid_cms/templates/public/cms/stylesheets/liquid.css +7 -0
- data/generators/liquid_cms/templates/public/cms/stylesheets/simple_form.css +0 -8
- data/lib/liquid_cms/version.rb +1 -1
- data/liquid_cms.gemspec +0 -1
- data/test/functional/assets_controller_test.rb +35 -20
- data/test/functional/components_controller_test.rb +15 -5
- data/test/functional/pages_controller_test.rb +19 -6
- data/test/rails_app/config/environment.rb +1 -1
- data/test/rails_app/config/locales/cms/en.yml +19 -4
- data/test/rails_app/db/migrate/20110511161859_create_liquid_cms_upgrade_rev2.rb +13 -0
- data/test/unit/asset_test.rb +1 -1
- metadata +100 -58
- data/generators/liquid_cms/templates/public/cms/codemirror/css/csscolors.css +0 -55
- data/generators/liquid_cms/templates/public/cms/codemirror/css/docs.css +0 -158
- data/generators/liquid_cms/templates/public/cms/codemirror/css/font.js +0 -15
- data/generators/liquid_cms/templates/public/cms/codemirror/css/jscolors.css +0 -59
- data/generators/liquid_cms/templates/public/cms/codemirror/css/sparqlcolors.css +0 -43
- data/generators/liquid_cms/templates/public/cms/codemirror/css/xmlcolors.css +0 -55
- data/generators/liquid_cms/templates/public/cms/codemirror/js/codemirror.js +0 -582
- data/generators/liquid_cms/templates/public/cms/codemirror/js/editor.js +0 -1671
- data/generators/liquid_cms/templates/public/cms/codemirror/js/highlight.js +0 -68
- data/generators/liquid_cms/templates/public/cms/codemirror/js/mirrorframe.js +0 -81
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsecss.js +0 -161
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsedummy.js +0 -32
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsehtmlmixed.js +0 -93
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsejavascript.js +0 -359
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsesparql.js +0 -162
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsexml.js +0 -291
- data/generators/liquid_cms/templates/public/cms/codemirror/js/select.js +0 -699
- data/generators/liquid_cms/templates/public/cms/codemirror/js/stringstream.js +0 -159
- data/generators/liquid_cms/templates/public/cms/codemirror/js/tokenize.js +0 -57
- data/generators/liquid_cms/templates/public/cms/codemirror/js/tokenizejavascript.js +0 -174
- data/generators/liquid_cms/templates/public/cms/codemirror/js/undo.js +0 -413
- data/generators/liquid_cms/templates/public/cms/codemirror/js/unittests.js +0 -44
- data/generators/liquid_cms/templates/public/cms/codemirror/js/util.js +0 -133
@@ -0,0 +1,481 @@
|
|
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
|
+
|
19
|
+
var TAG_INSTRUCTION = "!instruction";
|
20
|
+
var TAG_CDATA = "!cdata";
|
21
|
+
var TAG_COMMENT = "!comment";
|
22
|
+
var TAG_TEXT = "!text";
|
23
|
+
|
24
|
+
var doNotIndent = {
|
25
|
+
"!cdata": true,
|
26
|
+
"!comment": true,
|
27
|
+
"!text": true,
|
28
|
+
"!instruction": true
|
29
|
+
};
|
30
|
+
|
31
|
+
// options
|
32
|
+
var indentUnit = config.indentUnit;
|
33
|
+
|
34
|
+
///////////////////////////////////////////////////////////////////////////
|
35
|
+
// helper functions
|
36
|
+
|
37
|
+
// chain a parser to another parser
|
38
|
+
function chain(stream, state, parser) {
|
39
|
+
state.tokenize = parser;
|
40
|
+
return parser(stream, state);
|
41
|
+
}
|
42
|
+
|
43
|
+
// parse a block (comment, CDATA or text)
|
44
|
+
function inBlock(style, terminator, nextTokenize) {
|
45
|
+
return function(stream, state) {
|
46
|
+
while (!stream.eol()) {
|
47
|
+
if (stream.match(terminator)) {
|
48
|
+
popContext(state);
|
49
|
+
state.tokenize = nextTokenize;
|
50
|
+
break;
|
51
|
+
}
|
52
|
+
stream.next();
|
53
|
+
}
|
54
|
+
return style;
|
55
|
+
};
|
56
|
+
}
|
57
|
+
|
58
|
+
// go down a level in the document
|
59
|
+
// (hint: look at who calls this function to know what the contexts are)
|
60
|
+
function pushContext(state, tagName) {
|
61
|
+
var noIndent = doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.doIndent);
|
62
|
+
var newContext = {
|
63
|
+
tagName: tagName,
|
64
|
+
prev: state.context,
|
65
|
+
indent: state.context ? state.context.indent + indentUnit : 0,
|
66
|
+
lineNumber: state.lineNumber,
|
67
|
+
indented: state.indented,
|
68
|
+
noIndent: noIndent
|
69
|
+
};
|
70
|
+
state.context = newContext;
|
71
|
+
}
|
72
|
+
|
73
|
+
// go up a level in the document
|
74
|
+
function popContext(state) {
|
75
|
+
if (state.context) {
|
76
|
+
var oldContext = state.context;
|
77
|
+
state.context = oldContext.prev;
|
78
|
+
return oldContext;
|
79
|
+
}
|
80
|
+
|
81
|
+
// we shouldn't be here - it means we didn't have a context to pop
|
82
|
+
return null;
|
83
|
+
}
|
84
|
+
|
85
|
+
// return true if the current token is seperated from the tokens before it
|
86
|
+
// which means either this is the start of the line, or there is at least
|
87
|
+
// one space or tab character behind the token
|
88
|
+
// otherwise returns false
|
89
|
+
function isTokenSeparated(stream) {
|
90
|
+
return stream.sol() ||
|
91
|
+
stream.string.charAt(stream.start - 1) == " " ||
|
92
|
+
stream.string.charAt(stream.start - 1) == "\t";
|
93
|
+
}
|
94
|
+
|
95
|
+
///////////////////////////////////////////////////////////////////////////
|
96
|
+
// context: document
|
97
|
+
//
|
98
|
+
// an XML document can contain:
|
99
|
+
// - a single declaration (if defined, it must be the very first line)
|
100
|
+
// - exactly one root element
|
101
|
+
// @todo try to actually limit the number of root elements to 1
|
102
|
+
// - zero or more comments
|
103
|
+
function parseDocument(stream, state) {
|
104
|
+
if(stream.eat("<")) {
|
105
|
+
if(stream.eat("?")) {
|
106
|
+
// processing instruction
|
107
|
+
pushContext(state, TAG_INSTRUCTION);
|
108
|
+
state.tokenize = parseProcessingInstructionStartTag;
|
109
|
+
return STYLE_INSTRUCTION;
|
110
|
+
} else if(stream.match("!--")) {
|
111
|
+
// new context: comment
|
112
|
+
pushContext(state, TAG_COMMENT);
|
113
|
+
return chain(stream, state, inBlock(STYLE_COMMENT, "-->", parseDocument));
|
114
|
+
} else if(stream.eatSpace() || stream.eol() ) {
|
115
|
+
stream.skipToEnd();
|
116
|
+
return STYLE_ERROR;
|
117
|
+
} else {
|
118
|
+
// element
|
119
|
+
state.tokenize = parseElementTagName;
|
120
|
+
return STYLE_ELEMENT_NAME;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
// error on line
|
125
|
+
stream.skipToEnd();
|
126
|
+
return STYLE_ERROR;
|
127
|
+
}
|
128
|
+
|
129
|
+
///////////////////////////////////////////////////////////////////////////
|
130
|
+
// context: XML element start-tag or end-tag
|
131
|
+
//
|
132
|
+
// - element start-tag can contain attributes
|
133
|
+
// - element start-tag may self-close (or start an element block if it doesn't)
|
134
|
+
// - element end-tag can contain only the tag name
|
135
|
+
function parseElementTagName(stream, state) {
|
136
|
+
// get the name of the tag
|
137
|
+
var startPos = stream.pos;
|
138
|
+
if(stream.match(/^[a-zA-Z_:][-a-zA-Z0-9_:.]*/)) {
|
139
|
+
// element start-tag
|
140
|
+
var tagName = stream.string.substring(startPos, stream.pos);
|
141
|
+
pushContext(state, tagName);
|
142
|
+
state.tokenize = parseElement;
|
143
|
+
return STYLE_ELEMENT_NAME;
|
144
|
+
} else if(stream.match(/^\/[a-zA-Z_:][-a-zA-Z0-9_:.]*( )*>/)) {
|
145
|
+
// element end-tag
|
146
|
+
var endTagName = stream.string.substring(startPos + 1, stream.pos - 1).trim();
|
147
|
+
var oldContext = popContext(state);
|
148
|
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
149
|
+
if(oldContext == null || endTagName != oldContext.tagName) {
|
150
|
+
// the start and end tag names should match - error
|
151
|
+
return STYLE_ERROR;
|
152
|
+
}
|
153
|
+
return STYLE_ELEMENT_NAME;
|
154
|
+
} else {
|
155
|
+
// no tag name - error
|
156
|
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
157
|
+
stream.eatWhile(/[^>]/);
|
158
|
+
stream.eat(">");
|
159
|
+
return STYLE_ERROR;
|
160
|
+
}
|
161
|
+
|
162
|
+
stream.skipToEnd();
|
163
|
+
return null;
|
164
|
+
}
|
165
|
+
|
166
|
+
function parseElement(stream, state) {
|
167
|
+
if(stream.match(/^\/>/)) {
|
168
|
+
// self-closing tag
|
169
|
+
popContext(state);
|
170
|
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
171
|
+
return STYLE_ELEMENT_NAME;
|
172
|
+
} else if(stream.eat(/^>/)) {
|
173
|
+
state.tokenize = parseElementBlock;
|
174
|
+
return STYLE_ELEMENT_NAME;
|
175
|
+
} else if(isTokenSeparated(stream) && stream.match(/^[a-zA-Z_:][-a-zA-Z0-9_:.]*( )*=/)) {
|
176
|
+
// attribute
|
177
|
+
state.tokenize = parseAttribute;
|
178
|
+
return STYLE_ATTRIBUTE;
|
179
|
+
}
|
180
|
+
|
181
|
+
// no other options - this is an error
|
182
|
+
state.tokenize = state.context == null ? parseDocument : parseDocument;
|
183
|
+
stream.eatWhile(/[^>]/);
|
184
|
+
stream.eat(">");
|
185
|
+
return STYLE_ERROR;
|
186
|
+
}
|
187
|
+
|
188
|
+
///////////////////////////////////////////////////////////////////////////
|
189
|
+
// context: attribute
|
190
|
+
//
|
191
|
+
// attribute values may contain everything, except:
|
192
|
+
// - the ending quote (with ' or ") - this marks the end of the value
|
193
|
+
// - the character "<" - should never appear
|
194
|
+
// - ampersand ("&") - unless it starts a reference: a string that ends with a semi-colon (";")
|
195
|
+
// ---> note: this parser is lax in what may be put into a reference string,
|
196
|
+
// ---> consult http://www.w3.org/TR/REC-xml/#NT-Reference if you want to make it tighter
|
197
|
+
function parseAttribute(stream, state) {
|
198
|
+
var quote = stream.next();
|
199
|
+
if(quote != "\"" && quote != "'") {
|
200
|
+
// attribute must be quoted
|
201
|
+
stream.skipToEnd();
|
202
|
+
state.tokenize = parseElement;
|
203
|
+
return STYLE_ERROR;
|
204
|
+
}
|
205
|
+
|
206
|
+
state.tokParams.quote = quote;
|
207
|
+
state.tokenize = parseAttributeValue;
|
208
|
+
return STYLE_WORD;
|
209
|
+
}
|
210
|
+
|
211
|
+
// @todo: find out whether this attribute value spans multiple lines,
|
212
|
+
// and if so, push a context for it in order not to indent it
|
213
|
+
// (or something of the sort..)
|
214
|
+
function parseAttributeValue(stream, state) {
|
215
|
+
var ch = "";
|
216
|
+
while(!stream.eol()) {
|
217
|
+
ch = stream.next();
|
218
|
+
if(ch == state.tokParams.quote) {
|
219
|
+
// end quote found
|
220
|
+
state.tokenize = parseElement;
|
221
|
+
return STYLE_WORD;
|
222
|
+
} else if(ch == "<") {
|
223
|
+
// can't have less-than signs in an attribute value, ever
|
224
|
+
stream.skipToEnd()
|
225
|
+
state.tokenize = parseElement;
|
226
|
+
return STYLE_ERROR;
|
227
|
+
} else if(ch == "&") {
|
228
|
+
// reference - look for a semi-colon, or return error if none found
|
229
|
+
ch = stream.next();
|
230
|
+
|
231
|
+
// make sure that semi-colon isn't right after the ampersand
|
232
|
+
if(ch == ';') {
|
233
|
+
stream.skipToEnd()
|
234
|
+
state.tokenize = parseElement;
|
235
|
+
return STYLE_ERROR;
|
236
|
+
}
|
237
|
+
|
238
|
+
// make sure no less-than characters slipped in
|
239
|
+
while(!stream.eol() && ch != ";") {
|
240
|
+
if(ch == "<") {
|
241
|
+
// can't have less-than signs in an attribute value, ever
|
242
|
+
stream.skipToEnd()
|
243
|
+
state.tokenize = parseElement;
|
244
|
+
return STYLE_ERROR;
|
245
|
+
}
|
246
|
+
ch = stream.next();
|
247
|
+
}
|
248
|
+
if(stream.eol() && ch != ";") {
|
249
|
+
// no ampersand found - error
|
250
|
+
stream.skipToEnd();
|
251
|
+
state.tokenize = parseElement;
|
252
|
+
return STYLE_ERROR;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
// attribute value continues to next line
|
258
|
+
return STYLE_WORD;
|
259
|
+
}
|
260
|
+
|
261
|
+
///////////////////////////////////////////////////////////////////////////
|
262
|
+
// context: element block
|
263
|
+
//
|
264
|
+
// a block can contain:
|
265
|
+
// - elements
|
266
|
+
// - text
|
267
|
+
// - CDATA sections
|
268
|
+
// - comments
|
269
|
+
function parseElementBlock(stream, state) {
|
270
|
+
if(stream.eat("<")) {
|
271
|
+
if(stream.match("?")) {
|
272
|
+
pushContext(state, TAG_INSTRUCTION);
|
273
|
+
state.tokenize = parseProcessingInstructionStartTag;
|
274
|
+
return STYLE_INSTRUCTION;
|
275
|
+
} else if(stream.match("!--")) {
|
276
|
+
// new context: comment
|
277
|
+
pushContext(state, TAG_COMMENT);
|
278
|
+
return chain(stream, state, inBlock(STYLE_COMMENT, "-->",
|
279
|
+
state.context == null ? parseDocument : parseElementBlock));
|
280
|
+
} else if(stream.match("![CDATA[")) {
|
281
|
+
// new context: CDATA section
|
282
|
+
pushContext(state, TAG_CDATA);
|
283
|
+
return chain(stream, state, inBlock(STYLE_TEXT, "]]>",
|
284
|
+
state.context == null ? parseDocument : parseElementBlock));
|
285
|
+
} else if(stream.eatSpace() || stream.eol() ) {
|
286
|
+
stream.skipToEnd();
|
287
|
+
return STYLE_ERROR;
|
288
|
+
} else {
|
289
|
+
// element
|
290
|
+
state.tokenize = parseElementTagName;
|
291
|
+
return STYLE_ELEMENT_NAME;
|
292
|
+
}
|
293
|
+
} else {
|
294
|
+
// new context: text
|
295
|
+
pushContext(state, TAG_TEXT);
|
296
|
+
state.tokenize = parseText;
|
297
|
+
return null;
|
298
|
+
}
|
299
|
+
|
300
|
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
301
|
+
stream.skipToEnd();
|
302
|
+
return null;
|
303
|
+
}
|
304
|
+
|
305
|
+
function parseText(stream, state) {
|
306
|
+
stream.eatWhile(/[^<]/);
|
307
|
+
if(!stream.eol()) {
|
308
|
+
// we cannot possibly be in the document context,
|
309
|
+
// just inside an element block
|
310
|
+
popContext(state);
|
311
|
+
state.tokenize = parseElementBlock;
|
312
|
+
}
|
313
|
+
return STYLE_TEXT;
|
314
|
+
}
|
315
|
+
|
316
|
+
///////////////////////////////////////////////////////////////////////////
|
317
|
+
// context: XML processing instructions
|
318
|
+
//
|
319
|
+
// XML processing instructions (PIs) allow documents to contain instructions for applications.
|
320
|
+
// PI format: <?name data?>
|
321
|
+
// - 'name' can be anything other than 'xml' (case-insensitive)
|
322
|
+
// - 'data' can be anything which doesn't contain '?>'
|
323
|
+
// XML declaration is a special PI (see XML declaration context below)
|
324
|
+
function parseProcessingInstructionStartTag(stream, state) {
|
325
|
+
if(stream.match("xml", true, true)) {
|
326
|
+
// xml declaration
|
327
|
+
if(state.lineNumber > 1 || stream.pos > 5) {
|
328
|
+
state.tokenize = parseDocument;
|
329
|
+
stream.skipToEnd();
|
330
|
+
return STYLE_ERROR;
|
331
|
+
} else {
|
332
|
+
state.tokenize = parseDeclarationVersion;
|
333
|
+
return STYLE_INSTRUCTION;
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
// regular processing instruction
|
338
|
+
if(isTokenSeparated(stream) || stream.match("?>")) {
|
339
|
+
// we have a space after the start-tag, or nothing but the end-tag
|
340
|
+
// either way - error!
|
341
|
+
state.tokenize = parseDocument;
|
342
|
+
stream.skipToEnd();
|
343
|
+
return STYLE_ERROR;
|
344
|
+
}
|
345
|
+
|
346
|
+
state.tokenize = parseProcessingInstructionBody;
|
347
|
+
return STYLE_INSTRUCTION;
|
348
|
+
}
|
349
|
+
|
350
|
+
function parseProcessingInstructionBody(stream, state) {
|
351
|
+
stream.eatWhile(/[^?]/);
|
352
|
+
if(stream.eat("?")) {
|
353
|
+
if(stream.eat(">")) {
|
354
|
+
popContext(state);
|
355
|
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
356
|
+
}
|
357
|
+
}
|
358
|
+
return STYLE_INSTRUCTION;
|
359
|
+
}
|
360
|
+
|
361
|
+
|
362
|
+
///////////////////////////////////////////////////////////////////////////
|
363
|
+
// context: XML declaration
|
364
|
+
//
|
365
|
+
// XML declaration is of the following format:
|
366
|
+
// <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
367
|
+
// - must start at the first character of the first line
|
368
|
+
// - may span multiple lines
|
369
|
+
// - must include 'version'
|
370
|
+
// - may include 'encoding' and 'standalone' (in that order after 'version')
|
371
|
+
// - attribute names must be lowercase
|
372
|
+
// - cannot contain anything else on the line
|
373
|
+
function parseDeclarationVersion(stream, state) {
|
374
|
+
state.tokenize = parseDeclarationEncoding;
|
375
|
+
|
376
|
+
if(isTokenSeparated(stream) && stream.match(/^version( )*=( )*"([a-zA-Z0-9_.:]|\-)+"/)) {
|
377
|
+
return STYLE_INSTRUCTION;
|
378
|
+
}
|
379
|
+
stream.skipToEnd();
|
380
|
+
return STYLE_ERROR;
|
381
|
+
}
|
382
|
+
|
383
|
+
function parseDeclarationEncoding(stream, state) {
|
384
|
+
state.tokenize = parseDeclarationStandalone;
|
385
|
+
|
386
|
+
if(isTokenSeparated(stream) && stream.match(/^encoding( )*=( )*"[A-Za-z]([A-Za-z0-9._]|\-)*"/)) {
|
387
|
+
return STYLE_INSTRUCTION;
|
388
|
+
}
|
389
|
+
return null;
|
390
|
+
}
|
391
|
+
|
392
|
+
function parseDeclarationStandalone(stream, state) {
|
393
|
+
state.tokenize = parseDeclarationEndTag;
|
394
|
+
|
395
|
+
if(isTokenSeparated(stream) && stream.match(/^standalone( )*=( )*"(yes|no)"/)) {
|
396
|
+
return STYLE_INSTRUCTION;
|
397
|
+
}
|
398
|
+
return null;
|
399
|
+
}
|
400
|
+
|
401
|
+
function parseDeclarationEndTag(stream, state) {
|
402
|
+
state.tokenize = parseDocument;
|
403
|
+
|
404
|
+
if(stream.match("?>") && stream.eol()) {
|
405
|
+
popContext(state);
|
406
|
+
return STYLE_INSTRUCTION;
|
407
|
+
}
|
408
|
+
stream.skipToEnd();
|
409
|
+
return STYLE_ERROR;
|
410
|
+
}
|
411
|
+
|
412
|
+
///////////////////////////////////////////////////////////////////////////
|
413
|
+
// returned object
|
414
|
+
return {
|
415
|
+
electricChars: "/",
|
416
|
+
|
417
|
+
startState: function() {
|
418
|
+
return {
|
419
|
+
tokenize: parseDocument,
|
420
|
+
tokParams: {},
|
421
|
+
lineNumber: 0,
|
422
|
+
lineError: false,
|
423
|
+
context: null,
|
424
|
+
indented: 0
|
425
|
+
};
|
426
|
+
},
|
427
|
+
|
428
|
+
token: function(stream, state) {
|
429
|
+
if(stream.sol()) {
|
430
|
+
// initialize a new line
|
431
|
+
state.lineNumber++;
|
432
|
+
state.lineError = false;
|
433
|
+
state.indented = stream.indentation();
|
434
|
+
}
|
435
|
+
|
436
|
+
// eat all (the spaces) you can
|
437
|
+
if(stream.eatSpace()) return null;
|
438
|
+
|
439
|
+
// run the current tokenize function, according to the state
|
440
|
+
var style = state.tokenize(stream, state);
|
441
|
+
|
442
|
+
// is there an error somewhere in the line?
|
443
|
+
state.lineError = (state.lineError || style == "error");
|
444
|
+
|
445
|
+
return style;
|
446
|
+
},
|
447
|
+
|
448
|
+
blankLine: function(state) {
|
449
|
+
// blank lines are lines too!
|
450
|
+
state.lineNumber++;
|
451
|
+
state.lineError = false;
|
452
|
+
},
|
453
|
+
|
454
|
+
indent: function(state, textAfter) {
|
455
|
+
if(state.context) {
|
456
|
+
if(state.context.noIndent == true) {
|
457
|
+
// do not indent - no return value at all
|
458
|
+
return;
|
459
|
+
}
|
460
|
+
if(textAfter.match(/^<\/.*/)) {
|
461
|
+
// eng-tag - indent back to last context
|
462
|
+
return state.context.indent;
|
463
|
+
}
|
464
|
+
// indent to last context + regular indent unit
|
465
|
+
return state.context.indent + indentUnit;
|
466
|
+
}
|
467
|
+
return 0;
|
468
|
+
},
|
469
|
+
|
470
|
+
compareStates: function(a, b) {
|
471
|
+
if (a.indented != b.indented) return false;
|
472
|
+
for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
|
473
|
+
if (!ca || !cb) return ca == cb;
|
474
|
+
if (ca.tagName != cb.tagName) return false;
|
475
|
+
}
|
476
|
+
}
|
477
|
+
};
|
478
|
+
});
|
479
|
+
|
480
|
+
CodeMirror.defineMIME("application/xml", "purexml");
|
481
|
+
CodeMirror.defineMIME("text/xml", "purexml");
|
@@ -0,0 +1,68 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>CodeMirror 2: YAML mode</title>
|
5
|
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
6
|
+
<script src="../../lib/codemirror.js"></script>
|
7
|
+
<script src="yaml.js"></script>
|
8
|
+
<link rel="stylesheet" href="../../theme/default.css">
|
9
|
+
<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }</style>
|
10
|
+
<link rel="stylesheet" href="../../css/docs.css">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<h1>CodeMirror 2: YAML mode</h1>
|
14
|
+
<form><textarea id="code" name="code">
|
15
|
+
--- # Favorite movies
|
16
|
+
- Casablanca
|
17
|
+
- North by Northwest
|
18
|
+
- The Man Who Wasn't There
|
19
|
+
--- # Shopping list
|
20
|
+
[milk, pumpkin pie, eggs, juice]
|
21
|
+
--- # Indented Blocks, common in YAML data files, use indentation and new lines to separate the key: value pairs
|
22
|
+
name: John Smith
|
23
|
+
age: 33
|
24
|
+
--- # Inline Blocks, common in YAML data streams, use commas to separate the key: value pairs between braces
|
25
|
+
{name: John Smith, age: 33}
|
26
|
+
---
|
27
|
+
receipt: Oz-Ware Purchase Invoice
|
28
|
+
date: 2007-08-06
|
29
|
+
customer:
|
30
|
+
given: Dorothy
|
31
|
+
family: Gale
|
32
|
+
|
33
|
+
items:
|
34
|
+
- part_no: A4786
|
35
|
+
descrip: Water Bucket (Filled)
|
36
|
+
price: 1.47
|
37
|
+
quantity: 4
|
38
|
+
|
39
|
+
- part_no: E1628
|
40
|
+
descrip: High Heeled "Ruby" Slippers
|
41
|
+
size: 8
|
42
|
+
price: 100.27
|
43
|
+
quantity: 1
|
44
|
+
|
45
|
+
bill-to: &id001
|
46
|
+
street: |
|
47
|
+
123 Tornado Alley
|
48
|
+
Suite 16
|
49
|
+
city: East Centerville
|
50
|
+
state: KS
|
51
|
+
|
52
|
+
ship-to: *id001
|
53
|
+
|
54
|
+
specialDelivery: >
|
55
|
+
Follow the Yellow Brick
|
56
|
+
Road to the Emerald City.
|
57
|
+
Pay no attention to the
|
58
|
+
man behind the curtain.
|
59
|
+
...
|
60
|
+
</textarea></form>
|
61
|
+
<script>
|
62
|
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
63
|
+
</script>
|
64
|
+
|
65
|
+
<p><strong>MIME types defined:</strong> <code>text/x-yaml</code>.</p>
|
66
|
+
|
67
|
+
</body>
|
68
|
+
</html>
|
@@ -0,0 +1,95 @@
|
|
1
|
+
CodeMirror.defineMode("yaml", function() {
|
2
|
+
|
3
|
+
var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
|
4
|
+
var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
|
5
|
+
|
6
|
+
return {
|
7
|
+
token: function(stream, state) {
|
8
|
+
var ch = stream.peek();
|
9
|
+
var esc = state.escaped;
|
10
|
+
state.escaped = false;
|
11
|
+
/* comments */
|
12
|
+
if (ch == "#") { stream.skipToEnd(); return "comment"; }
|
13
|
+
if (state.literal && stream.indentation() > state.keyCol) {
|
14
|
+
stream.skipToEnd(); return "string";
|
15
|
+
} else if (state.literal) { state.literal = false; }
|
16
|
+
if (stream.sol()) {
|
17
|
+
state.keyCol = 0;
|
18
|
+
state.pair = false;
|
19
|
+
state.pairStart = false;
|
20
|
+
/* document start */
|
21
|
+
if(stream.match(/---/)) { return "def"; }
|
22
|
+
/* document end */
|
23
|
+
if (stream.match(/\.\.\./)) { return "def"; }
|
24
|
+
/* array list item */
|
25
|
+
if (stream.match(/\s*-\s+/)) { return 'meta'; }
|
26
|
+
}
|
27
|
+
/* pairs (associative arrays) -> key */
|
28
|
+
if (!state.pair && stream.match(/^\s*([a-z0-9\._-])+(?=\s*:)/i)) {
|
29
|
+
state.pair = true;
|
30
|
+
state.keyCol = stream.indentation();
|
31
|
+
return "atom";
|
32
|
+
}
|
33
|
+
if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
|
34
|
+
|
35
|
+
/* inline pairs/lists */
|
36
|
+
if (stream.match(/^(\{|\}|\[|\])/)) {
|
37
|
+
if (ch == '{')
|
38
|
+
state.inlinePairs++;
|
39
|
+
else if (ch == '}')
|
40
|
+
state.inlinePairs--;
|
41
|
+
else if (ch == '[')
|
42
|
+
state.inlineList++;
|
43
|
+
else
|
44
|
+
state.inlineList--;
|
45
|
+
return 'meta';
|
46
|
+
}
|
47
|
+
|
48
|
+
/* list seperator */
|
49
|
+
if (state.inlineList > 0 && !esc && ch == ',') {
|
50
|
+
stream.next();
|
51
|
+
return 'meta';
|
52
|
+
}
|
53
|
+
/* pairs seperator */
|
54
|
+
if (state.inlinePairs > 0 && !esc && ch == ',') {
|
55
|
+
state.keyCol = 0;
|
56
|
+
state.pair = false;
|
57
|
+
state.pairStart = false;
|
58
|
+
stream.next();
|
59
|
+
return 'meta';
|
60
|
+
}
|
61
|
+
|
62
|
+
/* start of value of a pair */
|
63
|
+
if (state.pairStart) {
|
64
|
+
/* block literals */
|
65
|
+
if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
|
66
|
+
/* references */
|
67
|
+
if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
|
68
|
+
/* numbers */
|
69
|
+
if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
|
70
|
+
if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
|
71
|
+
/* keywords */
|
72
|
+
if (stream.match(keywordRegex)) { return 'keyword'; }
|
73
|
+
}
|
74
|
+
|
75
|
+
/* nothing found, continue */
|
76
|
+
state.pairStart = false;
|
77
|
+
state.escaped = (ch == '\\');
|
78
|
+
stream.next();
|
79
|
+
return null;
|
80
|
+
},
|
81
|
+
startState: function() {
|
82
|
+
return {
|
83
|
+
pair: false,
|
84
|
+
pairStart: false,
|
85
|
+
keyCol: 0,
|
86
|
+
inlinePairs: 0,
|
87
|
+
inlineList: 0,
|
88
|
+
literal: false,
|
89
|
+
escaped: false
|
90
|
+
};
|
91
|
+
}
|
92
|
+
};
|
93
|
+
});
|
94
|
+
|
95
|
+
CodeMirror.defineMIME("text/x-yaml", "yaml");
|
@@ -0,0 +1,17 @@
|
|
1
|
+
.cm-s-cobalt { background: #002240; color: white; }
|
2
|
+
.cm-s-cobalt span.CodeMirror-selected { background: #b36539 !important; }
|
3
|
+
.cm-s-cobalt .CodeMirror-gutter { background: #002240; border-right: 1px solid #aaa; }
|
4
|
+
.cm-s-cobalt .CodeMirror-gutter-text { color: #d0d0d0; }
|
5
|
+
.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white !important; }
|
6
|
+
|
7
|
+
.cm-s-cobalt span.cm-comment { color: #08f; }
|
8
|
+
.cm-s-cobalt span.cm-atom { color: #845dc4; }
|
9
|
+
.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
|
10
|
+
.cm-s-cobalt span.cm-keyword { color: #ffee80; }
|
11
|
+
.cm-s-cobalt span.cm-string { color: #3ad900; }
|
12
|
+
.cm-s-cobalt span.cm-meta { color: #ff9d00; }
|
13
|
+
.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
|
14
|
+
.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; }
|
15
|
+
.cm-s-cobalt span.cm-error { color: #9d1e15; }
|
16
|
+
.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
|
17
|
+
.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
|
@@ -0,0 +1,19 @@
|
|
1
|
+
.cm-s-default span.cm-keyword {color: #708;}
|
2
|
+
.cm-s-default span.cm-atom {color: #219;}
|
3
|
+
.cm-s-default span.cm-number {color: #164;}
|
4
|
+
.cm-s-default span.cm-def {color: #00f;}
|
5
|
+
.cm-s-default span.cm-variable {color: black;}
|
6
|
+
.cm-s-default span.cm-variable-2 {color: #05a;}
|
7
|
+
.cm-s-default span.cm-variable-3 {color: #0a5;}
|
8
|
+
.cm-s-default span.cm-property {color: black;}
|
9
|
+
.cm-s-default span.cm-operator {color: black;}
|
10
|
+
.cm-s-default span.cm-comment {color: #a50;}
|
11
|
+
.cm-s-default span.cm-string {color: #a11;}
|
12
|
+
.cm-s-default span.cm-string-2 {color: #f50;}
|
13
|
+
.cm-s-default span.cm-meta {color: #555;}
|
14
|
+
.cm-s-default span.cm-error {color: #f00;}
|
15
|
+
.cm-s-default span.cm-qualifier {color: #555;}
|
16
|
+
.cm-s-default span.cm-builtin {color: #30a;}
|
17
|
+
.cm-s-default span.cm-bracket {color: #cc7;}
|
18
|
+
.cm-s-default span.cm-tag {color: #170;}
|
19
|
+
.cm-s-default span.cm-attribute {color: #00c;}
|