shortcode 1.2.1 → 2.0.0.pre

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop +1 -0
  3. data/.rubocop.yml +72 -0
  4. data/.travis.yml +7 -6
  5. data/Appraisals +3 -7
  6. data/Gemfile +2 -2
  7. data/Gemfile.lock +136 -18
  8. data/bin/appraisal +17 -0
  9. data/bin/rspec +17 -0
  10. data/bin/rubocop +17 -0
  11. data/gemfiles/rails_4.2.gemfile +1 -1
  12. data/gemfiles/rails_5.0.gemfile +1 -1
  13. data/gemfiles/rails_5.1.gemfile +1 -1
  14. data/lib/shortcode.rb +17 -41
  15. data/lib/shortcode/configuration.rb +3 -1
  16. data/lib/shortcode/parser.rb +21 -17
  17. data/lib/shortcode/presenter.rb +18 -15
  18. data/lib/shortcode/processor.rb +3 -1
  19. data/lib/shortcode/railtie.rb +2 -0
  20. data/lib/shortcode/tag.rb +11 -4
  21. data/lib/shortcode/template_binding.rb +12 -7
  22. data/lib/shortcode/transformer.rb +8 -4
  23. data/lib/shortcode/version.rb +3 -1
  24. data/shortcode.gemspec +10 -7
  25. data/spec/.rubocop.yml +17 -0
  26. data/spec/performance_spec.rb +4 -5
  27. data/spec/rails_helpers_spec.rb +25 -31
  28. data/spec/shortcode/parser_spec.rb +313 -0
  29. data/spec/shortcode/presenter_spec.rb +118 -0
  30. data/spec/shortcode/tag_spec.rb +73 -0
  31. data/spec/shortcode_spec.rb +40 -37
  32. data/spec/spec_helper.rb +6 -20
  33. data/spec/support/fixtures.rb +4 -6
  34. data/spec/support/presenters/missing_attributes_presenter.rb +3 -6
  35. data/spec/support/presenters/missing_content_presenter.rb +3 -6
  36. data/spec/support/presenters/missing_for_presenter.rb +3 -6
  37. data/spec/support/presenters/missing_initialize_presenter.rb +3 -6
  38. data/spec/support/presenters/multiple_presenter.rb +4 -5
  39. data/spec/support/presenters/my_presenter.rb +3 -4
  40. data/spec/support/presenters/other_presenter.rb +3 -4
  41. data/spec/template_parsers_spec.rb +21 -22
  42. data/spec/transformer_spec.rb +26 -36
  43. metadata +75 -24
  44. data/gemfiles/rails_4.1.gemfile +0 -8
  45. data/spec/parser_spec.rb +0 -307
  46. data/spec/presenter_spec.rb +0 -126
  47. data/spec/tag_spec.rb +0 -86
@@ -1,4 +1,5 @@
1
1
  class Shortcode::Configuration
2
+
2
3
  # Sets the template parser to use, supports :erb, :haml, and :slim, default is :haml
3
4
  attr_accessor :template_parser
4
5
 
@@ -32,7 +33,7 @@ class Shortcode::Configuration
32
33
  # Set the quotation sign used for attribute values. Defaults to double quote (")
33
34
  attr_accessor :attribute_quote_type
34
35
 
35
- # Allows quotes around attributes to be omitted. Defaults to false (quotes must be present around the value).
36
+ # Allows quotes around attributes to be omitted. Defaults to false (quotes must be present around the value)
36
37
  attr_accessor :use_attribute_quotes
37
38
 
38
39
  def initialize
@@ -51,4 +52,5 @@ class Shortcode::Configuration
51
52
  def register_presenter(presenter)
52
53
  Shortcode::Presenter.register(self, presenter)
53
54
  end
55
+
54
56
  end
@@ -1,4 +1,5 @@
1
1
  class Shortcode::Parser
2
+
2
3
  def initialize(configuration)
3
4
  @configuration = configuration
4
5
  setup_rules
@@ -23,51 +24,54 @@ class Shortcode::Parser
23
24
  @klass_instance ||= klass.new
24
25
  end
25
26
 
27
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/LineLength
26
28
  def setup_rules
27
29
  define_match_any_of
28
30
 
29
31
  shortcode_configuration = @configuration
30
- klass.rule(:block_tag) { match_any_of shortcode_configuration.block_tags }
32
+ klass.rule(:block_tag) { match_any_of shortcode_configuration.block_tags }
31
33
  klass.rule(:self_closing_tag) { match_any_of shortcode_configuration.self_closing_tags }
32
34
 
33
35
  klass.rule(:quotes) { str(shortcode_configuration.attribute_quote_type) }
