bridgetown-inline-svg 1.1.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3ab68b27ce5c6ea4b77ff2340e106747d674029911ee582d9ee6eaf0e5ee222
4
- data.tar.gz: 3b8e527ff95606f74e10c42f99e80ae65769378bec2f69998060b514a4dd6baf
3
+ metadata.gz: e1c8e18d390771eeb4fddd2b1dbfb6d82357b55c21fdf8445af38506bb7ba4fc
4
+ data.tar.gz: 2e75d828cd0dd039dcb91e9efa5b3d9251c80bebfcadf8ea329dd3f80874c9cf
5
5
  SHA512:
6
- metadata.gz: df96ce63b617fe79b877c1a0b6ac08d2df0bc10464c57dab78fca651f2bbc813f34bb90e7c8a1b1efe38f42471e780ffc487513a0625d21c6d02e1000a95053f
7
- data.tar.gz: f1d22d0f9ac90a71cf717e6b469fcfc51cb595f30b7bc0d6f9a42d16e5bb989c8d41667a2597c87e40f174e28014cf84284d54364244a868cc24bea9bbba34ec
6
+ metadata.gz: d5aca7788bc7464fc726a03bd9a3aed7d9d8831d4a86dc3f55ff6a5809e3164865d60e8bddead21bf1147f28e68e7eed0e13f0f141ede345f7e3be0091f60289
7
+ data.tar.gz: 737e94de18e8f7fdbfef74439f7dc14aa586cb49f0eb7513d9b1aedc4c34ceb855af7d43f341b7694c90fc41a70ad72902c09e0c8cc1c88e9406500e67439a56
@@ -2,7 +2,19 @@
2
2
 
3
3
  ## [Unreleased](https://github.com/andrewmcodes/bridgetown-inline-svg/tree/HEAD)
4
4
 
