hamlit 1.7.2 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (283) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -3
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +25 -37
  5. data/CHANGELOG.md +18 -0
  6. data/Gemfile +16 -0
  7. data/LICENSE.txt +23 -2
  8. data/README.md +106 -48
  9. data/REFERENCE.md +222 -0
  10. data/Rakefile +77 -19
  11. data/benchmark/boolean_attribute.haml +6 -0
  12. data/benchmark/class_attribute.haml +5 -0
  13. data/benchmark/common_attribute.haml +3 -0
  14. data/benchmark/data_attribute.haml +4 -0
  15. data/benchmark/dynamic_attributes/boolean_attribute.haml +4 -0
  16. data/benchmark/dynamic_attributes/class_attribute.haml +4 -0
  17. data/benchmark/dynamic_attributes/common_attribute.haml +2 -0
  18. data/benchmark/dynamic_attributes/data_attribute.haml +2 -0
  19. data/benchmark/dynamic_attributes/id_attribute.haml +2 -0
  20. data/benchmark/etc/attribute_builder.haml +5 -0
  21. data/benchmark/etc/real_sample.haml +888 -0
  22. data/benchmark/etc/real_sample.rb +11 -0
  23. data/benchmark/etc/static_analyzer.haml +1 -0
  24. data/benchmark/etc/tags.haml +3 -0
  25. data/benchmark/ext/build_data.rb +15 -0
  26. data/benchmark/ext/build_id.rb +13 -0
  27. data/benchmark/id_attribute.haml +3 -0
  28. data/benchmark/plain.haml +4 -0
  29. data/benchmark/script.haml +4 -0
  30. data/benchmark/slim/LICENSE +21 -0
  31. data/{benchmarks → benchmark/slim}/context.rb +2 -4
  32. data/benchmark/slim/run-benchmarks.rb +94 -0
  33. data/{benchmarks → benchmark/slim}/view.erb +3 -3
  34. data/{benchmarks → benchmark/slim}/view.haml +0 -0
  35. data/{benchmarks/view.escaped.slim → benchmark/slim/view.slim} +1 -1
  36. data/benchmark/string_interpolation.haml +2 -0
  37. data/benchmark/utils/benchmark_ips_extension.rb +43 -0
  38. data/bin/bench +85 -0
  39. data/bin/clone +14 -0
  40. data/bin/console +11 -0
  41. data/bin/lineprof +48 -0
  42. data/bin/ruby +3 -0
  43. data/bin/setup +7 -0
  44. data/bin/stackprof +27 -0
  45. data/{test → bin/test} +6 -10
  46. data/{bin → exe}/hamlit +0 -0
  47. data/ext/hamlit/extconf.rb +14 -0
  48. data/ext/hamlit/hamlit.c +512 -0
  49. data/ext/hamlit/houdini/.gitignore +3 -0
  50. data/ext/hamlit/houdini/COPYING +7 -0
  51. data/ext/hamlit/houdini/Makefile +79 -0
  52. data/ext/hamlit/houdini/README.md +59 -0
  53. data/ext/hamlit/houdini/buffer.c +249 -0
  54. data/ext/hamlit/houdini/buffer.h +113 -0
  55. data/ext/hamlit/houdini/houdini.h +46 -0
  56. data/ext/hamlit/houdini/houdini_href_e.c +115 -0
  57. data/ext/hamlit/houdini/houdini_html_e.c +90 -0
  58. data/ext/hamlit/houdini/houdini_html_u.c +122 -0
  59. data/ext/hamlit/houdini/houdini_js_e.c +90 -0
  60. data/ext/hamlit/houdini/houdini_js_u.c +60 -0
  61. data/ext/hamlit/houdini/houdini_uri_e.c +107 -0
  62. data/ext/hamlit/houdini/houdini_uri_u.c +68 -0
  63. data/ext/hamlit/houdini/houdini_xml_e.c +136 -0
  64. data/ext/hamlit/houdini/html_unescape.gperf +258 -0
  65. data/ext/hamlit/houdini/html_unescape.h +754 -0
  66. data/ext/hamlit/houdini/tools/build_table.py +13 -0
  67. data/ext/hamlit/houdini/tools/build_tables.c +51 -0
  68. data/ext/hamlit/houdini/tools/wikipedia_table.txt +2025 -0
  69. data/hamlit.gemspec +30 -31
  70. data/lib/hamlit.rb +3 -1
  71. data/lib/hamlit/attribute_builder.rb +12 -0
  72. data/lib/hamlit/cli.rb +44 -43
  73. data/lib/hamlit/compiler.rb +92 -16
  74. data/lib/hamlit/compiler/attribute_compiler.rb +148 -0
  75. data/lib/hamlit/compiler/children_compiler.rb +111 -0
  76. data/lib/hamlit/compiler/comment_compiler.rb +36 -0
  77. data/lib/hamlit/compiler/doctype_compiler.rb +45 -0
  78. data/lib/hamlit/compiler/script_compiler.rb +97 -0
  79. data/lib/hamlit/compiler/silent_script_compiler.rb +24 -0
  80. data/lib/hamlit/compiler/tag_compiler.rb +69 -0
  81. data/lib/hamlit/engine.rb +12 -7
  82. data/lib/hamlit/error.rb +14 -0
  83. data/lib/hamlit/escapable.rb +12 -0
  84. data/lib/hamlit/filters.rb +65 -0
  85. data/lib/hamlit/filters/base.rb +4 -62
  86. data/lib/hamlit/filters/coffee.rb +9 -7
  87. data/lib/hamlit/filters/css.rb +25 -8
  88. data/lib/hamlit/filters/erb.rb +4 -6
  89. data/lib/hamlit/filters/escaped.rb +11 -9
  90. data/lib/hamlit/filters/javascript.rb +25 -8
  91. data/lib/hamlit/filters/less.rb +9 -7
  92. data/lib/hamlit/filters/markdown.rb +5 -6
  93. data/lib/hamlit/filters/plain.rb +11 -15
  94. data/lib/hamlit/filters/preserve.rb +15 -5
  95. data/lib/hamlit/filters/ruby.rb +3 -5
  96. data/lib/hamlit/filters/sass.rb +9 -7
  97. data/lib/hamlit/filters/scss.rb +9 -7
  98. data/lib/hamlit/filters/text_base.rb +24 -0
  99. data/lib/hamlit/filters/tilt_base.rb +47 -0
  100. data/lib/hamlit/hash_parser.rb +107 -0
  101. data/lib/hamlit/html.rb +9 -6
  102. data/lib/hamlit/identity.rb +12 -0
  103. data/lib/hamlit/object_ref.rb +29 -0
  104. data/lib/hamlit/parser.rb +25 -142
  105. data/lib/hamlit/parser/MIT-LICENSE +20 -0
  106. data/lib/hamlit/parser/README.md +28 -0
  107. data/lib/hamlit/parser/haml_buffer.rb +348 -0
  108. data/lib/hamlit/parser/haml_compiler.rb +553 -0
  109. data/lib/hamlit/parser/haml_error.rb +61 -0
  110. data/lib/hamlit/parser/haml_helpers.rb +727 -0
  111. data/lib/hamlit/parser/haml_options.rb +286 -0
  112. data/lib/hamlit/parser/haml_parser.rb +801 -0
  113. data/lib/hamlit/parser/haml_util.rb +283 -0
  114. data/lib/hamlit/parser/haml_xss_mods.rb +109 -0
  115. data/lib/hamlit/{helpers.rb → rails_helpers.rb} +2 -7
  116. data/lib/hamlit/rails_template.rb +30 -0
  117. data/lib/hamlit/railtie.rb +1 -12
  118. data/lib/hamlit/ruby_expression.rb +31 -0
  119. data/lib/hamlit/static_analyzer.rb +49 -0
  120. data/lib/hamlit/string_interpolation.rb +69 -0
  121. data/lib/hamlit/template.rb +8 -0
  122. data/lib/hamlit/utils.rb +9 -0
  123. data/lib/hamlit/version.rb +1 -1
  124. metadata +116 -324
  125. data/.rspec +0 -2
  126. data/benchmarks/benchmark.rb +0 -110
  127. data/benchmarks/view.slim +0 -17
  128. data/doc/README.md +0 -19
  129. data/doc/engine/indent.md +0 -48
  130. data/doc/engine/new_attribute.md +0 -77
  131. data/doc/engine/old_attributes.md +0 -198
  132. data/doc/engine/silent_script.md +0 -97
  133. data/doc/engine/tag.md +0 -48
  134. data/doc/engine/text.md +0 -64
  135. data/doc/faml/README.md +0 -16
  136. data/doc/faml/engine/indent.md +0 -48
  137. data/doc/faml/engine/old_attributes.md +0 -111
  138. data/doc/faml/engine/silent_script.md +0 -97
  139. data/doc/faml/engine/text.md +0 -59
  140. data/doc/faml/filters/erb.md +0 -24
  141. data/doc/faml/filters/javascript.md +0 -27
  142. data/doc/faml/filters/less.md +0 -57
  143. data/doc/faml/filters/plain.md +0 -25
  144. data/doc/filters/erb.md +0 -31
  145. data/doc/filters/javascript.md +0 -83
  146. data/doc/filters/less.md +0 -57
  147. data/doc/filters/markdown.md +0 -31
  148. data/doc/filters/plain.md +0 -25
  149. data/doc/haml/README.md +0 -15
  150. data/doc/haml/engine/new_attribute.md +0 -77
  151. data/doc/haml/engine/old_attributes.md +0 -142
  152. data/doc/haml/engine/tag.md +0 -48
  153. data/doc/haml/engine/text.md +0 -29
  154. data/doc/haml/filters/erb.md +0 -26
  155. data/doc/haml/filters/javascript.md +0 -76
  156. data/doc/haml/filters/markdown.md +0 -31
  157. data/lib/hamlit/attribute.rb +0 -78
  158. data/lib/hamlit/compilers/attributes.rb +0 -108
  159. data/lib/hamlit/compilers/comment.rb +0 -13
  160. data/lib/hamlit/compilers/doctype.rb +0 -39
  161. data/lib/hamlit/compilers/filter.rb +0 -53
  162. data/lib/hamlit/compilers/new_attribute.rb +0 -115
  163. data/lib/hamlit/compilers/old_attribute.rb +0 -241
  164. data/lib/hamlit/compilers/runtime_attribute.rb +0 -58
  165. data/lib/hamlit/compilers/script.rb +0 -31
  166. data/lib/hamlit/compilers/strip.rb +0 -19
  167. data/lib/hamlit/compilers/text.rb +0 -111
  168. data/lib/hamlit/concerns/attribute_builder.rb +0 -22
  169. data/lib/hamlit/concerns/balanceable.rb +0 -68
  170. data/lib/hamlit/concerns/deprecation.rb +0 -20
  171. data/lib/hamlit/concerns/error.rb +0 -31
  172. data/lib/hamlit/concerns/escapable.rb +0 -17
  173. data/lib/hamlit/concerns/included.rb +0 -28
  174. data/lib/hamlit/concerns/indentable.rb +0 -117
  175. data/lib/hamlit/concerns/lexable.rb +0 -32
  176. data/lib/hamlit/concerns/line_reader.rb +0 -62
  177. data/lib/hamlit/concerns/registerable.rb +0 -24
  178. data/lib/hamlit/concerns/string_interpolation.rb +0 -48
  179. data/lib/hamlit/concerns/whitespace.rb +0 -91
  180. data/lib/hamlit/filters/tilt.rb +0 -41
  181. data/lib/hamlit/parsers/attribute.rb +0 -71
  182. data/lib/hamlit/parsers/comment.rb +0 -30
  183. data/lib/hamlit/parsers/doctype.rb +0 -18
  184. data/lib/hamlit/parsers/filter.rb +0 -18
  185. data/lib/hamlit/parsers/multiline.rb +0 -58
  186. data/lib/hamlit/parsers/script.rb +0 -126
  187. data/lib/hamlit/parsers/tag.rb +0 -83
  188. data/lib/hamlit/parsers/text.rb +0 -28
  189. data/lib/hamlit/temple.rb +0 -9
  190. data/release +0 -6
  191. data/spec/Rakefile +0 -72
  192. data/spec/hamlit/engine/comment_spec.rb +0 -56
  193. data/spec/hamlit/engine/doctype_spec.rb +0 -19
  194. data/spec/hamlit/engine/error_spec.rb +0 -135
  195. data/spec/hamlit/engine/indent_spec.rb +0 -42
  196. data/spec/hamlit/engine/multiline_spec.rb +0 -44
  197. data/spec/hamlit/engine/new_attribute_spec.rb +0 -110
  198. data/spec/hamlit/engine/old_attributes_spec.rb +0 -404
  199. data/spec/hamlit/engine/script_spec.rb +0 -116
  200. data/spec/hamlit/engine/silent_script_spec.rb +0 -213
  201. data/spec/hamlit/engine/tag_spec.rb +0 -295
  202. data/spec/hamlit/engine/text_spec.rb +0 -239
  203. data/spec/hamlit/engine_spec.rb +0 -58
  204. data/spec/hamlit/filters/coffee_spec.rb +0 -60
  205. data/spec/hamlit/filters/css_spec.rb +0 -33
  206. data/spec/hamlit/filters/erb_spec.rb +0 -16
  207. data/spec/hamlit/filters/javascript_spec.rb +0 -82
  208. data/spec/hamlit/filters/less_spec.rb +0 -37
  209. data/spec/hamlit/filters/markdown_spec.rb +0 -30
  210. data/spec/hamlit/filters/plain_spec.rb +0 -15
  211. data/spec/hamlit/filters/ruby_spec.rb +0 -24
  212. data/spec/hamlit/filters/sass_spec.rb +0 -33
  213. data/spec/hamlit/filters/scss_spec.rb +0 -37
  214. data/spec/hamlit/haml_spec.rb +0 -910
  215. data/spec/rails/.gitignore +0 -18
  216. data/spec/rails/.rspec +0 -2
  217. data/spec/rails/Gemfile +0 -19
  218. data/spec/rails/README.rdoc +0 -28
  219. data/spec/rails/Rakefile +0 -6
  220. data/spec/rails/app/assets/images/.keep +0 -0
  221. data/spec/rails/app/assets/javascripts/application.js +0 -15
  222. data/spec/rails/app/assets/stylesheets/application.css +0 -15
  223. data/spec/rails/app/controllers/application_controller.rb +0 -8
  224. data/spec/rails/app/controllers/concerns/.keep +0 -0
  225. data/spec/rails/app/controllers/users_controller.rb +0 -23
  226. data/spec/rails/app/helpers/application_helper.rb +0 -2
  227. data/spec/rails/app/mailers/.keep +0 -0
  228. data/spec/rails/app/models/.keep +0 -0
  229. data/spec/rails/app/models/concerns/.keep +0 -0
  230. data/spec/rails/app/views/application/index.html.haml +0 -18
  231. data/spec/rails/app/views/layouts/application.html.haml +0 -12
  232. data/spec/rails/app/views/users/capture.html.haml +0 -5
  233. data/spec/rails/app/views/users/capture_haml.html.haml +0 -5
  234. data/spec/rails/app/views/users/form.html.haml +0 -2
  235. data/spec/rails/app/views/users/helpers.html.haml +0 -10
  236. data/spec/rails/app/views/users/index.html.haml +0 -9
  237. data/spec/rails/app/views/users/inline.html.haml +0 -6
  238. data/spec/rails/app/views/users/old_attributes.html.haml +0 -5
  239. data/spec/rails/app/views/users/safe_buffer.html.haml +0 -4
  240. data/spec/rails/app/views/users/whitespace.html.haml +0 -4
  241. data/spec/rails/bin/bundle +0 -3
  242. data/spec/rails/bin/rails +0 -8
  243. data/spec/rails/bin/rake +0 -8
  244. data/spec/rails/bin/setup +0 -29
  245. data/spec/rails/bin/spring +0 -15
  246. data/spec/rails/config.ru +0 -4
  247. data/spec/rails/config/application.rb +0 -34
  248. data/spec/rails/config/boot.rb +0 -3
  249. data/spec/rails/config/database.yml +0 -25
  250. data/spec/rails/config/environment.rb +0 -5
  251. data/spec/rails/config/environments/development.rb +0 -41
  252. data/spec/rails/config/environments/production.rb +0 -79
  253. data/spec/rails/config/environments/test.rb +0 -42
  254. data/spec/rails/config/initializers/assets.rb +0 -11
  255. data/spec/rails/config/initializers/backtrace_silencers.rb +0 -7
  256. data/spec/rails/config/initializers/cookies_serializer.rb +0 -3
  257. data/spec/rails/config/initializers/filter_parameter_logging.rb +0 -4
  258. data/spec/rails/config/initializers/inflections.rb +0 -16
  259. data/spec/rails/config/initializers/mime_types.rb +0 -4
  260. data/spec/rails/config/initializers/session_store.rb +0 -3
  261. data/spec/rails/config/initializers/wrap_parameters.rb +0 -14
  262. data/spec/rails/config/locales/en.yml +0 -24
  263. data/spec/rails/config/routes.rb +0 -16
  264. data/spec/rails/config/secrets.yml +0 -22
  265. data/spec/rails/db/schema.rb +0 -16
  266. data/spec/rails/db/seeds.rb +0 -7
  267. data/spec/rails/lib/assets/.keep +0 -0
  268. data/spec/rails/lib/tasks/.keep +0 -0
  269. data/spec/rails/log/.keep +0 -0
  270. data/spec/rails/public/404.html +0 -67
  271. data/spec/rails/public/422.html +0 -67
  272. data/spec/rails/public/500.html +0 -66
  273. data/spec/rails/public/favicon.ico +0 -0
  274. data/spec/rails/public/robots.txt +0 -5
  275. data/spec/rails/spec/hamlit_spec.rb +0 -123
  276. data/spec/rails/spec/rails_helper.rb +0 -56
  277. data/spec/rails/spec/spec_helper.rb +0 -91
  278. data/spec/rails/vendor/assets/javascripts/.keep +0 -0
  279. data/spec/rails/vendor/assets/stylesheets/.keep +0 -0
  280. data/spec/spec_helper.rb +0 -36
  281. data/spec/spec_helper/document_generator.rb +0 -93
  282. data/spec/spec_helper/render_helper.rb +0 -120
  283. data/spec/spec_helper/test_case.rb +0 -55
