bridgetown-inline-svg 1.0.0
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 +7 -0
- data/.gem_release.yml +4 -0
- data/.github/CODEOWNERS +1 -0
- data/.github/FUNDING.yml +12 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +24 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +23 -0
- data/.github/workflows/linters.yml +34 -0
- data/.github/workflows/pr_tests.yml +31 -0
- data/.github/workflows/tests.yml +33 -0
- data/.gitignore +39 -0
- data/.rspec +2 -0
- data/.solargraph.yml +15 -0
- data/.vscode/settings.json +26 -0
- data/CHANGELOG.md +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +24 -0
- data/Gemfile +18 -0
- data/LICENSE +674 -0
- data/README.md +139 -0
- data/Rakefile +8 -0
- data/SECURITY.md +14 -0
- data/_README.md +5 -0
- data/bin/check +3 -0
- data/bin/checks/standardrb +4 -0
- data/bin/console +14 -0
- data/bin/format +3 -0
- data/bin/formatters/standardrb +4 -0
- data/bin/rspec +29 -0
- data/bin/setup +8 -0
- data/bin/standardrb +29 -0
- data/bridgetown-inline-svg.gemspec +37 -0
- data/lib/bridgetown-inline-svg.rb +9 -0
- data/lib/bridgetown-inline-svg/svg-tag.rb +142 -0
- data/lib/bridgetown-inline-svg/version.rb +5 -0
- metadata +132 -0
data/README.md
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
<h1 align="center">Welcome to bridgetown-inline-svg 👋</h1>
|
2
|
+
<p>
|
3
|
+
<a href="LICENSE" target="_blank">
|
4
|
+
<img alt="License: GPL-3.0" src="https://img.shields.io/github/license/andrewmcodes/bridgetown-inline-svg" />
|
5
|
+
</a>
|
6
|
+
<a href="https://badge.fury.io/rb/bridgetown-inline-svg"><img src="https://badge.fury.io/rb/bridgetown-inline-svg.svg" alt="Gem Version" height="18"></a>
|
7
|
+
<a href="https://depfu.com"><img src="https://badges.depfu.com/badges/54fe87f2b14868b7c6e69aa0322e3764/status.svg" alt="Depfu"></a>
|
8
|
+
<a href="https://depfu.com/github/andrewmcodes/bridgetown-inline-svg?project_id=14094"><img src="https://badges.depfu.com/badges/54fe87f2b14868b7c6e69aa0322e3764/count.svg" alt="Depfu"></a>
|
9
|
+
<a href="https://codeclimate.com/github/andrewmcodes/bridgetown-inline-svg/maintainability"><img src="https://api.codeclimate.com/v1/badges/f9756d6568f43c7a407b/maintainability" /></a>
|
10
|
+
<a href="https://www.codacy.com/manual/andrewmcodes/bridgetown-inline-svg?utm_source=github.com&utm_medium=referral&utm_content=andrewmcodes/bridgetown-inline-svg&utm_campaign=Badge_Grade"><img src="https://app.codacy.com/project/badge/Grade/caad1b16367242ff973fe2e977985364" alt="Codacy Badge"></a>
|
11
|
+
<a href='https://coveralls.io/github/andrewmcodes/bridgetown-inline-svg?branch=main'><img src='https://coveralls.io/repos/github/andrewmcodes/bridgetown-inline-svg/badge.svg?branch=main' alt='Coverage Status' /></a>
|
12
|
+
<img alt="Tests" src="https://github.com/andrewmcodes/bridgetown-inline-svg/workflows/Tests/badge.svg" />
|
13
|
+
<img alt="Linters" src="https://github.com/andrewmcodes/bridgetown-inline-svg/workflows/Linters/badge.svg" />
|
14
|
+
</p>
|
15
|
+
|
16
|
+
> SVG optimizer and inliner for Bridgetown
|
17
|
+
|
18
|
+
- [Installation](#installation)
|
19
|
+
- [Optional configuration options](#optional-configuration-options)
|
20
|
+
- [Usage](#usage)
|
21
|
+
- [Optimizations](#optimizations)
|
22
|
+
- [Author](#author)
|
23
|
+
- [Contributing](#contributing)
|
24
|
+
- [Show your support](#show-your-support)
|
25
|
+
- [Acknowledgement](#acknowledgement)
|
26
|
+
- [License](#license)
|
27
|
+
|
28
|
+
## Installation
|
29
|
+
|
30
|
+
Run this command to add this plugin to your site's Gemfile:
|
31
|
+
|
32
|
+
```shell
|
33
|
+
bundle add bridgetown-inline-svg -g bridgetown_plugins
|
34
|
+
```
|
35
|
+
|
36
|
+
or add the following to your `Gemfile`:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
group :bridgetown_plugins do
|
40
|
+
gem "bridgetown-inline-svg", "~> 0.0.1"
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
### Optional configuration options
|
45
|
+
|
46
|
+
Optimization is opt-in and can be enabled by adding this to your `bridgetown.config.yml`
|
47
|
+
|
48
|
+
```
|
49
|
+
svg:
|
50
|
+
optimize: true
|
51
|
+
```
|
52
|
+
|
53
|
+
## Usage
|
54
|
+
|
55
|
+
Use the Liquid tag in your pages :
|
56
|
+
|
57
|
+
```liquid
|
58
|
+
{% svg /path/to/square.svg width=24 foo="bar" %}
|
59
|
+
```
|
60
|
+
|
61
|
+
Bridgetown will include the svg file in your output HTML like this :
|
62
|
+
|
63
|
+
```html
|
64
|
+
<svg width=24 foo="bar" version="1.1" id="square" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 24 24" >
|
65
|
+
<rect width="20" height="20" x="2" y="2" />
|
66
|
+
</svg>
|
67
|
+
```
|
68
|
+
|
69
|
+
**Note** : You will generally want to set the width/height of your SVG or a `style` attribute, but anything can be passed through.
|
70
|
+
|
71
|
+
Paths with a space should be quoted :
|
72
|
+
|
73
|
+
```liquid
|
74
|
+
{% svg "/path/to/foo bar.svg" %}
|
75
|
+
# or :
|
76
|
+
{% svg '/path/to/foo bar.svg' %}
|
77
|
+
```
|
78
|
+
Otherwise anything after the first space will be considered an attribute.
|
79
|
+
|
80
|
+
Liquid variables will be interpreted if enclosed in double brackets :
|
81
|
+
|
82
|
+
```liquid
|
83
|
+
{% assign size=40 %}
|
84
|
+
{% svg "/path/to/{{site.foo-name}}.svg" width="{{size}}" %}
|
85
|
+
```
|
86
|
+
|
87
|
+
`height` is automatically set to match `width` if omitted. It can't be left unset because IE11 won't use the viewport attribute to calculate the image's aspect ratio.
|
88
|
+
|
89
|
+
Relative paths and absolute paths will both be interpreted from Bridgetown's `src` directory. So both:
|
90
|
+
|
91
|
+
```liquid
|
92
|
+
{% svg "/path/to/foo.svg" %}
|
93
|
+
{% svg "path/to/foo.svg" %}
|
94
|
+
```
|
95
|
+
|
96
|
+
Should resolve to `/your/site/src/path/to/foo.svg`.
|
97
|
+
|
98
|
+
### Optimizations
|
99
|
+
|
100
|
+
Some processing is done to remove useless data when enabled:
|
101
|
+
|
102
|
+
- metadata
|
103
|
+
- comments
|
104
|
+
- unused groups
|
105
|
+
- Other filters from [svg_optimizer](https://github.com/fnando/svg_optimizer)
|
106
|
+
- default size
|
107
|
+
|
108
|
+
If any important data gets removed, or the output SVG looks different from input, it's a bug. Please file an issue to this repository describing your problem.
|
109
|
+
|
110
|
+
It does not perform any input validation on attributes. They will be appended as-is to the root node.
|
111
|
+
|
112
|
+
## Author
|
113
|
+
|
114
|
+
👤 **Andrew Mason**
|
115
|
+
|
116
|
+
* Website: https://www.andrewm.codes
|
117
|
+
* Twitter: [@andrewmcodes](https://twitter.com/andrewmcodes)
|
118
|
+
* Github: [@andrewmason](https://github.com/andrewmason)
|
119
|
+
|
120
|
+
## Contributing
|
121
|
+
|
122
|
+
Contributions, issues and feature requests are welcome!<br />Feel free to check [issues page](https://github.com/andrewmcodes/bridgetown-inline-svg/issues). You can also take a look at the [contributing guide](https://github.com/andrewmcodes/bridgetown-inline-svg/blob/main/CONTRIBUTING.md).
|
123
|
+
|
124
|
+
## Show your support
|
125
|
+
|
126
|
+
Give a ⭐️ if this project helped you!
|
127
|
+
|
128
|
+
## Acknowledgement
|
129
|
+
|
130
|
+
This project was initially forked from [jekyll-inline-svg](https://github.com/sdumetz/jekyll-inline-svg).
|
131
|
+
|
132
|
+
## License
|
133
|
+
|
134
|
+
Copyright © 2017-2020 [Sebastien Dumetz](https://github.com/sdumetz)
|
135
|
+
Copyright © 2020 [Andrew Mason](https://github.com/andrewmcodes)
|
136
|
+
|
137
|
+
The following code is a derivative work of the code from the [jekyll-inline-svg](https://github.com/sdumetz/jekyll-inline-svg) project, which is licensed GPLv3. This code therefore is also licensed under the terms of the GNU Public License, verison 3.
|
138
|
+
|
139
|
+
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2Fandrewmcodes%2Fbridgetown-inline-svg?ref=badge_large" alt="FOSSA Status"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2Fandrewmcodes%2Fbridgetown-inline-svg.svg?type=large"/></a>
|
data/Rakefile
ADDED
data/SECURITY.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Security Policy
|
2
|
+
|
3
|
+
## Supported Versions
|
4
|
+
|
5
|
+
Security backports will be provided for some previous release series if needed.
|
6
|
+
|
7
|
+
| Version | Supported |
|
8
|
+
| ------- | ------------------ |
|
9
|
+
| 0.0.x | :white_check_mark: |
|
10
|
+
|
11
|
+
|
12
|
+
## Reporting a Vulnerability
|
13
|
+
|
14
|
+
If you find a security issue with this gem, please open an issue, or email [Andrew Mason](mailto:andrew@andrewm.codes).
|
data/_README.md
ADDED
data/bin/check
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "dev_api"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/format
ADDED
data/bin/rspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/bin/setup
ADDED
data/bin/standardrb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'standardrb' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("standard", "standardrb")
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/bridgetown-inline-svg/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "bridgetown-inline-svg"
|
7
|
+
spec.version = BridgetownInlineSvg::VERSION
|
8
|
+
spec.authors = ["Andrew Mason"]
|
9
|
+
spec.email = ["andrewmcodes@protonmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "A SVG Inliner for Bridgetown"
|
12
|
+
spec.description = <<-EOF
|
13
|
+
A Liquid tag to inline and optimize SVG images in your HTML
|
14
|
+
Supports custom DOM Attributes parameters and variables interpretation.
|
15
|
+
EOF
|
16
|
+
spec.homepage = "https://github.com/andrewmcodes/bridgetown-inline-svg"
|
17
|
+
spec.license = "GPL-3.0"
|
18
|
+
|
19
|
+
spec.metadata = {
|
20
|
+
"bug_tracker_uri" => "#{spec.homepage}/issues",
|
21
|
+
"changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md",
|
22
|
+
"documentation_uri" => spec.homepage.to_s,
|
23
|
+
"homepage_uri" => spec.homepage.to_s,
|
24
|
+
"source_code_uri" => spec.homepage.to_s
|
25
|
+
}
|
26
|
+
|
27
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|script|spec|features|frontend)/}) }
|
28
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
|
31
|
+
spec.required_ruby_version = ">= 2.5.0"
|
32
|
+
|
33
|
+
spec.add_dependency "bridgetown", ">= 0.15", "< 2.0"
|
34
|
+
spec.add_dependency "svg_optimizer", "~> 0.2.5"
|
35
|
+
|
36
|
+
spec.add_development_dependency "nokogiri", "~> 1.6"
|
37
|
+
end
|
@@ -0,0 +1,142 @@
|
|
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 'highlight' 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
|
+
add_file_to_dependency(site, svg_file, context)
|
123
|
+
# replace variables with their current value
|
124
|
+
params = split_params(@params, context)
|
125
|
+
# because ie11 require to have a height AND a width
|
126
|
+
if params.key?("width") && !params.key?("height")
|
127
|
+
params["height"] = params["width"]
|
128
|
+
end
|
129
|
+
# params = @params
|
130
|
+
file = File.open(svg_file, "rb").read
|
131
|
+
conf = lookup_variable(context, "site.svg")
|
132
|
+
if conf["optimize"] == true
|
133
|
+
xml = SvgOptimizer.optimize(file, [create_plugin(params)] + PLUGINS)
|
134
|
+
else
|
135
|
+
xml = Nokogiri::XML(file)
|
136
|
+
params.each { |key, val| xml.root.set_attribute(key, val) }
|
137
|
+
xml = xml.root.to_xml
|
138
|
+
end
|
139
|
+
xml
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|