haml-more 0.4.0.a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. data/README.md +79 -0
  2. data/lib/haml/more/coffee_script.rb +137 -0
  3. data/lib/haml/more/content_for.rb +25 -0
  4. data/lib/haml/more.rb +45 -0
  5. data/lib/haml-more.rb +1 -0
  6. data/lib/sass/more.rb +16 -0
  7. data/lib/sass-more.rb +1 -0
  8. data/spec/sass/more_spec.rb +21 -0
  9. data/vendor/coffee-script/Cakefile +57 -0
  10. data/vendor/coffee-script/LICENSE +22 -0
  11. data/vendor/coffee-script/README +41 -0
  12. data/vendor/coffee-script/Rakefile +20 -0
  13. data/vendor/coffee-script/bin/cake +7 -0
  14. data/vendor/coffee-script/bin/coffee +7 -0
  15. data/vendor/coffee-script/documentation/coffee/aliases.coffee +9 -0
  16. data/vendor/coffee-script/documentation/coffee/arguments.coffee +4 -0
  17. data/vendor/coffee-script/documentation/coffee/array_comprehensions.coffee +7 -0
  18. data/vendor/coffee-script/documentation/coffee/assignment.coffee +2 -0
  19. data/vendor/coffee-script/documentation/coffee/cake_tasks.coffee +5 -0
  20. data/vendor/coffee-script/documentation/coffee/comparisons.coffee +5 -0
  21. data/vendor/coffee-script/documentation/coffee/conditionals.coffee +9 -0
  22. data/vendor/coffee-script/documentation/coffee/embedded.coffee +5 -0
  23. data/vendor/coffee-script/documentation/coffee/existence.coffee +8 -0
  24. data/vendor/coffee-script/documentation/coffee/expressions.coffee +9 -0
  25. data/vendor/coffee-script/documentation/coffee/expressions_assignment.coffee +1 -0
  26. data/vendor/coffee-script/documentation/coffee/expressions_comprehension.coffee +3 -0
  27. data/vendor/coffee-script/documentation/coffee/expressions_try.coffee +6 -0
  28. data/vendor/coffee-script/documentation/coffee/fat_arrow.coffee +6 -0
  29. data/vendor/coffee-script/documentation/coffee/functions.coffee +2 -0
  30. data/vendor/coffee-script/documentation/coffee/heredocs.coffee +5 -0
  31. data/vendor/coffee-script/documentation/coffee/multiple_return_values.coffee +5 -0
  32. data/vendor/coffee-script/documentation/coffee/object_comprehensions.coffee +4 -0
  33. data/vendor/coffee-script/documentation/coffee/object_extraction.coffee +13 -0
  34. data/vendor/coffee-script/documentation/coffee/objects_and_arrays.coffee +13 -0
  35. data/vendor/coffee-script/documentation/coffee/overview.coffee +29 -0
  36. data/vendor/coffee-script/documentation/coffee/parallel_assignment.coffee +4 -0
  37. data/vendor/coffee-script/documentation/coffee/range_comprehensions.coffee +6 -0
  38. data/vendor/coffee-script/documentation/coffee/scope.coffee +5 -0
  39. data/vendor/coffee-script/documentation/coffee/slices.coffee +6 -0
  40. data/vendor/coffee-script/documentation/coffee/soaks.coffee +1 -0
  41. data/vendor/coffee-script/documentation/coffee/splats.coffee +25 -0
  42. data/vendor/coffee-script/documentation/coffee/splices.coffee +5 -0
  43. data/vendor/coffee-script/documentation/coffee/strings.coffee +8 -0
  44. data/vendor/coffee-script/documentation/coffee/super.coffee +34 -0
  45. data/vendor/coffee-script/documentation/coffee/switch.coffee +10 -0
  46. data/vendor/coffee-script/documentation/coffee/try.coffee +7 -0
  47. data/vendor/coffee-script/documentation/coffee/while.coffee +10 -0
  48. data/vendor/coffee-script/documentation/css/docs.css +213 -0
  49. data/vendor/coffee-script/documentation/css/idle.css +63 -0
  50. data/vendor/coffee-script/documentation/css/logo.png +0 -0
  51. data/vendor/coffee-script/documentation/index.html.erb +967 -0
  52. data/vendor/coffee-script/documentation/js/aliases.js +14 -0
  53. data/vendor/coffee-script/documentation/js/arguments.js +8 -0
  54. data/vendor/coffee-script/documentation/js/array_comprehensions.js +26 -0
  55. data/vendor/coffee-script/documentation/js/assignment.js +5 -0
  56. data/vendor/coffee-script/documentation/js/cake_tasks.js +14 -0
  57. data/vendor/coffee-script/documentation/js/comparisons.js +5 -0
  58. data/vendor/coffee-script/documentation/js/conditionals.js +12 -0
  59. data/vendor/coffee-script/documentation/js/embedded.js +6 -0
  60. data/vendor/coffee-script/documentation/js/existence.js +7 -0
  61. data/vendor/coffee-script/documentation/js/expressions.js +13 -0
  62. data/vendor/coffee-script/documentation/js/expressions_assignment.js +4 -0
  63. data/vendor/coffee-script/documentation/js/expressions_comprehension.js +12 -0
  64. data/vendor/coffee-script/documentation/js/expressions_try.js +9 -0
  65. data/vendor/coffee-script/documentation/js/fat_arrow.js +15 -0
  66. data/vendor/coffee-script/documentation/js/functions.js +9 -0
  67. data/vendor/coffee-script/documentation/js/heredocs.js +4 -0
  68. data/vendor/coffee-script/documentation/js/intro.js +7 -0
  69. data/vendor/coffee-script/documentation/js/multiple_return_values.js +11 -0
  70. data/vendor/coffee-script/documentation/js/object_comprehensions.js +17 -0
  71. data/vendor/coffee-script/documentation/js/object_extraction.js +17 -0
  72. data/vendor/coffee-script/documentation/js/objects_and_arrays.js +10 -0
  73. data/vendor/coffee-script/documentation/js/overview.js +43 -0
  74. data/vendor/coffee-script/documentation/js/parallel_assignment.js +8 -0
  75. data/vendor/coffee-script/documentation/js/punctuation.js +8 -0
  76. data/vendor/coffee-script/documentation/js/range_comprehensions.js +21 -0
  77. data/vendor/coffee-script/documentation/js/scope.js +10 -0
  78. data/vendor/coffee-script/documentation/js/slices.js +6 -0
  79. data/vendor/coffee-script/documentation/js/soaks.js +4 -0
  80. data/vendor/coffee-script/documentation/js/splats.js +16 -0
  81. data/vendor/coffee-script/documentation/js/splices.js +5 -0
  82. data/vendor/coffee-script/documentation/js/strings.js +9 -0
  83. data/vendor/coffee-script/documentation/js/super.js +37 -0
  84. data/vendor/coffee-script/documentation/js/switch.js +18 -0
  85. data/vendor/coffee-script/documentation/js/try.js +10 -0
  86. data/vendor/coffee-script/documentation/js/while.js +22 -0
  87. data/vendor/coffee-script/documentation/underscore.html +627 -0
  88. data/vendor/coffee-script/examples/beautiful_code/binary_search.coffee +16 -0
  89. data/vendor/coffee-script/examples/beautiful_code/quicksort_runtime.coffee +13 -0
  90. data/vendor/coffee-script/examples/beautiful_code/regular_expression_matcher.coffee +34 -0
  91. data/vendor/coffee-script/examples/blocks.coffee +57 -0
  92. data/vendor/coffee-script/examples/code.coffee +173 -0
  93. data/vendor/coffee-script/examples/computer_science/README +4 -0
  94. data/vendor/coffee-script/examples/computer_science/binary_search.coffee +25 -0
  95. data/vendor/coffee-script/examples/computer_science/bubble_sort.coffee +11 -0
  96. data/vendor/coffee-script/examples/computer_science/linked_list.coffee +106 -0
  97. data/vendor/coffee-script/examples/computer_science/luhn_algorithm.coffee +36 -0
  98. data/vendor/coffee-script/examples/computer_science/merge_sort.coffee +19 -0
  99. data/vendor/coffee-script/examples/computer_science/selection_sort.coffee +23 -0
  100. data/vendor/coffee-script/examples/poignant.coffee +186 -0
  101. data/vendor/coffee-script/examples/potion.coffee +205 -0
  102. data/vendor/coffee-script/examples/underscore.coffee +603 -0
  103. data/vendor/coffee-script/examples/web_server.coffee +12 -0
  104. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/Preferences/CoffeeScript.tmPreferences +24 -0
  105. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/Syntaxes/CoffeeScript.tmLanguage +361 -0
  106. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/info.plist +10 -0
  107. data/vendor/coffee-script/extras/EXTRAS +20 -0
  108. data/vendor/coffee-script/extras/coffee.vim +117 -0
  109. data/vendor/coffee-script/index.html +1847 -0
  110. data/vendor/coffee-script/lib/bin/cake +7 -0
  111. data/vendor/coffee-script/lib/bin/coffee +7 -0
  112. data/vendor/coffee-script/lib/cake.js +80 -0
  113. data/vendor/coffee-script/lib/coffee-script.js +61 -0
  114. data/vendor/coffee-script/lib/command_line.js +201 -0
  115. data/vendor/coffee-script/lib/grammar.js +564 -0
  116. data/vendor/coffee-script/lib/lexer.js +405 -0
  117. data/vendor/coffee-script/lib/narwhal.js +44 -0
  118. data/vendor/coffee-script/lib/nodes.js +1328 -0
  119. data/vendor/coffee-script/lib/optparse.js +117 -0
  120. data/vendor/coffee-script/lib/parser.js +536 -0
  121. data/vendor/coffee-script/lib/repl.js +32 -0
  122. data/vendor/coffee-script/lib/rewriter.js +383 -0
  123. data/vendor/coffee-script/lib/scope.js +114 -0
  124. data/vendor/coffee-script/package.json +7 -0
  125. data/vendor/coffee-script/src/cake.coffee +45 -0
  126. data/vendor/coffee-script/src/coffee-script.coffee +45 -0
  127. data/vendor/coffee-script/src/command_line.coffee +130 -0
  128. data/vendor/coffee-script/src/grammar.coffee +456 -0
  129. data/vendor/coffee-script/src/lexer.coffee +327 -0
  130. data/vendor/coffee-script/src/narwhal.coffee +42 -0
  131. data/vendor/coffee-script/src/nodes.coffee +1045 -0
  132. data/vendor/coffee-script/src/optparse.coffee +79 -0
  133. data/vendor/coffee-script/src/repl.coffee +23 -0
  134. data/vendor/coffee-script/src/rewriter.coffee +253 -0
  135. data/vendor/coffee-script/src/scope.coffee +75 -0
  136. data/vendor/coffee-script/test/test_arguments.coffee +34 -0
  137. data/vendor/coffee-script/test/test_array_comprehension.coffee +42 -0
  138. data/vendor/coffee-script/test/test_assignment.coffee +26 -0
  139. data/vendor/coffee-script/test/test_blocks.coffee +4 -0
  140. data/vendor/coffee-script/test/test_calling_super.coffee +42 -0
  141. data/vendor/coffee-script/test/test_chained_calls.coffee +25 -0
  142. data/vendor/coffee-script/test/test_destructuring_assignment.coffee +62 -0
  143. data/vendor/coffee-script/test/test_everything.coffee +29 -0
  144. data/vendor/coffee-script/test/test_exceptions.coffee +2 -0
  145. data/vendor/coffee-script/test/test_existence.coffee +81 -0
  146. data/vendor/coffee-script/test/test_expressions.coffee +30 -0
  147. data/vendor/coffee-script/test/test_fancy_if_statement.coffee +26 -0
  148. data/vendor/coffee-script/test/test_functions.coffee +80 -0
  149. data/vendor/coffee-script/test/test_funky_comments.coffee +25 -0
  150. data/vendor/coffee-script/test/test_heredocs.coffee +46 -0
  151. data/vendor/coffee-script/test/test_lexical_scope.coffee +10 -0
  152. data/vendor/coffee-script/test/test_literals.coffee +56 -0
  153. data/vendor/coffee-script/test/test_nested_comprehensions.coffee +11 -0
  154. data/vendor/coffee-script/test/test_newline_escaping.coffee +6 -0
  155. data/vendor/coffee-script/test/test_operations.coffee +18 -0
  156. data/vendor/coffee-script/test/test_range_comprehension.coffee +20 -0
  157. data/vendor/coffee-script/test/test_ranges_and_slices.coffee +16 -0
  158. data/vendor/coffee-script/test/test_splats.coffee +47 -0
  159. data/vendor/coffee-script/test/test_splices.coffee +5 -0
  160. data/vendor/coffee-script/test/test_switch.coffee +64 -0
  161. data/vendor/coffee-script/test/test_while.coffee +30 -0
  162. data/vendor/coffee-script/vendor/jison/Jakefile +31 -0
  163. data/vendor/coffee-script/vendor/jison/README.md +347 -0
  164. data/vendor/coffee-script/vendor/jison/bin/jison +3 -0
  165. data/vendor/coffee-script/vendor/jison/bin/json2jison +3 -0
  166. data/vendor/coffee-script/vendor/jison/examples/ansic.jison +415 -0
  167. data/vendor/coffee-script/vendor/jison/examples/basic.json +8 -0
  168. data/vendor/coffee-script/vendor/jison/examples/basic2.json +9 -0
  169. data/vendor/coffee-script/vendor/jison/examples/basic2_lex.json +16 -0
  170. data/vendor/coffee-script/vendor/jison/examples/basic_lex.json +15 -0
  171. data/vendor/coffee-script/vendor/jison/examples/calculator.jison +38 -0
  172. data/vendor/coffee-script/vendor/jison/examples/calculator.jisonlex +14 -0
  173. data/vendor/coffee-script/vendor/jison/examples/calculator.json +42 -0
  174. data/vendor/coffee-script/vendor/jison/examples/classy.json +105 -0
  175. data/vendor/coffee-script/vendor/jison/examples/classy_ast.json +126 -0
  176. data/vendor/coffee-script/vendor/jison/examples/dism.json +25 -0
  177. data/vendor/coffee-script/vendor/jison/examples/dism_lr0.json +26 -0
  178. data/vendor/coffee-script/vendor/jison/examples/json.js +80 -0
  179. data/vendor/coffee-script/vendor/jison/examples/json_ast.js +83 -0
  180. data/vendor/coffee-script/vendor/jison/examples/precedence.json +26 -0
  181. data/vendor/coffee-script/vendor/jison/examples/reduce_conflict.json +13 -0
  182. data/vendor/coffee-script/vendor/jison/lib/jison/bnf.js +43 -0
  183. data/vendor/coffee-script/vendor/jison/lib/jison/jisonlex.js +18 -0
  184. data/vendor/coffee-script/vendor/jison/lib/jison/json2jison.js +146 -0
  185. data/vendor/coffee-script/vendor/jison/lib/jison/lexer.js +224 -0
  186. data/vendor/coffee-script/vendor/jison/lib/jison/util/bnf-parser.js +383 -0
  187. data/vendor/coffee-script/vendor/jison/lib/jison/util/lex-parser.js +407 -0
  188. data/vendor/coffee-script/vendor/jison/lib/jison/util/set.js +94 -0
  189. data/vendor/coffee-script/vendor/jison/lib/jison/util/typal.js +90 -0
  190. data/vendor/coffee-script/vendor/jison/lib/jison.js +1414 -0
  191. data/vendor/coffee-script/vendor/jison/package.json +14 -0
  192. data/vendor/coffee-script/vendor/jison/src/bnf.jison +110 -0
  193. data/vendor/coffee-script/vendor/jison/src/bnf.jisonlex +25 -0
  194. data/vendor/coffee-script/vendor/jison/src/bnf.lex.json +24 -0
  195. data/vendor/coffee-script/vendor/jison/src/jisonlex.jison +129 -0
  196. data/vendor/coffee-script/vendor/jison/src/jisonlex.jisonlex +31 -0
  197. data/vendor/coffee-script/vendor/jison/src/jisonlex.lex.json +30 -0
  198. data/vendor/coffee-script/vendor/jison/tests/all-tests.js +8 -0
  199. data/vendor/coffee-script/vendor/jison/tests/grammar/bnf.js +91 -0
  200. data/vendor/coffee-script/vendor/jison/tests/grammar/bnf_parse.js +65 -0
  201. data/vendor/coffee-script/vendor/jison/tests/grammar/grammar-tests.js +10 -0
  202. data/vendor/coffee-script/vendor/jison/tests/grammar/json2jison.js +24 -0
  203. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/ansic.jisonlex +115 -0
  204. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/bnf.jisonlex +25 -0
  205. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/bnf.lex.json +24 -0
  206. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/lex_grammar.jisonlex +31 -0
  207. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/lex_grammar.lex.json +30 -0
  208. data/vendor/coffee-script/vendor/jison/tests/grammar/lex.jison +119 -0
  209. data/vendor/coffee-script/vendor/jison/tests/grammar/lex.js +58 -0
  210. data/vendor/coffee-script/vendor/jison/tests/grammar/lex_parse.js +117 -0
  211. data/vendor/coffee-script/vendor/jison/tests/lexer/lexer-tests.js +6 -0
  212. data/vendor/coffee-script/vendor/jison/tests/lexer/regexplexer.js +417 -0
  213. data/vendor/coffee-script/vendor/jison/tests/parser/actions.js +311 -0
  214. data/vendor/coffee-script/vendor/jison/tests/parser/api.js +236 -0
  215. data/vendor/coffee-script/vendor/jison/tests/parser/generator.js +196 -0
  216. data/vendor/coffee-script/vendor/jison/tests/parser/lalr.js +183 -0
  217. data/vendor/coffee-script/vendor/jison/tests/parser/lr0.js +72 -0
  218. data/vendor/coffee-script/vendor/jison/tests/parser/lr1.js +119 -0
  219. data/vendor/coffee-script/vendor/jison/tests/parser/parser-tests.js +14 -0
  220. data/vendor/coffee-script/vendor/jison/tests/parser/precedence.js +237 -0
  221. data/vendor/coffee-script/vendor/jison/tests/parser/slr.js +52 -0
  222. data/vendor/coffee-script/vendor/jison/tests/parser/tables.js +126 -0
  223. data/vendor/coffee-script/vendor/jison/tests/performance.js +110 -0
  224. data/vendor/coffee-script/vendor/jison/tests/setup.js +3 -0
  225. metadata +324 -0
