jekyll-documents 0.7.2 → 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: 884c3afc18e96312dcd25a2328f652ec8cb1417ad8ec26337b4aa4ee2f175517
4
- data.tar.gz: 29e0d75b6b50c68acb124e0b31123cc85c3810789c39d562beb8da00c5c50a87
3
+ metadata.gz: c690ba4e56790f19326b49d3476839028784f9da66b4d46d5a18680cac0ba927
4
+ data.tar.gz: 6007f855de36ef230b789fdab081877f19c9be15c583a342e669eaa811898317
5
5
  SHA512:
6
- metadata.gz: c50ee45d94b33d62b344dadda31c9cf865d8d175de1b00e7c7f92aaeb046f0cef7fec3835de627e68ec0ce9849d925b8fbacb3012be5a5face435822c173b9c3
7
- data.tar.gz: 3a28dee0ff0b8078cac42e4097676a991496e8510a38518bd7d6ea013275f2f9f804b15b5f4ab46e846f6ab2a5eaa8e72dfd4a535ed8a1b9c7cf338671a64019
6
+ metadata.gz: ecc1cbd701f3b07f70694dd0a9f7314d7d65bb2b2040ad0af3658d763ad540bb40daf90e1494100e49ab72a10540377786d793a2416536cc055f85a16983fcb7
7
+ data.tar.gz: dbab2960b310640f780b3d88695ec16cbdf1902fba99019736bedf7ab3ecf0a6f956c370b9b3c8858ad559f4f40fe7a6f354843a7ceef790e97010f751c898cc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
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
+
17
+ ## [0.7.3] - 2026-09-10
18
+
19
+ ### Added
20
+ - Added Semgrep CE security scanning with a custom ReDoS detection rule for pre-commit and CI
21
+ - Added CodeFactor code quality analysis badge and integration
22
+ - Added SEMGREP_APP_TOKEN integration for Cloud dashboard sync from CI
23
+ - Added `rake version:pre_release` task for pre-release security gate with FORCE=1 override
24
+
25
+ ### Changed
26
+ - Updated CI to Node.js 26 and current Node 24-based GitHub Actions runtimes
27
+ - Pinned all GitHub Actions to commit SHAs to prevent supply-chain attacks
28
+ - Added cooldown period to Dependabot configuration
29
+ - Pinned Lunr.js CDN to version 2.3.9 with SRI integrity hash
30
+ - Bumped actions/checkout to v7.0.1 (SHA-pinned)
31
+ - Reduced method complexity across 6 flagged CodeFactor findings:
32
+ - `generator.rb`: Extracted `process_file` and `merge_passthrough_fields` from `generate` and `configure_client_search`
33
+ - `doc_link.rb`: Extracted `match_documents` and `report_ambiguous` from `find_document`
34
+ - `doc_category.rb`: Extracted `match_categories` and `report_ambiguous_category` from `resolve_category`
35
+ - `latest_documents.rb`: Extracted `render_list` and `list_item` from `render`
36
+ - `options_parser.rb`: Extracted `read_value` from `parse_options`
37
+
38
+ ### Fixed
39
+ - Replaced dangerous subshell in system spec with Open3.capture2
40
+
3
41
  ## [0.7.2] - 2026-09-09
4
42
 
5
43
  ### Fixed