data/hamlit.gemspec CHANGED
@@ -4,40 +4,39 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'hamlit/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "hamlit"
7
+ spec.name = 'hamlit'
8
8
  spec.version = Hamlit::VERSION
9
- spec.authors = ["Takashi Kokubun"]
10
- spec.email = ["takashikkbn@gmail.com"]
9
+ spec.authors = ['Takashi Kokubun']
10
+ spec.email = ['takashikkbn@gmail.com']
11
+
11
12
  spec.summary = %q{High Performance Haml Implementation}
12
13
  spec.description = %q{High Performance Haml Implementation}
13
- spec.homepage = "https://github.com/k0kubun/hamlit"
14
- spec.license = "MIT"
14
+ spec.homepage = 'https://github.com/k0kubun/hamlit'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|hamlit1|sample)/}) } + `git -C ext/hamlit/houdini ls-files -z`.split("\x0").map { |path| "ext/hamlit/houdini/#{path}" }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.extensions = ['ext/hamlit/extconf.rb']
21
+ spec.require_paths = ['lib']
15
22
 
16
- spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
- spec.required_ruby_version = ">= 2.0.0"
23
+ spec.add_dependency 'escape_utils'
24
+ spec.add_dependency 'temple', '~> 0.7.6'
25
+ spec.add_dependency 'thor'
26
+ spec.add_dependency 'tilt'
21
27
 
