jekyll_plugin_support 0.7.2 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,155 +1,182 @@
1
1
  # `jekyll_plugin_support` [![Gem Version](https://badge.fury.io/rb/jekyll_plugin_support.svg)](https://badge.fury.io/rb/jekyll_plugin_support)
2
2
 
3
- `Jekyll_plugin_support` is a Ruby gem that facilitates writing and testing Jekyll plugins.
3
+ `Jekyll_plugin_support` is a Ruby gem that provides a framework for writing and testing Jekyll plugins.
4
+
5
+ `Jekyll_plugin_support` can be used to create simple Jekyll plugins in
6
+ the `_plugins/` directory of your Jekyll project, or gem-based Jekyll plugins.
7
+
4
8
  At present, only Jekyll tags and blocks are supported.
5
9
 
10
+ Plugins that use `jekyll_plugin_support` include:
6
11
 
7
- ## Installation
12
+ <ul style="columns: 2">
13
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_all_collections'><code>jekyll_all_collections</code></a></li>
14
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_badge'><code>jekyll_badge</code></a></li>
15
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_emoji'><code>jekyll_emoji</code></a></li>
16
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_flexible_include.html'><code>jekyll_flexible_include</code></a></li>
17
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_href.html'><code>jekyll_href</code></a></li>
18
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_img.html'><code>jekyll_img</code></a></li>
19
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_plugin_template.html'><code>jekyll_plugin_template</code></a></li>
20
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_outline.html'><code>jekyll_outline</code></a></li>
21
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_pre.html'><code>jekyll_pre</code></a></li>
22
+ <li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_quote.html'><code>jekyll_quote</code></a></li>
23
+ </ul>
8
24
 
