@riebeckite/honox 0.0.4 → 0.0.5

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