22
- spec.add_dependency "escape_utils"
23
- spec.add_dependency "temple", "~> 0.7.6"
24
- spec.add_dependency "thor"
25
- spec.add_dependency "tilt"
26
- spec.add_development_dependency "benchmark-ips"
27
- spec.add_development_dependency "bundler"
28
- spec.add_development_dependency "coffee-script"
29
- spec.add_development_dependency "coveralls"
30
- spec.add_development_dependency "erubis"
31
- spec.add_development_dependency "faml"
32
- spec.add_development_dependency "haml"
33
- spec.add_development_dependency "less"
34
- spec.add_development_dependency "pry"
35
- spec.add_development_dependency "rake"
36
- spec.add_development_dependency "redcarpet"
37
- spec.add_development_dependency "rspec", ">= 3"
38
- spec.add_development_dependency "sass"
39
- spec.add_development_dependency "simplecov"
40
- spec.add_development_dependency "slim"
41
- spec.add_development_dependency "therubyracer"
42
- spec.add_development_dependency "unindent"
28
+ spec.add_development_dependency 'bundler'
29
+ spec.add_development_dependency 'coffee-script'
30
+ spec.add_development_dependency 'erubis'
31
+ spec.add_development_dependency 'faml'
32
+ spec.add_development_dependency 'less'
33
+ spec.add_development_dependency 'minitest-reporters', '~> 1.1'
34
+ spec.add_development_dependency 'rails', '>= 4.0.0'
35
+ spec.add_development_dependency 'rake', '~> 10.0'
36
+ spec.add_development_dependency 'rake-compiler'
37
+ spec.add_development_dependency 'redcarpet'
38
+ spec.add_development_dependency 'sass'
39
+ spec.add_development_dependency 'slim'
40
+ spec.add_development_dependency 'therubyracer'
41
+ spec.add_development_dependency 'unindent'
43
42
  end
