jekyll_pre 1.2.1 → 1.2.2
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 +5 -2
- data/CHANGELOG.md +5 -0
- data/README.md +4 -1
- data/lib/exec_tag.rb +65 -0
- data/lib/jekyll_pre/version.rb +1 -1
- data/lib/jekyll_pre.rb +8 -89
- data/lib/noselect_tag.rb +18 -0
- data/lib/pre_tag_block.rb +84 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6097d5cc2c288233bb1bdb16683fa3116ec244edead6a25d971d0f002932d939
|
4
|
+
data.tar.gz: ab7f388db1f0e9dbfc0f677ea1e830b8486f02acc6da3aa95f08654c2f7de3a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3069935c7ad9b664004cb4235002ab12fb6e91911876a9cb5113e880c3f6b3a565d84c51bd5706470866fd82d1a6c168c0b26b88cbf59cf9d3adfc49ce9e392
|
7
|
+
data.tar.gz: 5e14ff1c554fda49eb095538fef25297f13bf8cdf48d508747227db69e0fa32a698193f391dbb9981f19914f4a6a15656d9db4ad50240b1bf6162c01af68c77b
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 1.2.2
|
2
|
+
* Added `exec` tag.
|
3
|
+
* Demarked CSS for the `exec`, `noselect`, and `pre` tags in `demo/assets/css/style.css`
|
4
|
+
within `/* Start of pre tag css */` and `/* End of pre tag css */`.
|
5
|
+
|
1
6
|
## 1.2.1
|
2
7
|
* Updated to `jekyll_plugin_support` v0.5.1 so the `noselect` tag is more efficient.
|
3
8
|
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@ Jekyll_pre
|
|
2
2
|
[](https://badge.fury.io/rb/jekyll_pre)
|
3
3
|
===========
|
4
4
|
|
5
|
-
This Jekyll plugin provides
|
5
|
+
This Jekyll plugin provides 3 new Liquid tags that work together:
|
6
6
|
|
7
7
|
* A `pre` block tag that can optionally display a copy button.
|
8
8
|
```
|
@@ -27,6 +27,7 @@ This Jekyll plugin provides 2 new Liquid tags that work together:
|
|
27
27
|
- `style` – Apply CSS styles
|
28
28
|
|
29
29
|
The generated <pre></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.
|
30
|
+
|
30
31
|
* A `noselect` tag that can renders HTML content passed to it unselectable,
|
31
32
|
and generates a <code>$</code> prompt if no content is provided.
|
32
33
|
```
|
@@ -35,6 +36,8 @@ This Jekyll plugin provides 2 new Liquid tags that work together:
|
|
35
36
|
{% endpre %}
|
36
37
|
```
|
37
38
|
|
39
|
+
* An `exec` tag that executes shell commands and incorporates the command and its output into the content of the `pre` tag.
|
40
|
+
Output data is escaped, whitespace is condensed, and wrapped in the same `unselectable` class as does `unselectable`.
|
38
41
|
## CSS
|
39
42
|
Below are the CSS declarations that I defined pertaining to the pre and noselect tags that produced the above images:
|
40
43
|
```css
|
data/lib/exec_tag.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'jekyll_plugin_support'
|
2
|
+
require_relative 'jekyll_pre/version'
|
3
|
+
|
4
|
+
module ExecTag
|
5
|
+
class ExecTag < JekyllSupport::JekyllTag
|
6
|
+
include JekyllPreVersion
|
7
|
+
|
8
|
+
def render_impl
|
9
|
+
parse_args
|
10
|
+
|
11
|
+
command = @helper.remaining_markup
|
12
|
+
response = `#{command}`
|
13
|
+
if $CHILD_STATUS.success?
|
14
|
+
response = compress response
|
15
|
+
else
|
16
|
+
msg = "Error: executing '#{command}' on line #{@line_number} (after front matter) of #{@page['path']} returned error code #{$CHILD_STATUS.exitstatus}"
|
17
|
+
raise PreError, msg.red, [] if @die_if_nonzero
|
18
|
+
|
19
|
+
@logger.error { msg }
|
20
|
+
response = "<span class='error'>Error: error code #{$CHILD_STATUS.exitstatus}</span>"
|
21
|
+
end
|
22
|
+
|
23
|
+
<<~END_OUTPUT
|
24
|
+
#{Rack::Utils.escape_html(command)}
|
25
|
+
<span class='unselectable'>#{response}</span>
|
26
|
+
END_OUTPUT
|
27
|
+
rescue PreError => e
|
28
|
+
raise PreError, e.message, []
|
29
|
+
rescue StandardError => e
|
30
|
+
msg = remove_html_tags(e.message) + " from executing '#{command}' on line #{@line_number} (after front matter) of #{@page['path']}"
|
31
|
+
raise PreError, msg.red, [] if die_if_error
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def compress(response)
|
37
|
+
result = response.chomp
|
38
|
+
result = result.strip unless @no_strip
|
39
|
+
result = result.gsub('\n\n', '<br>\n')
|
40
|
+
result = Rack::Utils.escape_html(result) unless @no_escape
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_args
|
45
|
+
@no_escape = @helper.parameter_specified? 'no_escape'
|
46
|
+
@no_strip = @helper.parameter_specified? 'no_strip'
|
47
|
+
@die_if_nonzero = @helper.parameter_specified?('die_if_nonzero') # Implies die_if_error
|
48
|
+
@die_if_error = @helper.parameter_specified?('die_if_error') | @die_if_nonzero
|
49
|
+
end
|
50
|
+
|
51
|
+
JekyllPluginHelper.register(self, 'exec')
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def die(msg)
|
57
|
+
msg_no_html = remove_html_tags(msg)
|
58
|
+
@logger.error("#{@page['path']} - #{msg_no_html}")
|
59
|
+
raise PreError, "#{@page['path']} - #{msg_no_html.red}", []
|
60
|
+
end
|
61
|
+
|
62
|
+
def remove_html_tags(string)
|
63
|
+
string.gsub(/<[^>]*>/, '')
|
64
|
+
end
|
65
|
+
end
|
data/lib/jekyll_pre/version.rb
CHANGED
data/lib/jekyll_pre.rb
CHANGED
@@ -1,98 +1,17 @@
|
|
1
|
-
require 'liquid'
|
2
|
-
require 'jekyll_plugin_logger'
|
3
|
-
require 'jekyll_plugin_support'
|
4
|
-
require_relative 'jekyll_pre/version'
|
5
|
-
|
6
1
|
module JekyllPluginPreName
|
7
2
|
PLUGIN_NAME = 'jekyll_pre'.freeze
|
8
3
|
end
|
9
4
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
"alt='Copy to clipboard' style='width: 13px'></button>"
|
14
|
-
|
15
|
-
def self.highlight(content, pattern)
|
16
|
-
content.gsub(Regexp.new(pattern), "<span class='bg_yellow'>\\0</span>")
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.make_copy_button(pre_id)
|
20
|
-
"#{@@prefix}'##{pre_id}'#{@@suffix}"
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.make_pre(make_copy_button, number_lines, label, dark, highlight_pattern, css_class, style, clear, content) # rubocop:disable Metrics/ParameterLists
|
24
|
-
pre_clear = label_clear = ''
|
25
|
-
if clear
|
26
|
-
if label.to_s.empty?
|
27
|
-
pre_clear = ' clear'
|
28
|
-
else
|
29
|
-
label_clear = ' clear'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
css_class = css_class ? " #{css_class}" : ''
|
33
|
-
style = style ? " style='#{style}'" : ''
|
34
|
-
dark_label = ' darkLabel' if dark
|
35
|
-
label = if label.to_s.empty?
|
36
|
-
''
|
37
|
-
elsif label.to_s.downcase.strip == 'shell'
|
38
|
-
"<div class='codeLabel unselectable#{dark_label}#{label_clear}' data-lt-active='false'>Shell</div>"
|
39
|
-
else
|
40
|
-
"<div class='codeLabel unselectable#{dark_label}#{label_clear}' data-lt-active='false'>#{label}</div>"
|
41
|
-
end
|
42
|
-
pre_id = "id#{SecureRandom.hex(6)}"
|
43
|
-
copy_button = make_copy_button ? PreTagBlock.make_copy_button(pre_id) : ''
|
44
|
-
content = PreTagBlock.highlight(content, highlight_pattern) if highlight_pattern
|
45
|
-
content = PreTagBlock.number_content(content) if number_lines
|
46
|
-
|
47
|
-
classes = "maxOneScreenHigh copyContainer#{dark}#{pre_clear}#{css_class}"
|
48
|
-
pre_content = "#{copy_button}#{content.strip}"
|
49
|
-
"#{label}<pre data-lt-active='false' class='#{classes}'#{style} id='#{pre_id}'>#{pre_content}</pre>"
|
50
|
-
end
|
5
|
+
require_relative './exec_tag'
|
6
|
+
require_relative './noselect_tag'
|
7
|
+
require_relative './pre_tag_block'
|
51
8
|
|
52
|
-
|
53
|
-
lines = content.split("\n")
|
54
|
-
digits = lines.length.to_s.length
|
55
|
-
i = 0
|
56
|
-
numbered_content = lines.map do |line|
|
57
|
-
i += 1
|
58
|
-
number = i.to_s.rjust(digits, ' ')
|
59
|
-
"<span class='unselectable numbered_line'> #{number}: </span>#{line}"
|
60
|
-
end
|
61
|
-
result = numbered_content.join("\n")
|
62
|
-
result += "\n" unless result.end_with?("\n")
|
63
|
-
result
|
64
|
-
end
|
65
|
-
|
66
|
-
def render_impl(text)
|
67
|
-
text.strip!
|
68
|
-
|
69
|
-
@clear = @helper.parameter_specified? 'clear'
|
70
|
-
@class = @helper.parameter_specified? 'class'
|
71
|
-
@highlight = @helper.parameter_specified? 'highlight'
|
72
|
-
@make_copy_button = @helper.parameter_specified? 'copyButton'
|
73
|
-
@number_lines = @helper.parameter_specified? 'number'
|
74
|
-
@dark = ' dark' if @helper.parameter_specified? 'dark'
|
75
|
-
@style = @helper.parameter_specified? 'style'
|
76
|
-
@label = @helper.parameter_specified? 'label'
|
77
|
-
|
78
|
-
# If a label was specified, use it, otherwise concatenate any dangling parameters and use that as the label
|
79
|
-
@label ||= @helper.argv.join(' ')
|
80
|
-
|
81
|
-
@logger.debug { "@make_copy_button = '#{@make_copy_button}'; @label = '#{@label}'" }
|
82
|
-
self.class.make_pre(@make_copy_button, @number_lines, @label, @dark, @highlight, @class, @style, @clear, text)
|
83
|
-
end
|
84
|
-
end
|
9
|
+
PreError = Class.new(Liquid::Error)
|
85
10
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
text = @argument_string
|
91
|
-
text = '$ ' if text.nil? || text.empty?
|
92
|
-
"<span class='unselectable'>#{text}</span>"
|
93
|
-
end
|
11
|
+
module JekyllPreModule
|
12
|
+
include NoSelectTag
|
13
|
+
include PreTagBlock
|
14
|
+
include ExecTag
|
94
15
|
end
|
95
16
|
|
96
17
|
PluginMetaLogger.instance.info { "Loaded #{JekyllPluginPreName::PLUGIN_NAME} v#{JekyllPreVersion::VERSION} plugin." }
|
97
|
-
Liquid::Template.register_tag('pre', PreTagBlock)
|
98
|
-
Liquid::Template.register_tag('noselect', UnselectableTag)
|
data/lib/noselect_tag.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'jekyll_plugin_support'
|
2
|
+
require_relative 'jekyll_pre/version'
|
3
|
+
|
4
|
+
module NoSelectTag
|
5
|
+
# """\\{% noselect %} or \\{% noselect this all gets copied.
|
6
|
+
# Also, space before the closing percent is signficant %}"""
|
7
|
+
class NoSelectTag < JekyllSupport::JekyllTagNoArgParsing
|
8
|
+
include JekyllPreVersion
|
9
|
+
|
10
|
+
def render_impl
|
11
|
+
text = @argument_string
|
12
|
+
text = '$ ' if text.nil? || text.empty?
|
13
|
+
"<span class='unselectable'>#{text}</span>"
|
14
|
+
end
|
15
|
+
|
16
|
+
JekyllPluginHelper.register(self, 'noselect')
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'jekyll_plugin_support'
|
2
|
+
require_relative 'jekyll_pre/version'
|
3
|
+
|
4
|
+
module PreTagBlock
|
5
|
+
class PreTagBlock < JekyllSupport::JekyllBlock
|
6
|
+
include JekyllPreVersion
|
7
|
+
|
8
|
+
@@prefix = "<button class='copyBtn' data-clipboard-target="
|
9
|
+
@@suffix = " title='Copy to clipboard'><img src='/assets/images/clippy.svg' " \
|
10
|
+
"alt='Copy to clipboard' style='width: 13px'></button>"
|
11
|
+
|
12
|
+
def self.highlight(content, pattern)
|
13
|
+
content.gsub(Regexp.new(pattern), "<span class='bg_yellow'>\\0</span>")
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.make_copy_button(pre_id)
|
17
|
+
"#{@@prefix}'##{pre_id}'#{@@suffix}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.make_pre(make_copy_button, number_lines, label, dark, highlight_pattern, css_class, style, clear, content) # rubocop:disable Metrics/ParameterLists
|
21
|
+
pre_clear = label_clear = ''
|
22
|
+
if clear
|
23
|
+
if label.to_s.empty?
|
24
|
+
pre_clear = ' clear'
|
25
|
+
else
|
26
|
+
label_clear = ' clear'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
css_class = css_class ? " #{css_class}" : ''
|
30
|
+
style = style ? " style='#{style}'" : ''
|
31
|
+
dark_label = ' darkLabel' if dark
|
32
|
+
label = if label.to_s.empty?
|
33
|
+
''
|
34
|
+
elsif label.to_s.downcase.strip == 'shell'
|
35
|
+
"<div class='codeLabel unselectable#{dark_label}#{label_clear}' data-lt-active='false'>Shell</div>"
|
36
|
+
else
|
37
|
+
"<div class='codeLabel unselectable#{dark_label}#{label_clear}' data-lt-active='false'>#{label}</div>"
|
38
|
+
end
|
39
|
+
pre_id = "id#{SecureRandom.hex(6)}"
|
40
|
+
copy_button = make_copy_button ? PreTagBlock.make_copy_button(pre_id) : ''
|
41
|
+
content = PreTagBlock.highlight(content, highlight_pattern) if highlight_pattern
|
42
|
+
content = PreTagBlock.number_content(content) if number_lines
|
43
|
+
|
44
|
+
classes = "maxOneScreenHigh copyContainer#{dark}#{pre_clear}#{css_class}"
|
45
|
+
pre_content = "#{copy_button}#{content.strip}"
|
46
|
+
"#{label}<pre data-lt-active='false' class='#{classes}'#{style} id='#{pre_id}'>#{pre_content}</pre>"
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.number_content(content)
|
50
|
+
lines = content.split("\n")
|
51
|
+
digits = lines.length.to_s.length
|
52
|
+
i = 0
|
53
|
+
numbered_content = lines.map do |line|
|
54
|
+
i += 1
|
55
|
+
number = i.to_s.rjust(digits, ' ')
|
56
|
+
"<span class='unselectable numbered_line'> #{number}: </span>#{line}"
|
57
|
+
end
|
58
|
+
result = numbered_content.join("\n")
|
59
|
+
result += "\n" unless result.end_with?("\n")
|
60
|
+
result
|
61
|
+
end
|
62
|
+
|
63
|
+
def render_impl(text)
|
64
|
+
text.strip!
|
65
|
+
|
66
|
+
@clear = @helper.parameter_specified? 'clear'
|
67
|
+
@class = @helper.parameter_specified? 'class'
|
68
|
+
@highlight = @helper.parameter_specified? 'highlight'
|
69
|
+
@make_copy_button = @helper.parameter_specified? 'copyButton'
|
70
|
+
@number_lines = @helper.parameter_specified? 'number'
|
71
|
+
@dark = ' dark' if @helper.parameter_specified? 'dark'
|
72
|
+
@style = @helper.parameter_specified? 'style'
|
73
|
+
@label = @helper.parameter_specified? 'label'
|
74
|
+
|
75
|
+
# If a label was specified, use it, otherwise concatenate any dangling parameters and use that as the label
|
76
|
+
@label ||= @helper.argv.join(' ')
|
77
|
+
|
78
|
+
@logger.debug { "@make_copy_button = '#{@make_copy_button}'; @label = '#{@label}'" }
|
79
|
+
self.class.make_pre(@make_copy_button, @number_lines, @label, @dark, @highlight, @class, @style, @clear, text)
|
80
|
+
end
|
81
|
+
|
82
|
+
JekyllPluginHelper.register(self, 'pre')
|
83
|
+
end
|
84
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll_pre
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Slinn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -54,8 +54,11 @@ files:
|
|
54
54
|
- README.md
|
55
55
|
- Rakefile
|
56
56
|
- jekyll_pre.gemspec
|
57
|
+
- lib/exec_tag.rb
|
57
58
|
- lib/jekyll_pre.rb
|
58
59
|
- lib/jekyll_pre/version.rb
|
60
|
+
- lib/noselect_tag.rb
|
61
|
+
- lib/pre_tag_block.rb
|
59
62
|
- spec/pre_spec.rb
|
60
63
|
- spec/spec_helper.rb
|
61
64
|
- spec/status_persistence.txt
|