jekyll_pre 1.1.2 → 1.1.5
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 +3 -3
- data/CHANGELOG.md +12 -0
- data/README.md +2 -1
- data/jekyll_pre.gemspec +2 -2
- data/lib/jekyll_pre/version.rb +1 -1
- data/lib/jekyll_pre.rb +66 -37
- data/lib/jekyll_tag_helper.rb +92 -0
- data/spec/pre_spec.rb +17 -0
- data/spec/status_persistence.txt +3 -2
- metadata +8 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3eced8ae5430c67a303f08c90a38caf16c46efbad4e11232aa95ed9580c2f98
|
4
|
+
data.tar.gz: 9370b4fab76dc5ba5487c0d0876907ed9366d0f1e777e63ca8250121a9a32533
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fc327f37d0c5dc7f54ba78837984a05603ae24bbdee5e888eebdb01bc8d377ecd08bbc4b18a68c97a9bd3f1272f359cb8da53ee7a2143938793d5dca298fb31
|
7
|
+
data.tar.gz: 656acb136598d957e9b129a2ebd71cfb905f63191c6c0c09eb0565c9070c71d5790b1319289b6ac70d71f15b8710a1af5e693240102f10f5c4ecce0068784252
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## 1.1.5
|
2
|
+
* Added `class` and `style` options to allow for specifying additional CSS classes and inline CSS
|
3
|
+
* Added `clear` option to ensure no images overlap the pre output
|
4
|
+
|
5
|
+
## 1.1.4
|
6
|
+
* Added `highlight` regex option
|
7
|
+
* Now using `lib/jekyll_tag_helper.rb` to parse markup
|
8
|
+
|
9
|
+
## 1.1.3
|
10
|
+
* Documented the `data-lt-active="false"` attribute.
|
11
|
+
* Added the `dark` option, and [provided CSS](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#pre_css).
|
12
|
+
|
1
13
|
## 1.1.2 / 2022-04-05
|
2
14
|
* Updated to `jekyll_plugin_logger` v2.1.0
|
3
15
|
|
data/README.md
CHANGED
@@ -10,6 +10,7 @@ This Jekyll plugin provides 2 new Liquid tags that work together:
|
|
10
10
|
Contents of pre tag
|
11
11
|
{% endpre %}
|
12
12
|
```
|
13
|
+
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.
|
13
14
|
* A `noselect` tag that can renders HTML content passed to it unselectable.
|
14
15
|
```
|
15
16
|
{% pre [copyButton] %}
|
@@ -39,7 +40,7 @@ Below are the CSS declarations that I defined pertaining to the pre and noselect
|
|
39
40
|
```
|
40
41
|
|
41
42
|
## Additional Information
|
42
|
-
More information is available on my web site
|
43
|
+
More information is available on [my web site](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#jekyll_pre).
|
43
44
|
|
44
45
|
|
45
46
|
## Installation
|
data/jekyll_pre.gemspec
CHANGED
@@ -39,10 +39,10 @@ Gem::Specification.new do |spec|
|
|
39
39
|
spec.add_dependency "key-value-parser"
|
40
40
|
spec.add_dependency "shellwords"
|
41
41
|
|
42
|
-
spec.add_development_dependency "debase"
|
42
|
+
# spec.add_development_dependency "debase"
|
43
43
|
# spec.add_development_dependency "rubocop-jekyll"
|
44
44
|
# spec.add_development_dependency "rubocop-rake"
|
45
45
|
# spec.add_development_dependency "rubocop-rspec"
|
46
|
-
spec.add_development_dependency "ruby-debug-ide"
|
46
|
+
# spec.add_development_dependency "ruby-debug-ide"
|
47
47
|
end
|
48
48
|
# rubocop:enable Metrics/BlockLength
|
data/lib/jekyll_pre/version.rb
CHANGED
data/lib/jekyll_pre.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
3
|
+
require 'liquid'
|
4
|
+
require 'jekyll_plugin_logger'
|
5
|
+
require 'key_value_parser'
|
6
|
+
require 'shellwords'
|
7
|
+
require_relative 'jekyll_pre/version'
|
8
|
+
require_relative 'jekyll_tag_helper'
|
6
9
|
|
7
10
|
module JekyllPluginPreName
|
8
|
-
PLUGIN_NAME =
|
11
|
+
PLUGIN_NAME = 'jekyll_pre'
|
9
12
|
end
|
10
13
|
|
11
14
|
# """
|
@@ -33,31 +36,47 @@ class PreTagBlock < Liquid::Block
|
|
33
36
|
@@suffix = " title='Copy to clipboard'><img src='/assets/images/clippy.svg' " \
|
34
37
|
"alt='Copy to clipboard' style='width: 13px'></button>"
|
35
38
|
|
39
|
+
def self.highlight(content, pattern)
|
40
|
+
content.gsub(Regexp.new(pattern), "<span class='bg_yellow'>\\0</span>")
|
41
|
+
end
|
42
|
+
|
36
43
|
def self.make_copy_button(pre_id)
|
37
44
|
"#{@@prefix}'##{pre_id}'#{@@suffix}"
|
38
45
|
end
|
39
46
|
|
40
|
-
def self.make_pre(make_copy_button, number_lines, label, content)
|
47
|
+
def self.make_pre(make_copy_button, number_lines, label, dark, highlight_pattern, css_class, style, clear, content) # rubocop:disable Metrics/ParameterLists, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
48
|
+
pre_clear = label_clear = ''
|
49
|
+
if clear
|
50
|
+
if label.to_s.empty?
|
51
|
+
pre_clear = ' clear'
|
52
|
+
else
|
53
|
+
label_clear = ' clear'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
css_class = css_class ? " #{css_class}" : ''
|
57
|
+
style = style ? " style='#{style}'" : ''
|
58
|
+
dark_label = ' darkLabel' if dark
|
41
59
|
label = if label.to_s.empty?
|
42
|
-
|
43
|
-
elsif label.to_s.downcase.strip ==
|
44
|
-
"<div class='codeLabel unselectable' data-lt-active='false'>Shell</div>"
|
60
|
+
''
|
61
|
+
elsif label.to_s.downcase.strip == 'shell'
|
62
|
+
"<div class='codeLabel unselectable#{dark_label}#{label_clear}' data-lt-active='false'>Shell</div>"
|
45
63
|
else
|
46
|
-
"<div class='codeLabel unselectable' data-lt-active='false'>#{label}</div>"
|
64
|
+
"<div class='codeLabel unselectable#{dark_label}#{label_clear}' data-lt-active='false'>#{label}</div>"
|
47
65
|
end
|
48
66
|
pre_id = "id#{SecureRandom.hex(6)}"
|
49
|
-
copy_button = make_copy_button ? PreTagBlock.make_copy_button(pre_id) :
|
67
|
+
copy_button = make_copy_button ? PreTagBlock.make_copy_button(pre_id) : ''
|
68
|
+
content = PreTagBlock.highlight(content, highlight_pattern) if highlight_pattern
|
50
69
|
content = PreTagBlock.number_content(content) if number_lines
|
51
|
-
"#{label}<pre data-lt-active='false' class='maxOneScreenHigh copyContainer' id='#{pre_id}'>#{copy_button}#{content.strip}</pre>"
|
70
|
+
"#{label}<pre data-lt-active='false' class='maxOneScreenHigh copyContainer#{dark}#{pre_clear}#{css_class}'#{style} id='#{pre_id}'>#{copy_button}#{content.strip}</pre>"
|
52
71
|
end
|
53
72
|
|
54
|
-
def self.number_content(content)
|
73
|
+
def self.number_content(content) # rubocop:disable Metrics/MethodLength
|
55
74
|
lines = content.split("\n")
|
56
75
|
digits = lines.length.to_s.length
|
57
76
|
i = 0
|
58
77
|
numbered_content = lines.map do |line|
|
59
78
|
i += 1
|
60
|
-
number = i.to_s.rjust(digits,
|
79
|
+
number = i.to_s.rjust(digits, ' ')
|
61
80
|
"<span class='unselectable numbered_line'> #{number}: </span>#{line}"
|
62
81
|
end
|
63
82
|
result = numbered_content.join("\n")
|
@@ -66,33 +85,43 @@ class PreTagBlock < Liquid::Block
|
|
66
85
|
end
|
67
86
|
|
68
87
|
# @param _tag_name [String] is the name of the tag, which we already know.
|
69
|
-
# @param
|
88
|
+
# @param markup [String] the arguments from the web page.
|
70
89
|
# @param _tokens [Liquid::ParseContext] tokenized command line
|
90
|
+
# By default it has two keys: :locale and :line_numbers, the first is a Liquid::I18n object, and the second,
|
91
|
+
# a boolean parameter that determines if error messages should display the line number the error occurred.
|
92
|
+
# This argument is used mostly to display localized error messages on Liquid built-in Tags and Filters.
|
93
|
+
# See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
|
71
94
|
# @return [void]
|
72
|
-
def initialize(_tag_name,
|
95
|
+
def initialize(_tag_name, markup, _tokens)
|
73
96
|
super
|
74
|
-
|
75
|
-
|
97
|
+
markup = '' if markup.nil?
|
98
|
+
markup.strip!
|
76
99
|
|
77
100
|
@logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
78
|
-
|
79
|
-
@make_copy_button = argument_string.include? "copyButton"
|
80
|
-
remaining_text = argument_string.sub("copyButton", "").strip
|
81
|
-
|
82
|
-
@number_lines = remaining_text.include? "number"
|
83
|
-
remaining_text = remaining_text.sub("number", "").strip
|
84
|
-
|
85
|
-
@label = remaining_text
|
86
|
-
|
87
|
-
@logger.debug { "@make_copy_button = '#{@make_copy_button}'; argument_string = '#{argument_string}'; remaining_text = '#{remaining_text}'" }
|
101
|
+
@helper = JekyllTagHelper.new(tag_name, markup, @logger)
|
88
102
|
end
|
89
103
|
|
90
104
|
# Method prescribed by the Jekyll plugin lifecycle.
|
105
|
+
# @param liquid_context [Liquid::Context]
|
91
106
|
# @return [String]
|
92
|
-
def render(
|
107
|
+
def render(liquid_context) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
93
108
|
content = super
|
109
|
+
@helper.liquid_context = liquid_context
|
110
|
+
|
111
|
+
@clear = @helper.parameter_specified?('clear')
|
112
|
+
@class = @helper.parameter_specified?('class')
|
113
|
+
@highlight = @helper.parameter_specified? 'highlight'
|
114
|
+
@make_copy_button = @helper.parameter_specified? 'copyButton'
|
115
|
+
@number_lines = @helper.parameter_specified? 'number'
|
116
|
+
@dark = ' dark' if @helper.parameter_specified? 'dark'
|
117
|
+
@label = @helper.parameter_specified? 'label'
|
118
|
+
@style = @helper.parameter_specified?('style')
|
119
|
+
|
120
|
+
# If a label was specified, use it, otherwise concatenate any dangling parameters and use that as the label
|
121
|
+
@label ||= @helper.params.join(' ')
|
122
|
+
|
94
123
|
@logger.debug { "@make_copy_button = '#{@make_copy_button}'; @label = '#{@label}'" }
|
95
|
-
PreTagBlock.make_pre(@make_copy_button, @number_lines, @label, content)
|
124
|
+
PreTagBlock.make_pre(@make_copy_button, @number_lines, @label, @dark, @highlight, @class, @style, @clear, content)
|
96
125
|
end
|
97
126
|
end
|
98
127
|
|
@@ -100,23 +129,23 @@ end
|
|
100
129
|
# Also, space before the closing percent is signficant %}"""
|
101
130
|
class UnselectableTag < Liquid::Tag
|
102
131
|
# @param _tag_name [String] is the name of the tag, which we already know.
|
103
|
-
# @param
|
132
|
+
# @param markup [String] the arguments from the web page.
|
104
133
|
# @param _tokens [Liquid::ParseContext] tokenized command line
|
105
134
|
# @return [void]
|
106
|
-
def initialize(_tag_name,
|
135
|
+
def initialize(_tag_name, markup, _tokens)
|
107
136
|
super
|
108
137
|
@logger = PluginMetaLogger.instance.new_logger(self)
|
109
138
|
|
110
|
-
@
|
111
|
-
@
|
112
|
-
@logger.debug { "UnselectableTag:
|
139
|
+
@markup = markup
|
140
|
+
@markup = '$ ' if @markup.nil? || @markup.empty?
|
141
|
+
@logger.debug { "UnselectableTag: markup= '#{@markup}'" }
|
113
142
|
end
|
114
143
|
|
115
144
|
def render(_)
|
116
|
-
"<span class='unselectable'>#{@
|
145
|
+
"<span class='unselectable'>#{@markup}</span>"
|
117
146
|
end
|
118
147
|
end
|
119
148
|
|
120
149
|
PluginMetaLogger.instance.info { "Loaded #{JekyllPluginPreName::PLUGIN_NAME} v#{JekyllPreVersion::VERSION} plugin." }
|
121
|
-
Liquid::Template.register_tag(
|
122
|
-
Liquid::Template.register_tag(
|
150
|
+
Liquid::Template.register_tag('pre', PreTagBlock)
|
151
|
+
Liquid::Template.register_tag('noselect', UnselectableTag)
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shellwords'
|
4
|
+
require 'key_value_parser'
|
5
|
+
|
6
|
+
# Parses arguments and options
|
7
|
+
class JekyllTagHelper
|
8
|
+
attr_reader :argv, :liquid_context, :logger, :params, :tag_name
|
9
|
+
|
10
|
+
def self.escape_html(string)
|
11
|
+
string.gsub('&', '&')
|
12
|
+
.gsub('{', '{')
|
13
|
+
.gsub('}', '}')
|
14
|
+
.gsub('<', '<')
|
15
|
+
end
|
16
|
+
|
17
|
+
# Expand a environment variable reference
|
18
|
+
def self.expand_env(str, die_if_undefined: false)
|
19
|
+
str.gsub(/\$([a-zA-Z_][a-zA-Z0-9_]*)|\${\g<1>}|%\g<1>%/) do
|
20
|
+
envar = Regexp.last_match(1)
|
21
|
+
raise FlexibleError, "flexible_include error: #{envar} is undefined".red, [] if !ENV.key?(envar) && die_if_undefined # Suppress stack trace
|
22
|
+
|
23
|
+
ENV[envar]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# strip leading and trailing quotes if present
|
28
|
+
def self.remove_quotes(string)
|
29
|
+
string.strip.gsub(/\A'|\A"|'\Z|"\Z/, '').strip if string
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(tag_name, markup, logger)
|
33
|
+
@tag_name = tag_name
|
34
|
+
@argv = Shellwords.split(markup)
|
35
|
+
@keys_values = KeyValueParser.new.parse(@argv) # Hash[Symbol, String|Boolean]
|
36
|
+
@logger = logger
|
37
|
+
@logger.debug { "@keys_values='#{@keys_values}'" }
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete_parameter(name)
|
41
|
+
@params.delete(name)
|
42
|
+
@argv.delete_if { |x| x.start_with? name }
|
43
|
+
@keys_values.delete(name.to_sym)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return if parameter was specified, returns value and removes it from the available tokens
|
47
|
+
def parameter_specified?(name)
|
48
|
+
value = @keys_values[name.to_sym]
|
49
|
+
delete_parameter(name)
|
50
|
+
value
|
51
|
+
end
|
52
|
+
|
53
|
+
PREDEFINED_SCOPE_KEYS = [:include, :page].freeze
|
54
|
+
|
55
|
+
# Finds variables defined in an invoking include, or maybe somewhere else
|
56
|
+
# @return variable value or nil
|
57
|
+
def dereference_include_variable(name)
|
58
|
+
@liquid_context.scopes.each do |scope|
|
59
|
+
next if PREDEFINED_SCOPE_KEYS.include? scope.keys.first
|
60
|
+
|
61
|
+
value = scope[name]
|
62
|
+
return value if value
|
63
|
+
end
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return value of variable, or the empty string
|
68
|
+
def dereference_variable(name)
|
69
|
+
value = @liquid_context[name] # Finds variables named like 'include.my_variable', found in @liquid_context.scopes.first
|
70
|
+
value ||= @page[name] if @page # Finds variables named like 'page.my_variable'
|
71
|
+
value ||= dereference_include_variable(name)
|
72
|
+
value ||= ''
|
73
|
+
value
|
74
|
+
end
|
75
|
+
|
76
|
+
# Sets @params by replacing any Liquid variable names with their values
|
77
|
+
def liquid_context=(context)
|
78
|
+
@liquid_context = context
|
79
|
+
@params = @keys_values.map { |k, _v| lookup_variable(k) }
|
80
|
+
end
|
81
|
+
|
82
|
+
def lookup_variable(symbol)
|
83
|
+
string = symbol.to_s
|
84
|
+
return string unless string.start_with?('{{') && string.end_with?('}}')
|
85
|
+
|
86
|
+
dereference_variable(string.delete_prefix('{{').delete_suffix('}}'))
|
87
|
+
end
|
88
|
+
|
89
|
+
def page
|
90
|
+
@liquid_context.registers[:page]
|
91
|
+
end
|
92
|
+
end
|
data/spec/pre_spec.rb
CHANGED
@@ -45,4 +45,21 @@ RSpec.describe(PreTagBlock) do
|
|
45
45
|
END_CONTENT
|
46
46
|
expect(numbered_content).to eq(expected_content)
|
47
47
|
end
|
48
|
+
|
49
|
+
it "highlights regex patterns" do
|
50
|
+
content = <<~END_CONTENT
|
51
|
+
Line 1
|
52
|
+
Line 2
|
53
|
+
Line 3
|
54
|
+
Line 4
|
55
|
+
Line 5
|
56
|
+
Line 6
|
57
|
+
Line 7
|
58
|
+
Line 8
|
59
|
+
Line 9
|
60
|
+
Line 10
|
61
|
+
END_CONTENT
|
62
|
+
highlighted = PreTagBlock.highlight(content, ".*2").split("\n")[1]
|
63
|
+
expect(highlighted).to eq("<span class='bg_yellow'> Line 2</span>")
|
64
|
+
end
|
48
65
|
end
|
data/spec/status_persistence.txt
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
example_id | status | run_time |
|
2
2
|
----------------------- | ------ | --------------- |
|
3
|
-
./spec/pre_spec.rb[1:1] | passed | 0.
|
4
|
-
./spec/pre_spec.rb[1:2] | passed | 0.
|
3
|
+
./spec/pre_spec.rb[1:1] | passed | 0.00187 seconds |
|
4
|
+
./spec/pre_spec.rb[1:2] | passed | 0.00285 seconds |
|
5
|
+
./spec/pre_spec.rb[1:3] | passed | 0.00056 seconds |
|
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.1.
|
4
|
+
version: 1.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Slinn
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04
|
11
|
+
date: 2022-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -66,38 +66,10 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: debase
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: ruby-debug-ide
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
69
|
description: 'Jekyll tags pre and noselect, for HTML <pre/> tag, prompts and unselectable
|
98
70
|
text. Can number lines.
|
99
71
|
|
100
|
-
'
|
72
|
+
'
|
101
73
|
email:
|
102
74
|
- mslinn@mslinn.com
|
103
75
|
executables: []
|
@@ -112,6 +84,7 @@ files:
|
|
112
84
|
- jekyll_pre.gemspec
|
113
85
|
- lib/jekyll_pre.rb
|
114
86
|
- lib/jekyll_pre/version.rb
|
87
|
+
- lib/jekyll_tag_helper.rb
|
115
88
|
- spec/pre_spec.rb
|
116
89
|
- spec/spec_helper.rb
|
117
90
|
- spec/status_persistence.txt
|
@@ -142,8 +115,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
115
|
- !ruby/object:Gem::Version
|
143
116
|
version: '0'
|
144
117
|
requirements: []
|
145
|
-
rubygems_version: 3.
|
146
|
-
signing_key:
|
118
|
+
rubygems_version: 3.3.3
|
119
|
+
signing_key:
|
147
120
|
specification_version: 4
|
148
121
|
summary: Jekyll tags pre and noselect, for HTML <pre/> tag, prompts and unselectable
|
149
122
|
text. Can number lines.
|
@@ -151,3 +124,4 @@ test_files:
|
|
151
124
|
- spec/pre_spec.rb
|
152
125
|
- spec/spec_helper.rb
|
153
126
|
- spec/status_persistence.txt
|
127
|
+
...
|