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 +4 -4
- data/.rubocop.yml +60 -8
- data/CHANGELOG.md +24 -15
- data/README.md +145 -48
- data/Rakefile +3 -5
- data/jekyll_flexible_include_plugin.gemspec +19 -29
- data/lib/flexible_include/version.rb +1 -3
- data/lib/flexible_include.rb +93 -95
- data/spec/glob_spec.rb +9 -11
- data/spec/spec_helper.rb +4 -6
- metadata +5 -34
- data/lib/jekyll_tag_helper.rb +0 -90
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ef5ec6b930c61453fe741a89ea81e1da2d9303d910a23a9520f12c47a10b802b
|
|
4
|
+
data.tar.gz: 629a43513ddb0a6203024eeccbb52e8442d01612f5d10e2fc5451f4a9c739e52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d16333226e03cab0849b10d1b3c022c24f03d50d4e27c1459fc0e831f0bab64d080832dac3d3671dc9e1727e60e90a15864b4f74b6860d4045404f9058e5580b
|
|
7
|
+
data.tar.gz: ca350963ac6320ad1a1384ab8b2e3eea2c3e6043c12c0b872b95bfb05e942bc070a64a8b5631a642eaea4bd72f11fc7286b25e93a90643a6d54954a5b5b103ef
|
data/.rubocop.yml
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
|
-
require:
|
|
2
|
-
|
|
3
|
-
rubocop-jekyll
|
|
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
|
-
|
|
8
|
-
|
|
10
|
+
- demo/_site/**/*
|
|
11
|
+
- exe/**/*
|
|
12
|
+
- vendor/**/*
|
|
13
|
+
- Gemfile*
|
|
9
14
|
NewCops: enable
|
|
10
15
|
TargetRubyVersion: 2.6
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
44
|
-
|
|
45
|
-
*
|
|
46
|
-
*
|
|
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
|
-
*
|
|
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
|
[](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
|
|
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`,
|
|
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
|
-
|
|
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
|
|
23
|
-
expanded according to the environment variables
|
|
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><</code>,
|
|
35
|
-
unless <code>do_not_escape</code> is specified.
|
|
36
|
-
Note that the [square brackets] merely indicate optional parameters
|
|
45
|
+
By default, the included file will escape characters <code><</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
|
-
|
|
41
|
-
* `
|
|
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 <pre></pre> tag,
|
|
59
|
+
no label is generated.
|
|
60
|
+
The <pre></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 <pre></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
|
-
|
|
48
|
-
* `
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
|
|
69
|
+
* `download` uses the name of the file as a label,
|
|
70
|
+
and displays it above the <pre></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 <pre></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,
|
|
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.
|
|
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,
|
|
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 `
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
95
|
-
|
|
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
|
-
|
|
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
|
-
|
|
154
|
+
/* START OF CSS TO COPY */
|
|
155
|
+
Copy this stuff
|
|
156
|
+
/* END OF CSS TO COPY */
|
|
103
157
|
|
|
104
|
-
|
|
158
|
+
blah blah blah
|
|
159
|
+
```
|
|
105
160
|
|
|
106
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
189
|
-
|
|
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,12 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative 'lib/flexible_include/version'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
4
|
+
github = 'https://github.com/mslinn/jekyll_flexible_include_plugin'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
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 = [
|
|
18
|
-
spec.files = Dir[
|
|
19
|
-
spec.homepage =
|
|
20
|
-
spec.license =
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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 =
|
|
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 = [
|
|
35
|
-
spec.required_ruby_version =
|
|
36
|
-
spec.summary =
|
|
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
|
|
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
|
data/lib/flexible_include.rb
CHANGED
|
@@ -1,128 +1,102 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
|
|
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 =
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
class FlexibleError < StandardError
|
|
7
|
+
PLUGIN_NAME = 'flexible_include'.freeze
|
|
15
8
|
end
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@read_regexes = nil
|
|
10
|
+
module FlexibleClassMethods
|
|
11
|
+
def access_allowed(path)
|
|
12
|
+
return true unless @read_regexes
|
|
21
13
|
|
|
22
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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("&", "&")
|
|
19
|
+
.gsub("{", "{")
|
|
20
|
+
.gsub("}", "}")
|
|
21
|
+
.gsub("<", "<")
|
|
42
22
|
end
|
|
43
23
|
|
|
44
|
-
def
|
|
45
|
-
|
|
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
|
|
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
|
|
60
|
-
result += "\n" unless result.end_with?
|
|
38
|
+
result = numbered_content.join "\n"
|
|
39
|
+
result += "\n" unless result.end_with? "\n"
|
|
61
40
|
result
|
|
62
41
|
end
|
|
63
42
|
|
|
64
|
-
#
|
|
65
|
-
# @
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
@label ||= filename
|
|
63
|
+
class FlexibleInclude < JekyllSupport::JekyllTag
|
|
64
|
+
include JekyllFlexibleIncludePluginVersion
|
|
95
65
|
|
|
96
|
-
|
|
97
|
-
|
|
66
|
+
class << self
|
|
67
|
+
include FlexibleClassMethods
|
|
68
|
+
end
|
|
98
69
|
|
|
99
|
-
|
|
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.
|
|
112
|
-
path = File.join(
|
|
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(
|
|
90
|
+
return denied('Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.') if @execution_denied
|
|
116
91
|
|
|
117
|
-
filename =
|
|
118
|
-
filename.
|
|
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
|
-
|
|
122
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
191
|
-
|
|
188
|
+
JekyllPluginHelper.register(self, 'flexible_include')
|
|
189
|
+
end
|
data/spec/glob_spec.rb
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require_relative "../lib/flexible_include"
|
|
1
|
+
require_relative '../lib/flexible_include'
|
|
4
2
|
|
|
5
3
|
RSpec.describe(FlexibleInclude) do
|
|
6
|
-
it
|
|
4
|
+
it 'controls access to files' do
|
|
7
5
|
ENV['FLEXIBLE_INCLUDE_PATHS'] = '~/.*:spec/.*'
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
expect(
|
|
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(
|
|
11
|
+
expect(described_class.access_allowed('~/.mem_settings.yaml')).to be_truthy
|
|
14
12
|
|
|
15
|
-
home_file = JekyllTagHelper.expand_env(
|
|
16
|
-
expect(
|
|
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(
|
|
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
|
-
|
|
1
|
+
require 'jekyll'
|
|
2
2
|
|
|
3
|
-
|
|
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 =
|
|
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 =
|
|
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.
|
|
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:
|
|
13
|
+
date: 2023-02-19 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
|
-
name:
|
|
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:
|
|
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:
|
|
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
|
data/lib/jekyll_tag_helper.rb
DELETED
|
@@ -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("&", "&")
|
|
11
|
-
.gsub("{", "{")
|
|
12
|
-
.gsub("}", "}")
|
|
13
|
-
.gsub("<", "<")
|
|
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
|