jekyll_flexible_include 2.0.14 → 2.0.15

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: 235134772b0ff492ec61e24e71a8094977ae43e740c338dabfd65e92cd8ac416
4
- data.tar.gz: c89b5985bde7ec87ef12870cf27369d1f2c6194de9ef8459064675f13402d87f
3
+ metadata.gz: ef5ec6b930c61453fe741a89ea81e1da2d9303d910a23a9520f12c47a10b802b
4
+ data.tar.gz: 629a43513ddb0a6203024eeccbb52e8442d01612f5d10e2fc5451f4a9c739e52
5
5
  SHA512:
6
- metadata.gz: '094fae8fef148dd4801710911d8d0bde33e45a3ef0c7b5f5417e0a5baea1cc8d24d975d3b9e02e76ed96fca375651bd06074bf5a21a72ca1ee3343f960ab9aec'
7
- data.tar.gz: 810afd58a9df5f7d7d88f97de0bbbb5547cbe400d0a09a25dff8ada24bdc4ad313cb0a535571388d6990edc125e3fca9d07c3a71bf33f0868a057cc451f47bc6
6
+ metadata.gz: d16333226e03cab0849b10d1b3c022c24f03d50d4e27c1459fc0e831f0bab64d080832dac3d3671dc9e1727e60e90a15864b4f74b6860d4045404f9058e5580b
7
+ data.tar.gz: ca350963ac6320ad1a1384ab8b2e3eea2c3e6043c12c0b872b95bfb05e942bc070a64a8b5631a642eaea4bd72f11fc7286b25e93a90643a6d54954a5b5b103ef
data/.rubocop.yml CHANGED
@@ -1,16 +1,27 @@
1
- require: rubocop-jekyll
2
- inherit_gem:
3
- rubocop-jekyll: .rubocop.yml
1
+ require:
2
+ - rubocop-rspec
3
+ # - rubocop-jekyll
4
+
5
+ # inherit_gem:
6
+ # rubocop-jekyll: .rubocop.yml
4
7
 
5
8
  AllCops:
6
9
  Exclude:
7
- - vendor/**/*
8
- - Gemfile*
10
+ - demo/_site/**/*
11
+ - exe/**/*
12
+ - vendor/**/*
13
+ - Gemfile*
9
14
  NewCops: enable
10
15
  TargetRubyVersion: 2.6
11
16
 
12
- # Gemspec/RequireMFA:
13
- # Enabled: false
17
+ Gemspec/DeprecatedAttributeAssignment:
18
+ Enabled: false
19
+
20
+ Gemspec/RequireMFA:
21
+ Enabled: false
22
+
23
+ Layout/HashAlignment:
24
+ EnforcedHashRocketStyle: table
14
25
 
15
26
  Layout/LineLength:
16
27
  Max: 150
@@ -18,20 +29,61 @@ Layout/LineLength:
18
29
  Layout/MultilineMethodCallIndentation:
19
30
  Enabled: false
20
31
 
32
+ Metrics/AbcSize:
33
+ Max: 45
34
+
21
35
  Metrics/BlockLength:
22
- Enabled: false
36
+ Exclude:
37
+ - jekyll_flexible_include_plugin.gemspec
38
+ - spec/**/*
39
+
40
+ Metrics/ClassLength:
41
+ Exclude:
42
+ - spec/**/*
43
+
44
+ Metrics/CyclomaticComplexity:
45
+ Max: 10
46
+
47
+ Metrics/MethodLength:
48
+ Max: 30
49
+
50
+ Metrics/PerceivedComplexity:
51
+ Max: 15
52
+
53
+ Naming/FileName:
54
+ Exclude:
55
+ - Rakefile
56
+
57
+ RSpec/ExampleLength:
58
+ Max: 20
59
+
60
+ RSpec/MultipleExpectations:
61
+ Max: 15
23
62
 
24
63
  Style/CommandLiteral:
25
64
  Enabled: false
26
65
 
66
+ Style/Documentation:
67
+ Enabled: false
68
+
69
+ Style/FrozenStringLiteralComment:
70
+ Enabled: false
71
+
27
72
  Style/PercentLiteralDelimiters:
28
73
  Enabled: false
29
74
 
30
75
  Style/RegexpLiteral:
31
76
  Enabled: false
32
77
 
78
+ Style/StringConcatenation:
79
+ Exclude:
80
+ - spec/**/*
81
+
33
82
  Style/StringLiterals:
34
83
  Enabled: false
35
84
 
36
85
  Style/StringLiteralsInInterpolation:
37
86
  Enabled: false
87
+
88
+ Style/TrailingCommaInHashLiteral:
89
+ EnforcedStyleForMultiline: comma
data/CHANGELOG.md CHANGED
@@ -1,18 +1,26 @@
1
+ ## 2.0.15 / 2023-02-18
2
+ * Replaced dependency `key-value-parser` with `jekyll_plugin_support`.
3
+ * Added `demo` website.
4
+ * Improved the documentation.
5
+ * Updated Rubocop configuration.
6
+ * Added `strip` option.
7
+
1
8
  ## 2.0.14 / 2022-09-27
2
- * Added `key-value-parser` as a dependency
9
+ * Added `key-value-parser` as a dependency.
3
10
 
4
11
  ## 2.0.13 / 2022-04-24
5
- * Added `highlight` regex option, for highlighting
6
- * Added `number` option, for numbered lines
12
+ * Added `highlight` regex option, for highlighting.
13
+ * Added `number` option, for numbered lines.
7
14
 
8
15
  ## 2.0.12 / 2022-04-22
9
- * Exits with an error message if an environment variable included in the value of `FLEXIBLE_INCLUDE_PATHS` is undefined.
16
+ * Exits with an error message if an environment variable included in the value
17
+ of `FLEXIBLE_INCLUDE_PATHS` is undefined.
10
18
 
11
19
  ## 2.0.11 / 2022-04-15
12
- * Added & => & to the escaped characters
20
+ * Added & => & to the escaped characters.
13
21
 
14
22
  ## 2.0.10 / 2022-04-15