@@ -0,0 +1,405 @@
1
+ (function(){
2
+ var ACCESSORS, ASSIGNMENT, BEFORE_WHEN, CALLABLE, CODE, COFFEE_KEYWORDS, COMMENT, COMMENT_CLEANER, HEREDOC, HEREDOC_INDENT, IDENTIFIER, JS, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, KEYWORDS, LAST_DENT, LAST_DENTS, MULTILINER, MULTI_DENT, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RESERVED, Rewriter, STRING, STRING_NEWLINES, WHITESPACE, lex;
3
+ if ((typeof process !== "undefined" && process !== null)) {
4
+ Rewriter = require('./rewriter').Rewriter;
5
+ } else {
6
+ this.exports = this;
7
+ Rewriter = this.Rewriter;
8
+ }
9
+ // The lexer reads a stream of CoffeeScript and divvys it up into tagged
10
+ // tokens. A minor bit of the ambiguity in the grammar has been avoided by
11
+ // pushing some extra smarts into the Lexer.
12
+ exports.Lexer = (lex = function lex() { });
13
+ // Constants ============================================================
14
+ // Keywords that CoffeScript shares in common with JS.
15
+ JS_KEYWORDS = ["if", "else", "true", "false", "new", "return", "try", "catch", "finally", "throw", "break", "continue", "for", "in", "while", "delete", "instanceof", "typeof", "switch", "super", "extends"];
16
+ // CoffeeScript-only keywords -- which we're more relaxed about allowing.
17
+ COFFEE_KEYWORDS = ["then", "unless", "yes", "no", "on", "off", "and", "or", "is", "isnt", "not", "of", "by", "where", "when"];
18
+ // The list of keywords passed verbatim to the parser.
19
+ KEYWORDS = JS_KEYWORDS.concat(COFFEE_KEYWORDS);
20
+ // The list of keywords that are reserved by JavaScript, but not used, and aren't
21
+ // used by CoffeeScript. Using these will throw an error at compile time.
22
+ RESERVED = ["case", "default", "do", "function", "var", "void", "with", "class", "const", "let", "debugger", "enum", "export", "import", "native"];
23
+ // JavaScript keywords and reserved words together, excluding CoffeeScript ones.
24
+ JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED);
25
+ // Token matching regexes. (keep the IDENTIFIER regex in sync with AssignNode.)
26
+ IDENTIFIER = /^([a-zA-Z$_](\w|\$)*)/;
27
+ NUMBER = /^(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i;
28
+ STRING = /^(""|''|"([\s\S]*?)([^\\]|\\\\)"|'([\s\S]*?)([^\\]|\\\\)')/;
29
+ HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/;
30
+ JS = /^(``|`([\s\S]*?)([^\\]|\\\\)`)/;
31
+ OPERATOR = /^([+\*&|\/\-%=<>:!?]+)/;
32
+ WHITESPACE = /^([ \t]+)/;
33
+ COMMENT = /^(((\n?[ \t]*)?#[^\n]*)+)/;
34
+ CODE = /^((-|=)>)/;
35
+ REGEX = /^(\/(.*?)([^\\]|\\\\)\/[imgy]{0,4})/;
36
+ MULTI_DENT = /^((\n([ \t]*))+)(\.)?/;
37
+ LAST_DENTS = /\n([ \t]*)/g;
38
+ LAST_DENT = /\n([ \t]*)/;
39
+ ASSIGNMENT = /^(:|=)$/;
40
+ // Token cleaning regexes.
41
+ JS_CLEANER = /(^`|`$)/g;
42
+ MULTILINER = /\n/g;
43
+ STRING_NEWLINES = /\n[ \t]*/g;
44
+ COMMENT_CLEANER = /(^[ \t]*#|\n[ \t]*$)/mg;
45
+ NO_NEWLINE = /^([+\*&|\/\-%=<>:!.\\][<>=&|]*|and|or|is|isnt|not|delete|typeof|instanceof)$/;
46
+ HEREDOC_INDENT = /^[ \t]+/mg;
47
+ // Tokens which a regular expression will never immediately follow, but which
48
+ // a division operator might.
49
+ // See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
50
+ NOT_REGEX = ['IDENTIFIER', 'NUMBER', 'REGEX', 'STRING', ')', '++', '--', ']', '}', 'FALSE', 'NULL', 'TRUE'];
51
+ // Tokens which could legitimately be invoked or indexed.
52
+ CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@'];
53
+ // Tokens that indicate an access -- keywords immediately following will be
54
+ // treated as identifiers.
55
+ ACCESSORS = ['PROPERTY_ACCESS', 'PROTOTYPE_ACCESS', 'SOAK_ACCESS', '@'];
56
+ // Tokens that, when immediately preceding a 'WHEN', indicate that its leading.
57
+ BEFORE_WHEN = ['INDENT', 'OUTDENT', 'TERMINATOR'];
58
+ // Scan by attempting to match tokens one character at a time. Slow and steady.
59
+ lex.prototype.tokenize = function tokenize(code) {
60
+ this.code = code;
61
+ // Cleanup code by remove extra line breaks, TODO: chomp
62
+ this.i = 0;
63
+ // Current character position we're parsing
64
+ this.line = 1;
65
+ // The current line.
66
+ this.indent = 0;
67
+ // The current indent level.
68
+ this.indents = [];
69
+ // The stack of all indent levels we are currently within.
70
+ this.tokens = [];
71
+ // Collection of all parsed tokens in the form [:TOKEN_TYPE, value]
72
+ while (this.i < this.code.length) {
73
+ this.chunk = this.code.slice(this.i);
74
+ this.extract_next_token();
75
+ }
76
+ this.close_indentation();
77
+ return (new Rewriter()).rewrite(this.tokens);
78
+ };
79
+ // At every position, run through this list of attempted matches,
80
+ // short-circuiting if any of them succeed.
81
+ lex.prototype.extract_next_token = function extract_next_token() {
82
+ if (this.identifier_token()) {
83
+ return null;
84
+ }
85
+ if (this.number_token()) {
86
+ return null;
87
+ }
88
+ if (this.heredoc_token()) {
89
+ return null;
90
+ }
91
+ if (this.string_token()) {
92
+ return null;
93
+ }
94
+ if (this.js_token()) {
95
+ return null;
96
+ }
97
+ if (this.regex_token()) {
98
+ return null;
99
+ }
100
+ if (this.indent_token()) {
101
+ return null;
102
+ }
103
+ if (this.comment_token()) {
104
+ return null;
105
+ }
106
+ if (this.whitespace_token()) {
107
+ return null;
108
+ }
109
+ return this.literal_token();
110
+ };
111
+ // Tokenizers ==========================================================
112
+ // Matches identifying literals: variables, keywords, method names, etc.
113
+ lex.prototype.identifier_token = function identifier_token() {
114
+ var id, tag;
115
+ if (!((id = this.match(IDENTIFIER, 1)))) {
116
+ return false;
117
+ }
118
+ if (this.value() === '::') {
119
+ this.tag(1, 'PROTOTYPE_ACCESS');
120
+ }
121
+ if (this.value() === '.' && !(this.value(2) === '.')) {
122
+ if (this.tag(2) === '?') {
123
+ this.tag(1, 'SOAK_ACCESS');
124
+ this.tokens.splice(-2, 1);
125
+ } else {
126
+ this.tag(1, 'PROPERTY_ACCESS');
127
+ }
128
+ }
129
+ tag = 'IDENTIFIER';
130
+ if (KEYWORDS.indexOf(id) >= 0 && !((ACCESSORS.indexOf(this.tag()) >= 0) && !this.prev().spaced)) {
131
+ tag = id.toUpperCase();
132
+ }
133
+ if (RESERVED.indexOf(id) >= 0) {
134
+ throw new Error('SyntaxError: Reserved word "' + id + '" on line ' + this.line);
135
+ }
136
+ if (tag === 'WHEN' && BEFORE_WHEN.indexOf(this.tag()) >= 0) {
137
+ tag = 'LEADING_WHEN';
138
+ }
139
+ this.token(tag, id);
140
+ this.i += id.length;
141
+ return true;
142
+ };
143
+ // Matches numbers, including decimals, hex, and exponential notation.
144
+ lex.prototype.number_token = function number_token() {
145
+ var number;
146
+ if (!((number = this.match(NUMBER, 1)))) {
147
+ return false;
148
+ }
149
+ this.token('NUMBER', number);
150
+ this.i += number.length;
151
+ return true;
152
+ };
153
+ // Matches strings, including multi-line strings.
154
+ lex.prototype.string_token = function string_token() {
155
+ var escaped, string;
156
+ if (!((string = this.match(STRING, 1)))) {
157
+ return false;
158
+ }
159
+ escaped = string.replace(STRING_NEWLINES, " \\\n");
160
+ this.token('STRING', escaped);
161
+ this.line += this.count(string, "\n");
162
+ this.i += string.length;
163
+ return true;
164
+ };
165
+ // Matches heredocs, adjusting indentation to the correct level.
166
+ lex.prototype.heredoc_token = function heredoc_token() {
167
+ var doc, indent, match;
168
+ if (!((match = this.chunk.match(HEREDOC)))) {
169
+ return false;
170
+ }
171
+ doc = match[2] || match[4];
172
+ indent = (doc.match(HEREDOC_INDENT) || ['']).sort()[0];
173
+ doc = doc.replace(new RegExp("^" + indent, 'gm'), '').replace(MULTILINER, "\\n").replace('"', '\\"');
174
+ this.token('STRING', '"' + doc + '"');
175
+ this.line += this.count(match[1], "\n");
176
+ this.i += match[1].length;
177
+ return true;
178
+ };
179
+ // Matches interpolated JavaScript.
180
+ lex.prototype.js_token = function js_token() {
181
+ var script;
182
+ if (!((script = this.match(JS, 1)))) {
183
+ return false;
184
+ }
185
+ this.token('JS', script.replace(JS_CLEANER, ''));
186
+ this.i += script.length;
187
+ return true;
188
+ };
189
+ // Matches regular expression literals.
190
+ lex.prototype.regex_token = function regex_token() {
191
+ var regex;
192
+ if (!((regex = this.match(REGEX, 1)))) {
193
+ return false;
194
+ }
195
+ if (NOT_REGEX.indexOf(this.tag()) >= 0) {
196
+ return false;
197
+ }
198
+ this.token('REGEX', regex);
199
+ this.i += regex.length;
200
+ return true;
201
+ };
202
+ // Matches and conumes comments.
203
+ lex.prototype.comment_token = function comment_token() {
204
+ var comment;
205
+ if (!((comment = this.match(COMMENT, 1)))) {
206
+ return false;
207
+ }
208
+ this.line += (comment.match(MULTILINER) || []).length;
209
+ this.token('COMMENT', comment.replace(COMMENT_CLEANER, '').split(MULTILINER));
210
+ this.token('TERMINATOR', "\n");
211
+ this.i += comment.length;
212
+ return true;
213
+ };
214
+ // Record tokens for indentation differing from the previous line.
215
+ lex.prototype.indent_token = function indent_token() {
216
+ var diff, indent, next_character, no_newlines, prev, size;
217
+ if (!((indent = this.match(MULTI_DENT, 1)))) {
218
+ return false;
219
+ }
220
+ this.line += indent.match(MULTILINER).length;
221
+ this.i += indent.length;
222
+ next_character = this.chunk.match(MULTI_DENT)[4];
223
+ prev = this.prev(2);
224
+ no_newlines = next_character === '.' || (this.value() && this.value().match(NO_NEWLINE) && prev && (prev[0] !== '.') && !this.value().match(CODE));
225
+ if (no_newlines) {
226
+ return this.suppress_newlines(indent);
227
+ }
228
+ size = indent.match(LAST_DENTS).reverse()[0].match(LAST_DENT)[1].length;
229
+ if (size === this.indent) {
230
+ return this.newline_token(indent);
231
+ }
232
+ if (size > this.indent) {
233
+ diff = size - this.indent;
234
+ this.token('INDENT', diff);
235
+ this.indents.push(diff);
236
+ } else {
237
+ this.outdent_token(this.indent - size);
238
+ }
239
+ this.indent = size;
240
+ return true;
241
+ };
242
+ // Record an oudent token or tokens, if we're moving back inwards past
243
+ // multiple recorded indents.
244
+ lex.prototype.outdent_token = function outdent_token(move_out) {
245
+ var last_indent;
246
+ while (move_out > 0 && this.indents.length) {
247
+ last_indent = this.indents.pop();
248
+ this.token('OUTDENT', last_indent);
249
+ move_out -= last_indent;
250
+ }
251
+ if (!(this.tag() === 'TERMINATOR')) {
252
+ this.token('TERMINATOR', "\n");
253
+ }
254
+ return true;
255
+ };
256
+ // Matches and consumes non-meaningful whitespace.
257
+ lex.prototype.whitespace_token = function whitespace_token() {
258
+ var prev, space;
259
+ if (!((space = this.match(WHITESPACE, 1)))) {
260
+ return false;
261
+ }
262
+ prev = this.prev();
263
+ if (prev) {
264
+ prev.spaced = true;
265
+ }
266
+ this.i += space.length;
267
+ return true;
268
+ };
269
+ // Multiple newlines get merged together.
270
+ // Use a trailing \ to escape newlines.
271
+ lex.prototype.newline_token = function newline_token(newlines) {
272
+ if (!(this.tag() === 'TERMINATOR')) {
273
+ this.token('TERMINATOR', "\n");
274
+ }
275
+ return true;
276
+ };
277
+ // Tokens to explicitly escape newlines are removed once their job is done.
278
+ lex.prototype.suppress_newlines = function suppress_newlines(newlines) {
279
+ if (this.value() === "\\") {
280
+ this.tokens.pop();
281
+ }
282
+ return true;
283
+ };
284
+ // We treat all other single characters as a token. Eg.: ( ) , . !
285
+ // Multi-character operators are also literal tokens, so that Racc can assign
286
+ // the proper order of operations.
287
+ lex.prototype.literal_token = function literal_token() {
288
+ var match, not_spaced, tag, value;
289
+ match = this.chunk.match(OPERATOR);
290
+ value = match && match[1];
291
+ if (value && value.match(CODE)) {
292
+ this.tag_parameters();
293
+ }
294
+ value = value || this.chunk.substr(0, 1);
295
+ not_spaced = !this.prev() || !this.prev().spaced;
296
+ tag = value;
297
+ if (value.match(ASSIGNMENT)) {
298
+ tag = 'ASSIGN';
299
+ if (JS_FORBIDDEN.indexOf(this.value()) >= 0) {
300
+ throw new Error('SyntaxError: Reserved word "' + this.value() + '" on line ' + this.line + ' can\'t be assigned');
301
+ }
302
+ } else if (value === ';') {
303
+ tag = 'TERMINATOR';
304
+ } else if (value === '[' && this.tag() === '?' && not_spaced) {
305
+ tag = 'SOAKED_INDEX_START';
306
+ this.soaked_index = true;
307
+ this.tokens.pop();
308
+ } else if (value === ']' && this.soaked_index) {
309
+ tag = 'SOAKED_INDEX_END';
310
+ this.soaked_index = false;
311
+ } else if (CALLABLE.indexOf(this.tag()) >= 0 && not_spaced) {
312
+ if (value === '(') {
313
+ tag = 'CALL_START';
314
+ }
315
+ if (value === '[') {
316
+ tag = 'INDEX_START';
317
+ }
318
+ }
319
+ this.token(tag, value);
320
+ this.i += value.length;
321
+ return true;
322
+ };
323
+ // Helpers =============================================================
324
+ // Add a token to the results, taking note of the line number.
325
+ lex.prototype.token = function token(tag, value) {
326
+ return this.tokens.push([tag, value, this.line]);
327
+ };
328
+ // Look at a tag in the current token stream.
329
+ lex.prototype.tag = function tag(index, tag) {
330
+ var tok;
331
+ if (!((tok = this.prev(index)))) {
332
+ return null;
333
+ }
334
+ if ((typeof tag !== "undefined" && tag !== null)) {
335
+ return (tok[0] = tag);
336
+ }
337
+ return tok[0];
338
+ };
339
+ // Look at a value in the current token stream.
340
+ lex.prototype.value = function value(index, val) {
341
+ var tok;
342
+ if (!((tok = this.prev(index)))) {
343
+ return null;
344
+ }
345
+ if ((typeof val !== "undefined" && val !== null)) {
346
+ return (tok[1] = val);
347
+ }
348
+ return tok[1];
349
+ };
350
+ // Look at a previous token.
351
+ lex.prototype.prev = function prev(index) {
352
+ return this.tokens[this.tokens.length - (index || 1)];
353
+ };
354
+ // Count the occurences of a character in a string.
355
+ lex.prototype.count = function count(string, letter) {
356
+ var num, pos;
357
+ num = 0;
358
+ pos = string.indexOf(letter);
359
+ while (pos !== -1) {
360
+ num += 1;
361
+ pos = string.indexOf(letter, pos + 1);
362
+ }
363
+ return num;
364
+ };
365
+ // Attempt to match a string against the current chunk, returning the indexed
366
+ // match.
367
+ lex.prototype.match = function match(regex, index) {
368
+ var m;
369
+ if (!((m = this.chunk.match(regex)))) {
370
+ return false;
371
+ }
372
+ return m ? m[index] : false;
373
+ };
374
+ // A source of ambiguity in our grammar was parameter lists in function
375
+ // definitions (as opposed to argument lists in function calls). Tag
376
+ // parameter identifiers in order to avoid this. Also, parameter lists can
377
+ // make use of splats.
378
+ lex.prototype.tag_parameters = function tag_parameters() {
379
+ var _a, i, tok;
380
+ if (this.tag() !== ')') {
381
+ return null;
382
+ }
383
+ i = 0;
384
+ while (true) {
385
+ i += 1;
386
+ tok = this.prev(i);
387
+ if (!tok) {
388
+ return null;
389
+ }
390
+ if ((_a = tok[0]) === 'IDENTIFIER') {
391
+ tok[0] = 'PARAM';
392
+ } else if (_a === ')') {
393
+ tok[0] = 'PARAM_END';
394
+ } else if (_a === '(') {
395
+ return (tok[0] = 'PARAM_START');
396
+ }
397
+ }
398
+ return true;
399
+ };
400
+ // Close up all remaining open blocks. IF the first token is an indent,
401
+ // axe it.
402
+ lex.prototype.close_indentation = function close_indentation() {
403
+ return this.outdent_token(this.indent);
404
+ };
405
+ })();
@@ -0,0 +1,44 @@
1
+ (function(){
2
+ var coffee, factories, file, loader, os, puts;
3
+ // The Narwhal-compatibility wrapper for CoffeeScript.
4
+ // Require external dependencies.
5
+ os = require('os');
6
+ file = require('file');
7
+ coffee = require('./coffee-script');
8
+ // Alias print to "puts", for Node.js compatibility:
9
+ puts = print;
10
+ // Compile a string of CoffeeScript into JavaScript.
11
+ exports.compile = function compile(source) {
12
+ return coffee.compile(source);
13
+ };
14
+ // Compile a given CoffeeScript file into JavaScript.
15
+ exports.compileFile = function compileFile(path) {
16
+ return coffee.compile(file.read(path));
17
+ };
18
+ // Make a factory for the CoffeeScript environment.
19
+ exports.makeNarwhalFactory = function makeNarwhalFactory(path) {
20
+ var code, factoryText;
21
+ code = exports.compileFile(path);
22
+ factoryText = "function(require,exports,module,system,print){" + code + "/**/\n}";
23
+ if (system.engine === "rhino") {
24
+ return Packages.org.mozilla.javascript.Context.getCurrentContext().compileFunction(global, factoryText, path, 0, null);
25
+ } else {
26
+ // eval requires parentheses, but parentheses break compileFunction.
27
+ return eval("(" + factoryText + ")");
28
+ }
29
+ };
30
+ // The Narwhal loader for '.coffee' files.
31
+ factories = {};
32
+ loader = {};
33
+ // Reload the coffee-script environment from source.
34
+ loader.reload = function reload(topId, path) {
35
+ return factories[topId] = function() {
36
+ return exports.makeNarwhalFactory(path);
37
+ };
38
+ };
39
+ // Ensure that the coffee-script environment is loaded.
40
+ loader.load = function load(topId, path) {
41
+ return factories[topId] = factories[topId] || this.reload(topId, path);
42
+ };
43
+ require.loader.loaders.unshift([".coffee", loader]);
44
+ })();