9
- `Jekyll_plugin_support` can be used to create simple Jekyll plugins in the `_plugins/` directory, or gem-based Jekyll plugins.
25
+ ... and also the demonstration plugins in
26
+ [`jekyll_plugin_support`](https://github.com/mslinn/jekyll_plugin_support/tree/master/demo/_plugins)
10
27
 
11
- ### Simple Plugins
12
28
 
13
- For jekyll plugins defined in the `_plugins/` directory,
14
- add this line to your Jekyll plugin's `Gemfile`:
29
+ ## Installation
30
+
31
+ `Jekyll_plugin_support` is packaged as a Ruby gem.
32
+ If your project is a custom plugin that will reside in a Jekyll project’s `_plugins` directory,
33
+ add the following line to your Jekyll plugin’s `Gemfile`.
15
34
 
16
35
  ```ruby
17
36
  group :jekyll_plugins do
18
- gem 'jekyll_plugin_support'
37
+ ...
38
+ gem 'jekyll_plugin_support', '>= 0.8.0'
39
+ ...
19
40
  end
20
41
  ```
21
42
 
22
- And then execute:
43
+ Otherwise, if your custom plugin will be packaged into a gem, add the following to your plugin’s `.gemspec`:
23
44
 
24
- ```shell
25
- $ bundle
45
+ ```ruby
46
+ Gem::Specification.new do |spec|
47
+ ...
48
+ spec.add_dependency 'jekyll_plugin_support', '>= 0.8.0'
49
+ ...
50
+ end
26
51
  ```
27
52
 
53
+ Install the `jekyll_plugin_support` Ruby gem and mark it as a dependency of your project by typing:
28
54
 
29
- ### Gem-Based Plugins
55
+ ```shell
56
+ $ bundle
57
+ ```
30
58
 
31
- Add this line to your Jekyll plugin's `.gemspec`:
59
+ Copy the CSS classes from `demo/assets/css/jekyll_plugin_support.css` to your Jekyll project&rsquo;s CSS file.
32
60
 
33
- ```ruby
34
- spec.add_dependency 'jekyll_plugin_support'
35
- ```
36
61
 
37
- And then execute:
62
+ ## About `jekyll_plugin_support`
38
63
 
39
- ```shell
40
- $ bundle
41
- ```
64
+ `JekyllSupport::JekyllBlock` and `JekyllSupport::JekyllTag`
65
+ provide support for [Jekyll tag block plugins](https://jekyllrb.com/docs/plugins/tags/#tag-blocks)
66
+ and [Jekyll inline tag plugins](https://jekyllrb.com/docs/plugins/tags/), respectively.
67
+ They are very similar in construction and usage.
68
+
69
+ Instead of subclassing your custom Jekyll block tag class from `Liquid::Block`,
70
+ subclass from `JekyllSupport::JekyllBlock`.
71
+ Similarly, instead of subclassing your custom Jekyll tag class from `Liquid::Tag`,
72
+ subclass from `JekyllSupport::JekyllTag`.
73
+
74
+ Both JekyllSupport classes instantiate new instances of
75
+ [`PluginMetaLogger`](https://github.com/mslinn/jekyll_plugin_logger) (called `@logger`) and
76
+ [`JekyllPluginHelper`](https://github.com/mslinn/jekyll_plugin_support/blob/master/lib/jekyll_plugin_support_helper.rb)
77
+ (called `@helper`).
78
+
79
+ `JekyllPluginHelper` defines a generic initialize method, and your tag or block tag class should not need to override it.
80
+ Also, your tag or block tag class should not define a method called render, because `jekyll_plugin_support` defines one.
81
+
82
+ Instead, define a method called `render_impl`.
83
+ For inline tags, `render_impl` does not accept any parameters.
84
+ For block tags, a single parameter is required, which contains text passed from your block in the page.
85
+
86
+ Your implementation of render_impl can parse parameters passed to the tag / block tag, as described in
87
+ [Tag Parameter Parsing](http://mslinn.com/jekyll/10100-jekyll-plugin-background.html#params).
88
+
89
+ The following variables are predefined within `render`.
90
+ See the [Jekyll documentation](https://jekyllrb.com/docs/variables/) for more information.
91
+
92
+ * `@argument_string` – Original unparsed string from the tag in the web page
93
+ * `@config` – Jekyll [configuration data](https://jekyllrb.com/docs/configuration/)
94
+ * `@layout` – Front matter specified in layouts
95
+ * `@mode` – [possible values](https://jekyllrb.com/docs/configuration/environments/)
96
+ are `development`, `production`, or `test`
97
+ * `@page` – Jekyll [page variable](https://jekyllrb.com/docs/variables/#page-variables)
98
+ * `@paginator` – Only has a value when a paginator is active; they are only available in index files.
99
+ * `@site` – Jekyll [site variable](https://jekyllrb.com/docs/variables/#site-variables)
100
+ * `@tag_name` – Name of the inline tag or block plugin
101
+ * `@theme` – Theme variables (introduced in Jekyll 4.3.0)
42
102
 
43
103
 
44
104
  ## General Usage
45
105
 
106
+ Please see the [`demo/`](demo/) project for a well-documented set of demonstration Jekyll plugins that are built from `jekyll_plugin_support`.
107
+ Additional information is available [here](https://mslinn.com/jekyll/10200-jekyll-plugin-background.html) and the
108
+ [`jekyll_plugin_support`](https://www.mslinn.com/jekyll_plugins/jekyll_plugin_support.html) documentation.
109
+
46
110
  `JekyllSupport::JekyllBlock` and `JekyllSupport::JekyllTag`
47
- provide support for Jekyll tag blocks and Jekyll tags, respectively.
48
- They are very similar in construction and usage.
111
+ provide support for Jekyll block tags and Jekyll inline tags, respectively.
112
+ They are similar in construction and usage.
49
113
 
50
114
  Instead of subclassing your Jekyll block tag class from `Liquid::Block`,
51
115
  subclass from `JekyllSupport::JekyllBlock` instead.
52
116
 
53
- Similarly, instead of subclassing your Jekyll tag class from `Liquid::Tag`,
117
+ Likewise, instead of subclassing your Jekyll inline tag class from `Liquid::Tag`,
54
118
  subclass from `JekyllSupport::JekyllTag` instead.
55
119
 
56
120
  Both `JekyllSupport` classes instantiate new instances of
57
121
  [`PluginMetaLogger`](https://github.com/mslinn/jekyll_plugin_logger) (called `@logger`) and
58
- [`JekyllPluginHelper`](lib/jekyll_plugin_support_helper.rb) (called `@helper`).
122
+ [`JekyllPluginHelper`](lib/jekyll_plugin_helper.rb) (called `@helper`).
123
+
124
+
125
+ ### Inline and Block Tag Plugin Implementation
126
+
127
+ Both `JekyllSupport` classes define a generic `initialize` method,
128
+ and your inline tag or block tag class should not override it.
129
+
130
+ Also, your inline tag or block tag class should not define a method called `render`,
131
+ because both `JekyllSupport` classes define this method.
59
132
 
60
- `JekyllPluginHelper` defines a generic `initialize` method,
61
- and your tag or block tag class should not override it.
62
- Also, your tag or block tag class should not define a method called `render`,
63
- because `JekyllBlock.initialize` defines one, which creates variables called
64
- [`@page`](https://jekyllrb.com/docs/variables/#page-variables) and
65
- [`@site`](https://jekyllrb.com/docs/variables/#site-variables).
66
133
 
67
134
  Instead, define a method called `render_impl`.
68
- For tags, `render_impl` does not accept any parameters.
135
+ For inline tags, `render_impl` does not accept any parameters.
69
136
  For block tags, a single parameter is required, which contains any text enclosed within your block.
70
137
 
71
- Your implementation of `render_impl` can access `@page` and `@site`,
72
- and can parse parameters passed to the tag / block tag, [as described here](https://mslinn.com/jekyll/10100-jekyll-plugin-background.html#params):
73
138
 
74
- ### For a tag:
139
+ ## Predefined Plugin Variables
75
140
 
76
- ```ruby
77
- require 'jekyll_plugin_support'
141
+ `Jekyll_plugin_support` defines the following Ruby variables that you can use in your plugin&rsquo;s `render_impl` method:
78
142
 
79
- module Jekyll
80
- class MyTag < JekyllSupport::JekyllTag
81
- VERSION = '0.1.0'.freeze
143
+ * `@argument_string` Unparsed markup passed as a parameter to your block tag and inline tag.
82
144
 
83
- def render_impl
84
- my_output = "<p>blah blah</p>"
85
- <<~END_OUTPUT
86
- #{my_output}
87
- END_OUTPUT
88
- end
145
+ * [`@attribution`](#subclass-attribution) Attribution markup
89
146
 
90
- JekyllPluginHelper.register(self, 'demo_tag')
91
- end
92
- end
93
- ```
147
+ * [`@config`](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/about-github-pages-and-jekyll#configuring-jekyll-in-your-github-pages-site)
148
+ [YAML](https://yaml.org/) Jekyll site configuration file
94
149
 
95
- ### For a tag block:
150
+ * [`@helper`](https://github.com/mslinn/jekyll_plugin_support/blob/master/lib/jekyll_plugin_helper.rb)
151
+ `JekyllPluginHelper` instance for your plugin.
96
152
 
97
- ```ruby
98
- require 'jekyll_plugin_support'
99
-
100
- module Jekyll
101
- class MyBlock < JekyllSupport::JekyllBlock
102
- VERSION = '0.1.0'.freeze
103
-
104
- def render_impl(content)
105
- @helper.gem_file __FILE__ # Enables attribution
106
- my_output = "<p>blah blah</p>"
107
- <<~END_OUTPUT
108
- #{my_output}
109
- #{@helper.attribute if @helper.attribution}
110
- END_OUTPUT
111
- end
112
-
113
- JekyllPluginHelper.register(self, 'demo_block')
114
- end
115
- end
116
- ```
153
+ * [`@layout`](https://jekyllrb.com/docs/variables/#global-variables) Layout information
117
154
 
118
- Note that each tag or tag block must define a constant called `VERSION`.
119
- If your plugin is packaged as a gem, then you might need to include `version.rb` into the plugin class.
120
- For example, if `lib/my_plugin/version.rb` looks like this:
155
+ * [`@logger`](jekyll_plugin_logger) `jekyll_plugin_logger` instance for your Jekyll plugin.
121
156
 
122
- ```ruby
123
- module MyPluginVersion
124
- VERSION = '0.5.1'.freeze
125
- end
126
- ```
157
+ * [`@mode`](https://jekyllrb.com/docs/configuration/environments/)
158
+ Indicates `production` or `development` mode.
127
159
 
128
- Then your plugin can incorporate the `VERSION` constant into your plugin like this:
160
+ * [`@page`](https://jekyllrb.com/docs/variables/#page-variables) Page variables
161
+
162
+ * [`@paginator`](https://jekyllrb.com/docs/variables/#page-variables) Pagination variables
163
+
164
+ * [`@scopes`](https://jekyllrb.com/docs/variables/)
165
+ See the [`jekyll_plugin_support` demo project](demo/variables.html)
166
+
167
+ * [`@site`](https://jekyllrb.com/docs/variables/#site-variables) Site variables
168
+
169
+ * [`@tag_config`](lib/jekyll_plugin_support_tag.rb)
170
+ Contents of the section of `_config.yml` named after your plugin.
171
+
172
+ * `@tag_name` Name of your Jekyll block tag or inline tag plugin.
173
+
174
+ * [`@theme`](https://jekyllrb.com/docs/variables/#global-variables) Theme variables
175
+
176
+ * `text` Content provided to your block tag.
129
177
 
130
- ```ruby
131
- require 'jekyll_plugin_support'
132
- require_relative 'my_block/version'
133
-
134
- module Jekyll
135
- class MyBlock < JekyllSupport::JekyllBlock
136
- include MyPluginVersion
137
-
138
- def render_impl(text)
139
- @helper.gem_file __FILE__ # Enables attribution
140
- my_output = "<p>blah blah</p>"
141
- <<~END_OUTPUT
142
- #{my_output}
143
- #{@helper.attribute if @helper.attribution}
144
- END_OUTPUT
145
- end
146
-
147
- JekyllPluginHelper.register(self, 'demo_tag')
148
- end
149
- end
150
- ```
151
178
 
152
- ### Argument Parsing
179
+ ## Argument Parsing
153
180
 
154
181
  Tag arguments can be obtained within `render_impl`.
155
182
  Both keyword options and name/value parameters are supported.
@@ -158,24 +185,29 @@ Both `JekyllTag` and `JekyllBlock` use the standard Ruby mechanism for parsing c
158
185
  [`shellwords`](https://ruby-doc.org/stdlib-2.5.1/libdoc/shellwords/rdoc/Shellwords.html) and
159
186
  [`key_value_parser`](https://www.rubydoc.info/gems/key-value-parser).
160
187
 
161
- 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.
162
- The included `demo` website has examples; both [`demo/_plugins/demo_tag.rb`](demo/_plugins/demo_tag.rb) and
163
- [`demo/_plugins/demo_block.rb`](demo/_plugins/demo_block.rb) contain the following:
188
+ All your code has to do is to specify the keywords to search for in the string
189
+ passed from the HTML page that your tag is embedded in.
190
+ The included `demo` website has examples;
191
+ both [`demo/_plugins/demo_inline_tag.rb`](demo/_plugins/demo_inline_tag.rb) and
192
+ [`demo/_plugins/demo_block_tag.rb`](demo/_plugins/demo_block_tag.rb) contain the following:
164
193
 
165
194
  ```ruby
166
195
  @keyword1 = @helper.parameter_specified? 'keyword1'
167
196
  @keyword2 = @helper.parameter_specified? 'keyword2'
168
- @name1 = @helper.parameter_specified? 'name1'
169
- @name2 = @helper.parameter_specified? 'name2'
197
+ @name1 = @helper.parameter_specified? 'name1'
198
+ @name2 = @helper.parameter_specified? 'name2'
170
199
  ```
171
200
 
172
- In [`demo/index.html`](demo/index.html), the following invoked the tag:
201
+
202
+ ### Example
203
+
204
+ [`demo/index.html`](demo/index.html), contains the following inline tag invocation:
173
205
 
174
206
  ```html
175
- {% demo_tag keyword1 name1='value1' unreferenced_key unreferenced_name="unreferenced_value" %}
207
+ {% demo_inline_tag keyword1 name1='value1' unreferenced_key unreferenced_name="unreferenced_value" %}
176
208
  ```
177
209
 
178
- The `demo/_plugins/demo_tag.rb` plugin uses `@helper.parameter_specified?` provided by
210
+ The `demo/_plugins/demo_inline_tag.rb` plugin uses `@helper.parameter_specified?` provided by
179
211
  `jekyll_support_plugin` to parse the string passed to the tag, which is
180
212
  `keyword1 name1='value1' unreferenced_key unreferenced_name="unreferenced_value"`.
181
213
 
@@ -185,7 +217,12 @@ The `demo/_plugins/demo_tag.rb` plugin uses `@helper.parameter_specified?` provi
185
217
  that name/value pair is removed from the argument string.
186
218
  * The remainder of the argument string is now `unreferenced_key unreferenced_name="unreferenced_value"`.
187
219
 
188
- Name/value parameters can be quoted; if the value consists of only one token then it does not need to be quoted.
220
+
221
+ ### To Quote Or Not To Quote
222
+
223
+ Parameter values can be quoted.
224
+
225
+ If the value consists of only one token then quoting is optional.
189
226
  The following name/value parameters all have the same result:
190
227
 
191
228
  * `pay_tuesday="true"`
@@ -193,18 +230,117 @@ The following name/value parameters all have the same result:
193
230
  * `pay_tuesday=true`
194
231
  * `pay_tuesday`
195
232
 
196
- The following also have the same result, however note that because the value has more than one token, quotes must be used:
233
+ If the values consist of more than one token, quotes must be used.
234
+ The following examples both yield the same result:
197
235
 
198
236
  * `pay_tuesday="maybe not"`
199
237
  * `pay_tuesday='maybe not'`
200
238
 
201
- #### Remaining Markup
239
+ ### Remaining Markup
202
240
 
203
241
  After your plugin has parsed all the keyword options and name/value parameters,
204
242
  call `@helper.remaining_markup` to obtain the remaining markup that was passed to your plugin.
205
243
 
206
244
 
207
- ### `no_arg_parsing` Optimization
245
+ ## Liquid Variable Definitions
246
+
247
+ `jekyll_plugin_support` provides support for
248
+ [Liquid variables](https://shopify.github.io/liquid/tags/variable/)
249
+ to be defined in `_config.yml`, in a section called `liquid-vars`.
250
+ The following `_config.yml` fragment defines 3 variables called `var1`, `var2` and `var3`:
251
+
252
+ ```yaml
253
+ liquid-vars:
254
+ var1: value1
255
+ var2: 'value 2'
256
+ var3: value3
257
+ ```
258
+
259
+ Liquid variables defined in this manner are intended to be embedded in a webpage.
260
+ They are expanded transparently, and can be referenced like any other Liquid variable.
261
+ These Liquid variables can be passed as parameters to other plugins and includes.
262
+
263
+ In the following example web page, the Liquid variable called `var1` is expanded as part of the displayed page.
264
+ Liquid variables `var1` and `var2` are expanded and passed to the `my_plugin` plugin.
265
+
266
+ ```html
267
+ This is the value of <code>var1</code>: {{var1}}.
268
+
269
+ {% my_plugin param1="{{var1}}" param2="{{var2}}" %}
270
+ ```
271
+
272
+ `Jekyll_plugin_support` expands all but one of the
273
+ [plugin variables described above](#predefined-variables),
274
+ replacing Liquid variable references with their values.
275
+ The exception is `@argument_string`, which is not expanded.
276
+
277
+
278
+ ### Liquid Variable Values Specific To Production And Development Modes
279
+
280
+ `jekyll_plugin_support` allows Liquid variables defined in `_config.yml` to have different values
281
+ when Jekyll is running in `development`, `production` and `test` modes.
282
+ When injecting variables into your Jekyll website, `Jekyll_plugin_support`
283
+ refers to definitions specific to the current environment,
284
+ and then refers to other definitions that are not overridden.
285
+
286
+ Here is an example:
287
+
288
+ ```yaml
289
+ liquid-vars:
290
+ development:
291
+ var1: 'http://localhost:4444/demo_block_tag.html'
292
+ var2: 'http://localhost:4444/demo_inline_tag.html'
293
+ production:
294
+ var1: 'https://github.com/django/django/blob/3.1.7'
295
+ var2: 'https://github.com/django-oscar/django-oscar/blob/3.0.2'
296
+ var3: 'https://github.com/mslinn'
297
+ ```
298
+
299
+ For the above, the following variable values are set in `development` mode:
300
+
301
+ * `var1`: `http://localhost:4444/demo_block_tag.html`
302
+ * `var2`: `http://localhost:4444/demo_inline_tag.html`
303
+ * `var3`: `https://github.com/mslinn`
304
+
305
+ ... and the following variable values are set in `production` and `test` modes:
306
+
307
+ * `var1`: `https://github.com/django/django/blob/3.1.7`
308
+ * `var2`: `https://github.com/django-oscar/django-oscar/blob/3.0.2`
309
+ * `var3`: `https://github.com/mslinn`
310
+
311
+
312
+ ### Liquid Variables in `jekyll_plugin_support` Subclasses
313
+
314
+ You can define additional Liquid variables in plugins built using `jekyll_plugin_support`.
315
+ To do this, make entries in `_config.yml` under a key named after the value of `@tag_name`.
316
+
317
+ For example, let&rsquo;s imagine you create a plugin using `jekyll_plugin_support`,
318
+ and hou register it with the name `phonetic_alphabet`.
319
+ You could define Liquid variables that would be made available to content pages in web applications that
320
+ incorporate the `phonetic_alphabet` plugin.
321
+ The following section in `_config.yml` defines variables called `x`, `y` and `z`,
322
+ with values `xray`, `yankee` and `zulu`, respectively:
323
+
324
+ ```yaml
325
+ phonetic_alphabet:
326
+ x: xray
327
+ y: yankee
328
+ z: zulu
329
+ ```
330
+
331
+ The above definitions allow you to write content pages that use those variables, like the following page containing markup:
332
+
333
+ ```html
334
+ ---
335
+ layout: default
336
+ title: Variable demo
337
+ ---
338
+ The letter `x` is pronounced {{x}}.
339
+ Similarly, the letters `y` and `z` are pronounced {{y}} and {{z}}.
340
+ ```
341
+
342
+
343
+ ## `no_arg_parsing` Optimization
208
344
 
209
345
  If your tag or block plugin only needs access to the raw arguments passed from the web page,
210
346
  without tokenization, and you expect that the plugin might be invoked with large amounts of text,
@@ -213,8 +349,10 @@ derive your plugin from `JekyllBlockNoArgParsing` or `JekyllTagNoArgParsing`.
213
349
 
214
350
  ## Subclass Attribution
215
351
 
216
- `JekyllTag` and `JekyllBlock` subclasses of `jekyll_plugin_support` can utilize the `attribution` option IFF they are published as a gem.
352
+ `JekyllTag` and `JekyllBlock` subclasses of `jekyll_plugin_support` can utilize the `attribution`
353
+ option if they are published as a gem.
217
354
  `JekyllTagNoArgParsing` and `JekyllBlockNoArgParsing` subclasses cannot.
355
+ This feature is usually only desired for `JekyllBlock` subclasses.
218
356
 
219
357
  * When used as a keyword option, a default value is used for the attribution string.
220
358
  * When used as a name/value option, the attribution string can be specified.
@@ -237,10 +375,12 @@ The `id` attribute is in the sample HTML above is randomized so more than one at
237
375
  Typical usage for the `attribution` tag is:
238
376
 
239
377
  ```html
240
- {% my_tag attribution %}
378
+ {% my_block_tag attribution %}
379
+ Content of my_block_tag.
380
+ {% endmy_block_tag %}
241
381
  ```
242
382
 
243
- Normal processing of `my_tag` is augmented by interpolating the attribution format string,
383
+ Normal processing of `my_block_tag` is augmented by interpolating the attribution format string,
244
384
  which is a Ruby-compatible interpolated string.
245
385
 
246
386
  The default attribution format string is:
@@ -275,17 +415,11 @@ HEREDOC
275
415
  ```
276
416
 
277
417
 
278
- ## Additional Information
279
-
280
- More information is available on
281
- [Mike Slinn&rsquo;s website](https://www.mslinn.com/jekyll_plugins/jekyll_plugin_support.html).
282
-
283
-
284
418
  ## Development
285
419
 
286
- After checking out the repo, run `bin/setup` to install dependencies.
420
+ After checking out the `jekyll_plugin_suppprt` repository, run `bin/setup` to install dependencies.
287
421
 
288
- You can also run `bin/console` for an interactive prompt that will allow you to experiment.
422
+ `bin/console` provides an interactive prompt that allows you to experiment.
289
423
 
290
424
 
291
425
  To build and install this gem onto your local machine, run:
@@ -314,11 +448,25 @@ jekyll_plugin_support (0.1.0)
314
448
  ```
315
449
 
316
450
 
317
- ## Demo
451
+ ### Pry Breakpoint On StandardError
452
+
453
+ A `pry` breakpoint will be set in the `StandardError` handler if `pry_on_standard_error: true`
454
+ is set in variable configuration section of `_config.yml`.
455
+
456
+ For example, if your plugin is called `blah`, enable the breakpoint with the following section:
457
+
458
+ ```yml
459
+ blah:
460
+ pry_on_standard_error: true
461
+ ```
462
+
463
+
464
+ ## Demonstration Plugins and Website
318
465
 
319
466
  A demo / test website is provided in the `demo` directory.
320
467
  It can be used to debug the plugin or to run freely.
321
468
 
469
+
322
470
  ### Run Freely
323
471
 
324
472
  1. Run from the command line:
@@ -327,31 +475,57 @@ It can be used to debug the plugin or to run freely.
327
475
  $ demo/_bin/debug -r
328
476
  ```
329
477
 
330
- 2. View the generated website at [`http://localhost:4444`](http://localhost:4444)
478
+ 2. View the generated website,
479
+ which might be at [`http://localhost:4444`](http://localhost:4444),
480
+ depending on how you configured it.
481
+
331
482
 
332
483
  ### Plugin Debugging
333
484
 
334
485
  1. Set breakpoints in Visual Studio Code.
335
486
 
336
- 2. Initiate a debug session from the command line:
487
+ 2. Initiate a debug session from the command line by running the `demo/_bin/debug` script:
337
488
 
338
489
  ```shell
339
490
  $ demo/_bin/debug
491
+ Fetching gem metadata from https://rubygems.org/..........
492
+ Resolving dependencies...
493
+ Fetching public_suffix 5.0.4
494
+ Fetching nokogiri 1.15.5 (x86_64-linux)
495
+ Installing public_suffix 5.0.4
496
+ Installing nokogiri 1.15.5 (x86_64-linux)
497
+ Bundle complete! 17 Gemfile dependencies, 96 gems now installed.
498
+ Use `bundle info [gemname]` to see where a bundled gem is installed.
499
+
500
+ INFO PluginMetaLogger: Loaded DraftFilter plugin.
501
+ INFO PluginMetaLogger: Loaded outline_js v1.2.1 plugin.
502
+ INFO PluginMetaLogger: Loaded outline v1.2.1 plugin.
503
+ Configuration file: /mnt/f/jekyll_plugin_support/demo/_config.yml
504
+ Cleaner: Removing /mnt/f/jekyll_plugin_support/demo/_site...
505
+ Cleaner: Removing /mnt/f/jekyll_plugin_support/demo/.jekyll-metadata...
506
+ Cleaner: Removing /mnt/f/jekyll_plugin_support/demo/.jekyll-cache...
507
+ Cleaner: Nothing to do for .sass-cache.
508
+ DEBUGGER: Debugger can attach via TCP/IP (127.0.0.1:37177)
509
+ DEBUGGER: wait for debugger connection...
340
510
  ```
341
511
 
342
- 3. Once the `Fast Debugger` signon appears, launch the Visual Studio Code launch
343
- configuration called `Attach with rdbg`.
512
+ 3. Once the `DEBUGGER: wait for debugger connection...` message appears,
513
+ run the Visual Studio Code launch configuration called `Attach with rdbg`.
344
514
 
345
- 4. View the generated website at [`http://localhost:4444`](http://localhost:4444)
515
+ 4. View the generated website,
516
+ which might be at [`http://localhost:4444`](http://localhost:4444),
517
+ depending on how you configured it.
346
518
 
347
519
 
348
520
  ### Build and Push to RubyGems
349
521
 
350
- To release a new version,
522
+ To release a new version:
351
523
 
352
524
  1. Update the version number in `version.rb`.
353
- 2. Commit all changes to git; if you don't the next step might fail with an unexplainable error message.
354
- 3. Run the following:
525
+ 2. Add an entry to `CHANGELOG.md` describing the changes since the previous version.
526
+ 3. Commit all changes to git;
527
+ if you don't the next step might fail with an unexplainable error message.
528
+ 4. Run the following:
355
529
 
356
530
  ```shell
357
531
  $ bundle exec rake release
@@ -1,6 +1,6 @@
1
1
  require_relative 'lib/jekyll_plugin_support/version'
2
2
 
3
- Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
3
+ Gem::Specification.new do |spec|
4
4
  github = 'https://github.com/mslinn/jekyll_plugin_support'
5
5
 
6
6
  spec.bindir = 'exe'
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
24
24
  END_MESSAGE
25
25
  spec.require_paths = ['lib']
26
26
  spec.required_ruby_version = '>= 2.6.0'
27
- spec.summary = 'Provides support for writing Jekyll plugins.'
27
+ spec.summary = 'Provides a framework for writing and testing Jekyll plugins'
28
28
  spec.test_files = spec.files.grep %r{^(test|spec|features)/}
29
29
  spec.version = JekyllPluginSupportVersion::VERSION
30
30
 
@@ -32,4 +32,5 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
32
32
  spec.add_dependency 'jekyll', '>= 3.5.0'
33
33
  spec.add_dependency 'jekyll_plugin_logger'
34
34
  spec.add_dependency 'key-value-parser'
35
+ spec.add_dependency 'pry'
35
36
  end
@@ -0,0 +1,55 @@
1
+ require 'facets/string/camelcase'
2
+ require 'facets/string/snakecase'
3
+
4
+ module Jekyll
5
+ # Use like this:
6
+ # CustomError.new(:MyError, 'blah', 'asdf')
7
+ class CustomError < StandardError
8
+ def self.factory(name)
9
+ return if Object.const_defined? name
10
+
11
+ puts "Defining #{name}".yellow
12
+ eval "#{name} = Class.new Jekyll::CustomError" # rubocop:disable Style/EvalWithLocation, Security/Eval
13
+ end
14
+
15
+ def error_name
16
+ self.class.name.split('::').last
17
+ end
18
+
19
+ def calling_file
20
+ file_fq, _line_number, _extra = backtrace[0].split(':')
21
+ file_fq
22
+ end
23
+
24
+ # @return HTML <div> tag with class set to the snake_case version of the error class name.
25
+ def html_message
26
+ shorten_backtrace
27
+ line_number = self.class.class_variable_get :@@line_number
28
+ path = self.class.class_variable_get :@@path
29
+ <<~END_MSG
30
+ <div class='#{error_name.snakecase}'>
31
+ #{self.class} raised in #{calling_file} while processing line #{line_number} (after front matter) of #{path}
32
+ #{message}
33
+ </div>
34
+ END_MSG
35
+ end
36
+
37
+ def logger_message
38
+ shorten_backtrace
39
+ kaller = caller(1..1).first
40
+ line_number = self.class.class_variable_get :@@line_number
41
+ path = self.class.class_variable_get :@@path
42
+ <<~END_MSG
43
+ #{error_name} raised in #{kaller} while processing line #{line_number} (after front matter) of #{path}
44
+ #{message}
45
+ END_MSG
46
+ end
47
+
48
+ def shorten_backtrace(backtrace_element_count = 3)
49
+ b = backtrace[0..backtrace_element_count - 1].map do |x|
50
+ x.gsub(Dir.pwd + '/', './')
51
+ end
52
+ set_backtrace b
53
+ end
54
+ end
55
+ end