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 +4 -4
- data/CHANGELOG.md +13 -1
- data/lib/bridgetown-inline-svg.rb +4 -5
- data/lib/bridgetown-inline-svg/markup.rb +94 -0
- data/lib/bridgetown-inline-svg/render_optimized_svg.rb +34 -0
- data/lib/bridgetown-inline-svg/render_svg.rb +24 -0
- data/lib/bridgetown-inline-svg/tag.rb +62 -0
- data/lib/bridgetown-inline-svg/version.rb +1 -1
- metadata +6 -3
- data/lib/bridgetown-inline-svg/svg-tag.rb +0 -144
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1c8e18d390771eeb4fddd2b1dbfb6d82357b55c21fdf8445af38506bb7ba4fc
|
4
|
+
data.tar.gz: 2e75d828cd0dd039dcb91e9efa5b3d9251c80bebfcadf8ea329dd3f80874c9cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5aca7788bc7464fc726a03bd9a3aed7d9d8831d4a86dc3f55ff6a5809e3164865d60e8bddead21bf1147f28e68e7eed0e13f0f141ede345f7e3be0091f60289
|
7
|
+
data.tar.gz: 737e94de18e8f7fdbfef74439f7dc14aa586cb49f0eb7513d9b1aedc4c34ceb855af7d43f341b7694c90fc41a70ad72902c09e0c8cc1c88e9406500e67439a56
|
data/CHANGELOG.md
CHANGED
@@ -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.
|
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 :
|
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
|
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.
|
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-
|
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/
|
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
|