5
- [Full Changelog](https://github.com/andrewmcodes/bridgetown-inline-svg/compare/v1.0.0...HEAD)
5
+ [Full Changelog](https://github.com/andrewmcodes/bridgetown-inline-svg/compare/v1.1.0...HEAD)
6
+
7
+ **Closed issues:**
8
+
9
+ - Unknown tag 'svg' [\#7](https://github.com/andrewmcodes/bridgetown-inline-svg/issues/7)
10
+
11
+ **Merged pull requests:**
12
+
13
+ - feat: Extend Bridgetown::Builder over extending liquid [\#6](https://github.com/andrewmcodes/bridgetown-inline-svg/pull/6) ([MikeRogers0](https://github.com/MikeRogers0))
14
+
15
+ ## [v1.1.0](https://github.com/andrewmcodes/bridgetown-inline-svg/tree/v1.1.0) (2020-07-21)
16
+
17
+ [Full Changelog](https://github.com/andrewmcodes/bridgetown-inline-svg/compare/v1.0.0...v1.1.0)
6
18
 
7
19
  **Merged pull requests:**
8
20
 
@@ -1,9 +1,8 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "bridgetown"
2
+ require "bridgetown-inline-svg/tag"
4
3
 
5
4
  module BridgetownInlineSvg
6
- autoload :SvgTag, "bridgetown-inline-svg/svg-tag"
5
+ autoload :Markup, "bridgetown-inline-svg/markup"
6
+ autoload :RenderSvg, "bridgetown-inline-svg/render_svg"
7
+ autoload :RenderOptimizedSvg, "bridgetown-inline-svg/render_optimized_svg"
7
8
  end
8
-
9
- Liquid::Template.register_tag("svg", BridgetownInlineSvg::SvgTag)
@@ -0,0 +1,94 @@
1
+ # Converts the mark passed to the tag into a path & a hash of arguments.
2
+ module BridgetownInlineSvg
3
+ class Markup
4
+ attr_reader :markup
5
+
6
+ # Separate file path from other attributes
7
+ PATH_SYNTAX = /
8
+ ^(?<path>[^\s"']+|"[^"]+"|'[^']+')
9
+ (?<params>.*)
10
+ /x.freeze
11
+
12
+ # Parse the first parameter in a string, giving :
13
+ # [full_match, param_name, double_quoted_val, single_quoted_val, unquoted_val]
14
+ # The Regex works like :
15
+ # - first group
16
+ # - match a group of characters that is alphanumeric, _ or -.
17
+ # - second group (non-capturing OR)
18
+ # - match a double-quoted string
19
+ # - match a single-quoted string
20
+ # - match an unquoted string matching the set : [\w\.\-#]
21
+ #
22
+ PARAM_SYNTAX = /
23
+ ([\w-]+)\s*=\s*
24
+ (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w.\-#]+))
25
+ /x.freeze
26
+
27
+ def self.parse(markup)
28
+ new(markup).call
29
+ end
30
+
31
+ def initialize(markup)
32
+ @markup = markup
33
+ end
34
+
35
+ def call
36
+ raise_exception! unless matched
37
+
38
+ [path, params]
39
+ end
40
+
41
+ private
42
+
43
+ def matched
44
+ @matched ||= markup.strip.match(PATH_SYNTAX)
45
+ end
46
+
47
+ def path
48
+ @path ||= matched["path"].sub(/^["']/, "").sub(/["']$/, "").strip
49
+ end
50
+
51
+ def params
52
+ @params ||= begin
53
+ @params = {}
54
+ params_parse_with_liquid_match!
55
+ params_parse_with_custom_match!
56
+ params_set_height_if_missing!
57
+ @params
58
+ end
59
+ end
60
+
61
+ # Scan for arguments using liquids regex
62
+ # From: https://github.com/Shopify/liquid/blob/57c9cf64ebc777fe5e92d4408d31a911f087eeb4/lib/liquid/tags/render.rb#L27
63
+ def params_parse_with_liquid_match!
64
+ raw_params.scan(Liquid::TagAttributes) do |key, value|
65
+ @params[key.to_sym] = value
66
+ end
67
+ end
68
+
69
+ # Scan using our regex to support id="some-id"
70
+ def params_parse_with_custom_match!
71
+ raw_params.scan(PARAM_SYNTAX) do |key, group_2, group_3, group_4|
72
+ @params[key.to_sym] = (group_2 || group_3 || group_4)
73
+ end
74
+ end
75
+
76
+ # IE11 requires we have both width & height attributes
77
+ # on SVG elements
78
+ def params_set_height_if_missing!
79
+ @params[:height] = @params[:width] if @params.key?(:width) && @params[:width] != "" && !@params.key?(:height)
80
+ end
81
+
82
+ def raw_params
83
+ @raw_params = matched["params"].strip
84
+ end
85
+
86
+ def raise_exception!
87
+ raise SyntaxError, <<~END
88
+ Syntax Error in tag 'svg' while parsing the following markup:
89
+ #{markup}
90
+ Valid syntax: svg <path> [property=value]
91
+ END
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,34 @@
1
+ require "svg_optimizer"
2
+
3
+ module BridgetownInlineSvg
4
+ class RenderOptimizedSvg < RenderSvg
5
+ PLUGINS_BLOCKLIST = [
6
+ SvgOptimizer::Plugins::CleanupId
7
+ ].freeze
8
+
9
+ PLUGINS = SvgOptimizer::DEFAULT_PLUGINS.delete_if { |plugin|
10
+ PLUGINS_BLOCKLIST.include?(plugin)
11
+ }
12
+
13
+ def call
14
+ SvgOptimizer.optimize(file, [create_plugin!] + PLUGINS)
15
+ end
16
+
17
+ private
18
+
19
+ def create_plugin!
20
+ mod = Class.new(SvgOptimizer::Plugins::Base) {
21
+ def self.set(params)
22
+ @@params = params
23
+ end
24
+
25
+ def process
26
+ @@params.each { |key, value| xml.root.set_attribute(key, value) }
27
+ xml
28
+ end
29
+ }
30
+ mod.set(@attributes)
31
+ mod
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ require "nokogiri"
2
+
3
+ module BridgetownInlineSvg
4
+ class RenderSvg
5
+ attr_reader :attributes
6
+
7
+ def initialize(file_path, attributes)
8
+ @file_path = file_path
9
+ @attributes = attributes
10
+ end
11
+
12
+ def call
13
+ xml = Nokogiri::XML(file)
14
+ attributes.each { |key, value| xml.root.set_attribute(key, value) }
15
+ xml.root.to_xml
16
+ end
17
+
18
+ private
19
+
20
+ def file
21
+ @file ||= File.open(@file_path, File::RDONLY).read
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,62 @@
1
+ module BridgetownInlineSvg
2
+ class Tag < Bridgetown::Builder
3
+ attr_reader :attributes
4
+ attr_reader :context
5
+ attr_reader :markup
6
+ attr_reader :svg_path
7
+
8
+ def build
9
+ liquid_tag "svg", :render
10
+ end
11
+
12
+ def render(markup, builder)
13
+ @context = builder.context
14
+ @markup = markup
15
+
16
+ interpolate_variables_in_markup!
17
+ set_svg_path_and_attributes!
18
+
19
+ return unless svg_path
20
+
21
+ add_file_to_dependency!
22
+
23
+ render_svg
24
+ end
25
+
26
+ private
27
+
28
+ # Parse any variables in our Markup
29
+ def interpolate_variables_in_markup!
30
+ @markup = Liquid::Template.parse(markup).render(context)
31
+ end
32
+
33
+ def set_svg_path_and_attributes!
34
+ @svg_path, @attributes = Markup.parse(markup)
35
+ @svg_path = Bridgetown.sanitized_path(site.source, svg_path)
36
+ end
37
+
38
+ # When we change the svg, it'll regenerate our page.
39
+ def add_file_to_dependency!
40
+ if context.registers[:page]&.key?("path")
41
+ site.regenerator.add_dependency(
42
+ site.in_source_dir(context.registers[:page]["path"]),
43
+ svg_path
44
+ )
45
+ end
46
+ end
47
+
48
+ def render_svg
49
+ render_svg_class.new(svg_path, attributes).call
50
+ end
51
+
52
+ def render_svg_class
53
+ options["optimize"] == true ? RenderOptimizedSvg : RenderSvg
54
+ end
55
+
56
+ def options
57
+ config["svg"] || {}
58
+ end
59
+ end
60
+ end
61
+
62
+ BridgetownInlineSvg::Tag.register
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BridgetownInlineSvg
4
- VERSION = "1.1.0"
4
+ VERSION = "1.1.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-inline-svg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Mason
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-21 00:00:00.000000000 Z
11
+ date: 2020-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bridgetown
@@ -99,7 +99,10 @@ files:
99
99
  - bin/standardrb
100
100
  - bridgetown-inline-svg.gemspec
101
101
  - lib/bridgetown-inline-svg.rb
102
- - lib/bridgetown-inline-svg/svg-tag.rb
102
+ - lib/bridgetown-inline-svg/markup.rb
103
+ - lib/bridgetown-inline-svg/render_optimized_svg.rb
104
+ - lib/bridgetown-inline-svg/render_svg.rb
105
+ - lib/bridgetown-inline-svg/tag.rb
103
106
  - lib/bridgetown-inline-svg/version.rb
104
107
  - media/banner.png
105
108
  homepage: https://github.com/andrewmcodes/bridgetown-inline-svg
@@ -1,144 +0,0 @@
1
- require "nokogiri"
2
- require "svg_optimizer"
3
- require "bridgetown-core/liquid_extensions"
4
-
5
- PLUGINS_BLOCKLIST = [
6
- SvgOptimizer::Plugins::CleanupId
7
- ]
8
-
9
- PLUGINS = SvgOptimizer::DEFAULT_PLUGINS.delete_if { |plugin|
10
- PLUGINS_BLOCKLIST.include? plugin
11
- }
12
-
13
- module BridgetownInlineSvg
14
- class SvgTag < Liquid::Tag
15
- # import lookup_variable function
16
- # https://github.com/bridgetownrb/bridgetown/blob/main/bridgetown-core/lib/bridgetown-core/liquid_extensions.rb
17
- include Bridgetown::LiquidExtensions
18
-
19
- # For interpoaltion, look for liquid variables
20
- VARIABLE = /\{\{\s*([\w.\-]+)\s*\}\}/i
21
-
22
- # Separate file path from other attributes
23
- PATH_SYNTAX = %r{
24
- ^(?<path>[^\s"']+|"[^"]+"|'[^']+')
25
- (?<params>.*)
26
- }x
27
-
28
- # parse the first parameter in a string, giving :
29
- # [full_match, param_name, double_quoted_val, single_quoted_val, unquoted_val]
30
- # The Regex works like :
31
- # - first group
32
- # - match a group of characters that is alphanumeric, _ or -.
33
- # - second group (non-capturing OR)
34
- # - match a double-quoted string
35
- # - match a single-quoted string
36
- # - match an unquoted string matching the set : [\w\.\-#]
37
- PARAM_SYNTAX = %r{
38
- ([\w-]+)\s*=\s*
39
- (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w.\-#]+))
40
- }x
41
-
42
- def initialize(tag_name, markup, tokens)
43
- super
44
- @svg, @params = BridgetownInlineSvg::SvgTag.parse_params(markup)
45
- end
46
-
47
- # lookup Liquid variables from markup in context
48
- def interpolate(markup, context)
49
- markup.scan VARIABLE do |variable|
50
- markup = markup.sub(VARIABLE, lookup_variable(context, variable.first))
51
- end
52
- markup
53
- end
54
-
55
- def split_params(markup, context)
56
- params = {}
57
- while (match = PARAM_SYNTAX.match(markup))
58
- markup = markup[match.end(0)..-1]
59
- value = if match[2]
60
- interpolate(match[2].gsub(%r{\\"}, '"'), context)
61
- elsif match[3]
62
- interpolate(match[3].gsub(%r{\\'}, "'"), context)
63
- elsif match[4]
64
- lookup_variable(context, match[4])
65
- end
66
- params[match[1]] = value
67
- end
68
- params
69
- end
70
-
71
- # Parse parameters. Returns : [svg_path, parameters]
72
- # Does not interpret variables as it's done at render time
73
- def self.parse_params(markup)
74
- matched = markup.strip.match(PATH_SYNTAX)
75
- unless matched
76
- raise SyntaxError, <<~END
77
- Syntax Error in tag 'svg' while parsing the following markup:
78
- #{markup}
79
- Valid syntax: svg <path> [property=value]
80
- END
81
- end
82
- path = matched["path"].sub(%r{^["']}, "").sub(%r{["']$}, "").strip
83
- params = matched["params"].strip
84
- [path, params]
85
- end
86
-
87
- def fmt(params)
88
- r = params.to_a.select { |v| v[1] != "" }.map { |v| %(#{v[0]}="#{v[1]}") }
89
- r.join(" ")
90
- end
91
-
92
- def create_plugin(params)
93
- mod = Class.new(SvgOptimizer::Plugins::Base) {
94
- def self.set(p)
95
- @@params = p
96
- end
97
-
98
- def process
99
- @@params.each { |key, val| xml.root.set_attribute(key, val) }
100
- xml
101
- end
102
- }
103
- mod.set(params)
104
- mod
105
- end
106
-
107
- def add_file_to_dependency(site, path, context)
108
- if context.registers[:page]&.key?("path")
109
- site.regenerator.add_dependency(
110
- site.in_source_dir(context.registers[:page]["path"]),
111
- path
112
- )
113
- end
114
- end
115
-
116
- def render(context)
117
- # global site variable
118
- site = context.registers[:site]
119
- # check if given name is a variable. Otherwise use it as a file name
120
- svg_file = Bridgetown.sanitized_path(site.source, interpolate(@svg, context))
121
- return unless svg_file
122
-
123
- add_file_to_dependency(site, svg_file, context)
124
- # replace variables with their current value
125
- params = split_params(@params, context)
126
- # because ie11 require to have a height AND a width
127
- if params.key?("width") && !params.key?("height")
128
- params["height"] = params["width"]
129
- end
130
- # params = @params
131
- file = File.open(svg_file, "rb").read
132
-
133
- conf = site.config["svg"] || {}
134
-
135
- if conf["optimize"] == true
136
- SvgOptimizer.optimize(file, [create_plugin(params)] + PLUGINS)
137
- else
138
- xml = Nokogiri::XML(file)
139
- params.each { |key, val| xml.root.set_attribute(key, val) }
140
- xml.root.to_xml
141
- end
142
- end
143
- end
144
- end