34
36
 
35
- klass.rule(:space) { str(' ').repeat(1) }
36
- klass.rule(:space?) { space.maybe }
37
- klass.rule(:newline) { (str("\r\n") | str("\n")) >> space? }
38
- klass.rule(:newline?) { newline.maybe }
39
- klass.rule(:whitespace) { (space | newline).repeat(1) }
37
+ klass.rule(:space) { str(" ").repeat(1) }
38
+ klass.rule(:space?) { space.maybe }
39
+ klass.rule(:newline) { (str("\r\n") | str("\n")) >> space? }
40
+ klass.rule(:newline?) { newline.maybe }
41
+ klass.rule(:whitespace) { (space | newline).repeat(1) }
40
42
 
41
43
  klass.rule(:key) { match('[a-zA-Z0-9\-_]').repeat(1) }
42
44
 
43
45
  klass.rule(:value_with_quotes) { quotes >> (quotes.absent? >> any).repeat.as(:value) >> quotes }
44
- klass.rule(:value_without_quotes) { quotes.absent? >> ( (str(']') | whitespace).absent? >> any ).repeat.as(:value) }
46
+ klass.rule(:value_without_quotes) { quotes.absent? >> ((str("]") | whitespace).absent? >> any).repeat.as(:value) }
45
47
  klass.rule(:value) { shortcode_configuration.use_attribute_quotes ? value_with_quotes : (value_without_quotes | value_with_quotes) }
46
48
 
47
- klass.rule(:option) { key.as(:key) >> str('=') >> value }
48
- klass.rule(:options) { (str(' ') >> option).repeat(1) }
49
+ klass.rule(:option) { key.as(:key) >> str("=") >> value }
50
+ klass.rule(:options) { (str(" ") >> option).repeat(1) }
49
51
  klass.rule(:options?) { options.repeat(0, 1) }
50
52
 
51
- klass.rule(:open) { str('[') >> block_tag.as(:open) >> options?.as(:options) >> str(']') >> newline? }
52
- klass.rule(:close) { str('[/') >> block_tag.as(:close) >> str(']') >> newline? }
53
- klass.rule(:open_close) { str('[') >> self_closing_tag.as(:open_close) >> options?.as(:options) >> str(']') >> newline? }
53
+ klass.rule(:open) { str("[") >> block_tag.as(:open) >> options?.as(:options) >> str("]") >> newline? }
54
+ klass.rule(:close) { str("[/") >> block_tag.as(:close) >> str("]") >> newline? }
55
+ klass.rule(:open_close) { str("[") >> self_closing_tag.as(:open_close) >> options?.as(:options) >> str("]") >> newline? }
54
56
 
55
- klass.rule(:text) { ((close | block | open_close).absent? >> any).repeat(1).as(:text) }
56
- klass.rule(:block) { (open >> (block | text | open_close).repeat.as(:inner) >> close) }
57
+ klass.rule(:text) { ((close | block | open_close).absent? >> any).repeat(1).as(:text) }
58
+ klass.rule(:block) { (open >> (block | text | open_close).repeat.as(:inner) >> close) }
57
59
 
58
60
  klass.rule(:body) { (block | text | open_close).repeat.as(:body) }
59
61
  klass.root(:body)
60
62
  end
63
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/LineLength
61
64
 
62
65
  def define_match_any_of
63
66
  klass.send(:define_method, :match_any_of) do |tags|
64
- if tags.length < 1
65
- return str('')
67
+ if tags.empty?
68
+ str("")
66
69
  else
67
- tags.map{ |tag| str(tag) }.inject do |tag_chain, tag|
70
+ tags.map { |tag| str(tag) }.inject do |tag_chain, tag|
68
71
  tag_chain.send :|, tag
69
72
  end
70
73
  end
71
74
  end
72
75
  end
76
+
73
77
  end
@@ -1,14 +1,21 @@
1
1
  class Shortcode::Presenter
2
+
2
3
  def self.register(configuration, presenter)
3
4
  validate presenter
4
5
  [*presenter.for].each { |k| configuration.presenters[k.to_sym] = presenter }
5
6
  end
6
7
 
7
8
  def self.validate(presenter)