data/README.md CHANGED
@@ -6,6 +6,9 @@
6
6
  [![Gem Downloads](https://img.shields.io/gem/dt/jekyll-documents)](https://rubygems.org/gems/jekyll-documents)
7
7
  [![License: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue)](LICENSE)
8
8
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/gundestrup/jekyll-documents)
9
+ [![CodeFactor](https://www.codefactor.io/repository/github/gundestrup/jekyll-documents/badge)](https://www.codefactor.io/repository/github/gundestrup/jekyll-documents)
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)
9
12
 
10
13
  Turn files in `assets/documents/` into browsable document pages.
11
14
 
@@ -9,6 +9,8 @@
9
9
  window.__jekyllDocumentsIndexPath = {{ index_path | relative_url | jsonify }};
10
10
  window.__jekyllDocumentsBaseurl = {{ site.baseurl | jsonify }};
11
11
  </script>
12
- <script src="https://unpkg.com/lunr/lunr.js"></script>
12
+ <script src="https://unpkg.com/lunr@2.3.9/lunr.js"
13
+ integrity="sha384-Mrc0XsDxndfJgV5jLnEeThch4j9dNEXAE1vbWeyzmERxSvF8siQfuEczzgUelQQH"
14
+ crossorigin="anonymous"></script>
13
15
  <script src="{{ '/assets/js/documents-search.js' | relative_url }}"></script>
14
16
  {% endif %}
@@ -43,39 +43,10 @@ module Jekyll
43
43
  Dir.glob("#{root}/**/*").each do |path|
44
44
  next unless File.file?(path)
45
45
 
46
- source_extension = File.extname(path)
47
- ext = source_extension.downcase
48
- if @config["strict_extensions"] && !@config["include_extensions"].include?(ext)
49
- ::Jekyll.logger.abort_with "jekyll-documents",
50
- "Unsupported file type: #{path} (#{ext})"
51
- end
52
- next unless @config["include_extensions"].include?(ext)
46
+ doc, rel_path = process_file(path, root, collection)
47
+ next unless doc
53
48
 
54
- source_path = source_path_for(path, root)
55
- category_path = document_category_path(source_path)
56
- category = remap_category(category_path)
57
- rel_path = normalize_path(File.join(@config["root"], source_path))
58
49
  current_paths << rel_path
59
- basename = File.basename(path, source_extension)
60
-
61
- date, title, valid = parse_filename(basename)
62
- if !valid && @config["strict_filename"]
63
- ::Jekyll.logger.abort_with "jekyll-documents",
64
- "Filename must be 'YYYY-MM-DD_Title.ext' → #{rel_path}"
65
- end
66
-
67
- doc = ::Jekyll::Document.new(
68
- source_stub_for(source_path),
69
- site: site,
70
- collection: collection
71
- )
72
- file_info = {
73
- title: title, date: date, category: category, category_path: category_path,
74
- category_slug: slugify(category, "uncategorized"), source_path: source_path,
75
- rel_path: rel_path, ext: ext, file_type: ext.delete_prefix("."),
76
- icon_set: @config["icon_set"], slug: build_slug(basename), path: path
77
- }
78
- bake_document_data(doc, file_info)
79
50
  collection.docs << doc
80
51
  generated_docs << doc
81
52
  end
@@ -87,6 +58,42 @@ module Jekyll
87
58
 
88
59
  private
89
60
 
61
+ def process_file(path, root, collection)
62
+ source_extension = File.extname(path)
63
+ ext = source_extension.downcase
64
+ if @config["strict_extensions"] && !@config["include_extensions"].include?(ext)
65
+ ::Jekyll.logger.abort_with "jekyll-documents",
66
+ "Unsupported file type: #{path} (#{ext})"
67
+ end
68
+ return [nil, nil] unless @config["include_extensions"].include?(ext)
69
+
70
+ source_path = source_path_for(path, root)
71
+ rel_path = normalize_path(File.join(@config["root"], source_path))
72
+ basename = File.basename(path, source_extension)
73
+
74
+ date, title, valid = parse_filename(basename)
75
+ if !valid && @config["strict_filename"]
76
+ ::Jekyll.logger.abort_with "jekyll-documents",
77
+ "Filename must be 'YYYY-MM-DD_Title.ext' → #{rel_path}"
78
+ end
79
+
80
+ category_path = document_category_path(source_path)
81
+ category = remap_category(category_path)
82
+ doc = ::Jekyll::Document.new(
83
+ source_stub_for(source_path),
84
+ site: @site,
85
+ collection: collection
86
+ )
87
+ file_info = {
88
+ title: title, date: date, category: category, category_path: category_path,
89
+ category_slug: slugify(category, "uncategorized"), source_path: source_path,
90
+ rel_path: rel_path, ext: ext, file_type: ext.delete_prefix("."),
91
+ icon_set: @config["icon_set"], slug: build_slug(basename), path: path
92
+ }
93
+ bake_document_data(doc, file_info)
94
+ [doc, rel_path]
95
+ end
96
+
90
97
  # Auto-injects passthrough_fields into client_search config when the
91
98
  # documents collection is indexed. Only acts if client_search is already
92
99
  # configured with +documents+ in its collections list — does nothing if
@@ -96,13 +103,17 @@ module Jekyll
96
103
  return unless search_config.is_a?(Hash)
97
104
  return unless Array(search_config["collections"]).include?("documents")
98
105
 
106
+ merge_passthrough_fields(search_config)
107
+ search_config["icon_field"] = "icon_url" unless search_config.key?("icon_field")
108
+ end
109
+
110
+ def merge_passthrough_fields(search_config)
99
111
  fields = search_config["passthrough_fields"] || []
100
112
  existing = fields.flat_map { |f| f.is_a?(Hash) ? f.keys : [f.to_s] }
101
113
  %w[file_type icon_url icon_set].each do |field|
102
114
  fields << field unless existing.include?(field)
103
115
  end
104
116
  search_config["passthrough_fields"] = fields
105
- search_config["icon_field"] = "icon_url" unless search_config.key?("icon_field")
106
117
  end
107
118
 
108
119
  # Ensures a collection exists and is configured for output
@@ -27,17 +27,21 @@ module Jekyll
27
27
  scanner.skip(/\s*/)
28
28
  next unless scanner.scan(":")
29
29
 
30
- scanner.skip(/\s*/)
31
- value = if scanner.scan(/'([^']*)'/) || scanner.scan(/"([^"]*)"/)
32
- scanner[1]
33
- else
34
- scanner.scan(/\S+/)
35
- end
30
+ value = read_value(scanner)
36
31
  options[key] = value unless value.nil?
37
32
  end
38
33
 
39
34
  options
40
35
  end
36
+
37
+ def read_value(scanner)
38
+ scanner.skip(/\s*/)
39
+ if scanner.scan(/'([^']*)'/) || scanner.scan(/"([^"]*)"/)
40
+ scanner[1]
41
+ else
42
+ scanner.scan(/\S+/)
43
+ end
44
+ end
41
45
  end