data/lib/hamlit.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  require 'hamlit/engine'
2
- require 'hamlit/template'
2
+ require 'hamlit/error'
3
3
  require 'hamlit/version'
4
+ require 'hamlit/template'
4
5
 
5
6
  begin
7
+ require 'rails'
6
8
  require 'hamlit/railtie'
7
9
  rescue LoadError
8
10
  end
@@ -0,0 +1,12 @@
1
+ require 'hamlit/hamlit'
2
+ require 'hamlit/object_ref'
3
+ require 'hamlit/utils'
4
+
5
+ module Hamlit::AttributeBuilder
6
+ BOOLEAN_ATTRIBUTES = %w[disabled readonly multiple checked autobuffer
7
+ autoplay controls loop selected hidden scoped async
8
+ defer reversed ismap seamless muted required
9
+ autofocus novalidate formnovalidate open pubdate
10
+ itemscope allowfullscreen default inert sortable
11
+ truespeed typemustmatch].freeze
12
+ end
data/lib/hamlit/cli.rb CHANGED
@@ -3,80 +3,81 @@ require 'thor'
3
3
 
4
4
  module Hamlit
5
5
  class CLI < Thor
6
- IGNORED_COMPILERS = ['HTML'].freeze
7
-
8
6
  desc 'render HAML', 'Render haml template'
