living-documentation 7.20.0 β 7.24.0
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.
- package/dist/src/frontend/documents.js +2 -0
- package/dist/src/frontend/i18n/en.json +6 -0
- package/dist/src/frontend/i18n/fr.json +6 -0
- package/dist/src/frontend/index.html +27 -0
- package/dist/src/frontend/local-search.js +476 -0
- package/dist/src/frontend/snippets.js +2 -0
- package/dist/src/routes/export.d.ts.map +1 -1
- package/dist/src/routes/export.js +3 -1
- package/dist/src/routes/export.js.map +1 -1
- package/package.json +6 -6
|
@@ -30,6 +30,8 @@ function _wireDocContent(html) {
|
|
|
30
30
|
_decorateCodeBlocksWithCopy(contentEl);
|
|
31
31
|
_decorateCollapsibleCodeBlocks(contentEl);
|
|
32
32
|
|
|
33
|
+
if (typeof initLocalSearch === "function") initLocalSearch(contentEl);
|
|
34
|
+
|
|
33
35
|
contentEl.querySelectorAll("a[href]").forEach((a) => {
|
|
34
36
|
const href = a.getAttribute("href");
|
|
35
37
|
const m = href && href.match(/[?&]doc=([^&#]+)/);
|
|
@@ -237,6 +237,12 @@
|
|
|
237
237
|
"snippet.emoji_search_placeholder": "Search emojis⦠(e.g. heart, star, rocket)",
|
|
238
238
|
"snippet.emoji_no_results": "No emoji matches this search.",
|
|
239
239
|
"snippet.attachment": "π File attachment",
|
|
240
|
+
"snippet.local_search": "π Local search",
|
|
241
|
+
"local_search.placeholder": "Search in this documentβ¦",
|
|
242
|
+
"local_search.clear": "Clear",
|
|
243
|
+
"local_search.no_results": "No matches found.",
|
|
244
|
+
"local_search.count_singular": "{count} match",
|
|
245
|
+
"local_search.count_plural": "{count} matches",
|
|
240
246
|
"snippet.attachment_help": "Click <strong>Insert</strong> to choose a file. It will be uploaded under the <code>files/</code> folder and inserted as a <i class=\"fa-solid fa-paperclip\"></i> link in your document.",
|
|
241
247
|
"snippet.attachment_alt": "Tip: you can also drag & drop a file onto the editor, or paste it from the clipboard.",
|
|
242
248
|
|
|
@@ -237,6 +237,12 @@
|
|
|
237
237
|
"snippet.emoji_search_placeholder": "Rechercher un émoji⦠(ex : coeur, etoile, fusee)",
|
|
238
238
|
"snippet.emoji_no_results": "Aucun Γ©moji ne correspond Γ cette recherche.",
|
|
239
239
|
"snippet.attachment": "π PiΓ¨ce jointe",
|
|
240
|
+
"snippet.local_search": "π Recherche locale",
|
|
241
|
+
"local_search.placeholder": "Rechercher dans ce documentβ¦",
|
|
242
|
+
"local_search.clear": "Effacer",
|
|
243
|
+
"local_search.no_results": "Aucun rΓ©sultat.",
|
|
244
|
+
"local_search.count_singular": "{count} occurrence",
|
|
245
|
+
"local_search.count_plural": "{count} occurrences",
|
|
240
246
|
"snippet.attachment_help": "Cliquez sur <strong>InsΓ©rer</strong> pour choisir un fichier. Il sera tΓ©lΓ©versΓ© dans le dossier <code>files/</code> et insΓ©rΓ© sous forme de lien <i class=\"fa-solid fa-paperclip\"></i> dans votre document.",
|
|
241
247
|
"snippet.attachment_alt": "Astuce : vous pouvez aussi glisser-dΓ©poser un fichier sur l'Γ©diteur ou le coller depuis le presse-papiers.",
|
|
242
248
|
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
<script defer src="/sidebar.js"></script>
|
|
43
43
|
<script defer src="/sidebar-resize.js"></script>
|
|
44
44
|
<script defer src="/search.js"></script>
|
|
45
|
+
<script defer src="/local-search.js"></script>
|
|
45
46
|
<script defer src="/image-paste.js"></script>
|
|
46
47
|
<script defer src="/file-attach.js"></script>
|
|
47
48
|
<script defer src="/documents.js"></script>
|
|
@@ -247,6 +248,29 @@
|
|
|
247
248
|
border-color: #d1d5db;
|
|
248
249
|
}
|
|
249
250
|
|
|
251
|
+
/* Local search highlight β distinct from the global yellow search */
|
|
252
|
+
mark.ld-local-mark {
|
|
253
|
+
background: #bae6fd;
|
|
254
|
+
color: inherit;
|
|
255
|
+
padding: 0 1px;
|
|
256
|
+
border-radius: 2px;
|
|
257
|
+
}
|
|
258
|
+
mark.ld-local-mark.ld-local-active {
|
|
259
|
+
background: #0284c7;
|
|
260
|
+
color: #fff;
|
|
261
|
+
}
|
|
262
|
+
.dark mark.ld-local-mark {
|
|
263
|
+
background: #075985;
|
|
264
|
+
color: #e0f2fe;
|
|
265
|
+
}
|
|
266
|
+
.dark mark.ld-local-mark.ld-local-active {
|
|
267
|
+
background: #0ea5e9;
|
|
268
|
+
color: #082f49;
|
|
269
|
+
}
|
|
270
|
+
.ld-local-item-active {
|
|
271
|
+
background: rgba(14, 165, 233, 0.12);
|
|
272
|
+
}
|
|
273
|
+
|
|
250
274
|
/* File attachment pills β links pointing to /files/ */
|
|
251
275
|
.prose a.ld-file-attachment,
|
|
252
276
|
a.ld-file-attachment {
|
|
@@ -795,6 +819,8 @@
|
|
|
795
819
|
class="max-h-40 overflow-y-auto divide-y divide-yellow-100 dark:divide-yellow-900/40 list-none m-0 p-0"
|
|
796
820
|
></ol>
|
|
797
821
|
</div>
|
|
822
|
+
<!-- Local search widget mount point (populated by local-search.js) -->
|
|
823
|
+
<div id="local-search-mount" class="hidden no-print"></div>
|
|
798
824
|
</header>
|
|
799
825
|
|
|
800
826
|
<!-- Rendered markdown -->
|
|
@@ -1402,6 +1428,7 @@
|
|
|
1402
1428
|
<option data-i18n="snippet.colored_text" value="colored-text">Colored text</option>
|
|
1403
1429
|
<option data-i18n="snippet.emojis" value="emojis">π Emojis</option>
|
|
1404
1430
|
<option data-i18n="snippet.attachment" value="attachment">π File attachment</option>
|
|
1431
|
+
<option data-i18n="snippet.local_search" value="local-search">π Local search</option>
|
|
1405
1432
|
</select>
|
|
1406
1433
|
</div>
|
|
1407
1434
|
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
// ββ Local search widget βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
2
|
+
// Invoked from documents.js::_wireDocContent after hljs highlighting.
|
|
3
|
+
// Scans the rendered content for <div data-ld-local-search>. If at least one
|
|
4
|
+
// is found, detaches them from the doc body and injects a live-filter widget
|
|
5
|
+
// into the doc header (mount point #local-search-mount).
|
|
6
|
+
//
|
|
7
|
+
// Search features (zero external dependency):
|
|
8
|
+
// - diacritics stripped (NFD + combining removal) β "rΓ©sumΓ©" matches "resume"
|
|
9
|
+
// - separators collapsed ( -_ + whitespace β single space) β "date-only" matches "date only"
|
|
10
|
+
// - tokenized AND with OR fallback (no block matches all tokens β show any-token matches)
|
|
11
|
+
// - Damerau-Levenshtein distance 1-2 (length-adaptive) on unique-word index for typos and plurals
|
|
12
|
+
// - first-char + length pre-filters eliminate ~90% of candidates before Levenshtein
|
|
13
|
+
// - position map (normalizedIdx β originalIdx) so highlights wrap the exact source substring
|
|
14
|
+
|
|
15
|
+
// ββ Text normalization βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
16
|
+
|
|
17
|
+
// Normalize a string for case-insensitive, diacritic-insensitive, separator-tolerant matching.
|
|
18
|
+
// Also builds a map[normIdx] β originalIdx, so a match found in the normalized text
|
|
19
|
+
// can be translated back to an exact slice of the source.
|
|
20
|
+
function _ldNormalizeWithMap(src) {
|
|
21
|
+
let normalized = "";
|
|
22
|
+
const map = [];
|
|
23
|
+
let lastWasSpace = true;
|
|
24
|
+
for (let i = 0; i < src.length; i++) {
|
|
25
|
+
const decomposed = src[i].normalize("NFD");
|
|
26
|
+
for (let k = 0; k < decomposed.length; k++) {
|
|
27
|
+
const code = decomposed.charCodeAt(k);
|
|
28
|
+
if (code >= 0x0300 && code <= 0x036f) continue;
|
|
29
|
+
const isAlnum =
|
|
30
|
+
(code >= 48 && code <= 57) ||
|
|
31
|
+
(code >= 65 && code <= 90) ||
|
|
32
|
+
(code >= 97 && code <= 122);
|
|
33
|
+
if (isAlnum) {
|
|
34
|
+
const lower = code >= 65 && code <= 90 ? code + 32 : code;
|
|
35
|
+
normalized += String.fromCharCode(lower);
|
|
36
|
+
map.push(i);
|
|
37
|
+
lastWasSpace = false;
|
|
38
|
+
} else if (!lastWasSpace) {
|
|
39
|
+
normalized += " ";
|
|
40
|
+
map.push(i);
|
|
41
|
+
lastWasSpace = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
map.push(src.length);
|
|
46
|
+
if (normalized.endsWith(" ")) {
|
|
47
|
+
normalized = normalized.slice(0, -1);
|
|
48
|
+
map.splice(map.length - 2, 1);
|
|
49
|
+
}
|
|
50
|
+
return { normalized, map };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function _ldNormalize(src) {
|
|
54
|
+
return _ldNormalizeWithMap(src).normalized;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ββ Damerau-Levenshtein with early exit ββββββββββββββββββββββββββββββββββββ
|
|
58
|
+
// Returns the distance if β€ max, or `max + 1` as a sentinel "over max".
|
|
59
|
+
function _ldDamerauLevenshtein(a, b, max) {
|
|
60
|
+
if (a === b) return 0;
|
|
61
|
+
const alen = a.length;
|
|
62
|
+
const blen = b.length;
|
|
63
|
+
if (Math.abs(alen - blen) > max) return max + 1;
|
|
64
|
+
let prev2 = null;
|
|
65
|
+
let prev = new Array(blen + 1);
|
|
66
|
+
let curr = new Array(blen + 1);
|
|
67
|
+
for (let j = 0; j <= blen; j++) prev[j] = j;
|
|
68
|
+
for (let i = 1; i <= alen; i++) {
|
|
69
|
+
curr[0] = i;
|
|
70
|
+
let rowMin = i;
|
|
71
|
+
for (let j = 1; j <= blen; j++) {
|
|
72
|
+
const cost = a.charCodeAt(i - 1) === b.charCodeAt(j - 1) ? 0 : 1;
|
|
73
|
+
let v = Math.min(
|
|
74
|
+
prev[j] + 1,
|
|
75
|
+
curr[j - 1] + 1,
|
|
76
|
+
prev[j - 1] + cost,
|
|
77
|
+
);
|
|
78
|
+
if (
|
|
79
|
+
i > 1 &&
|
|
80
|
+
j > 1 &&
|
|
81
|
+
a.charCodeAt(i - 1) === b.charCodeAt(j - 2) &&
|
|
82
|
+
a.charCodeAt(i - 2) === b.charCodeAt(j - 1)
|
|
83
|
+
) {
|
|
84
|
+
v = Math.min(v, prev2[j - 2] + 1);
|
|
85
|
+
}
|
|
86
|
+
curr[j] = v;
|
|
87
|
+
if (v < rowMin) rowMin = v;
|
|
88
|
+
}
|
|
89
|
+
if (rowMin > max) return max + 1;
|
|
90
|
+
prev2 = prev;
|
|
91
|
+
prev = curr;
|
|
92
|
+
curr = new Array(blen + 1);
|
|
93
|
+
}
|
|
94
|
+
return prev[blen];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Adaptive distance: no typo tolerance for very short tokens.
|
|
98
|
+
function _ldMaxDistance(tokenLen) {
|
|
99
|
+
if (tokenLen >= 7) return 2;
|
|
100
|
+
if (tokenLen >= 4) return 1;
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ββ Widget βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
105
|
+
|
|
106
|
+
function _ldLocalTr(key, fallback) {
|
|
107
|
+
return (typeof window.t === "function" && window.t(key)) || fallback;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function _ldLocalEsc(s) {
|
|
111
|
+
return String(s)
|
|
112
|
+
.replace(/&/g, "&")
|
|
113
|
+
.replace(/</g, "<")
|
|
114
|
+
.replace(/>/g, ">")
|
|
115
|
+
.replace(/"/g, """)
|
|
116
|
+
.replace(/'/g, "'");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function _ldRegexEscape(s) {
|
|
120
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function initLocalSearch(contentEl) {
|
|
124
|
+
const mount = document.getElementById("local-search-mount");
|
|
125
|
+
if (!mount) return;
|
|
126
|
+
mount.innerHTML = "";
|
|
127
|
+
mount.classList.add("hidden");
|
|
128
|
+
|
|
129
|
+
const placeholders = contentEl.querySelectorAll("[data-ld-local-search]");
|
|
130
|
+
if (!placeholders.length) return;
|
|
131
|
+
placeholders.forEach((el) => el.remove());
|
|
132
|
+
|
|
133
|
+
// Build the unique-word index once per doc. Used only for Levenshtein variants.
|
|
134
|
+
const wordIndex = (() => {
|
|
135
|
+
const set = new Set();
|
|
136
|
+
const normalized = _ldNormalize(contentEl.textContent);
|
|
137
|
+
normalized.split(" ").forEach((w) => {
|
|
138
|
+
if (w.length >= 3) set.add(w);
|
|
139
|
+
});
|
|
140
|
+
return Array.from(set);
|
|
141
|
+
})();
|
|
142
|
+
|
|
143
|
+
const placeholderTxt = _ldLocalTr(
|
|
144
|
+
"local_search.placeholder",
|
|
145
|
+
"Search in this documentβ¦",
|
|
146
|
+
);
|
|
147
|
+
const clearTitle = _ldLocalTr("local_search.clear", "Clear");
|
|
148
|
+
|
|
149
|
+
const wrapper = document.createElement("div");
|
|
150
|
+
wrapper.className =
|
|
151
|
+
"no-print mt-4 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 overflow-hidden";
|
|
152
|
+
wrapper.innerHTML = `
|
|
153
|
+
<div class="flex items-center gap-2 px-3 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50">
|
|
154
|
+
<span class="text-gray-400 select-none" aria-hidden="true">π</span>
|
|
155
|
+
<input
|
|
156
|
+
type="text"
|
|
157
|
+
id="ld-local-search-input"
|
|
158
|
+
autocomplete="off"
|
|
159
|
+
class="flex-1 bg-transparent border-0 text-sm text-gray-700 dark:text-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-0"
|
|
160
|
+
placeholder="${_ldLocalEsc(placeholderTxt)}"
|
|
161
|
+
/>
|
|
162
|
+
<button
|
|
163
|
+
type="button"
|
|
164
|
+
id="ld-local-search-clear"
|
|
165
|
+
class="hidden text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 shrink-0 px-1"
|
|
166
|
+
title="${_ldLocalEsc(clearTitle)}"
|
|
167
|
+
aria-label="${_ldLocalEsc(clearTitle)}"
|
|
168
|
+
>β</button>
|
|
169
|
+
</div>
|
|
170
|
+
<div id="ld-local-search-results" class="hidden">
|
|
171
|
+
<div id="ld-local-search-title" class="px-3 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400 border-b border-gray-100 dark:border-gray-800"></div>
|
|
172
|
+
<ol id="ld-local-search-list" class="max-h-40 overflow-y-auto divide-y divide-gray-100 dark:divide-gray-800 list-none m-0 p-0"></ol>
|
|
173
|
+
</div>
|
|
174
|
+
`;
|
|
175
|
+
mount.appendChild(wrapper);
|
|
176
|
+
mount.classList.remove("hidden");
|
|
177
|
+
|
|
178
|
+
const input = wrapper.querySelector("#ld-local-search-input");
|
|
179
|
+
const clearBtn = wrapper.querySelector("#ld-local-search-clear");
|
|
180
|
+
const results = wrapper.querySelector("#ld-local-search-results");
|
|
181
|
+
const titleEl = wrapper.querySelector("#ld-local-search-title");
|
|
182
|
+
const listEl = wrapper.querySelector("#ld-local-search-list");
|
|
183
|
+
|
|
184
|
+
let timer = null;
|
|
185
|
+
|
|
186
|
+
function clearHighlights() {
|
|
187
|
+
contentEl.querySelectorAll("mark.ld-local-mark").forEach((m) => {
|
|
188
|
+
const parent = m.parentNode;
|
|
189
|
+
while (m.firstChild) parent.insertBefore(m.firstChild, m);
|
|
190
|
+
parent.removeChild(m);
|
|
191
|
+
});
|
|
192
|
+
contentEl.normalize();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Given a query token, return the set of terms to highlight for that token.
|
|
196
|
+
// - Always includes the token itself (substring match on normalized text).
|
|
197
|
+
// - Adds Levenshtein variants (distance 1-2 depending on token length) found in wordIndex.
|
|
198
|
+
function findVariants(token, normalizedContent) {
|
|
199
|
+
const variants = new Set();
|
|
200
|
+
if (normalizedContent.includes(token)) variants.add(token);
|
|
201
|
+
const maxDist = _ldMaxDistance(token.length);
|
|
202
|
+
if (maxDist === 0) return variants;
|
|
203
|
+
const firstChar = token[0];
|
|
204
|
+
for (const word of wordIndex) {
|
|
205
|
+
if (word === token) continue;
|
|
206
|
+
if (Math.abs(word.length - token.length) > maxDist) continue;
|
|
207
|
+
if (token.length >= 3 && word[0] !== firstChar) continue;
|
|
208
|
+
const d = _ldDamerauLevenshtein(token, word, maxDist);
|
|
209
|
+
if (d <= maxDist) variants.add(word);
|
|
210
|
+
}
|
|
211
|
+
return variants;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function runSearch(q) {
|
|
215
|
+
clearHighlights();
|
|
216
|
+
if (!q) {
|
|
217
|
+
results.classList.add("hidden");
|
|
218
|
+
clearBtn.classList.add("hidden");
|
|
219
|
+
listEl.innerHTML = "";
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
clearBtn.classList.remove("hidden");
|
|
223
|
+
|
|
224
|
+
const normalizedQuery = _ldNormalize(q);
|
|
225
|
+
const tokens = normalizedQuery.split(" ").filter(Boolean);
|
|
226
|
+
if (!tokens.length) {
|
|
227
|
+
results.classList.add("hidden");
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Pre-compute normalized content once (lightweight, reused for substring tests)
|
|
232
|
+
const normalizedContent = _ldNormalize(contentEl.textContent);
|
|
233
|
+
|
|
234
|
+
// For each token, gather the set of terms to highlight
|
|
235
|
+
const tokenVariants = tokens.map((t) => findVariants(t, normalizedContent));
|
|
236
|
+
|
|
237
|
+
// If no token has any variant, nothing to do
|
|
238
|
+
const hasAny = tokenVariants.some((s) => s.size > 0);
|
|
239
|
+
if (!hasAny) {
|
|
240
|
+
titleEl.textContent = _ldLocalTr(
|
|
241
|
+
"local_search.no_results",
|
|
242
|
+
"No matches found.",
|
|
243
|
+
);
|
|
244
|
+
listEl.innerHTML = "";
|
|
245
|
+
results.classList.remove("hidden");
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Build the highlight regex: union of all variants. Longer first to ensure
|
|
250
|
+
// longest match wins. Word-boundary applied to Levenshtein variants only
|
|
251
|
+
// (so we don't highlight "date" inside "updated" by way of the typo path).
|
|
252
|
+
const allVariants = new Set();
|
|
253
|
+
tokenVariants.forEach((vs, i) => {
|
|
254
|
+
vs.forEach((v) => {
|
|
255
|
+
const isToken = v === tokens[i];
|
|
256
|
+
allVariants.add(isToken ? v : "\\b" + _ldRegexEscape(v) + "\\b");
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
// Deduplicate by original string (without \b wrappers) so we don't double-match
|
|
260
|
+
const parts = Array.from(allVariants).sort((a, b) => b.length - a.length);
|
|
261
|
+
const re = new RegExp("(" + parts.map((p) =>
|
|
262
|
+
p.startsWith("\\b") ? p : _ldRegexEscape(p),
|
|
263
|
+
).join("|") + ")", "g");
|
|
264
|
+
|
|
265
|
+
// Walk text nodes; for each, normalize with a map, find regex matches on
|
|
266
|
+
// normalized, remap to original slice, wrap with a <mark>.
|
|
267
|
+
const walker = document.createTreeWalker(contentEl, NodeFilter.SHOW_TEXT, {
|
|
268
|
+
acceptNode(n) {
|
|
269
|
+
if (n.parentElement && n.parentElement.closest("mark")) {
|
|
270
|
+
return NodeFilter.FILTER_REJECT;
|
|
271
|
+
}
|
|
272
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
const textNodes = [];
|
|
276
|
+
while (walker.nextNode()) textNodes.push(walker.currentNode);
|
|
277
|
+
|
|
278
|
+
let matchIdx = 0;
|
|
279
|
+
// block β Set<tokenIndex> of which query tokens matched inside that block
|
|
280
|
+
const blockCoverage = new Map();
|
|
281
|
+
|
|
282
|
+
textNodes.forEach((node) => {
|
|
283
|
+
const original = node.textContent;
|
|
284
|
+
const { normalized, map } = _ldNormalizeWithMap(original);
|
|
285
|
+
if (!normalized) return;
|
|
286
|
+
|
|
287
|
+
const localMatches = [];
|
|
288
|
+
let m;
|
|
289
|
+
re.lastIndex = 0;
|
|
290
|
+
while ((m = re.exec(normalized)) !== null) {
|
|
291
|
+
if (m[0].length === 0) {
|
|
292
|
+
re.lastIndex++;
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
localMatches.push({
|
|
296
|
+
start: m.index,
|
|
297
|
+
end: m.index + m[0].length,
|
|
298
|
+
term: m[0],
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
if (!localMatches.length) return;
|
|
302
|
+
|
|
303
|
+
// Remap and wrap
|
|
304
|
+
const block =
|
|
305
|
+
node.parentElement?.closest(
|
|
306
|
+
"p, li, td, h1, h2, h3, h4, h5, h6, pre, blockquote",
|
|
307
|
+
) || node.parentElement;
|
|
308
|
+
|
|
309
|
+
let out = "";
|
|
310
|
+
let cursor = 0;
|
|
311
|
+
localMatches.forEach((mm) => {
|
|
312
|
+
const origStart = map[mm.start];
|
|
313
|
+
const origEnd = map[mm.end];
|
|
314
|
+
if (origStart < cursor) return; // overlap, skip
|
|
315
|
+
out += _ldLocalEsc(original.slice(cursor, origStart));
|
|
316
|
+
out += `<mark class="ld-local-mark" id="ld-local-match-${matchIdx++}">${_ldLocalEsc(original.slice(origStart, origEnd))}</mark>`;
|
|
317
|
+
cursor = origEnd;
|
|
318
|
+
|
|
319
|
+
if (block) {
|
|
320
|
+
if (!blockCoverage.has(block)) blockCoverage.set(block, new Set());
|
|
321
|
+
const cov = blockCoverage.get(block);
|
|
322
|
+
tokenVariants.forEach((vs, ti) => {
|
|
323
|
+
if (vs.has(mm.term)) cov.add(ti);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
out += _ldLocalEsc(original.slice(cursor));
|
|
328
|
+
|
|
329
|
+
const span = document.createElement("span");
|
|
330
|
+
span.innerHTML = out;
|
|
331
|
+
node.parentNode.replaceChild(span, node);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// AND mode: keep blocks that contain all tokens. OR fallback if none.
|
|
335
|
+
const totalTokens = tokens.length;
|
|
336
|
+
const andBlocks = [];
|
|
337
|
+
for (const [block, cov] of blockCoverage.entries()) {
|
|
338
|
+
if (cov.size === totalTokens) andBlocks.push(block);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
let marksToList;
|
|
342
|
+
if (andBlocks.length > 0) {
|
|
343
|
+
const ordered = Array.from(
|
|
344
|
+
contentEl.querySelectorAll("mark.ld-local-mark"),
|
|
345
|
+
);
|
|
346
|
+
const andBlockSet = new Set(andBlocks);
|
|
347
|
+
marksToList = ordered.filter((mk) => {
|
|
348
|
+
const parentBlock =
|
|
349
|
+
mk.closest("p, li, td, h1, h2, h3, h4, h5, h6, pre, blockquote") ||
|
|
350
|
+
mk.parentElement;
|
|
351
|
+
return andBlockSet.has(parentBlock);
|
|
352
|
+
});
|
|
353
|
+
} else {
|
|
354
|
+
marksToList = Array.from(
|
|
355
|
+
contentEl.querySelectorAll("mark.ld-local-mark"),
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (!marksToList.length) {
|
|
360
|
+
titleEl.textContent = _ldLocalTr(
|
|
361
|
+
"local_search.no_results",
|
|
362
|
+
"No matches found.",
|
|
363
|
+
);
|
|
364
|
+
listEl.innerHTML = "";
|
|
365
|
+
results.classList.remove("hidden");
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const label =
|
|
370
|
+
marksToList.length === 1
|
|
371
|
+
? _ldLocalTr("local_search.count_singular", "{count} match").replace(
|
|
372
|
+
"{count}",
|
|
373
|
+
marksToList.length,
|
|
374
|
+
)
|
|
375
|
+
: _ldLocalTr("local_search.count_plural", "{count} matches").replace(
|
|
376
|
+
"{count}",
|
|
377
|
+
marksToList.length,
|
|
378
|
+
);
|
|
379
|
+
titleEl.textContent = label;
|
|
380
|
+
|
|
381
|
+
const qLower = normalizedQuery;
|
|
382
|
+
listEl.innerHTML = marksToList
|
|
383
|
+
.map((mk, i) => {
|
|
384
|
+
const block =
|
|
385
|
+
mk.closest(
|
|
386
|
+
"p, li, td, h1, h2, h3, h4, h5, h6, pre, blockquote",
|
|
387
|
+
) || mk.parentElement;
|
|
388
|
+
const full = (block ? block.textContent : mk.textContent).trim();
|
|
389
|
+
const fullNorm = _ldNormalize(full);
|
|
390
|
+
// Find the first variant hit for snippet centering
|
|
391
|
+
let pos = -1;
|
|
392
|
+
for (const vs of tokenVariants) {
|
|
393
|
+
for (const v of vs) {
|
|
394
|
+
const p = fullNorm.indexOf(v);
|
|
395
|
+
if (p >= 0 && (pos < 0 || p < pos)) pos = p;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (pos < 0) pos = fullNorm.indexOf(qLower.split(" ")[0]);
|
|
399
|
+
if (pos < 0) pos = 0;
|
|
400
|
+
const start = Math.max(0, pos - 40);
|
|
401
|
+
const end = Math.min(full.length, pos + 80);
|
|
402
|
+
const snippet =
|
|
403
|
+
(start > 0 ? "β¦" : "") +
|
|
404
|
+
full.slice(start, end) +
|
|
405
|
+
(end < full.length ? "β¦" : "");
|
|
406
|
+
return `<li>
|
|
407
|
+
<button type="button" data-target="${mk.id}"
|
|
408
|
+
class="ld-local-item w-full text-left px-3 py-1.5 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors text-xs">
|
|
409
|
+
<span class="text-gray-400 font-mono mr-2">${i + 1}.</span>${_ldLocalEsc(snippet)}
|
|
410
|
+
</button>
|
|
411
|
+
</li>`;
|
|
412
|
+
})
|
|
413
|
+
.join("");
|
|
414
|
+
results.classList.remove("hidden");
|
|
415
|
+
|
|
416
|
+
listEl.querySelectorAll(".ld-local-item").forEach((btn) => {
|
|
417
|
+
btn.addEventListener("click", () => {
|
|
418
|
+
scrollToLocalMatch(btn.dataset.target);
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function scrollToLocalMatch(id) {
|
|
424
|
+
const mark = document.getElementById(id);
|
|
425
|
+
const container = document.getElementById("content-area");
|
|
426
|
+
if (!mark || !container) return;
|
|
427
|
+
|
|
428
|
+
let ancestor = mark.parentElement;
|
|
429
|
+
while (ancestor && ancestor !== container) {
|
|
430
|
+
if (ancestor.tagName === "DETAILS" && !ancestor.open) {
|
|
431
|
+
ancestor.open = true;
|
|
432
|
+
}
|
|
433
|
+
ancestor = ancestor.parentElement;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
contentEl
|
|
437
|
+
.querySelectorAll("mark.ld-local-mark.ld-local-active")
|
|
438
|
+
.forEach((m) => m.classList.remove("ld-local-active"));
|
|
439
|
+
mark.classList.add("ld-local-active");
|
|
440
|
+
|
|
441
|
+
listEl.querySelectorAll(".ld-local-item").forEach((b) => {
|
|
442
|
+
b.classList.toggle("ld-local-item-active", b.dataset.target === id);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
const stickyHeader = document.querySelector("#doc-view header");
|
|
446
|
+
const headerHeight = stickyHeader
|
|
447
|
+
? stickyHeader.getBoundingClientRect().height
|
|
448
|
+
: 0;
|
|
449
|
+
const markTop = mark.getBoundingClientRect().top;
|
|
450
|
+
const containerTop = container.getBoundingClientRect().top;
|
|
451
|
+
const targetOffset =
|
|
452
|
+
headerHeight + (container.clientHeight - headerHeight) / 3;
|
|
453
|
+
container.scrollTop += markTop - containerTop - targetOffset;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
input.addEventListener("input", () => {
|
|
457
|
+
clearTimeout(timer);
|
|
458
|
+
timer = setTimeout(() => runSearch(input.value.trim()), 250);
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
clearBtn.addEventListener("click", () => {
|
|
462
|
+
input.value = "";
|
|
463
|
+
runSearch("");
|
|
464
|
+
input.focus();
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
input.addEventListener("keydown", (e) => {
|
|
468
|
+
if (e.key === "Escape") {
|
|
469
|
+
input.value = "";
|
|
470
|
+
runSearch("");
|
|
471
|
+
input.blur();
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
window.initLocalSearch = initLocalSearch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/routes/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAwLpD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/routes/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAwLpD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA+IrD"}
|
|
@@ -198,7 +198,9 @@ function exportRouter(docsPath) {
|
|
|
198
198
|
if (!filePath || !fs_1.default.existsSync(filePath))
|
|
199
199
|
continue;
|
|
200
200
|
const raw = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
201
|
-
const bodyHtml = marked_1.marked.parse((0, documents_1.stripFrontmatter)(raw), markedOpts)
|
|
201
|
+
const bodyHtml = marked_1.marked.parse((0, documents_1.stripFrontmatter)(raw), markedOpts)
|
|
202
|
+
// Strip the local-search widget placeholder β feature is viewer-only
|
|
203
|
+
.replace(/<div\s+data-ld-local-search(?:="[^"]*")?\s*>\s*<\/div>/gi, '');
|
|
202
204
|
const baseName = sanitizeFilename(path_1.default.basename(doc.filename, '.md'));
|
|
203
205
|
const htmlFilename = baseName + '.html';
|
|
204
206
|
// Notion: group/page.html + group/image.png (images at same level as HTML)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/routes/export.ts"],"names":[],"mappings":";;;;;AAwLA,
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/routes/export.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "living-documentation",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.24.0",
|
|
4
4
|
"description": "A CLI tool that serves a local Markdown documentation viewer",
|
|
5
5
|
"main": "dist/src/server.js",
|
|
6
6
|
"bin": {
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"url": "https://github.com/craftskillz/living-documentation.git"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@modelcontextprotocol/sdk": "
|
|
33
|
-
"archiver": "
|
|
34
|
-
"commander": "
|
|
35
|
-
"express": "
|
|
36
|
-
"marked": "
|
|
32
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
33
|
+
"archiver": "7.0.1",
|
|
34
|
+
"commander": "12.1.0",
|
|
35
|
+
"express": "4.19.2",
|
|
36
|
+
"marked": "12.0.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/archiver": "^7.0.0",
|