hamlit 1.7.2 → 2.0.1

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 (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