blogelator 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ // Utility function that allows modes to be combined. The mode given
2
+ // as the base argument takes care of most of the normal mode
3
+ // functionality, but a second (typically simple) mode is used, which
4
+ // can override the style of text. Both modes get to parse all of the
5
+ // text, but when both assign a non-null style to a piece of code, the
6
+ // overlay wins, unless the combine argument was true, in which case
7
+ // the styles are combined.
8
+
9
+ // overlayParser is the old, deprecated name
10
+ CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, combine) {
11
+ return {
12
+ startState: function() {
13
+ return {
14
+ base: CodeMirror.startState(base),
15
+ overlay: CodeMirror.startState(overlay),
16
+ basePos: 0, baseCur: null,
17
+ overlayPos: 0, overlayCur: null
18
+ };
19
+ },
20
+ copyState: function(state) {
21
+ return {
22
+ base: CodeMirror.copyState(base, state.base),
23
+ overlay: CodeMirror.copyState(overlay, state.overlay),
24
+ basePos: state.basePos, baseCur: null,
25
+ overlayPos: state.overlayPos, overlayCur: null
26
+ };
27
+ },
28
+
29
+ token: function(stream, state) {
30
+ if (stream.start == state.basePos) {
31
+ state.baseCur = base.token(stream, state.base);
32
+ state.basePos = stream.pos;
33
+ }
34
+ if (stream.start == state.overlayPos) {
35
+ stream.pos = stream.start;
36
+ state.overlayCur = overlay.token(stream, state.overlay);
37
+ state.overlayPos = stream.pos;
38
+ }
39
+ stream.pos = Math.min(state.basePos, state.overlayPos);
40
+ if (stream.eol()) state.basePos = state.overlayPos = 0;
41
+
42
+ if (state.overlayCur == null) return state.baseCur;
43
+ if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
44
+ else return state.overlayCur;
45
+ },
46
+
47
+ indent: base.indent && function(state, textAfter) {
48
+ return base.indent(state.base, textAfter);
49
+ },
50
+ electricChars: base.electricChars,
51
+
52
+ innerMode: function(state) { return {state: state.base, mode: base}; },
53
+
54
+ blankLine: function(state) {
55
+ if (base.blankLine) base.blankLine(state.base);
56
+ if (overlay.blankLine) overlay.blankLine(state.overlay);
57
+ }
58
+ };
59
+ };
@@ -0,0 +1,131 @@
1
+ (function() {
2
+ function keywords(str) {
3
+ var obj = {}, words = str.split(" ");
4
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
5
+ return obj;
6
+ }
7
+ function heredoc(delim) {
8
+ return function(stream, state) {
9
+ if (stream.match(delim)) state.tokenize = null;
10
+ else stream.skipToEnd();
11
+ return "string";
12
+ };
13
+ }
14
+ var phpConfig = {
15
+ name: "clike",
16
+ keywords: keywords("abstract and array as break case catch class clone const continue declare default " +
17
+ "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
18
+ "for foreach function global goto if implements interface instanceof namespace " +
19
+ "new or private protected public static switch throw trait try use var while xor " +
20
+ "die echo empty exit eval include include_once isset list require require_once return " +
21
+ "print unset __halt_compiler self static parent yield insteadof finally"),
22
+ blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
23
+ atoms: keywords("true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__"),
24
+ builtin: keywords("func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once"),
25
+ multiLineStrings: true,
26
+ hooks: {
27
+ "$": function(stream) {
28
+ stream.eatWhile(/[\w\$_]/);
29
+ return "variable-2";
30
+ },
31
+ "<": function(stream, state) {
32
+ if (stream.match(/<</)) {
33
+ stream.eatWhile(/[\w\.]/);
34
+ state.tokenize = heredoc(stream.current().slice(3));
35
+ return state.tokenize(stream, state);
36
+ }
37
+ return false;
38
+ },
39
+ "#": function(stream) {
40
+ while (!stream.eol() && !stream.match("?>", false)) stream.next();
41
+ return "comment";
42
+ },
43
+ "/": function(stream) {
44
+ if (stream.eat("/")) {
45
+ while (!stream.eol() && !stream.match("?>", false)) stream.next();
46
+ return "comment";
47
+ }
48
+ return false;
49
+ }
50
+ }
51
+ };
52
+
53
+ CodeMirror.defineMode("php", function(config, parserConfig) {
54
+ var htmlMode = CodeMirror.getMode(config, "text/html");
55
+ var phpMode = CodeMirror.getMode(config, phpConfig);
56
+
57
+ function dispatch(stream, state) {
58
+ var isPHP = state.curMode == phpMode;
59
+ if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
60
+ if (!isPHP) {
61
+ if (stream.match(/^<\?\w*/)) {
62
+ state.curMode = phpMode;
63
+ state.curState = state.php;
64
+ return "meta";
65
+ }
66
+ if (state.pending == '"' || state.pending == "'") {
67
+ while (!stream.eol() && stream.next() != state.pending) {}
68
+ var style = "string";
69
+ } else if (state.pending && stream.pos < state.pending.end) {
70
+ stream.pos = state.pending.end;
71
+ var style = state.pending.style;
72
+ } else {
73
+ var style = htmlMode.token(stream, state.curState);
74
+ }
75
+ if (state.pending) state.pending = null;
76
+ var cur = stream.current(), openPHP = cur.search(/<\?/), m;
77
+ if (openPHP != -1) {
78
+ if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
79
+ else state.pending = {end: stream.pos, style: style};
80
+ stream.backUp(cur.length - openPHP);
81
+ }
82
+ return style;
83
+ } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
84
+ state.curMode = htmlMode;
85
+ state.curState = state.html;
86
+ return "meta";
87
+ } else {
88
+ return phpMode.token(stream, state.curState);
89
+ }
90
+ }
91
+
92
+ return {
93
+ startState: function() {
94
+ var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode);
95
+ return {html: html,
96
+ php: php,
97
+ curMode: parserConfig.startOpen ? phpMode : htmlMode,
98
+ curState: parserConfig.startOpen ? php : html,
99
+ pending: null};
100
+ },
101
+
102
+ copyState: function(state) {
103
+ var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
104
+ php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
105
+ if (state.curMode == htmlMode) cur = htmlNew;
106
+ else cur = phpNew;
107
+ return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
108
+ pending: state.pending};
109
+ },
110
+
111
+ token: dispatch,
112
+
113
+ indent: function(state, textAfter) {
114
+ if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
115
+ (state.curMode == phpMode && /^\?>/.test(textAfter)))
116
+ return htmlMode.indent(state.html, textAfter);
117
+ return state.curMode.indent(state.curState, textAfter);
118
+ },
119
+
120
+ blockCommentStart: "/*",
121
+ blockCommentEnd: "*/",
122
+ lineComment: "//",
123
+
124
+ innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
125
+ };
126
+ }, "htmlmixed", "clike");
127
+
128
+ CodeMirror.defineMIME("application/x-httpd-php", "php");
129
+ CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
130
+ CodeMirror.defineMIME("text/x-php", phpConfig);
131
+ })();
@@ -0,0 +1,250 @@
1
+ CodeMirror.defineMode("ruby", function(config) {
2
+ function wordObj(words) {
3
+ var o = {};
4
+ for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
5
+ return o;
6
+ }
7
+ var keywords = wordObj([
8
+ "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
9
+ "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
10
+ "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
11
+ "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
12
+ "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
13
+ "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
14
+ ]);
15
+ var indentWords = wordObj(["def", "class", "case", "for", "while", "module", "then",
16
+ "catch", "loop", "proc", "begin"]);
17
+ var dedentWords = wordObj(["end", "until"]);
18
+ var matching = {"[": "]", "{": "}", "(": ")"};
19
+ var curPunc;
20
+
21
+ function chain(newtok, stream, state) {
22
+ state.tokenize.push(newtok);
23
+ return newtok(stream, state);
24
+ }
25
+
26
+ function tokenBase(stream, state) {
27
+ curPunc = null;
28
+ if (stream.sol() && stream.match("=begin") && stream.eol()) {
29
+ state.tokenize.push(readBlockComment);
30
+ return "comment";
31
+ }
32
+ if (stream.eatSpace()) return null;
33
+ var ch = stream.next(), m;
34
+ if (ch == "`" || ch == "'" || ch == '"') {
35
+ return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
36
+ } else if (ch == "/" && !stream.eol() && stream.peek() != " ") {
37
+ if (stream.eat("=")) return "operator";
38
+ return chain(readQuoted(ch, "string-2", true), stream, state);
39
+ } else if (ch == "%") {
40
+ var style = "string", embed = true;
41
+ if (stream.eat("s")) style = "atom";
42
+ else if (stream.eat(/[WQ]/)) style = "string";
43
+ else if (stream.eat(/[r]/)) style = "string-2";
44
+ else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
45
+ var delim = stream.eat(/[^\w\s]/);
46
+ if (!delim) return "operator";
47
+ if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
48
+ return chain(readQuoted(delim, style, embed, true), stream, state);
49
+ } else if (ch == "#") {
50
+ stream.skipToEnd();
51
+ return "comment";
52
+ } else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
53
+ return chain(readHereDoc(m[1]), stream, state);
54
+ } else if (ch == "0") {
55
+ if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
56
+ else if (stream.eat("b")) stream.eatWhile(/[01]/);
57
+ else stream.eatWhile(/[0-7]/);
58
+ return "number";
59
+ } else if (/\d/.test(ch)) {
60
+ stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
61
+ return "number";
62
+ } else if (ch == "?") {
63
+ while (stream.match(/^\\[CM]-/)) {}
64
+ if (stream.eat("\\")) stream.eatWhile(/\w/);
65
+ else stream.next();
66
+ return "string";
67
+ } else if (ch == ":") {
68
+ if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
69
+ if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
70
+
71
+ // :> :>> :< :<< are valid symbols
72
+ if (stream.eat(/[\<\>]/)) {
73
+ stream.eat(/[\<\>]/);
74
+ return "atom";
75
+ }
76
+
77
+ // :+ :- :/ :* :| :& :! are valid symbols
78
+ if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
79
+ return "atom";
80
+ }
81
+
82
+ // Symbols can't start by a digit
83
+ if (stream.eat(/[a-zA-Z$@_]/)) {
84
+ stream.eatWhile(/[\w]/);
85
+ // Only one ? ! = is allowed and only as the last character
86
+ stream.eat(/[\?\!\=]/);
87
+ return "atom";
88
+ }
89
+ return "operator";
90
+ } else if (ch == "@" && stream.match(/^@?[a-zA-Z_]/)) {
91
+ stream.eat("@");
92
+ stream.eatWhile(/[\w]/);
93
+ return "variable-2";
94
+ } else if (ch == "$") {
95
+ if (stream.eat(/[a-zA-Z_]/)) {
96
+ stream.eatWhile(/[\w]/);
97
+ } else if (stream.eat(/\d/)) {
98
+ stream.eat(/\d/);
99
+ } else {
100
+ stream.next(); // Must be a special global like $: or $!
101
+ }
102
+ return "variable-3";
103
+ } else if (/[a-zA-Z_]/.test(ch)) {
104
+ stream.eatWhile(/[\w]/);
105
+ stream.eat(/[\?\!]/);
106
+ if (stream.eat(":")) return "atom";
107
+ return "ident";
108
+ } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
109
+ curPunc = "|";
110
+ return null;
111
+ } else if (/[\(\)\[\]{}\\;]/.test(ch)) {
112
+ curPunc = ch;
113
+ return null;
114
+ } else if (ch == "-" && stream.eat(">")) {
115
+ return "arrow";
116
+ } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
117
+ stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
118
+ return "operator";
119
+ } else {
120
+ return null;
121
+ }
122
+ }
123
+
124
+ function tokenBaseUntilBrace() {
125
+ var depth = 1;
126
+ return function(stream, state) {
127
+ if (stream.peek() == "}") {
128
+ depth--;
129
+ if (depth == 0) {
130
+ state.tokenize.pop();
131
+ return state.tokenize[state.tokenize.length-1](stream, state);
132
+ }
133
+ } else if (stream.peek() == "{") {
134
+ depth++;
135
+ }
136
+ return tokenBase(stream, state);
137
+ };
138
+ }
139
+ function tokenBaseOnce() {
140
+ var alreadyCalled = false;
141
+ return function(stream, state) {
142
+ if (alreadyCalled) {
143
+ state.tokenize.pop();
144
+ return state.tokenize[state.tokenize.length-1](stream, state);
145
+ }
146
+ alreadyCalled = true;
147
+ return tokenBase(stream, state);
148
+ };
149
+ }
150
+ function readQuoted(quote, style, embed, unescaped) {
151
+ return function(stream, state) {
152
+ var escaped = false, ch;
153
+
154
+ if (state.context.type === 'read-quoted-paused') {
155
+ state.context = state.context.prev;
156
+ stream.eat("}");
157
+ }
158
+
159
+ while ((ch = stream.next()) != null) {
160
+ if (ch == quote && (unescaped || !escaped)) {
161
+ state.tokenize.pop();
162
+ break;
163
+ }
164
+ if (embed && ch == "#" && !escaped) {
165
+ if (stream.eat("{")) {
166
+ if (quote == "}") {
167
+ state.context = {prev: state.context, type: 'read-quoted-paused'};
168
+ }
169
+ state.tokenize.push(tokenBaseUntilBrace());
170
+ break;
171
+ } else if (/[@\$]/.test(stream.peek())) {
172
+ state.tokenize.push(tokenBaseOnce());
173
+ break;
174
+ }
175
+ }
176
+ escaped = !escaped && ch == "\\";
177
+ }
178
+ return style;
179
+ };
180
+ }
181
+ function readHereDoc(phrase) {
182
+ return function(stream, state) {
183
+ if (stream.match(phrase)) state.tokenize.pop();
184
+ else stream.skipToEnd();
185
+ return "string";
186
+ };
187
+ }
188
+ function readBlockComment(stream, state) {
189
+ if (stream.sol() && stream.match("=end") && stream.eol())
190
+ state.tokenize.pop();
191
+ stream.skipToEnd();
192
+ return "comment";
193
+ }
194
+
195
+ return {
196
+ startState: function() {
197
+ return {tokenize: [tokenBase],
198
+ indented: 0,
199
+ context: {type: "top", indented: -config.indentUnit},
200
+ continuedLine: false,
201
+ lastTok: null,
202
+ varList: false};
203
+ },
204
+
205
+ token: function(stream, state) {
206
+ if (stream.sol()) state.indented = stream.indentation();
207
+ var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
208
+ if (style == "ident") {
209
+ var word = stream.current();
210
+ style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
211
+ : /^[A-Z]/.test(word) ? "tag"
212
+ : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
213
+ : "variable";
214
+ if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
215
+ else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
216
+ else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
217
+ kwtype = "indent";
218
+ else if (word == "do" && state.context.indented < state.indented)
219
+ kwtype = "indent";
220
+ }
221
+ if (curPunc || (style && style != "comment")) state.lastTok = word || curPunc || style;
222
+ if (curPunc == "|") state.varList = !state.varList;
223
+
224
+ if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
225
+ state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
226
+ else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
227
+ state.context = state.context.prev;
228
+
229
+ if (stream.eol())
230
+ state.continuedLine = (curPunc == "\\" || style == "operator");
231
+ return style;
232
+ },
233
+
234
+ indent: function(state, textAfter) {
235
+ if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
236
+ var firstChar = textAfter && textAfter.charAt(0);
237
+ var ct = state.context;
238
+ var closing = ct.type == matching[firstChar] ||
239
+ ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
240
+ return ct.indented + (closing ? 0 : config.indentUnit) +
241
+ (state.continuedLine ? config.indentUnit : 0);
242
+ },
243
+
244
+ electricChars: "}de", // enD and rescuE
245
+ lineComment: "#"
246
+ };
247
+ });
248
+
249
+ CodeMirror.defineMIME("text/x-ruby", "ruby");
250
+
@@ -0,0 +1,330 @@
1
+ CodeMirror.defineMode("sass", function(config) {
2
+ var tokenRegexp = function(words){
3
+ return new RegExp("^" + words.join("|"));
4
+ };
5
+
6
+ var keywords = ["true", "false", "null", "auto"];
7
+ var keywordsRegexp = new RegExp("^" + keywords.join("|"));
8
+
9
+ var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", "\\!=", "/", "\\*", "%", "and", "or", "not"];
10
+ var opRegexp = tokenRegexp(operators);
11
+
12
+ var pseudoElementsRegexp = /^::?[\w\-]+/;
13
+
14
+ var urlTokens = function(stream, state){
15
+ var ch = stream.peek();
16
+
17
+ if (ch === ")"){
18
+ stream.next();
19
+ state.tokenizer = tokenBase;
20
+ return "operator";
21
+ }else if (ch === "("){
22
+ stream.next();
23
+ stream.eatSpace();
24
+
25
+ return "operator";
26
+ }else if (ch === "'" || ch === '"'){
27
+ state.tokenizer = buildStringTokenizer(stream.next());
28
+ return "string";
29
+ }else{
30
+ state.tokenizer = buildStringTokenizer(")", false);
31
+ return "string";
32
+ }
33
+ };
34
+ var multilineComment = function(stream, state) {
35
+ if (stream.skipTo("*/")){
36
+ stream.next();
37
+ stream.next();
38
+ state.tokenizer = tokenBase;
39
+ }else {
40
+ stream.next();
41
+ }
42
+
43
+ return "comment";
44
+ };
45
+
46
+ var buildStringTokenizer = function(quote, greedy){
47
+ if(greedy == null){ greedy = true; }
48
+
49
+ function stringTokenizer(stream, state){
50
+ var nextChar = stream.next();
51
+ var peekChar = stream.peek();
52
+ var previousChar = stream.string.charAt(stream.pos-2);
53
+
54
+ var endingString = ((nextChar !== "\\" && peekChar === quote) || (nextChar === quote && previousChar !== "\\"));
55
+
56
+ /*
57
+ console.log("previousChar: " + previousChar);
58
+ console.log("nextChar: " + nextChar);
59
+ console.log("peekChar: " + peekChar);
60
+ console.log("ending: " + endingString);
61
+ */
62
+
63
+ if (endingString){
64
+ if (nextChar !== quote && greedy) { stream.next(); }
65
+ state.tokenizer = tokenBase;
66
+ return "string";
67
+ }else if (nextChar === "#" && peekChar === "{"){
68
+ state.tokenizer = buildInterpolationTokenizer(stringTokenizer);
69
+ stream.next();
70
+ return "operator";
71
+ }else {
72
+ return "string";
73
+ }
74
+ }
75
+
76
+ return stringTokenizer;
77
+ };
78
+
79
+ var buildInterpolationTokenizer = function(currentTokenizer){
80
+ return function(stream, state){
81
+ if (stream.peek() === "}"){
82
+ stream.next();
83
+ state.tokenizer = currentTokenizer;
84
+ return "operator";
85
+ }else{
86
+ return tokenBase(stream, state);
87
+ }
88
+ };
89
+ };
90
+
91
+ var indent = function(state){
92
+ if (state.indentCount == 0){
93
+ state.indentCount++;
94
+ var lastScopeOffset = state.scopes[0].offset;
95
+ var currentOffset = lastScopeOffset + config.indentUnit;
96
+ state.scopes.unshift({ offset:currentOffset });
97
+ }
98
+ };
99
+
100
+ var dedent = function(state){
101
+ if (state.scopes.length == 1) { return; }
102
+
103
+ state.scopes.shift();
104
+ };
105
+
106
+ var tokenBase = function(stream, state) {
107
+ var ch = stream.peek();
108
+
109
+ // Single line Comment
110
+ if (stream.match('//')) {
111
+ stream.skipToEnd();
112
+ return "comment";
113
+ }
114
+
115
+ // Multiline Comment
116
+ if (stream.match('/*')){
117
+ state.tokenizer = multilineComment;
118
+ return state.tokenizer(stream, state);
119
+ }
120
+
121
+ // Interpolation
122
+ if (stream.match('#{')){
123
+ state.tokenizer = buildInterpolationTokenizer(tokenBase);
124
+ return "operator";
125
+ }
126
+
127
+ if (ch === "."){
128
+ stream.next();
129
+
130
+ // Match class selectors
131
+ if (stream.match(/^[\w-]+/)){
132
+ indent(state);
133
+ return "atom";
134
+ }else if (stream.peek() === "#"){
135
+ indent(state);
136
+ return "atom";
137
+ }else{
138
+ return "operator";
139
+ }
140
+ }
141
+
142
+ if (ch === "#"){
143
+ stream.next();
144
+
145
+ // Hex numbers
146
+ if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){
147
+ return "number";
148
+ }
149
+
150
+ // ID selectors
151
+ if (stream.match(/^[\w-]+/)){
152
+ indent(state);
153
+ return "atom";
154
+ }
155
+
156
+ if (stream.peek() === "#"){
157
+ indent(state);
158
+ return "atom";
159
+ }
160
+ }
161
+
162
+ // Numbers
163
+ if (stream.match(/^-?[0-9\.]+/)){
164
+ return "number";
165
+ }
166
+
167
+ // Units
168
+ if (stream.match(/^(px|em|in)\b/)){
169
+ return "unit";
170
+ }
171
+
172
+ if (stream.match(keywordsRegexp)){
173
+ return "keyword";
174
+ }
175
+
176
+ if (stream.match(/^url/) && stream.peek() === "("){
177
+ state.tokenizer = urlTokens;
178
+ return "atom";
179
+ }
180
+
181
+ // Variables
182
+ if (ch === "$"){
183
+ stream.next();
184
+ stream.eatWhile(/[\w-]/);
185
+
186
+ if (stream.peek() === ":"){
187
+ stream.next();
188
+ return "variable-2";
189
+ }else{
190
+ return "variable-3";
191
+ }
192
+ }
193
+
194
+ if (ch === "!"){
195
+ stream.next();
196
+
197
+ if (stream.match(/^[\w]+/)){
198
+ return "keyword";
199
+ }
200
+
201
+ return "operator";
202
+ }
203
+
204
+ if (ch === "="){
205
+ stream.next();
206
+
207
+ // Match shortcut mixin definition
208
+ if (stream.match(/^[\w-]+/)){
209
+ indent(state);
210
+ return "meta";
211
+ }else {
212
+ return "operator";
213
+ }
214
+ }
215
+
216
+ if (ch === "+"){
217
+ stream.next();
218
+
219
+ // Match shortcut mixin definition
220
+ if (stream.match(/^[\w-]+/)){
221
+ return "variable-3";
222
+ }else {
223
+ return "operator";
224
+ }
225
+ }
226
+
227
+ // Indent Directives
228
+ if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)){
229
+ indent(state);
230
+ return "meta";
231
+ }
232
+
233
+ // Other Directives
234
+ if (ch === "@"){
235
+ stream.next();
236
+ stream.eatWhile(/[\w-]/);
237
+ return "meta";
238
+ }
239
+
240
+ // Strings
241
+ if (ch === '"' || ch === "'"){
242
+ stream.next();
243
+ state.tokenizer = buildStringTokenizer(ch);
244
+ return "string";
245
+ }
246
+
247
+ // Pseudo element selectors
248
+ if (ch == ':' && stream.match(pseudoElementsRegexp)){
249
+ return "keyword";
250
+ }
251
+
252
+ // atoms
253
+ if (stream.eatWhile(/[\w-&]/)){
254
+ // matches a property definition
255
+ if (stream.peek() === ":" && !stream.match(pseudoElementsRegexp, false))
256
+ return "property";
257
+ else
258
+ return "atom";
259
+ }
260
+
261
+ if (stream.match(opRegexp)){
262
+ return "operator";
263
+ }
264
+
265
+ // If we haven't returned by now, we move 1 character
266
+ // and return an error
267
+ stream.next();
268
+ return null;
269
+ };
270
+
271
+ var tokenLexer = function(stream, state) {
272
+ if (stream.sol()){
273
+ state.indentCount = 0;
274
+ }
275
+ var style = state.tokenizer(stream, state);
276
+ var current = stream.current();
277
+
278
+ if (current === "@return"){
279
+ dedent(state);
280
+ }
281
+
282
+ if (style === "atom"){
283
+ indent(state);
284
+ }
285
+
286
+ if (style !== null){
287
+ var startOfToken = stream.pos - current.length;
288
+ var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount);
289
+
290
+ var newScopes = [];
291
+
292
+ for (var i = 0; i < state.scopes.length; i++){
293
+ var scope = state.scopes[i];
294
+
295
+ if (scope.offset <= withCurrentIndent){
296
+ newScopes.push(scope);
297
+ }
298
+ }
299
+
300
+ state.scopes = newScopes;
301
+ }
302
+
303
+
304
+ return style;
305
+ };
306
+
307
+ return {
308
+ startState: function() {
309
+ return {
310
+ tokenizer: tokenBase,
311
+ scopes: [{offset: 0, type: 'sass'}],
312
+ definedVars: [],
313
+ definedMixins: []
314
+ };
315
+ },
316
+ token: function(stream, state) {
317
+ var style = tokenLexer(stream, state);
318
+
319
+ state.lastToken = { style: style, content: stream.current() };
320
+
321
+ return style;
322
+ },
323
+
324
+ indent: function(state) {
325
+ return state.scopes[0].offset;
326
+ }
327
+ };
328
+ });
329
+
330
+ CodeMirror.defineMIME("text/x-sass", "sass");