jekyll_plugin_support 0.1.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 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
+ ...