42
46
  end
43
47
  end
@@ -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
 
@@ -13,22 +14,28 @@ module Jekyll
13
14
  normalized = query.to_s.strip.downcase
14
15
  return nil if normalized.empty?
15
16
 
16
- exact = categories.select do |category|
17
- category_values(category).include?(normalized)
18
- end
19
- matches = exact.empty? ? partial_categories(categories, normalized) : exact
17
+ matches = match_categories(categories, normalized)
20
18
  aggregate = options["aggregate"] == "true" && options["list"] == "true"
21
19
  return matches if matches.one? || (aggregate && matches.any?)
22
20
  return nil if matches.empty?
23
21
 
22
+ report_ambiguous_category(site, query, matches)
23
+ nil
24
+ end
25
+
26
+ def match_categories(categories, normalized)
27
+ exact = categories.select { |cat| category_values(cat).include?(normalized) }
28
+ exact.empty? ? partial_categories(categories, normalized) : exact
29
+ end
30
+
31
+ def report_ambiguous_category(site, query, matches)
24
32
  paths = matches.map { |category| category["path"] }.sort.join(", ")
25
33
  message = "Ambiguous doc_category #{query.inspect}; matches: #{paths}. Rendering nothing."
26
34
  report_resolution_issue(site, message)
27
- nil
28
35
  end
29
36
 
30
37
  def resolve_category_path(path, categories, site)
31
- normalized = normalize_category_path(path)
38
+ normalized = normalize_tag_path(path)
32
39
  matches = categories.select { |category| category["path"] == normalized }
33
40
  return matches if matches.one?
34
41
 
@@ -48,17 +55,13 @@ module Jekyll
48
55
  leaf = category["path"].split("/").last.to_s.downcase
49
56
  [category["category"], category["slug"], leaf].map { |value| value.to_s.downcase }.uniq
50
57
  end
51
-
52
- def normalize_category_path(path)
53
- path.to_s.strip.tr("\\", "/").squeeze("/").delete_prefix("./").delete_prefix("/")
54
- .delete_suffix("/")
55
- end
56
58
  end