8
- raise ArgumentError, "The presenter must define the class method #for" unless presenter.respond_to?(:for)
9
- raise ArgumentError, "The presenter must define an initialize method" unless presenter.private_instance_methods(false).include?(:initialize)
10
- %w(content attributes).each do |method|
11
- raise ArgumentError, "The presenter must define the method ##{method}" unless presenter.method_defined?(method.to_sym)
9
+ unless presenter.respond_to?(:for)
10
+ raise ArgumentError, "The presenter must define the class method #for"
11
+ end
12
+ unless presenter.private_instance_methods(false).include?(:initialize)
13
+ raise ArgumentError, "The presenter must define an initialize method"
14
+ end
15
+ %w[content attributes].each do |method|
16
+ unless presenter.method_defined?(method.to_sym)
17
+ raise ArgumentError, "The presenter must define the method ##{method}"
18
+ end
12
19
  end
13
20
  end
14
21
 
@@ -20,23 +27,19 @@ class Shortcode::Presenter
20
27
  initialize_custom_presenter(name)
21
28
  end
22
29
 
23
- def content
24
- @content
25
- end
30
+ attr_reader :content
26
31
 
27
- def attributes
28
- @attributes
29
- end
32
+ attr_reader :attributes
30
33
 
31
34
  private
32
35
 
33
36
  attr_reader :configuration
34
37
 
35
38
  def initialize_custom_presenter(name)
36
- if configuration.presenters.has_key? name.to_sym
37
- presenter = configuration.presenters[name.to_sym].new(@attributes, @content, @additional_attributes)
38
- @attributes = presenter.attributes
39
- @content = presenter.content
40
- end
39
+ return unless configuration.presenters.key?(name.to_sym)
40
+ presenter = configuration.presenters[name.to_sym].new(@attributes, @content, @additional_attributes)
41
+ @attributes = presenter.attributes
42
+ @content = presenter.content
41
43
  end
44
+
42
45
  end
@@ -1,7 +1,8 @@
1
1
  class Shortcode::Processor
2
2
 
3
3
  def process(string, configuration, additional_attributes=nil)
4
- transformer(configuration).apply parser(configuration).parse(string), additional_attributes: additional_attributes
4
+ transformer(configuration).apply parser(configuration).parse(string),
5
+ additional_attributes: additional_attributes
5
6
  end
6
7
 
7
8
  private
@@ -13,4 +14,5 @@ class Shortcode::Processor
13
14
  def transformer(configuration)
14
15
  @transformer ||= Shortcode::Transformer.new(configuration)
15
16
  end
17
+
16
18
  end
@@ -1,3 +1,5 @@
1
1
  class Shortcode::TemplateBinding
2
+
2
3
  include ActionView::Helpers
4
+
3
5
  end
data/lib/shortcode/tag.rb CHANGED
@@ -1,9 +1,13 @@
1
1
  class Shortcode::Tag
2
2
 
3
- def initialize(name, configuration, attributes=[], content='', additional_attributes=nil)
3
+ def initialize(name, configuration, attributes=[], content="", additional_attributes=nil)
4
4
  @name = name.downcase
5
5
  @configuration = configuration
6
- @binding = Shortcode::TemplateBinding.new(@name, @configuration, attributes, content, additional_attributes)
6
+ @binding = Shortcode::TemplateBinding.new(@name,
7
+ @configuration,
8
+ attributes,
9
+ content,
10
+ additional_attributes)
7
11
  end
8
12
 
9
13
  def markup
@@ -21,10 +25,11 @@ class Shortcode::Tag
21
25
 
22
26
  attr_reader :configuration
23
27
 
28
+ # rubocop:disable Metrics/AbcSize
24
29
  def render_template
25
30
  case configuration.template_parser
26
31
  when :erb
27
- ERB.new(markup).result(@binding.get_binding)
32
+ ERB.new(markup).result(@binding.expose_binding)
28
33
  when :haml
29
34
  Haml::Engine.new(markup).render(@binding)
30
35
  when :slim
@@ -33,6 +38,7 @@ class Shortcode::Tag
33
38
  raise Shortcode::TemplateParserNotSupported, configuration.template_parser
34
39
  end
35
40
  end
41
+ # rubocop:enable Metrics/AbcSize
36
42
 
37
43
  def first_priority_template
38
44
  configuration.check_config_templates_first ? markup_from_config : markup_from_file
@@ -60,6 +66,7 @@ class Shortcode::Tag
60
66
  end
61
67
 
62
68
  def template_paths
63
- [ "#{@name}.html.#{configuration.template_parser.to_s}", "#{@name}.#{configuration.template_parser.to_s}" ]
69
+ ["#{@name}.html.#{configuration.template_parser}", "#{@name}.#{configuration.template_parser}"]
64
70
  end
71
+
65
72
  end
@@ -1,16 +1,20 @@
1
1
  class Shortcode::TemplateBinding
2
2
 
3
- def initialize(name, configuration, attributes=[], content='', additional_attributes=nil)
3
+ def initialize(name, configuration, attributes=[], content="", additional_attributes=nil)
4
4
  @configuration = configuration
