super-pro-kit 0.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 (127) hide show
  1. checksums.yaml +7 -0
  2. data/slim-5.2.1/CHANGES +496 -0
  3. data/slim-5.2.1/Gemfile +43 -0
  4. data/slim-5.2.1/LICENSE +21 -0
  5. data/slim-5.2.1/README.jp.md +1276 -0
  6. data/slim-5.2.1/README.md +1313 -0
  7. data/slim-5.2.1/Rakefile +80 -0
  8. data/slim-5.2.1/bin/slimrb +6 -0
  9. data/slim-5.2.1/doc/include.md +20 -0
  10. data/slim-5.2.1/doc/jp/include.md +20 -0
  11. data/slim-5.2.1/doc/jp/logic_less.md +137 -0
  12. data/slim-5.2.1/doc/jp/smart.md +102 -0
  13. data/slim-5.2.1/doc/jp/translator.md +28 -0
  14. data/slim-5.2.1/doc/logic_less.md +137 -0
  15. data/slim-5.2.1/doc/smart.md +120 -0
  16. data/slim-5.2.1/doc/translator.md +28 -0
  17. data/slim-5.2.1/lib/slim/code_attributes.rb +68 -0
  18. data/slim-5.2.1/lib/slim/command.rb +122 -0
  19. data/slim-5.2.1/lib/slim/controls.rb +61 -0
  20. data/slim-5.2.1/lib/slim/do_inserter.rb +34 -0
  21. data/slim-5.2.1/lib/slim/embedded.rb +248 -0
  22. data/slim-5.2.1/lib/slim/end_inserter.rb +63 -0
  23. data/slim-5.2.1/lib/slim/engine.rb +42 -0
  24. data/slim-5.2.1/lib/slim/erb_converter.rb +15 -0
  25. data/slim-5.2.1/lib/slim/filter.rb +31 -0
  26. data/slim-5.2.1/lib/slim/grammar.rb +24 -0
  27. data/slim-5.2.1/lib/slim/include.rb +58 -0
  28. data/slim-5.2.1/lib/slim/interpolation.rb +36 -0
  29. data/slim-5.2.1/lib/slim/logic_less/context.rb +126 -0
  30. data/slim-5.2.1/lib/slim/logic_less/filter.rb +81 -0
  31. data/slim-5.2.1/lib/slim/logic_less.rb +6 -0
  32. data/slim-5.2.1/lib/slim/parser.rb +535 -0
  33. data/slim-5.2.1/lib/slim/railtie.rb +19 -0
  34. data/slim-5.2.1/lib/slim/smart/escaper.rb +42 -0
  35. data/slim-5.2.1/lib/slim/smart/filter.rb +97 -0
  36. data/slim-5.2.1/lib/slim/smart/parser.rb +35 -0
  37. data/slim-5.2.1/lib/slim/smart.rb +9 -0
  38. data/slim-5.2.1/lib/slim/splat/builder.rb +115 -0
  39. data/slim-5.2.1/lib/slim/splat/filter.rb +93 -0
  40. data/slim-5.2.1/lib/slim/template.rb +6 -0
  41. data/slim-5.2.1/lib/slim/translator.rb +119 -0
  42. data/slim-5.2.1/lib/slim/version.rb +6 -0
  43. data/slim-5.2.1/lib/slim.rb +16 -0
  44. data/slim-5.2.1/slim.gemspec +33 -0
  45. data/slim-5.2.1/test/core/helper.rb +201 -0
  46. data/slim-5.2.1/test/core/test_code_blocks.rb +194 -0
  47. data/slim-5.2.1/test/core/test_code_escaping.rb +162 -0
  48. data/slim-5.2.1/test/core/test_code_evaluation.rb +181 -0
  49. data/slim-5.2.1/test/core/test_code_output.rb +168 -0
  50. data/slim-5.2.1/test/core/test_code_structure.rb +203 -0
  51. data/slim-5.2.1/test/core/test_commands.rb +219 -0
  52. data/slim-5.2.1/test/core/test_embedded_engines.rb +247 -0
  53. data/slim-5.2.1/test/core/test_encoding.rb +28 -0
  54. data/slim-5.2.1/test/core/test_erb_converter.rb +65 -0
  55. data/slim-5.2.1/test/core/test_html_attributes.rb +276 -0
  56. data/slim-5.2.1/test/core/test_html_escaping.rb +65 -0
  57. data/slim-5.2.1/test/core/test_html_structure.rb +599 -0
  58. data/slim-5.2.1/test/core/test_parser_errors.rb +148 -0
  59. data/slim-5.2.1/test/core/test_pretty.rb +163 -0
  60. data/slim-5.2.1/test/core/test_ruby_errors.rb +200 -0
  61. data/slim-5.2.1/test/core/test_slim_template.rb +78 -0
  62. data/slim-5.2.1/test/core/test_splat_prefix_option.rb +155 -0
  63. data/slim-5.2.1/test/core/test_tabs.rb +169 -0
  64. data/slim-5.2.1/test/core/test_text_interpolation.rb +79 -0
  65. data/slim-5.2.1/test/core/test_thread_options.rb +18 -0
  66. data/slim-5.2.1/test/core/test_unicode.rb +15 -0
  67. data/slim-5.2.1/test/include/files/recursive.slim +1 -0
  68. data/slim-5.2.1/test/include/files/slimfile.slim +3 -0
  69. data/slim-5.2.1/test/include/files/subdir/test.slim +1 -0
  70. data/slim-5.2.1/test/include/files/textfile +1 -0
  71. data/slim-5.2.1/test/include/test_include.rb +24 -0
  72. data/slim-5.2.1/test/literate/TESTS.md +1323 -0
  73. data/slim-5.2.1/test/literate/helper.rb +15 -0
  74. data/slim-5.2.1/test/literate/run.rb +92 -0
  75. data/slim-5.2.1/test/logic_less/test_logic_less.rb +330 -0
  76. data/slim-5.2.1/test/rails/Rakefile +7 -0
  77. data/slim-5.2.1/test/rails/app/assets/config/manifest.js +1 -0
  78. data/slim-5.2.1/test/rails/app/controllers/application_controller.rb +2 -0
  79. data/slim-5.2.1/test/rails/app/controllers/entries_controller.rb +5 -0
  80. data/slim-5.2.1/test/rails/app/controllers/slim_controller.rb +46 -0
  81. data/slim-5.2.1/test/rails/app/helpers/application_helper.rb +5 -0
  82. data/slim-5.2.1/test/rails/app/models/entry.rb +16 -0
  83. data/slim-5.2.1/test/rails/app/views/entries/edit.html.slim +3 -0
  84. data/slim-5.2.1/test/rails/app/views/layouts/application.html+testvariant.slim +10 -0
  85. data/slim-5.2.1/test/rails/app/views/layouts/application.html.slim +10 -0
  86. data/slim-5.2.1/test/rails/app/views/slim/_partial.html.slim +1 -0
  87. data/slim-5.2.1/test/rails/app/views/slim/attributes.html.slim +3 -0
  88. data/slim-5.2.1/test/rails/app/views/slim/content_for.html.slim +7 -0
  89. data/slim-5.2.1/test/rails/app/views/slim/erb.html.erb +1 -0
  90. data/slim-5.2.1/test/rails/app/views/slim/form_for.html.slim +2 -0
  91. data/slim-5.2.1/test/rails/app/views/slim/helper.html.slim +4 -0
  92. data/slim-5.2.1/test/rails/app/views/slim/integers.html.slim +1 -0
  93. data/slim-5.2.1/test/rails/app/views/slim/no_layout.html.slim +1 -0
  94. data/slim-5.2.1/test/rails/app/views/slim/normal.html.slim +1 -0
  95. data/slim-5.2.1/test/rails/app/views/slim/partial.html.slim +2 -0
  96. data/slim-5.2.1/test/rails/app/views/slim/splat.html.slim +2 -0
  97. data/slim-5.2.1/test/rails/app/views/slim/splat_with_delimiter.slim +1 -0
  98. data/slim-5.2.1/test/rails/app/views/slim/thread_options.html.slim +1 -0
  99. data/slim-5.2.1/test/rails/app/views/slim/variables.html.slim +1 -0
  100. data/slim-5.2.1/test/rails/app/views/slim/xml.slim +1 -0
  101. data/slim-5.2.1/test/rails/config/application.rb +44 -0
  102. data/slim-5.2.1/test/rails/config/boot.rb +10 -0
  103. data/slim-5.2.1/test/rails/config/environment.rb +5 -0
  104. data/slim-5.2.1/test/rails/config/environments/test.rb +34 -0
  105. data/slim-5.2.1/test/rails/config/initializers/backtrace_silencers.rb +7 -0
  106. data/slim-5.2.1/test/rails/config/initializers/inflections.rb +10 -0
  107. data/slim-5.2.1/test/rails/config/initializers/mime_types.rb +5 -0
  108. data/slim-5.2.1/test/rails/config/initializers/session_store.rb +8 -0
  109. data/slim-5.2.1/test/rails/config/locales/en.yml +5 -0
  110. data/slim-5.2.1/test/rails/config/routes.rb +60 -0
  111. data/slim-5.2.1/test/rails/config.ru +4 -0
  112. data/slim-5.2.1/test/rails/script/rails +6 -0
  113. data/slim-5.2.1/test/rails/test/helper.rb +34 -0
  114. data/slim-5.2.1/test/rails/test/test_slim.rb +102 -0
  115. data/slim-5.2.1/test/sinatra/contest.rb +91 -0
  116. data/slim-5.2.1/test/sinatra/helper.rb +143 -0
  117. data/slim-5.2.1/test/sinatra/test_core.rb +91 -0
  118. data/slim-5.2.1/test/sinatra/test_include.rb +16 -0
  119. data/slim-5.2.1/test/sinatra/views/embed_include_js.slim +8 -0
  120. data/slim-5.2.1/test/sinatra/views/embed_js.slim +11 -0
  121. data/slim-5.2.1/test/sinatra/views/footer.slim +1 -0
  122. data/slim-5.2.1/test/sinatra/views/hello.slim +1 -0
  123. data/slim-5.2.1/test/sinatra/views/layout2.slim +3 -0
  124. data/slim-5.2.1/test/smart/test_smart_text.rb +294 -0
  125. data/slim-5.2.1/test/translator/test_translator.rb +76 -0
  126. data/super-pro-kit.gemspec +11 -0
  127. metadata +165 -0
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ module Slim
3
+ module Smart
4
+ # @api private
5
+ class Parser < ::Slim::Parser
6
+ define_options implicit_text: true
7
+
8
+ def initialize(opts = {})
9
+ super
10
+ word_re = options[:implicit_text] ? '[_a-z0-9]' : '\p{Word}'
11
+ attr_keys = Regexp.union(@attr_shortcut.keys.sort_by { |k| -k.size })
12
+ @attr_shortcut_re = /\A(#{attr_keys}+)((?:\p{Word}|-)*)/
13
+ tag_keys = Regexp.union((@tag_shortcut.keys - @attr_shortcut.keys).sort_by { |k| -k.size })
14
+ @tag_re = /\A(?:#{attr_keys}(?=-*\p{Word})|#{tag_keys}|\*(?=[^\s]+)|(#{word_re}(?:#{word_re}|:|-)*#{word_re}|#{word_re}+))/
15
+ end
16
+
17
+ def unknown_line_indicator
18
+ if @line =~ /\A>( ?)/
19
+ # Found explicit text block.
20
+ @stacks.last << [:slim, :text, :explicit, parse_text_block($', @indents.last + $1.size + 1)]
21
+ else
22
+ unless options[:implicit_text]
23
+ syntax_error! 'Illegal shortcut' if @line =~ @attr_shortcut_re
24
+ super
25
+ end
26
+ # Found implicit smart text block.
27
+ if line = @lines.first
28
+ indent = (line =~ /\A\s*\Z/ ? @indents.last + 1 : get_indent(line))
29
+ end
30
+ @stacks.last << [:slim, :text, :implicit, parse_text_block(@line, indent)]
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+ require 'slim'
3
+ require 'slim/smart/filter'
4
+ require 'slim/smart/escaper'
5
+ require 'slim/smart/parser'
6
+
7
+ Slim::Engine.replace Slim::Parser, Slim::Smart::Parser
8
+ Slim::Engine.after Slim::Smart::Parser, Slim::Smart::Filter
9
+ Slim::Engine.after Slim::Interpolation, Slim::Smart::Escaper
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+ module Slim
3
+ class InvalidAttributeNameError < StandardError; end
4
+ module Splat
5
+ # @api private
6
+ class Builder
7
+ # https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
8
+ INVALID_ATTRIBUTE_NAME_REGEX = /[ \0"'>\/=]/
9
+
10
+ def initialize(options)
11
+ @options = options
12
+ @attrs = {}
13
+ end
14
+
15
+ def code_attr(name, escape, value)
16
+ if delim = @options[:merge_attrs][name]
17
+ value = Array === value ? value.join(delim) : value.to_s
18
+ attr(name, escape_html(escape, value)) unless value.empty?
19
+ elsif @options[:hyphen_attrs].include?(name) && Hash === value
20
+ hyphen_attr(name, escape, value)
21
+ elsif value != false && value != nil
22
+ attr(name, escape_html(escape, value))
23
+ end
24
+ end
25
+
26
+ def splat_attrs(splat)
27
+ splat.each do |name, value|
28
+ code_attr(name.to_s, true, value)
29
+ end
30
+ end
31
+
32
+ def attr(name, value)
33
+ if name =~ INVALID_ATTRIBUTE_NAME_REGEX
34
+ raise InvalidAttributeNameError, "Invalid attribute name '#{name}' was rendered"
35
+ end
36
+ if @attrs[name]
37
+ if delim = @options[:merge_attrs][name]
38
+ @attrs[name] = @attrs[name].to_s + delim + value.to_s
39
+ else
40
+ raise("Multiple #{name} attributes specified")
41
+ end
42
+ else
43
+ @attrs[name] = value
44
+ end
45
+ end
46
+
47
+ def build_tag(&block)
48
+ tag = @attrs.delete('tag').to_s
49
+ tag = @options[:default_tag] if tag.empty?
50
+ if block
51
+ # This is a bit of a hack to get a universal capturing.
52
+ #
53
+ # TODO: Add this as a helper somewhere to solve these capturing issues
54
+ # once and for all.
55
+ #
56
+ # If we have Slim capturing disabled and the scope defines the method `capture` (i.e. Rails)
57
+ # we use this method to capture the content.
58
+ #
59
+ # otherwise we just use normal Slim capturing (yield).
60
+ #
61
+ # See https://github.com/slim-template/slim/issues/591
62
+ # https://github.com/slim-template/slim#helpers-capturing-and-includes
63
+ #
64
+ content =
65
+ if @options[:disable_capture] && (scope = block.binding.eval('self')).respond_to?(:capture)
66
+ scope.capture(&block)
67
+ else
68
+ yield
69
+ end
70
+ "<#{tag}#{build_attrs}>#{content}</#{tag}>"
71
+ else
72
+ "<#{tag}#{build_attrs} />"
73
+ end
74
+ end
75
+
76
+ def build_attrs
77
+ attrs = @options[:sort_attrs] ? @attrs.sort_by(&:first) : @attrs
78
+ attrs.map do |k, v|
79
+ if v == true
80
+ if @options[:format] == :xhtml
81
+ " #{k}=#{@options[:attr_quote]}#{@options[:attr_quote]}"
82
+ else
83
+ " #{k}"
84
+ end
85
+ else
86
+ " #{k}=#{@options[:attr_quote]}#{v}#{@options[:attr_quote]}"
87
+ end
88
+ end.join
89
+ end
90
+
91
+ private
92
+
93
+ def hyphen_attr(name, escape, value)
94
+ if Hash === value
95
+ if @options[:hyphen_underscore_attrs]
96
+ value.each do |n, v|
97
+ hyphen_attr("#{name}-#{n.to_s.tr('_', '-')}", escape, v)
98
+ end
99
+ else
100
+ value.each do |n, v|
101
+ hyphen_attr("#{name}-#{n}", escape, v)
102
+ end
103
+ end
104
+ else
105
+ attr(name, escape_html(escape, value))
106
+ end
107
+ end
108
+
109
+ def escape_html(escape, value)
110
+ return value if !escape || value == true
111
+ @options[:use_html_safe] ? Temple::Utils.escape_html_safe(value) : Temple::Utils.escape_html(value)
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+ module Slim
3
+ module Splat
4
+ # @api private
5
+ class Filter < ::Slim::Filter
6
+ define_options :merge_attrs, :attr_quote, :sort_attrs, :default_tag, :format, :disable_capture,
7
+ hyphen_attrs: %w(data aria), use_html_safe: ''.respond_to?(:html_safe?),
8
+ hyphen_underscore_attrs: false
9
+
10
+ def call(exp)
11
+ @splat_options = nil
12
+ exp = compile(exp)
13
+ if @splat_options
14
+ opts = options.to_hash.reject { |k, v| !Filter.options.valid_key?(k) }.inspect
15
+ [:multi, [:code, "#{@splat_options} = #{opts}"], exp]
16
+ else
17
+ exp
18
+ end
19
+ end
20
+
21
+ # Handle tag expression `[:html, :tag, name, attrs, content]`
22
+ #
23
+ # @param [String] name Tag name
24
+ # @param [Array] attrs Temple expression
25
+ # @param [Array] content Temple expression
26
+ # @return [Array] Compiled temple expression
27
+ def on_html_tag(name, attrs, content = nil)
28
+ return super if name != '*'
29
+ builder, block = make_builder(attrs[2..-1])
30
+ if content
31
+ [:multi,
32
+ block,
33
+ [:slim, :output, false,
34
+ "#{builder}.build_tag #{empty_exp?(content) ? '{}' : 'do'}",
35
+ compile(content)]]
36
+ else
37
+ [:multi,
38
+ block,
39
+ [:dynamic, "#{builder}.build_tag"]]
40
+ end
41
+ end
42
+
43
+ # Handle attributes expression `[:html, :attrs, *attrs]`
44
+ #
45
+ # @param [Array] attrs Array of temple expressions
46
+ # @return [Array] Compiled temple expression
47
+ def on_html_attrs(*attrs)
48
+ if attrs.any? { |attr| splat?(attr) }
49
+ builder, block = make_builder(attrs)
50
+ [:multi,
51
+ block,
52
+ [:dynamic, "#{builder}.build_attrs"]]
53
+ else
54
+ super
55
+ end
56
+ end
57
+
58
+ protected
59
+
60
+ def splat?(attr)
61
+ # Splat attribute given
62
+ attr[0] == :slim && attr[1] == :splat ||
63
+ # Hyphenated attribute also needs splat handling
64
+ (attr[0] == :html && attr[1] == :attr && options[:hyphen_attrs].include?(attr[2]) &&
65
+ attr[3][0] == :slim && attr[3][1] == :attrvalue)
66
+ end
67
+
68
+ def make_builder(attrs)
69
+ @splat_options ||= unique_name
70
+ builder = unique_name
71
+ result = [:multi, [:code, "#{builder} = ::Slim::Splat::Builder.new(#{@splat_options})"]]
72
+ attrs.each do |attr|
73
+ result <<
74
+ if attr[0] == :html && attr[1] == :attr
75
+ if attr[3][0] == :slim && attr[3][1] == :attrvalue
76
+ [:code, "#{builder}.code_attr(#{attr[2].inspect}, #{attr[3][2]}, (#{attr[3][3]}))"]
77
+ else
78
+ tmp = unique_name
79
+ [:multi,
80
+ [:capture, tmp, compile(attr[3])],
81
+ [:code, "#{builder}.attr(#{attr[2].inspect}, #{tmp})"]]
82
+ end
83
+ elsif attr[0] == :slim && attr[1] == :splat
84
+ [:code, "#{builder}.splat_attrs((#{attr[2]}))"]
85
+ else
86
+ attr
87
+ end
88
+ end
89
+ [builder, result]
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ module Slim
3
+ # Tilt template implementation for Slim
4
+ # @api public
5
+ Template = Temple::Templates::Tilt(Slim::Engine, register_as: :slim)
6
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+ require 'slim'
3
+
4
+ module Slim
5
+ # @api private
6
+ class Translator < Filter
7
+ define_options :tr,
8
+ tr_mode: :dynamic,
9
+ tr_fn: '_'
10
+
11
+ if defined?(::I18n)
12
+ set_options tr_fn: '::Slim::Translator.i18n_text',
13
+ tr: true
14
+ elsif defined?(::GetText)
15
+ set_options tr_fn: '::GetText._',
16
+ tr: true
17
+ elsif defined?(::FastGettext)
18
+ set_options tr_fn: '::FastGettext::Translation._',
19
+ tr: true
20
+ end
21
+
22
+ def self.i18n_text(text)
23
+ I18n.t!(text)
24
+ rescue I18n::MissingTranslationData
25
+ text
26
+ end
27
+
28
+ def self.i18n_key(text)
29
+ key = text.parameterize.underscore
30
+ I18n.t!(key)
31
+ rescue I18n::MissingTranslationData
32
+ text
33
+ end
34
+
35
+ def call(exp)
36
+ options[:tr] ? super : exp
37
+ end
38
+
39
+ def initialize(opts = {})
40
+ super
41
+ case options[:tr_mode]
42
+ when :static
43
+ @translator = StaticTranslator.new(tr_fn: options[:tr_fn])
44
+ when :dynamic
45
+ @translator = DynamicTranslator.new(tr_fn: options[:tr_fn])
46
+ else
47
+ raise ArgumentError, "Invalid translator mode #{options[:tr_mode].inspect}"
48
+ end
49
+ end
50
+
51
+ def on_slim_text(type, exp)
52
+ [:slim, :text, type, @translator.call(exp)]
53
+ end
54
+
55
+ private
56
+
57
+ class StaticTranslator < Filter
58
+ define_options :tr_fn
59
+
60
+ def initialize(opts = {})
61
+ super
62
+ @translate = eval("proc {|string| #{options[:tr_fn]}(string) }")
63
+ end
64
+
65
+ def call(exp)
66
+ @text, @captures = ''.dup, []
67
+ result = compile(exp)
68
+
69
+ text = @translate.call(@text)
70
+ while text =~ /%(\d+)/
71
+ result << [:static, $`] << @captures[$1.to_i - 1]
72
+ text = $'
73
+ end
74
+ result << [:static, text]
75
+ end
76
+
77
+ def on_static(text)
78
+ @text << text
79
+ [:multi]
80
+ end
81
+
82
+ def on_slim_output(escape, code, content)
83
+ @captures << [:slim, :output, escape, code, content]
84
+ @text << "%#{@captures.size}"
85
+ [:multi]
86
+ end
87
+ end
88
+
89
+ class DynamicTranslator < Filter
90
+ define_options :tr_fn
91
+
92
+ def call(exp)
93
+ @captures_count, @captures_var, @text = 0, unique_name, ''.dup
94
+
95
+ result = compile(exp)
96
+
97
+ if @captures_count > 0
98
+ result.insert(1, [:code, "#{@captures_var}=[]"])
99
+ result << [:slim, :output, false, "#{options[:tr_fn]}(#{@text.inspect}).gsub(/%(\\d+)/) { #{@captures_var}[$1.to_i-1] }", [:multi]]
100
+ else
101
+ result << [:slim, :output, false, "#{options[:tr_fn]}(#{@text.inspect})", [:multi]]
102
+ end
103
+ end
104
+
105
+ def on_static(text)
106
+ @text << text
107
+ [:multi]
108
+ end
109
+
110
+ def on_slim_output(escape, code, content)
111
+ @captures_count += 1
112
+ @text << "%#{@captures_count}"
113
+ [:capture, "#{@captures_var}[#{@captures_count - 1}]", [:slim, :output, escape, code, content]]
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ Slim::Engine.before Slim::EndInserter, Slim::Translator
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ module Slim
3
+ # Slim version string
4
+ # @api public
5
+ VERSION = '5.2.1'
6
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ require 'temple'
3
+ require 'slim/parser'
4
+ require 'slim/filter'
5
+ require 'slim/do_inserter'
6
+ require 'slim/end_inserter'
7
+ require 'slim/embedded'
8
+ require 'slim/interpolation'
9
+ require 'slim/controls'
10
+ require 'slim/splat/filter'
11
+ require 'slim/splat/builder'
12
+ require 'slim/code_attributes'
13
+ require 'slim/engine'
14
+ require 'slim/template'
15
+ require 'slim/version'
16
+ require 'slim/railtie' if defined?(Rails::Railtie)
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/lib/slim/version'
2
+ require 'date'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'slim'
6
+ s.version = Slim::VERSION
7
+ s.date = Date.today.to_s
8
+ s.authors = ['Daniel Mendler', 'Andrew Stone', 'Fred Wu']
9
+ s.email = ['mail@daniel-mendler.de', 'andy@stonean.com', 'ifredwu@gmail.com']
10
+ s.summary = 'Slim is a template language.'
11
+ s.description = 'Slim is a template language whose goal is reduce the syntax to the essential parts without becoming cryptic.'
12
+ s.homepage = 'https://slim-template.github.io/'
13
+ s.license = 'MIT'
14
+
15
+ s.metadata = {
16
+ "bug_tracker_uri" => "https://github.com/slim-template/slim/issues",
17
+ "changelog_uri" => "https://github.com/slim-template/slim/blob/main/CHANGES",
18
+ "documentation_uri" => "https://rubydoc.info/gems/slim/frames",
19
+ "homepage_uri" => "https://slim-template.github.io/",
20
+ "source_code_uri" => "https://github.com/slim-template/slim",
21
+ "wiki_uri" => "https://github.com/slim-template/slim/wiki",
22
+ "funding_uri" => "https://github.com/sponsors/slim-template"
23
+ }
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.require_paths = %w(lib)
28
+
29
+ s.required_ruby_version = '>= 2.5.0'
30
+
31
+ s.add_runtime_dependency('temple', ['~> 0.10.0'])
32
+ s.add_runtime_dependency('tilt', ['>= 2.1.0'])
33
+ end
@@ -0,0 +1,201 @@
1
+ begin
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+ rescue LoadError
5
+ end
6
+
7
+ require 'minitest/autorun'
8
+ require 'slim'
9
+ require 'slim/grammar'
10
+
11
+ Slim::Engine.after Slim::Parser, Temple::Filters::Validator, grammar: Slim::Grammar
12
+ Slim::Engine.before :Pretty, Temple::Filters::Validator
13
+
14
+ class TestSlim < Minitest::Test
15
+ def setup
16
+ @env = Env.new
17
+ end
18
+
19
+ def render(source, options = {}, &block)
20
+ scope = options.delete(:scope)
21
+ locals = options.delete(:locals)
22
+ Slim::Template.new(options[:file], options) { source }.render(scope || @env, locals, &block)
23
+ end
24
+
25
+ class HtmlSafeString < String
26
+ def html_safe?
27
+ true
28
+ end
29
+
30
+ def to_s
31
+ self
32
+ end
33
+ end
34
+
35
+ def with_html_safe
36
+ String.send(:define_method, :html_safe?) { false }
37
+ String.send(:define_method, :html_safe) { HtmlSafeString.new(self) }
38
+ yield
39
+ ensure
40
+ String.send(:undef_method, :html_safe?) if String.method_defined?(:html_safe?)
41
+ String.send(:undef_method, :html_safe) if String.method_defined?(:html_safe)
42
+ end
43
+
44
+ def assert_html(expected, source, options = {}, &block)
45
+ assert_equal expected, render(source, options, &block)
46
+ end
47
+
48
+ def assert_syntax_error(message, source, options = {})
49
+ render(source, options)
50
+ raise 'Syntax error expected'
51
+ rescue Slim::Parser::SyntaxError => ex
52
+ assert_equal message, ex.message
53
+ message =~ /([^\s]+), Line (\d+)/
54
+ assert_backtrace ex, "#{$1}:#{$2}"
55
+ end
56
+
57
+ def assert_ruby_error(error, from, source, options = {})
58
+ render(source, options)
59
+ raise 'Ruby error expected'
60
+ rescue error => ex
61
+ assert_backtrace(ex, from)
62
+ end
63
+
64
+ def assert_backtrace(ex, from)
65
+ ex.backtrace[0] =~ /([^\s]+:\d+)/
66
+ assert_equal from, $1
67
+ end
68
+
69
+ def assert_ruby_syntax_error(from, source, options = {})
70
+ render(source, options)
71
+ raise 'Ruby syntax error expected'
72
+ rescue SyntaxError => ex
73
+ ex.message =~ /([^\s]+:\d+):/
74
+ assert_equal from, $1
75
+ end
76
+
77
+ def assert_runtime_error(message, source, options = {})
78
+ render(source, options)
79
+ raise Exception, 'Runtime error expected'
80
+ rescue RuntimeError => ex
81
+ assert_equal message, ex.message
82
+ end
83
+ end
84
+
85
+ class Env
86
+ attr_reader :var, :x
87
+
88
+ def initialize
89
+ @var = 'instance'
90
+ @x = 0
91
+ end
92
+
93
+ def id_helper
94
+ "notice"
95
+ end
96
+
97
+ def hash
98
+ {a: 'The letter a', b: 'The letter b'}
99
+ end
100
+
101
+ def show_first?(show = false)
102
+ show
103
+ end
104
+
105
+ def define_macro(name, &block)
106
+ @macro ||= {}
107
+ @macro[name.to_s] = block
108
+ ''
109
+ end
110
+
111
+ def call_macro(name, *args)
112
+ @macro[name.to_s].call(*args)
113
+ end
114
+
115
+ def hello_world(text = "Hello World from @env", opts = {})
116
+ text = text + (opts.to_a * " ") if opts.any?
117
+ if block_given?
118
+ "#{text} #{yield} #{text}"
119
+ else
120
+ text
121
+ end
122
+ end
123
+
124
+ def message(*args)
125
+ args.join(' ')
126
+ end
127
+
128
+ def action_path(*args)
129
+ "/action-#{args.join('-')}"
130
+ end
131
+
132
+ def in_keyword
133
+ "starts with keyword"
134
+ end
135
+
136
+ def evil_method
137
+ "<script>do_something_evil();</script>"
138
+ end
139
+
140
+ def output_number
141
+ 1337
142
+ end
143
+
144
+ def succ_x
145
+ @x = @x.succ
146
+ end
147
+
148
+ end
149
+
150
+ class ViewEnv
151
+ def output_number
152
+ 1337
153
+ end
154
+
155
+ def person
156
+ [{name: 'Joe'}, {name: 'Jack'}]
157
+ end
158
+
159
+ def people
160
+ %w(Andy Fred Daniel).collect{|n| Person.new(n)}
161
+ end
162
+
163
+ def cities
164
+ %w{Atlanta Melbourne Karlsruhe}
165
+ end
166
+
167
+ def people_with_locations
168
+ array = []
169
+ people.each_with_index do |p,i|
170
+ p.location = Location.new cities[i]
171
+ array << p
172
+ end
173
+ array
174
+ end
175
+ end
176
+
177
+ require 'forwardable'
178
+
179
+ class Person
180
+ extend Forwardable
181
+
182
+ attr_accessor :name
183
+
184
+ def initialize(name)
185
+ @name = name
186
+ end
187
+
188
+ def location=(location)
189
+ @location = location
190
+ end
191
+
192
+ def_delegators :@location, :city
193
+ end
194
+
195
+ class Location
196
+ attr_accessor :city
197
+
198
+ def initialize(city)
199
+ @city = city
200
+ end
201
+ end