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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '02751991aafe0decd461b0596ea3b8e06cd537bfe036ed5d2d5851aebf7c1295'
4
- data.tar.gz: b2f326314d48b1752ad40b9c50c4df9c7f39dfb93d80662dddc9bab2ebe7291d
3
+ metadata.gz: a3eced8ae5430c67a303f08c90a38caf16c46efbad4e11232aa95ed9580c2f98
4
+ data.tar.gz: 9370b4fab76dc5ba5487c0d0876907ed9366d0f1e777e63ca8250121a9a32533
5
5
  SHA512:
6
- metadata.gz: 8f62ab9616720b33cd9598c431501e1ac4de30ed8c0fd9a8afaba076f8f4dde15b8885381f4d2716f48c32b68a0dbda6fd021e1f3d0806a46a28322c4ab34671
7
- data.tar.gz: d28408a99c9a4e465caedb7a71296c6ecdeb5a4e13719e2360039fc8eeb84d378034cd996162dbbc3fae57840b1da5afc4972fc892787161d291ff9dbc06f835
6
+ metadata.gz: 7fc327f37d0c5dc7f54ba78837984a05603ae24bbdee5e888eebdb01bc8d377ecd08bbc4b18a68c97a9bd3f1272f359cb8da53ee7a2143938793d5dca298fb31
7
+ data.tar.gz: 656acb136598d957e9b129a2ebd71cfb905f63191c6c0c09eb0565c9070c71d5790b1319289b6ac70d71f15b8710a1af5e693240102f10f5c4ecce0068784252
data/.rubocop.yml CHANGED
@@ -1,6 +1,6 @@
1
- require: rubocop-jekyll
2
- inherit_gem:
3
- rubocop-jekyll: .rubocop.yml
1
+ # require: rubocop-jekyll
2
+ # inherit_gem:
3
+ # rubocop-jekyll: .rubocop.yml
4
4
 
5
5
  AllCops:
6
6
  Exclude:
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 about [my Jekyll plugins](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html).
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllPreVersion
4
- VERSION = "1.1.2"
4
+ VERSION = "1.1.5"
5
5
  end
data/lib/jekyll_pre.rb CHANGED
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "liquid"
4
- require "jekyll_plugin_logger"
5
- require_relative "jekyll_pre/version"
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 = "jekyll_pre"
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 == "shell"
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 argument_string [String] the arguments from the web page.
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, argument_string, _tokens)
95
+ def initialize(_tag_name, markup, _tokens)
73
96
  super
74
- argument_string = "" if argument_string.nil?
75
- argument_string.strip!
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(context)
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 argument_string [String] the arguments from the web page.
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, argument_string, _tokens)
135
+ def initialize(_tag_name, markup, _tokens)
107
136
  super
108
137
  @logger = PluginMetaLogger.instance.new_logger(self)
109
138
 
110
- @argument_string = argument_string
111
- @argument_string = "$ " if @argument_string.nil? || @argument_string.empty?
112
- @logger.debug { "UnselectableTag: argument_string= '#{@argument_string}'" }
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'>#{@argument_string}</span>"
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("pre", PreTagBlock)
122
- Liquid::Template.register_tag("noselect", UnselectableTag)
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('&', '&amp;')
12
+ .gsub('{', '&#123;')
13
+ .gsub('}', '&#125;')
14
+ .gsub('<', '&lt;')
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
@@ -1,4 +1,5 @@
1
1
  example_id | status | run_time |
2
2
  ----------------------- | ------ | --------------- |
3
- ./spec/pre_spec.rb[1:1] | passed | 0.00366 seconds |
4
- ./spec/pre_spec.rb[1:2] | passed | 0.00288 seconds |
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.2
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-06 00:00:00.000000000 Z
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.1.4
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
+ ...