9
7
  def render(file)
10
8
  code = generate_code(file)
11
9
  puts eval(code)
12
10
  end
13
11
 
14
- desc 'compile HAML', 'Show generated rendering code'
12
+ desc 'compile HAML', 'Show compile result'
13
+ option :actionview, type: :boolean, default: false, aliases: %w[-a]
15
14
  def compile(file)
16
- code = generate_code(file)
17
- puts code
15
+ print_code generate_code(file)
18
16
  end
19
17
 
20
- desc 'temple HAML', 'Show a compile result of hamlit AST'
18
+ desc 'temple HAML', 'Show temple intermediate expression'
21
19
  def temple(file)
22
- pp generate_temple_ast(file)
20
+ pp generate_temple(file)
23
21
  end
24
22
 
25
23
  desc 'parse HAML', 'Show parse result'
26
24
  def parse(file)
27
- pp generate_hamlit_ast(file)
25
+ pp generate_ast(file)
28
26
  end
29
27
 
30
28
  private
31
29
 
32
- # Flexible default_task, compatible with haml's CLI
33
- def method_missing(*args)
34
- return super(*args) if args.length > 1
35
-
36
- render(args.first.to_s)
37
- end
38
-
39
30
  def generate_code(file)
40
31
  template = File.read(file)
41
- Hamlit::Engine.new.call(template)
42
- end
43
-
44
- def generate_temple_ast(file)
45
- chain = Hamlit::Engine.chain.map(&:first).map(&:to_s)
46
- compilers = chain.select do |compiler|
47
- compiler =~ /\AHamlit::/ && !ignored_compilers.include?(compiler)
32
+ if options[:actionview]
33
+ require 'action_view'
34
+ require 'action_view/base'
35
+ require 'hamlit/rails_template'
36
+ handler = Hamlit::RailsTemplate.new
37
+ template = ActionView::Template.new(template, 'inline template', handler, { locals: [] })
38
+ code = handler.call(template)
39
+ source = <<-end_src
40
+ def _inline_template___2144273726781623612_70327218547300(local_assigns, output_buffer)
41
+ _old_virtual_path, @virtual_path = @virtual_path, nil;_old_output_buffer = @output_buffer;;#{code}
42
+ ensure
43
+ @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
44
+ end
45
+ end_src
46
+ else
47
+ Hamlit::Engine.new.call(template)
48
48
  end
