jekyll-documents 0.7.3 → 0.7.4

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: aa6c0e2569d3772c02fe174700001a8290d7b313e7b068781d21627172d9e785
4
- data.tar.gz: 407cc042bf5b2de1fe1b01cf9c9043bd961c811de7d0e6ee2dc896b1ab29e1dc
3
+ metadata.gz: c690ba4e56790f19326b49d3476839028784f9da66b4d46d5a18680cac0ba927
4
+ data.tar.gz: 6007f855de36ef230b789fdab081877f19c9be15c583a342e669eaa811898317
5
5
  SHA512:
6
- metadata.gz: d9016ce9608b013d8b0b6ac4d3756512d99a17cb55d5c2d2d67e096ccb5175e07ca40a17c68629dd09c684b5291fcad0ea1b876d74e7e58b0fedff0a7d1b97c7
7
- data.tar.gz: f13021dccbed117f29e6c3f2c3d70f9ba9c499f3008ba30083f69c710ba3b30753a72009e3b84fa7fed64c3c73e8a85d20630cbe26de46623a38fb7766cd3986
6
+ metadata.gz: ecc1cbd701f3b07f70694dd0a9f7314d7d65bb2b2040ad0af3658d763ad540bb40daf90e1494100e49ab72a10540377786d793a2416536cc055f85a16983fcb7
7
+ data.tar.gz: dbab2960b310640f780b3d88695ec16cbdf1902fba99019736bedf7ab3ecf0a6f956c370b9b3c8858ad559f4f40fe7a6f354843a7ceef790e97010f751c898cc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [0.7.4] - 2026-09-18
6
+
7
+ ### Added
8
+ - Added Codecov coverage reporting: CI uploads Cobertura XML (via `simplecov-cobertura`) after the Ruby quality suite, with `codecov.yml` status checks (98% project / 90% patch targets)
9
+
10
+ ### Changed
11
+ - Auto-update `Gemfile.lock` on `rake version:bump` via `bundle lock` (use `SKIP_LOCK=1` to skip)
12
+ - Further reduced `latest_documents.rb` `render` complexity by extracting `resolve_count` and `select_documents`
13
+ - Extracted shared `TagHelpers` module (markup parsing, document collection access, path normalization, HTML escaping) used by `doc_link`, `doc_category`, `document_icon`, and `latest_documents` tags — removes SonarCloud-flagged duplication
14
+ - Extracted shared `liquid tag helpers` spec context (`spec/support/shared_context_tags.rb`) for tag spec setup
15
+ - Added `.sonarcloud.properties` excluding `spec/fixtures/` from SonarCloud duplication analysis (fixture templates intentionally mirror shipped includes/layouts)
16
+
3
17
  ## [0.7.3] - 2026-09-10
4
18
 
5
19
  ### Added
