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.
@@ -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&amp;utm_medium=referral&amp;utm_content=andrewmcodes/bridgetown-inline-svg&amp;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>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -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).
@@ -0,0 +1,5 @@
1
+ # bridgetown-inline-svg
2
+
3
+ SVG optimizer and inliner for [Bridgetown](https://www.bridgetownrb.com)
4
+
5
+ This liquid tag will let you inline SVG images in your bridgetown sites. It will add `{%svg %}` to `Liquid::Tag`.
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ bin/checks/standardrb
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ echo "== Checking StandardRb =="
4
+ bundle exec standardrb --format=progress
@@ -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__)
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ bin/formatters/standardrb
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ echo "== StandardRb =="
4
+ bundle exec standardrb --fix --format=progress
@@ -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")
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bridgetown"
4
+
5
+ module BridgetownInlineSvg
6
+ autoload :SvgTag, "bridgetown-inline-svg/svg-tag"
7
+ end
8
+
9
+ Liquid::Template.register_tag("svg", BridgetownInlineSvg::SvgTag)
@@ -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