jekyll-documents 0.3.0 → 0.3.2
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/CHANGELOG.md +41 -2
- data/README.md +24 -4
- data/_includes/documents_list.html +1 -1
- data/_includes/documents_search.html +8 -0
- data/_includes/latest_documents.html +1 -1
- data/_layouts/document.html +1 -1
- data/assets/js/documents-search.js +68 -90
- data/jekyll-documents.gemspec +6 -6
- data/lib/jekyll/documents/assets_generator.rb +48 -0
- data/lib/jekyll/documents/file_type_icons.rb +67 -38
- data/lib/jekyll/documents/generator.rb +1 -1
- data/lib/jekyll/documents/json_index_generator.rb +2 -1
- data/lib/jekyll/documents/layout_registrar.rb +60 -0
- data/lib/jekyll/documents/tags/document_icon.rb +68 -0
- data/lib/jekyll/documents/version.rb +1 -1
- data/lib/jekyll-documents.rb +3 -0
- metadata +23 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2c05b94feef92602870b24fd7b9c4e9244eb724061c1ef599ed12a23905d51ad
|
|
4
|
+
data.tar.gz: ccfe08306d471478e21092fd7518df1c6d593b05fa219051a6d866d3c947c6c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '087a677f0f1efd8c54d7b52c05c1fd0b88c746e9063f8fc0ba843c5ca24db53b8cbdd6904a959d7ca606e490bf8da590ff9b400b21a9de25204079ed0f0b0eff'
|
|
7
|
+
data.tar.gz: 7519b8f1e7035b4391299dd6399dcb1a6fa6572d4b3567891e35fc3f383a7b2958acc28bdbfe058983d6fbf73592c33a609dd07ae082751410873d8d29ac1434
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [0.3.2] - 2026-08-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Auto-registration of gem-packaged `_layouts` and `_includes` via a `:site, :after_init` hook so Jekyll discovers the `document` layout and all includes without the gem being declared as a theme; user-provided files always take precedence
|
|
9
|
+
- 7 RSpec examples for `LayoutRegistrar` covering copy, override, idempotency, and hook registration
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Corrected publish workflow Ruby version from 3.2 to 3.3 to match the gemspec `required_ruby_version` so the gem builds and publishes to RubyGems successfully
|
|
13
|
+
|
|
14
|
+
## [0.3.1] - 2026-08-03
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- Added the context-aware `{% document_icon page %}` Liquid tag for simple icon rendering
|
|
18
|
+
- Added installed-gem system coverage for all supported document types and icon themes
|
|
19
|
+
- Added Playwright browser coverage for search interaction, links, icons, baseurl, and network errors
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Minimum Ruby version raised from `>= 3.2` to `>= 3.3`
|
|
23
|
+
- Updated RuboCop target Ruby version to 3.3
|
|
24
|
+
- Updated compatible development gems, including RuboCop, Reek, RSpec, and Playwright tooling
|
|
25
|
+
- Test and quality tasks now rebuild and force-install the gem before testing
|
|
26
|
+
- Added package-content checks to verify the built gem contains runtime templates, icons, JavaScript, and Liquid tags
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Corrected non-color icon mappings to reference packaged SVG assets
|
|
30
|
+
- Registered packaged icons and search JavaScript for copying during Jekyll builds
|
|
31
|
+
- Made document search respect the configured index path and site base URL
|
|
32
|
+
- Hardened document search index validation and disabled the search include when JSON indexing is disabled
|
|
33
|
+
- Escaped search-result URLs, icon URLs, titles, categories, and dates before rendering
|
|
34
|
+
- Added the missing date conversion required for Jekyll 4.4 document publishing
|
|
35
|
+
- Removed duplicate search scripts from the example site
|
|
36
|
+
- Made Reek failures fail the quality task consistently
|
|
37
|
+
|
|
38
|
+
### Verification
|
|
39
|
+
- 186 Ruby/system examples passing with 100% Ruby line coverage
|
|
40
|
+
- 3 Playwright browser tests passing
|
|
41
|
+
- 0 RuboCop offenses, 0 Reek warnings, and 0 Bundler Audit vulnerabilities
|
|
3
42
|
|
|
4
43
|
## [0.3.0] - 2026-07-23
|
|
5
44
|
|
|
@@ -13,8 +52,8 @@
|
|
|
13
52
|
- **System test for full build pipeline**: End-to-end test covering generator → JSON index → tag rendering
|
|
14
53
|
|
|
15
54
|
### Changed
|
|
16
|
-
- **Minimum Ruby version**: Bumped from `>= 2.7` to `>= 3.
|
|
17
|
-
- **RuboCop `TargetRubyVersion`**: Updated from `2.7` to `3.
|
|
55
|
+
- **Minimum Ruby version**: Bumped from `>= 2.7` to `>= 3.2` (zeitwerk 2.7+ — a Jekyll dependency — requires Ruby >= 3.2)
|
|
56
|
+
- **RuboCop `TargetRubyVersion`**: Updated from `2.7` to `3.2` to match gemspec
|
|
18
57
|
- **Templates use baked icon data**: `latest_documents.html`, `documents_list.html`, `document.html` now use `{{ doc.icon_url }}` instead of the broken `file_type_icon_tag` filter
|
|
19
58
|
- **`category_list.html` icon set**: Now reads `icon_set` from first document's baked data instead of non-functional `site.documents.icon_set`
|
|
20
59
|
- **`latest_documents.html` count fallback**: Simplified to `| default: 5` since `site.config` is inaccessible in Liquid
|
data/README.md
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
# jekyll-documents
|
|
2
|
+
[](https://github.com/gundestrup/jekyll-documents)
|
|
3
|
+
[](https://github.com/gundestrup/jekyll-documents/actions/workflows/test.yml)
|
|
4
|
+
[](https://codecov.io/gh/gundestrup/jekyll-documents)
|
|
5
|
+
[](https://rubygems.org/gems/jekyll-documents)
|
|
6
|
+
[](https://rubygems.org/gems/jekyll-documents)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://deepwiki.com/gundestrup/jekyll-documents)
|
|
2
9
|
|
|
3
10
|
Turn files in `assets/documents/` into browsable document pages.
|
|
4
11
|
|
|
12
|
+
**Requirements**: Ruby 3.3+ • Jekyll 4.4+
|
|
13
|
+
|
|
5
14
|
**Features**: Auto-collection • File icons • Categories • Search
|
|
6
15
|
|
|
16
|
+
[](https://deepwiki.com/gundestrup/jekyll-documents)
|
|
17
|
+
|
|
7
18
|
## Quick Start
|
|
8
19
|
|
|
9
20
|
```ruby
|
|
@@ -52,10 +63,15 @@ documents:
|
|
|
52
63
|
icon_set: "color"
|
|
53
64
|
```
|
|
54
65
|
|
|
66
|
+
Render a document icon in templates with the context-aware tag:
|
|
67
|
+
|
|
55
68
|
```liquid
|
|
56
|
-
{
|
|
69
|
+
{% document_icon page %}
|
|
57
70
|
```
|
|
58
71
|
|
|
72
|
+
The tag applies the configured icon set and site `baseurl` automatically. The `file_type_icon` and
|
|
73
|
+
`file_type_icon_tag` filters remain available for lower-level or Ruby-side use.
|
|
74
|
+
|
|
59
75
|
## Usage
|
|
60
76
|
|
|
61
77
|
```liquid
|
|
@@ -78,15 +94,19 @@ See [configuration.rb](lib/jekyll/documents/configuration.rb) for all options.
|
|
|
78
94
|
## Development
|
|
79
95
|
|
|
80
96
|
```bash
|
|
81
|
-
rake #
|
|
82
|
-
rake
|
|
97
|
+
rake # Ruby quality checks
|
|
98
|
+
rake test # Rebuild/install gem + Ruby and browser tests
|
|
99
|
+
rake browser_test # Browser search tests (Node.js + Chromium required)
|
|
100
|
+
rake quick # Fast Ruby check
|
|
83
101
|
rake help # Show commands
|
|
84
102
|
```
|
|
85
103
|
|
|
86
|
-
**Quality**:
|
|
104
|
+
**Quality**: 100% coverage • 0 vulnerabilities • 0 offenses • 0 warnings
|
|
87
105
|
|
|
88
106
|
See [README.Development.md](README.Development.md) for details.
|
|
89
107
|
|
|
108
|
+
**DeepWiki**: [https://deepwiki.com/gundestrup/jekyll-documents](https://deepwiki.com/gundestrup/jekyll-documents)
|
|
109
|
+
|
|
90
110
|
## Release
|
|
91
111
|
|
|
92
112
|
```bash
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<ul class="documents-list">
|
|
3
3
|
{% for doc in docs %}
|
|
4
4
|
<li>
|
|
5
|
-
|
|
5
|
+
{% document_icon doc %}
|
|
6
6
|
<a href="{{ doc.url | relative_url }}">{{ doc.title }}</a>
|
|
7
7
|
<small>({{ doc.date | date: "%Y-%m-%d" }}, {{ doc.category }})</small>
|
|
8
8
|
</li>
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
{% assign documents_config = site.data.jekyll_documents %}
|
|
2
|
+
{% assign index_path = documents_config.json_index_path | default: '/documents.json' %}
|
|
3
|
+
{% if documents_config.json_index != false %}
|
|
1
4
|
<div class="documents-search">
|
|
2
5
|
<input id="doc-search-input" type="search" placeholder="Search documents…" aria-label="Search documents" />
|
|
3
6
|
<div id="doc-search-results" class="documents-search-results"></div>
|
|
4
7
|
</div>
|
|
8
|
+
<script>
|
|
9
|
+
window.__jekyllDocumentsIndexPath = {{ index_path | relative_url | jsonify }};
|
|
10
|
+
window.__jekyllDocumentsBaseurl = {{ site.baseurl | jsonify }};
|
|
11
|
+
</script>
|
|
5
12
|
<script src="https://unpkg.com/lunr/lunr.js"></script>
|
|
6
13
|
<script src="{{ '/assets/js/documents-search.js' | relative_url }}"></script>
|
|
14
|
+
{% endif %}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<ul class="latest-documents">
|
|
4
4
|
{% for doc in docs %}
|
|
5
5
|
<li>
|
|
6
|
-
|
|
6
|
+
{% document_icon doc %}
|
|
7
7
|
<a href="{{ doc.url | relative_url }}">{{ doc.title }}</a>
|
|
8
8
|
<small>({{ doc.date | date: "%Y-%m-%d" }}, {{ doc.category }})</small>
|
|
9
9
|
</li>
|
data/_layouts/document.html
CHANGED
|
@@ -13,7 +13,7 @@ layout: default
|
|
|
13
13
|
|
|
14
14
|
<p>
|
|
15
15
|
<a href="{{ page.file_url | relative_url }}" class="document-download">
|
|
16
|
-
|
|
16
|
+
{% document_icon page %}
|
|
17
17
|
Download ({{ page.extension | remove: "." | upcase }})
|
|
18
18
|
</a>
|
|
19
19
|
</p>
|
|
@@ -1,80 +1,38 @@
|
|
|
1
|
-
/* Minimal client-side search using Lunr and
|
|
1
|
+
/* Minimal client-side search using Lunr and the generated document index.
|
|
2
2
|
Usage on any page:
|
|
3
3
|
{% include documents_search.html %}
|
|
4
|
-
<script src="https://unpkg.com/lunr/lunr.js"></script>
|
|
5
|
-
<script src="{{ '/assets/js/documents-search.js' | relative_url }}"></script>
|
|
6
4
|
*/
|
|
7
5
|
(function () {
|
|
8
6
|
const input = document.getElementById("doc-search-input");
|
|
9
7
|
const resultsEl = document.getElementById("doc-search-results");
|
|
10
8
|
if (!input || !resultsEl) return;
|
|
11
9
|
|
|
12
|
-
const indexUrl =
|
|
10
|
+
const indexUrl = window.__jekyllDocumentsIndexPath || "/documents.json";
|
|
13
11
|
let idx, docs = [];
|
|
14
12
|
|
|
15
|
-
function escapeHtml(
|
|
13
|
+
function escapeHtml(value) {
|
|
16
14
|
const div = document.createElement("div");
|
|
17
|
-
div.appendChild(document.createTextNode(
|
|
18
|
-
return div.innerHTML
|
|
15
|
+
div.appendChild(document.createTextNode(String(value)));
|
|
16
|
+
return div.innerHTML
|
|
17
|
+
.replace(/"/g, """)
|
|
18
|
+
.replace(/'/g, "'");
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"ppt": "/assets/icons/color/ppt-document-svgrepo-com.svg",
|
|
30
|
-
"xlsx": "/assets/icons/color/excel-document-svgrepo-com.svg",
|
|
31
|
-
"xls": "/assets/icons/color/excel-document-svgrepo-com.svg",
|
|
32
|
-
"txt": "/assets/icons/color/txt-document-svgrepo-com.svg",
|
|
33
|
-
"zip": "/assets/icons/color/zip-document-svgrepo-com.svg"
|
|
34
|
-
},
|
|
35
|
-
"lines": {
|
|
36
|
-
"pdf": "/assets/icons/lines/pdf-svgrepo-com.svg",
|
|
37
|
-
"doc": "/assets/icons/lines/doc-svgrepo-com.svg",
|
|
38
|
-
"docx": "/assets/icons/lines/doc-svgrepo-com.svg",
|
|
39
|
-
"ppt": "/assets/icons/lines/ppt-svgrepo-com.svg",
|
|
40
|
-
"pptx": "/assets/icons/lines/ppt-svgrepo-com.svg",
|
|
41
|
-
"xls": "/assets/icons/lines/xls-svgrepo-com.svg",
|
|
42
|
-
"xlsx": "/assets/icons/lines/xls-svgrepo-com.svg",
|
|
43
|
-
"txt": "/assets/icons/lines/txt-svgrepo-com.svg",
|
|
44
|
-
"zip": "/assets/icons/lines/zip-svgrepo-com.svg"
|
|
45
|
-
},
|
|
46
|
-
"minimal": {
|
|
47
|
-
"pdf": "/assets/icons/minimal/pdf-svgrepo-com.svg",
|
|
48
|
-
"doc": "/assets/icons/minimal/doc-svgrepo-com.svg",
|
|
49
|
-
"docx": "/assets/icons/minimal/doc-svgrepo-com.svg",
|
|
50
|
-
"ppt": "/assets/icons/minimal/ppt-svgrepo-com.svg",
|
|
51
|
-
"pptx": "/assets/icons/minimal/ppt-svgrepo-com.svg",
|
|
52
|
-
"xls": "/assets/icons/minimal/xls-svgrepo-com.svg",
|
|
53
|
-
"xlsx": "/assets/icons/minimal/xls-svgrepo-com.svg",
|
|
54
|
-
"txt": "/assets/icons/minimal/txt-svgrepo-com.svg",
|
|
55
|
-
"zip": "/assets/icons/minimal/zip-svgrepo-com.svg"
|
|
56
|
-
},
|
|
57
|
-
"ultra-minimal": {
|
|
58
|
-
"pdf": "/assets/icons/ultra-minimal/pdf.svg",
|
|
59
|
-
"doc": "/assets/icons/ultra-minimal/doc.svg",
|
|
60
|
-
"docx": "/assets/icons/ultra-minimal/doc.svg",
|
|
61
|
-
"ppt": "/assets/icons/ultra-minimal/ppt.svg",
|
|
62
|
-
"pptx": "/assets/icons/ultra-minimal/ppt.svg",
|
|
63
|
-
"xls": "/assets/icons/ultra-minimal/xls.svg",
|
|
64
|
-
"xlsx": "/assets/icons/ultra-minimal/xls.svg",
|
|
65
|
-
"txt": "/assets/icons/ultra-minimal/txt.svg",
|
|
66
|
-
"zip": "/assets/icons/ultra-minimal/zip.svg"
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
const icons = iconMap[iconSet] || iconMap["color"];
|
|
70
|
-
return icons[fileType] || `/assets/icons/${iconSet}/unknown-document-svgrepo-com.svg`;
|
|
21
|
+
function withBaseurl(url) {
|
|
22
|
+
const value = String(url || "");
|
|
23
|
+
if (!value || /^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(value)) return value;
|
|
24
|
+
|
|
25
|
+
const baseurl = String(window.__jekyllDocumentsBaseurl || "")
|
|
26
|
+
.replace(/^\/+|\/+$/g, "");
|
|
27
|
+
const path = value.replace(/^\/+/, "");
|
|
28
|
+
return `/${[baseurl, path].filter(Boolean).join("/")}`;
|
|
71
29
|
}
|
|
72
30
|
|
|
73
|
-
function getIconTag(fileType) {
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
return `<img src="${
|
|
31
|
+
function getIconTag(fileType, iconUrl) {
|
|
32
|
+
if (!iconUrl) return "";
|
|
33
|
+
const altText = `${String(fileType || "file").toUpperCase()} file`;
|
|
34
|
+
const url = escapeHtml(withBaseurl(iconUrl));
|
|
35
|
+
return `<img src="${url}" alt="${escapeHtml(altText)}" class="file-icon" />`;
|
|
78
36
|
}
|
|
79
37
|
|
|
80
38
|
function render(matches) {
|
|
@@ -82,21 +40,27 @@
|
|
|
82
40
|
resultsEl.innerHTML = "<p>No results.</p>";
|
|
83
41
|
return;
|
|
84
42
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
43
|
+
|
|
44
|
+
const items = matches.slice(0, 20).map(match => {
|
|
45
|
+
const document = docs.find(item => item.url === match.ref);
|
|
46
|
+
if (!document) return "";
|
|
47
|
+
|
|
48
|
+
const title = escapeHtml(document.title || "Untitled");
|
|
49
|
+
const category = escapeHtml(document.category || "uncategorized");
|
|
50
|
+
const date = document.date ? `<small>${escapeHtml(document.date)}</small>` : "";
|
|
51
|
+
const icon = getIconTag(document.file_type, document.icon_url);
|
|
52
|
+
const url = escapeHtml(withBaseurl(document.url));
|
|
53
|
+
return `<li>${icon}<a href="${url}">${title}</a> ` +
|
|
54
|
+
`<small>[${category}]</small> ${date}</li>`;
|
|
93
55
|
});
|
|
94
56
|
resultsEl.innerHTML = `<ul class="documents-search-list">${items.join("")}</ul>`;
|
|
95
57
|
}
|
|
96
58
|
|
|
97
59
|
function debounce(fn, wait) {
|
|
98
|
-
let
|
|
99
|
-
|
|
60
|
+
let timer;
|
|
61
|
+
return function (...args) {
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
timer = setTimeout(() => fn.apply(this, args), wait);
|
|
100
64
|
};
|
|
101
65
|
}
|
|
102
66
|
|
|
@@ -106,34 +70,48 @@
|
|
|
106
70
|
this.field("title", { boost: 10 });
|
|
107
71
|
this.field("category", { boost: 5 });
|
|
108
72
|
this.field("slug");
|
|
109
|
-
docs.forEach(
|
|
73
|
+
docs.forEach(document => this.add(document));
|
|
110
74
|
});
|
|
111
75
|
}
|
|
112
76
|
|
|
113
|
-
function doSearch(
|
|
114
|
-
if (!idx || !
|
|
77
|
+
function doSearch(query) {
|
|
78
|
+
if (!idx || !query || query.trim().length === 0) {
|
|
115
79
|
resultsEl.innerHTML = "";
|
|
116
80
|
return;
|
|
117
81
|
}
|
|
82
|
+
|
|
118
83
|
try {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
render(res);
|
|
84
|
+
render(idx.search(query));
|
|
85
|
+
} catch (error) {
|
|
86
|
+
// If Lunr query syntax fails, fall back to a simple contains filter.
|
|
87
|
+
const normalizedQuery = query.toLowerCase();
|
|
88
|
+
const matches = docs.filter(document =>
|
|
89
|
+
[document.title, document.category, document.slug].some(value =>
|
|
90
|
+
String(value || "").toLowerCase().includes(normalizedQuery)
|
|
91
|
+
)
|
|
92
|
+
).map(document => ({ ref: document.url }));
|
|
93
|
+
render(matches);
|
|
130
94
|
}
|
|
131
95
|
}
|
|
132
96
|
|
|
133
97
|
fetch(indexUrl)
|
|
134
|
-
.then(
|
|
135
|
-
|
|
136
|
-
|
|
98
|
+
.then(response => {
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
throw new Error(`Search index request failed: ${response.status}`);
|
|
101
|
+
}
|
|
102
|
+
return response.json();
|
|
103
|
+
})
|
|
104
|
+
.then(json => {
|
|
105
|
+
if (!Array.isArray(json)) {
|
|
106
|
+
throw new Error("Search index must be a JSON array");
|
|
107
|
+
}
|
|
108
|
+
docs = json;
|
|
109
|
+
buildIndex();
|
|
110
|
+
})
|
|
111
|
+
.catch(error => {
|
|
112
|
+
resultsEl.innerHTML = "<p>Document search is currently unavailable.</p>";
|
|
113
|
+
console.error("Documents search index failed:", error);
|
|
114
|
+
});
|
|
137
115
|
|
|
138
|
-
input.addEventListener("input", debounce(
|
|
116
|
+
input.addEventListener("input", debounce(event => doSearch(event.target.value), 150));
|
|
139
117
|
})();
|
data/jekyll-documents.gemspec
CHANGED
|
@@ -25,20 +25,20 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
"rubygems_mfa_required" => "true"
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
spec.required_ruby_version = ">= 3.
|
|
28
|
+
spec.required_ruby_version = ">= 3.3"
|
|
29
29
|
|
|
30
30
|
spec.files = Dir.glob("{lib,assets,_includes,_layouts}/**/*") +
|
|
31
31
|
["README.md", "CHANGELOG.md", "LICENSE", "jekyll-documents.gemspec"]
|
|
32
32
|
spec.require_paths = ["lib"]
|
|
33
33
|
|
|
34
|
-
spec.add_dependency "jekyll", ">= 4.0"
|
|
34
|
+
spec.add_dependency "jekyll", ">= 4.4", "< 5.0"
|
|
35
35
|
|
|
36
36
|
spec.add_development_dependency "bundler-audit", "~> 0.9"
|
|
37
37
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
38
|
-
spec.add_development_dependency "reek", "~> 6.
|
|
39
|
-
spec.add_development_dependency "rspec", "~> 3.
|
|
40
|
-
spec.add_development_dependency "rubocop", "~> 1.
|
|
41
|
-
spec.add_development_dependency "rubocop-performance", "~> 1.
|
|
38
|
+
spec.add_development_dependency "reek", "~> 6.5"
|
|
39
|
+
spec.add_development_dependency "rspec", "~> 3.13"
|
|
40
|
+
spec.add_development_dependency "rubocop", "~> 1.88"
|
|
41
|
+
spec.add_development_dependency "rubocop-performance", "~> 1.26"
|
|
42
42
|
spec.add_development_dependency "simplecov", "~> 1.0"
|
|
43
43
|
spec.add_development_dependency "yard", "~> 0.9"
|
|
44
44
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module Documents
|
|
5
|
+
# Registers gem-packaged frontend assets for copying into the generated site.
|
|
6
|
+
class AssetsGenerator < ::Jekyll::Generator
|
|
7
|
+
safe true
|
|
8
|
+
priority :normal
|
|
9
|
+
|
|
10
|
+
def generate(site)
|
|
11
|
+
package_root = File.expand_path("../../..", __dir__)
|
|
12
|
+
site.data["jekyll_documents"] = configuration(site)
|
|
13
|
+
register_assets(site, package_root)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def configuration(site)
|
|
19
|
+
config = Configuration.read(site)
|
|
20
|
+
{
|
|
21
|
+
"json_index" => config["json_index"],
|
|
22
|
+
"json_index_path" => config["json_index_path"]
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def register_assets(site, package_root)
|
|
27
|
+
assets_root = File.join(package_root, "assets")
|
|
28
|
+
Dir.glob(File.join(assets_root, "**", "*")).each do |path|
|
|
29
|
+
register_asset(site, package_root, path)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def register_asset(site, package_root, path)
|
|
34
|
+
return unless File.file?(path)
|
|
35
|
+
|
|
36
|
+
relative_path = path.delete_prefix("#{package_root}/")
|
|
37
|
+
return if site.static_files.any? { |file| file.relative_path == relative_path }
|
|
38
|
+
|
|
39
|
+
site.static_files << ::Jekyll::StaticFile.new(
|
|
40
|
+
site,
|
|
41
|
+
package_root,
|
|
42
|
+
File.dirname(relative_path),
|
|
43
|
+
File.basename(relative_path)
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -13,6 +13,9 @@ module Jekyll
|
|
|
13
13
|
# Lines: https://www.svgrepo.com/collection/simple-file-types-line-vectors/
|
|
14
14
|
# Minimal: https://www.svgrepo.com/collection/file-type-minimal-icons/
|
|
15
15
|
# Ultra-minimal: Based on simple document icons
|
|
16
|
+
LINES_ICON_PATH = "/assets/icons/lines/"
|
|
17
|
+
MINIMAL_ICON_PATH = "/assets/icons/minimal/"
|
|
18
|
+
|
|
16
19
|
ICON_MAP = {
|
|
17
20
|
"color" => {
|
|
18
21
|
"pdf" => "/assets/icons/color/pdf-document-svgrepo-com.svg",
|
|
@@ -38,42 +41,59 @@ module Jekyll
|
|
|
38
41
|
"rtf" => "/assets/icons/color/rtf-document-svgrepo-com.svg"
|
|
39
42
|
},
|
|
40
43
|
"lines" => {
|
|
41
|
-
"pdf" => "
|
|
42
|
-
"docx" => "
|
|
43
|
-
"doc" => "
|
|
44
|
-
"pptx" => "
|
|
45
|
-
"ppt" => "
|
|
46
|
-
"xlsx" => "
|
|
47
|
-
"xls" => "
|
|
48
|
-
"odt" => "
|
|
49
|
-
"ods" => "
|
|
50
|
-
"odp" => "
|
|
51
|
-
"txt" => "
|
|
52
|
-
"zip" => "
|
|
53
|
-
"mp3" => "
|
|
54
|
-
"mp4" => "
|
|
55
|
-
"jpg" => "
|
|
56
|
-
"jpeg" => "
|
|
57
|
-
"png" => "
|
|
44
|
+
"pdf" => "#{LINES_ICON_PATH}pdf-file-type-svgrepo-com.svg",
|
|
45
|
+
"docx" => "#{LINES_ICON_PATH}word-file-type-svgrepo-com.svg",
|
|
46
|
+
"doc" => "#{LINES_ICON_PATH}word-file-type-svgrepo-com.svg",
|
|
47
|
+
"pptx" => "#{LINES_ICON_PATH}ppt-file-type-svgrepo-com.svg",
|
|
48
|
+
"ppt" => "#{LINES_ICON_PATH}ppt-file-type-svgrepo-com.svg",
|
|
49
|
+
"xlsx" => "#{LINES_ICON_PATH}excel-file-type-svgrepo-com.svg",
|
|
50
|
+
"xls" => "#{LINES_ICON_PATH}excel-file-type-svgrepo-com.svg",
|
|
51
|
+
"odt" => "#{LINES_ICON_PATH}word-file-type-svgrepo-com.svg",
|
|
52
|
+
"ods" => "#{LINES_ICON_PATH}excel-file-type-svgrepo-com.svg",
|
|
53
|
+
"odp" => "#{LINES_ICON_PATH}ppt-file-type-svgrepo-com.svg",
|
|
54
|
+
"txt" => "#{LINES_ICON_PATH}txt-file-type-svgrepo-com.svg",
|
|
55
|
+
"zip" => "#{LINES_ICON_PATH}zip-file-type-svgrepo-com.svg",
|
|
56
|
+
"mp3" => "#{LINES_ICON_PATH}mp3-file-type-svgrepo-com.svg",
|
|
57
|
+
"mp4" => "#{LINES_ICON_PATH}other-file-type-svgrepo-com.svg",
|
|
58
|
+
"jpg" => "#{LINES_ICON_PATH}jpg-file-type-svgrepo-com.svg",
|
|
59
|
+
"jpeg" => "#{LINES_ICON_PATH}jpg-file-type-svgrepo-com.svg",
|
|
60
|
+
"png" => "#{LINES_ICON_PATH}png-file-type-svgrepo-com.svg"
|
|
58
61
|
},
|
|
59
62
|
"minimal" => {
|
|
60
|
-
"pdf" => "
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
"
|
|
63
|
+
"pdf" => "#{MINIMAL_ICON_PATH}" \
|
|
64
|
+
"extension-file-format-pdf-document-file-format-svgrepo-com.svg",
|
|
65
|
+
"docx" => "#{MINIMAL_ICON_PATH}" \
|
|
66
|
+
"extension-file-format-document-file-format-svgrepo-com.svg",
|
|
67
|
+
"doc" => "#{MINIMAL_ICON_PATH}" \
|
|
68
|
+
"extension-file-format-document-file-format-svgrepo-com.svg",
|
|
69
|
+
"pptx" => "#{MINIMAL_ICON_PATH}" \
|
|
70
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
71
|
+
"ppt" => "#{MINIMAL_ICON_PATH}" \
|
|
72
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
73
|
+
"xlsx" => "#{MINIMAL_ICON_PATH}" \
|
|
74
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
75
|
+
"xls" => "#{MINIMAL_ICON_PATH}" \
|
|
76
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
77
|
+
"odt" => "#{MINIMAL_ICON_PATH}" \
|
|
78
|
+
"extension-file-format-document-file-format-svgrepo-com.svg",
|
|
79
|
+
"ods" => "#{MINIMAL_ICON_PATH}" \
|
|
80
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
81
|
+
"odp" => "#{MINIMAL_ICON_PATH}" \
|
|
82
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
83
|
+
"txt" => "#{MINIMAL_ICON_PATH}" \
|
|
84
|
+
"extension-file-format-txt-document-file-format-svgrepo-com.svg",
|
|
85
|
+
"zip" => "#{MINIMAL_ICON_PATH}" \
|
|
86
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
87
|
+
"mp3" => "#{MINIMAL_ICON_PATH}" \
|
|
88
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
89
|
+
"mp4" => "#{MINIMAL_ICON_PATH}" \
|
|
90
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
91
|
+
"jpg" => "#{MINIMAL_ICON_PATH}" \
|
|
92
|
+
"extension-file-format-jpg-document-file-format-svgrepo-com.svg",
|
|
93
|
+
"jpeg" => "#{MINIMAL_ICON_PATH}" \
|
|
94
|
+
"file-format-jpeg-document-extension-file-format-svgrepo-com.svg",
|
|
95
|
+
"png" => "#{MINIMAL_ICON_PATH}" \
|
|
96
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg"
|
|
77
97
|
},
|
|
78
98
|
"ultra-minimal" => {
|
|
79
99
|
"pdf" => "/assets/icons/ultra-minimal/pdf.svg",
|
|
@@ -95,16 +115,25 @@ module Jekyll
|
|
|
95
115
|
}
|
|
96
116
|
}.freeze
|
|
97
117
|
|
|
118
|
+
UNKNOWN_ICON_MAP = {
|
|
119
|
+
"color" => "/assets/icons/color/unknown-document-svgrepo-com.svg",
|
|
120
|
+
"lines" => "#{LINES_ICON_PATH}other-file-type-svgrepo-com.svg",
|
|
121
|
+
"minimal" => "#{MINIMAL_ICON_PATH}" \
|
|
122
|
+
"extension-file-format-document-file-format-2-svgrepo-com.svg",
|
|
123
|
+
"ultra-minimal" => "/assets/icons/ultra-minimal/file.svg"
|
|
124
|
+
}.freeze
|
|
125
|
+
|
|
98
126
|
# Returns the icon URL for a given file type and explicit icon set
|
|
99
127
|
# @param file_type [String] the file extension (e.g., 'pdf', 'docx')
|
|
100
128
|
# @param icon_set [String] the icon set name (defaults to 'color')
|
|
101
129
|
# @return [String] the icon file URL
|
|
102
130
|
# @example
|
|
103
|
-
# FileTypeIcons.icon_for('pdf', 'lines') #=>
|
|
131
|
+
# FileTypeIcons.icon_for('pdf', 'lines') #=>
|
|
132
|
+
# "/assets/icons/lines/pdf-file-type-svgrepo-com.svg"
|
|
104
133
|
def self.icon_for(file_type, icon_set = "color")
|
|
105
|
-
|
|
106
|
-
icons[
|
|
107
|
-
|
|
134
|
+
selected_set = ICON_MAP.key?(icon_set) ? icon_set : "color"
|
|
135
|
+
icons = ICON_MAP[selected_set]
|
|
136
|
+
icons[file_type.to_s.downcase] || UNKNOWN_ICON_MAP[selected_set]
|
|
108
137
|
end
|
|
109
138
|
|
|
110
139
|
# Returns the icon URL for a given file type using configured icon set
|
|
@@ -58,7 +58,7 @@ module Jekyll
|
|
|
58
58
|
data = doc.data
|
|
59
59
|
data["layout"] = @config["layout"]
|
|
60
60
|
data["title"] = title
|
|
61
|
-
data["date"] = date
|
|
61
|
+
data["date"] = date ? date.to_time : File.mtime(path)
|
|
62
62
|
data["category"] = remap_category(category)
|
|
63
63
|
data["file_url"] = "/#{rel_path}"
|
|
64
64
|
data["extension"] = ext
|
|
@@ -25,7 +25,8 @@ module Jekyll
|
|
|
25
25
|
"date" => (data["date"] || Time.at(0)).strftime("%Y-%m-%d"),
|
|
26
26
|
"slug" => data["slug"],
|
|
27
27
|
"file_type" => data["file_type"],
|
|
28
|
-
"extension" => data["extension"]
|
|
28
|
+
"extension" => data["extension"],
|
|
29
|
+
"icon_url" => data["icon_url"]
|
|
29
30
|
}
|
|
30
31
|
end
|
|
31
32
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module Jekyll
|
|
6
|
+
module Documents
|
|
7
|
+
# Registers gem-packaged _layouts and _includes with the site so Jekyll can
|
|
8
|
+
# discover them without the gem being declared as a theme.
|
|
9
|
+
#
|
|
10
|
+
# Jekyll only auto-discovers _layouts and _includes from theme gems (set via
|
|
11
|
+
# the +theme:+ config key). Plugin gems loaded via +group :jekyll_plugins+
|
|
12
|
+
# do not get their template directories added to Jekyll's lookup paths.
|
|
13
|
+
#
|
|
14
|
+
# This hook copies any gem-packaged layouts and includes into the site's
|
|
15
|
+
# source directories when the user has not provided their own. Files already
|
|
16
|
+
# present in the site take precedence (user overrides are never clobbered).
|
|
17
|
+
module LayoutRegistrar
|
|
18
|
+
GEM_ROOT = File.expand_path("../../..", __dir__)
|
|
19
|
+
TEMPLATE_DIRS = %w[_layouts _includes].freeze
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
# Copies gem-packaged template files into the site source.
|
|
23
|
+
# @param site [Jekyll::Site] the Jekyll site instance
|
|
24
|
+
# @return [void]
|
|
25
|
+
def register(site)
|
|
26
|
+
TEMPLATE_DIRS.each do |dir|
|
|
27
|
+
gem_dir = File.join(GEM_ROOT, dir)
|
|
28
|
+
next unless Dir.exist?(gem_dir)
|
|
29
|
+
|
|
30
|
+
copy_templates(gem_dir, File.join(site.source, dir))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# Recursively copies files from +source_dir+ to +dest_dir+, skipping any
|
|
37
|
+
# file that already exists in the destination (user overrides win).
|
|
38
|
+
# @param source_dir [String] gem template directory
|
|
39
|
+
# @param dest_dir [String] site template directory
|
|
40
|
+
# @return [void]
|
|
41
|
+
def copy_templates(source_dir, dest_dir)
|
|
42
|
+
Dir.glob(File.join(source_dir, "**", "*")).each do |path|
|
|
43
|
+
next unless File.file?(path)
|
|
44
|
+
|
|
45
|
+
relative = path.delete_prefix("#{source_dir}/")
|
|
46
|
+
destination = File.join(dest_dir, relative)
|
|
47
|
+
next if File.exist?(destination)
|
|
48
|
+
|
|
49
|
+
FileUtils.mkdir_p(File.dirname(destination))
|
|
50
|
+
FileUtils.cp(path, destination)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Jekyll::Hooks.register :site, :after_init do |site|
|
|
59
|
+
Jekyll::Documents::LayoutRegistrar.register(site)
|
|
60
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module Documents
|
|
5
|
+
class DocumentIconTag < Liquid::Tag
|
|
6
|
+
public_class_method :new
|
|
7
|
+
|
|
8
|
+
include Jekyll::Filters::URLFilters
|
|
9
|
+
|
|
10
|
+
def initialize(tag_name, markup, tokens)
|
|
11
|
+
super
|
|
12
|
+
@document_expression, @options = parse_markup(markup)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def render(context)
|
|
16
|
+
document = context.find_variable(@document_expression)
|
|
17
|
+
return "" unless document
|
|
18
|
+
|
|
19
|
+
@context = context
|
|
20
|
+
icon_url = document_value(document, "icon_url") || fallback_icon(document, context)
|
|
21
|
+
url = relative_url(icon_url)
|
|
22
|
+
file_type = document_value(document, "file_type").to_s
|
|
23
|
+
alt = @options["alt"] || "#{file_type.upcase} file"
|
|
24
|
+
css_class = @options["class"] || "file-icon"
|
|
25
|
+
|
|
26
|
+
%(<img src="#{escape_html(url)}" alt="#{escape_html(alt)}" ) \
|
|
27
|
+
+ %(class="#{escape_html(css_class)}" />)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def document_value(document, key)
|
|
33
|
+
return document.data[key] if document.respond_to?(:data)
|
|
34
|
+
return document[key] if document.respond_to?(:[])
|
|
35
|
+
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def fallback_icon(document, context)
|
|
40
|
+
file_type = document_value(document, "file_type")
|
|
41
|
+
icon_set = Configuration.read(context.registers[:site])["icon_set"]
|
|
42
|
+
FileTypeIcons.icon_for(file_type, icon_set)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def parse_markup(markup)
|
|
46
|
+
expression = markup.to_s.strip[/\A[^\s]+/]
|
|
47
|
+
options = {}
|
|
48
|
+
markup.to_s.scan(
|
|
49
|
+
/(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|([^\s]+))/
|
|
50
|
+
) do |key, single, double, bare|
|
|
51
|
+
options[key] = single || double || bare
|
|
52
|
+
end
|
|
53
|
+
[expression, options]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def escape_html(value)
|
|
57
|
+
value.to_s.gsub(/[&<>"']/,
|
|
58
|
+
"&" => "&",
|
|
59
|
+
"<" => "<",
|
|
60
|
+
">" => ">",
|
|
61
|
+
'"' => """,
|
|
62
|
+
"'" => "'")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
Liquid::Template.register_tag("document_icon", Jekyll::Documents::DocumentIconTag)
|
data/lib/jekyll-documents.rb
CHANGED
|
@@ -7,10 +7,13 @@ require_relative "jekyll/documents/utils"
|
|
|
7
7
|
require_relative "jekyll/documents/filters"
|
|
8
8
|
require_relative "jekyll/documents/file_type_icons"
|
|
9
9
|
require_relative "jekyll/documents/generator"
|
|
10
|
+
require_relative "jekyll/documents/assets_generator"
|
|
10
11
|
require_relative "jekyll/documents/json_index_generator"
|
|
12
|
+
require_relative "jekyll/documents/layout_registrar"
|
|
11
13
|
|
|
12
14
|
# Liquid tag(s)
|
|
13
15
|
require_relative "jekyll/documents/tags/latest_documents"
|
|
16
|
+
require_relative "jekyll/documents/tags/document_icon"
|
|
14
17
|
|
|
15
18
|
module Jekyll
|
|
16
19
|
module Documents
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-documents
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Svend Gundestrup
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jekyll
|
|
@@ -16,14 +16,20 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '4.
|
|
19
|
+
version: '4.4'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '5.0'
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
27
|
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '4.
|
|
29
|
+
version: '4.4'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '5.0'
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: bundler-audit
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -58,56 +64,56 @@ dependencies:
|
|
|
58
64
|
requirements:
|
|
59
65
|
- - "~>"
|
|
60
66
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '6.
|
|
67
|
+
version: '6.5'
|
|
62
68
|
type: :development
|
|
63
69
|
prerelease: false
|
|
64
70
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
71
|
requirements:
|
|
66
72
|
- - "~>"
|
|
67
73
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '6.
|
|
74
|
+
version: '6.5'
|
|
69
75
|
- !ruby/object:Gem::Dependency
|
|
70
76
|
name: rspec
|
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
|
72
78
|
requirements:
|
|
73
79
|
- - "~>"
|
|
74
80
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '3.
|
|
81
|
+
version: '3.13'
|
|
76
82
|
type: :development
|
|
77
83
|
prerelease: false
|
|
78
84
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
85
|
requirements:
|
|
80
86
|
- - "~>"
|
|
81
87
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '3.
|
|
88
|
+
version: '3.13'
|
|
83
89
|
- !ruby/object:Gem::Dependency
|
|
84
90
|
name: rubocop
|
|
85
91
|
requirement: !ruby/object:Gem::Requirement
|
|
86
92
|
requirements:
|
|
87
93
|
- - "~>"
|
|
88
94
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '1.
|
|
95
|
+
version: '1.88'
|
|
90
96
|
type: :development
|
|
91
97
|
prerelease: false
|
|
92
98
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
99
|
requirements:
|
|
94
100
|
- - "~>"
|
|
95
101
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '1.
|
|
102
|
+
version: '1.88'
|
|
97
103
|
- !ruby/object:Gem::Dependency
|
|
98
104
|
name: rubocop-performance
|
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|
|
100
106
|
requirements:
|
|
101
107
|
- - "~>"
|
|
102
108
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '1.
|
|
109
|
+
version: '1.26'
|
|
104
110
|
type: :development
|
|
105
111
|
prerelease: false
|
|
106
112
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
113
|
requirements:
|
|
108
114
|
- - "~>"
|
|
109
115
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '1.
|
|
116
|
+
version: '1.26'
|
|
111
117
|
- !ruby/object:Gem::Dependency
|
|
112
118
|
name: simplecov
|
|
113
119
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -253,11 +259,14 @@ files:
|
|
|
253
259
|
- assets/js/documents-search.js
|
|
254
260
|
- jekyll-documents.gemspec
|
|
255
261
|
- lib/jekyll-documents.rb
|
|
262
|
+
- lib/jekyll/documents/assets_generator.rb
|
|
256
263
|
- lib/jekyll/documents/configuration.rb
|
|
257
264
|
- lib/jekyll/documents/file_type_icons.rb
|
|
258
265
|
- lib/jekyll/documents/filters.rb
|
|
259
266
|
- lib/jekyll/documents/generator.rb
|
|
260
267
|
- lib/jekyll/documents/json_index_generator.rb
|
|
268
|
+
- lib/jekyll/documents/layout_registrar.rb
|
|
269
|
+
- lib/jekyll/documents/tags/document_icon.rb
|
|
261
270
|
- lib/jekyll/documents/tags/latest_documents.rb
|
|
262
271
|
- lib/jekyll/documents/utils.rb
|
|
263
272
|
- lib/jekyll/documents/version.rb
|
|
@@ -279,14 +288,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
279
288
|
requirements:
|
|
280
289
|
- - ">="
|
|
281
290
|
- !ruby/object:Gem::Version
|
|
282
|
-
version: '3.
|
|
291
|
+
version: '3.3'
|
|
283
292
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
284
293
|
requirements:
|
|
285
294
|
- - ">="
|
|
286
295
|
- !ruby/object:Gem::Version
|
|
287
296
|
version: '0'
|
|
288
297
|
requirements: []
|
|
289
|
-
rubygems_version: 3.
|
|
298
|
+
rubygems_version: 3.5.22
|
|
290
299
|
signing_key:
|
|
291
300
|
specification_version: 4
|
|
292
301
|
summary: Auto-generate Jekyll pages for documents (PDF/DOCX/...) with category/date/title
|