57
59
 
58
60
  class DocCategoryTag < Liquid::Tag
59
61
  public_class_method :new
60
62
 
61
63
  include CategoryResolver
64
+ include TagHelpers
62
65
  include Jekyll::Filters::URLFilters
63
66
 
64
67
  def initialize(tag_name, markup, tokens)
@@ -82,11 +85,6 @@ module Jekyll
82
85
 
83
86
  private
84
87
 
85
- def documents_from(context)
86
- site = context.registers[:site]
87
- site.collections["documents"]&.docs || []
88
- end
89
-
90
88
  def available_categories(docs)
91
89
  categories = docs.group_by { |doc| doc.data["category_path"] || doc.data["category"] }
92
90
  .map do |path, matches|
@@ -131,38 +129,6 @@ module Jekyll
131
129
  out << %(<li><a href="#{url}">#{title}</a> <small>(#{date})</small></li>\n)
132
130
  end
133
131
  end
134
-
135
- def parse_markup(markup)
136
- text = markup.to_s
137
- category, remainder = extract_category(text)
138
- options = extract_options(remainder)
139
- [category, options]
140
- end
141
-
142
- def extract_category(text)
143
- return [nil, text] if text.strip.match?(/\Apath\s*:/)
144
-
145
- quoted = text.match(/\A["']([^"']+)["']/)
146
- return [quoted[1], text[quoted.end(0)..]] if quoted
147
-
148
- bare = text.strip.match(/\A([^\s]+)/)
149
- return [nil, ""] unless bare
150
-
151
- [bare[1], text[bare.end(0)..]]
152
- end
153
-
154
- def extract_options(text)
155
- OptionsParser.parse_options(text)
156
- end
157
-
158
- def escape_html(value)
159
- value.to_s.gsub(/[&<>"']/,
160
- "&" => "&amp;",
161
- "<" => "&lt;",
162
- ">" => "&gt;",
163
- '"' => "&quot;",
164
- "'" => "&#39;")
165
- end
166
132
  end
167
133
  end
168
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
 
@@ -13,25 +14,31 @@ module Jekyll
13
14
  normalized = query.to_s.strip.downcase
14
15
  return nil if normalized.empty?
15
16
 
16
- exact = docs.select { |doc| document_values(doc).include?(normalized) }
17
- matches = if exact.empty?
18
- docs.select do |doc|
19
- document_values(doc).any? { |value| value.include?(normalized) }
20
- end
21
- else
22
- exact
23
- end
17
+ matches = match_documents(docs, normalized)
24
18
  return matches.first if matches.one?
25
19
  return nil if matches.empty?
26
20
 
21
+ report_ambiguous(site, query, matches)
22
+ nil
23
+ end
24
+
25
+ def match_documents(docs, normalized)
26
+ exact = docs.select { |doc| document_values(doc).include?(normalized) }
27
+ return exact unless exact.empty?
28
+
29
+ docs.select do |doc|
30
+ document_values(doc).any? { |value| value.include?(normalized) }
31
+ end
32
+ end
33
+
34
+ def report_ambiguous(site, query, matches)
27
35
  paths = matches.map { |doc| doc.data["source_path"] || doc.path }.sort.join(", ")
28
36
  message = "Ambiguous doc_link #{query.inspect}; matches: #{paths}. Rendering nothing."
29
37
  report_resolution_issue(site, message)
30
- nil
31
38
  end
32
39
 
33
40
  def find_document_by_path(docs, path, site)
34
- normalized = normalize_identifier_path(path)
41
+ normalized = normalize_tag_path(path)
35
42
  matches = docs.select { |doc| doc.data["source_path"].to_s == normalized }
36
43
  return matches.first if matches.one?
37
44
 
@@ -42,11 +49,6 @@ module Jekyll
42
49
  nil
43
50
  end
44
51
 
45
- def normalize_identifier_path(path)
46
- path.to_s.strip.tr("\\", "/").squeeze("/").delete_prefix("./").delete_prefix("/")
47
- .delete_suffix("/")
48
- end
49
-
50
52
  def document_values(doc)
51
53
  [doc.data["title"], doc.data["slug"]].map { |value| value.to_s.downcase }
52
54
  end
@@ -56,6 +58,7 @@ module Jekyll
56
58
  public_class_method :new
57
59
 
58
60
  include DocumentResolver
61
+ include TagHelpers
59
62
  include Jekyll::Filters::URLFilters
60
63
 
61
64
  SIZE_UNITS = %w[B KB MB GB].freeze
@@ -81,11 +84,6 @@ module Jekyll
81
84
 
82
85
  private
83
86
 
84
- def documents_from(context)
85
- site = context.registers[:site]
86
- site.collections["documents"]&.docs || []
87
- end
88
-
89
87
  def build_link(doc, url, text)
90
88
  inner = +""
91
89
  inner << icon_html(doc) if @options["icon"] != "false"
@@ -127,38 +125,6 @@ module Jekyll
127
125
  value /= 1024
128
126
  end
129
127
  end
130
-
131
- def parse_markup(markup)
132
- text = markup.to_s
133
- query, remainder = extract_query(text)
134
- options = extract_options(remainder)
135
- [query, options]
136
- end
137
-
138
- def extract_query(text)
139
- return [nil, text] if text.strip.match?(/\Apath\s*:/)
140
-
141
- quoted = text.match(/\A["']([^"']+)["']/)
142
- return [quoted[1], text[quoted.end(0)..]] if quoted
143
-
144
- bare = text.strip.match(/\A([^\s]+)/)
145
- return [nil, ""] unless bare
146
-
147
- [bare[1], text[bare.end(0)..]]
148
- end
149
-
150
- def extract_options(text)
151
- OptionsParser.parse_options(text)
152
- end
153
-
154
- def escape_html(value)
155
- value.to_s.gsub(/[&<>"']/,
156
- "&" => "&amp;",
157
- "<" => "&lt;",
158
- ">" => "&gt;",
159
- '"' => "&quot;",
160
- "'" => "&#39;")
161
- end
162
128
  end
163
129
  end
164
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,45 +10,47 @@ 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
+ count = resolve_count(cfg)
19
+ docs = select_documents(site, @args["category"], count)
20
+
21
+ render_list(docs)
22
+ end
18
23
 
24
+ private
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)
19
31
  docs = site.collections["documents"]&.docs || []
20
32
  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)
33
+ docs.sort_by { |doc| doc.data["date"] || Time.at(0) }.reverse.first(count)
34
+ end
22
35
 
36
+ def render_list(docs)
23
37
  out = +"<ul class=\"latest-documents\">\n"
24
- docs.each do |doc|
25
- data = doc.data
26
- title = escape_html(data["title"])
27
- url = escape_html(doc.url)
28
- date = (data["date"] || Time.at(0)).strftime("%Y-%m-%d")
29
- out << %(<li><a href="#{url}">#{title}</a> <small>(#{date})</small></li>\n)
30
- end
38
+ docs.each { |doc| out << list_item(doc) }
31
39
  out << "</ul>\n"
32
40
  out
33
41
  end
34
42
 
35
- private
36
-
37
- def escape_html(text)
38
- return "" unless text
39
-
40
- text.to_s.gsub(/[&<>"']/, {
41
- "&" => "&amp;",
42
- "<" => "&lt;",
43
- ">" => "&gt;",
44
- '"' => "&quot;",
45
- "'" => "&#39;"
46
- })
43
+ def list_item(doc)
44
+ data = doc.data
45
+ title = escape_html(data["title"])
46
+ url = escape_html(doc.url)
47
+ date = (data["date"] || Time.at(0)).strftime("%Y-%m-%d")
48
+ %(<li><a href="#{url}">#{title}</a> <small>(#{date})</small></li>\n)
47
49
  end
48
50
 
49
51
  # supports: count:5 category:'referat'
50
52
  def parse_args(markup)
51
- OptionsParser.parse_options(markup)
53
+ extract_options(markup)
52
54
  end
53
55
  end
54
56
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jekyll
4
4
  module Documents
5
- VERSION = "0.7.2"
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.2
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