15
- * Fixed nil pointer
23
+ * Fixed nil pointer.
16
24
 
17
25
  ## 2.0.9 / 2022-04-15
18
26
  * Changed how path matching was implemented.
@@ -40,10 +48,11 @@
40
48
  * Updated to `jekyll_plugin_logger` v2.1.0
41
49
 
42
50
  ## 2.0.0 / 2022-03-11
43
- * Made into a Ruby gem and published on RubyGems.org as [jekyll_flexible_include](https://rubygems.org/gems/jekyll_flexible_include).
44
- * `bin/attach` script added for debugging
45
- * Rubocop standards added
46
- * Proper versioning and CHANGELOG.md added
51
+ * Made into a Ruby gem and published on RubyGems.org as
52
+ [jekyll_flexible_include](https://rubygems.org/gems/jekyll_flexible_include).
53
+ * `bin/attach` script added for debugging.
54
+ * Rubocop standards added.
55
+ * Proper versioning and CHANGELOG.md added.
47
56
 
48
57
  ## 1.1.1 / 2021-05-01
49
58
  * Handles spaces in filenames properly.
@@ -52,14 +61,14 @@
52
61
  * Added `do_not_escape` optional parameter.
53
62
 
54
63
  ## 1.0.0 / 2020-11-28
55
- * Mike Slinn took over the project
56
- * Now supports relative includes
64
+ * Mike Slinn took over the project.
65
+ * Now supports relative includes.
57
66
 
58
67
  ## 2020-11-28
59
- * Renamed include_absolute to flexible_include
68
+ * Mike Slinn renamed `include_absolute` to `flexible_include`.
60
69
 
61
70
  ## 2020-08-23
62
- * Now supports absolute paths
71
+ * Now supports absolute paths.
63
72
 
64
73
  ## 2022-03-11
65
- * Project began
74
+ * Project began.
data/README.md CHANGED
@@ -2,52 +2,83 @@ Jekyll `flexible_include` Plugin
2
2
  [![Gem Version](https://badge.fury.io/rb/jekyll_flexible_include.svg)](https://badge.fury.io/rb/jekyll_flexible_include)
3
3
  ===========
4
4
 
5
- `Flexible_include` is a Jekyll plugin that includes the contents of a file or the result of a process into a generated page. `Flexible_include` is useful because Jekyll's built-in `include` tag only supports the including of files residing within the `_includes/` subfolder of a Jekyll project, and because `flexible_include` offers additional ways of including content.
5
+ `Flexible_include` is a Jekyll plugin that includes the contents of a file
6
+ or the result of a process into a generated page.
7
+ `Flexible_include` is useful because Jekyll's built-in `include` tag only
8
+ supports the including of files residing within the `_includes/` subfolder of a Jekyll project,
9
+ and because `flexible_include` offers additional ways of including content.
6
10
 
7
- Originally called `include_absolute`, this plugin has been renamed to `flexible_include` because it no longer just includes absolute file names.
11
+ Originally called `include_absolute`,
12
+ this plugin has been renamed to `flexible_include` because it no longer just
13
+ includes absolute file names.
8
14
 
9
15
  This plugin is available as a [Ruby gem](https://rubygems.org/gems/jekyll_flexible_include).
10
16
  More information is available on my website about [my Jekyll plugins](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html).
11
17
 
12
18
  This plugin supports 4 types of includes:
13
19
 
20
+
14
21
  ### Include Types
15
22
 
16
23
  1. Absolute filenames (recognized by filename paths that start with `/`).
17
- 2. Filenames relative to the top-level directory of the Jekyll web site (relative paths **do not** start with `.` or `/`).
24
+
25
+ 2. Filenames relative to the top-level directory of the Jekyll website (relative paths **do not** start with `.` or `/`).
26
+
18
27
  3. Filenames relative to the user home directory (recognized by filename paths starting with `~/`).
28
+
19
29
  4. Executable filenames on the `PATH` (recognized by filename paths that begin with `!`).
20
30
 
21
31
 
22
- In addition, filenames that require environment expansion because they contain a <code>$</code> character are
23
- expanded according to the environment variables defined when <code>jekyll build</code> executes.
32
+ In addition, filenames that require environment expansion because they contain a
33
+ <code>$</code> character are expanded according to the environment variables
34
+ defined when <code>jekyll build</code> executes.
24
35
 
25
36
 
26
37
  ### Syntax
27
38
  The following are equivalent:
28
- ```
39
+ ```html
29
40
  {% flexible_include path [ OPTIONS ] %}
30
41
  {% flexible_include 'path' [ OPTIONS ] %}
31
42
  {% flexible_include "path" [ OPTIONS ] %}
32
43
  ```
33
44
 
34
- By default, the included file will escape characters <code>&lt;</code>, <code>{</code> and <code>}</code>
35
- unless <code>do_not_escape</code> is specified.
36
- Note that the [square brackets] merely indicate optional parameters and are not intended to be written literally.
45
+ By default, the included file will escape characters <code>&lt;</code>,
46
+ <code>{</code> and <code>}</code> unless the <code>do_not_escape</code> keyword option is specified.
47
+ Note that the [square brackets] merely indicate optional parameters
48
+ and are not intended to be written literally.
49
+
37
50
 
38
51
  ### Options
39
52
  * `do_not_escape` includes the content without HTML escaping it.
40
- * `highlight='regex pattern here'` wraps content matching the regex pattern within a `<span class='bg_yellow'></span>` tag.
41
- * `pre` causes the included file to be wrapped inside a &lt;pre>&lt;/pre> tag, no label is generated. The &lt;pre>&lt;/pre> tag has an `data-lt-active="false"` attribute, so [LanguageTool](https://forum.languagetool.org/t/avoid-spell-check-on-certain-html-inputs-manually/3944) does not check the spelling or grammar of the contents.
53
+
54
+ * `highlight='regex pattern here'` wraps content matching the regex pattern within a
55
+ `<span class='bg_yellow'></span>` tag.
56
+ Note that the pattern can simply consist of the exact text that you want to highlight.
57
+
58
+ * `pre` causes the included file to be wrapped inside a &lt;pre>&lt;/pre> tag,
59
+ no label is generated.
60
+ The &lt;pre>&lt;/pre> tag has an `data-lt-active="false"` attribute, so
61
+ [LanguageTool](https://forum.languagetool.org/t/avoid-spell-check-on-certain-html-inputs-manually/3944)
62
+ will not attempt to check the spelling or grammar of the contents.
42
63
 
43
64
  The following options imply `pre`:
44
65
  * `dark` applies the `dark` class to the generated &lt;pre>&lt;/pre> tag.
45
66
  You can define the `dark` and `darkLabel` classes as desired.
46
67
  [This CSS is a good starting point.](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#pre_css)
47
- * `download` uses the name of the file as a label, and displays it above the &lt;pre>&lt;/pre> tag. Clicking the label causes the file to be downloaded.
48
- * `copy_button` draws an icon at the top right of the &lt;pre>&lt;/pre> tag that causes the included contents to be copied to the clipboard.
49
- * `label` specifies that an automatically generated label be placed above the contents. There is no need to specify this option if `download` or `copy_button` options are provided.
50
- * `label="blah blah"` specifies a label for the contents; this value overrides the default label. The value can be enclosed in single or double quotes.
68
+
69
+ * `download` uses the name of the file as a label,
70
+ and displays it above the &lt;pre>&lt;/pre> tag.
71
+ Clicking the label causes the file to be downloaded.
72
+
73
+ * `copy_button` draws an icon at the top right of the &lt;pre>&lt;/pre>
74
+ tag that causes the included contents to be copied to the clipboard.
75
+
76
+ * `label` specifies that an automatically generated label be placed above the contents.
77
+ There is no need to specify this option if `download` or `copy_button` options are provided.
78
+
79
+ * `label="blah blah"` specifies a label for the contents; this value overrides the default label.
80
+ The value can be enclosed in single or double quotes.
81
+
51
82
 
52
83
  ### Restricting Directory Access
53
84
  By default, `flexible_include` can read from all directories according to the permissions of the user account that launched the `jekyll` process.
@@ -57,58 +88,85 @@ Defining an environment variable called `FLEXIBLE_INCLUDE_PATHS` prior to launch
57
88
  This environment variable consists of a colon-delimited set of
58
89
  [file and directory glob patterns](https://docs.ruby-lang.org/en/2.7.0/Dir.html#method-c-glob).
59
90
  For example, the following restricts access to only the files within:
91
+
60
92
  1. The `~/my_dir` directory tree of the account of the user that launched Jekyll.
93
+
61
94
  2. The directory tree rooted at `/var/files`.
95
+
62
96
  3. The directory tree rooted at the expanded value of the `$work` environment variable.
97
+
63
98
  ```shell
64
99
  export FLEXIBLE_INCLUDE_PATHS='~/.*:$sites/.*:$work/.*'
65
100
  ```
101
+
66
102
  Note that the above matches dot (hidden) files as well as regular files.
67
103
  To just match visible files:
104
+
68
105
  ```shell
69
106
  export FLEXIBLE_INCLUDE_PATHS='~/my_dir/**/*:/var/files/**/*:$work/**/*'
70
107
  ```
71
108
 
72
109
  #### Note
73
- The specified directories are traversed when the plugin starts, and the filenames are stored in memory. Directories with lots of files might take a noticable amount to time to enumerate the files.
110
+ The specified directories are traversed when the plugin starts,
111
+ and the filenames are stored in memory.
112
+ Directories with lots of files might take a noticable amount of
113
+ time to enumerate the files.
74
114
 
75
115
 
76
116
  ### Restricting Arbitrary Processes
77
- By default, `flexible_include` can execute any command. You can disable that by setting the environment variable `DISABLE_FLEXIBLE_INCLUDE` to any non-empty value.
117
+ By default, `flexible_include` can execute any command.
118
+ You can disable that by setting the environment variable `DISABLE_FLEXIBLE_INCLUDE`
119
+ to any non-empty value.
78
120
  ```shell
79
121
  export DISABLE_FLEXIBLE_INCLUDE=true
80
122
  ```
81
123
 
82
- If a potential command execution is intercepted, a big red message will appear on the generated web page that says `Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.`, and a red error message will be logged on the console that says something like: `ERROR FlexibleInclude: _posts/2020/2020-10-03-jekyll-plugins.html - Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.`
124
+ If a potential command execution is intercepted,
125
+ a big red message will appear on the generated web page that says
126
+ `Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.`,
127
+ and a red error message will be logged on the console that says something like:
128
+ `ERROR FlexibleInclude: _posts/2020/2020-10-03-jekyll-plugins.html - Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.`
83
129
 
84
130
 
85
131
  ## Installation
132
+ 1. Add the following to `Gemfile`, inside the `jekyll_plugins` group:
133
+ ```
134
+ group :jekyll_plugins do
135
+ gem 'jekyll_flexible_include', '~> 2.0.15'
136
+ end
137
+ ```
86
138
 
87
- Add the following to `Gemfile`, inside the `jekyll_plugins` group:
88
- ```
89
- group :jekyll_plugins do
90
- gem 'jekyll_flexible_include', '~> 2.0.0'
91
- end
92
- ```
139
+ 2. Add the following to `_config.yml`.
140
+ This is necessary because the name of the plugin
141
+ does not match the name of the entry point file:
142
+ ```yaml
143
+ plugins:
144
+ - flexible_include
145
+ ```
93
146
 
94
- Also add it to `_config.yml`:
95
- ```yaml
96
- plugins:
97
- - flexible_include
98
- ```
147
+ 3. Copy `demo/assets/images/clippy.svg` to a directory that resolves to
148
+ `assets/images/` in your Jekyll website.
99
149
 
100
- And then execute:
150
+ 4. Copy the CSS from `demo/assets/css/styles.css` between the comments to your Jekyll project's CSS file:
151
+ ```css
152
+ blah blah blah
101
153
 
102
- $ bundle install
154
+ /* START OF CSS TO COPY */
155
+ Copy this stuff
156
+ /* END OF CSS TO COPY */
103
157
 
104
- Or install it yourself as:
158
+ blah blah blah
159
+ ```
105
160
 
106
- $ gem install jekyll_flexible_include
161
+ 5. Install the `jekyll_flexible_include` Ruby gem as usual:
162
+ ```shell
163
+ $ bundle install
164
+ ```
107
165
 
108
166
 
109
167
  ## Examples
110
168
 
111
- 1. Include files, escaping any HTML markup so it appears as written; all four types of includes are shown.
169
+ 1. Include files, escaping any HTML markup, so it appears as written; all four types of includes are shown.
112
170
  ```
113
171
  {% flexible_include '../../folder/outside/jekyll/site/foo.html' %}
114
172
  {% flexible_include 'folder/within/jekyll/site/bar.js' %}
@@ -132,37 +190,43 @@ More information is available on
132
190
  GitHub Pages only allows [these plugins](https://pages.github.com/versions/).
133
191
  That means `flexible_include` will not work on GitHub Pages.
134
192
  Following is a workaround.
193
+
135
194
  1. Let's assume your git repository that you want to publish as GitHub Pages is called `mysite`.
136
195
  This repository cannot be the source of your GitHub Pages because you are using the `flexible_include` plugin.
196
+
137
197
  2. Make a new git repository to hold the generated website. Let's call this git repository `generated_site`.
198
+
138
199
  3. Generate `mysite` locally as usual.
200
+
139
201
  4. Copy the generated HTML in the `mysite/_site/` directory to `generated_site`.
202
+
140
203
  5. Run `git commit` on `generated_site`.
204
+
141
205
  6. Tell GitHub that you want the `generated_site` repository to hold your GitHub pages.
206
+
142
207
  7. A moment later, your website will now be visible as GitHub Pages, with the included content, just as you saw it locally.
143
208
 
144
209
 
145
210
  ## Known Issues
146
211
  If the plugin does not work:
147
- 1. Ensure `_config.yml` doesn't have `safe: true`. That prevents all plugins from working.
148
- 2. If you have version older than v2.x.x, delete the file `_plugins/flexible_include.rb` or you will have version conflicts.
149
212
 
213
+ 1. Ensure `_config.yml` doesn't have `safe: true`.
214
+ That prevents all plugins from working.
150
215
 
151
- ## Development
216
+ 2. If you have version older than v2.x.x,
217
+ delete the file `_plugins/flexible_include.rb`,
218
+ or you will have version conflicts.
152
219
 
153
- After checking out the repo, run `bin/setup` to install dependencies.
220
+
221
+ ## Development
222
+ After checking out the repo, run `bin/setup` to install dependencies as binstubs in the `exe` directory.
154
223
 
155
224
  You can also run `bin/console` for an interactive prompt that will allow you to experiment.
156
225
 
157
226
  ### Build and Install Locally
158
227
  To build and install this gem onto your local machine, run:
159
228
  ```shell
160
- $ rake install:local
161
- ```
162
-
163
- The following also does the same thing:
164
- ```shell
165
- $ bundle exec rake install
229
+ $ rake install
166
230
  ```
167
231
 
168
232
  Examine the newly built gem:
@@ -182,11 +246,42 @@ jekyll_flexible_include (2.0.4)
182
246
  ```
183
247
 
184
248
 
249
+ ## Demo
250
+ A test/demo website is provided in the `demo` directory.
251
+ You can run it under a debugger, or let it run free.
252
+
253
+ ### Free Range Demo Website
254
+ To let it run freely, without a debugger, use the `-r` option:
255
+ ```shell
256
+ $ demo/bin/debug -r
257
+ ```
258
+
259
+ View the generated website at [`http://localhost:4444`](http://localhost:4444)
260
+
261
+ ### Demo Website Debugging
262
+ To run under a debugger, for example Visual Studio Code:
263
+ 1. Set breakpoints.
264
+
265
+ 2. Initiate a debug session from the command line:
266
+ ```shell
267
+ $ demo/bin/debug
268
+ ```
269
+
270
+ 3. Once the `Fast Debugger` signon appears, launch the Visual Studio Code launch configuration called `Attach rdebug-ide`.
271
+
272
+ 4. View the generated website at [`http://localhost:4444`](http://localhost:4444)
273
+
274
+
185
275
  ### Build and Push to RubyGems
186
276
  To release a new version,
277
+
187
278
  1. Update the version number in `version.rb`.
188
- 2. Commit all changes to git; if you don't the next step might fail with an unexplainable error message.
189
- 3. Run the following:
279
+
280
+ 2. Add a comment to the top of `CHANGELOG.md`.
281
+
282
+ 3. Commit all changes to git; if you don't the next step will fail.
283
+
284
+ 4. Run the following:
190
285
  ```shell
191
286
  $ bundle exec rake release
192
287
  ```
@@ -195,12 +290,14 @@ To release a new version,
195
290
 
196
291
 
197
292
  ## Contributing
198
-
199
293
  1. Fork the project
294
+
200
295
  2. Create a descriptively named feature branch
296
+
201
297
  3. Add your feature
298
+
202
299
  4. Submit a pull request
203
300
 
204
- ## License
205
301
 
302
+ ## License
206
303
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,7 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
5
3
 
6
4
  RSpec::Core::RakeTask.new(:spec)
7
- task :default => :spec
5
+ task default: :spec
@@ -1,12 +1,10 @@
1
- # frozen_string_literal: true
1
+ require_relative 'lib/flexible_include/version'
2
2
 
3
- require_relative "lib/flexible_include/version"
3
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
4
+ github = 'https://github.com/mslinn/jekyll_flexible_include_plugin'
4
5
 
5
- Gem::Specification.new do |spec|
6
- github = "https://github.com/mslinn/jekyll_flexible_include_plugin"
7
-
8
- spec.authors = ["Mike Slinn", "Tan Nhu", "Maarten Brakkee"]
9
- spec.bindir = "exe"
6
+ spec.authors = ['Mike Slinn', 'Tan Nhu', 'Maarten Brakkee']
7
+ spec.bindir = 'exe'
10
8
  spec.description = <<~END_OF_DESC
11
9
  Jekyll's built-in include tag only supports including files within the _includes folder.
12
10
  This plugin supports 4 types of includes: absolute filenames,
@@ -14,36 +12,28 @@ Gem::Specification.new do |spec|
14
12
  filenames relative to the user home directory,
15
13
  and executable filenames on the PATH.
16
14
  END_OF_DESC
17
- spec.email = ["mslinn@mslinn.com"]
18
- spec.files = Dir[".rubocop.yml", "LICENSE.*", "Rakefile", "{lib,spec}/**/*", "*.gemspec", "*.md"]
19
- spec.homepage = "https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#flexibleInclude"
20
- spec.license = "MIT"
15
+ spec.email = ['mslinn@mslinn.com']
16
+ spec.files = Dir['.rubocop.yml', 'LICENSE.*', 'Rakefile', '{lib,spec}/**/*', '*.gemspec', '*.md']
17
+ spec.homepage = 'https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#flexibleInclude'
18
+ spec.license = 'MIT'
21
19
  spec.metadata = {
22
- "allowed_push_host" => "https://rubygems.org",
23
- "bug_tracker_uri" => "#{github}/issues",
24
- "changelog_uri" => "#{github}/CHANGELOG.md",
25
- "homepage_uri" => spec.homepage,
26
- "source_code_uri" => github,
20
+ 'allowed_push_host' => 'https://rubygems.org',
21
+ 'bug_tracker_uri' => "#{github}/issues",
22
+ 'changelog_uri' => "#{github}/CHANGELOG.md",
23
+ 'homepage_uri' => spec.homepage,
24
+ 'source_code_uri' => github,
27
25
  }
28
- spec.name = "jekyll_flexible_include"
26
+ spec.name = 'jekyll_flexible_include'
29
27
  spec.post_install_message = <<~END_MESSAGE
30
28
 
31
29
  Thanks for installing #{spec.name}!
32
30
 
33
31
  END_MESSAGE
34
- spec.require_paths = ["lib"]
35
- spec.required_ruby_version = ">= 2.6.0"
36
- spec.summary = "Jekyll plugin supports various ways to include content into the generated site."
32
+ spec.require_paths = ['lib']
33
+ spec.required_ruby_version = '>= 2.6.0'
34
+ spec.summary = 'Jekyll plugin supports various ways to include content into the generated site.'
37
35
  spec.test_files = spec.files.grep(%r!^(test|spec|features)/!)
38
36
  spec.version = JekyllFlexibleIncludePluginVersion::VERSION
39
37
 
40
- spec.add_dependency "jekyll", ">= 3.5.0"
41
- spec.add_dependency "jekyll_plugin_logger", '~> 2.1.0'
42
- spec.add_dependency "key-value-parser"
43
-
44
- # spec.add_development_dependency "debase"
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"
38
+ spec.add_dependency 'jekyll_plugin_support', '~> 0.5.1'
49
39
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module JekyllFlexibleIncludePluginVersion
4
- VERSION = "2.0.14"
2
+ VERSION = '2.0.15'.freeze
5
3
  end
@@ -1,128 +1,102 @@
1
- # frozen_string_literal: true
2
-
3
- require "benchmark"
4
- require "jekyll"
5
- require "jekyll_plugin_logger"
6
- require "securerandom"
7
- require_relative "flexible_include/version"
8
- require_relative "jekyll_tag_helper"
1
+ require 'benchmark'
2
+ require 'jekyll_plugin_support'
3
+ require 'securerandom'
4
+ require_relative 'flexible_include/version'
9
5
 
10
6
  module JekyllFlexibleIncludeName
11
- PLUGIN_NAME = "flexible_include"
12
- end
13
-
14
- class FlexibleError < StandardError
7
+ PLUGIN_NAME = 'flexible_include'.freeze
15
8
  end
16
9
 
17
- class FlexibleInclude < Liquid::Tag
18
- FlexibleIncludeError = Class.new(Liquid::Error)
19
-
20
- @read_regexes = nil
10
+ module FlexibleClassMethods
11
+ def access_allowed(path)
12
+ return true unless @read_regexes
21
13
 
22
- def self.normalize_path(path)
23
- JekyllTagHelper.expand_env(path, die_if_undefined: true)
24
- .gsub("~", Dir.home)
14
+ @read_regexes.find { |regex| regex.match(normalize_path(path)) }
25
15
  end
26
16
 
27
- # If FLEXIBLE_INCLUDE_PATHS='~/lib/.*:.*:$WORK/.*'
28
- # Then @read_regexes will be set to regexes of ["/home/my_user_id/lib/.*", "/pwd/.*", "/work/envar/path/.*"]
29
- def self.security_check
30
- @execution_denied = ENV['DISABLE_FLEXIBLE_INCLUDE']
31
-
32
- unless @read_regexes
33
- flexible_include_paths = ENV['FLEXIBLE_INCLUDE_PATHS']
34
- read_paths = normalize_path(flexible_include_paths) if flexible_include_paths
35
- if read_paths
36
- @read_regexes = read_paths.split(":").map do |path|
37
- abs_path = path.start_with?('/') ? path : (Pathname.new(Dir.pwd) + path).to_s
38
- Regexp.new(abs_path)
39
- end
40
- end
41
- end
17
+ def self.escape_html(string)
18
+ string.gsub("&", "&amp;")
19
+ .gsub("{", "&#123;")
20
+ .gsub("}", "&#125;")
21
+ .gsub("<", "&lt;")
42
22
  end
43
23
 
44
- def self.access_allowed(path)
45
- return true unless @read_regexes
46
-
47
- @read_regexes.find { |regex| regex.match(normalize_path(path)) }
24
+ def normalize_path(path)
25
+ JekyllPluginHelper.expand_env(path, die_if_undefined: true)
26
+ .gsub('~', Dir.home)
48
27
  end
49
28
 
50
- def self.number_content(content)
29
+ def number_content(content)
51
30
  lines = content.split("\n")
52
31
  digits = lines.length.to_s.length
53
32
  i = 0
54
33
  numbered_content = lines.map do |line|
55
34
  i += 1
56
- number = i.to_s.rjust(digits, " ")
35
+ number = i.to_s.rjust(digits, ' ')
57
36
  "<span class='unselectable numbered_line'> #{number}: </span>#{line}"
58
37
  end
59
- result = numbered_content.join("\n")
60
- result += "\n" unless result.end_with?("\n")
38
+ result = numbered_content.join "\n"
39
+ result += "\n" unless result.end_with? "\n"
61
40
  result
62
41
  end
63
42
 
64
- # @param tag_name [String] the name of the tag, which we already know.
65
- # @param markup [String] the arguments from the tag, as a single string.
66
- # @param parse_context [Liquid::ParseContext] hash that stores Liquid options.
67
- # By default it has two keys: :locale and :line_numbers, the first is a Liquid::I18n object, and the second,
68
- # a boolean parameter that determines if error messages should display the line number the error occurred.
69
- # This argument is used mostly to display localized error messages on Liquid built-in Tags and Filters.
70
- # See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
71
- def initialize(tag_name, markup, _parse_context)
72
- super
73
- @logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
74
- @helper = JekyllTagHelper.new(tag_name, markup, @logger)
43
+ # If FLEXIBLE_INCLUDE_PATHS='~/lib/.*:.*:$WORK/.*'
44
+ # Then @read_regexes will be set to regexes of ['/home/my_user_id/lib/.*', '/pwd/.*', '/work/envar/path/.*']
45
+ def security_check
46
+ @execution_denied = ENV.fetch('DISABLE_FLEXIBLE_INCLUDE', nil)
47
+
48
+ return if @read_regexes
75
49
 
76
- self.class.security_check
50
+ flexible_include_paths = ENV.fetch('FLEXIBLE_INCLUDE_PATHS', nil)
51
+ read_paths = normalize_path(flexible_include_paths) if flexible_include_paths
52
+ return unless read_paths
53
+
54
+ @read_regexes = read_paths.split(':').map do |path|
55
+ abs_path = path.start_with?('/') ? path : (Pathname.new(Dir.pwd) + path).to_s
56
+ Regexp.new(abs_path)
57
+ end
77
58
  end
59
+ end
78
60
 
79
- # @param liquid_context [Liquid::Context]
80
- def render(liquid_context) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity
81
- @helper.liquid_context = liquid_context
82
- @do_not_escape = @helper.parameter_specified? "do_not_escape"
83
- @download = @helper.parameter_specified? "download"
84
- @dark = " dark" if @helper.parameter_specified?("dark")
85
- @highlight_pattern = @helper.parameter_specified? "highlight"
86
- @label = @helper.parameter_specified? "label"
87
- @number_lines = @helper.parameter_specified? "number"
88
- @label_specified = @label
89
- @copy_button = @helper.parameter_specified? "copyButton"
90
- @pre = @copy_button || @dark || @download || @label_specified || @number_lines || @helper.parameter_specified?("pre") # Download or label implies pre
61
+ class FlexibleError < StandardError; end
91
62
 
92
- filename = @helper.parameter_specified? "file"
93
- filename ||= @helper.params.first # Do this after all options have been checked for
94
- @label ||= filename
63
+ class FlexibleInclude < JekyllSupport::JekyllTag
64
+ include JekyllFlexibleIncludePluginVersion
95
65
 
96
- # If a label was specified, use it, otherwise concatenate any dangling parameters and use that as the label
97
- @label ||= @helper.params[1..].join(" ")
66
+ class << self
67
+ include FlexibleClassMethods
68
+ end
98
69
 
99
- @logger.debug("filename=#{filename}")
70
+ FlexibleIncludeError = Class.new(Liquid::Error)
71
+
72
+ def render_impl
73
+ self.class.security_check
74
+ parse_args
75
+ path = JekyllPluginHelper.expand_env(@filename)
100
76
 
101
- path = JekyllTagHelper.expand_env(filename)
102
77
  case path
103
78
  when /\A\// # Absolute path
104
79
  return denied("Access to #{path} denied by FLEXIBLE_INCLUDE_PATHS value.") unless self.class.access_allowed(path)
105
80
 
106
- @logger.debug { "Absolute path=#{path}, filename=#{filename}" }
81
+ @logger.debug { "Absolute path=#{path}, @filename=#{@filename}" }
107
82
  when /\A~/ # Relative path to user's home directory
108
83
  return denied("Access to #{path} denied by FLEXIBLE_INCLUDE_PATHS value.") unless self.class.access_allowed(path)
109
84
 
110
- @logger.debug { "User home start filename=#{filename}, path=#{path}" }
111
- filename.slice! "~/"
112
- path = File.join(ENV['HOME'], filename)
113
- @logger.debug { "User home end filename=#{filename}, path=#{path}" }
85
+ @logger.debug { "User home start @filename=#{@filename}, path=#{path}" }
86
+ @filename = @filename.delete_prefix '~/'
87
+ path = File.join(Dir.home, @filename)
88
+ @logger.debug { "User home end @filename=#{@filename}, path=#{path}" }
114
89
  when /\A!/ # Run command and return response
115
- return denied("Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.") if @execution_denied
90
+ return denied('Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.') if @execution_denied
116
91
 
117
- filename = JekyllTagHelper.remove_quotes(@helper.argv.first) if @helper.argv.first
118
- filename.slice! "!"
119
- contents = run(filename)
92
+ @filename = JekyllPluginHelper.remove_quotes(@helper.argv.first) if @helper.argv.first
93
+ @filename = @filename.delete_prefix '!'
94
+ contents = run(@filename)
120
95
  else # Relative path
121
- site = liquid_context.registers[:site]
122
- source = File.expand_path(site.config['source']) # website root directory
123
- path = File.join(source, filename) # Fully qualified path of include file from relative path
96
+ source = File.expand_path(@site.config['source']) # website root directory
97
+ path = File.join(source, @filename) # Fully qualified path of include file from relative path
124
98
  @relative = true
125
- @logger.debug { "Relative end filename=#{filename}, path=#{path}" }
99
+ @logger.debug { "Relative end @filename=#{@filename}, path=#{path}" }
126
100
  end
127
101
  render_completion(path, contents)
128
102
  # rescue StandardError => e
@@ -140,6 +114,30 @@ class FlexibleInclude < Liquid::Tag
140
114
  content.gsub(Regexp::new(pattern), "<span class='bg_yellow'>\\0</span>")
141
115
  end
142
116
 
117
+ def parse_args
118
+ @copy_button = @helper.parameter_specified? 'copyButton'
119
+ @dark = ' dark' if @helper.parameter_specified? 'dark'
120
+ @do_not_escape = @helper.parameter_specified? 'do_not_escape'
121
+ @download = @helper.parameter_specified? 'download'
122
+ @highlight_pattern = @helper.parameter_specified? 'highlight'
123
+ @label = @helper.parameter_specified? 'label'
124
+ @label_specified = @label
125
+ @number_lines = @helper.parameter_specified? 'number'
126
+ @strip = @helper.parameter_specified? 'strip'
127
+
128
+ # Download, dark, label or number implies pre
129
+ @pre = @helper.parameter_specified?('pre') || @copy_button || @dark || @download || @label_specified || @number_lines
130
+
131
+ @filename = @helper.parameter_specified? 'file'
132
+ @filename ||= @helper.params.first # Do this after all options have been checked for
133
+ @label ||= @filename
134
+
135
+ # If a label was specified, use it, otherwise concatenate any dangling parameters and use that as the label
136
+ @label ||= @helper.params[1..].join(' ')
137
+
138
+ @logger.debug("@filename=#{@filename}")
139
+ end
140
+
143
141
  def read_file(file)
144
142
  File.read(file)
145
143
  end
@@ -152,19 +150,20 @@ class FlexibleInclude < Liquid::Tag
152
150
 
153
151
  def render_completion(path, contents)
154
152
  contents ||= read_file(path)
155
- contents2 = @do_not_escape ? contents : JekyllTagHelper.escape_html(contents)
153
+ contents.strip! if @strip
154
+ contents2 = @do_not_escape ? contents : FlexibleClassMethods.escape_html(contents)
156
155
  contents2 = highlight(contents2, @highlight_pattern) if @highlight_pattern
157
156
  contents2 = FlexibleInclude.number_content(contents2) if @number_lines
158
157
  @pre ? wrap_in_pre(path, contents2) : contents2
159
158
  end
160
159
 
161
160
  def run(cmd)
162
- @logger.debug { "Executing filename=#{cmd}" }
161
+ @logger.debug { "Executing @filename=#{cmd}" }
163
162
  %x[#{cmd}].chomp
164
163
  end
165
164
 
166
- PREFIX = "<button class='copyBtn' data-clipboard-target="
167
- SUFFIX = "title='Copy to clipboard'><img src='/assets/images/clippy.svg' alt='Copy to clipboard' style='width: 13px'></button>"
165
+ PREFIX = "<button class='copyBtn' data-clipboard-target=".freeze
166
+ SUFFIX = "title='Copy to clipboard'><img src='/assets/images/clippy.svg' alt='Copy to clipboard' style='width: 13px'></button>".freeze
168
167
 
169
168
  def wrap_in_pre(path, content)
170
169
  basename = File.basename(path)
@@ -178,14 +177,13 @@ class FlexibleInclude < Liquid::Tag
178
177
  @label_specified ? @label : basename
179
178
  end
180
179
  pre_id = "id#{SecureRandom.hex 6}"
181
- copy_button = @copy_button ? "#{PREFIX}'##{pre_id}'#{SUFFIX}" : ""
182
- dark_label = " darkLabel" if @dark
180
+ copy_button = @copy_button ? "#{PREFIX}'##{pre_id}'#{SUFFIX}" : ''
181
+ dark_label = ' darkLabel' if @dark
183
182
  <<~END_PRE
184
183
  <div class="codeLabel#{dark_label}">#{label_or_href}</div>
185
184
  <pre data-lt-active="false" class="maxOneScreenHigh copyContainer#{@dark}" id="#{pre_id}">#{copy_button}#{content}</pre>
186
185
  END_PRE
187
186
  end
188
- end
189
187
 
190
- PluginMetaLogger.instance.info { "Loaded #{JekyllFlexibleIncludeName::PLUGIN_NAME} v#{JekyllFlexibleIncludePluginVersion::VERSION} plugin." }
191
- Liquid::Template.register_tag('flexible_include', FlexibleInclude)
188
+ JekyllPluginHelper.register(self, 'flexible_include')
189
+ end
data/spec/glob_spec.rb CHANGED
@@ -1,20 +1,18 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../lib/flexible_include"
1
+ require_relative '../lib/flexible_include'
4
2
 
5
3
  RSpec.describe(FlexibleInclude) do
6
- it "controls access to files" do
4
+ it 'controls access to files' do
7
5
  ENV['FLEXIBLE_INCLUDE_PATHS'] = '~/.*:spec/.*'
8
6
 
9
- FlexibleInclude.send(:new, 'my_tag', "", Liquid::ParseContext.new)
10
- FlexibleInclude.security_check
11
- expect(FlexibleInclude.access_allowed(__FILE__)).to be_truthy
7
+ described_class.send(:new, 'my_tag', '', Liquid::ParseContext.new)
8
+ described_class.security_check
9
+ expect(described_class.access_allowed(__FILE__)).to be_truthy
12
10
 
13
- expect(FlexibleInclude.access_allowed("~/.mem_settings.yaml")).to be_truthy
11
+ expect(described_class.access_allowed('~/.mem_settings.yaml')).to be_truthy
14
12
 
15
- home_file = JekyllTagHelper.expand_env("$HOME/.mem_settings.yaml")
16
- expect(FlexibleInclude.access_allowed(home_file)).to be_truthy
13
+ home_file = JekyllTagHelper.expand_env('$HOME/.mem_settings.yaml')
14
+ expect(described_class.access_allowed(home_file)).to be_truthy
17
15
 
18
- expect(FlexibleInclude.access_allowed('/asdf')).to be_falsey
16
+ expect(described_class.access_allowed('/asdf')).to be_falsey
19
17
  end
20
18
  end
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,14 @@
1
- # frozen_string_literal: true
1
+ require 'jekyll'
2
2
 
3
- require "jekyll"
4
-
5
- require_relative "../lib/flexible_include"
3
+ require_relative '../lib/flexible_include'
6
4
 
7
5
  Jekyll.logger.log_level = :info
8
6
 
9
7
  RSpec.configure do |config|
10
8
  config.filter_run :focus
11
- config.order = "random"
9
+ config.order = 'random'
12
10
  config.run_all_when_everything_filtered = true
13
11
 
14
12
  # See https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures
15
- config.example_status_persistence_file_path = "spec/status_persistence.txt"
13
+ config.example_status_persistence_file_path = 'spec/status_persistence.txt'
16
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll_flexible_include
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.14
4
+ version: 2.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Slinn
@@ -10,50 +10,22 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-09-27 00:00:00.000000000 Z
13
+ date: 2023-02-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: jekyll
17
- requirement: !ruby/object:Gem::Requirement
18
- requirements:
19
- - - ">="
20
- - !ruby/object:Gem::Version
21
- version: 3.5.0
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- version: 3.5.0
29
- - !ruby/object:Gem::Dependency
30
- name: jekyll_plugin_logger
16
+ name: jekyll_plugin_support
31
17
  requirement: !ruby/object:Gem::Requirement
32
18
  requirements:
33
19
  - - "~>"
34
20
  - !ruby/object:Gem::Version
35
- version: 2.1.0
21
+ version: 0.5.1
36
22
  type: :runtime
37
23
  prerelease: false
38
24
  version_requirements: !ruby/object:Gem::Requirement
39
25
  requirements:
40
26
  - - "~>"
41
27
  - !ruby/object:Gem::Version
42
- version: 2.1.0
43
- - !ruby/object:Gem::Dependency
44
- name: key-value-parser
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: '0'
50
- type: :runtime
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: '0'
28
+ version: 0.5.1
57
29
  description: |
58
30
  Jekyll's built-in include tag only supports including files within the _includes folder.
59
31
  This plugin supports 4 types of includes: absolute filenames,
@@ -73,7 +45,6 @@ files:
73
45
  - jekyll_flexible_include_plugin.gemspec
74
46
  - lib/flexible_include.rb
75
47
  - lib/flexible_include/version.rb
76
- - lib/jekyll_tag_helper.rb
77
48
  - spec/glob_spec.rb
78
49
  - spec/spec_helper.rb
79
50
  - spec/status_persistence.txt
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "shellwords"
4
- require 'key_value_parser'
5
-
6
- class JekyllTagHelper
7
- attr_reader :argv, :liquid_context, :logger, :params, :tag_name
8
-
9
- def self.escape_html(string)
10
- string.gsub("&", "&amp;")
11
- .gsub("{", "&#123;")
12
- .gsub("}", "&#125;")
13
- .gsub("<", "&lt;")
14
- end
15
-
16
- # Expand a environment variable reference
17
- def self.expand_env(str, die_if_undefined=false)
18
- str.gsub(/\$([a-zA-Z_][a-zA-Z0-9_]*)|\${\g<1>}|%\g<1>%/) do
19
- envar = Regexp.last_match(1)
20
- raise FlexibleError, "flexible_include error: #{envar} is undefined".red, [] if !ENV.key?(envar) && die_if_undefined # Suppress stack trace
21
- ENV[envar]
22
- end
23
- end
24
-
25
- # strip leading and trailing quotes if present
26
- def self.remove_quotes(string)
27
- string.strip.gsub(/\A'|\A"|'\Z|"\Z/, '').strip if string
28
- end
29
-
30
- def initialize(tag_name, markup, logger)
31
- @tag_name = tag_name
32
- @argv = Shellwords.split(markup)
33
- @keys_values = KeyValueParser.new.parse(@argv) # Hash[Symbol, String|Boolean]
34
- @logger = logger
35
- @logger.debug { "@keys_values='#{@keys_values}'" }
36
- end
37
-
38
- def delete_parameter(name)
39
- @params.delete(name)
40
- @argv.delete_if { |x| x.start_with? name }
41
- @keys_values.delete(name.to_sym)
42
- end
43
-
44
- # @return if parameter was specified, returns value and removes it from the available tokens
45
- def parameter_specified?(name)
46
- value = @keys_values[name.to_sym]
47
- delete_parameter(name)
48
- value
49
- end
50
-
51
- PREDEFINED_SCOPE_KEYS = [:include, :page].freeze
52
-
53
- # Finds variables defined in an invoking include, or maybe somewhere else
54
- # @return variable value or nil
55
- def dereference_include_variable(name)
56
- @liquid_context.scopes.each do |scope|
57
- next if PREDEFINED_SCOPE_KEYS.include? scope.keys.first
58
-
59
- value = scope[name]
60
- return value if value
61
- end
62
- nil
63
- end
64
-
65
- # @return value of variable, or the empty string
66
- def dereference_variable(name)
67
- value = @liquid_context[name] # Finds variables named like 'include.my_variable', found in @liquid_context.scopes.first
68
- value ||= @page[name] if @page # Finds variables named like 'page.my_variable'
69
- value ||= dereference_include_variable(name)
70
- value ||= ""
71
- value
72
- end
73
-
74
- # Sets @params by replacing any Liquid variable names with their values
75
- def liquid_context=(context)
76
- @liquid_context = context
77
- @params = @keys_values.map { |k, _v| lookup_variable(k) }
78
- end
79
-
80
- def lookup_variable(symbol)
81
- string = symbol.to_s
82
- return string unless string.start_with?("{{") && string.end_with?("}}")
83
-
84
- dereference_variable(string.delete_prefix("{{").delete_suffix("}}"))
85
- end
86
-
87
- def page
88
- @liquid_context.registers[:page]
89
- end
90
- end