mdorigin 0.1.1 → 0.1.3
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/README.md +97 -9
- package/dist/adapters/cloudflare.d.ts +7 -1
- package/dist/adapters/cloudflare.js +11 -1
- package/dist/adapters/node.d.ts +4 -0
- package/dist/adapters/node.js +51 -11
- package/dist/cli/build-cloudflare.js +11 -4
- package/dist/cli/build-index.js +17 -3
- package/dist/cli/build-search.d.ts +1 -0
- package/dist/cli/build-search.js +45 -0
- package/dist/cli/dev.js +14 -4
- package/dist/cli/main.js +15 -3
- package/dist/cli/search.d.ts +1 -0
- package/dist/cli/search.js +36 -0
- package/dist/cloudflare.d.ts +3 -0
- package/dist/cloudflare.js +67 -6
- package/dist/core/api.d.ts +13 -0
- package/dist/core/api.js +160 -0
- package/dist/core/content-store.js +5 -0
- package/dist/core/content-type.d.ts +1 -0
- package/dist/core/content-type.js +3 -0
- package/dist/core/directory-index.d.ts +1 -1
- package/dist/core/directory-index.js +5 -1
- package/dist/core/extensions.d.ts +66 -0
- package/dist/core/extensions.js +86 -0
- package/dist/core/markdown.d.ts +4 -0
- package/dist/core/markdown.js +53 -0
- package/dist/core/request-handler.d.ts +6 -0
- package/dist/core/request-handler.js +211 -68
- package/dist/core/site-config.d.ts +18 -0
- package/dist/core/site-config.js +88 -16
- package/dist/html/template.d.ts +8 -0
- package/dist/html/template.js +228 -12
- package/dist/html/theme.js +254 -9
- package/dist/index-builder.d.ts +3 -1
- package/dist/index-builder.js +82 -45
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/search.d.ts +59 -0
- package/dist/search.js +370 -0
- package/package.json +20 -5
package/dist/html/template.js
CHANGED
|
@@ -14,6 +14,14 @@ export function renderDocument(options) {
|
|
|
14
14
|
const faviconMeta = options.favicon
|
|
15
15
|
? `<link rel="icon" href="${escapeHtml(options.favicon)}">`
|
|
16
16
|
: '';
|
|
17
|
+
const absoluteSocialImageUrl = getAbsoluteSiteAssetUrl(options.siteUrl, options.socialImage);
|
|
18
|
+
const socialImageMeta = absoluteSocialImageUrl
|
|
19
|
+
? [
|
|
20
|
+
`<meta property="og:image" content="${escapeHtml(absoluteSocialImageUrl)}">`,
|
|
21
|
+
'<meta name="twitter:card" content="summary_large_image">',
|
|
22
|
+
`<meta name="twitter:image" content="${escapeHtml(absoluteSocialImageUrl)}">`,
|
|
23
|
+
].join('')
|
|
24
|
+
: '';
|
|
17
25
|
const alternateMarkdownMeta = options.alternateMarkdownPath
|
|
18
26
|
? `<link rel="alternate" type="text/markdown" href="${escapeHtml(options.alternateMarkdownPath)}">`
|
|
19
27
|
: '';
|
|
@@ -23,6 +31,24 @@ export function renderDocument(options) {
|
|
|
23
31
|
.map((item) => `<li><a href="${escapeHtml(item.href)}">${escapeHtml(item.label)}</a></li>`)
|
|
24
32
|
.join('')}</ul></nav>`
|
|
25
33
|
: '';
|
|
34
|
+
const searchToggleBlock = options.searchEnabled
|
|
35
|
+
? [
|
|
36
|
+
'<div class="site-search" data-site-search>',
|
|
37
|
+
'<button type="button" class="site-search__toggle" aria-expanded="false" aria-controls="site-search-panel">Search</button>',
|
|
38
|
+
'<div id="site-search-panel" class="site-search__panel" hidden>',
|
|
39
|
+
'<form class="site-search__form" role="search" action="/api/search" method="get">',
|
|
40
|
+
'<label class="site-search__label" for="site-search-input">Search site</label>',
|
|
41
|
+
'<div class="site-search__controls">',
|
|
42
|
+
'<input id="site-search-input" class="site-search__input" type="search" name="q" placeholder="Search docs and skills" autocomplete="off">',
|
|
43
|
+
'<button type="submit" class="site-search__submit">Go</button>',
|
|
44
|
+
'</div>',
|
|
45
|
+
'<p class="site-search__hint">Search is powered by <code>/api/search</code>.</p>',
|
|
46
|
+
'</form>',
|
|
47
|
+
'<div class="site-search__results" data-site-search-results></div>',
|
|
48
|
+
'</div>',
|
|
49
|
+
'</div>',
|
|
50
|
+
].join('')
|
|
51
|
+
: '';
|
|
26
52
|
const footerNavBlock = options.footerNav && options.footerNav.length > 0
|
|
27
53
|
? `<nav class="site-footer__nav"><ul>${options.footerNav
|
|
28
54
|
.map((item) => `<li><a href="${escapeHtml(item.href)}">${escapeHtml(item.label)}</a></li>`)
|
|
@@ -46,12 +72,23 @@ export function renderDocument(options) {
|
|
|
46
72
|
const footerTextBlock = options.footerText
|
|
47
73
|
? `<p class="site-footer__text">${escapeHtml(options.footerText)}</p>`
|
|
48
74
|
: '';
|
|
49
|
-
const
|
|
50
|
-
? `<
|
|
75
|
+
const footerMetaBlock = socialLinksBlock || editLinkBlock
|
|
76
|
+
? `<div class="site-footer__meta">${socialLinksBlock}${editLinkBlock}</div>`
|
|
77
|
+
: '';
|
|
78
|
+
const footerBlock = footerNavBlock || footerTextBlock || footerMetaBlock
|
|
79
|
+
? `<footer class="site-footer"><div class="site-footer__inner">${footerNavBlock}${footerTextBlock}${footerMetaBlock}</div></footer>`
|
|
51
80
|
: '';
|
|
52
81
|
const articleBody = options.template === 'catalog'
|
|
53
|
-
? renderCatalogArticle(options.body, options.catalogEntries ?? []
|
|
82
|
+
? renderCatalogArticle(options.body, options.catalogEntries ?? [], {
|
|
83
|
+
requestPath: options.catalogRequestPath ?? '/',
|
|
84
|
+
initialPostCount: options.catalogInitialPostCount ?? 10,
|
|
85
|
+
loadMoreStep: options.catalogLoadMoreStep ?? 10,
|
|
86
|
+
})
|
|
54
87
|
: options.body;
|
|
88
|
+
const searchScript = options.searchEnabled ? renderSearchScript() : '';
|
|
89
|
+
const headerBlock = options.headerHtml ??
|
|
90
|
+
`<header class="site-header"><div class="site-header__inner"><div class="site-header__brand"><p class="site-header__title"><a href="${brandHref}">${logoBlock}<span>${siteTitle}</span></a></p>${siteDescriptionBlock}</div><div class="site-header__actions">${navBlock}${searchToggleBlock}</div></div></header>`;
|
|
91
|
+
const renderedFooterBlock = options.footerHtml ?? footerBlock;
|
|
55
92
|
return [
|
|
56
93
|
'<!doctype html>',
|
|
57
94
|
'<html lang="en">',
|
|
@@ -62,19 +99,33 @@ export function renderDocument(options) {
|
|
|
62
99
|
summaryMeta,
|
|
63
100
|
canonicalMeta,
|
|
64
101
|
faviconMeta,
|
|
102
|
+
socialImageMeta,
|
|
65
103
|
alternateMarkdownMeta,
|
|
66
104
|
stylesheetBlock,
|
|
67
105
|
'</head>',
|
|
68
106
|
`<body data-theme="${options.theme}" data-template="${options.template}">`,
|
|
69
|
-
|
|
107
|
+
headerBlock,
|
|
70
108
|
'<main>',
|
|
71
109
|
`<article>${articleBody}</article>`,
|
|
72
110
|
'</main>',
|
|
73
|
-
|
|
111
|
+
renderedFooterBlock,
|
|
112
|
+
searchScript,
|
|
74
113
|
'</body>',
|
|
75
114
|
'</html>',
|
|
76
115
|
].join('');
|
|
77
116
|
}
|
|
117
|
+
function getAbsoluteSiteAssetUrl(siteUrl, href) {
|
|
118
|
+
if (!href) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
if (/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(href) || href.startsWith('//')) {
|
|
122
|
+
return href;
|
|
123
|
+
}
|
|
124
|
+
if (!siteUrl) {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
return new URL(href.replace(/^\//, ''), `${siteUrl}/`).toString();
|
|
128
|
+
}
|
|
78
129
|
export function escapeHtml(value) {
|
|
79
130
|
return value
|
|
80
131
|
.replaceAll('&', '&')
|
|
@@ -102,18 +153,29 @@ function renderSocialIcon(icon) {
|
|
|
102
153
|
function iconSvg(pathData) {
|
|
103
154
|
return `<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${pathData}"></path></svg>`;
|
|
104
155
|
}
|
|
105
|
-
function renderCatalogArticle(body, entries) {
|
|
156
|
+
function renderCatalogArticle(body, entries, options) {
|
|
106
157
|
if (entries.length === 0) {
|
|
107
158
|
return body;
|
|
108
159
|
}
|
|
109
160
|
const directories = entries.filter((entry) => entry.kind === 'directory');
|
|
110
161
|
const articles = entries.filter((entry) => entry.kind === 'article');
|
|
162
|
+
const initialPostCount = Math.max(1, options.initialPostCount);
|
|
163
|
+
const visibleArticles = articles.slice(0, initialPostCount);
|
|
164
|
+
const shouldLoadMore = articles.length > visibleArticles.length;
|
|
111
165
|
return [
|
|
112
166
|
`<div class="catalog-page__body">${body}</div>`,
|
|
113
167
|
'<section class="catalog-page" aria-label="Catalog">',
|
|
114
168
|
directories.length > 0 ? renderCatalogDirectories(directories) : '',
|
|
115
|
-
articles.length > 0
|
|
169
|
+
articles.length > 0
|
|
170
|
+
? renderCatalogArticles(visibleArticles, {
|
|
171
|
+
requestPath: options.requestPath,
|
|
172
|
+
nextOffset: visibleArticles.length,
|
|
173
|
+
loadMoreStep: options.loadMoreStep,
|
|
174
|
+
hasMore: shouldLoadMore,
|
|
175
|
+
})
|
|
176
|
+
: '',
|
|
116
177
|
'</section>',
|
|
178
|
+
shouldLoadMore ? renderCatalogLoadMoreScript() : '',
|
|
117
179
|
].join('');
|
|
118
180
|
}
|
|
119
181
|
function renderCatalogDirectories(entries) {
|
|
@@ -125,12 +187,166 @@ function renderCatalogDirectories(entries) {
|
|
|
125
187
|
'</div>',
|
|
126
188
|
].join('');
|
|
127
189
|
}
|
|
128
|
-
function
|
|
190
|
+
export function renderCatalogArticleItems(entries) {
|
|
191
|
+
return entries
|
|
192
|
+
.map((entry) => `<a class="catalog-item" href="${escapeHtml(entry.href)}"><strong class="catalog-item__title">${escapeHtml(entry.title)}</strong>${entry.detail
|
|
193
|
+
? `<span class="catalog-item__detail">${escapeHtml(entry.detail)}</span>`
|
|
194
|
+
: ''}</a>`)
|
|
195
|
+
.join('');
|
|
196
|
+
}
|
|
197
|
+
function renderCatalogArticles(entries, options) {
|
|
129
198
|
return [
|
|
130
|
-
'<div class="catalog-list">',
|
|
131
|
-
|
|
132
|
-
? `<span class="catalog-item__detail">${escapeHtml(entry.detail)}</span>`
|
|
133
|
-
: ''}</a>`),
|
|
199
|
+
'<div class="catalog-list" data-catalog-articles>',
|
|
200
|
+
renderCatalogArticleItems(entries),
|
|
134
201
|
'</div>',
|
|
202
|
+
options.hasMore
|
|
203
|
+
? `<div class="catalog-load-more"><button type="button" class="catalog-load-more__button" data-catalog-load-more data-request-path="${escapeHtml(options.requestPath)}" data-next-offset="${escapeHtml(String(options.nextOffset))}" data-load-more-step="${escapeHtml(String(options.loadMoreStep))}">Load more</button></div>`
|
|
204
|
+
: '',
|
|
205
|
+
].join('');
|
|
206
|
+
}
|
|
207
|
+
function renderCatalogLoadMoreScript() {
|
|
208
|
+
return `<script>
|
|
209
|
+
(() => {
|
|
210
|
+
const button = document.querySelector('[data-catalog-load-more]');
|
|
211
|
+
const list = document.querySelector('[data-catalog-articles]');
|
|
212
|
+
if (!(button instanceof HTMLButtonElement) || !(list instanceof HTMLElement)) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const loadMore = async () => {
|
|
217
|
+
const requestPath = button.dataset.requestPath;
|
|
218
|
+
const nextOffset = button.dataset.nextOffset;
|
|
219
|
+
const loadMoreStep = button.dataset.loadMoreStep;
|
|
220
|
+
if (!requestPath || !nextOffset || !loadMoreStep) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
button.disabled = true;
|
|
225
|
+
const previousLabel = button.textContent;
|
|
226
|
+
button.textContent = 'Loading...';
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
const url = new URL(requestPath, window.location.origin);
|
|
230
|
+
url.searchParams.set('catalog-format', 'posts');
|
|
231
|
+
url.searchParams.set('catalog-offset', nextOffset);
|
|
232
|
+
url.searchParams.set('catalog-limit', loadMoreStep);
|
|
233
|
+
|
|
234
|
+
const response = await fetch(url.toString(), {
|
|
235
|
+
headers: { Accept: 'application/json' },
|
|
236
|
+
});
|
|
237
|
+
if (!response.ok) {
|
|
238
|
+
throw new Error('Failed to load more posts');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const payload = await response.json();
|
|
242
|
+
if (typeof payload.itemsHtml === 'string' && payload.itemsHtml !== '') {
|
|
243
|
+
list.insertAdjacentHTML('beforeend', payload.itemsHtml);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (payload.hasMore === true && typeof payload.nextOffset === 'number') {
|
|
247
|
+
button.dataset.nextOffset = String(payload.nextOffset);
|
|
248
|
+
button.disabled = false;
|
|
249
|
+
button.textContent = previousLabel ?? 'Load more';
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
button.remove();
|
|
254
|
+
} catch {
|
|
255
|
+
button.disabled = false;
|
|
256
|
+
button.textContent = previousLabel ?? 'Load more';
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
button.addEventListener('click', () => {
|
|
261
|
+
void loadMore();
|
|
262
|
+
});
|
|
263
|
+
})();
|
|
264
|
+
</script>`;
|
|
265
|
+
}
|
|
266
|
+
function renderSearchScript() {
|
|
267
|
+
return [
|
|
268
|
+
'<script>',
|
|
269
|
+
'(function () {',
|
|
270
|
+
' const root = document.querySelector("[data-site-search]");',
|
|
271
|
+
' if (!root) return;',
|
|
272
|
+
' const toggle = root.querySelector(".site-search__toggle");',
|
|
273
|
+
' const panel = root.querySelector(".site-search__panel");',
|
|
274
|
+
' const form = root.querySelector(".site-search__form");',
|
|
275
|
+
' const input = root.querySelector(".site-search__input");',
|
|
276
|
+
' const results = root.querySelector("[data-site-search-results]");',
|
|
277
|
+
' if (!toggle || !panel || !form || !input || !results) return;',
|
|
278
|
+
' let controller = null;',
|
|
279
|
+
' function renderMessage(message) {',
|
|
280
|
+
' results.innerHTML = `<p class="site-search__message">${escapeHtmlForScript(message)}</p>`;',
|
|
281
|
+
' }',
|
|
282
|
+
' function renderHits(hits) {',
|
|
283
|
+
' if (!Array.isArray(hits) || hits.length === 0) {',
|
|
284
|
+
' renderMessage("No results.");',
|
|
285
|
+
' return;',
|
|
286
|
+
' }',
|
|
287
|
+
' results.innerHTML = hits.map((hit) => {',
|
|
288
|
+
' const href = escapeHtmlForScript(hit.canonicalUrl || hit.docId || "#");',
|
|
289
|
+
' const title = escapeHtmlForScript(hit.title || hit.relativePath || "Untitled");',
|
|
290
|
+
' const summary = typeof hit.summary === "string" ? `<span class="site-search__item-summary">${escapeHtmlForScript(hit.summary)}</span>` : "";',
|
|
291
|
+
' const excerpt = hit.bestMatch && typeof hit.bestMatch.excerpt === "string" ? `<span class="site-search__item-excerpt">${escapeHtmlForScript(hit.bestMatch.excerpt)}</span>` : "";',
|
|
292
|
+
' return `<a class="site-search__item" href="${href}"><strong class="site-search__item-title">${title}</strong>${summary}${excerpt}</a>`;',
|
|
293
|
+
' }).join("");',
|
|
294
|
+
' }',
|
|
295
|
+
' async function runSearch(query) {',
|
|
296
|
+
' if (controller) controller.abort();',
|
|
297
|
+
' controller = new AbortController();',
|
|
298
|
+
' renderMessage("Searching...");',
|
|
299
|
+
' try {',
|
|
300
|
+
' const url = new URL("/api/search", window.location.origin);',
|
|
301
|
+
' url.searchParams.set("q", query);',
|
|
302
|
+
' url.searchParams.set("topK", "8");',
|
|
303
|
+
' const response = await fetch(url, { signal: controller.signal });',
|
|
304
|
+
' if (!response.ok) {',
|
|
305
|
+
' renderMessage(`Search failed (${response.status}).`);',
|
|
306
|
+
' return;',
|
|
307
|
+
' }',
|
|
308
|
+
' const payload = await response.json();',
|
|
309
|
+
' renderHits(payload.hits);',
|
|
310
|
+
' } catch (error) {',
|
|
311
|
+
' if (error && typeof error === "object" && "name" in error && error.name === "AbortError") return;',
|
|
312
|
+
' renderMessage("Search failed.");',
|
|
313
|
+
' }',
|
|
314
|
+
' }',
|
|
315
|
+
' function setOpen(open) {',
|
|
316
|
+
' toggle.setAttribute("aria-expanded", open ? "true" : "false");',
|
|
317
|
+
' panel.hidden = !open;',
|
|
318
|
+
' if (open) {',
|
|
319
|
+
' input.focus();',
|
|
320
|
+
' if (!results.innerHTML) renderMessage("Search docs, guides, and skills.");',
|
|
321
|
+
' }',
|
|
322
|
+
' }',
|
|
323
|
+
' toggle.addEventListener("click", () => setOpen(panel.hidden));',
|
|
324
|
+
' form.addEventListener("submit", (event) => {',
|
|
325
|
+
' event.preventDefault();',
|
|
326
|
+
' const query = input.value.trim();',
|
|
327
|
+
' if (!query) {',
|
|
328
|
+
' renderMessage("Enter a search query.");',
|
|
329
|
+
' return;',
|
|
330
|
+
' }',
|
|
331
|
+
' void runSearch(query);',
|
|
332
|
+
' });',
|
|
333
|
+
' document.addEventListener("keydown", (event) => {',
|
|
334
|
+
' if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {',
|
|
335
|
+
' event.preventDefault();',
|
|
336
|
+
' setOpen(true);',
|
|
337
|
+
' }',
|
|
338
|
+
' if (event.key === "Escape" && !panel.hidden) setOpen(false);',
|
|
339
|
+
' });',
|
|
340
|
+
'})();',
|
|
341
|
+
'',
|
|
342
|
+
'function escapeHtmlForScript(value) {',
|
|
343
|
+
' return String(value)',
|
|
344
|
+
' .replaceAll("&", "&")',
|
|
345
|
+
' .replaceAll("<", "<")',
|
|
346
|
+
' .replaceAll(">", ">")',
|
|
347
|
+
' .replaceAll(\'"\', """)',
|
|
348
|
+
' .replaceAll("\\\'", "'");',
|
|
349
|
+
'}',
|
|
350
|
+
'</script>',
|
|
135
351
|
].join('');
|
|
136
352
|
}
|
package/dist/html/theme.js
CHANGED
|
@@ -1,13 +1,135 @@
|
|
|
1
1
|
export function getBuiltInThemeStyles(theme) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
const themeStyles = (() => {
|
|
3
|
+
switch (theme) {
|
|
4
|
+
case 'atlas':
|
|
5
|
+
return buildAtlasThemeStyles();
|
|
6
|
+
case 'gazette':
|
|
7
|
+
return buildGazetteThemeStyles();
|
|
8
|
+
case 'paper':
|
|
9
|
+
default:
|
|
10
|
+
return buildPaperThemeStyles();
|
|
11
|
+
}
|
|
12
|
+
})();
|
|
13
|
+
return `${themeStyles}\n${buildSharedSearchStyles()}`;
|
|
14
|
+
}
|
|
15
|
+
function buildSharedSearchStyles() {
|
|
16
|
+
return `
|
|
17
|
+
.site-header__actions {
|
|
18
|
+
min-width: 0;
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: flex-end;
|
|
21
|
+
justify-content: flex-end;
|
|
22
|
+
gap: 1rem;
|
|
23
|
+
}
|
|
24
|
+
.site-search {
|
|
25
|
+
position: relative;
|
|
26
|
+
}
|
|
27
|
+
.site-search__toggle {
|
|
28
|
+
appearance: none;
|
|
29
|
+
border: 1px solid var(--border);
|
|
30
|
+
background: color-mix(in srgb, var(--surface) 92%, transparent);
|
|
31
|
+
color: var(--muted);
|
|
32
|
+
border-radius: 999px;
|
|
33
|
+
padding: 0.45rem 0.82rem;
|
|
34
|
+
font: inherit;
|
|
35
|
+
font-size: 0.88rem;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
.site-search__toggle:hover {
|
|
39
|
+
color: var(--text);
|
|
40
|
+
}
|
|
41
|
+
.site-search__panel {
|
|
42
|
+
position: absolute;
|
|
43
|
+
top: calc(100% + 0.7rem);
|
|
44
|
+
right: 0;
|
|
45
|
+
width: min(32rem, calc(100vw - 2rem));
|
|
46
|
+
padding: 1rem;
|
|
47
|
+
border: 1px solid var(--border);
|
|
48
|
+
border-radius: 18px;
|
|
49
|
+
background: color-mix(in srgb, var(--surface) 95%, white 5%);
|
|
50
|
+
box-shadow: 0 18px 40px rgba(24, 18, 11, 0.14);
|
|
51
|
+
z-index: 2;
|
|
52
|
+
}
|
|
53
|
+
.site-search__label {
|
|
54
|
+
display: block;
|
|
55
|
+
font-size: 0.8rem;
|
|
56
|
+
text-transform: uppercase;
|
|
57
|
+
letter-spacing: 0.08em;
|
|
58
|
+
color: var(--muted);
|
|
59
|
+
margin-bottom: 0.55rem;
|
|
60
|
+
}
|
|
61
|
+
.site-search__controls {
|
|
62
|
+
display: grid;
|
|
63
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
64
|
+
gap: 0.6rem;
|
|
65
|
+
}
|
|
66
|
+
.site-search__input,
|
|
67
|
+
.site-search__submit {
|
|
68
|
+
font: inherit;
|
|
69
|
+
}
|
|
70
|
+
.site-search__input {
|
|
71
|
+
width: 100%;
|
|
72
|
+
border: 1px solid var(--border);
|
|
73
|
+
border-radius: 12px;
|
|
74
|
+
background: var(--surface);
|
|
75
|
+
color: var(--text);
|
|
76
|
+
padding: 0.7rem 0.85rem;
|
|
77
|
+
}
|
|
78
|
+
.site-search__submit {
|
|
79
|
+
appearance: none;
|
|
80
|
+
border: 1px solid var(--text);
|
|
81
|
+
border-radius: 12px;
|
|
82
|
+
background: var(--text);
|
|
83
|
+
color: var(--surface);
|
|
84
|
+
padding: 0.7rem 0.95rem;
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
}
|
|
87
|
+
.site-search__hint,
|
|
88
|
+
.site-search__message {
|
|
89
|
+
color: var(--muted);
|
|
90
|
+
font-size: 0.84rem;
|
|
91
|
+
}
|
|
92
|
+
.site-search__results {
|
|
93
|
+
margin-top: 0.9rem;
|
|
94
|
+
display: grid;
|
|
95
|
+
gap: 0.7rem;
|
|
96
|
+
}
|
|
97
|
+
.site-search__item {
|
|
98
|
+
display: block;
|
|
99
|
+
text-decoration: none;
|
|
100
|
+
border-top: 1px solid var(--border);
|
|
101
|
+
padding-top: 0.7rem;
|
|
102
|
+
}
|
|
103
|
+
.site-search__item:first-child {
|
|
104
|
+
border-top: 0;
|
|
105
|
+
padding-top: 0;
|
|
106
|
+
}
|
|
107
|
+
.site-search__item-title {
|
|
108
|
+
display: block;
|
|
109
|
+
color: var(--text);
|
|
110
|
+
}
|
|
111
|
+
.site-search__item-summary,
|
|
112
|
+
.site-search__item-excerpt {
|
|
113
|
+
display: block;
|
|
114
|
+
margin-top: 0.25rem;
|
|
115
|
+
color: var(--muted);
|
|
116
|
+
font-size: 0.88rem;
|
|
117
|
+
}
|
|
118
|
+
.site-search__item-excerpt {
|
|
119
|
+
font-size: 0.82rem;
|
|
120
|
+
}
|
|
121
|
+
@media (max-width: 720px) {
|
|
122
|
+
.site-header__actions {
|
|
123
|
+
flex-direction: column;
|
|
124
|
+
align-items: stretch;
|
|
125
|
+
}
|
|
126
|
+
.site-search__panel {
|
|
127
|
+
left: 0;
|
|
128
|
+
right: auto;
|
|
129
|
+
width: min(100%, 34rem);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
`.trim();
|
|
11
133
|
}
|
|
12
134
|
function buildPaperThemeStyles() {
|
|
13
135
|
return `
|
|
@@ -125,6 +247,13 @@ main {
|
|
|
125
247
|
padding-top: 1rem;
|
|
126
248
|
color: var(--muted);
|
|
127
249
|
}
|
|
250
|
+
.site-footer__meta {
|
|
251
|
+
margin-top: 0.9rem;
|
|
252
|
+
display: flex;
|
|
253
|
+
align-items: center;
|
|
254
|
+
justify-content: space-between;
|
|
255
|
+
gap: 1rem;
|
|
256
|
+
}
|
|
128
257
|
.site-footer__nav ul,
|
|
129
258
|
.site-footer__social {
|
|
130
259
|
list-style: none;
|
|
@@ -163,6 +292,19 @@ main {
|
|
|
163
292
|
display: block;
|
|
164
293
|
margin-top: 0.9rem;
|
|
165
294
|
}
|
|
295
|
+
.site-footer__edit-link {
|
|
296
|
+
display: inline-block;
|
|
297
|
+
margin-top: 0;
|
|
298
|
+
font-size: 0.78rem;
|
|
299
|
+
color: var(--muted);
|
|
300
|
+
opacity: 0.72;
|
|
301
|
+
}
|
|
302
|
+
@media (max-width: 720px) {
|
|
303
|
+
.site-footer__meta {
|
|
304
|
+
flex-direction: column;
|
|
305
|
+
align-items: flex-start;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
166
308
|
article {
|
|
167
309
|
background: color-mix(in srgb, var(--surface) 92%, white 8%);
|
|
168
310
|
border: 1px solid var(--border);
|
|
@@ -253,6 +395,27 @@ hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
|
|
|
253
395
|
.catalog-item:hover {
|
|
254
396
|
text-decoration: none;
|
|
255
397
|
}
|
|
398
|
+
.catalog-load-more {
|
|
399
|
+
margin-top: 1.2rem;
|
|
400
|
+
}
|
|
401
|
+
.catalog-load-more__button {
|
|
402
|
+
appearance: none;
|
|
403
|
+
border: 1px solid var(--border);
|
|
404
|
+
background: var(--surface);
|
|
405
|
+
color: var(--text);
|
|
406
|
+
border-radius: 999px;
|
|
407
|
+
padding: 0.65rem 1rem;
|
|
408
|
+
font: inherit;
|
|
409
|
+
font-size: 0.95rem;
|
|
410
|
+
cursor: pointer;
|
|
411
|
+
}
|
|
412
|
+
.catalog-load-more__button:hover {
|
|
413
|
+
background: color-mix(in srgb, var(--surface) 86%, var(--code-bg) 14%);
|
|
414
|
+
}
|
|
415
|
+
.catalog-load-more__button:disabled {
|
|
416
|
+
cursor: wait;
|
|
417
|
+
opacity: 0.7;
|
|
418
|
+
}
|
|
256
419
|
@media (max-width: 720px) {
|
|
257
420
|
html { font-size: 17px; }
|
|
258
421
|
.site-header, main, .site-footer { padding-left: 1rem; padding-right: 1rem; }
|
|
@@ -386,6 +549,13 @@ main {
|
|
|
386
549
|
padding-top: 1rem;
|
|
387
550
|
color: var(--muted);
|
|
388
551
|
}
|
|
552
|
+
.site-footer__meta {
|
|
553
|
+
margin-top: 1rem;
|
|
554
|
+
display: flex;
|
|
555
|
+
align-items: center;
|
|
556
|
+
justify-content: space-between;
|
|
557
|
+
gap: 1rem;
|
|
558
|
+
}
|
|
389
559
|
.site-footer__nav ul,
|
|
390
560
|
.site-footer__social {
|
|
391
561
|
list-style: none;
|
|
@@ -424,6 +594,19 @@ main {
|
|
|
424
594
|
display: block;
|
|
425
595
|
margin-top: 0.95rem;
|
|
426
596
|
}
|
|
597
|
+
.site-footer__edit-link {
|
|
598
|
+
display: inline-block;
|
|
599
|
+
margin-top: 0;
|
|
600
|
+
font-size: 0.78rem;
|
|
601
|
+
color: var(--muted);
|
|
602
|
+
opacity: 0.72;
|
|
603
|
+
}
|
|
604
|
+
@media (max-width: 720px) {
|
|
605
|
+
.site-footer__meta {
|
|
606
|
+
flex-direction: column;
|
|
607
|
+
align-items: flex-start;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
427
610
|
article {
|
|
428
611
|
background: linear-gradient(180deg, rgba(255,255,255,0.96), rgba(247,250,252,0.98));
|
|
429
612
|
border: 1px solid var(--border);
|
|
@@ -518,6 +701,27 @@ hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
|
|
|
518
701
|
.catalog-item:hover {
|
|
519
702
|
text-decoration: none;
|
|
520
703
|
}
|
|
704
|
+
.catalog-load-more {
|
|
705
|
+
margin-top: 1.2rem;
|
|
706
|
+
}
|
|
707
|
+
.catalog-load-more__button {
|
|
708
|
+
appearance: none;
|
|
709
|
+
border: 1px solid var(--border);
|
|
710
|
+
background: var(--surface);
|
|
711
|
+
color: var(--text);
|
|
712
|
+
border-radius: 999px;
|
|
713
|
+
padding: 0.65rem 1rem;
|
|
714
|
+
font: inherit;
|
|
715
|
+
font-size: 0.95rem;
|
|
716
|
+
cursor: pointer;
|
|
717
|
+
}
|
|
718
|
+
.catalog-load-more__button:hover {
|
|
719
|
+
background: color-mix(in srgb, var(--surface) 75%, var(--accent) 25%);
|
|
720
|
+
}
|
|
721
|
+
.catalog-load-more__button:disabled {
|
|
722
|
+
cursor: wait;
|
|
723
|
+
opacity: 0.7;
|
|
724
|
+
}
|
|
521
725
|
@media (max-width: 720px) {
|
|
522
726
|
.site-header__inner, main, .site-footer { padding-left: 1rem; padding-right: 1rem; }
|
|
523
727
|
.site-header__inner {
|
|
@@ -648,6 +852,13 @@ main {
|
|
|
648
852
|
padding-top: 1rem;
|
|
649
853
|
color: var(--muted);
|
|
650
854
|
}
|
|
855
|
+
.site-footer__meta {
|
|
856
|
+
margin-top: 0.95rem;
|
|
857
|
+
display: flex;
|
|
858
|
+
align-items: center;
|
|
859
|
+
justify-content: space-between;
|
|
860
|
+
gap: 1rem;
|
|
861
|
+
}
|
|
651
862
|
.site-footer__nav ul,
|
|
652
863
|
.site-footer__social {
|
|
653
864
|
list-style: none;
|
|
@@ -686,6 +897,19 @@ main {
|
|
|
686
897
|
display: block;
|
|
687
898
|
margin-top: 0.9rem;
|
|
688
899
|
}
|
|
900
|
+
.site-footer__edit-link {
|
|
901
|
+
display: inline-block;
|
|
902
|
+
margin-top: 0;
|
|
903
|
+
font-size: 0.78rem;
|
|
904
|
+
color: var(--muted);
|
|
905
|
+
opacity: 0.72;
|
|
906
|
+
}
|
|
907
|
+
@media (max-width: 720px) {
|
|
908
|
+
.site-footer__meta {
|
|
909
|
+
flex-direction: column;
|
|
910
|
+
align-items: flex-start;
|
|
911
|
+
}
|
|
912
|
+
}
|
|
689
913
|
article {
|
|
690
914
|
background:
|
|
691
915
|
linear-gradient(180deg, rgba(255,255,255,0.94), rgba(255,253,248,0.98)),
|
|
@@ -785,6 +1009,27 @@ hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
|
|
|
785
1009
|
.catalog-item:hover {
|
|
786
1010
|
text-decoration: none;
|
|
787
1011
|
}
|
|
1012
|
+
.catalog-load-more {
|
|
1013
|
+
margin-top: 1.2rem;
|
|
1014
|
+
}
|
|
1015
|
+
.catalog-load-more__button {
|
|
1016
|
+
appearance: none;
|
|
1017
|
+
border: 1px solid var(--border);
|
|
1018
|
+
background: var(--surface);
|
|
1019
|
+
color: var(--text);
|
|
1020
|
+
border-radius: 999px;
|
|
1021
|
+
padding: 0.65rem 1rem;
|
|
1022
|
+
font: inherit;
|
|
1023
|
+
font-size: 0.95rem;
|
|
1024
|
+
cursor: pointer;
|
|
1025
|
+
}
|
|
1026
|
+
.catalog-load-more__button:hover {
|
|
1027
|
+
background: color-mix(in srgb, var(--surface) 84%, #fff 16%);
|
|
1028
|
+
}
|
|
1029
|
+
.catalog-load-more__button:disabled {
|
|
1030
|
+
cursor: wait;
|
|
1031
|
+
opacity: 0.7;
|
|
1032
|
+
}
|
|
788
1033
|
@media (max-width: 720px) {
|
|
789
1034
|
html { font-size: 17px; }
|
|
790
1035
|
.site-header, main, .site-footer { padding-left: 1rem; padding-right: 1rem; }
|
package/dist/index-builder.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import { type MdoPlugin } from './core/extensions.js';
|
|
1
2
|
export interface BuildIndexOptions {
|
|
2
3
|
rootDir?: string;
|
|
3
4
|
dir?: string;
|
|
5
|
+
plugins?: MdoPlugin[];
|
|
4
6
|
}
|
|
5
7
|
export interface BuildIndexResult {
|
|
6
8
|
updatedFiles: string[];
|
|
7
9
|
skippedDirectories: string[];
|
|
8
10
|
}
|
|
9
11
|
export declare function buildDirectoryIndexes(options: BuildIndexOptions): Promise<BuildIndexResult>;
|
|
10
|
-
export declare function buildManagedIndexBlock(directoryPath: string): Promise<string>;
|
|
12
|
+
export declare function buildManagedIndexBlock(directoryPath: string, plugins?: MdoPlugin[]): Promise<string>;
|
|
11
13
|
export declare function upsertManagedIndexBlock(source: string, block: string, options?: {
|
|
12
14
|
directoryPath?: string;
|
|
13
15
|
}): string;
|