jekyll_plugin_support 0.5.1 → 0.5.3
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 +4 -4
- data/.rubocop.yml +24 -4
- data/CHANGELOG.md +11 -0
- data/README.md +54 -1
- data/jekyll_plugin_support.gemspec +1 -1
- data/lib/jekyll_plugin_support/version.rb +1 -1
- data/lib/jekyll_plugin_support_helper.rb +49 -27
- data/spec/jekyll_block_plugin_support_spec.rb +51 -32
- data/spec/spec_helper.rb +1 -1
- data/spec/status_persistence.txt +6 -0
- metadata +2 -4
- data/spec/jekyll_tag_plugin_support_spec.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16fe00b243305d30e8dff85f604336e9c9802afe837a762dd295bd7283d8e1d4
|
4
|
+
data.tar.gz: c4ae30a570d27d77d17d7710be941731aefeaf11e4c2e19ec9f8fb773a9ad01d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0abe907f3c564efdf0192279e1d7b2553f3fe97ecb9cbac989defe6a9051979c295db7b0e5917a9c954bc1faab1b42b3fb88b1ac6ef4d20cf3b49217b859fae
|
7
|
+
data.tar.gz: fe6027eaccdc0e46de5d98bc954e17600d088e988fbe3798cb2ad842cdcf8b5d417cd2fdd6bdb0d27f517831d81dd8956444235c23767db222634c579d2d60e6
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,11 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rspec
|
3
|
+
- rubocop-rake
|
4
|
+
# - rubocop-jekyll
|
5
|
+
|
1
6
|
AllCops:
|
2
7
|
Exclude:
|
8
|
+
- demo/_site/**/*
|
3
9
|
- exe/**/*
|
4
10
|
- vendor/**/*
|
5
11
|
- Gemfile*
|
@@ -13,16 +19,24 @@ Gemspec/RequireMFA:
|
|
13
19
|
Enabled: false
|
14
20
|
|
15
21
|
Layout/HashAlignment:
|
16
|
-
|
22
|
+
EnforcedHashRocketStyle: table
|
17
23
|
|
18
24
|
Layout/LineLength:
|
19
25
|
Max: 150
|
20
26
|
|
27
|
+
Layout/CommentIndentation:
|
28
|
+
Exclude:
|
29
|
+
- spec/**/*
|
30
|
+
|
21
31
|
Layout/MultilineMethodCallIndentation:
|
22
32
|
Enabled: false
|
23
33
|
|
34
|
+
Lint/RedundantCopDisableDirective:
|
35
|
+
Exclude:
|
36
|
+
- jekyll_plugin_support.gemspec
|
37
|
+
|
24
38
|
Metrics/AbcSize:
|
25
|
-
Max:
|
39
|
+
Max: 30
|
26
40
|
|
27
41
|
Metrics/BlockLength:
|
28
42
|
Exclude:
|
@@ -31,11 +45,17 @@ Metrics/BlockLength:
|
|
31
45
|
Metrics/MethodLength:
|
32
46
|
Max: 25
|
33
47
|
|
34
|
-
|
35
|
-
|
48
|
+
RSpec/ExampleLength:
|
49
|
+
Max: 20
|
50
|
+
|
51
|
+
RSpec/MultipleExpectations:
|
52
|
+
Max: 15
|
36
53
|
|
37
54
|
Style/Documentation:
|
38
55
|
Enabled: false
|
39
56
|
|
57
|
+
Style/FrozenStringLiteralComment:
|
58
|
+
Enabled: false
|
59
|
+
|
40
60
|
Style/TrailingCommaInHashLiteral:
|
41
61
|
EnforcedStyleForMultiline: comma
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 0.5.3 / 2023-03-19
|
2
|
+
* Added properties `argv_original`, `keys_values_original`, `remaining_markup_original`,
|
3
|
+
and `params_original`, which are the original values of `argv`, `keys_values`,
|
4
|
+
`remaining_markup`, and `params`, before environment variable expansion.
|
5
|
+
|
6
|
+
## 0.5.2 / 2023-03-17
|
7
|
+
* Added `@helper.remaining_markup` public method, which returns remaining markup passed to your tag, after keyword and name/value parsing is complete.
|
8
|
+
* Finally wrote proper `rspec` tests.
|
9
|
+
* Finally documented argument parsing.
|
10
|
+
* Fixed bug introduced in v0.5.1 which did not remove elements from `@params`.
|
11
|
+
|
1
12
|
## 0.5.1 / 2023-02-17
|
2
13
|
* `no_arg_parsing` optimization added.
|
3
14
|
|
data/README.md
CHANGED
@@ -109,6 +109,59 @@ module Jekyll
|
|
109
109
|
end
|
110
110
|
```
|
111
111
|
|
112
|
+
### Argument Parsing
|
113
|
+
Tag arguments can be obtained within `render_impl`.
|
114
|
+
Both keyword options and name/value parameters are supported.
|
115
|
+
|
116
|
+
Both `JekyllTag` and `JekyllBlock` use the standard Ruby mechanism for parsing command-line options:
|
117
|
+
[`shellwords`](https://ruby-doc.org/stdlib-2.5.1/libdoc/shellwords/rdoc/Shellwords.html) and
|
118
|
+
[`key_value_parser`](https://www.rubydoc.info/gems/key-value-parser).
|
119
|
+
|
120
|
+
All your code has to do is to specify the keywords to search for in the string passed from the HTML page that your tag is embedded in.
|
121
|
+
The included `demo` website has examples; both [`demo/_plugins/demo_tag.rb`](demo/_plugins/demo_tag.rb) and
|
122
|
+
[`demo/_plugins/demo_block.rb`](demo/_plugins/demo_block.rb) contain the following:
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
@keyword1 = @helper.parameter_specified? 'keyword1'
|
126
|
+
@keyword2 = @helper.parameter_specified? 'keyword2'
|
127
|
+
@name1 = @helper.parameter_specified? 'name1'
|
128
|
+
@name2 = @helper.parameter_specified? 'name2'
|
129
|
+
```
|
130
|
+
|
131
|
+
In [`demo/index.html`](demo/index.html), the following invoked the tag:
|
132
|
+
|
133
|
+
```html
|
134
|
+
{% demo_tag keyword1 name1='value1' unreferenced_key unreferenced_name="unreferenced_value" %}
|
135
|
+
```
|
136
|
+
|
137
|
+
The `demo/_plugins/demo_tag.rb` plugin uses `@helper.parameter_specified?` provided by
|
138
|
+
`jekyll_support_plugin` to parse the string passed to the tag, which is
|
139
|
+
`keyword1 name1='value1' unreferenced_key unreferenced_name="unreferenced_value"`.
|
140
|
+
|
141
|
+
- Because `keyword1` was referenced by `@helper.parameter_specified?` above,
|
142
|
+
that keyword option is removed from the argument string.
|
143
|
+
- Because the `name1` key/value parameter was referenced by `@helper.parameter_specified?` above,
|
144
|
+
that name/value pair is removed from the argument string.
|
145
|
+
- The remainder of the argument string is now `unreferenced_key unreferenced_name="unreferenced_value"`.
|
146
|
+
|
147
|
+
Name/value parameters can be quoted; if the value consists of only one token then it does not need to be quoted.
|
148
|
+
The following name/value parameters all have the same result:
|
149
|
+
|
150
|
+
- `pay_tuesday="true"`
|
151
|
+
- `pay_tuesday='true'`
|
152
|
+
- `pay_tuesday=true`
|
153
|
+
- `pay_tuesday`
|
154
|
+
|
155
|
+
The following also have the same result, however note that because the value has more than one token, quotes must be used:
|
156
|
+
|
157
|
+
- `pay_tuesday="maybe not"`
|
158
|
+
- `pay_tuesday='maybe not'`
|
159
|
+
|
160
|
+
#### Remaining Markup
|
161
|
+
After your plugin has parsed all the keyword options and name/value parameters,
|
162
|
+
call `@helper.remaining_markup` to obtain the remaining markup that was passed to your plugin.
|
163
|
+
|
164
|
+
|
112
165
|
### `no_arg_parsing` Optimization
|
113
166
|
If your tag or block plugin only needs access to the raw arguments passed from the web page,
|
114
167
|
without tokenization, and you expect that the plugin might be invoked with large amounts of text,
|
@@ -147,7 +200,7 @@ jekyll_plugin_support (0.1.0)
|
|
147
200
|
License: MIT
|
148
201
|
Installed at: /home/mslinn/.gems
|
149
202
|
|
150
|
-
|
203
|
+
Provides support for writing Jekyll plugins.
|
151
204
|
```
|
152
205
|
|
153
206
|
|
@@ -2,8 +2,10 @@ require 'shellwords'
|
|
2
2
|
require 'key_value_parser'
|
3
3
|
|
4
4
|
# Base class for all types of Jekyll plugin helpers
|
5
|
-
class JekyllPluginHelper
|
6
|
-
|
5
|
+
class JekyllPluginHelper # rubocop:disable Metrics/ClassLength
|
6
|
+
attr_accessor :liquid_context
|
7
|
+
attr_reader :argv, :keys_values, :logger, :markup, :no_arg_parsing, :params, :tag_name,
|
8
|
+
:argv_original, :keys_values_original, :params_original
|
7
9
|
|
8
10
|
# Expand an environment variable reference
|
9
11
|
def self.expand_env(str, die_if_undefined: false)
|
@@ -53,12 +55,15 @@ class JekyllPluginHelper
|
|
53
55
|
@logger.debug { "@keys_values='#{@keys_values}'" }
|
54
56
|
end
|
55
57
|
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
# @return if parameter was specified, removes it from the available tokens and returns value
|
59
|
+
def parameter_specified?(name)
|
60
|
+
return false if @keys_values.empty?
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
+
key = name
|
63
|
+
key = name.to_sym if @keys_values.first.first.instance_of?(Symbol)
|
64
|
+
value = @keys_values[key]
|
65
|
+
delete_parameter(name)
|
66
|
+
value
|
62
67
|
end
|
63
68
|
|
64
69
|
def reinitialize(markup)
|
@@ -71,30 +76,39 @@ class JekyllPluginHelper
|
|
71
76
|
define_singleton_method(:parameter_specified?) { |_name| warn_parse(:parameter_specified?) }
|
72
77
|
define_singleton_method(:delete_parameter) { |_name| warn_parse(:delete_parameter) }
|
73
78
|
else
|
74
|
-
|
75
|
-
@keys_values = KeyValueParser \
|
76
|
-
.new({}, { array_values: false, normalize_keys: false, separator: /=/ }) \
|
77
|
-
.parse(@argv)
|
79
|
+
parse markup
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
83
|
+
# Call this method to return the remaining markup after `parameter_specified?` has been invoked.
|
84
|
+
def remaining_markup
|
85
|
+
@argv.join(' ')
|
86
|
+
end
|
87
|
+
|
88
|
+
def remaining_markup_original
|
89
|
+
@argv_original.join(' ')
|
90
|
+
end
|
91
|
+
|
92
|
+
def warn_fetch(variable)
|
93
|
+
abort "Error: Argument parsing was suppressed, but an attempt to obtain the value of #{variable} was made"
|
94
|
+
end
|
95
|
+
|
96
|
+
def warn_parse(meth)
|
97
|
+
abort "Error: Argument parsing was suppressed, but an attempt to invoke #{meth} was made"
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
81
102
|
def delete_parameter(key)
|
82
103
|
return if @keys_values.empty? || @params.nil?
|
83
104
|
|
84
105
|
@params.delete(key)
|
85
106
|
@argv.delete_if { |x| x == key or x.start_with?("#{key}=") }
|
86
107
|
@keys_values.delete(key)
|
87
|
-
end
|
88
108
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
key = name
|
94
|
-
key = name.to_sym if @keys_values.first.first.instance_of?(Symbol)
|
95
|
-
value = @keys_values[key]
|
96
|
-
delete_parameter(name)
|
97
|
-
value
|
109
|
+
@params_original.delete(key)
|
110
|
+
@argv_original.delete_if { |x| x == key or x.start_with?("#{key}=") }
|
111
|
+
@keys_values_original.delete(key)
|
98
112
|
end
|
99
113
|
|
100
114
|
PREDEFINED_SCOPE_KEYS = %i[include page].freeze
|
@@ -120,12 +134,6 @@ class JekyllPluginHelper
|
|
120
134
|
value
|
121
135
|
end
|
122
136
|
|
123
|
-
# Sets @params by replacing any Liquid variable names with their values
|
124
|
-
def liquid_context=(context)
|
125
|
-
@liquid_context = context
|
126
|
-
@params = @keys_values.map { |k, _v| lookup_variable(k) } unless respond_to?(:no_arg_parsing) && no_arg_parsing
|
127
|
-
end
|
128
|
-
|
129
137
|
def lookup_variable(symbol)
|
130
138
|
string = symbol.to_s
|
131
139
|
return string unless string.start_with?('{{') && string.end_with?('}}')
|
@@ -136,4 +144,18 @@ class JekyllPluginHelper
|
|
136
144
|
def page
|
137
145
|
@liquid_context.registers[:page]
|
138
146
|
end
|
147
|
+
|
148
|
+
def parse(markup)
|
149
|
+
@argv_original = Shellwords.split(markup)
|
150
|
+
@keys_values_original = KeyValueParser \
|
151
|
+
.new({}, { array_values: false, normalize_keys: false, separator: /=/ }) \
|
152
|
+
.parse(@argv_original)
|
153
|
+
@params_original = @keys_values_original.map { |k, _v| lookup_variable(k) } unless respond_to?(:no_arg_parsing) && no_arg_parsing
|
154
|
+
|
155
|
+
@argv = Shellwords.split(self.class.expand_env(markup))
|
156
|
+
@keys_values = KeyValueParser \
|
157
|
+
.new({}, { array_values: false, normalize_keys: false, separator: /=/ }) \
|
158
|
+
.parse(@argv)
|
159
|
+
@params = @keys_values.map { |k, _v| lookup_variable(k) } unless respond_to?(:no_arg_parsing) && no_arg_parsing
|
160
|
+
end
|
139
161
|
end
|
@@ -1,41 +1,60 @@
|
|
1
1
|
require 'jekyll_plugin_logger'
|
2
|
-
|
2
|
+
require 'rspec/match_ignoring_whitespace'
|
3
3
|
require_relative '../lib/jekyll_plugin_support'
|
4
4
|
require_relative '../lib/jekyll_plugin_support_spec_support'
|
5
5
|
|
6
|
-
# Lets get this party started
|
7
6
|
class MyTest
|
8
|
-
RSpec.describe
|
9
|
-
|
10
|
-
|
7
|
+
RSpec.describe JekyllPluginHelper do
|
8
|
+
logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
9
|
+
|
10
|
+
it 'parses quoted string options' do
|
11
|
+
helper = described_class.new('my_tag', "colors='blue or green' blah ick", logger, false)
|
12
|
+
expect(helper.keys_values.keys).to eq(%w[colors blah ick])
|
13
|
+
|
14
|
+
colors = helper.parameter_specified? 'colors'
|
15
|
+
expect(colors).to eq('blue or green')
|
16
|
+
|
17
|
+
expect(helper.keys_values.keys).to eq(%w[blah ick])
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'parses unquoted string options' do
|
21
|
+
helper = described_class.new('my_tag', 'color=blue blah ick', logger, false)
|
22
|
+
expect(helper.keys_values.keys).to eq(%w[color blah ick])
|
23
|
+
|
24
|
+
color = helper.parameter_specified? 'color'
|
25
|
+
expect(color).to eq('blue')
|
26
|
+
|
27
|
+
expect(helper.keys_values.keys).to eq(%w[blah ick])
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'parses quoted booleans' do
|
31
|
+
helper = described_class.new('my_tag', "bool1='true' bool2='false' blah ick", logger, false)
|
32
|
+
expect(helper.keys_values.keys).to eq(%w[bool1 bool2 blah ick])
|
33
|
+
|
34
|
+
bool1 = helper.parameter_specified? 'bool1'
|
35
|
+
expect(bool1).to be true
|
36
|
+
|
37
|
+
bool2 = helper.parameter_specified? 'bool2'
|
38
|
+
expect(bool2).to be false
|
39
|
+
|
40
|
+
expect(helper.keys_values.keys).to eq(%w[blah ick])
|
41
|
+
|
42
|
+
expect(helper.remaining_markup).to eq('blah ick')
|
11
43
|
end
|
12
44
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# quote = Jekyll::Quote.send(
|
28
|
-
# :new,
|
29
|
-
# 'quote',
|
30
|
-
# command_line,
|
31
|
-
# parse_context
|
32
|
-
# )
|
33
|
-
# result = quote.send(:render_impl, command_line)
|
34
|
-
# expect(result).to match_ignoring_whitespace <<-END_RESULT
|
35
|
-
# <div class='quote'>
|
36
|
-
# This is the quoted text.
|
37
|
-
# </div>
|
38
|
-
# END_RESULT
|
39
|
-
# end
|
45
|
+
it 'parses unquoted booleans' do
|
46
|
+
helper = described_class.new('my_tag', 'bool1=true bool2=false blah ick', logger, false)
|
47
|
+
expect(helper.keys_values.keys).to eq(%w[bool1 bool2 blah ick])
|
48
|
+
|
49
|
+
bool1 = helper.parameter_specified? 'bool1'
|
50
|
+
expect(bool1).to be true
|
51
|
+
|
52
|
+
bool2 = helper.parameter_specified? 'bool2'
|
53
|
+
expect(bool2).to be false
|
54
|
+
|
55
|
+
expect(helper.keys_values.keys).to eq(%w[blah ick])
|
56
|
+
|
57
|
+
expect(helper.remaining_markup).to eq('blah ick')
|
58
|
+
end
|
40
59
|
end
|
41
60
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,7 +3,7 @@ require_relative '../lib/jekyll_plugin_support'
|
|
3
3
|
|
4
4
|
RSpec.configure do |config|
|
5
5
|
config.filter_run :focus
|
6
|
-
config.order = 'random'
|
6
|
+
# config.order = 'random'
|
7
7
|
config.run_all_when_everything_filtered = true
|
8
8
|
|
9
9
|
# See https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures
|
data/spec/status_persistence.txt
CHANGED
@@ -0,0 +1,6 @@
|
|
1
|
+
example_id | status | run_time |
|
2
|
+
------------------------------------------------------------------------------------------------- | ------ | --------------- |
|
3
|
+
/mnt/_/work/jekyll/my_plugins/jekyll_plugin_support/spec/jekyll_block_plugin_support_spec.rb[1:1] | passed | 0.00335 seconds |
|
4
|
+
/mnt/_/work/jekyll/my_plugins/jekyll_plugin_support/spec/jekyll_block_plugin_support_spec.rb[1:2] | passed | 0.00019 seconds |
|
5
|
+
/mnt/_/work/jekyll/my_plugins/jekyll_plugin_support/spec/jekyll_block_plugin_support_spec.rb[1:3] | passed | 0.00337 seconds |
|
6
|
+
/mnt/_/work/jekyll/my_plugins/jekyll_plugin_support/spec/jekyll_block_plugin_support_spec.rb[1:4] | passed | 0.00026 seconds |
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll_plugin_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Slinn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -70,7 +70,6 @@ files:
|
|
70
70
|
- lib/jekyll_plugin_support_helper.rb
|
71
71
|
- lib/jekyll_plugin_support_spec_support.rb
|
72
72
|
- spec/jekyll_block_plugin_support_spec.rb
|
73
|
-
- spec/jekyll_tag_plugin_support_spec.rb
|
74
73
|
- spec/spec_helper.rb
|
75
74
|
- spec/status_persistence.txt
|
76
75
|
homepage: https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#quote
|
@@ -106,7 +105,6 @@ specification_version: 4
|
|
106
105
|
summary: Provides support for writing Jekyll plugins.
|
107
106
|
test_files:
|
108
107
|
- spec/jekyll_block_plugin_support_spec.rb
|
109
|
-
- spec/jekyll_tag_plugin_support_spec.rb
|
110
108
|
- spec/spec_helper.rb
|
111
109
|
- spec/status_persistence.txt
|
112
110
|
...
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'jekyll_plugin_logger'
|
2
|
-
# require 'rspec/match_ignoring_whitespace'
|
3
|
-
require_relative '../lib/jekyll_plugin_support'
|
4
|
-
require_relative '../lib/jekyll_plugin_support_spec_support'
|
5
|
-
|
6
|
-
# Lets get this party started
|
7
|
-
class MyTest
|
8
|
-
RSpec.describe JekyllSupport::JekyllTag do
|
9
|
-
let(:logger) do
|
10
|
-
PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
11
|
-
end
|
12
|
-
|
13
|
-
let(:parse_context) { TestParseContext.new }
|
14
|
-
|
15
|
-
# Example for plugin authors to refer to:
|
16
|
-
#
|
17
|
-
# let(:helper) do
|
18
|
-
# JekyllTagHelper.new(
|
19
|
-
# 'quote',
|
20
|
-
# "cite='This is a citation' url='https://blah.com' This is the quoted text.",
|
21
|
-
# logger
|
22
|
-
# )
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# fit 'is created properly' do
|
26
|
-
# command_line = "cite='This is a citation' url='https://blah.com' This is the quoted text.".dup
|
27
|
-
# quote = Jekyll::Quote.send(
|
28
|
-
# :new,
|
29
|
-
# 'quote',
|
30
|
-
# command_line,
|
31
|
-
# parse_context
|
32
|
-
# )
|
33
|
-
# result = quote.send(:render_impl, command_line)
|
34
|
-
# expect(result).to match_ignoring_whitespace <<-END_RESULT
|
35
|
-
# <div class='quote'>
|
36
|
-
# This is the quoted text.
|
37
|
-
# </div>
|
38
|
-
# END_RESULT
|
39
|
-
# end
|
40
|
-
end
|
41
|
-
end
|