5
5
  include_helper_modules
6
- presenter = Shortcode::Presenter.new name, configuration, set_attributes(attributes), content, additional_attributes
7
- @name = name
8
- @attributes = presenter.attributes
9
- @content = presenter.content
6
+ presenter = Shortcode::Presenter.new name,
7
+ configuration,
8
+ map_attributes(attributes),
9
+ content,
10
+ additional_attributes
11
+ @name = name
12
+ @attributes = presenter.attributes
13
+ @content = presenter.content
10
14
  end
11
15
 
12
16
  # Expose private binding() method for use with erb templates
13
- def get_binding
17
+ def expose_binding
14
18
  binding
15
19
  end
16
20
 
@@ -18,7 +22,7 @@ class Shortcode::TemplateBinding
18
22
 
19
23
  attr_reader :configuration
20
24
 
21
- def set_attributes(attributes)
25
+ def map_attributes(attributes)
22
26
  hash = {}
23
27
  attributes.each { |o| hash[o[:key].to_sym] = o[:value] }
24
28
  hash
@@ -31,4 +35,5 @@ class Shortcode::TemplateBinding
31
35
  self.class.send(:include, helper)
32
36
  end
33
37
  end
38
+
34
39
  end
@@ -1,10 +1,11 @@
1
1
  class Shortcode::Transformer
2
+
2
3
  def initialize(configuration)
3
4
  @configuration = configuration
4
5
  setup_rules
5
6
  end
6
7
 
7
- def apply(str, options = {})
8
+ def apply(str, options={})
8
9
  klass_instance.apply(str, options)
9
10
  end
10
11
 
@@ -18,8 +19,9 @@ class Shortcode::Transformer
18
19
  @klass_instance ||= klass.new
19
20
  end
20
21
 
22
+ # rubocop:disable Metrics/AbcSize
21
23
  def setup_rules
22
- shortcode_configuration = @configuration
24
+ config = @configuration
23
25
 
24
26
  klass.rule(text: klass.send(:simple, :text)) { String(text) }
25
27
  klass.rule(
@@ -27,12 +29,14 @@ class Shortcode::Transformer
27
29
  options: klass.send(:subtree, :options),
28
30
  inner: klass.send(:sequence, :inner),
29
31
  close: klass.send(:simple, :name)
30
- ) { Shortcode::Tag.new(name.to_s, shortcode_configuration, options, inner.join, additional_attributes).render }
32
+ ) { Shortcode::Tag.new(name.to_s, config, options, inner.join, additional_attributes).render }
31
33
  klass.rule(
32
34
  open_close: klass.send(:simple, :name),
33
35
  options: klass.send(:subtree, :options)
34
- ) { Shortcode::Tag.new(name.to_s, shortcode_configuration, options, '', additional_attributes).render }
36
+ ) { Shortcode::Tag.new(name.to_s, config, options, "", additional_attributes).render }
35
37
 
36
38
  klass.rule(body: klass.send(:sequence, :strings)) { strings.join }
37
39
  end
40
+ # rubocop:enable Metrics/AbcSize
41
+
38
42
  end
@@ -1,3 +1,5 @@
1
1
  class Shortcode
2
- VERSION = "1.2.1"
2
+
3
+ VERSION = "2.0.0.pre".freeze
4
+
3
5
  end
data/shortcode.gemspec CHANGED
@@ -1,7 +1,7 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'shortcode/version'
4
+ require "shortcode/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "shortcode"
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "https://github.com/kernow/shortcode"
14
14
  spec.license = "MIT"
15
15
 
16
- spec.files = `git ls-files`.split($/)
16
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
@@ -21,9 +21,12 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "parslet", "1.8.0"
22
22
 
23
23
  spec.add_development_dependency "bundler", "~> 1.15"
24
- spec.add_development_dependency "rake", "~> 12.0"
25
- spec.add_development_dependency "rspec", "~> 3.6"
26
24
  spec.add_development_dependency "coveralls", "~> 0.8"
27
- spec.add_development_dependency "slim", "~> 3.0"
28
25
  spec.add_development_dependency "haml", "~> 5.0"
26
+ spec.add_development_dependency "rails", "5.1.4"
27
+ spec.add_development_dependency "rake", "~> 12.0"
28
+ spec.add_development_dependency "rspec", "~> 3.7"
29
+ spec.add_development_dependency "rubocop", "~> 0.51"
30
+ spec.add_development_dependency "rubocop-rspec", "~> 1.19"
31
+ spec.add_development_dependency "slim", "~> 3.0"
29
32
  end