49
+ end
49
50
 
51
+ def generate_ast(file)
50
52
  template = File.read(file)
51
- compilers.inject(template) do |exp, compiler|
52
- Module.const_get(compiler).new.call(exp)
53
- end
53
+ Hamlit::Parser.new(escape_html: true, escape_attrs: true, ugly: true).call(template)
54
54
  end
55
55
 
56
- def generate_hamlit_ast(file)
57
- template = File.read(file)
58
- Hamlit::Parser.new.call(template)
56
+ def generate_temple(file)
57
+ ast = generate_ast(file)
58
+ Hamlit::Compiler.new.call(ast)
59
59
  end
60
60
 
61
- # Enable colored pretty printing only for development environment.
62
- # I don't think it is a good idea to add pry as runtime dependency
63
- # just for debug color printing.
64
- def pp(arg)
65
- begin
66
- require 'pry'
67
- Pry::ColorPrinter.pp(arg)
68
- rescue LoadError
69
- require 'pp'
70
- super(arg)
71
- end
61
+ # Flexible default_task, compatible with haml's CLI
62
+ def method_missing(*args)
63
+ return super(*args) if args.length > 1
64
+ render(args.first.to_s)
72
65
  end
73
66
 
74
- def ignored_compilers
75
- IGNORED_COMPILERS.map { |name| "Hamlit::#{name}" }
67
+ def print_code(code)
68
+ require 'pry'
69
+ puts Pry.Code(code).highlighted
70
+ rescue LoadError
71
+ puts code
76
72
  end
77
73
 
78
- def symbolize_keys(hash)
79
- {}.tap { |h| hash.each { |k, v| h[k.to_sym] = v } }
74
+ # Enable colored pretty printing only for development environment.
75
+ def pp(arg)
76
+ require 'pry'
77
+ Pry::ColorPrinter.pp(arg)
78
+ rescue LoadError
79
+ require 'pp'
80
+ super(arg)
80
81
  end
81
82
  end
82
83
  end
@@ -1,20 +1,96 @@
1
- require 'hamlit/compilers/attributes'
2
- require 'hamlit/compilers/comment'
3
- require 'hamlit/compilers/doctype'
4
- require 'hamlit/compilers/filter'
5
- require 'hamlit/compilers/script'
6
- require 'hamlit/compilers/strip'
7
- require 'hamlit/compilers/text'
8
- require 'temple/html/filter'
1
+ require 'hamlit/compiler/children_compiler'
2
+ require 'hamlit/compiler/comment_compiler'
3
+ require 'hamlit/compiler/doctype_compiler'
4
+ require 'hamlit/compiler/script_compiler'
5
+ require 'hamlit/compiler/silent_script_compiler'
6
+ require 'hamlit/compiler/tag_compiler'
7
+ require 'hamlit/filters'
8
+ require 'hamlit/identity'
9
9
 
