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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0856ddeea29e8a1e24f0a4997aecb7f6b6b22eae587ca8466142686b65557b7
4
- data.tar.gz: ac8a8a047666f89b055b6ab90d6535b59e7f34441405852f5905ed6a517cbc27
3
+ metadata.gz: 16fe00b243305d30e8dff85f604336e9c9802afe837a762dd295bd7283d8e1d4
4
+ data.tar.gz: c4ae30a570d27d77d17d7710be941731aefeaf11e4c2e19ec9f8fb773a9ad01d
5
5
  SHA512:
6
- metadata.gz: 8122412d70d1c99a6195834a51faa25f0d7beb59a23c18db0beba2883c83f5625920a63495b7ff21abf891faf97ae2ffe085c764c2be9d178bfeb37a7ae4e2f5
7
- data.tar.gz: abd34bf8420c7040e7015ce131a8ae3ea01158a552637a4e8d63c51095c138bdf87fd11bff1c3fb3f35fbd3e8b728a09934c4aefe0bbe29817703bdb032a8114
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
- Enabled: false
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: 20
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
- Style/FrozenStringLiteralComment:
35
- Enabled: false
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
- Generates Jekyll logger with colored output.
203
+ Provides support for writing Jekyll plugins.
151
204
  ```
152
205
 
153
206
 
@@ -1,6 +1,6 @@
1
1
  require_relative 'lib/jekyll_plugin_support/version'
2
2
 
3
- Gem::Specification.new do |spec|
3
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
4
4
  github = 'https://github.com/mslinn/jekyll_plugin_support'
5
5
 
6
6
  spec.bindir = 'exe'
@@ -1,3 +1,3 @@
1
1
  module JekyllPluginSupportVersion
2
- VERSION = '0.5.1'.freeze
2
+ VERSION = '0.5.3'.freeze
3
3
  end
@@ -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
- attr_reader :argv, :keys_values, :liquid_context, :logger, :markup, :no_arg_parsing, :params, :tag_name
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
- def warn_fetch(variable)
57
- abort "Error: Argument parsing was suppressed, but an attempt to obtain the value of #{variable} was made"
58
- end
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
- def warn_parse(meth)
61
- abort "Error: Argument parsing was suppressed, but an attempt to invoke #{meth} was made"
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
- @argv = Shellwords.split(self.class.expand_env(markup))
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
- # @return if parameter was specified, removes it from the available tokens and returns value
90
- def parameter_specified?(name)
91
- return false if @keys_values.empty?
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
- # require 'rspec/match_ignoring_whitespace'
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 JekyllSupport::JekyllBlock do
9
- let(:logger) do
10
- PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
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
- 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
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
@@ -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.1
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-02-17 00:00:00.000000000 Z
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