data/spec/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ inherit_from:
2
+ - ../.rubocop.yml
3
+
4
+ EmptyLinesAroundBlockBody:
5
+ Enabled: false
6
+
7
+ Metrics/BlockLength:
8
+ Enabled: false
9
+
10
+ RSpec/MessageChain:
11
+ Enabled: false
12
+
13
+ RSpec/MultipleExpectations:
14
+ Max: 3
15
+
16
+ RSpec/NestedGroups:
17
+ Max: 3
@@ -1,11 +1,10 @@
1
- require 'spec_helper'
2
- require 'parslet/rig/rspec'
3
- require 'pp'
4
- require 'benchmark'
1
+ require "spec_helper"
2
+ require "parslet/rig/rspec"
3
+ require "pp"
4
+ require "benchmark"
5
5
 
6
6
  # Uncomment to run performace specs
7
7
 
8
-
9
8
  # describe Shortcode do
10
9
 
11
10
  # let(:long_text) { load_fixture :long_text }
@@ -1,72 +1,66 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  module ShortcodeSpecViewHelper
4
+
4
5
  def wrap_in_p(content)
5
6
  content_tag :p, content
6
7
  end
7
- end
8
8
 
9
- describe "rails helpers" do
9
+ end
10
10
 
11
+ describe "rails helpers", type: :feature do
11
12
  let(:template) { load_fixture :rails_helper }
12
13
 
13
14
  let(:erb_output) { load_fixture :rails_helper_output_erb, :html }
14
15
  let(:haml_output) { load_fixture :rails_helper_output_haml, :html }
15
16
  let(:slim_output) { load_fixture :rails_helper_output_slim, :html }
16
17
 
17
- describe "erb" do
18
+ let(:shortcode) { Shortcode.new }
19
+ let(:configuration) { shortcode.configuration }
18
20
 
21
+ before do
22
+ configuration.block_tags = %i[rails_helper custom_helper]
23
+ configuration.template_path = File.join File.dirname(__FILE__), "support/templates/erb"
24
+ end
25
+
26
+ describe "erb" do
19
27
  it "are accessible within erb templates" do
20
- expect(Shortcode.process(template).gsub("\n",'')).to eq(erb_output)
28
+ expect(shortcode.process(template).delete("\n")).to eq(erb_output)
21
29
  end
22
-
23
30
  end
24
31
 
25
32
  describe "haml" do
26
-
27
- before(:each) do
28
- Shortcode.setup do |config|
29
- config.template_parser = :haml
30
- config.template_path = File.join File.dirname(__FILE__), "support/templates/haml"
31
- end
33
+ before do
34
+ configuration.template_parser = :haml
35
+ configuration.template_path = File.join File.dirname(__FILE__), "support/templates/haml"
32
36
  end
33
37
 
34
38
  it "are accessible within haml templates" do
35
- expect(Shortcode.process(template).gsub("\n",'')).to eq(haml_output)
39
+ expect(shortcode.process(template).delete("\n")).to eq(haml_output)
36
40
  end
37
-
38
41
  end
39
42
 
40
43
  describe "slim" do
41
-
42
- before(:each) do
43
- Shortcode.setup do |config|
44
- config.template_parser = :slim
45
- config.template_path = File.join File.dirname(__FILE__), "support/templates/slim"
46
- end
44
+ before do
45
+ configuration.template_parser = :slim
46
+ configuration.template_path = File.join File.dirname(__FILE__), "support/templates/slim"
47
47
  end
48
48
 
49
49
  it "are accessible within slim templates" do
50
- expect(Shortcode.process(template).gsub("\n",'')).to eq(slim_output)
50
+ expect(shortcode.process(template).delete("\n")).to eq(slim_output)
51
51
  end
52
-
53
52
  end
54
53
 
55
54
  describe "using a custom helper module" do
56
-
57
55
  let(:template) { load_fixture :custom_helper }
58
- let(:output) { load_fixture :custom_helper_output, :html }
56
+ let(:output) { load_fixture :custom_helper_output, :html }
59
57
 
60
- before(:each) do
61
- Shortcode.setup do |config|
62
- config.helpers = [ShortcodeSpecViewHelper]
63
- end
58
+ before do
59
+ configuration.helpers = [ShortcodeSpecViewHelper]
64
60
  end
65
61
 
66
62
  it "is accessible within templates" do
67
- expect(Shortcode.process(template).gsub("\n",'')).to eq(output)
63
+ expect(shortcode.process(template).delete("\n")).to eq(output)
68
64
  end
69
-
70
65
  end
71
-
72
66
  end