10
10
  module Hamlit
11
- class Compiler < Temple::HTML::Filter
12
- include Compilers::Attributes
13
- include Compilers::Comment
14
- include Compilers::Doctype
15
- include Compilers::Filter
16
- include Compilers::Script
17
- include Compilers::Strip
18
- include Compilers::Text
11
+ class Compiler
12
+ def initialize(options = {})
13
+ identity = Identity.new
14
+ @children_compiler = ChildrenCompiler.new
15
+ @comment_compiler = CommentCompiler.new
16
+ @doctype_compiler = DoctypeCompiler.new(options)
17
+ @filter_compiler = Filters.new(options)
18
+ @script_compiler = ScriptCompiler.new(identity)
19
+ @silent_script_compiler = SilentScriptCompiler.new
20
+ @tag_compiler = TagCompiler.new(identity, options)
21
+ end
22
+
23
+ def call(ast)
24
+ return runtime_error(ast) if ast.is_a?(HamlError)
25
+ compile(ast)
26
+ rescue Error => e
27
+ runtime_error(e)
28
+ end
29
+
30
+ private
31
+
32
+ def compile(node)
33
+ case node.type
34
+ when :root
35
+ compile_children(node)
36
+ when :comment
37
+ compile_comment(node)
38
+ when :doctype
39
+ compile_doctype(node)
40
+ when :filter
41
+ compile_filter(node)
42
+ when :plain
43
+ compile_plain(node)
44
+ when :script
45
+ compile_script(node)
46
+ when :silent_script
47
+ compile_silent_script(node)
48
+ when :tag
49
+ compile_tag(node)
50
+ when :haml_comment
51
+ [:multi]
52
+ else
53
+ raise InternalError.new("Unexpected node type: #{node.type}")
54
+ end
55
+ end
56
+
57
+ def compile_children(node)
58
+ @children_compiler.compile(node) { |n| compile(n) }
59
+ end
60
+
61
+ def compile_comment(node)
62
+ @comment_compiler.compile(node) { |n| compile_children(n) }
63
+ end
64
+
65
+ def compile_doctype(node)
66
+ @doctype_compiler.compile(node)
67
+ end
68
+
69
+ def compile_filter(node)
70
+ @filter_compiler.compile(node)
71
+ end
72
+
73
+ def compile_plain(node)
74
+ [:static, node.value[:text]]
75
+ end
76
+
77
+ def compile_script(node)
78
+ @script_compiler.compile(node) { |n| compile_children(n) }
79
+ end
80
+
81
+ def compile_silent_script(node)
82
+ @silent_script_compiler.compile(node) { |n| compile_children(n) }
83
+ end
84
+
85
+ def compile_tag(node)
86
+ @tag_compiler.compile(node) { |n| compile_children(n) }
87
+ end
88
+
89
+ def runtime_error(error)
90
+ [:multi].tap do |temple|
91
+ error.line.times { temple << [:newline] } if error.line
92
+ temple << [:code, %Q[raise #{error.class}.new(%q[#{error.message}], #{error.line.inspect})]]
93
+ end
94
+ end
19
95
  end
20
96
  end
@@ -0,0 +1,148 @@
1
+ require 'hamlit/attribute_builder'
2
+ require 'hamlit/hash_parser'
3
+ require 'hamlit/ruby_expression'
4
+ require 'hamlit/static_analyzer'
5
+ require 'hamlit/string_interpolation'
6
+
7
+ module Hamlit
8
+ class Compiler
9
+ class AttributeCompiler
10
+ def initialize(identity, options)
11
+ @identity = identity
12
+ @quote = options[:attr_quote]
13
+ @format = options[:format]
14
+ @escape_attrs = options[:escape_attrs]
15
+ end
16
+
17
+ def compile(node)
18
+ hashes = []
19
+ return runtime_compile(node) if node.value[:object_ref] != :nil
20
+ node.value[:attributes_hashes].each do |attribute_str|
21
+ hash = HashParser.parse(attribute_str)
22
+ return runtime_compile(node) unless hash
23
+ hashes << hash
24
+ end
25
+ static_compile(node.value[:attributes], hashes)
26
+ end
27
+
28
+ private
29
+
30
+ def runtime_compile(node)
31
+ attrs = node.value[:attributes_hashes]
32
+ attrs.unshift(node.value[:attributes].inspect) if node.value[:attributes] != {}
33
+
34
+ args = [@escape_attrs, @quote, @format].map(&:inspect).push(node.value[:object_ref]) + attrs
35
+ [:html, :attrs, [:dynamic, "::Hamlit::AttributeBuilder.build(#{args.join(', ')})"]]
36
+ end
37
+
38
+ def static_compile(static_hash, dynamic_hashes)
39
+ temple = [:html, :attrs]
40
+ keys = [*static_hash.keys, *dynamic_hashes.map(&:keys).flatten].uniq.sort
41
+ keys.each do |key|
42
+ values = [[:static, static_hash[key]], *dynamic_hashes.map { |h| [:dynamic, h[key]] }]
43
+ values.select! { |_, exp| exp != nil }
44
+
45
+ case key
46
+ when 'id'.freeze
47
+ compile_id!(temple, key, values)
48
+ when 'class'.freeze
49
+ compile_class!(temple, key, values)
50
+ when 'data'.freeze
51
+ compile_data!(temple, key, values)
52
+ when *AttributeBuilder::BOOLEAN_ATTRIBUTES, /\Adata-/
53
+ compile_boolean!(temple, key, values)
54
+ else
55
+ compile_common!(temple, key, values)
56
+ end
57
+ end
58
+ temple
59
+ end
60
+
61
+ def compile_id!(temple, key, values)
62
+ build_code = attribute_builder(:id, values)
63
+ if values.all? { |type, exp| type == :static || StaticAnalyzer.static?(exp) }
64
+ temple << [:html, :attr, key, [:static, eval(build_code)]]
65
+ else
66
+ temple << [:html, :attr, key, [:dynamic, build_code]]
67
+ end
68
+ end
69
+
70
+ def compile_class!(temple, key, values)
71
+ build_code = attribute_builder(:class, values)
72
+ if values.all? { |type, exp| type == :static || StaticAnalyzer.static?(exp) }
73
+ temple << [:html, :attr, key, [:static, eval(build_code)]]
74
+ else
75
+ temple << [:html, :attr, key, [:dynamic, build_code]]
76
+ end
77
+ end
78
+
79
+ def compile_data!(temple, key, values)
80
+ args = [@escape_attrs.inspect, @quote.inspect, values.map { |v| literal_for(v) }]
81
+ build_code = "::Hamlit::AttributeBuilder.build_data(#{args.join(', ')})"
82
+
83
+ if values.all? { |type, exp| type == :static || StaticAnalyzer.static?(exp) }
84
+ temple << [:static, eval(build_code)]
85
+ else
86
+ temple << [:dynamic, build_code]
87
+ end
88
+ end
89
+
90
+ def compile_boolean!(temple, key, values)
91
+ exp = literal_for(values.last)
92
+
93
+ if StaticAnalyzer.static?(exp)
94
+ value = eval(exp)
95
+ case value
96
+ when true then temple << [:html, :attr, key, @format == :xhtml ? [:static, key] : [:multi]]
97
+ when false, nil
98
+ else temple << [:html, :attr, key, [:escape, @escape_attrs, [:static, value]]]
99
+ end
100
+ else
101
+ var = @identity.generate
102
+ temple << [
103
+ :case, "(#{var} = (#{exp}))",
104
+ ['true', [:html, :attr, key, @format == :xhtml ? [:static, key] : [:multi]]],
105
+ ['false, nil', [:multi]],
106
+ [:else, [:multi, [:static, " #{key}=#{@quote}"], [:escape, @escape_attrs, [:dynamic, var]], [:static, @quote]]],
107
+ ]
108
+ end
109
+ end
110
+
111
+ def compile_common!(temple, key, values)
112
+ type, exp = values.last
113
+
114
+ case
115
+ when type == :dynamic && StaticAnalyzer.static?(exp)
116
+ temple << [:html, :attr, key, [:escape, @escape_attrs, [:static, eval(exp).to_s]]]
117
+ when type == :dynamic && RubyExpression.string_literal?(exp)
118
+ value_temple = [:multi]
119
+ StringInterpolation.compile(exp).each do |type, v|
120
+ case type
121
+ when :static
122
+ value_temple << [:escape, @escape_attrs, [:static, v]]
123
+ when :dynamic
124
+ if Hamlit::StaticAnalyzer.static?(v)
125
+ value_temple << [:escape, @escape_attrs, [:static, eval(v).to_s]]
126
+ else
127
+ value_temple << [:escape, @escape_attrs, [:dynamic, v]]
128
+ end
129
+ end
130
+ end
131
+ temple << [:html, :attr, key, value_temple]
132
+ else
133
+ temple << [:html, :attr, key, [:escape, @escape_attrs, [type, exp]]]
134
+ end
135
+ end
136
+
137
+ def attribute_builder(type, values)
138
+ args = [@escape_attrs.inspect, *values.map { |v| literal_for(v) }]
139
+ "::Hamlit::AttributeBuilder.build_#{type}(#{args.join(', ')})"
140
+ end
141
+
142
+ def literal_for(value)
143
+ type, exp = value
144
+ type == :static ? exp.inspect : exp
145
+ end
146
+ end
147
+ end
148
+ end