@riebeckite/honox 0.0.4 → 0.0.6

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.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 alias = aliases.find(
32
+ const alias2 = aliases.find(
33
33
  (currentAlias) => currentAlias.find.test(args.path)
34
34
  );
35
- return alias ? { path: alias.replacement } : null;
35
+ return alias2 ? { path: alias2.replacement } : null;
36
36
  });
37
37
  }
38
38
  };
@@ -167,6 +167,10 @@ function replaceHonoxIslandDependencyPlugin(plugins) {
167
167
  ];
168
168
  }
169
169
  function disableHonoxIslandDependencyPlugin(plugin) {
170
+ if (!plugin || typeof plugin === "boolean") return plugin;
171
+ if (Array.isArray(plugin)) {
172
+ return plugin.map(disableHonoxIslandDependencyPlugin);
173
+ }
170
174
  if (plugin instanceof Promise) {
171
175
  return plugin.then(disableHonoxIslandDependencyPlugin);
172
176
  }
@@ -254,7 +258,7 @@ function isJavaScriptModule(filePath) {
254
258
  import fs6 from "node:fs/promises";
255
259
  import path7 from "node:path";
256
260
 
257
- // src/scaffold/localized-content.ts
261
+ // src/scaffold/presets.ts
258
262
  var SCAFFOLD_LANGUAGES = [
259
263
  "en",
260
264
  "ja",
@@ -274,154 +278,1235 @@ function defaultLanguageForLocale(locale) {
274
278
  if (normalized.startsWith("ko")) return "ko";
275
279
  return "en";
276
280
  }
277
- var HELPERS = {
278
- en: "https://github.com/Rerurate514/riebeckite/blob/main/docs/en/README.md",
279
- ja: "https://github.com/Rerurate514/riebeckite/blob/main/docs/ja/README.md"
281
+ var SCAFFOLD_PRESET_NAMES = [
282
+ "empty",
283
+ "minimal",
284
+ "starter",
285
+ "rich",
286
+ "full",
287
+ "max",
288
+ "ultra"
289
+ ];
290
+ function isScaffoldPresetName(value) {
291
+ return SCAFFOLD_PRESET_NAMES.includes(value);
292
+ }
293
+ var np = (package_, factory, options) => ({
294
+ package: package_,
295
+ factory,
296
+ options
297
+ });
298
+ var obsidianMarkdown = np(
299
+ "@riebeckite/plugin-obsidian-markdown",
300
+ "obsidianMarkdown"
301
+ );
302
+ var colorMode = np("@riebeckite/plugin-color-mode", "colorModePlugin");
303
+ var l10n = np("@riebeckite/plugin-l10n", "l10n", (context) => {
304
+ const defaultLang = defaultLanguageForLocale(context.variables.locale);
305
+ return `{ defaultLang: ${JSON.stringify(defaultLang)}, languages: ${JSON.stringify(context.languages)} }`;
306
+ });
307
+ var seo = np("@riebeckite/plugin-seo", "seo", {
308
+ siteName: {
309
+ depth: 1,
310
+ value: (context) => JSON.stringify(context.variables.title)
311
+ },
312
+ sitemap: { depth: 1, value: "true" },
313
+ robots: { depth: 2, value: "true" },
314
+ defaultImage: { depth: 3, value: '"/ogp.png"' },
315
+ feed: { depth: 3, value: "{ rss: true, atom: true, json: true }" }
316
+ });
317
+ var toc = np("@riebeckite/plugin-toc", "tocPlugin");
318
+ var properties = np("@riebeckite/plugin-properties", "properties", {
319
+ render: { depth: 1, value: '"slot"' },
320
+ include: { depth: 2, value: '["created", "modified", "tags", "status"]' },
321
+ order: { depth: 2, value: '["created", "modified", "tags", "status"]' }
322
+ });
323
+ var alias = np("@riebeckite/plugin-alias", "aliasPlugin", `{ status: 308 }`);
324
+ var codeEnhance = np("@riebeckite/plugin-code-enhance", "codeEnhance", {
325
+ lineNumbers: { depth: 1, value: "true" },
326
+ copyButton: { depth: 1, value: "true" },
327
+ filename: { depth: 2, value: "true" },
328
+ lineHighlight: { depth: 2, value: "true" },
329
+ diffHighlight: { depth: 2, value: "true" },
330
+ theme: { depth: 3, value: '{ light: "github-light", dark: "github-dark" }' },
331
+ wrapToggle: { depth: 3, value: "true" }
332
+ });
333
+ var search = np("@riebeckite/plugin-search", "searchPlugin");
334
+ var backlinks = np("@riebeckite/plugin-backlinks", "backlinksPlugin");
335
+ var relatedPosts = np("@riebeckite/plugin-related-posts", "relatedPosts", {
336
+ limit: { depth: 2, value: "5" },
337
+ useTags: { depth: 2, value: "true" },
338
+ useBacklinks: { depth: 2, value: "true" },
339
+ minScore: { depth: 3, value: "1" },
340
+ heading: { depth: 3, value: "true" },
341
+ headingText: { depth: 3, value: '"Related"' },
342
+ className: { depth: 3, value: '"rb-related-posts"' }
343
+ });
344
+ var share = np("@riebeckite/plugin-share", "share", {
345
+ placement: { depth: 2, value: '"bottom"' },
346
+ services: {
347
+ depth: 3,
348
+ value: '["x", "bluesky", "mastodon", "facebook", "linkedin", "hatena", "copy"]'
349
+ },
350
+ mastodonInstance: { depth: 3, value: '"mastodon.social"' }
351
+ });
352
+ var recentPosts = np("@riebeckite/plugin-recent-posts", "recentPostsPlugin");
353
+ var changelog = np("@riebeckite/plugin-changelog", "changelog", {
354
+ perNote: { depth: 2, value: "true" },
355
+ lookbackDays: { depth: 3, value: "90" },
356
+ dateFormat: { depth: 3, value: '"iso"' },
357
+ siteWide: { depth: 3, value: "false" }
358
+ });
359
+ var webmention = np("@riebeckite/plugin-webmention", "webmention", {
360
+ headingText: { depth: 2, value: '"Mentions"' },
361
+ limit: { depth: 3, value: "20" }
362
+ });
363
+ var attachment = np(
364
+ "@riebeckite/plugin-attachment",
365
+ "attachment",
366
+ `{ showSize: true }`
367
+ );
368
+ var pdf = np("@riebeckite/plugin-pdf", "pdf", {
369
+ height: { depth: 2, value: '"640px"' },
370
+ initialPage: { depth: 2, value: "1" },
371
+ toolbar: { depth: 2, value: "true" },
372
+ showMetadata: { depth: 3, value: "true" },
373
+ downloadLabel: { depth: 3, value: '"Download PDF"' }
374
+ });
375
+ var media = np("@riebeckite/plugin-media", "media", {
376
+ preload: { depth: 2, value: '"metadata"' },
377
+ lazy: { depth: 2, value: "true" },
378
+ showCaption: { depth: 3, value: "true" },
379
+ showDownload: { depth: 3, value: "false" },
380
+ showOpenOriginal: { depth: 3, value: "true" }
381
+ });
382
+ var responsiveImage = np(
383
+ "@riebeckite/plugin-responsive-image",
384
+ "responsiveImage",
385
+ {
386
+ lazy: { depth: 2, value: "true" },
387
+ decoding: { depth: 2, value: "true" },
388
+ sizes: { depth: 2, value: '"100vw"' },
389
+ widths: { depth: 2, value: "[640, 1280, 1920]" },
390
+ formats: { depth: 3, value: '["webp", "avif"]' },
391
+ className: { depth: 3, value: '"rb-responsive-image"' }
392
+ }
393
+ );
394
+ var lightbox = np(
395
+ "@riebeckite/plugin-lightbox",
396
+ "lightboxPlugin",
397
+ `{ selectorClass: "rr-lightbox-trigger" }`
398
+ );
399
+ var highlight = np("@riebeckite/plugin-highlight", "highlight", {
400
+ tag: { depth: 2, value: '"mark"' },
401
+ className: { depth: 3, value: '"rb-mark"' }
402
+ });
403
+ var codeTabs = np(
404
+ "@riebeckite/plugin-code-tabs",
405
+ "codeTabs",
406
+ `{ syncTabs: true }`
407
+ );
408
+ var codeAnnotations = np(
409
+ "@riebeckite/plugin-code-annotations",
410
+ "codeAnnotations",
411
+ `{ className: "rb-code" }`
412
+ );
413
+ var shortcodes = np(
414
+ "@riebeckite/plugin-shortcodes",
415
+ "shortcodes",
416
+ `{ builtins: true }`
417
+ );
418
+ var series = np("@riebeckite/plugin-series", "series", {
419
+ key: { depth: 2, value: '"series"' },
420
+ orderKey: { depth: 2, value: '"series_order"' },
421
+ titleKey: { depth: 2, value: '"series_title"' },
422
+ positionLabel: { depth: 2, value: "false" },
423
+ heading: { depth: 3, value: "true" },
424
+ className: { depth: 3, value: '"rb-series"' }
425
+ });
426
+ var taxonomy = np("@riebeckite/plugin-taxonomy", "taxonomy", {
427
+ tags: { depth: 2, value: "true" },
428
+ folders: { depth: 2, value: "true" },
429
+ related: { depth: 2, value: "true" },
430
+ feeds: { depth: 3, value: "{ rss: true, atom: true, json: true }" },
431
+ relatedLimit: { depth: 3, value: "8" }
432
+ });
433
+ var autoCardLink = np(
434
+ "@riebeckite/plugin-autocardlink",
435
+ "autoCardLinkPlugin",
436
+ `{ className: "rb-cardlink" }`
437
+ );
438
+ var richEmbed = np(
439
+ "@riebeckite/plugin-rich-embed",
440
+ "richEmbed",
441
+ `{ providers: ["youtube", "vimeo", "spotify"] }`
442
+ );
443
+ var gallery = np("@riebeckite/plugin-gallery", "gallery", {
444
+ columns: { depth: 2, value: "3" },
445
+ aspect: { depth: 2, value: '"4/3"' },
446
+ language: { depth: 3, value: '"gallery"' }
447
+ });
448
+ var mermaid = np("@riebeckite/plugin-mermaid", "mermaid", {
449
+ render: { depth: 2, value: '"build"' },
450
+ theme: { depth: 2, value: '{ light: "default", dark: "dark" }' },
451
+ caption: { depth: 3, value: "true" },
452
+ fallback: { depth: 3, value: "true" }
453
+ });
454
+ var graphviz = np("@riebeckite/plugin-graphviz", "graphviz", {
455
+ render: { depth: 2, value: '"build"' },
456
+ engine: { depth: 2, value: '"dot"' },
457
+ caption: { depth: 3, value: "true" },
458
+ fallback: { depth: 3, value: "true" }
459
+ });
460
+ var d2 = np("@riebeckite/plugin-d2", "d2", {
461
+ render: { depth: 2, value: '"build"' },
462
+ theme: { depth: 2, value: "{ light: 0, dark: 1 }" },
463
+ layout: { depth: 2, value: '"dagre"' },
464
+ caption: { depth: 3, value: "true" }
465
+ });
466
+ var plantuml = np("@riebeckite/plugin-plantuml", "plantuml", {
467
+ server: { depth: 2, value: '"https://www.plantuml.com/plantuml"' },
468
+ format: { depth: 2, value: '"svg"' },
469
+ caption: { depth: 3, value: "true" },
470
+ fallback: { depth: 3, value: "true" }
471
+ });
472
+ var chartjs = np("@riebeckite/plugin-chartjs", "chartjs", {
473
+ responsive: { depth: 2, value: "true" },
474
+ caption: { depth: 2, value: "true" },
475
+ className: { depth: 3, value: '"rb-chartjs"' }
476
+ });
477
+ var vegaLite = np("@riebeckite/plugin-vega-lite", "vegaLite", {
478
+ caption: { depth: 2, value: "true" },
479
+ theme: { depth: 2, value: '"light"' },
480
+ renderer: { depth: 2, value: '"canvas"' },
481
+ actions: { depth: 3, value: "false" },
482
+ className: { depth: 3, value: '"rb-vega-lite"' }
483
+ });
484
+ var wavedrom = np("@riebeckite/plugin-wavedrom", "wavedrom", {
485
+ skin: { depth: 2, value: '"default"' },
486
+ caption: { depth: 2, value: "true" },
487
+ fallback: { depth: 3, value: "true" },
488
+ className: { depth: 3, value: '"rb-wavedrom"' }
489
+ });
490
+ var markmap = np("@riebeckite/plugin-markmap", "markmap", {
491
+ caption: { depth: 2, value: "true" },
492
+ height: { depth: 2, value: "320" },
493
+ colorFreezeLevel: { depth: 3, value: "2" }
494
+ });
495
+ var map = np("@riebeckite/plugin-map", "map", {
496
+ zoom: { depth: 2, value: "13" },
497
+ height: { depth: 2, value: "320" },
498
+ tileUrl: {
499
+ depth: 3,
500
+ value: JSON.stringify("https://tile.openstreetmap.org/{z}/{x}/{y}.png")
501
+ },
502
+ attribution: {
503
+ depth: 3,
504
+ value: JSON.stringify(
505
+ '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
506
+ )
507
+ }
508
+ });
509
+ var marp = np("@riebeckite/plugin-marp", "marp", {
510
+ theme: { depth: 2, value: '"default"' },
511
+ allowHtml: { depth: 2, value: "true" },
512
+ math: { depth: 2, value: "true" },
513
+ caption: { depth: 3, value: "true" }
514
+ });
515
+ var qrCode = np("@riebeckite/plugin-qr-code", "qrCode", {
516
+ level: { depth: 2, value: '"M"' },
517
+ margin: { depth: 2, value: "1" },
518
+ width: { depth: 2, value: "160" },
519
+ dark: { depth: 3, value: '"#000000"' },
520
+ light: { depth: 3, value: '"#ffffff"' },
521
+ caption: { depth: 3, value: "true" },
522
+ className: { depth: 3, value: '"rb-qr"' }
523
+ });
524
+ var discordEmbed = np("@riebeckite/plugin-discord-embed", "discordEmbed", {
525
+ themeColor: { depth: 2, value: '"#5865F2"' },
526
+ imageAlt: { depth: 3, value: "true" },
527
+ imageDimensions: { depth: 3, value: "true" }
528
+ });
529
+ var excalidraw = np(
530
+ "@riebeckite/plugin-excalidraw",
531
+ "excalidraw",
532
+ `{ lazy: true }`
533
+ );
534
+ var excaliBrain = np("@riebeckite/plugin-excalibrain", "excaliBrain", {
535
+ render: { depth: 2, value: '"build"' },
536
+ auto: { depth: 2, value: "true" },
537
+ heading: { depth: 2, value: "true" },
538
+ infer: { depth: 2, value: "true" },
539
+ siblings: { depth: 2, value: "true" },
540
+ headingText: { depth: 3, value: '"ExcaliBrain"' },
541
+ width: { depth: 3, value: "720" },
542
+ height: { depth: 3, value: "480" }
543
+ });
544
+ var canvas = np("@riebeckite/plugin-canvas", "canvas", {
545
+ language: { depth: 2, value: '"canvas"' },
546
+ render: { depth: 2, value: '"both"' },
547
+ className: { depth: 3, value: '"rb-canvas"' }
548
+ });
549
+ var bases = np("@riebeckite/plugin-bases", "bases", {
550
+ language: { depth: 2, value: '"base"' },
551
+ limit: { depth: 2, value: "100" },
552
+ className: { depth: 3, value: '"rb-bases"' },
553
+ showFallback: { depth: 3, value: "true" }
554
+ });
555
+ var dataview = np("@riebeckite/plugin-dataview", "dataviewPlugin", {
556
+ limit: { depth: 2, value: "50" },
557
+ className: { depth: 3, value: '"rb-dataview"' },
558
+ hideFallback: { depth: 3, value: "false" }
559
+ });
560
+ var flashcards = np("@riebeckite/plugin-flashcards", "flashcardsPlugin", {
561
+ shuffle: { depth: 2, value: "true" },
562
+ fallback: { depth: 2, value: "true" },
563
+ className: { depth: 3, value: '"rb-flashcards"' }
564
+ });
565
+ var kanban = np("@riebeckite/plugin-kanban", "kanban", {
566
+ columnMarker: { depth: 2, value: '"##"' },
567
+ autoDetect: { depth: 2, value: "true" },
568
+ className: { depth: 3, value: '"rb-kanban"' },
569
+ fallback: { depth: 3, value: "true" }
570
+ });
571
+ var query = np("@riebeckite/plugin-query", "queryPlugin", {
572
+ defaultFormat: { depth: 2, value: '"list"' },
573
+ defaultLimit: { depth: 2, value: "50" },
574
+ className: { depth: 3, value: '"rb-query"' },
575
+ excludeSelf: { depth: 3, value: "true" }
576
+ });
577
+ var localGraph = np("@riebeckite/plugin-local-graph", "localGraphPlugin");
578
+ var hoverPreview = np(
579
+ "@riebeckite/plugin-hover-preview",
580
+ "hoverPreviewPlugin",
581
+ {
582
+ delay: { depth: 2, value: "120" },
583
+ excerptLength: { depth: 2, value: "160" },
584
+ selector: { depth: 2, value: 'a[href^="/"]' },
585
+ includeTitles: { depth: 3, value: "true" }
586
+ }
587
+ );
588
+ var gardenExplorer = np(
589
+ "@riebeckite/plugin-garden-explorer",
590
+ "gardenExplorerPlugin"
591
+ );
592
+ var ux = np("@riebeckite/plugin-ux", "uxPlugin", {
593
+ progress: { depth: 2, value: "true" },
594
+ backToTop: { depth: 2, value: "true" },
595
+ tocScrollSpy: { depth: 2, value: "true" },
596
+ codeCopy: { depth: 3, value: "true" }
597
+ });
598
+ var dailyNotes = np(
599
+ "@riebeckite/plugin-daily-notes",
600
+ "dailyNotesPlugin",
601
+ `{ source: { directory: "Daily", pathPattern: "Daily/{YYYY}-{MM}-{DD}" }, extract: { frontmatter: "daily-summary", codeBlock: "daily-snippet" }, widget: { limit: 5 } }`
602
+ );
603
+ var rename = np(
604
+ "@riebeckite/plugin-rename",
605
+ "renamePlugin",
606
+ `{ enabled: true, status: 308, onUnexpectedRemoval: "warning" }`
607
+ );
608
+ var textFragment = np(
609
+ "@riebeckite/plugin-text-fragment",
610
+ "textFragmentPlugin",
611
+ (context) => `{ prefix: ${JSON.stringify(`${context.variables.title}: `)} }`
612
+ );
613
+ var quality = np(
614
+ "@riebeckite/plugin-quality",
615
+ "qualityPlugin",
616
+ `{ a11y: { enabled: true }, ignoreRules: [] }`
617
+ );
618
+ var deploy = np(
619
+ "@riebeckite/plugin-deploy",
620
+ "deployPlugin",
621
+ (context) => `{ provider: "cloudflare-pages", baseUrl: ${JSON.stringify(context.variables.baseUrl)} }`
622
+ );
623
+ var diagnostics = np(
624
+ "@riebeckite/plugin-diagnostics",
625
+ "diagnostics",
626
+ `{ reportUnusedAssets: true, reportOrphans: true, requiredFrontmatter: ["title"] }`
627
+ );
628
+ var defaultTheme = {
629
+ package: "@riebeckite/theme-default",
630
+ factory: "defaultTheme"
280
631
  };
281
- var PLUGIN_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/plugins";
282
- var THEMES_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/themes";
283
- function pluginReadmeUrl(slug) {
284
- return `https://github.com/Rerurate514/riebeckite/blob/main/packages/plugins/${slug}/README.md`;
632
+ var showCaseTheme = {
633
+ package: "@riebeckite/theme-default",
634
+ factory: "defaultTheme",
635
+ options: '{ colorMode: "system", typography: "system", articleLayout: "article", userCss: [] }'
636
+ };
637
+ var minimalTheme = {
638
+ package: "@riebeckite/theme-minimal",
639
+ factory: "minimalTheme"
640
+ };
641
+ var BASE_APP_FILES = [
642
+ "server",
643
+ "client",
644
+ "config",
645
+ "content",
646
+ "paths",
647
+ "global",
648
+ "style",
649
+ "renderer"
650
+ ];
651
+ var empty = {
652
+ name: "empty",
653
+ description: "A blank application shell: no plugins, no theme, no content, no components.",
654
+ languages: [],
655
+ theme: null,
656
+ plugins: [],
657
+ contentPages: [],
658
+ appFiles: [...BASE_APP_FILES, "index"],
659
+ readme: "short"
660
+ };
661
+ var minimal = {
662
+ name: "minimal",
663
+ description: "The smallest useful site: Obsidian Markdown, the minimal theme, and one page.",
664
+ languages: ["en"],
665
+ theme: minimalTheme,
666
+ plugins: [obsidianMarkdown],
667
+ contentPages: ["index"],
668
+ appFiles: [...BASE_APP_FILES, "index", "slug", "article"],
669
+ readme: "short"
670
+ };
671
+ var starter = {
672
+ name: "starter",
673
+ description: "The default starter: Obsidian Markdown, color mode, seven languages, and a site header.",
674
+ languages: [...SCAFFOLD_LANGUAGES],
675
+ theme: defaultTheme,
676
+ plugins: [obsidianMarkdown, colorMode, l10n],
677
+ contentPages: ["index"],
678
+ appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
679
+ readme: "standard"
680
+ };
681
+ var rich = {
682
+ name: "rich",
683
+ description: "A showcasing starter: publishing and reading plugins plus guided ecosystem tour pages in seven languages.",
684
+ languages: [...SCAFFOLD_LANGUAGES],
685
+ theme: showCaseTheme,
686
+ plugins: [
687
+ obsidianMarkdown,
688
+ colorMode,
689
+ l10n,
690
+ seo,
691
+ toc,
692
+ properties,
693
+ alias,
694
+ codeEnhance
695
+ ],
696
+ contentPages: ["index", "framework/plugins", "framework/themes"],
697
+ appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
698
+ readme: "rich"
699
+ };
700
+ var full = {
701
+ name: "full",
702
+ description: "A ready blog: discovery, media, and reading plugins plus a build guide.",
703
+ languages: [...SCAFFOLD_LANGUAGES],
704
+ theme: showCaseTheme,
705
+ plugins: [
706
+ obsidianMarkdown,
707
+ colorMode,
708
+ l10n,
709
+ seo,
710
+ toc,
711
+ properties,
712
+ alias,
713
+ codeEnhance,
714
+ search,
715
+ backlinks,
716
+ relatedPosts,
717
+ share,
718
+ changelog,
719
+ webmention,
720
+ recentPosts,
721
+ attachment,
722
+ pdf,
723
+ media,
724
+ responsiveImage,
725
+ lightbox,
726
+ highlight,
727
+ codeTabs,
728
+ codeAnnotations,
729
+ shortcodes,
730
+ series,
731
+ taxonomy,
732
+ autoCardLink,
733
+ richEmbed,
734
+ gallery
735
+ ],
736
+ contentPages: ["index", "framework/plugins", "framework/themes", "guide"],
737
+ appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
738
+ readme: "rich"
739
+ };
740
+ var max = {
741
+ name: "max",
742
+ description: "Diagram and knowledge plugins on top of full, with showcase example pages.",
743
+ languages: [...SCAFFOLD_LANGUAGES],
744
+ theme: showCaseTheme,
745
+ plugins: [
746
+ obsidianMarkdown,
747
+ colorMode,
748
+ l10n,
749
+ seo,
750
+ toc,
751
+ properties,
752
+ alias,
753
+ codeEnhance,
754
+ search,
755
+ backlinks,
756
+ relatedPosts,
757
+ share,
758
+ changelog,
759
+ webmention,
760
+ recentPosts,
761
+ attachment,
762
+ pdf,
763
+ media,
764
+ responsiveImage,
765
+ lightbox,
766
+ highlight,
767
+ codeTabs,
768
+ codeAnnotations,
769
+ shortcodes,
770
+ series,
771
+ taxonomy,
772
+ autoCardLink,
773
+ richEmbed,
774
+ gallery,
775
+ mermaid,
776
+ graphviz,
777
+ d2,
778
+ plantuml,
779
+ chartjs,
780
+ vegaLite,
781
+ wavedrom,
782
+ markmap,
783
+ map,
784
+ marp,
785
+ qrCode,
786
+ discordEmbed,
787
+ excalidraw,
788
+ excaliBrain,
789
+ canvas,
790
+ bases,
791
+ dataview,
792
+ flashcards,
793
+ kanban,
794
+ query,
795
+ localGraph,
796
+ hoverPreview,
797
+ gardenExplorer,
798
+ ux
799
+ ],
800
+ contentPages: [
801
+ "index",
802
+ "framework/plugins",
803
+ "framework/themes",
804
+ "guide",
805
+ "examples"
806
+ ],
807
+ appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
808
+ readme: "rich"
809
+ };
810
+ var ultra = {
811
+ name: "ultra",
812
+ description: "The full plugin catalog and theme reference pages — everything the ecosystem offers.",
813
+ languages: [...SCAFFOLD_LANGUAGES],
814
+ theme: showCaseTheme,
815
+ plugins: [
816
+ obsidianMarkdown,
817
+ colorMode,
818
+ l10n,
819
+ seo,
820
+ toc,
821
+ properties,
822
+ alias,
823
+ codeEnhance,
824
+ search,
825
+ backlinks,
826
+ relatedPosts,
827
+ share,
828
+ changelog,
829
+ webmention,
830
+ recentPosts,
831
+ attachment,
832
+ pdf,
833
+ media,
834
+ responsiveImage,
835
+ lightbox,
836
+ highlight,
837
+ codeTabs,
838
+ codeAnnotations,
839
+ shortcodes,
840
+ series,
841
+ taxonomy,
842
+ autoCardLink,
843
+ richEmbed,
844
+ gallery,
845
+ mermaid,
846
+ graphviz,
847
+ d2,
848
+ plantuml,
849
+ chartjs,
850
+ vegaLite,
851
+ wavedrom,
852
+ markmap,
853
+ map,
854
+ marp,
855
+ qrCode,
856
+ discordEmbed,
857
+ excalidraw,
858
+ excaliBrain,
859
+ canvas,
860
+ bases,
861
+ dataview,
862
+ flashcards,
863
+ kanban,
864
+ query,
865
+ localGraph,
866
+ hoverPreview,
867
+ gardenExplorer,
868
+ ux,
869
+ dailyNotes,
870
+ rename,
871
+ textFragment,
872
+ quality,
873
+ deploy,
874
+ diagnostics
875
+ ],
876
+ contentPages: [
877
+ "index",
878
+ "framework/plugins",
879
+ "framework/themes",
880
+ "guide",
881
+ "examples",
882
+ "reference/plugins",
883
+ "reference/themes"
884
+ ],
885
+ appFiles: [...BASE_APP_FILES, "index", "slug", "header", "article"],
886
+ readme: "rich"
887
+ };
888
+ var scaffoldPresets = { empty, minimal, starter, rich, full, max, ultra };
889
+ var SCAFFOLD_DEFAULT_PRESET = "starter";
890
+ function resolveScaffoldPreset(value) {
891
+ if (value === void 0) return scaffoldPresets[SCAFFOLD_DEFAULT_PRESET];
892
+ if (typeof value === "object") return value;
893
+ const preset = scaffoldPresets[value];
894
+ if (!preset) {
895
+ throw new Error(
896
+ `Unknown scaffold preset: ${value}. Available presets: ${SCAFFOLD_PRESET_NAMES.join(", ")}.`
897
+ );
898
+ }
899
+ return preset;
285
900
  }
286
- function themeReadmeUrl(slug) {
287
- return `https://github.com/Rerurate514/riebeckite/blob/main/packages/themes/${slug}/README.md`;
901
+
902
+ // src/vite_plugin.ts
903
+ import path6 from "node:path";
904
+
905
+ // src/asset_entries.ts
906
+ import fs4 from "node:fs";
907
+ import path4 from "node:path";
908
+ import { uniqueStrings } from "@riebeckite/core";
909
+ function writeRiebeckiteAssetEntries(config, paths2) {
910
+ writeGeneratedFile(paths2.pluginStyles, createPluginStylesEntry(config));
911
+ writeGeneratedFile(paths2.themeStyles, createThemeStylesEntry(config));
288
912
  }
289
- function localizedContentFiles(variables) {
290
- const defaultLang = defaultLanguageForLocale(variables.locale);
291
- const pages = [
292
- { basePath: "index", build: (language) => indexContent(variables, language) },
293
- { basePath: "framework/plugins", build: (language) => pluginsContent(language) },
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;
913
+ function createPluginStylesEntry(config) {
914
+ return createStylesheetEntry(
915
+ collectPluginStyleSpecifiers(config),
916
+ "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."
917
+ );
307
918
  }
308
- function read(text, language) {
309
- return text[language];
919
+ function createThemeStylesEntry(config) {
920
+ return createStylesheetEntry(
921
+ config.theme.styles.map((style2) => style2.moduleSpecifier),
922
+ "Theme styles. Generated by @riebeckite/honox; do not edit. Import this after the plugin stylesheet so the theme wins the plugin/theme cascade."
923
+ );
310
924
  }
311
- function frontmatter() {
312
- return ["---", "publish: true", "---", ""].join("\n");
925
+ function collectPluginStyleSpecifiers(config) {
926
+ return config.plugins.flatMap(
927
+ (plugin) => (plugin.assets ?? []).filter((asset) => asset.kind === "style").map((asset) => asset.moduleSpecifier)
928
+ );
313
929
  }
314
- function heading(level, text) {
315
- return `${"#".repeat(level)} ${text}`;
930
+ function createStylesheetEntry(moduleSpecifiers, banner) {
931
+ const imports = uniqueStrings(moduleSpecifiers).map((specifier) => `@import ${JSON.stringify(specifier)};`).join("\n");
932
+ if (!banner) return imports;
933
+ const header = `/* ${banner.replace(/\*\//g, "* /")} */`;
934
+ return imports ? `${header}
935
+ ${imports}
936
+ ` : `${header}
937
+ `;
316
938
  }
317
- function codeBlock(language, code) {
318
- return ["```" + language, code, "```", ""].join("\n");
939
+ function writeGeneratedFile(filePath, contents) {
940
+ fs4.mkdirSync(path4.dirname(filePath), { recursive: true });
941
+ fs4.writeFileSync(filePath, contents);
319
942
  }
320
- var INDEX = {
321
- lead: {
322
- en: "Welcome to your Riebeckite site.",
323
- ja: "あなたの Riebeckite サイトへようこそ。",
324
- "zh-CN": "欢迎来到你的 Riebeckite 站点。",
325
- es: "Bienvenido a tu sitio Riebeckite.",
326
- de: "Willkommen auf deiner Riebeckite-Seite.",
327
- fr: "Bienvenue sur votre site Riebeckite.",
328
- ko: "Riebeckite 사이트에 오신 것을 환영합니다."
329
- },
330
- translatedNote: {
331
- en: "Every page of this starter is available in seven languages. Switch with the selector below the page title.",
332
- ja: "このスターターのすべてのページは 7 言語で利用できます。ページタイトル下のセレクターで切り替えられます。",
333
- "zh-CN": "本模板的每个页面均提供七种语言版本,可用页面标题下方的选择器切换。",
334
- es: "Cada página de este starter está disponible en siete idiomas. Cámbialos con el selector bajo el título.",
335
- de: "Jede Seite dieses Starters ist in sieben Sprachen verfügbar. Wechsel mit dem Auswahlfeld unter dem Seitentitel.",
336
- fr: "Chaque page de ce starter est disponible en sept langues. Changez avec le sélecteur sous le titre.",
337
- ko: "이 스타터의 모든 페이지는 7개 언어로 제공됩니다. 페이지 제목 아래 선택기로 전환하세요."
338
- },
339
- whatHeading: {
340
- en: "What is Riebeckite?",
341
- ja: "Riebeckite とは",
342
- "zh-CN": "什么是 Riebeckite?",
343
- es: "¿Qué es Riebeckite?",
344
- de: "Was ist Riebeckite?",
345
- fr: "Qu'est-ce que Riebeckite ?",
346
- ko: "Riebeckite란?"
347
- },
348
- whatBody: {
349
- 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.",
350
- ja: "Riebeckite は、プレーンな Markdown(Obsidian で管理しているのと同じノート)から高速な静的サイトを生成する、拡張性のあるコンテンツファーストのフレームワークです。エコシステムには 50 以上のプラグインと 6 つのテーマがあり、このサイトはその両方をデモしています。",
351
- "zh-CN": "Riebeckite 是一个可扩展、内容优先的框架,可从纯 Markdown(即你在 Obsidian 中保存的笔记)构建快速的静态站点。生态包含 50+ 插件与六个主题,本站点同时演示两者。",
352
- 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.",
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/` 경로로 서빙하며 자동으로 링크합니다."
410
- }
411
- };
412
- function indexContent(variables, language) {
413
- const title = variables.title;
414
- return [
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)),
943
+
944
+ // src/client_module.ts
945
+ import {
946
+ serializePublicClientConfig
947
+ } from "@riebeckite/core";
948
+ var clientModuleId = "virtual:riebeckite/client";
949
+ var resolvedClientModuleId = `\0${clientModuleId}`;
950
+ function riebeckiteClientModule(getConfig) {
951
+ return {
952
+ name: "riebeckite-client-module",
953
+ resolveId(id) {
954
+ if (id === clientModuleId) return resolvedClientModuleId;
955
+ return null;
956
+ },
957
+ load(id) {
958
+ if (id !== resolvedClientModuleId) return null;
959
+ return createClientModule(getConfig());
960
+ }
961
+ };
962
+ }
963
+ function createClientModule(config) {
964
+ const imports = [];
965
+ const initializers = [];
966
+ for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
967
+ const localName = `pluginClientInitializer${index}`;
968
+ const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
969
+ imports.push(
970
+ `import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
971
+ );
972
+ const publicConfig = entry.publicConfig;
973
+ initializers.push(
974
+ publicConfig === void 0 ? `${localName}()` : `${localName}(${serializePublicClientConfig(publicConfig)})`
975
+ );
976
+ }
977
+ return `${imports.join("\n")}
978
+
979
+ export function initRiebeckiteClient() {
980
+ ${initializers.map((initializer) => ` ${initializer};`).join("\n")}
981
+ }
982
+ `;
983
+ }
984
+
985
+ // src/ssg_plugin.ts
986
+ import { relative } from "node:path";
987
+ import { defaultExtensionMap, toSSG } from "hono/ssg";
988
+ import { createServer } from "vite";
989
+ var defaultEntry = "./src/index.tsx";
990
+ function riebeckiteSsg(options = {}) {
991
+ const virtualId = "virtual:riebeckite-ssg-void-entry";
992
+ const resolvedVirtualId = `\0${virtualId}`;
993
+ const entry = options.entry ?? defaultEntry;
994
+ let resolvedConfig;
995
+ return {
996
+ name: "riebeckite-ssg",
997
+ apply: "build",
998
+ enforce: "post",
999
+ config() {
1000
+ return {
1001
+ build: {
1002
+ rollupOptions: {
1003
+ input: [virtualId]
1004
+ }
1005
+ }
1006
+ };
1007
+ },
1008
+ configResolved(config) {
1009
+ resolvedConfig = config;
1010
+ },
1011
+ resolveId(id) {
1012
+ return id === virtualId ? resolvedVirtualId : void 0;
1013
+ },
1014
+ load(id) {
1015
+ return id === resolvedVirtualId ? 'console.log("suppress empty chunk message")' : void 0;
1016
+ },
1017
+ async generateBundle(_outputOptions, bundle) {
1018
+ const config = resolvedConfig;
1019
+ if (!config) {
1020
+ throw new Error(
1021
+ "Riebeckite SSG could not resolve the Vite configuration."
1022
+ );
1023
+ }
1024
+ removeVirtualEntryChunk(bundle, resolvedVirtualId);
1025
+ const server2 = await createServer({
1026
+ root: config.root,
1027
+ define: config.define,
1028
+ resolve: {
1029
+ ...config.resolve,
1030
+ builtins: [...config.resolve.builtins, /^node:/]
1031
+ },
1032
+ plugins: [],
1033
+ build: { ssr: true },
1034
+ mode: config.mode
1035
+ });
1036
+ try {
1037
+ const module = await server2.ssrLoadModule(entry);
1038
+ const app = module.default;
1039
+ if (!app) {
1040
+ throw new Error(`Failed to find a default export from ${entry}.`);
1041
+ }
1042
+ const generatedHtml = [];
1043
+ const result = await toSSG(
1044
+ app,
1045
+ {
1046
+ writeFile: async (filePath, data) => {
1047
+ const fileName = relative(
1048
+ config.build.outDir,
1049
+ filePath
1050
+ ).replaceAll("\\", "/");
1051
+ if (fileName.endsWith(".html") && typeof data === "string") {
1052
+ generatedHtml.push({ path: fileName, html: data });
1053
+ }
1054
+ this.emitFile({
1055
+ type: "asset",
1056
+ fileName,
1057
+ source: data
1058
+ });
1059
+ },
1060
+ async mkdir() {
1061
+ }
1062
+ },
1063
+ {
1064
+ dir: config.build.outDir,
1065
+ plugins: options.plugins ?? [],
1066
+ extensionMap: options.extensionMap ?? defaultExtensionMap
1067
+ }
1068
+ );
1069
+ if (!result.success) throw result.error;
1070
+ await emitGeneratedOutputs(module, (asset) => this.emitFile(asset));
1071
+ inspectGeneratedHtmlPages(module, generatedHtml, {
1072
+ warn: (message) => this.warn(message),
1073
+ info: (message) => this.info(message)
1074
+ });
1075
+ } finally {
1076
+ await server2.close();
1077
+ }
1078
+ }
1079
+ };
1080
+ }
1081
+ async function emitGeneratedOutputs(module, emit) {
1082
+ const content = module.content;
1083
+ if (!content) return;
1084
+ const manifest = await content.getManifest();
1085
+ for (const output of manifest.generatedOutputs ?? []) {
1086
+ emit({
1087
+ type: "asset",
1088
+ fileName: output.path,
1089
+ source: output.content
1090
+ });
1091
+ }
1092
+ }
1093
+ function inspectGeneratedHtmlPages(module, pages, log) {
1094
+ const plugins = module.config?.plugins ?? [];
1095
+ for (const plugin of plugins) {
1096
+ const inspector = plugin.inspectGeneratedHtml;
1097
+ if (typeof inspector !== "function") continue;
1098
+ for (const page of pages) {
1099
+ for (const diagnostic of inspector(page) ?? []) {
1100
+ const label = `[${plugin.name ?? "plugin"}] ${page.path}: ${diagnostic.message}`;
1101
+ if (diagnostic.severity === "info") log.info(label);
1102
+ else log.warn(label);
1103
+ }
1104
+ }
1105
+ }
1106
+ }
1107
+ function removeVirtualEntryChunk(bundle, virtualEntryId) {
1108
+ for (const chunk of Object.values(bundle)) {
1109
+ if (chunk.type === "chunk" && chunk.moduleIds?.includes(virtualEntryId)) {
1110
+ delete bundle[chunk.fileName];
1111
+ }
1112
+ }
1113
+ }
1114
+
1115
+ // src/ssg.ts
1116
+ var defaultSsgEntry = "./app/server.ts";
1117
+ function riebeckiteSsgExtensionMap() {
1118
+ return {
1119
+ "application/atom+xml": "xml",
1120
+ "application/json": "json",
1121
+ "application/rss+xml": "xml",
1122
+ "application/xml": "xml",
1123
+ "text/html": "html",
1124
+ "text/plain": "txt",
1125
+ "text/xml": "xml"
1126
+ };
1127
+ }
1128
+ function createRiebeckiteSsg(options = {}) {
1129
+ return riebeckiteSsg({
1130
+ ...options,
1131
+ entry: options.entry ?? defaultSsgEntry,
1132
+ extensionMap: {
1133
+ ...riebeckiteSsgExtensionMap(),
1134
+ ...options.extensionMap
1135
+ }
1136
+ });
1137
+ }
1138
+
1139
+ // src/vite_runner.ts
1140
+ import fs5 from "node:fs/promises";
1141
+ import path5 from "node:path";
1142
+ import { build, createServer as createServer2 } from "vite";
1143
+ var viteConfigFileNames = [
1144
+ "vite.config.ts",
1145
+ "vite.config.js",
1146
+ "vite.config.mjs"
1147
+ ];
1148
+ async function resolveHonoxApplicationRoot(configRoot) {
1149
+ const roots = await findViteApplicationRoots(configRoot);
1150
+ if (roots.length === 1) return roots[0];
1151
+ if (roots.length === 0) {
1152
+ throw new HonoxApplicationRootError(
1153
+ `Could not find a Vite application under ${configRoot}.`
1154
+ );
1155
+ }
1156
+ throw new HonoxApplicationRootError(
1157
+ `Found multiple Vite applications under ${configRoot}: ${roots.join(", ")}.`
1158
+ );
1159
+ }
1160
+ var HonoxApplicationRootError = class extends Error {
1161
+ constructor(message) {
1162
+ super(message);
1163
+ this.name = "HonoxApplicationRootError";
1164
+ }
1165
+ };
1166
+ async function resolveHonoxApplication(options) {
1167
+ const configRoot = path5.resolve(options.configRoot);
1168
+ const appRoot = options.appRoot ? path5.resolve(options.appRoot) : await resolveHonoxApplicationRoot(configRoot);
1169
+ const workspaceRoot = options.workspaceRoot ?? await findWorkspaceRoot(configRoot);
1170
+ const rawConfig = await loadRiebeckiteConfig({
1171
+ configRoot,
1172
+ configFile: options.configFile,
1173
+ workspaceRoot
1174
+ });
1175
+ const config = resolveHonoxConfig(rawConfig, appRoot);
1176
+ return {
1177
+ config,
1178
+ configRoot,
1179
+ appRoot,
1180
+ contentRoot: config.content.directory
1181
+ };
1182
+ }
1183
+ async function findWorkspaceRoot(configRoot) {
1184
+ try {
1185
+ const workspaceConfig = path5.join(configRoot, "pnpm-workspace.yaml");
1186
+ return (await fs5.stat(workspaceConfig)).isFile() ? configRoot : void 0;
1187
+ } catch {
1188
+ return void 0;
1189
+ }
1190
+ }
1191
+ async function startHonoxDevServer(options) {
1192
+ const server2 = await createServer2({ root: options.root });
1193
+ await server2.listen();
1194
+ server2.printUrls();
1195
+ await waitForShutdown(server2);
1196
+ }
1197
+ async function buildHonoxApplication(options) {
1198
+ await runTraced(
1199
+ options.tracer,
1200
+ "integration.honox.client_build",
1201
+ () => build({ root: options.root, mode: "client" })
1202
+ );
1203
+ await runTraced(
1204
+ options.tracer,
1205
+ "integration.honox.server_build",
1206
+ () => build({ root: options.root })
1207
+ );
1208
+ }
1209
+ async function runTraced(tracer, name, buildTask) {
1210
+ return tracer ? await tracer.span(name, {}, buildTask) : await buildTask();
1211
+ }
1212
+ async function waitForShutdown(server2) {
1213
+ await new Promise((resolve) => {
1214
+ const close = () => {
1215
+ void server2.close().finally(resolve);
1216
+ };
1217
+ process.once("SIGINT", close);
1218
+ process.once("SIGTERM", close);
1219
+ });
1220
+ }
1221
+ async function findViteApplicationRoots(root) {
1222
+ const directories = [root];
1223
+ const applicationRoots = [];
1224
+ while (directories.length > 0) {
1225
+ const directory = directories.pop();
1226
+ if (!directory) continue;
1227
+ if (await hasViteConfig(directory)) applicationRoots.push(directory);
1228
+ const entries = await fs5.readdir(directory, { withFileTypes: true });
1229
+ for (const entry of entries) {
1230
+ if (!entry.isDirectory() || entry.name === "node_modules" || entry.name === ".git" || entry.name === "tests") {
1231
+ continue;
1232
+ }
1233
+ directories.push(path5.join(directory, entry.name));
1234
+ }
1235
+ }
1236
+ return applicationRoots;
1237
+ }
1238
+ async function hasViteConfig(directory) {
1239
+ for (const fileName of viteConfigFileNames) {
1240
+ try {
1241
+ if ((await fs5.stat(path5.join(directory, fileName))).isFile()) return true;
1242
+ } catch {
1243
+ }
1244
+ }
1245
+ return false;
1246
+ }
1247
+
1248
+ // src/vite_plugin.ts
1249
+ var defaultSsrExternals = [
1250
+ "extend",
1251
+ "debug",
1252
+ "node:fs/promises",
1253
+ "node:path",
1254
+ "parse-numeric-range",
1255
+ "slugify",
1256
+ "vfile-matter",
1257
+ "yaml"
1258
+ ];
1259
+ function riebeckite(options = {}) {
1260
+ let resolvedConfig;
1261
+ const getConfig = () => {
1262
+ if (!resolvedConfig) {
1263
+ throw new Error("Riebeckite config has not been loaded yet.");
1264
+ }
1265
+ return resolvedConfig;
1266
+ };
1267
+ return [
1268
+ {
1269
+ name: "riebeckite-host-integration",
1270
+ async config(userConfig) {
1271
+ const root = userConfig.root ? path6.resolve(userConfig.root) : process.cwd();
1272
+ const appRoot = options.appRoot ?? root;
1273
+ const application = await resolveHonoxApplication({
1274
+ configRoot: options.configRoot ?? appRoot,
1275
+ configFile: options.configFile,
1276
+ appRoot,
1277
+ workspaceRoot: options.workspaceRoot
1278
+ });
1279
+ resolvedConfig = application.config;
1280
+ writeRiebeckiteAssetEntries(resolvedConfig, {
1281
+ pluginStyles: path6.join(appRoot, "app/.riebeckite/plugin-styles.css"),
1282
+ themeStyles: path6.join(appRoot, "app/.riebeckite/theme-styles.css")
1283
+ });
1284
+ return {
1285
+ define: {
1286
+ "process.env.RIEBECKITE_APP_ROOT": JSON.stringify(appRoot)
1287
+ },
1288
+ resolve: {
1289
+ alias: options.workspaceRoot ? createWorkspacePackageAliases(options.workspaceRoot) : []
1290
+ }
1291
+ };
1292
+ }
1293
+ },
1294
+ riebeckiteClientModule(getConfig)
1295
+ ];
1296
+ }
1297
+ function riebeckiteVite(options = {}) {
1298
+ const { ssg, ssrExternals, ...integration } = options;
1299
+ return [
1300
+ ...riebeckite(integration),
1301
+ riebeckiteSsrExternals([...defaultSsrExternals, ...ssrExternals ?? []]),
1302
+ createRiebeckiteSsg(ssg)
1303
+ ];
1304
+ }
1305
+ function riebeckiteSsrExternals(externals) {
1306
+ return {
1307
+ name: "riebeckite-ssr-externals",
1308
+ config() {
1309
+ return {
1310
+ environments: {
1311
+ ssr: {
1312
+ resolve: {
1313
+ external: [...externals]
1314
+ }
1315
+ }
1316
+ }
1317
+ };
1318
+ }
1319
+ };
1320
+ }
1321
+
1322
+ // src/scaffold/localized-content.ts
1323
+ var HELPERS = {
1324
+ en: "https://github.com/Rerurate514/riebeckite/blob/main/docs/en/README.md",
1325
+ ja: "https://github.com/Rerurate514/riebeckite/blob/main/docs/ja/README.md"
1326
+ };
1327
+ var PLUGIN_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/plugins";
1328
+ var THEMES_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/themes";
1329
+ function pluginReadmeUrl(slug) {
1330
+ return `https://github.com/Rerurate514/riebeckite/blob/main/packages/plugins/${slug}/README.md`;
1331
+ }
1332
+ function themeReadmeUrl(slug) {
1333
+ return `https://github.com/Rerurate514/riebeckite/blob/main/packages/themes/${slug}/README.md`;
1334
+ }
1335
+ function localizedContentFiles(variables, preset) {
1336
+ const defaultLang = defaultLanguageForLocale(variables.locale);
1337
+ const files = [];
1338
+ const localized = preset.languages.length > 1;
1339
+ const pushLocalized = (basePath, build2) => {
1340
+ if (!localized) {
1341
+ files.push({
1342
+ path: `content/${basePath}.md`,
1343
+ content: build2(defaultLang)
1344
+ });
1345
+ return;
1346
+ }
1347
+ for (const language of SCAFFOLD_LANGUAGES) {
1348
+ const suffix = language === defaultLang ? "" : `.${language}`;
1349
+ files.push({
1350
+ path: `content/${basePath}${suffix}.md`,
1351
+ content: build2(language)
1352
+ });
1353
+ }
1354
+ };
1355
+ const pushEnglishOnly = (basePath, build2) => {
1356
+ const suffix = defaultLang === "en" ? "" : ".en";
1357
+ files.push({
1358
+ path: `content/${basePath}${suffix}.md`,
1359
+ content: build2()
1360
+ });
1361
+ };
1362
+ for (const page of preset.contentPages) {
1363
+ if (page === "index") {
1364
+ pushLocalized("index", (language) => indexContent(variables, language));
1365
+ } else if (page === "framework/plugins") {
1366
+ pushLocalized(
1367
+ "framework/plugins",
1368
+ (language) => pluginsContent(language)
1369
+ );
1370
+ } else if (page === "framework/themes") {
1371
+ pushLocalized("framework/themes", (language) => themesContent(language));
1372
+ } else if (page === "guide") {
1373
+ pushEnglishOnly("guide", guideContent);
1374
+ } else if (page === "examples") {
1375
+ pushLocalized(
1376
+ "examples",
1377
+ (language) => examplesContent(preset, language)
1378
+ );
1379
+ } else if (page === "reference/plugins") {
1380
+ pushEnglishOnly(
1381
+ "reference/plugins",
1382
+ () => referencePluginsContent(preset, variables)
1383
+ );
1384
+ } else if (page === "reference/themes") {
1385
+ pushEnglishOnly("reference/themes", referenceThemesContent);
1386
+ }
1387
+ }
1388
+ return files;
1389
+ }
1390
+ function read(text, language) {
1391
+ return text[language];
1392
+ }
1393
+ function frontmatter() {
1394
+ return ["---", "publish: true", "---", ""].join("\n");
1395
+ }
1396
+ function heading(level, text) {
1397
+ return `${"#".repeat(level)} ${text}`;
1398
+ }
1399
+ function codeBlock(language, code) {
1400
+ return `\`\`\`${language}
1401
+ ${code}
1402
+ \`\`\`
1403
+ `;
1404
+ }
1405
+ var INDEX = {
1406
+ lead: {
1407
+ en: "Welcome to your Riebeckite site.",
1408
+ ja: "あなたの Riebeckite サイトへようこそ。",
1409
+ "zh-CN": "欢迎来到你的 Riebeckite 站点。",
1410
+ es: "Bienvenido a tu sitio Riebeckite.",
1411
+ de: "Willkommen auf deiner Riebeckite-Seite.",
1412
+ fr: "Bienvenue sur votre site Riebeckite.",
1413
+ ko: "Riebeckite 사이트에 오신 것을 환영합니다."
1414
+ },
1415
+ translatedNote: {
1416
+ en: "Every page of this starter is available in seven languages. Switch with the selector below the page title.",
1417
+ ja: "このスターターのすべてのページは 7 言語で利用できます。ページタイトル下のセレクターで切り替えられます。",
1418
+ "zh-CN": "本模板的每个页面均提供七种语言版本,可用页面标题下方的选择器切换。",
1419
+ es: "Cada página de este starter está disponible en siete idiomas. Cámbialos con el selector bajo el título.",
1420
+ de: "Jede Seite dieses Starters ist in sieben Sprachen verfügbar. Wechsel mit dem Auswahlfeld unter dem Seitentitel.",
1421
+ fr: "Chaque page de ce starter est disponible en sept langues. Changez avec le sélecteur sous le titre.",
1422
+ ko: "이 스타터의 모든 페이지는 7개 언어로 제공됩니다. 페이지 제목 아래 선택기로 전환하세요."
1423
+ },
1424
+ whatHeading: {
1425
+ en: "What is Riebeckite?",
1426
+ ja: "Riebeckite とは",
1427
+ "zh-CN": "什么是 Riebeckite?",
1428
+ es: "¿Qué es Riebeckite?",
1429
+ de: "Was ist Riebeckite?",
1430
+ fr: "Qu'est-ce que Riebeckite ?",
1431
+ ko: "Riebeckite란?"
1432
+ },
1433
+ whatBody: {
1434
+ 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.",
1435
+ ja: "Riebeckite は、プレーンな Markdown(Obsidian で管理しているのと同じノート)から高速な静的サイトを生成する、拡張性のあるコンテンツファーストのフレームワークです。エコシステムには 50 以上のプラグインと 6 つのテーマがあり、このサイトはその両方をデモしています。",
1436
+ "zh-CN": "Riebeckite 是一个可扩展、内容优先的框架,可从纯 Markdown(即你在 Obsidian 中保存的笔记)构建快速的静态站点。生态包含 50+ 插件与六个主题,本站点同时演示两者。",
1437
+ 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.",
1438
+ 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.",
1439
+ 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.",
1440
+ ko: "Riebeckite는 일반 Markdown(Obsidian에서 관리하는 노트)에서 빠른 정적 사이트를 만드는 확장 가능한 콘텐츠 우선 프레임워크입니다. 생태계에는 50개 이상의 플러그인과 6개 테마가 있으며, 이 사이트가 그 두 가지를 보여줍니다."
1441
+ },
1442
+ exploreHeading: {
1443
+ en: "Explore",
1444
+ ja: "さらに深く",
1445
+ "zh-CN": "继续探索",
1446
+ es: "Explorar",
1447
+ de: "Weiter erkunden",
1448
+ fr: "Explorer",
1449
+ ko: "더 살펴보기"
1450
+ },
1451
+ explorePlugins: {
1452
+ en: "Plugins — representative packages grouped by capability",
1453
+ ja: "プラグイン — 機能別の代表的なパッケージ",
1454
+ "zh-CN": "插件 — 按能力分组的代表性包",
1455
+ es: "Plugins — paquetes representativos por capacidad",
1456
+ de: "Plugins — repräsentative Pakete nach Fähigkeit",
1457
+ fr: "Plugins — paquets représentatifs par capacité",
1458
+ ko: "플러그인 — 기능별 대표 패키지"
1459
+ },
1460
+ exploreThemes: {
1461
+ en: "Themes — built-in design packages and how to switch",
1462
+ ja: "テーマ — 同梱のデザインパッケージと切り替え方",
1463
+ "zh-CN": "主题 — 内置设计包与切换方法",
1464
+ es: "Temas — paquetes de diseño incluidos y cómo cambiar",
1465
+ de: "Themes — mitgelieferte Design-Pakete und wie man wechselt",
1466
+ fr: "Thèmes — paquets de design inclus et comment changer",
1467
+ ko: "테마 — 내장 디자인 패키지와 전환 방법"
1468
+ },
1469
+ editHeading: {
1470
+ en: "Edit this site",
1471
+ ja: "サイトの編集",
1472
+ "zh-CN": "编辑本站点",
1473
+ es: "Editar este sitio",
1474
+ de: "Diese Seite bearbeiten",
1475
+ fr: "Éditer ce site",
1476
+ ko: "사이트 편집"
1477
+ },
1478
+ editLead: {
1479
+ 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.",
1480
+ ja: "コンテンツは `content/` にプレーンな Markdown として置きます。ファイルを追加してフロントマターに `publish: true` を書けば、ビルドされたサイトに反映されます。",
1481
+ "zh-CN": "内容以纯 Markdown 存于 `content/`。新建文件并在 frontmatter 中写入 `publish: true`,它就会出现在构建后的站点中。",
1482
+ 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.",
1483
+ 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.",
1484
+ 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.",
1485
+ ko: "콘텐츠는 `content/`에 일반 Markdown으로 저장됩니다. 파일을 추가하고 프론트매터에 `publish: true`를 쓰면 빌드된 사이트에 나타납니다."
1486
+ },
1487
+ editL10n: {
1488
+ 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.",
1489
+ ja: "翻訳ページは既定ファイルの隣に `<base>.<lang>.md` の命名規則で置きます(例:`about.ja.md`)。l10n プラグインが `/lang/` パスの配下で配信し、自動的にリンクします。",
1490
+ "zh-CN": "本地化页面采用默认文件旁的 `<base>.<lang>.md` 命名约定(例如 `about.ja.md`)。l10n 插件会在 `/lang/` 路径下提供服务并自动互链。",
1491
+ 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.",
1492
+ 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.",
1493
+ 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.",
1494
+ ko: "번역 페이지는 기본 파일 옆에 `<base>.<lang>.md` 규칙으로 둡니다(예: `about.ja.md`). l10n 플러그인이 `/lang/` 경로로 서빙하며 자동으로 링크합니다."
1495
+ }
1496
+ };
1497
+ function indexContent(variables, language) {
1498
+ const title = variables.title;
1499
+ return [
1500
+ frontmatter(),
1501
+ heading(1, title),
1502
+ read(INDEX.lead, language),
1503
+ read(INDEX.translatedNote, language),
1504
+ heading(2, read(INDEX.whatHeading, language)),
1505
+ read(INDEX.whatBody, language),
1506
+ heading(2, read(INDEX.exploreHeading, language)),
1507
+ `- [${read(INDEX.explorePlugins, language)}](/framework/plugins)`,
1508
+ `- [${read(INDEX.exploreThemes, language)}](/framework/themes)`,
1509
+ heading(2, read(INDEX.editHeading, language)),
425
1510
  read(INDEX.editLead, language),
426
1511
  read(INDEX.editL10n, language),
427
1512
  ""
@@ -607,7 +1692,7 @@ function themesContent(language) {
607
1692
  lines.push(heading(2, read(copy.switchHeading, language)), "");
608
1693
  lines.push(read(copy.switchCurrent, language), "");
609
1694
  lines.push(read(copy.switchStep1, language), "");
610
- lines.push(codeBlock("sh", "pnpm add @riebeckite/theme-sakura"));
1695
+ lines.push(codeBlock("sh", "npm install @riebeckite/theme-sakura"));
611
1696
  lines.push(read(copy.switchStep2, language), "");
612
1697
  lines.push(
613
1698
  codeBlock(
@@ -848,6 +1933,18 @@ var PLUGIN_CATEGORIES = [
848
1933
  fr: "Rend les croquis Excalidraw.",
849
1934
  ko: "Excalidraw 스케치 파일 렌더링."
850
1935
  }
1936
+ },
1937
+ {
1938
+ slug: "gallery",
1939
+ desc: {
1940
+ en: "Card grids for theme or project showcases.",
1941
+ ja: "テーマやプロジェクトの紹介向けカードグリッド。",
1942
+ "zh-CN": "用于主题或项目展示的卡片网格。",
1943
+ es: "Cuadrículas de tarjetas para escaparates de temas o proyectos.",
1944
+ de: "Kartenraster für Theme- oder Projekt-Showcases.",
1945
+ fr: "Grilles de cartes pour vitrines de thèmes ou de projets.",
1946
+ ko: "테마·프로젝트 소개용 카드 그리드."
1947
+ }
851
1948
  }
852
1949
  ]
853
1950
  },
@@ -908,726 +2005,483 @@ var PLUGIN_CATEGORIES = [
908
2005
  }
909
2006
  },
910
2007
  {
911
- slug: "backlinks",
912
- desc: {
913
- en: "Lists notes that link to the current one.",
914
- ja: "現在のノートを参照するノートを一覧表示。",
915
- "zh-CN": "列出链接到当前笔记的笔记。",
916
- es: "Lista las notas que enlazan con la actual.",
917
- de: "Listet Notizen, die auf die aktuelle verlinken.",
918
- fr: "Liste les notes qui pointent vers la note courante.",
919
- ko: "현재 노트를 링크한 노트 목록."
920
- }
921
- }
922
- ]
923
- },
924
- {
925
- title: {
926
- en: "Search and navigation",
927
- ja: "検索とナビゲーション",
928
- "zh-CN": "搜索与导航",
929
- es: "Búsqueda y navegación",
930
- de: "Suche und Navigation",
931
- fr: "Recherche et navigation",
932
- ko: "검색과 탐색"
933
- },
934
- summary: {
935
- en: "Find and move through your notes quickly.",
936
- ja: "ノートをすばやく探して移動する。",
937
- "zh-CN": "快速查找并在笔记之间穿梭。",
938
- es: "Encuentra y recorre tus notas rápidamente.",
939
- de: "Notizen schnell finden und durch sie navigieren.",
940
- fr: "Retrouvez et parcourez vos notes rapidement.",
941
- ko: "노트를 빠르게 찾고 이동하기."
942
- },
943
- plugins: [
944
- {
945
- slug: "search",
946
- desc: {
947
- en: "Client-side full-text search with a Ctrl+K modal.",
948
- ja: "Ctrl+K モーダル付きのクライアント側全文検索。",
949
- "zh-CN": "带 Ctrl+K 弹窗的客户端全文搜索。",
950
- es: "Búsqueda de texto completo en el cliente con modal Ctrl+K.",
951
- de: "Clientseitige Volltextsuche mit Ctrl+K-Modal.",
952
- fr: "Recherche plein texte côté client avec modal Ctrl+K.",
953
- ko: "Ctrl+K 모달이 있는 클라이언트 전체 텍스트 검색."
954
- }
955
- },
956
- {
957
- slug: "garden-explorer",
958
- desc: {
959
- en: "An interactive graph and search explorer.",
960
- ja: "ノートのグラフと検索を探索するインタラクティブビュー。",
961
- "zh-CN": "交互式图谱与搜索探索器。",
962
- es: "Un explorador interactivo de grafo y búsqueda.",
963
- de: "Ein interaktiver Graph- und Such-Explorer.",
964
- fr: "Un explorateur interactif de graphe et de recherche.",
965
- ko: "노트 그래프와 검색을 탐색하는 대화형 뷰."
966
- }
967
- },
968
- {
969
- slug: "local-graph",
970
- desc: {
971
- en: "A link graph around the current note.",
972
- ja: "ノート周辺のリンクグラフ。",
973
- "zh-CN": "当前笔记周边的链接图谱。",
974
- es: "Un grafo de enlaces alrededor de la nota actual.",
975
- de: "Ein Link-Graph rund um die aktuelle Notiz.",
976
- fr: "Un graphe de liens autour de la note courante.",
977
- ko: "현재 노트 주변의 링크 그래프."
978
- }
979
- },
980
- {
981
- slug: "permalink",
982
- desc: {
983
- en: "Stable, configurable permalinks.",
984
- ja: "安定したカスタマイズ可能なパーマリンク。",
985
- "zh-CN": "稳定、可配置的永久链接。",
986
- es: "Permalinks estables y configurables.",
987
- de: "Stabile, konfigurierbare Permalinks.",
988
- fr: "Permaliens stables et configurables.",
989
- ko: "안정적이고 설정 가능한 고유 주소."
990
- }
991
- }
992
- ]
993
- },
994
- {
995
- title: {
996
- en: "Publishing and SEO",
997
- ja: "公開と SEO",
998
- "zh-CN": "发布与 SEO",
999
- es: "Publicación y SEO",
1000
- de: "Veröffentlichung und SEO",
1001
- fr: "Publication et SEO",
1002
- ko: "배포와 SEO"
1003
- },
1004
- summary: {
1005
- en: "Ship a site that search engines and readers both understand.",
1006
- ja: "検索エンジンにも読者にも伝わるサイトを公開する。",
1007
- "zh-CN": "发布搜索引擎和读者都能理解的站点。",
1008
- es: "Publica un sitio que buscan buscadores y lectores por igual.",
1009
- de: "Veröffentliche eine Seite, die Suchmaschinen und Leser gleichermaßen verstehen.",
1010
- fr: "Publiez un site que moteurs de recherche et lecteurs comprennent.",
1011
- ko: "검색 엔진과 독자 모두가 이해하는 사이트를 배포."
1012
- },
1013
- plugins: [
1014
- {
1015
- slug: "seo",
1016
- desc: {
1017
- en: "SEO metadata, sitemaps, RSS/Atom/JSON feeds, and robots.txt.",
1018
- ja: "SEO メタデータ・サイトマップ・RSS/Atom/JSON フィード・robots.txt。",
1019
- "zh-CN": "SEO 元数据、站点地图、RSS/Atom/JSON 订阅与 robots.txt。",
1020
- es: "Metadatos SEO, sitemaps, feeds RSS/Atom/JSON y robots.txt.",
1021
- de: "SEO-Metadaten, Sitemaps, RSS/Atom/JSON-Feeds und robots.txt.",
1022
- fr: "Métadonnées SEO, sitemaps, flux RSS/Atom/JSON et robots.txt.",
1023
- ko: "SEO 메타데이터·사이트맵·RSS/Atom/JSON 피드·robots.txt."
1024
- }
1025
- },
1026
- {
1027
- slug: "l10n",
1028
- desc: {
1029
- en: "Localized URLs, a language switcher, and hreflang metadata — this site runs on it.",
1030
- ja: "ローカライズ済み URL・言語スイッチャー・hreflang メタデータ——このサイトもこれで動いています。",
1031
- "zh-CN": "本地化 URL、语言切换器与 hreflang 元数据——本站就运行在它之上。",
1032
- es: "URLs localizadas, selector de idioma y metadatos hreflang — este sitio se ejecuta sobre él.",
1033
- de: "Lokalisierte URLs, Sprachumschalter und hreflang-Metadaten — diese Seite läuft darauf.",
1034
- fr: "URLs localisées, sélecteur de langue et métadonnées hreflang — ce site repose dessus.",
1035
- ko: "로컬라이즈된 URL·언어 전환 UI·hreflang 메타데이터 — 이 사이트가 동작하는 기반입니다."
1036
- }
1037
- },
1038
- {
1039
- slug: "rich-embed",
1040
- desc: {
1041
- en: "Build-time rich media cards for external links.",
1042
- ja: "外部リンクのビルド時リッチメディアカード。",
1043
- "zh-CN": "外部链接的构建时富媒体卡片。",
1044
- es: "Tarjetas multimedia en build para enlaces externos.",
1045
- de: "Rich-Media-Karten für externe Links zur Build-Zeit.",
1046
- fr: "Cartes média construites à la compilation pour les liens externes.",
1047
- ko: "외부 링크의 빌드 시점 리치 미디어 카드."
1048
- }
1049
- },
1050
- {
1051
- slug: "deploy",
1052
- desc: {
1053
- en: "Static deployment output for hosting services.",
1054
- ja: "ホスティングサービス向けの静的デプロイ出力。",
1055
- "zh-CN": "面向托管服务的静态部署产物。",
1056
- es: "Salida de despliegue estático para servicios de hosting.",
1057
- de: "Statische Deployment-Ausgabe für Hosting-Dienste.",
1058
- fr: "Sortie de déploiement statique pour les services d'hébergement.",
1059
- ko: "호스팅 서비스용 정적 배포 산출물."
2008
+ slug: "backlinks",
2009
+ desc: {
2010
+ en: "Lists notes that link to the current one.",
2011
+ ja: "現在のノートを参照するノートを一覧表示。",
2012
+ "zh-CN": "列出链接到当前笔记的笔记。",
2013
+ es: "Lista las notas que enlazan con la actual.",
2014
+ de: "Listet Notizen, die auf die aktuelle verlinken.",
2015
+ fr: "Liste les notes qui pointent vers la note courante.",
2016
+ ko: "현재 노트를 링크한 노트 목록."
1060
2017
  }
1061
2018
  }
1062
2019
  ]
1063
2020
  },
1064
2021
  {
1065
2022
  title: {
1066
- en: "Content and developer experience",
1067
- ja: "コンテンツと開発体験",
1068
- "zh-CN": "内容与开发者体验",
1069
- es: "Contenido y experiencia de desarrollo",
1070
- de: "Content und Developer Experience",
1071
- fr: "Contenu et expérience développeur",
1072
- ko: "콘텐츠와 개발자 경험"
2023
+ en: "Search and navigation",
2024
+ ja: "検索とナビゲーション",
2025
+ "zh-CN": "搜索与导航",
2026
+ es: "Búsqueda y navegación",
2027
+ de: "Suche und Navigation",
2028
+ fr: "Recherche et navigation",
2029
+ ko: "검색과 탐색"
1073
2030
  },
1074
2031
  summary: {
1075
- en: "Query, organize, and keep your content healthy.",
1076
- ja: "コンテンツを検索・整理し、健全に保つ。",
1077
- "zh-CN": "查询、整理并保持内容健康。",
1078
- es: "Consulta, organiza y mantén sano tu contenido.",
1079
- de: "Content abfragen, organisieren und gesund halten.",
1080
- fr: "Requêter, organiser et garder votre contenu sain.",
1081
- ko: "콘텐츠를 조회·정리하고 건강하게 유지."
2032
+ en: "Find and move through your notes quickly.",
2033
+ ja: "ノートをすばやく探して移動する。",
2034
+ "zh-CN": "快速查找并在笔记之间穿梭。",
2035
+ es: "Encuentra y recorre tus notas rápidamente.",
2036
+ de: "Notizen schnell finden und durch sie navigieren.",
2037
+ fr: "Retrouvez et parcourez vos notes rapidement.",
2038
+ ko: "노트를 빠르게 찾고 이동하기."
1082
2039
  },
1083
2040
  plugins: [
1084
2041
  {
1085
- slug: "dataview",
2042
+ slug: "search",
1086
2043
  desc: {
1087
- en: "Build-time queries over your notes.",
1088
- ja: "ノートに対するビルド時クエリ。",
1089
- "zh-CN": "对笔记的构建时查询。",
1090
- es: "Consultas en build sobre tus notas.",
1091
- de: "Build-Zeit-Abfragen über deine Notizen.",
1092
- fr: "Requêtes temps de build sur vos notes.",
1093
- ko: "노트에 대한 빌드 시점 조회."
2044
+ en: "Client-side full-text search with a Ctrl+K modal.",
2045
+ ja: "Ctrl+K モーダル付きのクライアント側全文検索。",
2046
+ "zh-CN": "带 Ctrl+K 弹窗的客户端全文搜索。",
2047
+ es: "Búsqueda de texto completo en el cliente con modal Ctrl+K.",
2048
+ de: "Clientseitige Volltextsuche mit Ctrl+K-Modal.",
2049
+ fr: "Recherche plein texte côté client avec modal Ctrl+K.",
2050
+ ko: "Ctrl+K 모달이 있는 클라이언트 전체 텍스트 검색."
1094
2051
  }
1095
2052
  },
1096
2053
  {
1097
- slug: "kanban",
2054
+ slug: "garden-explorer",
1098
2055
  desc: {
1099
- en: "Obsidian-style Kanban boards from Markdown lists.",
1100
- ja: "Markdown リストから Obsidian スタイルのカンバンボードを作成。",
1101
- "zh-CN": "从 Markdown 列表创建 Obsidian 风格看板。",
1102
- es: "Tableros Kanban estilo Obsidian desde listas Markdown.",
1103
- de: "Obsidian-ähnliche Kanban-Boards aus Markdown-Listen.",
1104
- fr: "Tableaux Kanban façon Obsidian depuis des listes Markdown.",
1105
- ko: "Markdown 목록에서 Obsidian 스타일 칸반 보드 생성."
2056
+ en: "An interactive graph and search explorer.",
2057
+ ja: "ノートのグラフと検索を探索するインタラクティブビュー。",
2058
+ "zh-CN": "交互式图谱与搜索探索器。",
2059
+ es: "Un explorador interactivo de grafo y búsqueda.",
2060
+ de: "Ein interaktiver Graph- und Such-Explorer.",
2061
+ fr: "Un explorateur interactif de graphe et de recherche.",
2062
+ ko: "노트 그래프와 검색을 탐색하는 대화형 뷰."
1106
2063
  }
1107
2064
  },
1108
2065
  {
1109
- slug: "responsive-image",
2066
+ slug: "local-graph",
1110
2067
  desc: {
1111
- en: "Responsive images with lazy loading.",
1112
- ja: "レスポンシブ画像と遅延読み込み。",
1113
- "zh-CN": "响应式图片与懒加载。",
1114
- es: "Imágenes responsive con carga diferida.",
1115
- de: "Responsive Bilder mit Lazy Loading.",
1116
- fr: "Images responsives avec chargement différé.",
1117
- ko: "지연 로딩 지원 반응형 이미지."
2068
+ en: "A link graph around the current note.",
2069
+ ja: "ノート周辺のリンクグラフ。",
2070
+ "zh-CN": "当前笔记周边的链接图谱。",
2071
+ es: "Un grafo de enlaces alrededor de la nota actual.",
2072
+ de: "Ein Link-Graph rund um die aktuelle Notiz.",
2073
+ fr: "Un graphe de liens autour de la note courante.",
2074
+ ko: "현재 노트 주변의 링크 그래프."
1118
2075
  }
1119
2076
  },
1120
2077
  {
1121
- slug: "quality",
2078
+ slug: "permalink",
1122
2079
  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
- }
2080
+ en: "Stable, configurable permalinks.",
2081
+ ja: "安定したカスタマイズ可能なパーマリンク。",
2082
+ "zh-CN": "稳定、可配置的永久链接。",
2083
+ es: "Permalinks estables y configurables.",
2084
+ de: "Stabile, konfigurierbare Permalinks.",
2085
+ fr: "Permaliens stables et configurables.",
2086
+ ko: "안정적이고 설정 가능한 고유 주소."
1288
2087
  }
1289
- };
2088
+ }
2089
+ ]
2090
+ },
2091
+ {
2092
+ title: {
2093
+ en: "Publishing and SEO",
2094
+ ja: "公開と SEO",
2095
+ "zh-CN": "发布与 SEO",
2096
+ es: "Publicación y SEO",
2097
+ de: "Veröffentlichung und SEO",
2098
+ fr: "Publication et SEO",
2099
+ ko: "배포와 SEO"
1290
2100
  },
1291
- configResolved(config) {
1292
- resolvedConfig = config;
2101
+ summary: {
2102
+ en: "Ship a site that search engines and readers both understand.",
2103
+ ja: "検索エンジンにも読者にも伝わるサイトを公開する。",
2104
+ "zh-CN": "发布搜索引擎和读者都能理解的站点。",
2105
+ es: "Publica un sitio que buscan buscadores y lectores por igual.",
2106
+ de: "Veröffentliche eine Seite, die Suchmaschinen und Leser gleichermaßen verstehen.",
2107
+ fr: "Publiez un site que moteurs de recherche et lecteurs comprennent.",
2108
+ ko: "검색 엔진과 독자 모두가 이해하는 사이트를 배포."
1293
2109
  },
1294
- resolveId(id) {
1295
- return id === virtualId ? resolvedVirtualId : void 0;
2110
+ plugins: [
2111
+ {
2112
+ slug: "seo",
2113
+ desc: {
2114
+ en: "SEO metadata, sitemaps, RSS/Atom/JSON feeds, and robots.txt.",
2115
+ ja: "SEO メタデータ・サイトマップ・RSS/Atom/JSON フィード・robots.txt。",
2116
+ "zh-CN": "SEO 元数据、站点地图、RSS/Atom/JSON 订阅与 robots.txt。",
2117
+ es: "Metadatos SEO, sitemaps, feeds RSS/Atom/JSON y robots.txt.",
2118
+ de: "SEO-Metadaten, Sitemaps, RSS/Atom/JSON-Feeds und robots.txt.",
2119
+ fr: "Métadonnées SEO, sitemaps, flux RSS/Atom/JSON et robots.txt.",
2120
+ ko: "SEO 메타데이터·사이트맵·RSS/Atom/JSON 피드·robots.txt."
2121
+ }
2122
+ },
2123
+ {
2124
+ slug: "l10n",
2125
+ desc: {
2126
+ en: "Localized URLs, a language switcher, and hreflang metadata — this site runs on it.",
2127
+ ja: "ローカライズ済み URL・言語スイッチャー・hreflang メタデータ——このサイトもこれで動いています。",
2128
+ "zh-CN": "本地化 URL、语言切换器与 hreflang 元数据——本站就运行在它之上。",
2129
+ es: "URLs localizadas, selector de idioma y metadatos hreflang — este sitio se ejecuta sobre él.",
2130
+ de: "Lokalisierte URLs, Sprachumschalter und hreflang-Metadaten — diese Seite läuft darauf.",
2131
+ fr: "URLs localisées, sélecteur de langue et métadonnées hreflang — ce site repose dessus.",
2132
+ ko: "로컬라이즈된 URL·언어 전환 UI·hreflang 메타데이터 — 이 사이트가 동작하는 기반입니다."
2133
+ }
2134
+ },
2135
+ {
2136
+ slug: "rich-embed",
2137
+ desc: {
2138
+ en: "Build-time rich media cards for external links.",
2139
+ ja: "外部リンクのビルド時リッチメディアカード。",
2140
+ "zh-CN": "外部链接的构建时富媒体卡片。",
2141
+ es: "Tarjetas multimedia en build para enlaces externos.",
2142
+ de: "Rich-Media-Karten für externe Links zur Build-Zeit.",
2143
+ fr: "Cartes média construites à la compilation pour les liens externes.",
2144
+ ko: "외부 링크의 빌드 시점 리치 미디어 카드."
2145
+ }
2146
+ },
2147
+ {
2148
+ slug: "deploy",
2149
+ desc: {
2150
+ en: "Static deployment output for hosting services.",
2151
+ ja: "ホスティングサービス向けの静的デプロイ出力。",
2152
+ "zh-CN": "面向托管服务的静态部署产物。",
2153
+ es: "Salida de despliegue estático para servicios de hosting.",
2154
+ de: "Statische Deployment-Ausgabe für Hosting-Dienste.",
2155
+ fr: "Sortie de déploiement statique pour les services d'hébergement.",
2156
+ ko: "호스팅 서비스용 정적 배포 산출물."
2157
+ }
2158
+ }
2159
+ ]
2160
+ },
2161
+ {
2162
+ title: {
2163
+ en: "Content and developer experience",
2164
+ ja: "コンテンツと開発体験",
2165
+ "zh-CN": "内容与开发者体验",
2166
+ es: "Contenido y experiencia de desarrollo",
2167
+ de: "Content und Developer Experience",
2168
+ fr: "Contenu et expérience développeur",
2169
+ ko: "콘텐츠와 개발자 경험"
1296
2170
  },
1297
- load(id) {
1298
- return id === resolvedVirtualId ? 'console.log("suppress empty chunk message")' : void 0;
2171
+ summary: {
2172
+ en: "Query, organize, and keep your content healthy.",
2173
+ ja: "コンテンツを検索・整理し、健全に保つ。",
2174
+ "zh-CN": "查询、整理并保持内容健康。",
2175
+ es: "Consulta, organiza y mantén sano tu contenido.",
2176
+ de: "Content abfragen, organisieren und gesund halten.",
2177
+ fr: "Requêter, organiser et garder votre contenu sain.",
2178
+ ko: "콘텐츠를 조회·정리하고 건강하게 유지."
1299
2179
  },
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}.`);
2180
+ plugins: [
2181
+ {
2182
+ slug: "dataview",
2183
+ desc: {
2184
+ en: "Build-time queries over your notes.",
2185
+ ja: "ノートに対するビルド時クエリ。",
2186
+ "zh-CN": "对笔记的构建时查询。",
2187
+ es: "Consultas en build sobre tus notas.",
2188
+ de: "Build-Zeit-Abfragen über deine Notizen.",
2189
+ fr: "Requêtes temps de build sur vos notes.",
2190
+ ko: "노트에 대한 빌드 시점 조회."
1322
2191
  }
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
- }
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
- }
1396
- }
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"
2192
+ },
2193
+ {
2194
+ slug: "kanban",
2195
+ desc: {
2196
+ en: "Obsidian-style Kanban boards from Markdown lists.",
2197
+ ja: "Markdown リストから Obsidian スタイルのカンバンボードを作成。",
2198
+ "zh-CN": "从 Markdown 列表创建 Obsidian 风格看板。",
2199
+ es: "Tableros Kanban estilo Obsidian desde listas Markdown.",
2200
+ de: "Obsidian-ähnliche Kanban-Boards aus Markdown-Listen.",
2201
+ fr: "Tableaux Kanban façon Obsidian depuis des listes Markdown.",
2202
+ ko: "Markdown 목록에서 Obsidian 스타일 칸반 보드 생성."
2203
+ }
2204
+ },
2205
+ {
2206
+ slug: "responsive-image",
2207
+ desc: {
2208
+ en: "Responsive images with lazy loading.",
2209
+ ja: "レスポンシブ画像と遅延読み込み。",
2210
+ "zh-CN": "响应式图片与懒加载。",
2211
+ es: "Imágenes responsive con carga diferida.",
2212
+ de: "Responsive Bilder mit Lazy Loading.",
2213
+ fr: "Images responsives avec chargement différé.",
2214
+ ko: "지연 로딩 지원 반응형 이미지."
2215
+ }
2216
+ },
2217
+ {
2218
+ slug: "quality",
2219
+ desc: {
2220
+ en: "Static quality and accessibility checks.",
2221
+ ja: "静的品質・アクセシビリティ検査。",
2222
+ "zh-CN": "静态质量与可访问性检查。",
2223
+ es: "Inspección estática de calidad y accesibilidad.",
2224
+ de: "Statische Qualitäts- und Barrierefreiheitsprüfung.",
2225
+ fr: "Contrôle statique de qualité et d'accessibilité.",
2226
+ ko: "정적 품질·접근성 검사."
2227
+ }
2228
+ }
2229
+ ]
2230
+ }
1431
2231
  ];
1432
- async function resolveHonoxApplicationRoot(configRoot) {
1433
- const roots = await findViteApplicationRoots(configRoot);
1434
- if (roots.length === 1) return roots[0];
1435
- if (roots.length === 0) {
1436
- throw new HonoxApplicationRootError(
1437
- `Could not find a Vite application under ${configRoot}.`
2232
+ function pluginsContent(language) {
2233
+ const copy = PLUGINS_COPY;
2234
+ const categories = PLUGIN_CATEGORIES;
2235
+ const lines = [frontmatter()];
2236
+ lines.push(heading(1, read(copy.title, language)), "");
2237
+ lines.push(read(copy.intro, language), "");
2238
+ lines.push(heading(2, read(copy.installHeading, language)), "");
2239
+ lines.push(read(copy.installStep1, language), "");
2240
+ lines.push(codeBlock("sh", "npm install @riebeckite/plugin-mermaid"));
2241
+ lines.push(read(copy.installStep2, language), "");
2242
+ lines.push(
2243
+ codeBlock(
2244
+ "ts",
2245
+ [
2246
+ 'import { defineConfig } from "@riebeckite/core";',
2247
+ 'import { l10n } from "@riebeckite/plugin-l10n";',
2248
+ 'import { mermaid } from "@riebeckite/plugin-mermaid";',
2249
+ 'import { obsidianMarkdown } from "@riebeckite/plugin-obsidian-markdown";',
2250
+ "",
2251
+ "export default defineConfig({",
2252
+ " // ...",
2253
+ " plugins: [obsidianMarkdown(), l10n({ ... }), mermaid()],",
2254
+ "});"
2255
+ ].join("\n")
2256
+ )
2257
+ );
2258
+ lines.push(read(copy.fullList, language), "");
2259
+ lines.push(
2260
+ `[${read(copy.fullListLabel, language)}](${PLUGIN_INDEX_URL})`,
2261
+ ""
2262
+ );
2263
+ for (const category of categories) {
2264
+ lines.push(heading(2, read(category.title, language)), "");
2265
+ lines.push(read(category.summary, language), "");
2266
+ lines.push(
2267
+ `| ${read(copy.columnPlugin, language)} | ${read(copy.columnDescription, language)} |`
1438
2268
  );
2269
+ lines.push("| --- | --- |");
2270
+ for (const plugin of category.plugins) {
2271
+ const packageName = `@riebeckite/plugin-${plugin.slug}`;
2272
+ lines.push(
2273
+ `| [\`${packageName}\`](${pluginReadmeUrl(plugin.slug)}) | ${read(plugin.desc, language)} |`
2274
+ );
2275
+ }
2276
+ lines.push("");
1439
2277
  }
1440
- throw new HonoxApplicationRootError(
1441
- `Found multiple Vite applications under ${configRoot}: ${roots.join(", ")}.`
2278
+ lines.push("");
2279
+ lines.push(
2280
+ `Riebeckite: [documentation](${HELPERS.en}) · [日本語ドキュメント](${HELPERS.ja})`,
2281
+ ""
1442
2282
  );
2283
+ lines.push("");
2284
+ return lines.join("\n");
1443
2285
  }
1444
- var HonoxApplicationRootError = class extends Error {
1445
- constructor(message) {
1446
- super(message);
1447
- this.name = "HonoxApplicationRootError";
2286
+ function guideContent() {
2287
+ return [
2288
+ frontmatter(),
2289
+ heading(1, "Getting started"),
2290
+ "",
2291
+ "This site was generated from a Riebeckite scaffold preset. Everything",
2292
+ "you see lives in this repository, ready to edit.",
2293
+ "",
2294
+ heading(2, "Add a page"),
2295
+ "",
2296
+ "Drop a Markdown file into `content/` with `publish: true` in its",
2297
+ "frontmatter and it appears in the built site:",
2298
+ "",
2299
+ codeBlock(
2300
+ "md",
2301
+ ["---", "publish: true", "---", "", "# Hello", "", "Body text..."].join(
2302
+ "\n"
2303
+ )
2304
+ ),
2305
+ "",
2306
+ heading(2, "Run the site"),
2307
+ "",
2308
+ codeBlock("sh", ["npm install", "npm run dev", "npm run build"].join("\n")),
2309
+ "",
2310
+ heading(2, "Localize a page"),
2311
+ "",
2312
+ "Add a translated file next to the default one using the",
2313
+ "`<base>.<lang>.md` convention (`about.ja.md`, `about.en.md`). With the",
2314
+ "l10n plugin enabled, translations are served under `/lang/` paths and",
2315
+ "linked by the language switcher.",
2316
+ "",
2317
+ heading(2, "Extend"),
2318
+ "",
2319
+ "Plugins and themes are registered in `riebeckite.config.ts`. Install a",
2320
+ "package, import its factory, and add it to the `plugins` array or point",
2321
+ "`theme` at a new theme factory.",
2322
+ ""
2323
+ ].join("\n");
2324
+ }
2325
+ function readSummary(text, language) {
2326
+ return language === "ja" ? text.ja ?? text.en : text.en;
2327
+ }
2328
+ var EXAMPLES_COPY = {
2329
+ heading: {
2330
+ en: "Examples",
2331
+ ja: "サンプル集"
2332
+ },
2333
+ intro: {
2334
+ en: "A working demo of every diagram, chart, and code feature this preset ships. Fenced code blocks are turned into rendered output at build time by the diagram plugins; code blocks gain toolbars from the code plugins. Each section below is also copy-pasteable into any Markdown document.",
2335
+ ja: "このプリセットが含む、すべての図表・チャート・コード機能の実例です。フェンス付きコードブロックはビルド時に図表プラグインが描画し、コードブロックにはコードプラグインがツールバーを追加します。以下の各セクションは、任意の Markdown 文書にそのままコピーして使えます。"
1448
2336
  }
1449
2337
  };
1450
- async function resolveHonoxApplication(options) {
1451
- const configRoot = path5.resolve(options.configRoot);
1452
- const appRoot = options.appRoot ? path5.resolve(options.appRoot) : await resolveHonoxApplicationRoot(configRoot);
1453
- const workspaceRoot = options.workspaceRoot ?? await findWorkspaceRoot(configRoot);
1454
- const rawConfig = await loadRiebeckiteConfig({
1455
- configRoot,
1456
- configFile: options.configFile,
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;
2338
+ function examplesContent(preset, language) {
2339
+ const lines = [
2340
+ frontmatter(),
2341
+ heading(1, readSummary(EXAMPLES_COPY.heading, language)),
2342
+ "",
2343
+ readSummary(EXAMPLES_COPY.intro, language),
2344
+ ""
2345
+ ];
2346
+ for (const key of README_DEMO_ORDER) {
2347
+ const packageName = demoPackage(key);
2348
+ if (!hasPlugin(preset, packageName)) continue;
2349
+ const demo = README_DEMOS[key];
2350
+ lines.push(heading(2, readSummary(demo.title, language)), "");
2351
+ lines.push(readSummary(demo.intro, language), "");
2352
+ lines.push(demo.markdown, "");
1473
2353
  }
2354
+ return lines.join("\n");
1474
2355
  }
1475
- async function startHonoxDevServer(options) {
1476
- const server2 = await createServer2({ root: options.root });
1477
- await server2.listen();
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 })
2356
+ function referencePluginsContent(preset, variables) {
2357
+ const lines = [frontmatter()];
2358
+ lines.push(heading(1, "Plugin reference"), "");
2359
+ lines.push(
2360
+ "Every plugin registered by this preset, with the factory and options",
2361
+ "used in `riebeckite.config.ts`. Full documentation lives in each package",
2362
+ "README.",
2363
+ ""
1491
2364
  );
1492
- }
1493
- async function runTraced(tracer, name, buildTask) {
1494
- return tracer ? await tracer.span(name, {}, buildTask) : await buildTask();
1495
- }
1496
- async function waitForShutdown(server2) {
1497
- await new Promise((resolve) => {
1498
- const close = () => {
1499
- void server2.close().finally(resolve);
1500
- };
1501
- process.once("SIGINT", close);
1502
- process.once("SIGTERM", close);
1503
- });
1504
- }
1505
- async function findViteApplicationRoots(root) {
1506
- const directories = [root];
1507
- const applicationRoots = [];
1508
- while (directories.length > 0) {
1509
- const directory = directories.pop();
1510
- if (!directory) continue;
1511
- if (await hasViteConfig(directory)) applicationRoots.push(directory);
1512
- const entries = await fs5.readdir(directory, { withFileTypes: true });
1513
- for (const entry of entries) {
1514
- if (!entry.isDirectory() || entry.name === "node_modules" || entry.name === ".git" || entry.name === "tests") {
1515
- continue;
1516
- }
1517
- directories.push(path5.join(directory, entry.name));
1518
- }
1519
- }
1520
- return applicationRoots;
1521
- }
1522
- async function hasViteConfig(directory) {
1523
- for (const fileName of viteConfigFileNames) {
1524
- try {
1525
- if ((await fs5.stat(path5.join(directory, fileName))).isFile()) return true;
1526
- } catch {
1527
- }
2365
+ lines.push("| Package | Factory | Options |");
2366
+ lines.push("| --- | --- | --- |");
2367
+ for (const plugin of preset.plugins) {
2368
+ const options = readmePluginOptions(variables, preset, plugin);
2369
+ const cell = options === null ? "—" : `\`${options}\``;
2370
+ lines.push(
2371
+ `| [\`${plugin.package}\`](${pluginReadmeUrl(plugin.package.replace(/^@riebeckite\/plugin-/, ""))}) | \`${plugin.factory}\` | ${cell} |`
2372
+ );
1528
2373
  }
1529
- return false;
1530
- }
1531
-
1532
- // src/vite_plugin.ts
1533
- var defaultSsrExternals = [
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
- };
1551
- return [
1552
- {
1553
- name: "riebeckite-host-integration",
1554
- async config(userConfig) {
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
- }
1577
- },
1578
- riebeckiteClientModule(getConfig)
1579
- ];
1580
- }
1581
- function riebeckiteVite(options = {}) {
1582
- const { ssg, ssrExternals, ...integration } = options;
1583
- return [
1584
- ...riebeckite(integration),
1585
- riebeckiteSsrExternals([...defaultSsrExternals, ...ssrExternals ?? []]),
1586
- createRiebeckiteSsg(ssg)
1587
- ];
2374
+ lines.push("");
2375
+ lines.push(`[Riebeckite plugins on GitHub](${PLUGIN_INDEX_URL})`, "");
2376
+ lines.push("");
2377
+ return lines.join("\n");
1588
2378
  }
1589
- function riebeckiteSsrExternals(externals) {
1590
- return {
1591
- name: "riebeckite-ssr-externals",
1592
- config() {
1593
- return {
1594
- environments: {
1595
- ssr: {
1596
- resolve: {
1597
- external: [...externals]
1598
- }
1599
- }
1600
- }
1601
- };
1602
- }
1603
- };
2379
+ function referenceThemesContent() {
2380
+ const lines = [frontmatter()];
2381
+ lines.push(heading(1, "Theme reference"), "");
2382
+ lines.push(
2383
+ "The bundled themes. Switch by installing a package and changing the",
2384
+ "`theme` factory in `riebeckite.config.ts`.",
2385
+ ""
2386
+ );
2387
+ lines.push("| Theme | Factory | Description |");
2388
+ lines.push("| --- | --- | --- |");
2389
+ for (const theme of THEMES) {
2390
+ const packageName = `@riebeckite/theme-${theme.slug}`;
2391
+ lines.push(
2392
+ `| [\`${packageName}\`](${themeReadmeUrl(theme.slug)}) | \`${theme.factory}\` | ${read(theme.desc, "en")} |`
2393
+ );
2394
+ }
2395
+ lines.push("");
2396
+ lines.push(`[Riebeckite themes on GitHub](${THEMES_INDEX_URL})`, "");
2397
+ lines.push("");
2398
+ return lines.join("\n");
1604
2399
  }
1605
2400
 
2401
+ // src/scaffold/version.ts
2402
+ var RIEBECKITE_VERSION = "^0.0.6";
2403
+
1606
2404
  // src/scaffold/templates.ts
1607
- function siteTemplateFiles(variables) {
2405
+ function siteTemplateFiles(preset, variables) {
1608
2406
  return [
1609
- { path: "package.json", content: packageJson(variables) },
1610
- { path: "riebeckite.config.ts", content: riebeckiteConfig(variables) },
2407
+ { path: "package.json", content: packageJson(preset, variables) },
2408
+ {
2409
+ path: "riebeckite.config.ts",
2410
+ content: riebeckiteConfig(preset, variables)
2411
+ },
1611
2412
  { path: "vite.config.ts", content: viteConfig() },
1612
2413
  { path: "tsconfig.json", content: tsconfig() },
1613
2414
  { path: ".gitignore", content: gitignore() },
1614
- { path: "README.md", content: readme(variables) },
1615
- ...localizedContentFiles(variables),
1616
- { path: "app/server.ts", content: server() },
1617
- { path: "app/client.ts", content: client() },
1618
- { path: "app/config.ts", content: appConfig() },
1619
- { path: "app/content.ts", content: appContent() },
1620
- { path: "app/constants/paths.ts", content: paths() },
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() }
2415
+ { path: "README.md", content: readme(preset, variables) },
2416
+ ...localizedContentFiles(variables, preset),
2417
+ ...appFiles(preset)
2418
+ ];
2419
+ }
2420
+ var APP_FILE_LABELS = [
2421
+ "server",
2422
+ "client",
2423
+ "config",
2424
+ "content",
2425
+ "paths",
2426
+ "global",
2427
+ "style",
2428
+ "renderer",
2429
+ "index",
2430
+ "slug",
2431
+ "header",
2432
+ "article"
2433
+ ];
2434
+ function appFiles(preset) {
2435
+ const builders = {
2436
+ server: () => server(),
2437
+ client: () => client(),
2438
+ config: () => appConfig(),
2439
+ content: () => appContent(),
2440
+ paths: () => paths(),
2441
+ global: () => globalDeclarations(),
2442
+ style: () => style(preset),
2443
+ renderer: () => renderer(preset),
2444
+ index: () => indexRoute(preset),
2445
+ slug: () => slugRoute(),
2446
+ header: () => siteHeader(),
2447
+ article: () => article()
2448
+ };
2449
+ const generated = /* @__PURE__ */ new Map();
2450
+ for (const key of APP_FILE_LABELS) {
2451
+ if (preset.appFiles.includes(key)) {
2452
+ generated.set(key, builders[key]());
2453
+ }
2454
+ }
2455
+ const has = (key) => generated.has(key);
2456
+ const get = (key) => generated.get(key);
2457
+ return [
2458
+ ...has("server") ? [{ path: "app/server.ts", content: get("server") }] : [],
2459
+ ...has("client") ? [{ path: "app/client.ts", content: get("client") }] : [],
2460
+ ...has("config") ? [{ path: "app/config.ts", content: get("config") }] : [],
2461
+ ...has("content") ? [{ path: "app/content.ts", content: get("content") }] : [],
2462
+ ...has("paths") ? [{ path: "app/constants/paths.ts", content: get("paths") }] : [],
2463
+ ...has("global") ? [{ path: "app/global.d.ts", content: get("global") }] : [],
2464
+ ...has("style") ? [{ path: "app/style.css", content: get("style") }] : [],
2465
+ ...has("renderer") ? [{ path: "app/routes/_renderer.tsx", content: get("renderer") }] : [],
2466
+ ...has("index") ? [{ path: "app/routes/index.tsx", content: get("index") }] : [],
2467
+ ...has("slug") ? [{ path: "app/routes/[slug{.+}].tsx", content: get("slug") }] : [],
2468
+ ...has("header") ? [{ path: "app/components/site-header.tsx", content: get("header") }] : [],
2469
+ ...has("article") ? [{ path: "app/components/article.tsx", content: get("article") }] : []
1628
2470
  ];
1629
2471
  }
1630
- function packageJson(variables) {
2472
+ function packageJson(preset, variables) {
2473
+ const dependencies = {
2474
+ "@riebeckite/core": RIEBECKITE_VERSION,
2475
+ "@riebeckite/honox": RIEBECKITE_VERSION,
2476
+ hono: "^4.12.25",
2477
+ honox: "0.1.56"
2478
+ };
2479
+ for (const plugin of preset.plugins) {
2480
+ dependencies[plugin.package] = RIEBECKITE_VERSION;
2481
+ }
2482
+ if (preset.theme) {
2483
+ dependencies[preset.theme.package] = RIEBECKITE_VERSION;
2484
+ }
1631
2485
  return `${JSON.stringify(
1632
2486
  {
1633
2487
  name: variables.name,
@@ -1641,19 +2495,10 @@ function packageJson(variables) {
1641
2495
  doctor: "riebeckite doctor",
1642
2496
  inspect: "riebeckite inspect"
1643
2497
  },
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
- },
2498
+ dependencies,
1654
2499
  devDependencies: {
1655
2500
  "@hono/vite-build": "^1.11.1",
1656
- "@riebeckite/cli": "^0.0.3",
2501
+ "@riebeckite/cli": RIEBECKITE_VERSION,
1657
2502
  "@types/node": "^24.5.2",
1658
2503
  typescript: "^5.0.0",
1659
2504
  vite: "^8.0.9"
@@ -1664,37 +2509,78 @@ function packageJson(variables) {
1664
2509
  )}
1665
2510
  `;
1666
2511
  }
1667
- function riebeckiteConfig(variables) {
2512
+ function riebeckiteConfig(preset, variables) {
1668
2513
  const { title, description, baseUrl, locale } = variables;
1669
- const languages = ["en", "ja", "zh-CN", "es", "de", "fr", "ko"];
1670
- return `import { defineConfig } from "@riebeckite/core";
1671
- import { colorModePlugin } from "@riebeckite/plugin-color-mode";
1672
- import { l10n } from "@riebeckite/plugin-l10n";
1673
- import { obsidianMarkdown } from "@riebeckite/plugin-obsidian-markdown";
1674
- import { defaultTheme } from "@riebeckite/theme-default";
1675
-
1676
- export default defineConfig({
1677
- site: {
1678
- title: ${JSON.stringify(title)},
1679
- description: ${JSON.stringify(description)},
1680
- baseUrl: ${JSON.stringify(baseUrl)},
1681
- locale: ${JSON.stringify(locale)},
1682
- },
1683
- content: {
1684
- directory: "content",
1685
- },
1686
- theme: defaultTheme(),
1687
- plugins: [
1688
- obsidianMarkdown(),
1689
- colorModePlugin(),
1690
- l10n({
1691
- defaultLang: ${JSON.stringify(defaultLanguageForLocale(locale))},
1692
- languages: ${JSON.stringify(languages)},
1693
- }),
1694
- ],
1695
- });
2514
+ const lines = ['import { defineConfig } from "@riebeckite/core";'];
2515
+ for (const plugin of preset.plugins) {
2516
+ lines.push(`import { ${plugin.factory} } from "${plugin.package}";`);
2517
+ }
2518
+ if (preset.theme) {
2519
+ lines.push(
2520
+ `import { ${preset.theme.factory} } from "${preset.theme.package}";`
2521
+ );
2522
+ }
2523
+ lines.push("");
2524
+ lines.push("export default defineConfig({");
2525
+ lines.push(" site: {");
2526
+ lines.push(` title: ${JSON.stringify(title)},`);
2527
+ lines.push(` description: ${JSON.stringify(description)},`);
2528
+ lines.push(` baseUrl: ${JSON.stringify(baseUrl)},`);
2529
+ lines.push(` locale: ${JSON.stringify(locale)},`);
2530
+ lines.push(" },");
2531
+ lines.push(" content: {");
2532
+ lines.push(' directory: "content",');
2533
+ lines.push(" },");
2534
+ if (preset.theme) {
2535
+ const theme = preset.theme;
2536
+ lines.push(
2537
+ ` theme: ${theme.options ? `${theme.factory}(${theme.options})` : `${theme.factory}()`},`
2538
+ );
2539
+ }
2540
+ lines.push(" plugins: [");
2541
+ for (const plugin of preset.plugins) {
2542
+ lines.push(` ${pluginExpression(plugin, preset, variables)},`);
2543
+ }
2544
+ lines.push(" ],");
2545
+ lines.push("});");
2546
+ return `${lines.join("\n")}
1696
2547
  `;
1697
2548
  }
2549
+ var OPTION_DEPTH = {
2550
+ empty: 0,
2551
+ minimal: 0,
2552
+ starter: 0,
2553
+ rich: 1,
2554
+ full: 2,
2555
+ max: 2,
2556
+ ultra: 3
2557
+ };
2558
+ function optionContext(preset, variables) {
2559
+ return {
2560
+ variables,
2561
+ languages: preset.languages,
2562
+ depth: OPTION_DEPTH[preset.name]
2563
+ };
2564
+ }
2565
+ function renderOptionValue(value, context) {
2566
+ return typeof value === "function" ? value(context) : value;
2567
+ }
2568
+ function renderOptions(options, context) {
2569
+ if (options === void 0) return null;
2570
+ if (typeof options === "string") return options;
2571
+ if (typeof options === "function") return options(context);
2572
+ const fields = Object.entries(options).filter(([, field]) => field.depth <= context.depth).map(
2573
+ ([key, field]) => `${key}: ${renderOptionValue(field.value, context)}`
2574
+ );
2575
+ return fields.length === 0 ? null : `{ ${fields.join(", ")} }`;
2576
+ }
2577
+ function pluginExpression(plugin, preset, variables) {
2578
+ const options = renderOptions(
2579
+ plugin.options,
2580
+ optionContext(preset, variables)
2581
+ );
2582
+ return options === null ? `${plugin.factory}()` : `${plugin.factory}(${options})`;
2583
+ }
1698
2584
  function viteConfig() {
1699
2585
  const ssrExternals = [...defaultSsrExternals].map((name) => ` "${name}",`).join("\n");
1700
2586
  return `import path from "node:path";
@@ -1767,112 +2653,625 @@ function tsconfig() {
1767
2653
  function gitignore() {
1768
2654
  return ["node_modules/", "dist/", ".riebeckite/", ""].join("\n");
1769
2655
  }
1770
- function readme(variables) {
1771
- return defaultLanguageForLocale(variables.locale) === "ja" ? jaReadme(variables) : enReadme(variables);
1772
- }
1773
2656
  var REPO = "https://github.com/Rerurate514/riebeckite";
1774
- function enReadme(variables) {
1775
- return [
2657
+ var README_INTRO = {
2658
+ empty: {
2659
+ en: "A blank Riebeckite application shell — no theme, no plugins, no components, and no content. Everything is yours to add.",
2660
+ ja: "空の Riebeckite アプリケーションシェルです。テーマもプラグインもコンポーネントもコンテンツもなく、すべてを自由に追加できます。"
2661
+ },
2662
+ minimal: {
2663
+ en: "The smallest useful Riebeckite site: Obsidian Markdown, the minimal theme, and a single page.",
2664
+ ja: "最小限で実用的な Riebeckite サイトです。Obsidian マークダウン・minimal テーマ・1 ページ構成。"
2665
+ },
2666
+ starter: {
2667
+ en: "The default Riebeckite starter: Obsidian Markdown, a color-mode toggle, and seven languages.",
2668
+ ja: "Riebeckite の既定スターターです。Obsidian マークダウン・カラーモード切替・7 言語対応。"
2669
+ },
2670
+ rich: {
2671
+ en: "A showcasing starter: publishing and reading plugins plus guided ecosystem tour pages in seven languages.",
2672
+ ja: "紹介を目的としたスターターです。公開・読書体験のプラグインと、7 言語のエコシステム紹介ページ付き。"
2673
+ },
2674
+ full: {
2675
+ en: "A ready-to-use blog preset: discovery, media, and reading plugins plus a getting-started guide.",
2676
+ ja: "そのまま使えるブログ向けプリセットです。検索・メディア・読書体験のプラグインと入門ガイド付き。"
2677
+ },
2678
+ max: {
2679
+ en: "Diagram, chart, and knowledge plugins on top of full, with showcase example pages.",
2680
+ ja: "full に図解・チャート・ナレッジ系プラグインを加えた構成で、お試し用サンプルページ付き。"
2681
+ },
2682
+ ultra: {
2683
+ en: "The complete plugin catalog with plugin and theme reference pages.",
2684
+ ja: "全プラグインを有効化した最上位構成。プラグイン/テーマのリファレンスページ付き。"
2685
+ }
2686
+ };
2687
+ var README_WORDS = {
2688
+ en: {
2689
+ included: "What's included",
2690
+ languages: "Languages",
2691
+ theme: "Theme",
2692
+ plugins: "Plugins",
2693
+ pages: "Content pages",
2694
+ commands: "Commands",
2695
+ localization: "Localization",
2696
+ 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.",
2697
+ extending: "Extending",
2698
+ 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.",
2699
+ none: "none",
2700
+ noPlugins: "no plugins",
2701
+ single: "single language",
2702
+ configReference: "Configuration reference",
2703
+ configReferenceBody: "`riebeckite.config.ts` already registers every plugin below with its full option set — the file doubles as the settings reference. Every option is documented in the plugin's package README.",
2704
+ factory: "Factory",
2705
+ options: "Options",
2706
+ emDash: "—",
2707
+ demoPages: "Try the demos",
2708
+ demoPagesBody: "The generated site ships content pages that exercise these features:",
2709
+ copyDemos: "Copy-paste demos",
2710
+ copyDemosBody: "Paste any of these snippets into a Markdown file under `content/` and run `npm run dev`. Each one renders through a plugin this preset registers."
2711
+ },
2712
+ ja: {
2713
+ included: "含まれているもの",
2714
+ languages: "言語",
2715
+ theme: "テーマ",
2716
+ plugins: "プラグイン",
2717
+ pages: "コンテンツページ",
2718
+ commands: "コマンド",
2719
+ localization: "ローカライズ",
2720
+ localizationBody: "コンテンツは `content/` にプレーンな Markdown として置きます。翻訳ページは既定ファイルの隣に `<base>.<lang>.md` の規則で配置します(`about.ja.md`、`about.en.md` など)。既定言語は接尾辞なしのパス、それ以外は `/lang/` のパスで配信されます。言語の追加・削除は `riebeckite.config.ts` の `l10n(...)` プラグインを編集し、対応する翻訳ファイルを追加・削除してください。",
2721
+ extending: "拡張",
2722
+ extendingBody: "プラグインとテーマは `riebeckite.config.ts` で登録します。パッケージをインストールし、ファクトリを import して `plugins` 配列に追加するか、`theme` を別のテーマファクトリに変更します。全プラグイン・テーマの一覧は Riebeckite リポジトリを参照してください。",
2723
+ none: "なし",
2724
+ noPlugins: "プラグインなし",
2725
+ single: "単一言語",
2726
+ configReference: "設定リファレンス",
2727
+ configReferenceBody: "`riebeckite.config.ts` には、以下の全プラグインがあらかじめ全オプション付きで登録されています。このファイル自体を設定リファレンスとして利用できます。各オプションの詳しい説明はプラグインパッケージの README を参照してください。",
2728
+ factory: "ファクトリ",
2729
+ options: "オプション",
2730
+ emDash: "—",
2731
+ demoPages: "デモを試す",
2732
+ demoPagesBody: "生成されたサイトには、各機能を体験できるコンテンツページが含まれています:",
2733
+ copyDemos: "コピーして使えるデモ",
2734
+ copyDemosBody: "以下のスニペットを `content/` 配下の Markdown ファイルに貼り付けて `npm run dev` を実行してください。それぞれ、このプリセットが登録しているプラグインでレンダリングされます。"
2735
+ }
2736
+ };
2737
+ function readme(preset, variables) {
2738
+ const ja = defaultLanguageForLocale(variables.locale) === "ja";
2739
+ return ja ? readmeJa(preset, variables) : readmeEn(preset, variables);
2740
+ }
2741
+ function readmeEn(preset, variables) {
2742
+ const words = README_WORDS.en;
2743
+ const lines = [
1776
2744
  `# ${variables.title}`,
1777
2745
  "",
1778
- "A multilingual Riebeckite site generated by `riebeckite init` — seven",
1779
- "languages out of the box, plus a tour of the plugin and theme ecosystem.",
1780
- "",
1781
- "## What's inside",
1782
- "",
1783
- "- **Seven languages** (`en`, `ja`, `zh-CN`, `es`, `de`, `fr`, `ko`) via",
1784
- ` [\`@riebeckite/plugin-l10n\`](${REPO}/blob/main/packages/plugins/l10n/README.md).`,
1785
- " Every page is translated; non-default languages are served under `/lang/`",
1786
- " paths, and each page carries a language switcher.",
1787
- "- **Ecosystem tour pages**, written in all seven languages:",
1788
- " - `/framework/plugins` — representative plugins grouped by capability.",
1789
- " - `/framework/themes` — the bundled themes and how to switch.",
1790
- "- The **HonoX application shell** under `app/` — routes, components, and the",
1791
- " renderer are yours to extend.",
1792
- "",
1793
- "Run `pnpm dev` and open the site to explore.",
1794
- "",
1795
- "## Commands",
1796
- "",
2746
+ README_INTRO[preset.name].en,
2747
+ ""
2748
+ ];
2749
+ if (preset.readme !== "short") {
2750
+ lines.push(`## ${words.included}`, "");
2751
+ lines.push(`- **${words.languages}**: ${languagesLabel(preset, words)}`);
2752
+ lines.push(
2753
+ `- **${words.theme}**: ${preset.theme ? `\`${preset.theme.package}\`` : words.none}`
2754
+ );
2755
+ lines.push(
2756
+ `- **${words.plugins}** (${preset.plugins.length}): ${preset.plugins.length === 0 ? words.noPlugins : preset.plugins.map((p) => `\`${p.package}\``).join(", ")}`
2757
+ );
2758
+ lines.push(`- **${words.pages}**: ${pagesLabel(preset) ?? words.none}`);
2759
+ lines.push("");
2760
+ if (preset.readme === "rich") {
2761
+ lines.push(...configurationReferenceLines(preset, variables, words));
2762
+ }
2763
+ }
2764
+ lines.push(`## ${words.commands}`, "");
2765
+ lines.push(
1797
2766
  "```sh",
1798
- "pnpm install",
1799
- "pnpm exec riebeckite check",
1800
- "pnpm exec riebeckite dev",
1801
- "pnpm exec riebeckite build",
2767
+ "npm install",
2768
+ "npm run check",
2769
+ "npm run dev",
2770
+ "npm run build",
1802
2771
  "```",
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
2772
  ""
1824
- ].join("\n");
2773
+ );
2774
+ if (preset.readme === "rich") {
2775
+ lines.push(...demoPagesLines(preset, variables, words, "en"));
2776
+ lines.push(...copyPasteDemoLines(preset, words, "en"));
2777
+ lines.push(`## ${words.localization}`, "");
2778
+ lines.push(words.localizationBody, "");
2779
+ lines.push(`## ${words.extending}`, "");
2780
+ lines.push(words.extendingBody, "");
2781
+ lines.push(
2782
+ `- Docs: [English](${REPO}/blob/main/docs/en/README.md)`,
2783
+ ` · [日本語](${REPO}/blob/main/docs/ja/README.md)`,
2784
+ ""
2785
+ );
2786
+ }
2787
+ return lines.join("\n");
1825
2788
  }
1826
- function jaReadme(variables) {
1827
- return [
2789
+ function readmeJa(preset, variables) {
2790
+ const words = README_WORDS.ja;
2791
+ const lines = [
1828
2792
  `# ${variables.title}`,
1829
2793
  "",
1830
- "`riebeckite init` で生成した多言語対応の Riebeckite サイトです。7 言語に対応し、",
1831
- "プラグインとテーマのエコシステムを体感できる構成になっています。",
1832
- "",
1833
- "## 含まれているもの",
1834
- "",
1835
- "- **7 言語対応**(`en`, `ja`, `zh-CN`, `es`, `de`, `fr`, `ko`)—",
1836
- ` [\`@riebeckite/plugin-l10n\`](${REPO}/blob/main/packages/plugins/l10n/README_ja.md)`,
1837
- " によるもの。すべてのページが翻訳され、既定言語以外は `/lang/` パスで配信され",
1838
- " ます。各ページには言語スイッチャーが付いています。",
1839
- "- **エコシステム紹介ページ**(全 7 言語で作成):",
1840
- " - `/framework/plugins` — 代表的なプラグインを機能別に紹介。",
1841
- " - `/framework/themes` — 同梱のテーマと切り替え方。",
1842
- "- **HonoX アプリケーションシェル** `app/` — ルート・コンポーネント・レンダラー",
1843
- " は自由に拡張できます。",
1844
- "",
1845
- "`pnpm dev` を実行してサイトを開いてください。",
1846
- "",
1847
- "## コマンド",
1848
- "",
2794
+ README_INTRO[preset.name].ja,
2795
+ ""
2796
+ ];
2797
+ if (preset.readme !== "short") {
2798
+ lines.push(`## ${words.included}`, "");
2799
+ lines.push(`- **${words.languages}**: ${languagesLabel(preset, words)}`);
2800
+ lines.push(
2801
+ `- **${words.theme}**: ${preset.theme ? `\`${preset.theme.package}\`` : words.none}`
2802
+ );
2803
+ lines.push(
2804
+ `- **${words.plugins}**(${preset.plugins.length} 個): ${preset.plugins.length === 0 ? words.noPlugins : preset.plugins.map((p) => `\`${p.package}\``).join(", ")}`
2805
+ );
2806
+ lines.push(`- **${words.pages}**: ${pagesLabel(preset) ?? words.none}`);
2807
+ lines.push("");
2808
+ if (preset.readme === "rich") {
2809
+ lines.push(...configurationReferenceLines(preset, variables, words));
2810
+ }
2811
+ }
2812
+ lines.push(`## ${words.commands}`, "");
2813
+ lines.push(
1849
2814
  "```sh",
1850
- "pnpm install",
1851
- "pnpm exec riebeckite check",
1852
- "pnpm exec riebeckite dev",
1853
- "pnpm exec riebeckite build",
2815
+ "npm install",
2816
+ "npm run check",
2817
+ "npm run dev",
2818
+ "npm run build",
1854
2819
  "```",
2820
+ ""
2821
+ );
2822
+ if (preset.readme === "rich") {
2823
+ lines.push(...demoPagesLines(preset, variables, words, "ja"));
2824
+ lines.push(...copyPasteDemoLines(preset, words, "ja"));
2825
+ lines.push(`## ${words.localization}`, "");
2826
+ lines.push(words.localizationBody, "");
2827
+ lines.push(`## ${words.extending}`, "");
2828
+ lines.push(words.extendingBody, "");
2829
+ lines.push(
2830
+ `- ドキュメント: [English](${REPO}/blob/main/docs/en/README.md)`,
2831
+ ` · [日本語](${REPO}/blob/main/docs/ja/README.md)`,
2832
+ ""
2833
+ );
2834
+ }
2835
+ return lines.join("\n");
2836
+ }
2837
+ function languagesLabel(preset, words) {
2838
+ if (preset.languages.length === 0) return words.none;
2839
+ if (preset.languages.length === 1)
2840
+ return `${preset.languages[0]} (${words.single})`;
2841
+ return preset.languages.join(", ");
2842
+ }
2843
+ function pagesLabel(preset) {
2844
+ if (preset.contentPages.length === 0) return null;
2845
+ return preset.contentPages.map((page) => `/${page}`).join(", ");
2846
+ }
2847
+ var README_DEMOS = {
2848
+ "@riebeckite/plugin-obsidian-markdown/callout": {
2849
+ title: { en: "Callouts", ja: "コールアウト" },
2850
+ intro: {
2851
+ en: "A block quote with a `[!type]` marker becomes a styled callout panel.",
2852
+ ja: "`[!type]` マーカー付きブロック引用をスタイル付きパネルに変換します。"
2853
+ },
2854
+ markdown: [
2855
+ "> [!tip] Try it",
2856
+ "> A callout is a block quote with a `[!type]` marker. `[!info]`,",
2857
+ "> `[!warning]`, and `[!question]` render the same way."
2858
+ ].join("\n")
2859
+ },
2860
+ "@riebeckite/plugin-obsidian-markdown/wikilinks": {
2861
+ title: { en: "Wikilinks and embeds", ja: "ウィキリンクと埋め込み" },
2862
+ intro: {
2863
+ en: "`[[...]]` links and `![[...]]` embeds resolve to real permalinks from the content manifest.",
2864
+ ja: "`[[...]]` リンクと `![[...]]` 埋め込みは、コンテンツマニフェストから実際のパーマリンクへ解決されます。"
2865
+ },
2866
+ markdown: "Read the [[guide]] and [[index]] pages. `![[index]]` embeds the note inline."
2867
+ },
2868
+ "@riebeckite/plugin-code-enhance": {
2869
+ title: { en: "Code with a toolbar", ja: "ツールバー付きコード" },
2870
+ intro: {
2871
+ en: "Code fences get line numbers, a filename bar, line highlighting, and a copy button.",
2872
+ ja: "コードフェンスに行番号・ファイル名バー・行ハイライト・コピーボタンが付きます。"
2873
+ },
2874
+ markdown: fence(
2875
+ "ts",
2876
+ [
2877
+ "// Syntax highlighting, line numbers, and a copy button",
2878
+ "export function hello(name: string): string {",
2879
+ ' return "Hello, " + name + "!";',
2880
+ "}"
2881
+ ].join("\n")
2882
+ )
2883
+ },
2884
+ "@riebeckite/plugin-code-tabs": {
2885
+ title: { en: "Code tabs", ja: "タブ切り替えコード" },
2886
+ intro: {
2887
+ en: 'Adjacent `tab="..."` fences become one tabbed group; `syncTabs: true` keeps the same label in sync across groups.',
2888
+ ja: '隣り合う `tab="..."` フェンスがタブグループになります。`syncTabs: true` でページ内の同じラベルを同期できます。'
2889
+ },
2890
+ markdown: [
2891
+ fence('ts tab="React"', 'const greeting = "Hello from React";'),
2892
+ fence('js tab="Vanilla"', 'console.log("Hello from JavaScript");')
2893
+ ].join("\n")
2894
+ },
2895
+ "@riebeckite/plugin-mermaid": {
2896
+ title: { en: "Mermaid", ja: "Mermaid" },
2897
+ intro: {
2898
+ en: "A `mermaid` fence becomes a rendered diagram at build time.",
2899
+ ja: "`mermaid` フェンスはビルド時にレンダリングされた図になります。"
2900
+ },
2901
+ markdown: fence(
2902
+ "mermaid",
2903
+ [
2904
+ "flowchart LR",
2905
+ " A[Note] --> B{Published?}",
2906
+ " B -->|yes| C[Site]",
2907
+ " B -->|no| D[Draft]"
2908
+ ].join("\n")
2909
+ )
2910
+ },
2911
+ "@riebeckite/plugin-d2": {
2912
+ title: { en: "D2", ja: "D2" },
2913
+ intro: {
2914
+ en: "A `d2` fence is compiled into an SVG diagram.",
2915
+ ja: "`d2` フェンスが SVG 図にコンパイルされます。"
2916
+ },
2917
+ markdown: fence("d2", "site: Riebeckite\n content -> build -> deploy")
2918
+ },
2919
+ "@riebeckite/plugin-graphviz": {
2920
+ title: { en: "Graphviz / DOT", ja: "Graphviz / DOT" },
2921
+ intro: {
2922
+ en: "A `dot` fence is rendered with a configurable engine (here `dot`).",
2923
+ ja: "`dot` フェンスが指定のエンジン(ここでは `dot`)でレンダリングされます。"
2924
+ },
2925
+ markdown: fence(
2926
+ "dot",
2927
+ "digraph G {\n notes -> pages;\n pages -> html;\n}"
2928
+ )
2929
+ },
2930
+ "@riebeckite/plugin-chartjs": {
2931
+ title: { en: "Chart.js", ja: "Chart.js" },
2932
+ intro: {
2933
+ en: "A `chart` JSON fence renders with Chart.js; a caption comes from the block `title`.",
2934
+ ja: "`chart` JSON フェンスが Chart.js で描画されます。キャプションはブロックの `title` から取られます。"
2935
+ },
2936
+ markdown: fence(
2937
+ "chart",
2938
+ `{
2939
+ "type": "bar",
2940
+ "data": {
2941
+ "labels": ["Mon", "Tue", "Wed"],
2942
+ "datasets": [{ "label": "Visits", "data": [12, 19, 8] }]
2943
+ }
2944
+ }`
2945
+ )
2946
+ },
2947
+ "@riebeckite/plugin-vega-lite": {
2948
+ title: { en: "Vega-Lite", ja: "Vega-Lite" },
2949
+ intro: {
2950
+ en: "A `vega-lite` JSON specification becomes a Vega chart.",
2951
+ ja: "`vega-lite` の JSON 仕様が Vega チャートになります。"
2952
+ },
2953
+ markdown: fence(
2954
+ "vega-lite",
2955
+ `{
2956
+ "title": "Revenue",
2957
+ "data": {
2958
+ "values": [
2959
+ { "category": "A", "value": 28 },
2960
+ { "category": "B", "value": 55 }
2961
+ ]
2962
+ },
2963
+ "mark": "bar",
2964
+ "encoding": {
2965
+ "x": { "field": "category", "type": "nominal" },
2966
+ "y": { "field": "value", "type": "quantitative" }
2967
+ }
2968
+ }`
2969
+ )
2970
+ },
2971
+ "@riebeckite/plugin-wavedrom": {
2972
+ title: { en: "WaveDrom", ja: "WaveDrom" },
2973
+ intro: {
2974
+ en: "A `wavedrom` JSON fence becomes a digital timing diagram.",
2975
+ ja: "`wavedrom` JSON フェンスがデジタルタイミング図になります。"
2976
+ },
2977
+ markdown: fence(
2978
+ "wavedrom",
2979
+ `{
2980
+ "signal": [
2981
+ { "name": "clk", "wave": "p......" },
2982
+ { "name": "bus", "wave": "x.34.5x", "data": "head body tail" }
2983
+ ]
2984
+ }`
2985
+ )
2986
+ },
2987
+ "@riebeckite/plugin-markmap": {
2988
+ title: { en: "Markmap", ja: "Markmap" },
2989
+ intro: {
2990
+ en: "A `markmap` fence turns its heading outline into an interactive mind map.",
2991
+ ja: "`markmap` フェンスの見出し構成がインタラクティブなマインドマップになります。"
2992
+ },
2993
+ markdown: fence(
2994
+ "markmap",
2995
+ [
2996
+ "# Project",
2997
+ "",
2998
+ "## Design",
2999
+ "",
3000
+ "### Notation",
3001
+ "### Rendering",
3002
+ "",
3003
+ "## Delivery"
3004
+ ].join("\n")
3005
+ )
3006
+ },
3007
+ "@riebeckite/plugin-map": {
3008
+ title: { en: "Maps", ja: "地図" },
3009
+ intro: {
3010
+ en: "A `map` fence embeds an OpenStreetMap: a static fallback (coordinates and links) first, upgraded to an interactive map when JavaScript is available.",
3011
+ ja: "`map` フェンスが OpenStreetMap を埋め込みます。まず静的なフォールバック(座標とリンク)を表示し、JavaScript がある場合はインタラクティブな地図に拡張します。"
3012
+ },
3013
+ markdown: fence(
3014
+ "map",
3015
+ [
3016
+ "center: 35.6812, 139.7671",
3017
+ "zoom: 13",
3018
+ "label: Tokyo Station",
3019
+ "markers:",
3020
+ " - 35.6812, 139.7671 | Tokyo Station",
3021
+ " - 35.6586, 139.7454 | Tokyo Tower"
3022
+ ].join("\n")
3023
+ )
3024
+ },
3025
+ "@riebeckite/plugin-marp": {
3026
+ title: { en: "Marp slides", ja: "Marp スライド" },
3027
+ intro: {
3028
+ en: "A `marp` fence renders slides, separated by `---`.",
3029
+ ja: "`marp` フェンスがスライドとして描画されます。スライドは `---` で区切ります。"
3030
+ },
3031
+ markdown: fence(
3032
+ 'marp title="Intro deck"',
3033
+ ["# First slide", "", "- a bullet", "", "---", "", "# Second slide"].join(
3034
+ "\n"
3035
+ )
3036
+ )
3037
+ },
3038
+ "@riebeckite/plugin-qr-code": {
3039
+ title: { en: "QR codes", ja: "QR コード" },
3040
+ intro: {
3041
+ en: "A `qr` fence becomes an inline SVG QR code, encoded entirely at build time.",
3042
+ ja: "`qr` フェンスがインライン SVG の QR コードになります(ビルド時に全てエンコードされます)。"
3043
+ },
3044
+ markdown: fence("qr", "# caption: Project page\nhttps://example.com/")
3045
+ },
3046
+ "@riebeckite/plugin-rich-embed": {
3047
+ title: { en: "Rich embeds", ja: "リッチ埋め込み" },
3048
+ intro: {
3049
+ en: "An `embed` fence turns a URL into a YouTube, Vimeo, Spotify, CodePen, or Gist embed.",
3050
+ ja: "`embed` フェンスの URL が YouTube・Vimeo・Spotify・CodePen・Gist の埋め込みになります。"
3051
+ },
3052
+ markdown: fence(
3053
+ "embed",
3054
+ [
3055
+ "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
3056
+ "title: Demo video",
3057
+ "caption: A short caption",
3058
+ "aspect: 16/9"
3059
+ ].join("\n")
3060
+ )
3061
+ },
3062
+ "@riebeckite/plugin-gallery": {
3063
+ title: { en: "Gallery cards", ja: "ギャラリーカード" },
3064
+ intro: {
3065
+ en: "A `gallery` YAML fence renders a responsive grid of cards — handy for theme or project showcases.",
3066
+ ja: "`gallery` の YAML フェンスがレスポンシブなカードグリッドを描画します。テーマやプロジェクトの紹介に便利です。"
3067
+ },
3068
+ markdown: fence(
3069
+ "gallery",
3070
+ [
3071
+ "columns: 3",
3072
+ "items:",
3073
+ " - title: Default",
3074
+ " description: A clean, typographic theme.",
3075
+ " meta: v0.0.5",
3076
+ " href: https://example.com/themes/default/",
3077
+ " - title: Minimal",
3078
+ " description: Stripped back to the essentials.",
3079
+ " meta: v0.0.5",
3080
+ " href: https://example.com/themes/minimal/",
3081
+ " - title: Gruvbox",
3082
+ " description: A warm, high-contrast palette.",
3083
+ " meta: v0.0.5",
3084
+ " href: https://example.com/themes/gruvbox/"
3085
+ ].join("\n")
3086
+ )
3087
+ },
3088
+ "@riebeckite/plugin-dataview": {
3089
+ title: { en: "Dataview", ja: "Dataview" },
3090
+ intro: {
3091
+ en: "A `dataview` query renders a table of notes from the manifest.",
3092
+ ja: "`dataview` クエリがマニフェストからノート一覧を描画します。"
3093
+ },
3094
+ markdown: fence(
3095
+ "dataview",
3096
+ [
3097
+ 'TABLE file.name AS "Name", status',
3098
+ "FROM #project",
3099
+ 'WHERE status = "active"',
3100
+ "SORT file.name asc",
3101
+ "LIMIT 10"
3102
+ ].join("\n")
3103
+ )
3104
+ },
3105
+ "@riebeckite/plugin-query": {
3106
+ title: { en: "Query", ja: "Query" },
3107
+ intro: {
3108
+ en: "A `query` fence is YAML that filters and sorts entries from the manifest.",
3109
+ ja: "`query` フェンスの YAML でマニフェストのエントリを絞り込み・並べ替えできます。"
3110
+ },
3111
+ markdown: fence(
3112
+ "query",
3113
+ [
3114
+ "filter:",
3115
+ " tags:",
3116
+ " any: [diary]",
3117
+ "sort:",
3118
+ " field: date",
3119
+ " order: desc",
3120
+ "limit: 5"
3121
+ ].join("\n")
3122
+ )
3123
+ },
3124
+ "@riebeckite/plugin-bases": {
3125
+ title: { en: "Base views", ja: "Base ビュー" },
3126
+ intro: {
3127
+ en: "A `base` YAML fence renders a Base table view.",
3128
+ ja: "`base` YAML フェンスが Base のテーブルビューを描画します。"
3129
+ },
3130
+ markdown: fence(
3131
+ "base",
3132
+ [
3133
+ "filters:",
3134
+ " and:",
3135
+ ' - file.hasTag("featured")',
3136
+ "properties:",
3137
+ " file.name:",
3138
+ " displayName: Title",
3139
+ "views:",
3140
+ " - type: table",
3141
+ " name: Featured",
3142
+ " limit: 10"
3143
+ ].join("\n")
3144
+ )
3145
+ },
3146
+ "@riebeckite/plugin-kanban": {
3147
+ title: { en: "Kanban boards", ja: "カンバンボード" },
3148
+ intro: {
3149
+ en: "A note whose body is `##` columns of task lists becomes a board; `#tags` and `[[wikilinks]]` work inside cards.",
3150
+ ja: "本文が `##` 列とタスクリストでできたノートはボードになります。カード内では `#タグ` や `[[ウィキリンク]]` も使えます。"
3151
+ },
3152
+ markdown: fence(
3153
+ "md",
3154
+ [
3155
+ "## Backlog",
3156
+ "",
3157
+ "- [ ] Draft the release notes",
3158
+ "- [ ] Link to [[index]]",
3159
+ "",
3160
+ "## Done",
3161
+ "",
3162
+ "- [x] Publish the fixture"
3163
+ ].join("\n")
3164
+ )
3165
+ }
3166
+ };
3167
+ var README_PAGE_LINKS = {
3168
+ "framework/plugins": { en: "Plugin tour", ja: "プラグインツアー" },
3169
+ "framework/themes": { en: "Theme tour", ja: "テーマツアー" },
3170
+ guide: { en: "Getting-started guide", ja: "はじめにガイド" },
3171
+ examples: { en: "Examples", ja: "サンプル集" },
3172
+ "reference/plugins": { en: "Plugin reference", ja: "プラグインリファレンス" },
3173
+ "reference/themes": { en: "Theme reference", ja: "テーマリファレンス" }
3174
+ };
3175
+ var ENGLISH_ONLY_PAGES = /* @__PURE__ */ new Set([
3176
+ "guide",
3177
+ "reference/plugins",
3178
+ "reference/themes"
3179
+ ]);
3180
+ function fence(language, body) {
3181
+ const tick = "```";
3182
+ return `${tick}${language}
3183
+ ${body}
3184
+ ${tick}`;
3185
+ }
3186
+ function hasPlugin(preset, packageName) {
3187
+ return preset.plugins.some((plugin) => plugin.package === packageName);
3188
+ }
3189
+ function demoPackage(key) {
3190
+ return key.split("/", 2).join("/");
3191
+ }
3192
+ function readmePluginOptions(variables, preset, plugin) {
3193
+ return renderOptions(plugin.options, optionContext(preset, variables));
3194
+ }
3195
+ function configurationReferenceLines(preset, variables, words) {
3196
+ const lines = [
3197
+ `## ${words.configReference}`,
1855
3198
  "",
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
- "対応する翻訳ファイルを追加・削除してください。",
3199
+ words.configReferenceBody,
3200
+ ""
3201
+ ];
3202
+ if (preset.theme) {
3203
+ const themeCall = preset.theme.options ? `${preset.theme.factory}(${preset.theme.options})` : `${preset.theme.factory}()`;
3204
+ lines.push(`- **${words.theme}**: \`${themeCall}\``, "");
3205
+ }
3206
+ lines.push(
3207
+ `| Package | ${words.factory} | ${words.options} |`,
3208
+ "| --- | --- | --- |"
3209
+ );
3210
+ for (const plugin of preset.plugins) {
3211
+ const options = readmePluginOptions(variables, preset, plugin);
3212
+ const cell = options === null ? words.emDash : `\`${options}\``;
3213
+ lines.push(`| \`${plugin.package}\` | \`${plugin.factory}\` | ${cell} |`);
3214
+ }
3215
+ lines.push("");
3216
+ return lines;
3217
+ }
3218
+ function demoPagesLines(preset, variables, words, language) {
3219
+ const lines = [
3220
+ `## ${words.demoPages}`,
1865
3221
  "",
1866
- "## 拡張",
3222
+ words.demoPagesBody,
3223
+ ""
3224
+ ];
3225
+ const defaultLang = defaultLanguageForLocale(variables.locale);
3226
+ const pages = preset.contentPages.filter((page) => page !== "index");
3227
+ for (const page of pages) {
3228
+ const label = README_PAGE_LINKS[page]?.[language] ?? `/${page}/`;
3229
+ const suffix = ENGLISH_ONLY_PAGES.has(page) && defaultLang !== "en" ? ".en" : "";
3230
+ const source = `content/${page}${suffix}.md`;
3231
+ const url = `/${page}/`;
3232
+ lines.push(`- [**${label}**](${source}) — live at [\`${url}\`](${url})`);
3233
+ }
3234
+ lines.push("");
3235
+ return lines;
3236
+ }
3237
+ var README_DEMO_ORDER = [
3238
+ "@riebeckite/plugin-obsidian-markdown/callout",
3239
+ "@riebeckite/plugin-obsidian-markdown/wikilinks",
3240
+ "@riebeckite/plugin-code-enhance",
3241
+ "@riebeckite/plugin-code-tabs",
3242
+ "@riebeckite/plugin-mermaid",
3243
+ "@riebeckite/plugin-d2",
3244
+ "@riebeckite/plugin-graphviz",
3245
+ "@riebeckite/plugin-chartjs",
3246
+ "@riebeckite/plugin-vega-lite",
3247
+ "@riebeckite/plugin-wavedrom",
3248
+ "@riebeckite/plugin-markmap",
3249
+ "@riebeckite/plugin-map",
3250
+ "@riebeckite/plugin-marp",
3251
+ "@riebeckite/plugin-qr-code",
3252
+ "@riebeckite/plugin-rich-embed",
3253
+ "@riebeckite/plugin-gallery",
3254
+ "@riebeckite/plugin-dataview",
3255
+ "@riebeckite/plugin-query",
3256
+ "@riebeckite/plugin-bases",
3257
+ "@riebeckite/plugin-kanban"
3258
+ ];
3259
+ function copyPasteDemoLines(preset, words, language) {
3260
+ const lines = [
3261
+ `## ${words.copyDemos}`,
1867
3262
  "",
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)`,
3263
+ words.copyDemosBody,
1874
3264
  ""
1875
- ].join("\n");
3265
+ ];
3266
+ for (const key of README_DEMO_ORDER) {
3267
+ const packageName = demoPackage(key);
3268
+ if (!hasPlugin(preset, packageName)) continue;
3269
+ const demo = README_DEMOS[key];
3270
+ lines.push(`### ${demo.title[language]}`, "");
3271
+ lines.push(demo.intro[language], "");
3272
+ lines.push(demo.markdown, "");
3273
+ }
3274
+ return lines;
1876
3275
  }
1877
3276
  function server() {
1878
3277
  return `import { mountRiebeckiteEndpoints } from "@riebeckite/honox/server";
@@ -1887,6 +3286,7 @@ const app = createApp({
1887
3286
  });
1888
3287
 
1889
3288
  export default app;
3289
+ export { config, content };
1890
3290
  `;
1891
3291
  }
1892
3292
  function client() {
@@ -1972,37 +3372,63 @@ declare module "hono" {
1972
3372
  }
1973
3373
  `;
1974
3374
  }
1975
- function style() {
1976
- return `@import "./.riebeckite/plugin-styles.css";
1977
- @import "./.riebeckite/theme-styles.css";
1978
-
1979
- body {
1980
- margin: 0;
1981
- font-family: system-ui, sans-serif;
1982
- }
1983
-
1984
- .site-header {
1985
- display: flex;
1986
- align-items: center;
1987
- justify-content: space-between;
1988
- gap: 1rem;
1989
- padding: 1rem;
1990
- border-bottom: 1px solid #d1d5db;
1991
- }
1992
-
1993
- .site-header__home {
1994
- color: #111827;
1995
- font-weight: 700;
1996
- text-decoration: none;
1997
- }
1998
-
1999
- .site-article {
2000
- display: block;
2001
- max-width: 48rem;
2002
- padding: 2rem 1rem;
2003
- margin: 0 auto;
2004
- }
2005
- `;
3375
+ function style(preset) {
3376
+ const imports = [];
3377
+ if (preset.plugins.length > 0) {
3378
+ imports.push('@import "./.riebeckite/plugin-styles.css";');
3379
+ }
3380
+ if (preset.theme) {
3381
+ imports.push('@import "./.riebeckite/theme-styles.css";');
3382
+ }
3383
+ const blocks = [
3384
+ "",
3385
+ "body {",
3386
+ " margin: 0;",
3387
+ " font-family: system-ui, sans-serif;",
3388
+ "}",
3389
+ ""
3390
+ ];
3391
+ if (preset.appFiles.includes("header")) {
3392
+ blocks.push(
3393
+ ".site-header {",
3394
+ " display: flex;",
3395
+ " align-items: center;",
3396
+ " justify-content: space-between;",
3397
+ " gap: 1rem;",
3398
+ " padding: 1rem;",
3399
+ " border-bottom: 1px solid #d1d5db;",
3400
+ "}",
3401
+ "",
3402
+ ".site-header__home {",
3403
+ " color: #111827;",
3404
+ " font-weight: 700;",
3405
+ " text-decoration: none;",
3406
+ "}",
3407
+ ""
3408
+ );
3409
+ }
3410
+ if (preset.appFiles.includes("article")) {
3411
+ blocks.push(
3412
+ ".site-article {",
3413
+ " display: block;",
3414
+ " max-width: 48rem;",
3415
+ " padding: 2rem 1rem;",
3416
+ " margin: 0 auto;",
3417
+ "}",
3418
+ ""
3419
+ );
3420
+ }
3421
+ if (!preset.theme) {
3422
+ blocks.push(
3423
+ ".riebeckite-empty {",
3424
+ " max-width: 48rem;",
3425
+ " padding: 4rem 1rem;",
3426
+ " margin: 0 auto;",
3427
+ "}",
3428
+ ""
3429
+ );
3430
+ }
3431
+ return [...imports, ...blocks].join("\n");
2006
3432
  }
2007
3433
  function siteHeader() {
2008
3434
  return `import { ColorModeToggle } from "@riebeckite/plugin-color-mode";
@@ -2049,13 +3475,18 @@ export function SiteArticle({
2049
3475
  }
2050
3476
  `;
2051
3477
  }
2052
- function renderer() {
3478
+ function renderer(preset) {
3479
+ if (!preset.theme) return bareRenderer();
3480
+ const hasHeader = preset.appFiles.includes("header");
3481
+ const hasColorMode = preset.plugins.some(
3482
+ (plugin) => plugin.package === "@riebeckite/plugin-color-mode"
3483
+ );
2053
3484
  return `import type { PluginHeadTag } from "@riebeckite/core";
2054
3485
  import { jsxRenderer } from "hono/jsx-renderer";
2055
3486
  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";
3487
+ ${hasColorMode ? `import { ColorModeScript } from "@riebeckite/plugin-color-mode";
3488
+ ` : ""}${hasHeader ? `import { SiteHeader } from "../components/site-header";
3489
+ ` : ""}import { config } from "../config";
2059
3490
 
2060
3491
  function themeAttributes() {
2061
3492
  const { theme } = config;
@@ -2081,14 +3512,14 @@ export default jsxRenderer(({ children }, c) => {
2081
3512
  <meta charset="utf-8" />
2082
3513
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
2083
3514
  <title>{config.site.title}</title>
2084
- <ColorModeScript />
2085
- <Link href="/app/style.css" rel="stylesheet" />
3515
+ ${hasColorMode ? ` <ColorModeScript />
3516
+ ` : ""} <Link href="/app/style.css" rel="stylesheet" />
2086
3517
  {headTags.map(renderHeadTag)}
2087
3518
  <Script src="/app/client.ts" async />
2088
3519
  </head>
2089
3520
  <body class="riebeckite-page">
2090
- <SiteHeader />
2091
- {children}
3521
+ ${hasHeader ? ` <SiteHeader />
3522
+ ` : ""} {children}
2092
3523
  </body>
2093
3524
  </html>
2094
3525
  );
@@ -2110,7 +3541,27 @@ function renderHeadTag(tag: PluginHeadTag, index: number) {
2110
3541
  }
2111
3542
  `;
2112
3543
  }
2113
- function indexRoute() {
3544
+ function bareRenderer() {
3545
+ return `import { jsxRenderer } from "hono/jsx-renderer";
3546
+ import { Link, Script } from "honox/server";
3547
+ import { config } from "../config";
3548
+
3549
+ export default jsxRenderer(({ children }, c) => (
3550
+ <html lang={c.get("htmlLanguage") ?? config.site.locale}>
3551
+ <head>
3552
+ <meta charset="utf-8" />
3553
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
3554
+ <title>{config.site.title}</title>
3555
+ <Link href="/app/style.css" rel="stylesheet" />
3556
+ <Script src="/app/client.ts" async />
3557
+ </head>
3558
+ <body class="riebeckite-page">{children}</body>
3559
+ </html>
3560
+ ));
3561
+ `;
3562
+ }
3563
+ function indexRoute(preset) {
3564
+ if (!preset.appFiles.includes("article")) return staticIndexRoute();
2114
3565
  return `import { isPublished } from "@riebeckite/core";
2115
3566
  import { createRoute } from "honox/factory";
2116
3567
  import { SiteArticle } from "../components/article";
@@ -2143,6 +3594,20 @@ export default createRoute(async (c) => {
2143
3594
  });
2144
3595
  `;
2145
3596
  }
3597
+ function staticIndexRoute() {
3598
+ return `import { createRoute } from "honox/factory";
3599
+ import { config } from "../config";
3600
+
3601
+ export default createRoute((c) =>
3602
+ c.render(
3603
+ <main class="riebeckite-empty">
3604
+ <h1>{config.site.title}</h1>
3605
+ <p>This is a blank Riebeckite site. Add Markdown files under content/ to get started.</p>
3606
+ </main>,
3607
+ ),
3608
+ );
3609
+ `;
3610
+ }
2146
3611
  function slugRoute() {
2147
3612
  return `import { isPublished } from "@riebeckite/core";
2148
3613
  import {
@@ -2201,7 +3666,11 @@ var ScaffoldSiteError = class extends Error {
2201
3666
  };
2202
3667
  async function scaffoldRiebeckiteSite(options) {
2203
3668
  const targetDirectory = path7.resolve(options.targetDirectory);
2204
- const files = siteTemplateFiles(templateVariables(options, targetDirectory));
3669
+ const preset = resolveScaffoldPreset(options.preset);
3670
+ const files = siteTemplateFiles(
3671
+ preset,
3672
+ templateVariables(options, targetDirectory)
3673
+ );
2205
3674
  await assertTargetWritable(
2206
3675
  targetDirectory,
2207
3676
  files,
@@ -2252,21 +3721,40 @@ function normalizePackageName(value) {
2252
3721
  function isNotFoundError(error) {
2253
3722
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
2254
3723
  }
3724
+
3725
+ // src/scaffold/next-steps.ts
3726
+ function formatScaffoldNextSteps(relativeDirectory) {
3727
+ const lines = ["Next steps:"];
3728
+ if (relativeDirectory !== ".") {
3729
+ lines.push(` cd ${relativeDirectory}`);
3730
+ }
3731
+ lines.push(" npm install");
3732
+ lines.push(" npm run check");
3733
+ lines.push(" npm run dev");
3734
+ lines.push(" npm run build");
3735
+ return lines.join("\n");
3736
+ }
2255
3737
  export {
3738
+ SCAFFOLD_DEFAULT_PRESET,
3739
+ SCAFFOLD_PRESET_NAMES,
2256
3740
  ScaffoldSiteError,
2257
3741
  buildHonoxApplication,
2258
3742
  createRiebeckiteSsg,
2259
3743
  defaultSsgEntry,
2260
3744
  defaultSsrExternals,
3745
+ formatScaffoldNextSteps,
3746
+ isScaffoldPresetName,
2261
3747
  loadRiebeckiteConfig,
2262
3748
  replaceHonoxIslandDependencyPlugin,
2263
3749
  resolveHonoxApplication,
2264
3750
  resolveHonoxApplicationRoot,
2265
3751
  resolveHonoxConfig,
3752
+ resolveScaffoldPreset,
2266
3753
  riebeckite,
2267
3754
  riebeckiteSsg,
2268
3755
  riebeckiteSsgExtensionMap,
2269
3756
  riebeckiteVite,
3757
+ scaffoldPresets,
2270
3758
  scaffoldRiebeckiteSite,
2271
3759
  startHonoxDevServer
2272
3760
  };