jekyll-documents 0.1.1

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.
Files changed (117) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +42 -0
  3. data/LICENSE +661 -0
  4. data/README.md +126 -0
  5. data/_includes/category_list.html +10 -0
  6. data/_includes/documents_list.html +10 -0
  7. data/_includes/documents_search.html +4 -0
  8. data/_includes/latest_documents.html +11 -0
  9. data/_layouts/document.html +20 -0
  10. data/assets/icons/color/ai-document-svgrepo-com.svg +2 -0
  11. data/assets/icons/color/attachment-document-svgrepo-com.svg +10 -0
  12. data/assets/icons/color/audio-document-svgrepo-com.svg +10 -0
  13. data/assets/icons/color/box-notes-svgrepo-com.svg +21 -0
  14. data/assets/icons/color/csv-document-svgrepo-com.svg +10 -0
  15. data/assets/icons/color/eps-document-svgrepo-com.svg +10 -0
  16. data/assets/icons/color/excel-document-svgrepo-com.svg +2 -0
  17. data/assets/icons/color/exe-document-svgrepo-com.svg +10 -0
  18. data/assets/icons/color/flash-document-svgrepo-com.svg +10 -0
  19. data/assets/icons/color/folder-svgrepo-com.svg +2 -0
  20. data/assets/icons/color/gdoc-document-svgrepo-com.svg +10 -0
  21. data/assets/icons/color/gdocs-document-svgrepo-com.svg +12 -0
  22. data/assets/icons/color/gform-document-svgrepo-com.svg +16 -0
  23. data/assets/icons/color/gpres-document-svgrepo-com.svg +10 -0
  24. data/assets/icons/color/gsheet-document-svgrepo-com.svg +10 -0
  25. data/assets/icons/color/html-document-svgrepo-com.svg +10 -0
  26. data/assets/icons/color/image-document-svgrepo-com.svg +10 -0
  27. data/assets/icons/color/keynote-document-svgrepo-com.svg +10 -0
  28. data/assets/icons/color/library-folder-svgrepo-com.svg +19 -0
  29. data/assets/icons/color/link-svgrepo-com.svg +10 -0
  30. data/assets/icons/color/mp4-document-svgrepo-com.svg +10 -0
  31. data/assets/icons/color/overlay-document-svgrepo-com.svg +11 -0
  32. data/assets/icons/color/pack-document-svgrepo-com.svg +10 -0
  33. data/assets/icons/color/pages-document-svgrepo-com.svg +10 -0
  34. data/assets/icons/color/pdf-document-svgrepo-com.svg +16 -0
  35. data/assets/icons/color/ppt-document-svgrepo-com.svg +10 -0
  36. data/assets/icons/color/psd-document-svgrepo-com.svg +10 -0
  37. data/assets/icons/color/quip-doc-svgrepo-com.svg +21 -0
  38. data/assets/icons/color/quip-sheet-document-svgrepo-com.svg +21 -0
  39. data/assets/icons/color/quip-slide-document-svgrepo-com.svg +21 -0
  40. data/assets/icons/color/rtf-document-svgrepo-com.svg +10 -0
  41. data/assets/icons/color/slide-document-svgrepo-com.svg +2 -0
  42. data/assets/icons/color/stypi-document-svgrepo-com.svg +11 -0
  43. data/assets/icons/color/txt-document-svgrepo-com.svg +10 -0
  44. data/assets/icons/color/unknown-document-svgrepo-com.svg +9 -0
  45. data/assets/icons/color/video-document-svgrepo-com.svg +10 -0
  46. data/assets/icons/color/visio-document-svgrepo-com.svg +10 -0
  47. data/assets/icons/color/webex-document-svgrepo-com.svg +11 -0
  48. data/assets/icons/color/word-document-svgrepo-com.svg +10 -0
  49. data/assets/icons/color/xml-document-svgrepo-com.svg +10 -0
  50. data/assets/icons/color/zip-document-svgrepo-com.svg +10 -0
  51. data/assets/icons/lines/ae-file-type-svgrepo-com.svg +18 -0
  52. data/assets/icons/lines/ai-file-type-svgrepo-com.svg +18 -0
  53. data/assets/icons/lines/avi-file-type-svgrepo-com.svg +19 -0
  54. data/assets/icons/lines/css-file-type-svgrepo-com.svg +19 -0
  55. data/assets/icons/lines/csv-file-type-svgrepo-com (1).svg +19 -0
  56. data/assets/icons/lines/eps-file-type-svgrepo-com.svg +19 -0
  57. data/assets/icons/lines/excel-file-type-svgrepo-com.svg +21 -0
  58. data/assets/icons/lines/file-file-type-svgrepo-com.svg +16 -0
  59. data/assets/icons/lines/folder-svgrepo-com.svg +3 -0
  60. data/assets/icons/lines/html-file-type-svgrepo-com.svg +20 -0
  61. data/assets/icons/lines/jpg-file-type-svgrepo-com.svg +19 -0
  62. data/assets/icons/lines/mov-file-type-svgrepo-com.svg +19 -0
  63. data/assets/icons/lines/mp3-file-type-svgrepo-com.svg +19 -0
  64. data/assets/icons/lines/other-file-type-svgrepo-com.svg +17 -0
  65. data/assets/icons/lines/pdf-file-type-svgrepo-com.svg +19 -0
  66. data/assets/icons/lines/png-file-type-svgrepo-com.svg +19 -0
  67. data/assets/icons/lines/ppt-file-type-svgrepo-com.svg +19 -0
  68. data/assets/icons/lines/psd-file-type-svgrepo-com.svg +19 -0
  69. data/assets/icons/lines/rar-file-type-svgrepo-com.svg +19 -0
  70. data/assets/icons/lines/txt-file-type-svgrepo-com.svg +19 -0
  71. data/assets/icons/lines/wav-file-type-svgrepo-com.svg +19 -0
  72. data/assets/icons/lines/word-file-type-svgrepo-com.svg +20 -0
  73. data/assets/icons/lines/zip-file-type-svgrepo-com.svg +19 -0
  74. data/assets/icons/minimal/c-file-format-document-extension-file-format-2-svgrepo-com.svg +7 -0
  75. data/assets/icons/minimal/c-file-format-document-extension-file-format-svgrepo-com.svg +7 -0
  76. data/assets/icons/minimal/css-file-format-document-extension-file-format-svgrepo-com.svg +7 -0
  77. data/assets/icons/minimal/dwg-file-format-document-extension-file-format-svgrepo-com.svg +7 -0
  78. data/assets/icons/minimal/dxf-file-format-document-extension-file-format-svgrepo-com.svg +7 -0
  79. data/assets/icons/minimal/extension-file-format-document-file-format-2-svgrepo-com.svg +7 -0
  80. data/assets/icons/minimal/extension-file-format-document-file-format-svgrepo-com.svg +7 -0
  81. data/assets/icons/minimal/extension-file-format-html-document-file-format-svgrepo-com.svg +7 -0
  82. data/assets/icons/minimal/extension-file-format-jpg-document-file-format-svgrepo-com.svg +7 -0
  83. data/assets/icons/minimal/extension-file-format-json-document-file-format-svgrepo-com (1).svg +7 -0
  84. data/assets/icons/minimal/extension-file-format-pdf-document-file-format-svgrepo-com.svg +7 -0
  85. data/assets/icons/minimal/extension-file-format-php-document-file-format-svgrepo-com.svg +7 -0
  86. data/assets/icons/minimal/extension-file-format-sql-document-file-format-svgrepo-com.svg +7 -0
  87. data/assets/icons/minimal/extension-file-format-txt-document-file-format-svgrepo-com.svg +7 -0
  88. data/assets/icons/minimal/file-format-gif-document-extension-file-format-svgrepo-com.svg +7 -0
  89. data/assets/icons/minimal/file-format-jpeg-document-extension-file-format-svgrepo-com.svg +7 -0
  90. data/assets/icons/minimal/file-format-js-document-extension-file-format-svgrepo-com.svg +7 -0
  91. data/assets/icons/minimal/file-format-vb-document-extension-file-format-svgrepo-com.svg +7 -0
  92. data/assets/icons/minimal/folder-svgrepo-com.svg +3 -0
  93. data/assets/icons/minimal/ico-file-format-svgrepo-com.svg +7 -0
  94. data/assets/icons/ultra-minimal/doc.svg +7 -0
  95. data/assets/icons/ultra-minimal/file.svg +4 -0
  96. data/assets/icons/ultra-minimal/folder-svgrepo-com.svg +3 -0
  97. data/assets/icons/ultra-minimal/jpg.svg +6 -0
  98. data/assets/icons/ultra-minimal/mp3.svg +5 -0
  99. data/assets/icons/ultra-minimal/mp4.svg +5 -0
  100. data/assets/icons/ultra-minimal/pdf.svg +7 -0
  101. data/assets/icons/ultra-minimal/png.svg +5 -0
  102. data/assets/icons/ultra-minimal/ppt.svg +5 -0
  103. data/assets/icons/ultra-minimal/txt.svg +7 -0
  104. data/assets/icons/ultra-minimal/xls.svg +6 -0
  105. data/assets/icons/ultra-minimal/zip.svg +5 -0
  106. data/assets/js/documents-search.js +139 -0
  107. data/jekyll-documents.gemspec +27 -0
  108. data/lib/jekyll/documents/configuration.rb +37 -0
  109. data/lib/jekyll/documents/file_type_icons.rb +144 -0
  110. data/lib/jekyll/documents/filters.rb +34 -0
  111. data/lib/jekyll/documents/generator.rb +142 -0
  112. data/lib/jekyll/documents/json_index_generator.rb +38 -0
  113. data/lib/jekyll/documents/tags/latest_documents.rb +64 -0
  114. data/lib/jekyll/documents/utils.rb +27 -0
  115. data/lib/jekyll/documents/version.rb +7 -0
  116. data/lib/jekyll-documents.rb +19 -0
  117. metadata +215 -0
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" ?>
2
+
3
+ <svg width="800px" height="800px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg">
4
+
5
+
6
+
7
+
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" ?>
2
+
3
+ <svg width="800px" height="800px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg">
4
+
5
+
6
+
7
+
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
2
+ <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
3
+ </svg>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" ?>
2
+
3
+ <svg width="800px" height="800px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg">
4
+
5
+
6
+
7
+
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <line x1="16" y1="13" x2="8" y2="13"/>
5
+ <line x1="16" y1="17" x2="8" y2="17"/>
6
+ <polyline points="10,9 9,9 8,9"/>
7
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
3
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <circle cx="10" cy="15" r="2"/>
5
+ <path d="M16 13l-4 4"/>
6
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <polygon points="10,13 10,17 13,15 16,17 16,13 13,15"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <polygon points="10,13 10,17 14,15 18,17 18,13 14,15"/>
5
+ </svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <line x1="16" y1="13" x2="8" y2="13"/>
5
+ <line x1="16" y1="17" x2="8" y2="17"/>
6
+ <polyline points="10,9 9,9 8,9"/>
7
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <rect x="8" y="12" width="8" height="6" rx="1"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <rect x="8" y="13" width="8" height="6"/>
5
+ </svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <line x1="16" y1="13" x2="8" y2="13"/>
5
+ <line x1="16" y1="17" x2="8" y2="17"/>
6
+ <polyline points="10,9 9,9 8,9"/>
7
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <line x1="8" y1="15" x2="16" y2="15"/>
5
+ <line x1="8" y1="11" x2="16" y2="11"/>
6
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
3
+ <polyline points="14,2 14,8 20,8"/>
4
+ <path d="M10 13v4M8 15h4"/>
5
+ </svg>
@@ -0,0 +1,139 @@
1
+ /* Minimal client-side search using Lunr and /documents.json (generated by the plugin).
2
+ Usage on any page:
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
+ */
7
+ (function () {
8
+ const input = document.getElementById("doc-search-input");
9
+ const resultsEl = document.getElementById("doc-search-results");
10
+ if (!input || !resultsEl) return;
11
+
12
+ const indexUrl = (window.__jekyllDocumentsIndexPath || "/documents.json");
13
+ let idx, docs = [];
14
+
15
+ function escapeHtml(s) {
16
+ const div = document.createElement("div");
17
+ div.appendChild(document.createTextNode(s));
18
+ return div.innerHTML;
19
+ }
20
+
21
+ function getIconPath(fileType, iconSet) {
22
+ iconSet = iconSet || "color";
23
+ const iconMap = {
24
+ "color": {
25
+ "pdf": "/assets/icons/color/pdf-document-svgrepo-com.svg",
26
+ "docx": "/assets/icons/color/word-document-svgrepo-com.svg",
27
+ "doc": "/assets/icons/color/word-document-svgrepo-com.svg",
28
+ "pptx": "/assets/icons/color/ppt-document-svgrepo-com.svg",
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`;
71
+ }
72
+
73
+ function getIconTag(fileType) {
74
+ const iconSet = window.__jekyllDocumentsIconSet || "color";
75
+ const iconPath = getIconPath(fileType, iconSet);
76
+ const altText = (fileType || "file").toUpperCase() + " file";
77
+ return `<img src="${iconPath}" alt="${escapeHtml(altText)}" class="file-icon" />`;
78
+ }
79
+
80
+ function render(matches) {
81
+ if (!matches || matches.length === 0) {
82
+ resultsEl.innerHTML = "<p>No results.</p>";
83
+ return;
84
+ }
85
+ const items = matches.slice(0, 20).map(m => {
86
+ const d = docs.find(x => x.url === m.ref);
87
+ if (!d) return "";
88
+ const title = escapeHtml(d.title || "Untitled");
89
+ const category = escapeHtml(d.category || "uncategorized");
90
+ const date = d.date ? `<small>${escapeHtml(d.date)}</small>` : "";
91
+ const icon = d.file_type ? getIconTag(d.file_type) : "";
92
+ return `<li>${icon}<a href="${d.url}">${title}</a> <small>[${category}]</small> ${date}</li>`;
93
+ });
94
+ resultsEl.innerHTML = `<ul class="documents-search-list">${items.join("")}</ul>`;
95
+ }
96
+
97
+ function debounce(fn, wait) {
98
+ let t; return function (...args) {
99
+ clearTimeout(t); t = setTimeout(() => fn.apply(this, args), wait);
100
+ };
101
+ }
102
+
103
+ function buildIndex() {
104
+ idx = lunr(function () {
105
+ this.ref("url");
106
+ this.field("title", { boost: 10 });
107
+ this.field("category", { boost: 5 });
108
+ this.field("slug");
109
+ docs.forEach(doc => this.add(doc));
110
+ });
111
+ }
112
+
113
+ function doSearch(q) {
114
+ if (!idx || !q || q.trim().length === 0) {
115
+ resultsEl.innerHTML = "";
116
+ return;
117
+ }
118
+ try {
119
+ const res = idx.search(q);
120
+ render(res);
121
+ } catch (e) {
122
+ // If Lunr query syntax fails, fallback to simple contains filter
123
+ const qlc = q.toLowerCase();
124
+ const res = docs.filter(d =>
125
+ (d.title || "").toLowerCase().includes(qlc) ||
126
+ (d.category || "").toLowerCase().includes(qlc) ||
127
+ (d.slug || "").toLowerCase().includes(qlc)
128
+ ).map(d => ({ ref: d.url }));
129
+ render(res);
130
+ }
131
+ }
132
+
133
+ fetch(indexUrl)
134
+ .then(r => r.json())
135
+ .then(json => { docs = json; buildIndex(); })
136
+ .catch(err => { console.error("Documents search index failed:", err); });
137
+
138
+ input.addEventListener("input", debounce(e => doSearch(e.target.value), 150));
139
+ })();
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "jekyll-documents"
5
+ spec.version = File.read(File.expand_path("lib/jekyll/documents/version.rb", __dir__))
6
+ .match(/VERSION\s*=\s*"([^"]+)"/)[1]
7
+ spec.authors = ["Svend Gundestrup"]
8
+ spec.email = ["no-reply@borg-collective.eu"]
9
+
10
+ spec.summary = "Auto-generate Jekyll pages for documents (PDF/DOCX/...) with category/date/title parsing."
11
+ spec.description = "A Jekyll plugin + theme that scans assets/documents/**, creates a collection item per file, " \
12
+ "adds metadata (title/date/category), outputs pages, generates a JSON index for Lunr, and integrates with jekyll-sitemap."
13
+ spec.homepage = "https://github.com/gundestrup/jekyll-documents"
14
+ spec.license = "AGPL-3.0-only"
15
+
16
+ spec.required_ruby_version = ">= 2.7"
17
+
18
+ spec.files = Dir.glob("{lib,assets,_includes,_layouts}/**/*") +
19
+ ["README.md", "CHANGELOG.md", "LICENSE", "jekyll-documents.gemspec"]
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "jekyll", ">= 4.0"
23
+
24
+ spec.add_development_dependency "rspec", "~> 3.12"
25
+ spec.add_development_dependency "rake", "~> 13.0"
26
+ spec.add_development_dependency "yard", "~> 0.9"
27
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Documents
5
+ class Configuration
6
+ DEFAULTS = {
7
+ "root" => "assets/documents",
8
+ "permalink" => "/documents/:category/:slug/",
9
+ "slug_downcase" => true,
10
+ "slug_danish_map" => true,
11
+ "categories_from_path" => true,
12
+ "include_extensions" => %w[.pdf .docx .pptx .xlsx .odt .ods .odp],
13
+ "layout" => "document",
14
+ "latest_default_count" => 5,
15
+
16
+ # Icon configuration
17
+ "icon_set" => "color",
18
+
19
+ # Validation
20
+ "strict_filename" => true,
21
+ "strict_extensions" => true,
22
+
23
+ # JSON Index for Lunr
24
+ "json_index" => true,
25
+ "json_index_path" => "/documents.json",
26
+
27
+ # Optional category mapping
28
+ "category_map" => {}
29
+ }.freeze
30
+
31
+ def self.read(site)
32
+ cfg = site.config["documents"] || {}
33
+ DEFAULTS.merge(cfg)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Documents
5
+ # Maps file extensions to local SVG icon files with configurable icon sets
6
+ # Provides Liquid filters for displaying file type icons
7
+ # Icons are based on designs from svgrepo.com and included in the gem
8
+ # @api public
9
+ module FileTypeIcons
10
+ # Mapping of file extensions to icon files for each icon set
11
+ # Icons sourced from svgrepo.com collections:
12
+ # Color: https://www.svgrepo.com/collection/file-type-doctype-vectors/
13
+ # Lines: https://www.svgrepo.com/collection/simple-file-types-line-vectors/
14
+ # Minimal: https://www.svgrepo.com/collection/file-type-minimal-icons/
15
+ # Ultra-minimal: Based on simple document icons
16
+ ICON_MAP = {
17
+ "color" => {
18
+ "pdf" => "/assets/icons/color/pdf-document-svgrepo-com.svg",
19
+ "docx" => "/assets/icons/color/word-document-svgrepo-com.svg",
20
+ "doc" => "/assets/icons/color/word-document-svgrepo-com.svg",
21
+ "pptx" => "/assets/icons/color/ppt-document-svgrepo-com.svg",
22
+ "ppt" => "/assets/icons/color/ppt-document-svgrepo-com.svg",
23
+ "xlsx" => "/assets/icons/color/excel-document-svgrepo-com.svg",
24
+ "xls" => "/assets/icons/color/excel-document-svgrepo-com.svg",
25
+ "odt" => "/assets/icons/color/word-document-svgrepo-com.svg",
26
+ "ods" => "/assets/icons/color/excel-document-svgrepo-com.svg",
27
+ "odp" => "/assets/icons/color/ppt-document-svgrepo-com.svg",
28
+ "txt" => "/assets/icons/color/txt-document-svgrepo-com.svg",
29
+ "zip" => "/assets/icons/color/zip-document-svgrepo-com.svg",
30
+ "mp3" => "/assets/icons/color/audio-document-svgrepo-com.svg",
31
+ "mp4" => "/assets/icons/color/mp4-document-svgrepo-com.svg",
32
+ "jpg" => "/assets/icons/color/image-document-svgrepo-com.svg",
33
+ "jpeg" => "/assets/icons/color/image-document-svgrepo-com.svg",
34
+ "png" => "/assets/icons/color/image-document-svgrepo-com.svg",
35
+ "csv" => "/assets/icons/color/csv-document-svgrepo-com.svg",
36
+ "html" => "/assets/icons/color/html-document-svgrepo-com.svg",
37
+ "xml" => "/assets/icons/color/xml-document-svgrepo-com.svg",
38
+ "rtf" => "/assets/icons/color/rtf-document-svgrepo-com.svg"
39
+ },
40
+ "lines" => {
41
+ "pdf" => "/assets/icons/lines/pdf-svgrepo-com.svg",
42
+ "docx" => "/assets/icons/lines/doc-svgrepo-com.svg",
43
+ "doc" => "/assets/icons/lines/doc-svgrepo-com.svg",
44
+ "pptx" => "/assets/icons/lines/ppt-svgrepo-com.svg",
45
+ "ppt" => "/assets/icons/lines/ppt-svgrepo-com.svg",
46
+ "xlsx" => "/assets/icons/lines/xls-svgrepo-com.svg",
47
+ "xls" => "/assets/icons/lines/xls-svgrepo-com.svg",
48
+ "odt" => "/assets/icons/lines/doc-svgrepo-com.svg",
49
+ "ods" => "/assets/icons/lines/xls-svgrepo-com.svg",
50
+ "odp" => "/assets/icons/lines/ppt-svgrepo-com.svg",
51
+ "txt" => "/assets/icons/lines/txt-svgrepo-com.svg",
52
+ "zip" => "/assets/icons/lines/zip-svgrepo-com.svg",
53
+ "mp3" => "/assets/icons/lines/mp3-svgrepo-com.svg",
54
+ "mp4" => "/assets/icons/lines/mp4-svgrepo-com.svg",
55
+ "jpg" => "/assets/icons/lines/jpg-svgrepo-com.svg",
56
+ "jpeg" => "/assets/icons/lines/jpg-svgrepo-com.svg",
57
+ "png" => "/assets/icons/lines/png-svgrepo-com.svg"
58
+ },
59
+ "minimal" => {
60
+ "pdf" => "/assets/icons/minimal/pdf-svgrepo-com.svg",
61
+ "docx" => "/assets/icons/minimal/doc-svgrepo-com.svg",
62
+ "doc" => "/assets/icons/minimal/doc-svgrepo-com.svg",
63
+ "pptx" => "/assets/icons/minimal/ppt-svgrepo-com.svg",
64
+ "ppt" => "/assets/icons/minimal/ppt-svgrepo-com.svg",
65
+ "xlsx" => "/assets/icons/minimal/xls-svgrepo-com.svg",
66
+ "xls" => "/assets/icons/minimal/xls-svgrepo-com.svg",
67
+ "odt" => "/assets/icons/minimal/doc-svgrepo-com.svg",
68
+ "ods" => "/assets/icons/minimal/xls-svgrepo-com.svg",
69
+ "odp" => "/assets/icons/minimal/ppt-svgrepo-com.svg",
70
+ "txt" => "/assets/icons/minimal/txt-svgrepo-com.svg",
71
+ "zip" => "/assets/icons/minimal/zip-svgrepo-com.svg",
72
+ "mp3" => "/assets/icons/minimal/mp3-svgrepo-com.svg",
73
+ "mp4" => "/assets/icons/minimal/mp4-svgrepo-com.svg",
74
+ "jpg" => "/assets/icons/minimal/jpg-svgrepo-com.svg",
75
+ "jpeg" => "/assets/icons/minimal/jpg-svgrepo-com.svg",
76
+ "png" => "/assets/icons/minimal/png-svgrepo-com.svg"
77
+ },
78
+ "ultra-minimal" => {
79
+ "pdf" => "/assets/icons/ultra-minimal/pdf.svg",
80
+ "docx" => "/assets/icons/ultra-minimal/doc.svg",
81
+ "doc" => "/assets/icons/ultra-minimal/doc.svg",
82
+ "pptx" => "/assets/icons/ultra-minimal/ppt.svg",
83
+ "ppt" => "/assets/icons/ultra-minimal/ppt.svg",
84
+ "xlsx" => "/assets/icons/ultra-minimal/xls.svg",
85
+ "xls" => "/assets/icons/ultra-minimal/xls.svg",
86
+ "odt" => "/assets/icons/ultra-minimal/doc.svg",
87
+ "ods" => "/assets/icons/ultra-minimal/xls.svg",
88
+ "odp" => "/assets/icons/ultra-minimal/ppt.svg",
89
+ "txt" => "/assets/icons/ultra-minimal/txt.svg",
90
+ "zip" => "/assets/icons/ultra-minimal/zip.svg",
91
+ "mp3" => "/assets/icons/ultra-minimal/mp3.svg",
92
+ "mp4" => "/assets/icons/ultra-minimal/mp4.svg",
93
+ "jpg" => "/assets/icons/ultra-minimal/jpg.svg",
94
+ "png" => "/assets/icons/ultra-minimal/png.svg"
95
+ }
96
+ }.freeze
97
+
98
+ # Returns the icon URL for a given file type using configured icon set
99
+ # @param file_type [String] the file extension (e.g., 'pdf', 'docx')
100
+ # @param context [Liquid::Context] the Liquid context for accessing site config
101
+ # @return [String] the icon file URL
102
+ # @example
103
+ # file_type_icon('pdf') #=> "/assets/icons/color/pdf.svg"
104
+ def file_type_icon(file_type, context = nil)
105
+ icon_set = get_icon_set(context)
106
+ icons = ICON_MAP[icon_set] || ICON_MAP["color"]
107
+ icons[file_type.to_s.downcase] || "/assets/icons/#{icon_set}/unknown-document-svgrepo-com.svg"
108
+ end
109
+
110
+ # Returns an HTML img tag for the file type icon
111
+ # @param file_type [String] the file extension
112
+ # @param css_class [String] CSS class for the img tag (default: 'file-icon')
113
+ # @param alt [String, nil] alt text for the image (default: auto-generated)
114
+ # @param context [Liquid::Context] the Liquid context for accessing site config
115
+ # @return [String] HTML img tag
116
+ # @example
117
+ # file_type_icon_tag('pdf') #=> '<img src="/assets/icons/color/pdf.svg" alt="PDF file" class="file-icon" />'
118
+ def file_type_icon_tag(file_type, css_class: "file-icon", alt: nil, context: nil)
119
+ url = file_type_icon(file_type, context)
120
+ alt_text = alt || "#{file_type.upcase} file"
121
+ %(<img src="#{url}" alt="#{alt_text}" class="#{css_class}" />)
122
+ end
123
+
124
+ private
125
+
126
+ # Gets the configured icon set from site configuration
127
+ # @param context [Liquid::Context] the Liquid context
128
+ # @return [String] the icon set name
129
+ def get_icon_set(context)
130
+ return "color" unless context
131
+
132
+ site_config = context.registers[:site]&.config
133
+ documents_config = site_config["documents"] if site_config
134
+ icon_set = documents_config["icon_set"] if documents_config
135
+
136
+ # Validate icon set exists
137
+ return "color" unless icon_set && ICON_MAP.key?(icon_set)
138
+ icon_set
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ Liquid::Template.register_filter(Jekyll::Documents::FileTypeIcons)
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Documents
5
+ module Filters
6
+ DANISH_MAP = {
7
+ "æ" => "ae", "ø" => "oe", "å" => "aa",
8
+ "Æ" => "Ae", "Ø" => "Oe", "Å" => "Aa"
9
+ }.freeze
10
+
11
+ # Slugify while handling Danish letters and basic punctuation cleanup.
12
+ def documents_slugify(input, downcase = true, danish_map = true)
13
+ s = input.to_s.dup
14
+ s = s.gsub(/[æøåÆØÅ]/) { |ch| DANISH_MAP[ch] } if danish_map
15
+ s = s.strip.gsub(/[^\p{Alnum}\-_\s]/u, "")
16
+ s = s.tr(" ", "-").gsub(/-+/, "-")
17
+ s = s.gsub(/[æøåÆØÅ]/, "") unless danish_map # Remove Danish chars if mapping disabled
18
+ s = s.downcase if downcase
19
+ s
20
+ end
21
+
22
+ # Title from filename e.g. "2026-03-01_Title_Here" -> "Title Here"
23
+ def documents_title_from_filename(basename)
24
+ if basename =~ /^\d{4}-\d{2}-\d{2}_(.+)$/
25
+ Regexp.last_match(1).tr("_", " ")
26
+ else
27
+ basename.tr("_", " ")
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ Liquid::Template.register_filter(Jekyll::Documents::Filters)