jekyll_pre 1.1.3 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/jekyll_pre/version.rb +1 -1
- data/lib/jekyll_pre.rb +38 -26
- data/lib/jekyll_tag_helper.rb +90 -0
- data/spec/pre_spec.rb +17 -0
- data/spec/status_persistence.txt +3 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be2fcd1765446ab64973e355acb073057dea3c98ed1be553362b5b755e5453fb
|
4
|
+
data.tar.gz: 33b14de234b5764673af3c9380d6ae32fa5a429294f7ee5f53d094aa63bf1f87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46fcc4e0dcab10f27bfc9f8fa408e84e5d5c3c19f926d1de51167b39754740a2a4a3af2a17ca4c4f8dc2bf25011283205137c7afa9d144abb67ee6c2479276a5
|
7
|
+
data.tar.gz: c39c5e30e3386d1eeb3029d7cf31ab159fcb8b32fb3b72fa5f03d5af8269daa30b7cf308e0bdbf1905180a468f88b2e7b00ab1e440daf75ba5ee96987bc1a727
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 1.1.4
|
2
|
+
* Added `highlight` regex option
|
3
|
+
* Now using `lib/jekyll_tag_helper.rb` to parse markup
|
4
|
+
|
1
5
|
## 1.1.3
|
2
6
|
* Documented the `data-lt-active="false"` attribute.
|
3
7
|
* Added the `dark` option, and [provided CSS](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#pre_css).
|
data/lib/jekyll_pre/version.rb
CHANGED
data/lib/jekyll_pre.rb
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
require "liquid"
|
4
4
|
require "jekyll_plugin_logger"
|
5
|
+
require 'key_value_parser'
|
6
|
+
require "shellwords"
|
5
7
|
require_relative "jekyll_pre/version"
|
8
|
+
require_relative "jekyll_tag_helper"
|
6
9
|
|
7
10
|
module JekyllPluginPreName
|
8
11
|
PLUGIN_NAME = "jekyll_pre"
|
@@ -33,11 +36,15 @@ 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, dark, content) # rubocop:disable Metrics/ParameterLists
|
47
|
+
def self.make_pre(make_copy_button, number_lines, label, dark, highlight_pattern, content) # rubocop:disable Metrics/ParameterLists
|
41
48
|
dark_label = " darkLabel" if dark
|
42
49
|
label = if label.to_s.empty?
|
43
50
|
""
|
@@ -48,6 +55,7 @@ class PreTagBlock < Liquid::Block
|
|
48
55
|
end
|
49
56
|
pre_id = "id#{SecureRandom.hex(6)}"
|
50
57
|
copy_button = make_copy_button ? PreTagBlock.make_copy_button(pre_id) : ""
|
58
|
+
content = PreTagBlock.highlight(content, highlight_pattern) if highlight_pattern
|
51
59
|
content = PreTagBlock.number_content(content) if number_lines
|
52
60
|
"#{label}<pre data-lt-active='false' class='maxOneScreenHigh copyContainer#{dark}' id='#{pre_id}'>#{copy_button}#{content.strip}</pre>"
|
53
61
|
end
|
@@ -67,36 +75,40 @@ class PreTagBlock < Liquid::Block
|
|
67
75
|
end
|
68
76
|
|
69
77
|
# @param _tag_name [String] is the name of the tag, which we already know.
|
70
|
-
# @param
|
78
|
+
# @param markup [String] the arguments from the web page.
|
71
79
|
# @param _tokens [Liquid::ParseContext] tokenized command line
|
80
|
+
# By default it has two keys: :locale and :line_numbers, the first is a Liquid::I18n object, and the second,
|
81
|
+
# a boolean parameter that determines if error messages should display the line number the error occurred.
|
82
|
+
# This argument is used mostly to display localized error messages on Liquid built-in Tags and Filters.
|
83
|
+
# See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
|
72
84
|
# @return [void]
|
73
|
-
def initialize(_tag_name,
|
85
|
+
def initialize(_tag_name, markup, _tokens)
|
74
86
|
super
|
75
|
-
|
76
|
-
|
87
|
+
markup = "" if markup.nil?
|
88
|
+
markup.strip!
|
77
89
|
|
78
90
|
@logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
79
|
-
|
80
|
-
@make_copy_button = argument_string.include? "copyButton"
|
81
|
-
remaining_text = argument_string.sub("copyButton", "").strip
|
82
|
-
|
83
|
-
@number_lines = remaining_text.include? "number"
|
84
|
-
remaining_text = remaining_text.sub("number", "").strip
|
85
|
-
|
86
|
-
@dark = " dark" if remaining_text.include? "dark"
|
87
|
-
remaining_text = remaining_text.sub("dark", "").strip
|
88
|
-
|
89
|
-
@label = remaining_text
|
90
|
-
|
91
|
-
@logger.debug { "@make_copy_button = '#{@make_copy_button}'; argument_string = '#{argument_string}'; remaining_text = '#{remaining_text}'" }
|
91
|
+
@helper = JekyllTagHelper.new(tag_name, markup, @logger)
|
92
92
|
end
|
93
93
|
|
94
94
|
# Method prescribed by the Jekyll plugin lifecycle.
|
95
|
+
# @param liquid_context [Liquid::Context]
|
95
96
|
# @return [String]
|
96
|
-
def render(
|
97
|
+
def render(liquid_context)
|
97
98
|
content = super
|
99
|
+
@helper.liquid_context = liquid_context
|
100
|
+
|
101
|
+
@highlight = @helper.parameter_specified? "highlight"
|
102
|
+
@make_copy_button = @helper.parameter_specified? "copyButton"
|
103
|
+
@number_lines = @helper.parameter_specified? "number"
|
104
|
+
@dark = " dark" if @helper.parameter_specified? "dark"
|
105
|
+
@label = @helper.parameter_specified? "label"
|
106
|
+
|
107
|
+
# If a label was specified, use it, otherwise concatenate any dangling parameters and use that as the label
|
108
|
+
@label ||= @helper.params.join(" ")
|
109
|
+
|
98
110
|
@logger.debug { "@make_copy_button = '#{@make_copy_button}'; @label = '#{@label}'" }
|
99
|
-
PreTagBlock.make_pre(@make_copy_button, @number_lines, @label, @dark, content)
|
111
|
+
PreTagBlock.make_pre(@make_copy_button, @number_lines, @label, @dark, @highlight, content)
|
100
112
|
end
|
101
113
|
end
|
102
114
|
|
@@ -104,20 +116,20 @@ end
|
|
104
116
|
# Also, space before the closing percent is signficant %}"""
|
105
117
|
class UnselectableTag < Liquid::Tag
|
106
118
|
# @param _tag_name [String] is the name of the tag, which we already know.
|
107
|
-
# @param
|
119
|
+
# @param markup [String] the arguments from the web page.
|
108
120
|
# @param _tokens [Liquid::ParseContext] tokenized command line
|
109
121
|
# @return [void]
|
110
|
-
def initialize(_tag_name,
|
122
|
+
def initialize(_tag_name, markup, _tokens)
|
111
123
|
super
|
112
124
|
@logger = PluginMetaLogger.instance.new_logger(self)
|
113
125
|
|
114
|
-
@
|
115
|
-
@
|
116
|
-
@logger.debug { "UnselectableTag:
|
126
|
+
@markup = markup
|
127
|
+
@markup = "$ " if @markup.nil? || @markup.empty?
|
128
|
+
@logger.debug { "UnselectableTag: markup= '#{@markup}'" }
|
117
129
|
end
|
118
130
|
|
119
131
|
def render(_)
|
120
|
-
"<span class='unselectable'>#{@
|
132
|
+
"<span class='unselectable'>#{@markup}</span>"
|
121
133
|
end
|
122
134
|
end
|
123
135
|
|
@@ -0,0 +1,90 @@
|
|
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
|
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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Slinn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- jekyll_pre.gemspec
|
113
113
|
- lib/jekyll_pre.rb
|
114
114
|
- lib/jekyll_pre/version.rb
|
115
|
+
- lib/jekyll_tag_helper.rb
|
115
116
|
- spec/pre_spec.rb
|
116
117
|
- spec/spec_helper.rb
|
117
118
|
- spec/status_persistence.txt
|