jekyll_plugin_support 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6d7d771129ced9b40dd3910fd9a36104e3c497bd26a20a4bb0ce821abceca7de
4
+ data.tar.gz: dcbf44d0d30980e90aff16792fc59d33a6e3c6e3a0f9d757f26184894499180a
5
+ SHA512:
6
+ metadata.gz: c32a692546b9f806ee3325396a804ab9b0b2c30dd2aa835dbd989d924f10e959b04dd85608315bf4412fa2cf89c70ff06c278348f4d837a9e1da1eb748952f9e
7
+ data.tar.gz: a126b88309c016407baad103e09f6c3e4eb554962ad8aabfbe31b31565001c9a98003bc7b56889329c669d638de75c255f939dd06b151c4a548dcdeac4daa4f7
data/.rubocop.yml ADDED
@@ -0,0 +1,16 @@
1
+ AllCops:
2
+ Exclude:
3
+ - vendor/**/*
4
+ - Gemfile*
5
+ - '*.gemspec' # This does nothing. Why?
6
+ NewCops: enable
7
+ TargetRubyVersion: 2.6
8
+
9
+ Layout/HashAlignment:
10
+ Enabled: false
11
+
12
+ Layout/LineLength:
13
+ Max: 150
14
+
15
+ Layout/MultilineMethodCallIndentation:
16
+ Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ ## 0.1.0 / 2023-01-10
2
+ * Initial version; only supports Jekyll block tags
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Mike Slinn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ `jekyll_plugin_support`
2
+ [![Gem Version](https://badge.fury.io/rb/jekyll_plugin_support.svg)](https://badge.fury.io/rb/jekyll_plugin_support)
3
+ ===========
4
+
5
+ `jekyll_plugin_support` is a Ruby gem that facilitates writing and testing Jekyll plugins.
6
+ At present only Jekyll block tags are supported.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your Jekyll plugin's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'jekyll_plugin_support'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle install
19
+
20
+
21
+ ## Additional Information
22
+ More information is available on
23
+ [Mike Slinn’s website](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html).
24
+
25
+
26
+ ## Development
27
+
28
+ After checking out the repo, run `bin/setup` to install dependencies.
29
+
30
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
31
+
32
+
33
+ To build and install this gem onto your local machine, run:
34
+ ```shell
35
+ $ bundle exec rake install
36
+ jekyll_plugin_support 0.1.0 built to pkg/jekyll_plugin_support-0.1.0.gem.
37
+ jekyll_plugin_support (0.1.0) installed.
38
+ ```
39
+
40
+ Examine the newly built gem:
41
+ ```shell
42
+ $ gem info jekyll_plugin_support
43
+
44
+ *** LOCAL GEMS ***
45
+
46
+ jekyll_plugin_support (0.1.0)
47
+ Author: Mike Slinn
48
+ Homepage:
49
+ https://github.com/mslinn/jekyll_plugin_support
50
+ License: MIT
51
+ Installed at: /home/mslinn/.gems
52
+
53
+ Generates Jekyll logger with colored output.
54
+ ```
55
+
56
+
57
+ ### Build and Push to RubyGems
58
+ To release a new version,
59
+ 1. Update the version number in `version.rb`.
60
+ 2. Commit all changes to git; if you don't the next step might fail with an unexplainable error message.
61
+ 3. Run the following:
62
+ ```shell
63
+ $ bundle exec rake release
64
+ ```
65
+ The above creates a git tag for the version, commits the created tag,
66
+ and pushes the new `.gem` file to [RubyGems.org](https://rubygems.org).
67
+
68
+
69
+ ## Contributing
70
+
71
+ 1. Fork the project
72
+ 2. Create a descriptively named feature branch
73
+ 3. Add your feature
74
+ 4. Submit a pull request
75
+
76
+
77
+ ## License
78
+
79
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,7 @@
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
+ task :default => :spec
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/jekyll_plugin_support/version'
4
+
5
+ # rubocop:disable Metrics/BlockLength
6
+ Gem::Specification.new do |spec|
7
+ github = 'https://github.com/mslinn/jekyll_plugin_support'
8
+
9
+ spec.bindir = 'exe'
10
+ spec.authors = ['Mike Slinn']
11
+ spec.email = ['mslinn@mslinn.com']
12
+ spec.files = Dir['.rubocop.yml', 'LICENSE.*', 'Rakefile', '{lib,spec}/**/*', '*.gemspec', '*.md']
13
+ spec.homepage = 'https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#quote'
14
+ spec.license = 'MIT'
15
+ spec.metadata = {
16
+ 'allowed_push_host' => 'https://rubygems.org',
17
+ 'bug_tracker_uri' => "#{github}/issues",
18
+ 'changelog_uri' => "#{github}/CHANGELOG.md",
19
+ 'homepage_uri' => spec.homepage,
20
+ 'source_code_uri' => github,
21
+ }
22
+ spec.name = 'jekyll_plugin_support'
23
+ spec.post_install_message = <<~END_MESSAGE
24
+
25
+ Thanks for installing #{spec.name}!
26
+
27
+ END_MESSAGE
28
+ spec.post_install_message = <<~END_MESSAGE
29
+
30
+ Thanks for installing #{spec.name}!
31
+
32
+ END_MESSAGE
33
+ spec.require_paths = ['lib']
34
+ spec.required_ruby_version = '>= 2.6.0'
35
+ spec.summary = 'Provides support for writing Jekyll plugins.'
36
+ spec.test_files = spec.files.grep %r{^(test|spec|features)/}
37
+ spec.version = JekyllQuoteVersion::VERSION
38
+
39
+ spec.add_dependency 'jekyll', '>= 3.5.0'
40
+ spec.add_dependency 'jekyll_plugin_logger'
41
+ spec.add_dependency 'key-value-parser'
42
+
43
+ # spec.add_development_dependency 'debase'
44
+ # spec.add_development_dependency 'rspec-match_ignoring_whitespace'
45
+ # spec.add_development_dependency 'rubocop-jekyll'
46
+ # spec.add_development_dependency 'rubocop-rake'
47
+ spec.add_development_dependency 'rubocop-rspec'
48
+ # spec.add_development_dependency 'ruby-debug-ide'
49
+ end
50
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllQuoteVersion
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll'
4
+ require 'jekyll_plugin_logger'
5
+ require_relative 'jekyll_plugin_support_helper'
6
+ require_relative 'jekyll_plugin_support/version'
7
+
8
+ # @author Copyright 2022 Michael Slinn
9
+ # @license SPDX-License-Identifier: Apache-2.0
10
+ module JekyllSupport
11
+ # Base class for Jekyll block tags
12
+ class JekyllBlock < Liquid::Block
13
+ attr_reader :argument_string, :helper, :line_number, :logger, :page, :site, :text
14
+
15
+ # See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
16
+ # @param tag_name [String] the name of the tag, which we usually know.
17
+ # @param argument_string [String] the arguments passed to the tag, as a single string.
18
+ # @param parse_context [Liquid::ParseContext] hash that stores Liquid options.
19
+ # By default it has two keys: :locale and :line_numbers, the first is a Liquid::I18n object, and the second,
20
+ # a boolean parameter that determines if error messages should display the line number the error occurred.
21
+ # This argument is used mostly to display localized error messages on Liquid built-in Tags and Filters.
22
+ # See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
23
+ # @return [void]
24
+ def initialize(tag_name, argument_string, parse_context)
25
+ super
26
+ @logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
27
+ @helper = JekyllPluginHelper.new(tag_name, argument_string, @logger)
28
+ @argument_string = argument_string
29
+ end
30
+
31
+ # Method prescribed by the Jekyll plugin lifecycle.
32
+ # @return [String]
33
+ def render(context)
34
+ text = super
35
+ render_impl text
36
+ end
37
+
38
+ # Jekyll plugins should override this method, not render, so their plugin can be tested more easily
39
+ # @return [String]
40
+ def render_impl(text)
41
+ text
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shellwords'
4
+ require 'key_value_parser'
5
+
6
+ # Base class for all types of Jekyll plugin helpers
7
+ class JekyllPluginHelper
8
+ attr_reader :argv, :keys_values, :liquid_context, :logger, :markup, :params, :tag_name
9
+
10
+ # Expand a environment variable reference
11
+ def self.expand_env(str, die_if_undefined: false)
12
+ str.gsub(/\$([a-zA-Z_][a-zA-Z0-9_]*)|\${\g<1>}|%\g<1>%/) do
13
+ envar = Regexp.last_match(1)
14
+ raise HrefError, "jekyll_href error: #{envar} is undefined".red, [] \
15
+ if !ENV.key?(envar) && die_if_undefined # Suppress stack trace
16
+
17
+ ENV[envar]
18
+ end
19
+ end
20
+
21
+ # strip leading and trailing quotes if present
22
+ def self.remove_quotes(string)
23
+ string.strip.gsub(/\A'|\A"|'\Z|"\Z/, '').strip if string
24
+ end
25
+
26
+ def initialize(tag_name, markup, logger)
27
+ # @keys_values was a Hash[Symbol, String|Boolean] but now it is Hash[String, String|Boolean]
28
+ @tag_name = tag_name
29
+ @markup = markup # Useful for debugging
30
+ @argv = Shellwords.split(JekyllPluginHelper.expand_env(markup))
31
+ @keys_values = KeyValueParser \
32
+ .new({}, { array_values: false, normalize_keys: false, separator: /=/ }) \
33
+ .parse(@argv)
34
+ @logger = logger
35
+ @logger.debug { "@keys_values='#{@keys_values}'" }
36
+ end
37
+
38
+ def delete_parameter(key)
39
+ return if @keys_values.empty? || @params.nil?
40
+
41
+ @params.delete(key)
42
+ @argv.delete_if { |x| x == key or x.start_with?("#{key}=") }
43
+ @keys_values.delete(key)
44
+ end
45
+
46
+ # @return if parameter was specified, removes it from the available tokens and returns value
47
+ def parameter_specified?(name)
48
+ return false if @keys_values.empty?
49
+
50
+ key = name
51
+ key = name.to_sym if @keys_values.first.first.instance_of?(Symbol)
52
+ value = @keys_values[key]
53
+ delete_parameter(name)
54
+ value
55
+ end
56
+
57
+ PREDEFINED_SCOPE_KEYS = %i[include page].freeze
58
+
59
+ # Finds variables defined in an invoking include, or maybe somewhere else
60
+ # @return variable value or nil
61
+ def dereference_include_variable(name)
62
+ @liquid_context.scopes.each do |scope|
63
+ next if PREDEFINED_SCOPE_KEYS.include? scope.keys.first
64
+
65
+ value = scope[name]
66
+ return value if value
67
+ end
68
+ nil
69
+ end
70
+
71
+ # @return value of variable, or the empty string
72
+ def dereference_variable(name)
73
+ value = @liquid_context[name] # Finds variables named like 'include.my_variable', found in @liquid_context.scopes.first
74
+ value ||= @page[name] if @page # Finds variables named like 'page.my_variable'
75
+ value ||= dereference_include_variable(name)
76
+ value ||= ''
77
+ value
78
+ end
79
+
80
+ # Sets @params by replacing any Liquid variable names with their values
81
+ def liquid_context=(context)
82
+ @liquid_context = context
83
+ @params = @keys_values.map { |k, _v| lookup_variable(k) }
84
+ end
85
+
86
+ def lookup_variable(symbol)
87
+ string = symbol.to_s
88
+ return string unless string.start_with?('{{') && string.end_with?('}}')
89
+
90
+ dereference_variable(string.delete_prefix('{{').delete_suffix('}}'))
91
+ end
92
+
93
+ def page
94
+ @liquid_context.registers[:page]
95
+ end
96
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll'
4
+
5
+ Registers = Struct.new(:page, :site)
6
+
7
+ # Mock for Collections
8
+ class Collections
9
+ def values
10
+ []
11
+ end
12
+ end
13
+
14
+ # Mock for Site
15
+ class SiteMock
16
+ attr_reader :config
17
+
18
+ def collections
19
+ Collections.new
20
+ end
21
+ end
22
+
23
+ # Mock for Liquid::ParseContent
24
+ class TestParseContext < Liquid::ParseContext
25
+ attr_reader :line_number, :registers
26
+
27
+ # rubocop:disable Layout/CommentIndentation
28
+ # def initialize
29
+ # super
30
+ # @line_number = 123
31
+
32
+ # @registers = Registers.new(
33
+ # { 'path' => 'https://feeds.soundcloud.com/users/soundcloud:users:7143896/sounds.rss' },
34
+ # SiteMock.new
35
+ # )
36
+ # end
37
+ # rubocop:enable Layout/CommentIndentation
38
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll_plugin_logger'
4
+ # require 'rspec/match_ignoring_whitespace'
5
+ require_relative '../lib/jekyll_plugin_support'
6
+ require_relative '../lib/jekyll_plugin_support_spec_support'
7
+
8
+ # Lets get this party started
9
+ class MyTest
10
+ RSpec.describe Jekyll::Quote do
11
+ let(:logger) do
12
+ PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
13
+ end
14
+
15
+ let(:parse_context) { TestParseContext.new }
16
+
17
+ # Example for plugin authors to refer to:
18
+ #
19
+ # let(:helper) do
20
+ # JekyllTagHelper.new(
21
+ # 'quote',
22
+ # "cite='This is a citation' url='https://blah.com' This is the quoted text.",
23
+ # logger
24
+ # )
25
+ # end
26
+ #
27
+ # fit 'is created properly' do
28
+ # command_line = "cite='This is a citation' url='https://blah.com' This is the quoted text.".dup
29
+ # quote = Jekyll::Quote.send(
30
+ # :new,
31
+ # 'quote',
32
+ # command_line,
33
+ # parse_context
34
+ # )
35
+ # result = quote.send(:render_impl, command_line)
36
+ # expect(result).to match_ignoring_whitespace <<-END_RESULT
37
+ # <div class='quote'>
38
+ # This is the quoted text.
39
+ # </div>
40
+ # END_RESULT
41
+ # end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll'
4
+ require_relative '../lib/jekyll_plugin_support'
5
+
6
+ RSpec.configure do |config|
7
+ config.filter_run :focus
8
+ config.order = 'random'
9
+ config.run_all_when_everything_filtered = true
10
+
11
+ # See https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures
12
+ config.example_status_persistence_file_path = 'spec/status_persistence.txt'
13
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll_plugin_support
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mike Slinn
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-01-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 3.5.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.5.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: jekyll_plugin_logger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: key-value-parser
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - mslinn@mslinn.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".rubocop.yml"
77
+ - CHANGELOG.md
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - jekyll_plugin_support.gemspec
82
+ - lib/jekyll_plugin_support.rb
83
+ - lib/jekyll_plugin_support/version.rb
84
+ - lib/jekyll_plugin_support_helper.rb
85
+ - lib/jekyll_plugin_support_spec_support.rb
86
+ - spec/jekyll_plugin_support_spec.rb
87
+ - spec/spec_helper.rb
88
+ homepage: https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#quote
89
+ licenses:
90
+ - MIT
91
+ metadata:
92
+ allowed_push_host: https://rubygems.org
93
+ bug_tracker_uri: https://github.com/mslinn/jekyll_plugin_support/issues
94
+ changelog_uri: https://github.com/mslinn/jekyll_plugin_support/CHANGELOG.md
95
+ homepage_uri: https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#quote
96
+ source_code_uri: https://github.com/mslinn/jekyll_plugin_support
97
+ post_install_message: |2+
98
+
99
+ Thanks for installing jekyll_plugin_support!
100
+
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 2.6.0
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubygems_version: 3.3.3
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Provides support for writing Jekyll plugins.
119
+ test_files:
120
+ - spec/jekyll_plugin_support_spec.rb
121
+ - spec/spec_helper.rb
122
+ ...