data/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/gundestrup/jekyll-documents)
9
9
  [![CodeFactor](https://www.codefactor.io/repository/github/gundestrup/jekyll-documents/badge)](https://www.codefactor.io/repository/github/gundestrup/jekyll-documents)
10
10
  [![Semgrep CE](https://img.shields.io/badge/Semgrep_CE-security-success)](https://github.com/gundestrup/jekyll-documents/security/code-scanning)
11
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=gundestrup_jekyll-documents&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=gundestrup_jekyll-documents)
11
12
 
12
13
  Turn files in `assets/documents/` into browsable document pages.
13
14
 
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Documents
5
+ # Shared markup parsing, document collection access, path
6
+ # normalization, and HTML escaping for the Liquid tags.
7
+ module TagHelpers
8
+ private
9
+
10
+ def parse_markup(markup)
11
+ text = markup.to_s
12
+ target, remainder = extract_target(text)
13
+ options = extract_options(remainder)
14
+ [target, options]
15
+ end
16
+
17
+ def extract_target(text)
18
+ return [nil, text] if text.strip.match?(/\Apath\s*:/)
19
+
20
+ quoted = text.match(/\A["']([^"']+)["']/)
21
+ return [quoted[1], text[quoted.end(0)..]] if quoted
22
+
23
+ bare = text.strip.match(/\A([^\s]+)/)
24
+ return [nil, ""] unless bare
25
+
26
+ [bare[1], text[bare.end(0)..]]
27
+ end
28
+
29
+ def extract_options(text)
30
+ OptionsParser.parse_options(text)
31
+ end
32
+
33
+ def documents_from(context)
34
+ site = context.registers[:site]
35
+ site.collections["documents"]&.docs || []
36
+ end
37
+
38
+ def normalize_tag_path(path)
39
+ path.to_s.strip.tr("\\", "/").squeeze("/").delete_prefix("./").delete_prefix("/")
40
+ .delete_suffix("/")
41
+ end
42
+
43
+ def escape_html(value)
44
+ value.to_s.gsub(/[&<>"']/,
45
+ "&" => "&amp;",
46
+ "<" => "&lt;",
47
+ ">" => "&gt;",
48
+ '"' => "&quot;",
49
+ "'" => "&#39;")
50
+ end
51
+ end
52
+ end
53
+ end
@@ -4,6 +4,7 @@ module Jekyll
4
4
  module Documents
5
5
  module CategoryResolver
6
6
  include ResolutionReporter
7
+ include TagHelpers
7
8
 
8
9
  private
9
10
 
@@ -34,7 +35,7 @@ module Jekyll
34
35
  end
35
36
 
36
37
  def resolve_category_path(path, categories, site)
37
- normalized = normalize_category_path(path)
38
+ normalized = normalize_tag_path(path)
38
39
  matches = categories.select { |category| category["path"] == normalized }
39
40
  return matches if matches.one?
40
41
 
@@ -54,17 +55,13 @@ module Jekyll
54
55
  leaf = category["path"].split("/").last.to_s.downcase
55
56
  [category["category"], category["slug"], leaf].map { |value| value.to_s.downcase }.uniq
56
57
  end
57
-
58
- def normalize_category_path(path)
59
- path.to_s.strip.tr("\\", "/").squeeze("/").delete_prefix("./").delete_prefix("/")
60
- .delete_suffix("/")
61
- end
62
58
  end
63
59
 
64
60
  class DocCategoryTag < Liquid::Tag
65
61
  public_class_method :new
66
62
 
67
63
  include CategoryResolver
64
+ include TagHelpers
68
65
  include Jekyll::Filters::URLFilters
69
66
 
70
67
  def initialize(tag_name, markup, tokens)
@@ -88,11 +85,6 @@ module Jekyll
88
85
 
89
86
  private
90
87
 
91
- def documents_from(context)
92
- site = context.registers[:site]
93
- site.collections["documents"]&.docs || []
94
- end
95
-
96
88
  def available_categories(docs)
97
89
  categories = docs.group_by { |doc| doc.data["category_path"] || doc.data["category"] }
98
90
  .map do |path, matches|
@@ -137,38 +129,6 @@ module Jekyll
137
129
  out << %(<li><a href="#{url}">#{title}</a> <small>(#{date})</small></li>\n)
138
130
  end
139
131
  end
140
-
141
- def parse_markup(markup)
142
- text = markup.to_s
143
- category, remainder = extract_category(text)
144
- options = extract_options(remainder)
145
- [category, options]
146
- end
147
-
148
- def extract_category(text)
149
- return [nil, text] if text.strip.match?(/\Apath\s*:/)
150
-
151
- quoted = text.match(/\A["']([^"']+)["']/)
152
- return [quoted[1], text[quoted.end(0)..]] if quoted
153
-
154
- bare = text.strip.match(/\A([^\s]+)/)
155
- return [nil, ""] unless bare
156
-
157
- [bare[1], text[bare.end(0)..]]
158
- end
159
-
160
- def extract_options(text)
161
- OptionsParser.parse_options(text)
162
- end
163
-
164
- def escape_html(value)
165
- value.to_s.gsub(/[&<>"']/,
166
- "&" => "&amp;",
167
- "<" => "&lt;",
168
- ">" => "&gt;",
169
- '"' => "&quot;",
170
- "'" => "&#39;")
171
- end
172
132
  end
173
133
  end
174
134
  end
@@ -4,6 +4,7 @@ module Jekyll
4
4
  module Documents
5
5
  module DocumentResolver
6
6
  include ResolutionReporter
7
+ include TagHelpers
7
8
 
8
9
  private
9
10
 
@@ -37,7 +38,7 @@ module Jekyll
37
38
  end
38
39
 
39
40
  def find_document_by_path(docs, path, site)
40
- normalized = normalize_identifier_path(path)
41
+ normalized = normalize_tag_path(path)
41
42
  matches = docs.select { |doc| doc.data["source_path"].to_s == normalized }
42
43
  return matches.first if matches.one?
43
44
 
@@ -48,11 +49,6 @@ module Jekyll
48
49
  nil
49
50
  end
50
51
 
51
- def normalize_identifier_path(path)
52
- path.to_s.strip.tr("\\", "/").squeeze("/").delete_prefix("./").delete_prefix("/")
53
- .delete_suffix("/")
54
- end
55
-
56
52
  def document_values(doc)
57
53
  [doc.data["title"], doc.data["slug"]].map { |value| value.to_s.downcase }
58
54
  end
@@ -62,6 +58,7 @@ module Jekyll
62
58
  public_class_method :new
63
59
 
64
60
  include DocumentResolver
61
+ include TagHelpers
65
62
  include Jekyll::Filters::URLFilters
66
63
 
67
64
  SIZE_UNITS = %w[B KB MB GB].freeze
@@ -87,11 +84,6 @@ module Jekyll
87
84
 
88
85
  private
89
86
 
90
- def documents_from(context)
91
- site = context.registers[:site]
92
- site.collections["documents"]&.docs || []
93
- end
94
-
95
87
  def build_link(doc, url, text)
96
88
  inner = +""
97
89
  inner << icon_html(doc) if @options["icon"] != "false"
@@ -133,38 +125,6 @@ module Jekyll
133
125
  value /= 1024
134
126
  end
135
127
  end
136
-
137
- def parse_markup(markup)
138
- text = markup.to_s
139
- query, remainder = extract_query(text)
140
- options = extract_options(remainder)
141
- [query, options]
142
- end
143
-
144
- def extract_query(text)
145
- return [nil, text] if text.strip.match?(/\Apath\s*:/)
146
-
147
- quoted = text.match(/\A["']([^"']+)["']/)
148
- return [quoted[1], text[quoted.end(0)..]] if quoted
149
-
150
- bare = text.strip.match(/\A([^\s]+)/)
151
- return [nil, ""] unless bare
152
-
153
- [bare[1], text[bare.end(0)..]]
154
- end
155
-
156
- def extract_options(text)
157
- OptionsParser.parse_options(text)
158
- end
159
-
160
- def escape_html(value)
161
- value.to_s.gsub(/[&<>"']/,
162
- "&" => "&amp;",
163
- "<" => "&lt;",
164
- ">" => "&gt;",
165
- '"' => "&quot;",
166
- "'" => "&#39;")
167
- end
168
128
  end
169
129
  end
170
130
  end
@@ -5,6 +5,7 @@ module Jekyll
5
5
  class DocumentIconTag < Liquid::Tag
6
6
  public_class_method :new
7
7
 
8
+ include TagHelpers
8
9
  include Jekyll::Filters::URLFilters
9
10
 
10
11
  def initialize(tag_name, markup, tokens)
@@ -47,15 +48,6 @@ module Jekyll
47
48
  expression = markup.to_s.strip[/\A[^\s]+/]
48
49
  [expression, OptionsParser.parse_options(markup)]
49
50
  end
50
-
51
- def escape_html(value)
52
- value.to_s.gsub(/[&<>"']/,
53
- "&" => "&amp;",
54
- "<" => "&lt;",
55
- ">" => "&gt;",
56
- '"' => "&quot;",
57
- "'" => "&#39;")
58
- end
59
51
  end
60
52
  end
61
53
  end
@@ -10,21 +10,29 @@ module Jekyll
10
10
 
11
11
  public_class_method :new
12
12
 
13
+ include TagHelpers
14
+
13
15
  def render(context)
14
16
  site = context.registers[:site]
15
17
  cfg = Configuration.read(site)
16
- count = (@args["count"] || cfg["latest_default_count"] || 5).to_i
17
- category = @args["category"]
18
-
19
- docs = site.collections["documents"]&.docs || []
20
- docs = docs.select { |doc| doc.data["category"] == category } if category
21
- docs = docs.sort_by { |doc| doc.data["date"] || Time.at(0) }.reverse.first(count)
18
+ count = resolve_count(cfg)
19
+ docs = select_documents(site, @args["category"], count)
22
20
 
23
21
  render_list(docs)
24
22
  end
25
23
 
26
24
  private
27
25
 
26
+ def resolve_count(cfg)
27
+ (@args["count"] || cfg["latest_default_count"] || 5).to_i
28
+ end
29
+
30
+ def select_documents(site, category, count)
31
+ docs = site.collections["documents"]&.docs || []
32
+ docs = docs.select { |doc| doc.data["category"] == category } if category
33
+ docs.sort_by { |doc| doc.data["date"] || Time.at(0) }.reverse.first(count)
34
+ end
35
+
28
36
  def render_list(docs)
29
37
  out = +"<ul class=\"latest-documents\">\n"
30
38
  docs.each { |doc| out << list_item(doc) }
@@ -40,21 +48,9 @@ module Jekyll
40
48
  %(<li><a href="#{url}">#{title}</a> <small>(#{date})</small></li>\n)
41
49
  end
42
50
 
43
- def escape_html(text)
44
- return "" unless text
45
-
46
- text.to_s.gsub(/[&<>"']/, {
47
- "&" => "&amp;",
48
- "<" => "&lt;",
49
- ">" => "&gt;",
50
- '"' => "&quot;",
51
- "'" => "&#39;"
52
- })
53
- end
54
-
55
51
  # supports: count:5 category:'referat'
56
52
  def parse_args(markup)
57
- OptionsParser.parse_options(markup)
53
+ extract_options(markup)
58
54
  end
59
55
  end
60
56
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jekyll
4
4
  module Documents
5
- VERSION = "0.7.3"
5
+ VERSION = "0.7.4"
6
6
  end
7
7
  end
@@ -12,6 +12,7 @@ require_relative "jekyll/documents/assets_generator"
12
12
  require_relative "jekyll/documents/json_index_generator"
13
13
  require_relative "jekyll/documents/layout_registrar"
14
14
  require_relative "jekyll/documents/options_parser"
15
+ require_relative "jekyll/documents/tag_helpers"
15
16
 
16
17
  # Liquid tag(s)
17
18
  require_relative "jekyll/documents/tags/latest_documents"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-documents
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Svend Gundestrup
@@ -155,6 +155,7 @@ files:
155
155
  - lib/jekyll/documents/json_index_generator.rb
156
156
  - lib/jekyll/documents/layout_registrar.rb
157
157
  - lib/jekyll/documents/options_parser.rb
158
+ - lib/jekyll/documents/tag_helpers.rb
158
159
  - lib/jekyll/documents/tags/doc_category.rb
159
160
  - lib/jekyll/documents/tags/doc_link.rb
160
161
  - lib/jekyll/documents/tags/document_icon.rb