@riebeckite/honox 0.0.4 → 0.0.5
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/index.d.ts +2 -0
- package/dist/index.js +1498 -814
- package/dist/src/scaffold/index.d.ts +2 -0
- package/dist/src/scaffold/localized-content.d.ts +9 -10
- package/dist/src/scaffold/presets.d.ts +73 -0
- package/dist/src/scaffold/presets.js +374 -0
- package/dist/src/scaffold/templates.d.ts +2 -1
- package/package.json +8 -2
package/dist/index.js
CHANGED
|
@@ -29,10 +29,10 @@ function workspacePackageResolver(workspaceRoot) {
|
|
|
29
29
|
name: "workspace-package-resolver",
|
|
30
30
|
setup(buildApi) {
|
|
31
31
|
buildApi.onResolve({ filter: /.*/ }, (args) => {
|
|
32
|
-
const
|
|
32
|
+
const alias2 = aliases.find(
|
|
33
33
|
(currentAlias) => currentAlias.find.test(args.path)
|
|
34
34
|
);
|
|
35
|
-
return
|
|
35
|
+
return alias2 ? { path: alias2.replacement } : null;
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
};
|
|
@@ -254,7 +254,7 @@ function isJavaScriptModule(filePath) {
|
|
|
254
254
|
import fs6 from "node:fs/promises";
|
|
255
255
|
import path7 from "node:path";
|
|
256
256
|
|
|
257
|
-
// src/scaffold/
|
|
257
|
+
// src/scaffold/presets.ts
|
|
258
258
|
var SCAFFOLD_LANGUAGES = [
|
|
259
259
|
"en",
|
|
260
260
|
"ja",
|
|
@@ -274,175 +274,963 @@ function defaultLanguageForLocale(locale) {
|
|
|
274
274
|
if (normalized.startsWith("ko")) return "ko";
|
|
275
275
|
return "en";
|
|
276
276
|
}
|
|
277
|
-
var
|
|
278
|
-
|
|
279
|
-
|
|
277
|
+
var SCAFFOLD_PRESET_NAMES = [
|
|
278
|
+
"empty",
|
|
279
|
+
"minimal",
|
|
280
|
+
"starter",
|
|
281
|
+
"rich",
|
|
282
|
+
"full",
|
|
283
|
+
"max",
|
|
284
|
+
"ultra"
|
|
285
|
+
];
|
|
286
|
+
function isScaffoldPresetName(value) {
|
|
287
|
+
return SCAFFOLD_PRESET_NAMES.includes(value);
|
|
288
|
+
}
|
|
289
|
+
var np = (package_, factory, options) => ({
|
|
290
|
+
package: package_,
|
|
291
|
+
factory,
|
|
292
|
+
options
|
|
293
|
+
});
|
|
294
|
+
var obsidianMarkdown = np(
|
|
295
|
+
"@riebeckite/plugin-obsidian-markdown",
|
|
296
|
+
"obsidianMarkdown"
|
|
297
|
+
);
|
|
298
|
+
var colorMode = np("@riebeckite/plugin-color-mode", "colorModePlugin");
|
|
299
|
+
var l10n = np("@riebeckite/plugin-l10n", "l10n");
|
|
300
|
+
var seo = np("@riebeckite/plugin-seo", "seo");
|
|
301
|
+
var toc = np("@riebeckite/plugin-toc", "tocPlugin");
|
|
302
|
+
var properties = np("@riebeckite/plugin-properties", "properties");
|
|
303
|
+
var alias = np("@riebeckite/plugin-alias", "aliasPlugin");
|
|
304
|
+
var codeEnhance = np("@riebeckite/plugin-code-enhance", "codeEnhance");
|
|
305
|
+
var search = np("@riebeckite/plugin-search", "searchPlugin");
|
|
306
|
+
var backlinks = np("@riebeckite/plugin-backlinks", "backlinksPlugin");
|
|
307
|
+
var relatedPosts = np("@riebeckite/plugin-related-posts", "relatedPosts");
|
|
308
|
+
var recentPosts = np("@riebeckite/plugin-recent-posts", "recentPostsPlugin");
|
|
309
|
+
var attachment = np("@riebeckite/plugin-attachment", "attachment");
|
|
310
|
+
var media = np("@riebeckite/plugin-media", "media");
|
|
311
|
+
var responsiveImage = np(
|
|
312
|
+
"@riebeckite/plugin-responsive-image",
|
|
313
|
+
"responsiveImage"
|
|
314
|
+
);
|
|
315
|
+
var lightbox = np("@riebeckite/plugin-lightbox", "lightboxPlugin");
|
|
316
|
+
var highlight = np("@riebeckite/plugin-highlight", "highlight");
|
|
317
|
+
var codeTabs = np("@riebeckite/plugin-code-tabs", "codeTabs");
|
|
318
|
+
var codeAnnotations = np(
|
|
319
|
+
"@riebeckite/plugin-code-annotations",
|
|
320
|
+
"codeAnnotations"
|
|
321
|
+
);
|
|
322
|
+
var shortcodes = np("@riebeckite/plugin-shortcodes", "shortcodes");
|
|
323
|
+
var series = np("@riebeckite/plugin-series", "series");
|
|
324
|
+
var autoCardLink = np(
|
|
325
|
+
"@riebeckite/plugin-autocardlink",
|
|
326
|
+
"autoCardLinkPlugin"
|
|
327
|
+
);
|
|
328
|
+
var richEmbed = np("@riebeckite/plugin-rich-embed", "richEmbed");
|
|
329
|
+
var mermaid = np("@riebeckite/plugin-mermaid", "mermaid");
|
|
330
|
+
var graphviz = np("@riebeckite/plugin-graphviz", "graphviz");
|
|
331
|
+
var d2 = np("@riebeckite/plugin-d2", "d2");
|
|
332
|
+
var plantuml = np("@riebeckite/plugin-plantuml", "plantuml");
|
|
333
|
+
var chartjs = np("@riebeckite/plugin-chartjs", "chartjs");
|
|
334
|
+
var vegaLite = np("@riebeckite/plugin-vega-lite", "vegaLite");
|
|
335
|
+
var wavedrom = np("@riebeckite/plugin-wavedrom", "wavedrom");
|
|
336
|
+
var markmap = np("@riebeckite/plugin-markmap", "markmap");
|
|
337
|
+
var marp = np("@riebeckite/plugin-marp", "marp");
|
|
338
|
+
var qrCode = np("@riebeckite/plugin-qr-code", "qrCode");
|
|
339
|
+
var discordEmbed = np("@riebeckite/plugin-discord-embed", "discordEmbed");
|
|
340
|
+
var excalidraw = np("@riebeckite/plugin-excalidraw", "excalidraw");
|
|
341
|
+
var excaliBrain = np("@riebeckite/plugin-excalibrain", "excaliBrain");
|
|
342
|
+
var canvas = np("@riebeckite/plugin-canvas", "canvas");
|
|
343
|
+
var bases = np("@riebeckite/plugin-bases", "bases");
|
|
344
|
+
var dataview = np("@riebeckite/plugin-dataview", "dataviewPlugin");
|
|
345
|
+
var flashcards = np("@riebeckite/plugin-flashcards", "flashcardsPlugin");
|
|
346
|
+
var kanban = np("@riebeckite/plugin-kanban", "kanban");
|
|
347
|
+
var query = np("@riebeckite/plugin-query", "queryPlugin");
|
|
348
|
+
var localGraph = np("@riebeckite/plugin-local-graph", "localGraphPlugin");
|
|
349
|
+
var hoverPreview = np(
|
|
350
|
+
"@riebeckite/plugin-hover-preview",
|
|
351
|
+
"hoverPreviewPlugin"
|
|
352
|
+
);
|
|
353
|
+
var gardenExplorer = np(
|
|
354
|
+
"@riebeckite/plugin-garden-explorer",
|
|
355
|
+
"gardenExplorerPlugin"
|
|
356
|
+
);
|
|
357
|
+
var ux = np("@riebeckite/plugin-ux", "uxPlugin");
|
|
358
|
+
var dailyNotes = np("@riebeckite/plugin-daily-notes", "dailyNotesPlugin");
|
|
359
|
+
var rename = np("@riebeckite/plugin-rename", "renamePlugin");
|
|
360
|
+
var textFragment = np(
|
|
361
|
+
"@riebeckite/plugin-text-fragment",
|
|
362
|
+
"textFragmentPlugin"
|
|
363
|
+
);
|
|
364
|
+
var quality = np("@riebeckite/plugin-quality", "qualityPlugin");
|
|
365
|
+
var deploy = np("@riebeckite/plugin-deploy", "deployPlugin");
|
|
366
|
+
var diagnostics = np("@riebeckite/plugin-diagnostics", "diagnostics");
|
|
367
|
+
var defaultTheme = {
|
|
368
|
+
package: "@riebeckite/theme-default",
|
|
369
|
+
factory: "defaultTheme"
|
|
280
370
|
};
|
|
281
|
-
var
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
371
|
+
var minimalTheme = {
|
|
372
|
+
package: "@riebeckite/theme-minimal",
|
|
373
|
+
factory: "minimalTheme"
|
|
374
|
+
};
|
|
375
|
+
var BASE_APP_FILES = [
|
|
376
|
+
"server",
|
|
377
|
+
"client",
|
|
378
|
+
"config",
|
|
379
|
+
"content",
|
|
380
|
+
"paths",
|
|
381
|
+
"global",
|
|
382
|
+
"style",
|
|
383
|
+
"renderer"
|
|
384
|
+
];
|
|
385
|
+
var empty = {
|
|
386
|
+
name: "empty",
|
|
387
|
+
description: "A blank application shell: no plugins, no theme, no content, no components.",
|
|
388
|
+
languages: [],
|
|
389
|
+
theme: null,
|
|
390
|
+
plugins: [],
|
|
391
|
+
contentPages: [],
|
|
392
|
+
appFiles: [...BASE_APP_FILES, "index"],
|
|
393
|
+
readme: "short"
|
|
394
|
+
};
|
|
395
|
+
var minimal = {
|
|
396
|
+
name: "minimal",
|
|
397
|
+
description: "The smallest useful site: Obsidian Markdown, the minimal theme, and one page.",
|
|
398
|
+
languages: ["en"],
|
|
399
|
+
theme: minimalTheme,
|
|
400
|
+
plugins: [obsidianMarkdown],
|
|
401
|
+
contentPages: ["index"],
|
|
402
|
+
appFiles: [...BASE_APP_FILES, "index", "slug", "article"],
|
|
403
|
+
readme: "short"
|
|
404
|
+
};
|
|
405
|
+
var starter = {
|
|
406
|
+
name: "starter",
|
|
407
|
+
description: "The default starter: Obsidian Markdown, color mode, seven languages, and a site header.",
|
|
408
|
+
languages: [...SCAFFOLD_LANGUAGES],
|
|
409
|
+
theme: defaultTheme,
|
|
410
|
+
plugins: [obsidianMarkdown, colorMode, l10n],
|
|
411
|
+
contentPages: ["index"],
|
|
412
|
+
appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
|
|
413
|
+
readme: "standard"
|
|
414
|
+
};
|
|
415
|
+
var rich = {
|
|
416
|
+
name: "rich",
|
|
417
|
+
description: "A showcasing starter: publishing and reading plugins plus guided ecosystem tour pages in seven languages.",
|
|
418
|
+
languages: [...SCAFFOLD_LANGUAGES],
|
|
419
|
+
theme: defaultTheme,
|
|
420
|
+
plugins: [
|
|
421
|
+
obsidianMarkdown,
|
|
422
|
+
colorMode,
|
|
423
|
+
l10n,
|
|
424
|
+
seo,
|
|
425
|
+
toc,
|
|
426
|
+
properties,
|
|
427
|
+
alias,
|
|
428
|
+
codeEnhance
|
|
429
|
+
],
|
|
430
|
+
contentPages: ["index", "framework/plugins", "framework/themes"],
|
|
431
|
+
appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
|
|
432
|
+
readme: "rich"
|
|
433
|
+
};
|
|
434
|
+
var full = {
|
|
435
|
+
name: "full",
|
|
436
|
+
description: "A ready blog: discovery, media, and reading plugins plus a build guide.",
|
|
437
|
+
languages: [...SCAFFOLD_LANGUAGES],
|
|
438
|
+
theme: defaultTheme,
|
|
439
|
+
plugins: [
|
|
440
|
+
obsidianMarkdown,
|
|
441
|
+
colorMode,
|
|
442
|
+
l10n,
|
|
443
|
+
seo,
|
|
444
|
+
toc,
|
|
445
|
+
properties,
|
|
446
|
+
alias,
|
|
447
|
+
codeEnhance,
|
|
448
|
+
search,
|
|
449
|
+
backlinks,
|
|
450
|
+
relatedPosts,
|
|
451
|
+
recentPosts,
|
|
452
|
+
attachment,
|
|
453
|
+
media,
|
|
454
|
+
responsiveImage,
|
|
455
|
+
lightbox,
|
|
456
|
+
highlight,
|
|
457
|
+
codeTabs,
|
|
458
|
+
codeAnnotations,
|
|
459
|
+
shortcodes,
|
|
460
|
+
series,
|
|
461
|
+
autoCardLink,
|
|
462
|
+
richEmbed
|
|
463
|
+
],
|
|
464
|
+
contentPages: ["index", "framework/plugins", "framework/themes", "guide"],
|
|
465
|
+
appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
|
|
466
|
+
readme: "rich"
|
|
467
|
+
};
|
|
468
|
+
var max = {
|
|
469
|
+
name: "max",
|
|
470
|
+
description: "Diagram and knowledge plugins on top of full, with showcase example pages.",
|
|
471
|
+
languages: [...SCAFFOLD_LANGUAGES],
|
|
472
|
+
theme: defaultTheme,
|
|
473
|
+
plugins: [
|
|
474
|
+
obsidianMarkdown,
|
|
475
|
+
colorMode,
|
|
476
|
+
l10n,
|
|
477
|
+
seo,
|
|
478
|
+
toc,
|
|
479
|
+
properties,
|
|
480
|
+
alias,
|
|
481
|
+
codeEnhance,
|
|
482
|
+
search,
|
|
483
|
+
backlinks,
|
|
484
|
+
relatedPosts,
|
|
485
|
+
recentPosts,
|
|
486
|
+
attachment,
|
|
487
|
+
media,
|
|
488
|
+
responsiveImage,
|
|
489
|
+
lightbox,
|
|
490
|
+
highlight,
|
|
491
|
+
codeTabs,
|
|
492
|
+
codeAnnotations,
|
|
493
|
+
shortcodes,
|
|
494
|
+
series,
|
|
495
|
+
autoCardLink,
|
|
496
|
+
richEmbed,
|
|
497
|
+
mermaid,
|
|
498
|
+
graphviz,
|
|
499
|
+
d2,
|
|
500
|
+
plantuml,
|
|
501
|
+
chartjs,
|
|
502
|
+
vegaLite,
|
|
503
|
+
wavedrom,
|
|
504
|
+
markmap,
|
|
505
|
+
marp,
|
|
506
|
+
qrCode,
|
|
507
|
+
discordEmbed,
|
|
508
|
+
excalidraw,
|
|
509
|
+
excaliBrain,
|
|
510
|
+
canvas,
|
|
511
|
+
bases,
|
|
512
|
+
dataview,
|
|
513
|
+
flashcards,
|
|
514
|
+
kanban,
|
|
515
|
+
query,
|
|
516
|
+
localGraph,
|
|
517
|
+
hoverPreview,
|
|
518
|
+
gardenExplorer,
|
|
519
|
+
ux
|
|
520
|
+
],
|
|
521
|
+
contentPages: [
|
|
522
|
+
"index",
|
|
523
|
+
"framework/plugins",
|
|
524
|
+
"framework/themes",
|
|
525
|
+
"guide",
|
|
526
|
+
"examples"
|
|
527
|
+
],
|
|
528
|
+
appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
|
|
529
|
+
readme: "rich"
|
|
530
|
+
};
|
|
531
|
+
var ultra = {
|
|
532
|
+
name: "ultra",
|
|
533
|
+
description: "The full plugin catalog and theme reference pages — everything the ecosystem offers.",
|
|
534
|
+
languages: [...SCAFFOLD_LANGUAGES],
|
|
535
|
+
theme: defaultTheme,
|
|
536
|
+
plugins: [
|
|
537
|
+
obsidianMarkdown,
|
|
538
|
+
colorMode,
|
|
539
|
+
l10n,
|
|
540
|
+
seo,
|
|
541
|
+
toc,
|
|
542
|
+
properties,
|
|
543
|
+
alias,
|
|
544
|
+
codeEnhance,
|
|
545
|
+
search,
|
|
546
|
+
backlinks,
|
|
547
|
+
relatedPosts,
|
|
548
|
+
recentPosts,
|
|
549
|
+
attachment,
|
|
550
|
+
media,
|
|
551
|
+
responsiveImage,
|
|
552
|
+
lightbox,
|
|
553
|
+
highlight,
|
|
554
|
+
codeTabs,
|
|
555
|
+
codeAnnotations,
|
|
556
|
+
shortcodes,
|
|
557
|
+
series,
|
|
558
|
+
autoCardLink,
|
|
559
|
+
richEmbed,
|
|
560
|
+
mermaid,
|
|
561
|
+
graphviz,
|
|
562
|
+
d2,
|
|
563
|
+
plantuml,
|
|
564
|
+
chartjs,
|
|
565
|
+
vegaLite,
|
|
566
|
+
wavedrom,
|
|
567
|
+
markmap,
|
|
568
|
+
marp,
|
|
569
|
+
qrCode,
|
|
570
|
+
discordEmbed,
|
|
571
|
+
excalidraw,
|
|
572
|
+
excaliBrain,
|
|
573
|
+
canvas,
|
|
574
|
+
bases,
|
|
575
|
+
dataview,
|
|
576
|
+
flashcards,
|
|
577
|
+
kanban,
|
|
578
|
+
query,
|
|
579
|
+
localGraph,
|
|
580
|
+
hoverPreview,
|
|
581
|
+
gardenExplorer,
|
|
582
|
+
ux,
|
|
583
|
+
dailyNotes,
|
|
584
|
+
rename,
|
|
585
|
+
textFragment,
|
|
586
|
+
quality,
|
|
587
|
+
deploy,
|
|
588
|
+
diagnostics
|
|
589
|
+
],
|
|
590
|
+
contentPages: [
|
|
591
|
+
"index",
|
|
592
|
+
"framework/plugins",
|
|
593
|
+
"framework/themes",
|
|
594
|
+
"guide",
|
|
595
|
+
"examples",
|
|
596
|
+
"reference/plugins",
|
|
597
|
+
"reference/themes"
|
|
598
|
+
],
|
|
599
|
+
appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
|
|
600
|
+
readme: "rich"
|
|
601
|
+
};
|
|
602
|
+
var scaffoldPresets = { empty, minimal, starter, rich, full, max, ultra };
|
|
603
|
+
var SCAFFOLD_DEFAULT_PRESET = "starter";
|
|
604
|
+
function resolveScaffoldPreset(value) {
|
|
605
|
+
if (value === void 0) return scaffoldPresets[SCAFFOLD_DEFAULT_PRESET];
|
|
606
|
+
if (typeof value === "object") return value;
|
|
607
|
+
const preset = scaffoldPresets[value];
|
|
608
|
+
if (!preset) {
|
|
609
|
+
throw new Error(
|
|
610
|
+
`Unknown scaffold preset: ${value}. Available presets: ${SCAFFOLD_PRESET_NAMES.join(", ")}.`
|
|
611
|
+
);
|
|
612
|
+
}
|
|
613
|
+
return preset;
|
|
285
614
|
}
|
|
286
|
-
|
|
287
|
-
|
|
615
|
+
|
|
616
|
+
// src/vite_plugin.ts
|
|
617
|
+
import path6 from "node:path";
|
|
618
|
+
|
|
619
|
+
// src/asset_entries.ts
|
|
620
|
+
import fs4 from "node:fs";
|
|
621
|
+
import path4 from "node:path";
|
|
622
|
+
import { uniqueStrings } from "@riebeckite/core";
|
|
623
|
+
function writeRiebeckiteAssetEntries(config, paths2) {
|
|
624
|
+
writeGeneratedFile(paths2.pluginStyles, createPluginStylesEntry(config));
|
|
625
|
+
writeGeneratedFile(paths2.themeStyles, createThemeStylesEntry(config));
|
|
288
626
|
}
|
|
289
|
-
function
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
{ basePath: "framework/themes", build: (language) => themesContent(language) }
|
|
295
|
-
];
|
|
296
|
-
const files = [];
|
|
297
|
-
for (const page of pages) {
|
|
298
|
-
for (const language of SCAFFOLD_LANGUAGES) {
|
|
299
|
-
const suffix = language === defaultLang ? "" : `.${language}`;
|
|
300
|
-
files.push({
|
|
301
|
-
path: `content/${page.basePath}${suffix}.md`,
|
|
302
|
-
content: page.build(language)
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return files;
|
|
627
|
+
function createPluginStylesEntry(config) {
|
|
628
|
+
return createStylesheetEntry(
|
|
629
|
+
collectPluginStyleSpecifiers(config),
|
|
630
|
+
"Plugin default styles, in resolved plugin order. Generated by @riebeckite/honox; do not edit. Import this before the theme stylesheet so a theme can override plugin defaults."
|
|
631
|
+
);
|
|
307
632
|
}
|
|
308
|
-
function
|
|
309
|
-
return
|
|
633
|
+
function createThemeStylesEntry(config) {
|
|
634
|
+
return createStylesheetEntry(
|
|
635
|
+
config.theme.styles.map((style2) => style2.moduleSpecifier),
|
|
636
|
+
"Theme styles. Generated by @riebeckite/honox; do not edit. Import this after the plugin stylesheet so the theme wins the plugin/theme cascade."
|
|
637
|
+
);
|
|
310
638
|
}
|
|
311
|
-
function
|
|
312
|
-
return
|
|
639
|
+
function collectPluginStyleSpecifiers(config) {
|
|
640
|
+
return config.plugins.flatMap(
|
|
641
|
+
(plugin) => (plugin.assets ?? []).filter((asset) => asset.kind === "style").map((asset) => asset.moduleSpecifier)
|
|
642
|
+
);
|
|
313
643
|
}
|
|
314
|
-
function
|
|
315
|
-
|
|
644
|
+
function createStylesheetEntry(moduleSpecifiers, banner) {
|
|
645
|
+
const imports = uniqueStrings(moduleSpecifiers).map((specifier) => `@import ${JSON.stringify(specifier)};`).join("\n");
|
|
646
|
+
if (!banner) return imports;
|
|
647
|
+
const header = `/* ${banner.replace(/\*\//g, "* /")} */`;
|
|
648
|
+
return imports ? `${header}
|
|
649
|
+
${imports}
|
|
650
|
+
` : `${header}
|
|
651
|
+
`;
|
|
316
652
|
}
|
|
317
|
-
function
|
|
318
|
-
|
|
653
|
+
function writeGeneratedFile(filePath, contents) {
|
|
654
|
+
fs4.mkdirSync(path4.dirname(filePath), { recursive: true });
|
|
655
|
+
fs4.writeFileSync(filePath, contents);
|
|
319
656
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
de: "Riebeckite ist ein erweiterbares, inhaltsorientiertes Framework, das schnelle statische Seiten aus einfachem Markdown baut — denselben Notizen, die du in Obsidian führst. Das Ökosystem umfasst 50+ Plugins und sechs Themes; diese Seite demonstriert beides.",
|
|
354
|
-
fr: "Riebeckite est un framework extensible et centré sur le contenu qui construit des sites statiques rapides à partir de Markdown simple — les mêmes notes que vous gardez dans Obsidian. L'écosystème inclut plus de 50 plugins et six thèmes ; ce site en démontre les deux.",
|
|
355
|
-
ko: "Riebeckite는 일반 Markdown(Obsidian에서 관리하는 노트)에서 빠른 정적 사이트를 만드는 확장 가능한 콘텐츠 우선 프레임워크입니다. 생태계에는 50개 이상의 플러그인과 6개 테마가 있으며, 이 사이트가 그 두 가지를 보여줍니다."
|
|
356
|
-
},
|
|
357
|
-
exploreHeading: {
|
|
358
|
-
en: "Explore",
|
|
359
|
-
ja: "さらに深く",
|
|
360
|
-
"zh-CN": "继续探索",
|
|
361
|
-
es: "Explorar",
|
|
362
|
-
de: "Weiter erkunden",
|
|
363
|
-
fr: "Explorer",
|
|
364
|
-
ko: "더 살펴보기"
|
|
365
|
-
},
|
|
366
|
-
explorePlugins: {
|
|
367
|
-
en: "Plugins — representative packages grouped by capability",
|
|
368
|
-
ja: "プラグイン — 機能別の代表的なパッケージ",
|
|
369
|
-
"zh-CN": "插件 — 按能力分组的代表性包",
|
|
370
|
-
es: "Plugins — paquetes representativos por capacidad",
|
|
371
|
-
de: "Plugins — repräsentative Pakete nach Fähigkeit",
|
|
372
|
-
fr: "Plugins — paquets représentatifs par capacité",
|
|
373
|
-
ko: "플러그인 — 기능별 대표 패키지"
|
|
374
|
-
},
|
|
375
|
-
exploreThemes: {
|
|
376
|
-
en: "Themes — built-in design packages and how to switch",
|
|
377
|
-
ja: "テーマ — 同梱のデザインパッケージと切り替え方",
|
|
378
|
-
"zh-CN": "主题 — 内置设计包与切换方法",
|
|
379
|
-
es: "Temas — paquetes de diseño incluidos y cómo cambiar",
|
|
380
|
-
de: "Themes — mitgelieferte Design-Pakete und wie man wechselt",
|
|
381
|
-
fr: "Thèmes — paquets de design inclus et comment changer",
|
|
382
|
-
ko: "테마 — 내장 디자인 패키지와 전환 방법"
|
|
383
|
-
},
|
|
384
|
-
editHeading: {
|
|
385
|
-
en: "Edit this site",
|
|
386
|
-
ja: "サイトの編集",
|
|
387
|
-
"zh-CN": "编辑本站点",
|
|
388
|
-
es: "Editar este sitio",
|
|
389
|
-
de: "Diese Seite bearbeiten",
|
|
390
|
-
fr: "Éditer ce site",
|
|
391
|
-
ko: "사이트 편집"
|
|
392
|
-
},
|
|
393
|
-
editLead: {
|
|
394
|
-
en: "Content lives in `content/` as plain Markdown. Add a file, give it `publish: true` in the frontmatter, and it appears in the built site.",
|
|
395
|
-
ja: "コンテンツは `content/` にプレーンな Markdown として置きます。ファイルを追加してフロントマターに `publish: true` を書けば、ビルドされたサイトに反映されます。",
|
|
396
|
-
"zh-CN": "内容以纯 Markdown 存于 `content/`。新建文件并在 frontmatter 中写入 `publish: true`,它就会出现在构建后的站点中。",
|
|
397
|
-
es: "El contenido vive en `content/` como Markdown simple. Añade un archivo, pon `publish: true` en el frontmatter y aparecerá en el sitio compilado.",
|
|
398
|
-
de: "Inhalte liegen als einfaches Markdown in `content/`. Füge eine Datei hinzu, setze `publish: true` ins Frontmatter, und sie erscheint in der gebauten Seite.",
|
|
399
|
-
fr: "Le contenu vit dans `content/` en Markdown simple. Ajoutez un fichier, donnez-lui `publish: true` dans le frontmatter, et il apparaîtra dans le site construit.",
|
|
400
|
-
ko: "콘텐츠는 `content/`에 일반 Markdown으로 저장됩니다. 파일을 추가하고 프론트매터에 `publish: true`를 쓰면 빌드된 사이트에 나타납니다."
|
|
401
|
-
},
|
|
402
|
-
editL10n: {
|
|
403
|
-
en: "Localized pages use the `<base>.<lang>.md` convention next to the default file — for example `about.ja.md`. The l10n plugin serves them under `/lang/` paths and links them automatically.",
|
|
404
|
-
ja: "翻訳ページは既定ファイルの隣に `<base>.<lang>.md` の命名規則で置きます(例:`about.ja.md`)。l10n プラグインが `/lang/` パスの配下で配信し、自動的にリンクします。",
|
|
405
|
-
"zh-CN": "本地化页面采用默认文件旁的 `<base>.<lang>.md` 命名约定(例如 `about.ja.md`)。l10n 插件会在 `/lang/` 路径下提供服务并自动互链。",
|
|
406
|
-
es: "Las páginas localizadas usan la convención `<base>.<lang>.md` junto al archivo por defecto (p. ej. `about.ja.md`). El plugin l10n las sirve bajo rutas `/lang/` y las enlaza automáticamente.",
|
|
407
|
-
de: "Übersetzte Seiten folgen der Konvention `<base>.<lang>.md` neben der Standarddatei (z. B. `about.ja.md`). Das l10n-Plugin liefert sie unter `/lang/`-Pfaden und verlinkt sie automatisch.",
|
|
408
|
-
fr: "Les pages localisées suivent la convention `<base>.<lang>.md` à côté du fichier par défaut (ex. `about.ja.md`). Le plugin l10n les sert sous des chemins `/lang/` et les relie automatiquement.",
|
|
409
|
-
ko: "번역 페이지는 기본 파일 옆에 `<base>.<lang>.md` 규칙으로 둡니다(예: `about.ja.md`). l10n 플러그인이 `/lang/` 경로로 서빙하며 자동으로 링크합니다."
|
|
657
|
+
|
|
658
|
+
// src/client_module.ts
|
|
659
|
+
import {
|
|
660
|
+
serializePublicClientConfig
|
|
661
|
+
} from "@riebeckite/core";
|
|
662
|
+
var clientModuleId = "virtual:riebeckite/client";
|
|
663
|
+
var resolvedClientModuleId = `\0${clientModuleId}`;
|
|
664
|
+
function riebeckiteClientModule(getConfig) {
|
|
665
|
+
return {
|
|
666
|
+
name: "riebeckite-client-module",
|
|
667
|
+
resolveId(id) {
|
|
668
|
+
if (id === clientModuleId) return resolvedClientModuleId;
|
|
669
|
+
return null;
|
|
670
|
+
},
|
|
671
|
+
load(id) {
|
|
672
|
+
if (id !== resolvedClientModuleId) return null;
|
|
673
|
+
return createClientModule(getConfig());
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
function createClientModule(config) {
|
|
678
|
+
const imports = [];
|
|
679
|
+
const initializers = [];
|
|
680
|
+
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
681
|
+
const localName = `pluginClientInitializer${index}`;
|
|
682
|
+
const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
|
|
683
|
+
imports.push(
|
|
684
|
+
`import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
|
|
685
|
+
);
|
|
686
|
+
const publicConfig = entry.publicConfig;
|
|
687
|
+
initializers.push(
|
|
688
|
+
publicConfig === void 0 ? `${localName}()` : `${localName}(${serializePublicClientConfig(publicConfig)})`
|
|
689
|
+
);
|
|
410
690
|
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
frontmatter(),
|
|
416
|
-
heading(1, title),
|
|
417
|
-
read(INDEX.lead, language),
|
|
418
|
-
read(INDEX.translatedNote, language),
|
|
419
|
-
heading(2, read(INDEX.whatHeading, language)),
|
|
420
|
-
read(INDEX.whatBody, language),
|
|
421
|
-
heading(2, read(INDEX.exploreHeading, language)),
|
|
422
|
-
`- [${read(INDEX.explorePlugins, language)}](/framework/plugins)`,
|
|
423
|
-
`- [${read(INDEX.exploreThemes, language)}](/framework/themes)`,
|
|
424
|
-
heading(2, read(INDEX.editHeading, language)),
|
|
425
|
-
read(INDEX.editLead, language),
|
|
426
|
-
read(INDEX.editL10n, language),
|
|
427
|
-
""
|
|
428
|
-
].join("\n");
|
|
691
|
+
return `${imports.join("\n")}
|
|
692
|
+
|
|
693
|
+
export function initRiebeckiteClient() {
|
|
694
|
+
${initializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
429
695
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
696
|
+
`;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// src/ssg_plugin.ts
|
|
700
|
+
import { defaultExtensionMap, toSSG } from "hono/ssg";
|
|
701
|
+
import { relative } from "node:path";
|
|
702
|
+
import { createServer } from "vite";
|
|
703
|
+
var defaultEntry = "./src/index.tsx";
|
|
704
|
+
function riebeckiteSsg(options = {}) {
|
|
705
|
+
const virtualId = "virtual:riebeckite-ssg-void-entry";
|
|
706
|
+
const resolvedVirtualId = `\0${virtualId}`;
|
|
707
|
+
const entry = options.entry ?? defaultEntry;
|
|
708
|
+
let resolvedConfig;
|
|
709
|
+
return {
|
|
710
|
+
name: "riebeckite-ssg",
|
|
711
|
+
apply: "build",
|
|
712
|
+
enforce: "post",
|
|
713
|
+
config() {
|
|
714
|
+
return {
|
|
715
|
+
build: {
|
|
716
|
+
rollupOptions: {
|
|
717
|
+
input: [virtualId]
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
},
|
|
722
|
+
configResolved(config) {
|
|
723
|
+
resolvedConfig = config;
|
|
724
|
+
},
|
|
725
|
+
resolveId(id) {
|
|
726
|
+
return id === virtualId ? resolvedVirtualId : void 0;
|
|
727
|
+
},
|
|
728
|
+
load(id) {
|
|
729
|
+
return id === resolvedVirtualId ? 'console.log("suppress empty chunk message")' : void 0;
|
|
730
|
+
},
|
|
731
|
+
async generateBundle(_outputOptions, bundle) {
|
|
732
|
+
const config = resolvedConfig;
|
|
733
|
+
if (!config) {
|
|
734
|
+
throw new Error("Riebeckite SSG could not resolve the Vite configuration.");
|
|
735
|
+
}
|
|
736
|
+
removeVirtualEntryChunk(bundle, resolvedVirtualId);
|
|
737
|
+
const server2 = await createServer({
|
|
738
|
+
root: config.root,
|
|
739
|
+
define: config.define,
|
|
740
|
+
resolve: {
|
|
741
|
+
...config.resolve,
|
|
742
|
+
builtins: [...config.resolve.builtins, /^node:/]
|
|
743
|
+
},
|
|
744
|
+
plugins: [],
|
|
745
|
+
build: { ssr: true },
|
|
746
|
+
mode: config.mode
|
|
747
|
+
});
|
|
748
|
+
try {
|
|
749
|
+
const module = await server2.ssrLoadModule(entry);
|
|
750
|
+
const app = module.default;
|
|
751
|
+
if (!app) {
|
|
752
|
+
throw new Error(`Failed to find a default export from ${entry}.`);
|
|
753
|
+
}
|
|
754
|
+
const generatedHtml = [];
|
|
755
|
+
const result = await toSSG(
|
|
756
|
+
app,
|
|
757
|
+
{
|
|
758
|
+
writeFile: async (filePath, data) => {
|
|
759
|
+
const fileName = relative(config.build.outDir, filePath).replaceAll(
|
|
760
|
+
"\\",
|
|
761
|
+
"/"
|
|
762
|
+
);
|
|
763
|
+
if (fileName.endsWith(".html") && typeof data === "string") {
|
|
764
|
+
generatedHtml.push({ path: fileName, html: data });
|
|
765
|
+
}
|
|
766
|
+
this.emitFile({
|
|
767
|
+
type: "asset",
|
|
768
|
+
fileName,
|
|
769
|
+
source: data
|
|
770
|
+
});
|
|
771
|
+
},
|
|
772
|
+
async mkdir() {
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
dir: config.build.outDir,
|
|
777
|
+
plugins: options.plugins ?? [],
|
|
778
|
+
extensionMap: options.extensionMap ?? defaultExtensionMap
|
|
779
|
+
}
|
|
780
|
+
);
|
|
781
|
+
if (!result.success) throw result.error;
|
|
782
|
+
await emitGeneratedOutputs(
|
|
783
|
+
module,
|
|
784
|
+
(asset) => this.emitFile(asset)
|
|
785
|
+
);
|
|
786
|
+
inspectGeneratedHtmlPages(module, generatedHtml, {
|
|
787
|
+
warn: (message) => this.warn(message),
|
|
788
|
+
info: (message) => this.info(message)
|
|
789
|
+
});
|
|
790
|
+
} finally {
|
|
791
|
+
await server2.close();
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
async function emitGeneratedOutputs(module, emit) {
|
|
797
|
+
const content = module.content;
|
|
798
|
+
if (!content) return;
|
|
799
|
+
const manifest = await content.getManifest();
|
|
800
|
+
for (const output of manifest.generatedOutputs ?? []) {
|
|
801
|
+
emit({
|
|
802
|
+
type: "asset",
|
|
803
|
+
fileName: output.path,
|
|
804
|
+
source: output.content
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
function inspectGeneratedHtmlPages(module, pages, log) {
|
|
809
|
+
const plugins = module.config?.plugins ?? [];
|
|
810
|
+
for (const plugin of plugins) {
|
|
811
|
+
const inspector = plugin.inspectGeneratedHtml;
|
|
812
|
+
if (typeof inspector !== "function") continue;
|
|
813
|
+
for (const page of pages) {
|
|
814
|
+
for (const diagnostic of inspector(page) ?? []) {
|
|
815
|
+
const label = `[${plugin.name ?? "plugin"}] ${page.path}: ${diagnostic.message}`;
|
|
816
|
+
if (diagnostic.severity === "info") log.info(label);
|
|
817
|
+
else log.warn(label);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
function removeVirtualEntryChunk(bundle, virtualEntryId) {
|
|
823
|
+
for (const chunk of Object.values(bundle)) {
|
|
824
|
+
if (chunk.type === "chunk" && chunk.moduleIds?.includes(virtualEntryId)) {
|
|
825
|
+
delete bundle[chunk.fileName];
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// src/ssg.ts
|
|
831
|
+
var defaultSsgEntry = "./app/server.ts";
|
|
832
|
+
function riebeckiteSsgExtensionMap() {
|
|
833
|
+
return {
|
|
834
|
+
"application/atom+xml": "xml",
|
|
835
|
+
"application/json": "json",
|
|
836
|
+
"application/rss+xml": "xml",
|
|
837
|
+
"application/xml": "xml",
|
|
838
|
+
"text/html": "html",
|
|
839
|
+
"text/plain": "txt",
|
|
840
|
+
"text/xml": "xml"
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
function createRiebeckiteSsg(options = {}) {
|
|
844
|
+
return riebeckiteSsg({
|
|
845
|
+
...options,
|
|
846
|
+
entry: options.entry ?? defaultSsgEntry,
|
|
847
|
+
extensionMap: {
|
|
848
|
+
...riebeckiteSsgExtensionMap(),
|
|
849
|
+
...options.extensionMap
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// src/vite_runner.ts
|
|
855
|
+
import fs5 from "node:fs/promises";
|
|
856
|
+
import path5 from "node:path";
|
|
857
|
+
import { build, createServer as createServer2 } from "vite";
|
|
858
|
+
var viteConfigFileNames = [
|
|
859
|
+
"vite.config.ts",
|
|
860
|
+
"vite.config.js",
|
|
861
|
+
"vite.config.mjs"
|
|
862
|
+
];
|
|
863
|
+
async function resolveHonoxApplicationRoot(configRoot) {
|
|
864
|
+
const roots = await findViteApplicationRoots(configRoot);
|
|
865
|
+
if (roots.length === 1) return roots[0];
|
|
866
|
+
if (roots.length === 0) {
|
|
867
|
+
throw new HonoxApplicationRootError(
|
|
868
|
+
`Could not find a Vite application under ${configRoot}.`
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
throw new HonoxApplicationRootError(
|
|
872
|
+
`Found multiple Vite applications under ${configRoot}: ${roots.join(", ")}.`
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
var HonoxApplicationRootError = class extends Error {
|
|
876
|
+
constructor(message) {
|
|
877
|
+
super(message);
|
|
878
|
+
this.name = "HonoxApplicationRootError";
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
async function resolveHonoxApplication(options) {
|
|
882
|
+
const configRoot = path5.resolve(options.configRoot);
|
|
883
|
+
const appRoot = options.appRoot ? path5.resolve(options.appRoot) : await resolveHonoxApplicationRoot(configRoot);
|
|
884
|
+
const workspaceRoot = options.workspaceRoot ?? await findWorkspaceRoot(configRoot);
|
|
885
|
+
const rawConfig = await loadRiebeckiteConfig({
|
|
886
|
+
configRoot,
|
|
887
|
+
configFile: options.configFile,
|
|
888
|
+
workspaceRoot
|
|
889
|
+
});
|
|
890
|
+
const config = resolveHonoxConfig(rawConfig, appRoot);
|
|
891
|
+
return {
|
|
892
|
+
config,
|
|
893
|
+
configRoot,
|
|
894
|
+
appRoot,
|
|
895
|
+
contentRoot: config.content.directory
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
async function findWorkspaceRoot(configRoot) {
|
|
899
|
+
try {
|
|
900
|
+
const workspaceConfig = path5.join(configRoot, "pnpm-workspace.yaml");
|
|
901
|
+
return (await fs5.stat(workspaceConfig)).isFile() ? configRoot : void 0;
|
|
902
|
+
} catch {
|
|
903
|
+
return void 0;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
async function startHonoxDevServer(options) {
|
|
907
|
+
const server2 = await createServer2({ root: options.root });
|
|
908
|
+
await server2.listen();
|
|
909
|
+
server2.printUrls();
|
|
910
|
+
await waitForShutdown(server2);
|
|
911
|
+
}
|
|
912
|
+
async function buildHonoxApplication(options) {
|
|
913
|
+
await runTraced(
|
|
914
|
+
options.tracer,
|
|
915
|
+
"integration.honox.client_build",
|
|
916
|
+
() => build({ root: options.root, mode: "client" })
|
|
917
|
+
);
|
|
918
|
+
await runTraced(
|
|
919
|
+
options.tracer,
|
|
920
|
+
"integration.honox.server_build",
|
|
921
|
+
() => build({ root: options.root })
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
async function runTraced(tracer, name, buildTask) {
|
|
925
|
+
return tracer ? await tracer.span(name, {}, buildTask) : await buildTask();
|
|
926
|
+
}
|
|
927
|
+
async function waitForShutdown(server2) {
|
|
928
|
+
await new Promise((resolve) => {
|
|
929
|
+
const close = () => {
|
|
930
|
+
void server2.close().finally(resolve);
|
|
931
|
+
};
|
|
932
|
+
process.once("SIGINT", close);
|
|
933
|
+
process.once("SIGTERM", close);
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
async function findViteApplicationRoots(root) {
|
|
937
|
+
const directories = [root];
|
|
938
|
+
const applicationRoots = [];
|
|
939
|
+
while (directories.length > 0) {
|
|
940
|
+
const directory = directories.pop();
|
|
941
|
+
if (!directory) continue;
|
|
942
|
+
if (await hasViteConfig(directory)) applicationRoots.push(directory);
|
|
943
|
+
const entries = await fs5.readdir(directory, { withFileTypes: true });
|
|
944
|
+
for (const entry of entries) {
|
|
945
|
+
if (!entry.isDirectory() || entry.name === "node_modules" || entry.name === ".git" || entry.name === "tests") {
|
|
946
|
+
continue;
|
|
947
|
+
}
|
|
948
|
+
directories.push(path5.join(directory, entry.name));
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
return applicationRoots;
|
|
952
|
+
}
|
|
953
|
+
async function hasViteConfig(directory) {
|
|
954
|
+
for (const fileName of viteConfigFileNames) {
|
|
955
|
+
try {
|
|
956
|
+
if ((await fs5.stat(path5.join(directory, fileName))).isFile()) return true;
|
|
957
|
+
} catch {
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return false;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
// src/vite_plugin.ts
|
|
964
|
+
var defaultSsrExternals = [
|
|
965
|
+
"extend",
|
|
966
|
+
"debug",
|
|
967
|
+
"node:fs/promises",
|
|
968
|
+
"node:path",
|
|
969
|
+
"parse-numeric-range",
|
|
970
|
+
"slugify",
|
|
971
|
+
"vfile-matter",
|
|
972
|
+
"yaml"
|
|
973
|
+
];
|
|
974
|
+
function riebeckite(options = {}) {
|
|
975
|
+
let resolvedConfig;
|
|
976
|
+
const getConfig = () => {
|
|
977
|
+
if (!resolvedConfig) {
|
|
978
|
+
throw new Error("Riebeckite config has not been loaded yet.");
|
|
979
|
+
}
|
|
980
|
+
return resolvedConfig;
|
|
981
|
+
};
|
|
982
|
+
return [
|
|
983
|
+
{
|
|
984
|
+
name: "riebeckite-host-integration",
|
|
985
|
+
async config(userConfig) {
|
|
986
|
+
const root = userConfig.root ? path6.resolve(userConfig.root) : process.cwd();
|
|
987
|
+
const appRoot = options.appRoot ?? root;
|
|
988
|
+
const application = await resolveHonoxApplication({
|
|
989
|
+
configRoot: options.configRoot ?? appRoot,
|
|
990
|
+
configFile: options.configFile,
|
|
991
|
+
appRoot,
|
|
992
|
+
workspaceRoot: options.workspaceRoot
|
|
993
|
+
});
|
|
994
|
+
resolvedConfig = application.config;
|
|
995
|
+
writeRiebeckiteAssetEntries(resolvedConfig, {
|
|
996
|
+
pluginStyles: path6.join(appRoot, "app/.riebeckite/plugin-styles.css"),
|
|
997
|
+
themeStyles: path6.join(appRoot, "app/.riebeckite/theme-styles.css")
|
|
998
|
+
});
|
|
999
|
+
return {
|
|
1000
|
+
define: {
|
|
1001
|
+
"process.env.RIEBECKITE_APP_ROOT": JSON.stringify(appRoot)
|
|
1002
|
+
},
|
|
1003
|
+
resolve: {
|
|
1004
|
+
alias: options.workspaceRoot ? createWorkspacePackageAliases(options.workspaceRoot) : []
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
},
|
|
1009
|
+
riebeckiteClientModule(getConfig)
|
|
1010
|
+
];
|
|
1011
|
+
}
|
|
1012
|
+
function riebeckiteVite(options = {}) {
|
|
1013
|
+
const { ssg, ssrExternals, ...integration } = options;
|
|
1014
|
+
return [
|
|
1015
|
+
...riebeckite(integration),
|
|
1016
|
+
riebeckiteSsrExternals([...defaultSsrExternals, ...ssrExternals ?? []]),
|
|
1017
|
+
createRiebeckiteSsg(ssg)
|
|
1018
|
+
];
|
|
1019
|
+
}
|
|
1020
|
+
function riebeckiteSsrExternals(externals) {
|
|
1021
|
+
return {
|
|
1022
|
+
name: "riebeckite-ssr-externals",
|
|
1023
|
+
config() {
|
|
1024
|
+
return {
|
|
1025
|
+
environments: {
|
|
1026
|
+
ssr: {
|
|
1027
|
+
resolve: {
|
|
1028
|
+
external: [...externals]
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// src/scaffold/localized-content.ts
|
|
1038
|
+
var HELPERS = {
|
|
1039
|
+
en: "https://github.com/Rerurate514/riebeckite/blob/main/docs/en/README.md",
|
|
1040
|
+
ja: "https://github.com/Rerurate514/riebeckite/blob/main/docs/ja/README.md"
|
|
1041
|
+
};
|
|
1042
|
+
var PLUGIN_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/plugins";
|
|
1043
|
+
var THEMES_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/themes";
|
|
1044
|
+
function pluginReadmeUrl(slug) {
|
|
1045
|
+
return `https://github.com/Rerurate514/riebeckite/blob/main/packages/plugins/${slug}/README.md`;
|
|
1046
|
+
}
|
|
1047
|
+
function themeReadmeUrl(slug) {
|
|
1048
|
+
return `https://github.com/Rerurate514/riebeckite/blob/main/packages/themes/${slug}/README.md`;
|
|
1049
|
+
}
|
|
1050
|
+
function localizedContentFiles(variables, preset) {
|
|
1051
|
+
const defaultLang = defaultLanguageForLocale(variables.locale);
|
|
1052
|
+
const files = [];
|
|
1053
|
+
const localized = preset.languages.length > 1;
|
|
1054
|
+
const pushLocalized = (basePath, build2) => {
|
|
1055
|
+
if (!localized) {
|
|
1056
|
+
files.push({
|
|
1057
|
+
path: `content/${basePath}.md`,
|
|
1058
|
+
content: build2(defaultLang)
|
|
1059
|
+
});
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
for (const language of SCAFFOLD_LANGUAGES) {
|
|
1063
|
+
const suffix = language === defaultLang ? "" : `.${language}`;
|
|
1064
|
+
files.push({
|
|
1065
|
+
path: `content/${basePath}${suffix}.md`,
|
|
1066
|
+
content: build2(language)
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
};
|
|
1070
|
+
const pushEnglishOnly = (basePath, build2) => {
|
|
1071
|
+
const suffix = defaultLang === "en" ? "" : ".en";
|
|
1072
|
+
files.push({
|
|
1073
|
+
path: `content/${basePath}${suffix}.md`,
|
|
1074
|
+
content: build2()
|
|
1075
|
+
});
|
|
1076
|
+
};
|
|
1077
|
+
for (const page of preset.contentPages) {
|
|
1078
|
+
if (page === "index") {
|
|
1079
|
+
pushLocalized("index", (language) => indexContent(variables, language));
|
|
1080
|
+
} else if (page === "framework/plugins") {
|
|
1081
|
+
pushLocalized("framework/plugins", (language) => pluginsContent(language));
|
|
1082
|
+
} else if (page === "framework/themes") {
|
|
1083
|
+
pushLocalized("framework/themes", (language) => themesContent(language));
|
|
1084
|
+
} else if (page === "guide") {
|
|
1085
|
+
pushEnglishOnly("guide", guideContent);
|
|
1086
|
+
} else if (page === "examples") {
|
|
1087
|
+
pushEnglishOnly("examples", examplesContent);
|
|
1088
|
+
} else if (page === "reference/plugins") {
|
|
1089
|
+
pushEnglishOnly("reference/plugins", () => referencePluginsContent(preset));
|
|
1090
|
+
} else if (page === "reference/themes") {
|
|
1091
|
+
pushEnglishOnly("reference/themes", referenceThemesContent);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return files;
|
|
1095
|
+
}
|
|
1096
|
+
function read(text, language) {
|
|
1097
|
+
return text[language];
|
|
1098
|
+
}
|
|
1099
|
+
function frontmatter() {
|
|
1100
|
+
return ["---", "publish: true", "---", ""].join("\n");
|
|
1101
|
+
}
|
|
1102
|
+
function heading(level, text) {
|
|
1103
|
+
return `${"#".repeat(level)} ${text}`;
|
|
1104
|
+
}
|
|
1105
|
+
function codeBlock(language, code) {
|
|
1106
|
+
return ["```" + language, code, "```", ""].join("\n");
|
|
1107
|
+
}
|
|
1108
|
+
var INDEX = {
|
|
1109
|
+
lead: {
|
|
1110
|
+
en: "Welcome to your Riebeckite site.",
|
|
1111
|
+
ja: "あなたの Riebeckite サイトへようこそ。",
|
|
1112
|
+
"zh-CN": "欢迎来到你的 Riebeckite 站点。",
|
|
1113
|
+
es: "Bienvenido a tu sitio Riebeckite.",
|
|
1114
|
+
de: "Willkommen auf deiner Riebeckite-Seite.",
|
|
1115
|
+
fr: "Bienvenue sur votre site Riebeckite.",
|
|
1116
|
+
ko: "Riebeckite 사이트에 오신 것을 환영합니다."
|
|
1117
|
+
},
|
|
1118
|
+
translatedNote: {
|
|
1119
|
+
en: "Every page of this starter is available in seven languages. Switch with the selector below the page title.",
|
|
1120
|
+
ja: "このスターターのすべてのページは 7 言語で利用できます。ページタイトル下のセレクターで切り替えられます。",
|
|
1121
|
+
"zh-CN": "本模板的每个页面均提供七种语言版本,可用页面标题下方的选择器切换。",
|
|
1122
|
+
es: "Cada página de este starter está disponible en siete idiomas. Cámbialos con el selector bajo el título.",
|
|
1123
|
+
de: "Jede Seite dieses Starters ist in sieben Sprachen verfügbar. Wechsel mit dem Auswahlfeld unter dem Seitentitel.",
|
|
1124
|
+
fr: "Chaque page de ce starter est disponible en sept langues. Changez avec le sélecteur sous le titre.",
|
|
1125
|
+
ko: "이 스타터의 모든 페이지는 7개 언어로 제공됩니다. 페이지 제목 아래 선택기로 전환하세요."
|
|
1126
|
+
},
|
|
1127
|
+
whatHeading: {
|
|
1128
|
+
en: "What is Riebeckite?",
|
|
1129
|
+
ja: "Riebeckite とは",
|
|
1130
|
+
"zh-CN": "什么是 Riebeckite?",
|
|
1131
|
+
es: "¿Qué es Riebeckite?",
|
|
1132
|
+
de: "Was ist Riebeckite?",
|
|
1133
|
+
fr: "Qu'est-ce que Riebeckite ?",
|
|
1134
|
+
ko: "Riebeckite란?"
|
|
1135
|
+
},
|
|
1136
|
+
whatBody: {
|
|
1137
|
+
en: "Riebeckite is an extensible, content-first framework that builds fast static sites from plain Markdown — the same notes you keep in Obsidian. The ecosystem includes 50+ plugins and six themes, and this site demos both.",
|
|
1138
|
+
ja: "Riebeckite は、プレーンな Markdown(Obsidian で管理しているのと同じノート)から高速な静的サイトを生成する、拡張性のあるコンテンツファーストのフレームワークです。エコシステムには 50 以上のプラグインと 6 つのテーマがあり、このサイトはその両方をデモしています。",
|
|
1139
|
+
"zh-CN": "Riebeckite 是一个可扩展、内容优先的框架,可从纯 Markdown(即你在 Obsidian 中保存的笔记)构建快速的静态站点。生态包含 50+ 插件与六个主题,本站点同时演示两者。",
|
|
1140
|
+
es: "Riebeckite es un framework extensible y orientado al contenido que construye sitios estáticos rápidos desde Markdown simple — las mismas notas que guardas en Obsidian. El ecosistema incluye más de 50 plugins y seis temas; este sitio demuestra ambos.",
|
|
1141
|
+
de: "Riebeckite ist ein erweiterbares, inhaltsorientiertes Framework, das schnelle statische Seiten aus einfachem Markdown baut — denselben Notizen, die du in Obsidian führst. Das Ökosystem umfasst 50+ Plugins und sechs Themes; diese Seite demonstriert beides.",
|
|
1142
|
+
fr: "Riebeckite est un framework extensible et centré sur le contenu qui construit des sites statiques rapides à partir de Markdown simple — les mêmes notes que vous gardez dans Obsidian. L'écosystème inclut plus de 50 plugins et six thèmes ; ce site en démontre les deux.",
|
|
1143
|
+
ko: "Riebeckite는 일반 Markdown(Obsidian에서 관리하는 노트)에서 빠른 정적 사이트를 만드는 확장 가능한 콘텐츠 우선 프레임워크입니다. 생태계에는 50개 이상의 플러그인과 6개 테마가 있으며, 이 사이트가 그 두 가지를 보여줍니다."
|
|
1144
|
+
},
|
|
1145
|
+
exploreHeading: {
|
|
1146
|
+
en: "Explore",
|
|
1147
|
+
ja: "さらに深く",
|
|
1148
|
+
"zh-CN": "继续探索",
|
|
1149
|
+
es: "Explorar",
|
|
1150
|
+
de: "Weiter erkunden",
|
|
1151
|
+
fr: "Explorer",
|
|
1152
|
+
ko: "더 살펴보기"
|
|
1153
|
+
},
|
|
1154
|
+
explorePlugins: {
|
|
1155
|
+
en: "Plugins — representative packages grouped by capability",
|
|
1156
|
+
ja: "プラグイン — 機能別の代表的なパッケージ",
|
|
1157
|
+
"zh-CN": "插件 — 按能力分组的代表性包",
|
|
1158
|
+
es: "Plugins — paquetes representativos por capacidad",
|
|
1159
|
+
de: "Plugins — repräsentative Pakete nach Fähigkeit",
|
|
1160
|
+
fr: "Plugins — paquets représentatifs par capacité",
|
|
1161
|
+
ko: "플러그인 — 기능별 대표 패키지"
|
|
1162
|
+
},
|
|
1163
|
+
exploreThemes: {
|
|
1164
|
+
en: "Themes — built-in design packages and how to switch",
|
|
1165
|
+
ja: "テーマ — 同梱のデザインパッケージと切り替え方",
|
|
1166
|
+
"zh-CN": "主题 — 内置设计包与切换方法",
|
|
1167
|
+
es: "Temas — paquetes de diseño incluidos y cómo cambiar",
|
|
1168
|
+
de: "Themes — mitgelieferte Design-Pakete und wie man wechselt",
|
|
1169
|
+
fr: "Thèmes — paquets de design inclus et comment changer",
|
|
1170
|
+
ko: "테마 — 내장 디자인 패키지와 전환 방법"
|
|
1171
|
+
},
|
|
1172
|
+
editHeading: {
|
|
1173
|
+
en: "Edit this site",
|
|
1174
|
+
ja: "サイトの編集",
|
|
1175
|
+
"zh-CN": "编辑本站点",
|
|
1176
|
+
es: "Editar este sitio",
|
|
1177
|
+
de: "Diese Seite bearbeiten",
|
|
1178
|
+
fr: "Éditer ce site",
|
|
1179
|
+
ko: "사이트 편집"
|
|
1180
|
+
},
|
|
1181
|
+
editLead: {
|
|
1182
|
+
en: "Content lives in `content/` as plain Markdown. Add a file, give it `publish: true` in the frontmatter, and it appears in the built site.",
|
|
1183
|
+
ja: "コンテンツは `content/` にプレーンな Markdown として置きます。ファイルを追加してフロントマターに `publish: true` を書けば、ビルドされたサイトに反映されます。",
|
|
1184
|
+
"zh-CN": "内容以纯 Markdown 存于 `content/`。新建文件并在 frontmatter 中写入 `publish: true`,它就会出现在构建后的站点中。",
|
|
1185
|
+
es: "El contenido vive en `content/` como Markdown simple. Añade un archivo, pon `publish: true` en el frontmatter y aparecerá en el sitio compilado.",
|
|
1186
|
+
de: "Inhalte liegen als einfaches Markdown in `content/`. Füge eine Datei hinzu, setze `publish: true` ins Frontmatter, und sie erscheint in der gebauten Seite.",
|
|
1187
|
+
fr: "Le contenu vit dans `content/` en Markdown simple. Ajoutez un fichier, donnez-lui `publish: true` dans le frontmatter, et il apparaîtra dans le site construit.",
|
|
1188
|
+
ko: "콘텐츠는 `content/`에 일반 Markdown으로 저장됩니다. 파일을 추가하고 프론트매터에 `publish: true`를 쓰면 빌드된 사이트에 나타납니다."
|
|
1189
|
+
},
|
|
1190
|
+
editL10n: {
|
|
1191
|
+
en: "Localized pages use the `<base>.<lang>.md` convention next to the default file — for example `about.ja.md`. The l10n plugin serves them under `/lang/` paths and links them automatically.",
|
|
1192
|
+
ja: "翻訳ページは既定ファイルの隣に `<base>.<lang>.md` の命名規則で置きます(例:`about.ja.md`)。l10n プラグインが `/lang/` パスの配下で配信し、自動的にリンクします。",
|
|
1193
|
+
"zh-CN": "本地化页面采用默认文件旁的 `<base>.<lang>.md` 命名约定(例如 `about.ja.md`)。l10n 插件会在 `/lang/` 路径下提供服务并自动互链。",
|
|
1194
|
+
es: "Las páginas localizadas usan la convención `<base>.<lang>.md` junto al archivo por defecto (p. ej. `about.ja.md`). El plugin l10n las sirve bajo rutas `/lang/` y las enlaza automáticamente.",
|
|
1195
|
+
de: "Übersetzte Seiten folgen der Konvention `<base>.<lang>.md` neben der Standarddatei (z. B. `about.ja.md`). Das l10n-Plugin liefert sie unter `/lang/`-Pfaden und verlinkt sie automatisch.",
|
|
1196
|
+
fr: "Les pages localisées suivent la convention `<base>.<lang>.md` à côté du fichier par défaut (ex. `about.ja.md`). Le plugin l10n les sert sous des chemins `/lang/` et les relie automatiquement.",
|
|
1197
|
+
ko: "번역 페이지는 기본 파일 옆에 `<base>.<lang>.md` 규칙으로 둡니다(예: `about.ja.md`). l10n 플러그인이 `/lang/` 경로로 서빙하며 자동으로 링크합니다."
|
|
1198
|
+
}
|
|
1199
|
+
};
|
|
1200
|
+
function indexContent(variables, language) {
|
|
1201
|
+
const title = variables.title;
|
|
1202
|
+
return [
|
|
1203
|
+
frontmatter(),
|
|
1204
|
+
heading(1, title),
|
|
1205
|
+
read(INDEX.lead, language),
|
|
1206
|
+
read(INDEX.translatedNote, language),
|
|
1207
|
+
heading(2, read(INDEX.whatHeading, language)),
|
|
1208
|
+
read(INDEX.whatBody, language),
|
|
1209
|
+
heading(2, read(INDEX.exploreHeading, language)),
|
|
1210
|
+
`- [${read(INDEX.explorePlugins, language)}](/framework/plugins)`,
|
|
1211
|
+
`- [${read(INDEX.exploreThemes, language)}](/framework/themes)`,
|
|
1212
|
+
heading(2, read(INDEX.editHeading, language)),
|
|
1213
|
+
read(INDEX.editLead, language),
|
|
1214
|
+
read(INDEX.editL10n, language),
|
|
1215
|
+
""
|
|
1216
|
+
].join("\n");
|
|
1217
|
+
}
|
|
1218
|
+
var THEMES_COPY = {
|
|
1219
|
+
title: {
|
|
1220
|
+
en: "Themes",
|
|
1221
|
+
ja: "テーマ",
|
|
1222
|
+
"zh-CN": "主题",
|
|
1223
|
+
es: "Temas",
|
|
1224
|
+
de: "Themen",
|
|
1225
|
+
fr: "Thèmes",
|
|
1226
|
+
ko: "테마"
|
|
1227
|
+
},
|
|
1228
|
+
intro: {
|
|
1229
|
+
en: "A theme changes the whole look and feel of a site — colors, typography, and layout — without touching your content or routes. Riebeckite ships with six themes; switch by installing a package and changing one line.",
|
|
1230
|
+
ja: "テーマを変えるだけで、色・文字組み・レイアウトといったサイト全体の見た目が変わります。コンテンツやルートには一切触れる必要はありません。Riebeckite には 6 つのテーマが用意されており、パッケージをインストールして 1 行書き換えるだけで切り替えられます。",
|
|
1231
|
+
"zh-CN": "主题能整体改变站点的观感——配色、排版与布局——而无需改动你的内容或路由。Riebeckite 内置六个主题,安装一个包、改一行配置即可切换。",
|
|
1232
|
+
es: "Un tema cambia toda la apariencia del sitio — colores, tipografía y diseño — sin tocar tu contenido ni tus rutas. Riebeckite incluye seis temas: instala un paquete y cambia una línea.",
|
|
1233
|
+
de: "Ein Theme verändert das gesamte Erscheinungsbild einer Seite — Farben, Typografie, Layout — ohne dass du Inhalte oder Routen anfasst. Riebeckite bringt sechs Themes mit; der Wechsel ist eine Paketinstallation plus eine Zeile.",
|
|
446
1234
|
fr: "Un thème change tout l'aspect d'un site — couleurs, typographie, mise en page — sans toucher au contenu ni aux routes. Riebeckite fournit six thèmes ; installez un paquet et changez une ligne.",
|
|
447
1235
|
ko: "테마를 바꾸면 색상·타이포그래피·레이아웃 등 사이트 전체 분위기가 달라집니다. 콘텐츠나 라우트는 건드릴 필요가 없습니다. Riebeckite는 6개 테마를 제공하며 패키지 설치 후 한 줄만 바꾸면 전환됩니다."
|
|
448
1236
|
},
|
|
@@ -1118,516 +1906,278 @@ var PLUGIN_CATEGORIES = [
|
|
|
1118
1906
|
}
|
|
1119
1907
|
},
|
|
1120
1908
|
{
|
|
1121
|
-
slug: "quality",
|
|
1122
|
-
desc: {
|
|
1123
|
-
en: "Static quality and accessibility checks.",
|
|
1124
|
-
ja: "静的品質・アクセシビリティ検査。",
|
|
1125
|
-
"zh-CN": "静态质量与可访问性检查。",
|
|
1126
|
-
es: "Inspección estática de calidad y accesibilidad.",
|
|
1127
|
-
de: "Statische Qualitäts- und Barrierefreiheitsprüfung.",
|
|
1128
|
-
fr: "Contrôle statique de qualité et d'accessibilité.",
|
|
1129
|
-
ko: "정적 품질·접근성 검사."
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
]
|
|
1133
|
-
}
|
|
1134
|
-
];
|
|
1135
|
-
function pluginsContent(language) {
|
|
1136
|
-
const copy = PLUGINS_COPY;
|
|
1137
|
-
const categories = PLUGIN_CATEGORIES;
|
|
1138
|
-
const lines = [frontmatter()];
|
|
1139
|
-
lines.push(heading(1, read(copy.title, language)), "");
|
|
1140
|
-
lines.push(read(copy.intro, language), "");
|
|
1141
|
-
lines.push(heading(2, read(copy.installHeading, language)), "");
|
|
1142
|
-
lines.push(read(copy.installStep1, language), "");
|
|
1143
|
-
lines.push(codeBlock("sh", "pnpm add @riebeckite/plugin-mermaid"));
|
|
1144
|
-
lines.push(read(copy.installStep2, language), "");
|
|
1145
|
-
lines.push(
|
|
1146
|
-
codeBlock(
|
|
1147
|
-
"ts",
|
|
1148
|
-
[
|
|
1149
|
-
'import { defineConfig } from "@riebeckite/core";',
|
|
1150
|
-
'import { l10n } from "@riebeckite/plugin-l10n";',
|
|
1151
|
-
'import { mermaid } from "@riebeckite/plugin-mermaid";',
|
|
1152
|
-
'import { obsidianMarkdown } from "@riebeckite/plugin-obsidian-markdown";',
|
|
1153
|
-
"",
|
|
1154
|
-
"export default defineConfig({",
|
|
1155
|
-
" // ...",
|
|
1156
|
-
" plugins: [obsidianMarkdown(), l10n({ ... }), mermaid()],",
|
|
1157
|
-
"});"
|
|
1158
|
-
].join("\n")
|
|
1159
|
-
)
|
|
1160
|
-
);
|
|
1161
|
-
lines.push(read(copy.fullList, language), "");
|
|
1162
|
-
lines.push(`[${read(copy.fullListLabel, language)}](${PLUGIN_INDEX_URL})`, "");
|
|
1163
|
-
for (const category of categories) {
|
|
1164
|
-
lines.push(heading(2, read(category.title, language)), "");
|
|
1165
|
-
lines.push(read(category.summary, language), "");
|
|
1166
|
-
lines.push(`| ${read(copy.columnPlugin, language)} | ${read(copy.columnDescription, language)} |`);
|
|
1167
|
-
lines.push("| --- | --- |");
|
|
1168
|
-
for (const plugin of category.plugins) {
|
|
1169
|
-
const packageName = `@riebeckite/plugin-${plugin.slug}`;
|
|
1170
|
-
lines.push(
|
|
1171
|
-
`| [\`${packageName}\`](${pluginReadmeUrl(plugin.slug)}) | ${read(plugin.desc, language)} |`
|
|
1172
|
-
);
|
|
1173
|
-
}
|
|
1174
|
-
lines.push("");
|
|
1175
|
-
}
|
|
1176
|
-
lines.push("");
|
|
1177
|
-
lines.push(
|
|
1178
|
-
`Riebeckite: [documentation](${HELPERS.en}) · [日本語ドキュメント](${HELPERS.ja})`,
|
|
1179
|
-
""
|
|
1180
|
-
);
|
|
1181
|
-
lines.push("");
|
|
1182
|
-
return lines.join("\n");
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
// src/vite_plugin.ts
|
|
1186
|
-
import path6 from "node:path";
|
|
1187
|
-
|
|
1188
|
-
// src/asset_entries.ts
|
|
1189
|
-
import fs4 from "node:fs";
|
|
1190
|
-
import path4 from "node:path";
|
|
1191
|
-
import { uniqueStrings } from "@riebeckite/core";
|
|
1192
|
-
function writeRiebeckiteAssetEntries(config, paths2) {
|
|
1193
|
-
writeGeneratedFile(paths2.pluginStyles, createPluginStylesEntry(config));
|
|
1194
|
-
writeGeneratedFile(paths2.themeStyles, createThemeStylesEntry(config));
|
|
1195
|
-
}
|
|
1196
|
-
function createPluginStylesEntry(config) {
|
|
1197
|
-
return createStylesheetEntry(
|
|
1198
|
-
collectPluginStyleSpecifiers(config),
|
|
1199
|
-
"Plugin default styles, in resolved plugin order. Generated by @riebeckite/honox; do not edit. Import this before the theme stylesheet so a theme can override plugin defaults."
|
|
1200
|
-
);
|
|
1201
|
-
}
|
|
1202
|
-
function createThemeStylesEntry(config) {
|
|
1203
|
-
return createStylesheetEntry(
|
|
1204
|
-
config.theme.styles.map((style2) => style2.moduleSpecifier),
|
|
1205
|
-
"Theme styles. Generated by @riebeckite/honox; do not edit. Import this after the plugin stylesheet so the theme wins the plugin/theme cascade."
|
|
1206
|
-
);
|
|
1207
|
-
}
|
|
1208
|
-
function collectPluginStyleSpecifiers(config) {
|
|
1209
|
-
return config.plugins.flatMap(
|
|
1210
|
-
(plugin) => (plugin.assets ?? []).filter((asset) => asset.kind === "style").map((asset) => asset.moduleSpecifier)
|
|
1211
|
-
);
|
|
1212
|
-
}
|
|
1213
|
-
function createStylesheetEntry(moduleSpecifiers, banner) {
|
|
1214
|
-
const imports = uniqueStrings(moduleSpecifiers).map((specifier) => `@import ${JSON.stringify(specifier)};`).join("\n");
|
|
1215
|
-
if (!banner) return imports;
|
|
1216
|
-
const header = `/* ${banner.replace(/\*\//g, "* /")} */`;
|
|
1217
|
-
return imports ? `${header}
|
|
1218
|
-
${imports}
|
|
1219
|
-
` : `${header}
|
|
1220
|
-
`;
|
|
1221
|
-
}
|
|
1222
|
-
function writeGeneratedFile(filePath, contents) {
|
|
1223
|
-
fs4.mkdirSync(path4.dirname(filePath), { recursive: true });
|
|
1224
|
-
fs4.writeFileSync(filePath, contents);
|
|
1225
|
-
}
|
|
1226
|
-
|
|
1227
|
-
// src/client_module.ts
|
|
1228
|
-
import {
|
|
1229
|
-
serializePublicClientConfig
|
|
1230
|
-
} from "@riebeckite/core";
|
|
1231
|
-
var clientModuleId = "virtual:riebeckite/client";
|
|
1232
|
-
var resolvedClientModuleId = `\0${clientModuleId}`;
|
|
1233
|
-
function riebeckiteClientModule(getConfig) {
|
|
1234
|
-
return {
|
|
1235
|
-
name: "riebeckite-client-module",
|
|
1236
|
-
resolveId(id) {
|
|
1237
|
-
if (id === clientModuleId) return resolvedClientModuleId;
|
|
1238
|
-
return null;
|
|
1239
|
-
},
|
|
1240
|
-
load(id) {
|
|
1241
|
-
if (id !== resolvedClientModuleId) return null;
|
|
1242
|
-
return createClientModule(getConfig());
|
|
1243
|
-
}
|
|
1244
|
-
};
|
|
1245
|
-
}
|
|
1246
|
-
function createClientModule(config) {
|
|
1247
|
-
const imports = [];
|
|
1248
|
-
const initializers = [];
|
|
1249
|
-
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
1250
|
-
const localName = `pluginClientInitializer${index}`;
|
|
1251
|
-
const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
|
|
1252
|
-
imports.push(
|
|
1253
|
-
`import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
|
|
1254
|
-
);
|
|
1255
|
-
const publicConfig = entry.publicConfig;
|
|
1256
|
-
initializers.push(
|
|
1257
|
-
publicConfig === void 0 ? `${localName}()` : `${localName}(${serializePublicClientConfig(publicConfig)})`
|
|
1258
|
-
);
|
|
1259
|
-
}
|
|
1260
|
-
return `${imports.join("\n")}
|
|
1261
|
-
|
|
1262
|
-
export function initRiebeckiteClient() {
|
|
1263
|
-
${initializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
1264
|
-
}
|
|
1265
|
-
`;
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
// src/ssg_plugin.ts
|
|
1269
|
-
import { defaultExtensionMap, toSSG } from "hono/ssg";
|
|
1270
|
-
import { relative } from "node:path";
|
|
1271
|
-
import { createServer } from "vite";
|
|
1272
|
-
var defaultEntry = "./src/index.tsx";
|
|
1273
|
-
function riebeckiteSsg(options = {}) {
|
|
1274
|
-
const virtualId = "virtual:riebeckite-ssg-void-entry";
|
|
1275
|
-
const resolvedVirtualId = `\0${virtualId}`;
|
|
1276
|
-
const entry = options.entry ?? defaultEntry;
|
|
1277
|
-
let resolvedConfig;
|
|
1278
|
-
return {
|
|
1279
|
-
name: "riebeckite-ssg",
|
|
1280
|
-
apply: "build",
|
|
1281
|
-
enforce: "post",
|
|
1282
|
-
config() {
|
|
1283
|
-
return {
|
|
1284
|
-
build: {
|
|
1285
|
-
rollupOptions: {
|
|
1286
|
-
input: [virtualId]
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
};
|
|
1290
|
-
},
|
|
1291
|
-
configResolved(config) {
|
|
1292
|
-
resolvedConfig = config;
|
|
1293
|
-
},
|
|
1294
|
-
resolveId(id) {
|
|
1295
|
-
return id === virtualId ? resolvedVirtualId : void 0;
|
|
1296
|
-
},
|
|
1297
|
-
load(id) {
|
|
1298
|
-
return id === resolvedVirtualId ? 'console.log("suppress empty chunk message")' : void 0;
|
|
1299
|
-
},
|
|
1300
|
-
async generateBundle(_outputOptions, bundle) {
|
|
1301
|
-
const config = resolvedConfig;
|
|
1302
|
-
if (!config) {
|
|
1303
|
-
throw new Error("Riebeckite SSG could not resolve the Vite configuration.");
|
|
1304
|
-
}
|
|
1305
|
-
removeVirtualEntryChunk(bundle, resolvedVirtualId);
|
|
1306
|
-
const server2 = await createServer({
|
|
1307
|
-
root: config.root,
|
|
1308
|
-
define: config.define,
|
|
1309
|
-
resolve: {
|
|
1310
|
-
...config.resolve,
|
|
1311
|
-
builtins: [...config.resolve.builtins, /^node:/]
|
|
1312
|
-
},
|
|
1313
|
-
plugins: [],
|
|
1314
|
-
build: { ssr: true },
|
|
1315
|
-
mode: config.mode
|
|
1316
|
-
});
|
|
1317
|
-
try {
|
|
1318
|
-
const module = await server2.ssrLoadModule(entry);
|
|
1319
|
-
const app = module.default;
|
|
1320
|
-
if (!app) {
|
|
1321
|
-
throw new Error(`Failed to find a default export from ${entry}.`);
|
|
1909
|
+
slug: "quality",
|
|
1910
|
+
desc: {
|
|
1911
|
+
en: "Static quality and accessibility checks.",
|
|
1912
|
+
ja: "静的品質・アクセシビリティ検査。",
|
|
1913
|
+
"zh-CN": "静态质量与可访问性检查。",
|
|
1914
|
+
es: "Inspección estática de calidad y accesibilidad.",
|
|
1915
|
+
de: "Statische Qualitäts- und Barrierefreiheitsprüfung.",
|
|
1916
|
+
fr: "Contrôle statique de qualité et d'accessibilité.",
|
|
1917
|
+
ko: "정적 품질·접근성 검사."
|
|
1322
1918
|
}
|
|
1323
|
-
const generatedHtml = [];
|
|
1324
|
-
const result = await toSSG(
|
|
1325
|
-
app,
|
|
1326
|
-
{
|
|
1327
|
-
writeFile: async (filePath, data) => {
|
|
1328
|
-
const fileName = relative(config.build.outDir, filePath).replaceAll(
|
|
1329
|
-
"\\",
|
|
1330
|
-
"/"
|
|
1331
|
-
);
|
|
1332
|
-
if (fileName.endsWith(".html") && typeof data === "string") {
|
|
1333
|
-
generatedHtml.push({ path: fileName, html: data });
|
|
1334
|
-
}
|
|
1335
|
-
this.emitFile({
|
|
1336
|
-
type: "asset",
|
|
1337
|
-
fileName,
|
|
1338
|
-
source: data
|
|
1339
|
-
});
|
|
1340
|
-
},
|
|
1341
|
-
async mkdir() {
|
|
1342
|
-
}
|
|
1343
|
-
},
|
|
1344
|
-
{
|
|
1345
|
-
dir: config.build.outDir,
|
|
1346
|
-
plugins: options.plugins ?? [],
|
|
1347
|
-
extensionMap: options.extensionMap ?? defaultExtensionMap
|
|
1348
|
-
}
|
|
1349
|
-
);
|
|
1350
|
-
if (!result.success) throw result.error;
|
|
1351
|
-
await emitGeneratedOutputs(
|
|
1352
|
-
module,
|
|
1353
|
-
(asset) => this.emitFile(asset)
|
|
1354
|
-
);
|
|
1355
|
-
inspectGeneratedHtmlPages(module, generatedHtml, {
|
|
1356
|
-
warn: (message) => this.warn(message),
|
|
1357
|
-
info: (message) => this.info(message)
|
|
1358
|
-
});
|
|
1359
|
-
} finally {
|
|
1360
|
-
await server2.close();
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
};
|
|
1364
|
-
}
|
|
1365
|
-
async function emitGeneratedOutputs(module, emit) {
|
|
1366
|
-
const content = module.content;
|
|
1367
|
-
if (!content) return;
|
|
1368
|
-
const manifest = await content.getManifest();
|
|
1369
|
-
for (const output of manifest.generatedOutputs ?? []) {
|
|
1370
|
-
emit({
|
|
1371
|
-
type: "asset",
|
|
1372
|
-
fileName: output.path,
|
|
1373
|
-
source: output.content
|
|
1374
|
-
});
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
function inspectGeneratedHtmlPages(module, pages, log) {
|
|
1378
|
-
const plugins = module.config?.plugins ?? [];
|
|
1379
|
-
for (const plugin of plugins) {
|
|
1380
|
-
const inspector = plugin.inspectGeneratedHtml;
|
|
1381
|
-
if (typeof inspector !== "function") continue;
|
|
1382
|
-
for (const page of pages) {
|
|
1383
|
-
for (const diagnostic of inspector(page) ?? []) {
|
|
1384
|
-
const label = `[${plugin.name ?? "plugin"}] ${page.path}: ${diagnostic.message}`;
|
|
1385
|
-
if (diagnostic.severity === "info") log.info(label);
|
|
1386
|
-
else log.warn(label);
|
|
1387
1919
|
}
|
|
1388
|
-
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
function removeVirtualEntryChunk(bundle, virtualEntryId) {
|
|
1392
|
-
for (const chunk of Object.values(bundle)) {
|
|
1393
|
-
if (chunk.type === "chunk" && chunk.moduleIds?.includes(virtualEntryId)) {
|
|
1394
|
-
delete bundle[chunk.fileName];
|
|
1395
|
-
}
|
|
1920
|
+
]
|
|
1396
1921
|
}
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
// src/ssg.ts
|
|
1400
|
-
var defaultSsgEntry = "./app/server.ts";
|
|
1401
|
-
function riebeckiteSsgExtensionMap() {
|
|
1402
|
-
return {
|
|
1403
|
-
"application/atom+xml": "xml",
|
|
1404
|
-
"application/json": "json",
|
|
1405
|
-
"application/rss+xml": "xml",
|
|
1406
|
-
"application/xml": "xml",
|
|
1407
|
-
"text/html": "html",
|
|
1408
|
-
"text/plain": "txt",
|
|
1409
|
-
"text/xml": "xml"
|
|
1410
|
-
};
|
|
1411
|
-
}
|
|
1412
|
-
function createRiebeckiteSsg(options = {}) {
|
|
1413
|
-
return riebeckiteSsg({
|
|
1414
|
-
...options,
|
|
1415
|
-
entry: options.entry ?? defaultSsgEntry,
|
|
1416
|
-
extensionMap: {
|
|
1417
|
-
...riebeckiteSsgExtensionMap(),
|
|
1418
|
-
...options.extensionMap
|
|
1419
|
-
}
|
|
1420
|
-
});
|
|
1421
|
-
}
|
|
1422
|
-
|
|
1423
|
-
// src/vite_runner.ts
|
|
1424
|
-
import fs5 from "node:fs/promises";
|
|
1425
|
-
import path5 from "node:path";
|
|
1426
|
-
import { build, createServer as createServer2 } from "vite";
|
|
1427
|
-
var viteConfigFileNames = [
|
|
1428
|
-
"vite.config.ts",
|
|
1429
|
-
"vite.config.js",
|
|
1430
|
-
"vite.config.mjs"
|
|
1431
1922
|
];
|
|
1432
|
-
|
|
1433
|
-
const
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1923
|
+
function pluginsContent(language) {
|
|
1924
|
+
const copy = PLUGINS_COPY;
|
|
1925
|
+
const categories = PLUGIN_CATEGORIES;
|
|
1926
|
+
const lines = [frontmatter()];
|
|
1927
|
+
lines.push(heading(1, read(copy.title, language)), "");
|
|
1928
|
+
lines.push(read(copy.intro, language), "");
|
|
1929
|
+
lines.push(heading(2, read(copy.installHeading, language)), "");
|
|
1930
|
+
lines.push(read(copy.installStep1, language), "");
|
|
1931
|
+
lines.push(codeBlock("sh", "pnpm add @riebeckite/plugin-mermaid"));
|
|
1932
|
+
lines.push(read(copy.installStep2, language), "");
|
|
1933
|
+
lines.push(
|
|
1934
|
+
codeBlock(
|
|
1935
|
+
"ts",
|
|
1936
|
+
[
|
|
1937
|
+
'import { defineConfig } from "@riebeckite/core";',
|
|
1938
|
+
'import { l10n } from "@riebeckite/plugin-l10n";',
|
|
1939
|
+
'import { mermaid } from "@riebeckite/plugin-mermaid";',
|
|
1940
|
+
'import { obsidianMarkdown } from "@riebeckite/plugin-obsidian-markdown";',
|
|
1941
|
+
"",
|
|
1942
|
+
"export default defineConfig({",
|
|
1943
|
+
" // ...",
|
|
1944
|
+
" plugins: [obsidianMarkdown(), l10n({ ... }), mermaid()],",
|
|
1945
|
+
"});"
|
|
1946
|
+
].join("\n")
|
|
1947
|
+
)
|
|
1442
1948
|
);
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
workspaceRoot
|
|
1458
|
-
});
|
|
1459
|
-
const config = resolveHonoxConfig(rawConfig, appRoot);
|
|
1460
|
-
return {
|
|
1461
|
-
config,
|
|
1462
|
-
configRoot,
|
|
1463
|
-
appRoot,
|
|
1464
|
-
contentRoot: config.content.directory
|
|
1465
|
-
};
|
|
1466
|
-
}
|
|
1467
|
-
async function findWorkspaceRoot(configRoot) {
|
|
1468
|
-
try {
|
|
1469
|
-
const workspaceConfig = path5.join(configRoot, "pnpm-workspace.yaml");
|
|
1470
|
-
return (await fs5.stat(workspaceConfig)).isFile() ? configRoot : void 0;
|
|
1471
|
-
} catch {
|
|
1472
|
-
return void 0;
|
|
1949
|
+
lines.push(read(copy.fullList, language), "");
|
|
1950
|
+
lines.push(`[${read(copy.fullListLabel, language)}](${PLUGIN_INDEX_URL})`, "");
|
|
1951
|
+
for (const category of categories) {
|
|
1952
|
+
lines.push(heading(2, read(category.title, language)), "");
|
|
1953
|
+
lines.push(read(category.summary, language), "");
|
|
1954
|
+
lines.push(`| ${read(copy.columnPlugin, language)} | ${read(copy.columnDescription, language)} |`);
|
|
1955
|
+
lines.push("| --- | --- |");
|
|
1956
|
+
for (const plugin of category.plugins) {
|
|
1957
|
+
const packageName = `@riebeckite/plugin-${plugin.slug}`;
|
|
1958
|
+
lines.push(
|
|
1959
|
+
`| [\`${packageName}\`](${pluginReadmeUrl(plugin.slug)}) | ${read(plugin.desc, language)} |`
|
|
1960
|
+
);
|
|
1961
|
+
}
|
|
1962
|
+
lines.push("");
|
|
1473
1963
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
server2.printUrls();
|
|
1479
|
-
await waitForShutdown(server2);
|
|
1480
|
-
}
|
|
1481
|
-
async function buildHonoxApplication(options) {
|
|
1482
|
-
await runTraced(
|
|
1483
|
-
options.tracer,
|
|
1484
|
-
"integration.honox.client_build",
|
|
1485
|
-
() => build({ root: options.root, mode: "client" })
|
|
1486
|
-
);
|
|
1487
|
-
await runTraced(
|
|
1488
|
-
options.tracer,
|
|
1489
|
-
"integration.honox.server_build",
|
|
1490
|
-
() => build({ root: options.root })
|
|
1964
|
+
lines.push("");
|
|
1965
|
+
lines.push(
|
|
1966
|
+
`Riebeckite: [documentation](${HELPERS.en}) · [日本語ドキュメント](${HELPERS.ja})`,
|
|
1967
|
+
""
|
|
1491
1968
|
);
|
|
1969
|
+
lines.push("");
|
|
1970
|
+
return lines.join("\n");
|
|
1492
1971
|
}
|
|
1493
|
-
|
|
1494
|
-
return
|
|
1972
|
+
function guideContent() {
|
|
1973
|
+
return [
|
|
1974
|
+
frontmatter(),
|
|
1975
|
+
heading(1, "Getting started"),
|
|
1976
|
+
"",
|
|
1977
|
+
"This site was generated from a Riebeckite scaffold preset. Everything",
|
|
1978
|
+
"you see lives in this repository, ready to edit.",
|
|
1979
|
+
"",
|
|
1980
|
+
heading(2, "Add a page"),
|
|
1981
|
+
"",
|
|
1982
|
+
"Drop a Markdown file into `content/` with `publish: true` in its",
|
|
1983
|
+
"frontmatter and it appears in the built site:",
|
|
1984
|
+
"",
|
|
1985
|
+
codeBlock(
|
|
1986
|
+
"md",
|
|
1987
|
+
["---", "publish: true", "---", "", "# Hello", "", "Body text..."].join("\n")
|
|
1988
|
+
),
|
|
1989
|
+
"",
|
|
1990
|
+
heading(2, "Run the site"),
|
|
1991
|
+
"",
|
|
1992
|
+
codeBlock(
|
|
1993
|
+
"sh",
|
|
1994
|
+
["pnpm install", "pnpm exec riebeckite dev", "pnpm exec riebeckite build"].join("\n")
|
|
1995
|
+
),
|
|
1996
|
+
"",
|
|
1997
|
+
heading(2, "Localize a page"),
|
|
1998
|
+
"",
|
|
1999
|
+
"Add a translated file next to the default one using the",
|
|
2000
|
+
"`<base>.<lang>.md` convention (`about.ja.md`, `about.en.md`). With the",
|
|
2001
|
+
"l10n plugin enabled, translations are served under `/lang/` paths and",
|
|
2002
|
+
"linked by the language switcher.",
|
|
2003
|
+
"",
|
|
2004
|
+
heading(2, "Extend"),
|
|
2005
|
+
"",
|
|
2006
|
+
"Plugins and themes are registered in `riebeckite.config.ts`. Install a",
|
|
2007
|
+
"package, import its factory, and add it to the `plugins` array or point",
|
|
2008
|
+
"`theme` at a new theme factory.",
|
|
2009
|
+
""
|
|
2010
|
+
].join("\n");
|
|
1495
2011
|
}
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
2012
|
+
function examplesContent() {
|
|
2013
|
+
return [
|
|
2014
|
+
frontmatter(),
|
|
2015
|
+
heading(1, "Examples"),
|
|
2016
|
+
"",
|
|
2017
|
+
"A tour of what the richer Riebeckite presets enable. Fenced code blocks",
|
|
2018
|
+
"are turned into rendered diagrams and charts at build time by the",
|
|
2019
|
+
"diagram plugins; code blocks gain toolbars from the code plugins.",
|
|
2020
|
+
"",
|
|
2021
|
+
heading(2, "Mermaid"),
|
|
2022
|
+
"",
|
|
2023
|
+
codeBlock("mermaid", "flowchart LR\n A[Note] --> B{Published?}\n B -->|yes| C[Site]\n B -->|no| D[Draft]"),
|
|
2024
|
+
"",
|
|
2025
|
+
heading(2, "D2"),
|
|
2026
|
+
"",
|
|
2027
|
+
codeBlock("d2", "site: Riebeckite\n content -> build -> deploy"),
|
|
2028
|
+
"",
|
|
2029
|
+
heading(2, "Graphviz / DOT"),
|
|
2030
|
+
"",
|
|
2031
|
+
codeBlock("dot", "digraph G {\n notes -> pages;\n pages -> html;\n}"),
|
|
2032
|
+
"",
|
|
2033
|
+
heading(2, "A chart"),
|
|
2034
|
+
"",
|
|
2035
|
+
codeBlock("chartjs", "line\nlabels: Jan, Feb, Mar\nvalues: 3, 7, 5"),
|
|
2036
|
+
"",
|
|
2037
|
+
heading(2, "Code with a toolbar"),
|
|
2038
|
+
"",
|
|
2039
|
+
codeBlock(
|
|
2040
|
+
"ts",
|
|
2041
|
+
[
|
|
2042
|
+
"// Syntax highlighting, line numbers, and copy buttons",
|
|
2043
|
+
"export function hello(name: string): string {",
|
|
2044
|
+
' return "Hello, " + name + "!";',
|
|
2045
|
+
"}"
|
|
2046
|
+
].join("\n")
|
|
2047
|
+
),
|
|
2048
|
+
"",
|
|
2049
|
+
heading(2, "Callouts"),
|
|
2050
|
+
"",
|
|
2051
|
+
"> [!tip] Try it",
|
|
2052
|
+
"> Callouts from `@riebeckite/plugin-obsidian-markdown` render as styled",
|
|
2053
|
+
"> blocks. Add one with `> [!info]`, `> [!warning]`, or `> [!question]`.",
|
|
2054
|
+
""
|
|
2055
|
+
].join("\n");
|
|
1504
2056
|
}
|
|
1505
|
-
|
|
1506
|
-
const
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
2057
|
+
function referencePluginsContent(preset) {
|
|
2058
|
+
const lines = [frontmatter()];
|
|
2059
|
+
lines.push(heading(1, "Plugin reference"), "");
|
|
2060
|
+
lines.push(
|
|
2061
|
+
"Every plugin registered by this preset, with the factory used in",
|
|
2062
|
+
"`riebeckite.config.ts`. Full documentation lives in each package README.",
|
|
2063
|
+
""
|
|
2064
|
+
);
|
|
2065
|
+
lines.push("| Package | Factory |");
|
|
2066
|
+
lines.push("| --- | --- |");
|
|
2067
|
+
for (const plugin of preset.plugins) {
|
|
2068
|
+
lines.push(
|
|
2069
|
+
`| [\`${plugin.package}\`](${pluginReadmeUrl(plugin.package.replace(/^@riebeckite\/plugin-/, ""))}) | \`${plugin.factory}\` |`
|
|
2070
|
+
);
|
|
1519
2071
|
}
|
|
1520
|
-
|
|
2072
|
+
lines.push("");
|
|
2073
|
+
lines.push(`[Riebeckite plugins on GitHub](${PLUGIN_INDEX_URL})`, "");
|
|
2074
|
+
lines.push("");
|
|
2075
|
+
return lines.join("\n");
|
|
1521
2076
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
2077
|
+
function referenceThemesContent() {
|
|
2078
|
+
const lines = [frontmatter()];
|
|
2079
|
+
lines.push(heading(1, "Theme reference"), "");
|
|
2080
|
+
lines.push(
|
|
2081
|
+
"The bundled themes. Switch by installing a package and changing the",
|
|
2082
|
+
"`theme` factory in `riebeckite.config.ts`.",
|
|
2083
|
+
""
|
|
2084
|
+
);
|
|
2085
|
+
lines.push("| Theme | Factory | Description |");
|
|
2086
|
+
lines.push("| --- | --- | --- |");
|
|
2087
|
+
for (const theme of THEMES) {
|
|
2088
|
+
const packageName = `@riebeckite/theme-${theme.slug}`;
|
|
2089
|
+
lines.push(
|
|
2090
|
+
`| [\`${packageName}\`](${themeReadmeUrl(theme.slug)}) | \`${theme.factory}\` | ${read(theme.desc, "en")} |`
|
|
2091
|
+
);
|
|
1528
2092
|
}
|
|
1529
|
-
|
|
2093
|
+
lines.push("");
|
|
2094
|
+
lines.push(`[Riebeckite themes on GitHub](${THEMES_INDEX_URL})`, "");
|
|
2095
|
+
lines.push("");
|
|
2096
|
+
return lines.join("\n");
|
|
1530
2097
|
}
|
|
1531
2098
|
|
|
1532
|
-
// src/
|
|
1533
|
-
|
|
1534
|
-
"extend",
|
|
1535
|
-
"debug",
|
|
1536
|
-
"node:fs/promises",
|
|
1537
|
-
"node:path",
|
|
1538
|
-
"parse-numeric-range",
|
|
1539
|
-
"slugify",
|
|
1540
|
-
"vfile-matter",
|
|
1541
|
-
"yaml"
|
|
1542
|
-
];
|
|
1543
|
-
function riebeckite(options = {}) {
|
|
1544
|
-
let resolvedConfig;
|
|
1545
|
-
const getConfig = () => {
|
|
1546
|
-
if (!resolvedConfig) {
|
|
1547
|
-
throw new Error("Riebeckite config has not been loaded yet.");
|
|
1548
|
-
}
|
|
1549
|
-
return resolvedConfig;
|
|
1550
|
-
};
|
|
2099
|
+
// src/scaffold/templates.ts
|
|
2100
|
+
function siteTemplateFiles(preset, variables) {
|
|
1551
2101
|
return [
|
|
2102
|
+
{ path: "package.json", content: packageJson(preset, variables) },
|
|
1552
2103
|
{
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
const root = userConfig.root ? path6.resolve(userConfig.root) : process.cwd();
|
|
1556
|
-
const appRoot = options.appRoot ?? root;
|
|
1557
|
-
const application = await resolveHonoxApplication({
|
|
1558
|
-
configRoot: options.configRoot ?? appRoot,
|
|
1559
|
-
configFile: options.configFile,
|
|
1560
|
-
appRoot,
|
|
1561
|
-
workspaceRoot: options.workspaceRoot
|
|
1562
|
-
});
|
|
1563
|
-
resolvedConfig = application.config;
|
|
1564
|
-
writeRiebeckiteAssetEntries(resolvedConfig, {
|
|
1565
|
-
pluginStyles: path6.join(appRoot, "app/.riebeckite/plugin-styles.css"),
|
|
1566
|
-
themeStyles: path6.join(appRoot, "app/.riebeckite/theme-styles.css")
|
|
1567
|
-
});
|
|
1568
|
-
return {
|
|
1569
|
-
define: {
|
|
1570
|
-
"process.env.RIEBECKITE_APP_ROOT": JSON.stringify(appRoot)
|
|
1571
|
-
},
|
|
1572
|
-
resolve: {
|
|
1573
|
-
alias: options.workspaceRoot ? createWorkspacePackageAliases(options.workspaceRoot) : []
|
|
1574
|
-
}
|
|
1575
|
-
};
|
|
1576
|
-
}
|
|
2104
|
+
path: "riebeckite.config.ts",
|
|
2105
|
+
content: riebeckiteConfig(preset, variables)
|
|
1577
2106
|
},
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
...riebeckite(integration),
|
|
1585
|
-
riebeckiteSsrExternals([...defaultSsrExternals, ...ssrExternals ?? []]),
|
|
1586
|
-
createRiebeckiteSsg(ssg)
|
|
2107
|
+
{ path: "vite.config.ts", content: viteConfig() },
|
|
2108
|
+
{ path: "tsconfig.json", content: tsconfig() },
|
|
2109
|
+
{ path: ".gitignore", content: gitignore() },
|
|
2110
|
+
{ path: "README.md", content: readme(preset, variables) },
|
|
2111
|
+
...localizedContentFiles(variables, preset),
|
|
2112
|
+
...appFiles(preset)
|
|
1587
2113
|
];
|
|
1588
2114
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
2115
|
+
var APP_FILE_LABELS = [
|
|
2116
|
+
"server",
|
|
2117
|
+
"client",
|
|
2118
|
+
"config",
|
|
2119
|
+
"content",
|
|
2120
|
+
"paths",
|
|
2121
|
+
"global",
|
|
2122
|
+
"style",
|
|
2123
|
+
"renderer",
|
|
2124
|
+
"index",
|
|
2125
|
+
"slug",
|
|
2126
|
+
"header",
|
|
2127
|
+
"article"
|
|
2128
|
+
];
|
|
2129
|
+
function appFiles(preset) {
|
|
2130
|
+
const builders = {
|
|
2131
|
+
server: () => server(),
|
|
2132
|
+
client: () => client(),
|
|
2133
|
+
config: () => appConfig(),
|
|
2134
|
+
content: () => appContent(),
|
|
2135
|
+
paths: () => paths(),
|
|
2136
|
+
global: () => globalDeclarations(),
|
|
2137
|
+
style: () => style(preset),
|
|
2138
|
+
renderer: () => renderer(preset),
|
|
2139
|
+
index: () => indexRoute(preset),
|
|
2140
|
+
slug: () => slugRoute(),
|
|
2141
|
+
header: () => siteHeader(),
|
|
2142
|
+
article: () => article()
|
|
1603
2143
|
};
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
2144
|
+
const generated = /* @__PURE__ */ new Map();
|
|
2145
|
+
for (const key of APP_FILE_LABELS) {
|
|
2146
|
+
if (preset.appFiles.includes(key)) {
|
|
2147
|
+
generated.set(key, builders[key]());
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
const has = (key) => generated.has(key);
|
|
2151
|
+
const get = (key) => generated.get(key);
|
|
1608
2152
|
return [
|
|
1609
|
-
{ path: "
|
|
1610
|
-
{ path: "
|
|
1611
|
-
{ path: "
|
|
1612
|
-
{ path: "
|
|
1613
|
-
{ path: ".
|
|
1614
|
-
{ path: "
|
|
1615
|
-
...
|
|
1616
|
-
{ path: "app/
|
|
1617
|
-
{ path: "app/
|
|
1618
|
-
{ path: "app/
|
|
1619
|
-
{ path: "app/
|
|
1620
|
-
{ path: "app/
|
|
1621
|
-
{ path: "app/global.d.ts", content: globalDeclarations() },
|
|
1622
|
-
{ path: "app/style.css", content: style() },
|
|
1623
|
-
{ path: "app/components/site-header.tsx", content: siteHeader() },
|
|
1624
|
-
{ path: "app/components/article.tsx", content: article() },
|
|
1625
|
-
{ path: "app/routes/_renderer.tsx", content: renderer() },
|
|
1626
|
-
{ path: "app/routes/index.tsx", content: indexRoute() },
|
|
1627
|
-
{ path: "app/routes/[slug{.+}].tsx", content: slugRoute() }
|
|
2153
|
+
...has("server") ? [{ path: "app/server.ts", content: get("server") }] : [],
|
|
2154
|
+
...has("client") ? [{ path: "app/client.ts", content: get("client") }] : [],
|
|
2155
|
+
...has("config") ? [{ path: "app/config.ts", content: get("config") }] : [],
|
|
2156
|
+
...has("content") ? [{ path: "app/content.ts", content: get("content") }] : [],
|
|
2157
|
+
...has("paths") ? [{ path: "app/constants/paths.ts", content: get("paths") }] : [],
|
|
2158
|
+
...has("global") ? [{ path: "app/global.d.ts", content: get("global") }] : [],
|
|
2159
|
+
...has("style") ? [{ path: "app/style.css", content: get("style") }] : [],
|
|
2160
|
+
...has("renderer") ? [{ path: "app/routes/_renderer.tsx", content: get("renderer") }] : [],
|
|
2161
|
+
...has("index") ? [{ path: "app/routes/index.tsx", content: get("index") }] : [],
|
|
2162
|
+
...has("slug") ? [{ path: "app/routes/[slug{.+}].tsx", content: get("slug") }] : [],
|
|
2163
|
+
...has("header") ? [{ path: "app/components/site-header.tsx", content: get("header") }] : [],
|
|
2164
|
+
...has("article") ? [{ path: "app/components/article.tsx", content: get("article") }] : []
|
|
1628
2165
|
];
|
|
1629
2166
|
}
|
|
1630
|
-
|
|
2167
|
+
var RIEBECKITE_VERSION = "^0.0.3";
|
|
2168
|
+
function packageJson(preset, variables) {
|
|
2169
|
+
const dependencies = {
|
|
2170
|
+
"@riebeckite/core": RIEBECKITE_VERSION,
|
|
2171
|
+
"@riebeckite/honox": RIEBECKITE_VERSION,
|
|
2172
|
+
hono: "^4.12.25",
|
|
2173
|
+
honox: "0.1.56"
|
|
2174
|
+
};
|
|
2175
|
+
for (const plugin of preset.plugins) {
|
|
2176
|
+
dependencies[plugin.package] = RIEBECKITE_VERSION;
|
|
2177
|
+
}
|
|
2178
|
+
if (preset.theme) {
|
|
2179
|
+
dependencies[preset.theme.package] = RIEBECKITE_VERSION;
|
|
2180
|
+
}
|
|
1631
2181
|
return `${JSON.stringify(
|
|
1632
2182
|
{
|
|
1633
2183
|
name: variables.name,
|
|
@@ -1641,19 +2191,10 @@ function packageJson(variables) {
|
|
|
1641
2191
|
doctor: "riebeckite doctor",
|
|
1642
2192
|
inspect: "riebeckite inspect"
|
|
1643
2193
|
},
|
|
1644
|
-
dependencies
|
|
1645
|
-
"@riebeckite/core": "^0.0.3",
|
|
1646
|
-
"@riebeckite/honox": "^0.0.3",
|
|
1647
|
-
"@riebeckite/plugin-color-mode": "^0.0.3",
|
|
1648
|
-
"@riebeckite/plugin-l10n": "^0.0.3",
|
|
1649
|
-
"@riebeckite/plugin-obsidian-markdown": "^0.0.3",
|
|
1650
|
-
"@riebeckite/theme-default": "^0.0.3",
|
|
1651
|
-
hono: "^4.12.25",
|
|
1652
|
-
honox: "0.1.56"
|
|
1653
|
-
},
|
|
2194
|
+
dependencies,
|
|
1654
2195
|
devDependencies: {
|
|
1655
2196
|
"@hono/vite-build": "^1.11.1",
|
|
1656
|
-
"@riebeckite/cli":
|
|
2197
|
+
"@riebeckite/cli": RIEBECKITE_VERSION,
|
|
1657
2198
|
"@types/node": "^24.5.2",
|
|
1658
2199
|
typescript: "^5.0.0",
|
|
1659
2200
|
vite: "^8.0.9"
|
|
@@ -1664,37 +2205,50 @@ function packageJson(variables) {
|
|
|
1664
2205
|
)}
|
|
1665
2206
|
`;
|
|
1666
2207
|
}
|
|
1667
|
-
function riebeckiteConfig(variables) {
|
|
2208
|
+
function riebeckiteConfig(preset, variables) {
|
|
1668
2209
|
const { title, description, baseUrl, locale } = variables;
|
|
1669
|
-
const
|
|
1670
|
-
|
|
1671
|
-
import {
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
},
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
2210
|
+
const lines = ['import { defineConfig } from "@riebeckite/core";'];
|
|
2211
|
+
for (const plugin of preset.plugins) {
|
|
2212
|
+
lines.push(`import { ${plugin.factory} } from "${plugin.package}";`);
|
|
2213
|
+
}
|
|
2214
|
+
if (preset.theme) {
|
|
2215
|
+
lines.push(
|
|
2216
|
+
`import { ${preset.theme.factory} } from "${preset.theme.package}";`
|
|
2217
|
+
);
|
|
2218
|
+
}
|
|
2219
|
+
lines.push("");
|
|
2220
|
+
lines.push("export default defineConfig({");
|
|
2221
|
+
lines.push(" site: {");
|
|
2222
|
+
lines.push(` title: ${JSON.stringify(title)},`);
|
|
2223
|
+
lines.push(` description: ${JSON.stringify(description)},`);
|
|
2224
|
+
lines.push(` baseUrl: ${JSON.stringify(baseUrl)},`);
|
|
2225
|
+
lines.push(` locale: ${JSON.stringify(locale)},`);
|
|
2226
|
+
lines.push(" },");
|
|
2227
|
+
lines.push(" content: {");
|
|
2228
|
+
lines.push(' directory: "content",');
|
|
2229
|
+
lines.push(" },");
|
|
2230
|
+
if (preset.theme) {
|
|
2231
|
+
const theme = preset.theme;
|
|
2232
|
+
lines.push(
|
|
2233
|
+
` theme: ${theme.options ? `${theme.factory}(${theme.options})` : `${theme.factory}()`},`
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2236
|
+
lines.push(" plugins: [");
|
|
2237
|
+
for (const plugin of preset.plugins) {
|
|
2238
|
+
lines.push(` ${pluginExpression(plugin, preset, variables)},`);
|
|
2239
|
+
}
|
|
2240
|
+
lines.push(" ],");
|
|
2241
|
+
lines.push("});");
|
|
2242
|
+
return `${lines.join("\n")}
|
|
1696
2243
|
`;
|
|
1697
2244
|
}
|
|
2245
|
+
function pluginExpression(plugin, preset, variables) {
|
|
2246
|
+
if (plugin.package === "@riebeckite/plugin-l10n") {
|
|
2247
|
+
const defaultLang = defaultLanguageForLocale(variables.locale);
|
|
2248
|
+
return `l10n({ defaultLang: ${JSON.stringify(defaultLang)}, languages: ${JSON.stringify(preset.languages)} })`;
|
|
2249
|
+
}
|
|
2250
|
+
return plugin.options ? `${plugin.factory}(${plugin.options})` : `${plugin.factory}()`;
|
|
2251
|
+
}
|
|
1698
2252
|
function viteConfig() {
|
|
1699
2253
|
const ssrExternals = [...defaultSsrExternals].map((name) => ` "${name}",`).join("\n");
|
|
1700
2254
|
return `import path from "node:path";
|
|
@@ -1767,112 +2321,168 @@ function tsconfig() {
|
|
|
1767
2321
|
function gitignore() {
|
|
1768
2322
|
return ["node_modules/", "dist/", ".riebeckite/", ""].join("\n");
|
|
1769
2323
|
}
|
|
1770
|
-
function readme(variables) {
|
|
1771
|
-
return defaultLanguageForLocale(variables.locale) === "ja" ? jaReadme(variables) : enReadme(variables);
|
|
1772
|
-
}
|
|
1773
2324
|
var REPO = "https://github.com/Rerurate514/riebeckite";
|
|
1774
|
-
|
|
1775
|
-
|
|
2325
|
+
var README_INTRO = {
|
|
2326
|
+
empty: {
|
|
2327
|
+
en: "A blank Riebeckite application shell — no theme, no plugins, no components, and no content. Everything is yours to add.",
|
|
2328
|
+
ja: "空の Riebeckite アプリケーションシェルです。テーマもプラグインもコンポーネントもコンテンツもなく、すべてを自由に追加できます。"
|
|
2329
|
+
},
|
|
2330
|
+
minimal: {
|
|
2331
|
+
en: "The smallest useful Riebeckite site: Obsidian Markdown, the minimal theme, and a single page.",
|
|
2332
|
+
ja: "最小限で実用的な Riebeckite サイトです。Obsidian マークダウン・minimal テーマ・1 ページ構成。"
|
|
2333
|
+
},
|
|
2334
|
+
starter: {
|
|
2335
|
+
en: "The default Riebeckite starter: Obsidian Markdown, a color-mode toggle, and seven languages.",
|
|
2336
|
+
ja: "Riebeckite の既定スターターです。Obsidian マークダウン・カラーモード切替・7 言語対応。"
|
|
2337
|
+
},
|
|
2338
|
+
rich: {
|
|
2339
|
+
en: "A showcasing starter: publishing and reading plugins plus guided ecosystem tour pages in seven languages.",
|
|
2340
|
+
ja: "紹介を目的としたスターターです。公開・読書体験のプラグインと、7 言語のエコシステム紹介ページ付き。"
|
|
2341
|
+
},
|
|
2342
|
+
full: {
|
|
2343
|
+
en: "A ready-to-use blog preset: discovery, media, and reading plugins plus a getting-started guide.",
|
|
2344
|
+
ja: "そのまま使えるブログ向けプリセットです。検索・メディア・読書体験のプラグインと入門ガイド付き。"
|
|
2345
|
+
},
|
|
2346
|
+
max: {
|
|
2347
|
+
en: "Diagram, chart, and knowledge plugins on top of full, with showcase example pages.",
|
|
2348
|
+
ja: "full に図解・チャート・ナレッジ系プラグインを加えた構成で、お試し用サンプルページ付き。"
|
|
2349
|
+
},
|
|
2350
|
+
ultra: {
|
|
2351
|
+
en: "The complete plugin catalog with plugin and theme reference pages.",
|
|
2352
|
+
ja: "全プラグインを有効化した最上位構成。プラグイン/テーマのリファレンスページ付き。"
|
|
2353
|
+
}
|
|
2354
|
+
};
|
|
2355
|
+
var README_WORDS = {
|
|
2356
|
+
en: {
|
|
2357
|
+
included: "What's included",
|
|
2358
|
+
languages: "Languages",
|
|
2359
|
+
theme: "Theme",
|
|
2360
|
+
plugins: "Plugins",
|
|
2361
|
+
pages: "Content pages",
|
|
2362
|
+
commands: "Commands",
|
|
2363
|
+
localization: "Localization",
|
|
2364
|
+
localizationBody: "Content lives in `content/` as plain Markdown. Translations sit next to the default file using the `<base>.<lang>.md` convention (`about.ja.md`, `about.en.md`). The default language keeps the unsuffixed path; the rest are served under `/lang/`. To add or remove a language, edit the `l10n(...)` plugin in `riebeckite.config.ts` and add or remove the matching translation files.",
|
|
2365
|
+
extending: "Extending",
|
|
2366
|
+
extendingBody: "Plugins and themes are registered in `riebeckite.config.ts`. Install a package, import its factory, and add it to the `plugins` array — or point `theme` at another theme factory. See the Riebeckite repository for the full plugin and theme index.",
|
|
2367
|
+
none: "none",
|
|
2368
|
+
noPlugins: "no plugins",
|
|
2369
|
+
single: "single language"
|
|
2370
|
+
},
|
|
2371
|
+
ja: {
|
|
2372
|
+
included: "含まれているもの",
|
|
2373
|
+
languages: "言語",
|
|
2374
|
+
theme: "テーマ",
|
|
2375
|
+
plugins: "プラグイン",
|
|
2376
|
+
pages: "コンテンツページ",
|
|
2377
|
+
commands: "コマンド",
|
|
2378
|
+
localization: "ローカライズ",
|
|
2379
|
+
localizationBody: "コンテンツは `content/` にプレーンな Markdown として置きます。翻訳ページは既定ファイルの隣に `<base>.<lang>.md` の規則で配置します(`about.ja.md`、`about.en.md` など)。既定言語は接尾辞なしのパス、それ以外は `/lang/` のパスで配信されます。言語の追加・削除は `riebeckite.config.ts` の `l10n(...)` プラグインを編集し、対応する翻訳ファイルを追加・削除してください。",
|
|
2380
|
+
extending: "拡張",
|
|
2381
|
+
extendingBody: "プラグインとテーマは `riebeckite.config.ts` で登録します。パッケージをインストールし、ファクトリを import して `plugins` 配列に追加するか、`theme` を別のテーマファクトリに変更します。全プラグイン・テーマの一覧は Riebeckite リポジトリを参照してください。",
|
|
2382
|
+
none: "なし",
|
|
2383
|
+
noPlugins: "プラグインなし",
|
|
2384
|
+
single: "単一言語"
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
function readme(preset, variables) {
|
|
2388
|
+
const ja = defaultLanguageForLocale(variables.locale) === "ja";
|
|
2389
|
+
return ja ? readmeJa(preset, variables) : readmeEn(preset, variables);
|
|
2390
|
+
}
|
|
2391
|
+
function readmeEn(preset, variables) {
|
|
2392
|
+
const words = README_WORDS.en;
|
|
2393
|
+
const lines = [
|
|
1776
2394
|
`# ${variables.title}`,
|
|
1777
2395
|
"",
|
|
1778
|
-
|
|
1779
|
-
"
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
""
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
"## Commands",
|
|
1796
|
-
"",
|
|
2396
|
+
README_INTRO[preset.name].en,
|
|
2397
|
+
""
|
|
2398
|
+
];
|
|
2399
|
+
if (preset.readme !== "short") {
|
|
2400
|
+
lines.push(`## ${words.included}`, "");
|
|
2401
|
+
lines.push(`- **${words.languages}**: ${languagesLabel(preset, words)}`);
|
|
2402
|
+
lines.push(
|
|
2403
|
+
`- **${words.theme}**: ${preset.theme ? `\`${preset.theme.package}\`` : words.none}`
|
|
2404
|
+
);
|
|
2405
|
+
lines.push(
|
|
2406
|
+
`- **${words.plugins}** (${preset.plugins.length}): ${preset.plugins.length === 0 ? words.noPlugins : preset.plugins.map((p) => `\`${p.package}\``).join(", ")}`
|
|
2407
|
+
);
|
|
2408
|
+
lines.push(`- **${words.pages}**: ${pagesLabel(preset) ?? words.none}`);
|
|
2409
|
+
lines.push("");
|
|
2410
|
+
}
|
|
2411
|
+
lines.push(`## ${words.commands}`, "");
|
|
2412
|
+
lines.push(
|
|
1797
2413
|
"```sh",
|
|
1798
2414
|
"pnpm install",
|
|
1799
2415
|
"pnpm exec riebeckite check",
|
|
1800
2416
|
"pnpm exec riebeckite dev",
|
|
1801
2417
|
"pnpm exec riebeckite build",
|
|
1802
2418
|
"```",
|
|
1803
|
-
"",
|
|
1804
|
-
"## Localization",
|
|
1805
|
-
"",
|
|
1806
|
-
"Content lives in `content/` as plain Markdown. Translations sit next to the",
|
|
1807
|
-
"default file using the `<base>.<lang>.md` convention (`about.ja.md`,",
|
|
1808
|
-
"`about.en.md`). The default language keeps the unsuffixed path; the rest are",
|
|
1809
|
-
"served under `/lang/`.",
|
|
1810
|
-
"",
|
|
1811
|
-
"To add or remove a language, edit the `l10n(...)` plugin in",
|
|
1812
|
-
"`riebeckite.config.ts` and add or remove the matching translation files.",
|
|
1813
|
-
"",
|
|
1814
|
-
"## Extending",
|
|
1815
|
-
"",
|
|
1816
|
-
`- **Plugins**: browse [packages/plugins](${REPO}/tree/main/packages/plugins)`,
|
|
1817
|
-
" in the Riebeckite repository — each package has its own README with options",
|
|
1818
|
-
" and examples.",
|
|
1819
|
-
"- **Themes**: this starter uses `@riebeckite/theme-default`; swap it for",
|
|
1820
|
-
" another theme in `riebeckite.config.ts`.",
|
|
1821
|
-
`- Docs: [English](${REPO}/blob/main/docs/en/README.md)`,
|
|
1822
|
-
` · [日本語](${REPO}/blob/main/docs/ja/README.md)`,
|
|
1823
2419
|
""
|
|
1824
|
-
|
|
2420
|
+
);
|
|
2421
|
+
if (preset.readme === "rich") {
|
|
2422
|
+
lines.push(`## ${words.localization}`, "");
|
|
2423
|
+
lines.push(words.localizationBody, "");
|
|
2424
|
+
lines.push(`## ${words.extending}`, "");
|
|
2425
|
+
lines.push(words.extendingBody, "");
|
|
2426
|
+
lines.push(
|
|
2427
|
+
`- Docs: [English](${REPO}/blob/main/docs/en/README.md)`,
|
|
2428
|
+
` · [日本語](${REPO}/blob/main/docs/ja/README.md)`,
|
|
2429
|
+
""
|
|
2430
|
+
);
|
|
2431
|
+
}
|
|
2432
|
+
return lines.join("\n");
|
|
1825
2433
|
}
|
|
1826
|
-
function
|
|
1827
|
-
|
|
2434
|
+
function readmeJa(preset, variables) {
|
|
2435
|
+
const words = README_WORDS.ja;
|
|
2436
|
+
const lines = [
|
|
1828
2437
|
`# ${variables.title}`,
|
|
1829
2438
|
"",
|
|
1830
|
-
|
|
1831
|
-
"
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
""
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
"
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
"## コマンド",
|
|
1848
|
-
"",
|
|
2439
|
+
README_INTRO[preset.name].ja,
|
|
2440
|
+
""
|
|
2441
|
+
];
|
|
2442
|
+
if (preset.readme !== "short") {
|
|
2443
|
+
lines.push(`## ${words.included}`, "");
|
|
2444
|
+
lines.push(`- **${words.languages}**: ${languagesLabel(preset, words)}`);
|
|
2445
|
+
lines.push(
|
|
2446
|
+
`- **${words.theme}**: ${preset.theme ? `\`${preset.theme.package}\`` : words.none}`
|
|
2447
|
+
);
|
|
2448
|
+
lines.push(
|
|
2449
|
+
`- **${words.plugins}**(${preset.plugins.length} 個): ${preset.plugins.length === 0 ? words.noPlugins : preset.plugins.map((p) => `\`${p.package}\``).join(", ")}`
|
|
2450
|
+
);
|
|
2451
|
+
lines.push(`- **${words.pages}**: ${pagesLabel(preset) ?? words.none}`);
|
|
2452
|
+
lines.push("");
|
|
2453
|
+
}
|
|
2454
|
+
lines.push(`## ${words.commands}`, "");
|
|
2455
|
+
lines.push(
|
|
1849
2456
|
"```sh",
|
|
1850
2457
|
"pnpm install",
|
|
1851
2458
|
"pnpm exec riebeckite check",
|
|
1852
2459
|
"pnpm exec riebeckite dev",
|
|
1853
2460
|
"pnpm exec riebeckite build",
|
|
1854
2461
|
"```",
|
|
1855
|
-
"",
|
|
1856
|
-
"## ローカライズ",
|
|
1857
|
-
"",
|
|
1858
|
-
"コンテンツは `content/` にプレーンな Markdown として置きます。翻訳ページは既定",
|
|
1859
|
-
"ファイルの隣に `<base>.<lang>.md` の規則で配置します(`about.ja.md`、",
|
|
1860
|
-
"`about.en.md` など)。既定言語は接尾辞なしのパス、それ以外は `/lang/` のパスで",
|
|
1861
|
-
"配信されます。",
|
|
1862
|
-
"",
|
|
1863
|
-
"言語の追加・削除は `riebeckite.config.ts` の `l10n(...)` プラグインを編集し、",
|
|
1864
|
-
"対応する翻訳ファイルを追加・削除してください。",
|
|
1865
|
-
"",
|
|
1866
|
-
"## 拡張",
|
|
1867
|
-
"",
|
|
1868
|
-
`- **プラグイン**: [packages/plugins](${REPO}/tree/main/packages/plugins) を`,
|
|
1869
|
-
" 参照してください。各パッケージにはオプションと例付きの README があります。",
|
|
1870
|
-
"- **テーマ**: このスターターは `@riebeckite/theme-default` を使用しています。",
|
|
1871
|
-
" `riebeckite.config.ts` で別のテーマに差し替えられます。",
|
|
1872
|
-
`- ドキュメント: [English](${REPO}/blob/main/docs/en/README.md)`,
|
|
1873
|
-
` · [日本語](${REPO}/blob/main/docs/ja/README.md)`,
|
|
1874
2462
|
""
|
|
1875
|
-
|
|
2463
|
+
);
|
|
2464
|
+
if (preset.readme === "rich") {
|
|
2465
|
+
lines.push(`## ${words.localization}`, "");
|
|
2466
|
+
lines.push(words.localizationBody, "");
|
|
2467
|
+
lines.push(`## ${words.extending}`, "");
|
|
2468
|
+
lines.push(words.extendingBody, "");
|
|
2469
|
+
lines.push(
|
|
2470
|
+
`- ドキュメント: [English](${REPO}/blob/main/docs/en/README.md)`,
|
|
2471
|
+
` · [日本語](${REPO}/blob/main/docs/ja/README.md)`,
|
|
2472
|
+
""
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
return lines.join("\n");
|
|
2476
|
+
}
|
|
2477
|
+
function languagesLabel(preset, words) {
|
|
2478
|
+
if (preset.languages.length === 0) return words.none;
|
|
2479
|
+
if (preset.languages.length === 1)
|
|
2480
|
+
return `${preset.languages[0]} (${words.single})`;
|
|
2481
|
+
return preset.languages.join(", ");
|
|
2482
|
+
}
|
|
2483
|
+
function pagesLabel(preset) {
|
|
2484
|
+
if (preset.contentPages.length === 0) return null;
|
|
2485
|
+
return preset.contentPages.map((page) => `/${page}`).join(", ");
|
|
1876
2486
|
}
|
|
1877
2487
|
function server() {
|
|
1878
2488
|
return `import { mountRiebeckiteEndpoints } from "@riebeckite/honox/server";
|
|
@@ -1972,37 +2582,63 @@ declare module "hono" {
|
|
|
1972
2582
|
}
|
|
1973
2583
|
`;
|
|
1974
2584
|
}
|
|
1975
|
-
function style() {
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
.site-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2585
|
+
function style(preset) {
|
|
2586
|
+
const imports = [];
|
|
2587
|
+
if (preset.plugins.length > 0) {
|
|
2588
|
+
imports.push('@import "./.riebeckite/plugin-styles.css";');
|
|
2589
|
+
}
|
|
2590
|
+
if (preset.theme) {
|
|
2591
|
+
imports.push('@import "./.riebeckite/theme-styles.css";');
|
|
2592
|
+
}
|
|
2593
|
+
const blocks = [
|
|
2594
|
+
"",
|
|
2595
|
+
"body {",
|
|
2596
|
+
" margin: 0;",
|
|
2597
|
+
" font-family: system-ui, sans-serif;",
|
|
2598
|
+
"}",
|
|
2599
|
+
""
|
|
2600
|
+
];
|
|
2601
|
+
if (preset.appFiles.includes("header")) {
|
|
2602
|
+
blocks.push(
|
|
2603
|
+
".site-header {",
|
|
2604
|
+
" display: flex;",
|
|
2605
|
+
" align-items: center;",
|
|
2606
|
+
" justify-content: space-between;",
|
|
2607
|
+
" gap: 1rem;",
|
|
2608
|
+
" padding: 1rem;",
|
|
2609
|
+
" border-bottom: 1px solid #d1d5db;",
|
|
2610
|
+
"}",
|
|
2611
|
+
"",
|
|
2612
|
+
".site-header__home {",
|
|
2613
|
+
" color: #111827;",
|
|
2614
|
+
" font-weight: 700;",
|
|
2615
|
+
" text-decoration: none;",
|
|
2616
|
+
"}",
|
|
2617
|
+
""
|
|
2618
|
+
);
|
|
2619
|
+
}
|
|
2620
|
+
if (preset.appFiles.includes("article")) {
|
|
2621
|
+
blocks.push(
|
|
2622
|
+
".site-article {",
|
|
2623
|
+
" display: block;",
|
|
2624
|
+
" max-width: 48rem;",
|
|
2625
|
+
" padding: 2rem 1rem;",
|
|
2626
|
+
" margin: 0 auto;",
|
|
2627
|
+
"}",
|
|
2628
|
+
""
|
|
2629
|
+
);
|
|
2630
|
+
}
|
|
2631
|
+
if (!preset.theme) {
|
|
2632
|
+
blocks.push(
|
|
2633
|
+
".riebeckite-empty {",
|
|
2634
|
+
" max-width: 48rem;",
|
|
2635
|
+
" padding: 4rem 1rem;",
|
|
2636
|
+
" margin: 0 auto;",
|
|
2637
|
+
"}",
|
|
2638
|
+
""
|
|
2639
|
+
);
|
|
2640
|
+
}
|
|
2641
|
+
return [...imports, ...blocks].join("\n");
|
|
2006
2642
|
}
|
|
2007
2643
|
function siteHeader() {
|
|
2008
2644
|
return `import { ColorModeToggle } from "@riebeckite/plugin-color-mode";
|
|
@@ -2049,13 +2685,18 @@ export function SiteArticle({
|
|
|
2049
2685
|
}
|
|
2050
2686
|
`;
|
|
2051
2687
|
}
|
|
2052
|
-
function renderer() {
|
|
2688
|
+
function renderer(preset) {
|
|
2689
|
+
if (!preset.theme) return bareRenderer();
|
|
2690
|
+
const hasHeader = preset.appFiles.includes("header");
|
|
2691
|
+
const hasColorMode = preset.plugins.some(
|
|
2692
|
+
(plugin) => plugin.package === "@riebeckite/plugin-color-mode"
|
|
2693
|
+
);
|
|
2053
2694
|
return `import type { PluginHeadTag } from "@riebeckite/core";
|
|
2054
2695
|
import { jsxRenderer } from "hono/jsx-renderer";
|
|
2055
2696
|
import { Link, Script } from "honox/server";
|
|
2056
|
-
import { ColorModeScript } from "@riebeckite/plugin-color-mode";
|
|
2057
|
-
import { SiteHeader } from "../components/site-header";
|
|
2058
|
-
import { config } from "../config";
|
|
2697
|
+
${hasColorMode ? `import { ColorModeScript } from "@riebeckite/plugin-color-mode";
|
|
2698
|
+
` : ""}${hasHeader ? `import { SiteHeader } from "../components/site-header";
|
|
2699
|
+
` : ""}import { config } from "../config";
|
|
2059
2700
|
|
|
2060
2701
|
function themeAttributes() {
|
|
2061
2702
|
const { theme } = config;
|
|
@@ -2081,14 +2722,14 @@ export default jsxRenderer(({ children }, c) => {
|
|
|
2081
2722
|
<meta charset="utf-8" />
|
|
2082
2723
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
2083
2724
|
<title>{config.site.title}</title>
|
|
2084
|
-
<ColorModeScript />
|
|
2085
|
-
<Link href="/app/style.css" rel="stylesheet" />
|
|
2725
|
+
${hasColorMode ? ` <ColorModeScript />
|
|
2726
|
+
` : ""} <Link href="/app/style.css" rel="stylesheet" />
|
|
2086
2727
|
{headTags.map(renderHeadTag)}
|
|
2087
2728
|
<Script src="/app/client.ts" async />
|
|
2088
2729
|
</head>
|
|
2089
2730
|
<body class="riebeckite-page">
|
|
2090
|
-
<SiteHeader />
|
|
2091
|
-
{children}
|
|
2731
|
+
${hasHeader ? ` <SiteHeader />
|
|
2732
|
+
` : ""} {children}
|
|
2092
2733
|
</body>
|
|
2093
2734
|
</html>
|
|
2094
2735
|
);
|
|
@@ -2110,7 +2751,27 @@ function renderHeadTag(tag: PluginHeadTag, index: number) {
|
|
|
2110
2751
|
}
|
|
2111
2752
|
`;
|
|
2112
2753
|
}
|
|
2113
|
-
function
|
|
2754
|
+
function bareRenderer() {
|
|
2755
|
+
return `import { jsxRenderer } from "hono/jsx-renderer";
|
|
2756
|
+
import { Link, Script } from "honox/server";
|
|
2757
|
+
import { config } from "../config";
|
|
2758
|
+
|
|
2759
|
+
export default jsxRenderer(({ children }, c) => (
|
|
2760
|
+
<html lang={c.get("htmlLanguage") ?? config.site.locale}>
|
|
2761
|
+
<head>
|
|
2762
|
+
<meta charset="utf-8" />
|
|
2763
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
2764
|
+
<title>{config.site.title}</title>
|
|
2765
|
+
<Link href="/app/style.css" rel="stylesheet" />
|
|
2766
|
+
<Script src="/app/client.ts" async />
|
|
2767
|
+
</head>
|
|
2768
|
+
<body class="riebeckite-page">{children}</body>
|
|
2769
|
+
</html>
|
|
2770
|
+
));
|
|
2771
|
+
`;
|
|
2772
|
+
}
|
|
2773
|
+
function indexRoute(preset) {
|
|
2774
|
+
if (!preset.appFiles.includes("article")) return staticIndexRoute();
|
|
2114
2775
|
return `import { isPublished } from "@riebeckite/core";
|
|
2115
2776
|
import { createRoute } from "honox/factory";
|
|
2116
2777
|
import { SiteArticle } from "../components/article";
|
|
@@ -2143,6 +2804,20 @@ export default createRoute(async (c) => {
|
|
|
2143
2804
|
});
|
|
2144
2805
|
`;
|
|
2145
2806
|
}
|
|
2807
|
+
function staticIndexRoute() {
|
|
2808
|
+
return `import { createRoute } from "honox/factory";
|
|
2809
|
+
import { config } from "../config";
|
|
2810
|
+
|
|
2811
|
+
export default createRoute((c) =>
|
|
2812
|
+
c.render(
|
|
2813
|
+
<main class="riebeckite-empty">
|
|
2814
|
+
<h1>{config.site.title}</h1>
|
|
2815
|
+
<p>This is a blank Riebeckite site. Add Markdown files under content/ to get started.</p>
|
|
2816
|
+
</main>,
|
|
2817
|
+
),
|
|
2818
|
+
);
|
|
2819
|
+
`;
|
|
2820
|
+
}
|
|
2146
2821
|
function slugRoute() {
|
|
2147
2822
|
return `import { isPublished } from "@riebeckite/core";
|
|
2148
2823
|
import {
|
|
@@ -2201,7 +2876,11 @@ var ScaffoldSiteError = class extends Error {
|
|
|
2201
2876
|
};
|
|
2202
2877
|
async function scaffoldRiebeckiteSite(options) {
|
|
2203
2878
|
const targetDirectory = path7.resolve(options.targetDirectory);
|
|
2204
|
-
const
|
|
2879
|
+
const preset = resolveScaffoldPreset(options.preset);
|
|
2880
|
+
const files = siteTemplateFiles(
|
|
2881
|
+
preset,
|
|
2882
|
+
templateVariables(options, targetDirectory)
|
|
2883
|
+
);
|
|
2205
2884
|
await assertTargetWritable(
|
|
2206
2885
|
targetDirectory,
|
|
2207
2886
|
files,
|
|
@@ -2253,20 +2932,25 @@ function isNotFoundError(error) {
|
|
|
2253
2932
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
2254
2933
|
}
|
|
2255
2934
|
export {
|
|
2935
|
+
SCAFFOLD_DEFAULT_PRESET,
|
|
2936
|
+
SCAFFOLD_PRESET_NAMES,
|
|
2256
2937
|
ScaffoldSiteError,
|
|
2257
2938
|
buildHonoxApplication,
|
|
2258
2939
|
createRiebeckiteSsg,
|
|
2259
2940
|
defaultSsgEntry,
|
|
2260
2941
|
defaultSsrExternals,
|
|
2942
|
+
isScaffoldPresetName,
|
|
2261
2943
|
loadRiebeckiteConfig,
|
|
2262
2944
|
replaceHonoxIslandDependencyPlugin,
|
|
2263
2945
|
resolveHonoxApplication,
|
|
2264
2946
|
resolveHonoxApplicationRoot,
|
|
2265
2947
|
resolveHonoxConfig,
|
|
2948
|
+
resolveScaffoldPreset,
|
|
2266
2949
|
riebeckite,
|
|
2267
2950
|
riebeckiteSsg,
|
|
2268
2951
|
riebeckiteSsgExtensionMap,
|
|
2269
2952
|
riebeckiteVite,
|
|
2953
|
+
scaffoldPresets,
|
|
2270
2954
|
scaffoldRiebeckiteSite,
|
|
2271
2955
|
startHonoxDevServer
|
|
2272
2956
|
};
|