bridgetown-inline-svg 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|