@riebeckite/honox 0.0.7 → 0.0.9

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
@@ -1,6 +1,5 @@
1
1
  // src/config_loader.ts
2
2
  import fs2 from "node:fs/promises";
3
- import os from "node:os";
4
3
  import path2 from "node:path";
5
4
  import { build as buildWithEsbuild } from "esbuild";
6
5
 
@@ -112,7 +111,7 @@ function escapeRegExp(value) {
112
111
  async function loadRiebeckiteConfig(options) {
113
112
  const configFile = options.configFile ?? "riebeckite.config.ts";
114
113
  const temporaryDirectory = await fs2.mkdtemp(
115
- path2.join(os.tmpdir(), "riebeckite-config-")
114
+ path2.join(options.configRoot, ".riebeckite-config-")
116
115
  );
117
116
  const outputFile = path2.join(temporaryDirectory, "config.mjs");
118
117
  try {
@@ -144,6 +143,7 @@ async function loadRiebeckiteConfig(options) {
144
143
  function resolveHonoxConfig(config, appRoot) {
145
144
  return {
146
145
  ...config,
146
+ buildDirectory: path2.join(appRoot, ".riebeckite"),
147
147
  content: {
148
148
  ...config.content,
149
149
  directory: path2.resolve(appRoot, config.content.directory)
@@ -937,9 +937,21 @@ ${imports}
937
937
  `;
938
938
  }
939
939
  function writeGeneratedFile(filePath, contents) {
940
+ if (readGeneratedFile(filePath) === contents) return;
940
941
  fs4.mkdirSync(path4.dirname(filePath), { recursive: true });
941
942
  fs4.writeFileSync(filePath, contents);
942
943
  }
944
+ function readGeneratedFile(filePath) {
945
+ try {
946
+ return fs4.readFileSync(filePath, "utf8");
947
+ } catch (error) {
948
+ if (isNotFoundError(error)) return void 0;
949
+ throw error;
950
+ }
951
+ }
952
+ function isNotFoundError(error) {
953
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
954
+ }
943
955
 
944
956
  // src/client_module.ts
945
957
  import {
@@ -1285,6 +1297,11 @@ function riebeckite(options = {}) {
1285
1297
  define: {
1286
1298
  "process.env.RIEBECKITE_APP_ROOT": JSON.stringify(appRoot)
1287
1299
  },
1300
+ server: {
1301
+ watch: {
1302
+ ignored: ["**/.riebeckite/**"]
1303
+ }
1304
+ },
1288
1305
  resolve: {
1289
1306
  alias: options.workspaceRoot ? createWorkspacePackageAliases(options.workspaceRoot) : []
1290
1307
  }
@@ -1319,99 +1336,485 @@ function riebeckiteSsrExternals(externals) {
1319
1336
  };
1320
1337
  }
1321
1338
 
1322
- // src/scaffold/localized-content.ts
1323
- var HELPERS = {
1324
- en: "https://github.com/Rerurate514/riebeckite/blob/main/docs/en/README.md",
1325
- ja: "https://github.com/Rerurate514/riebeckite/blob/main/docs/ja/README.md"
1339
+ // src/scaffold/app-templates.ts
1340
+ function server() {
1341
+ return `import { mountRiebeckiteEndpoints } from "@riebeckite/honox/server";
1342
+ import { createApp } from "honox/server";
1343
+ import { config } from "./config";
1344
+ import { content } from "./content";
1345
+
1346
+ const app = createApp({
1347
+ init: (app) => {
1348
+ mountRiebeckiteEndpoints(app, { config, content });
1349
+ },
1350
+ });
1351
+
1352
+ export default app;
1353
+ export { config, content };
1354
+ `;
1355
+ }
1356
+ function client() {
1357
+ return `import { initRiebeckiteClient } from "virtual:riebeckite/client";
1358
+ import { createClient } from "honox/client";
1359
+
1360
+ createClient();
1361
+
1362
+ if (document.readyState === "loading") {
1363
+ document.addEventListener("DOMContentLoaded", initPage, { once: true });
1364
+ } else {
1365
+ initPage();
1366
+ }
1367
+
1368
+ function initPage() {
1369
+ initRiebeckiteClient();
1370
+ }
1371
+ `;
1372
+ }
1373
+ function appConfig() {
1374
+ return `import path from "node:path";
1375
+ import { fileURLToPath } from "node:url";
1376
+ import { resolveConfigModule } from "@riebeckite/core";
1377
+ import * as rawConfigModule from "../riebeckite.config";
1378
+
1379
+ const appRoot =
1380
+ process.env.RIEBECKITE_APP_ROOT ??
1381
+ fileURLToPath(new URL("../", import.meta.url));
1382
+ const resolvedConfig = resolveConfigModule(rawConfigModule);
1383
+
1384
+ export const config = {
1385
+ ...resolvedConfig,
1386
+ buildDirectory: path.join(appRoot, ".riebeckite"),
1387
+ content: {
1388
+ ...resolvedConfig.content,
1389
+ directory: path.resolve(appRoot, resolvedConfig.content.directory),
1390
+ },
1326
1391
  };
1327
- var PLUGIN_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/plugins";
1328
- var THEMES_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/themes";
1329
- function pluginReadmeUrl(slug) {
1330
- return `https://github.com/Rerurate514/riebeckite/blob/main/packages/plugins/${slug}/README.md`;
1392
+ `;
1331
1393
  }
1332
- function themeReadmeUrl(slug) {
1333
- return `https://github.com/Rerurate514/riebeckite/blob/main/packages/themes/${slug}/README.md`;
1394
+ function appContent() {
1395
+ return `import { ContentManager } from "@riebeckite/core";
1396
+ import { config } from "./config";
1397
+ import { CONTENT_DIR } from "./constants/paths";
1398
+
1399
+ export const content = new ContentManager(
1400
+ CONTENT_DIR,
1401
+ config.content.exclude,
1402
+ {
1403
+ config,
1404
+ plugins: config.plugins,
1405
+ },
1406
+ );
1407
+ `;
1334
1408
  }
1335
- function localizedContentFiles(variables, preset) {
1336
- const defaultLang = defaultLanguageForLocale(variables.locale);
1337
- const files = [];
1338
- const localized = preset.languages.length > 1;
1339
- const pushLocalized = (basePath, build2) => {
1340
- if (!localized) {
1341
- files.push({
1342
- path: `content/${basePath}.md`,
1343
- content: build2(defaultLang)
1344
- });
1345
- return;
1346
- }
1347
- for (const language of SCAFFOLD_LANGUAGES) {
1348
- const suffix = language === defaultLang ? "" : `.${language}`;
1349
- files.push({
1350
- path: `content/${basePath}${suffix}.md`,
1351
- content: build2(language)
1352
- });
1353
- }
1354
- };
1355
- const pushEnglishOnly = (basePath, build2) => {
1356
- const suffix = defaultLang === "en" ? "" : ".en";
1357
- files.push({
1358
- path: `content/${basePath}${suffix}.md`,
1359
- content: build2()
1360
- });
1361
- };
1362
- for (const page of preset.contentPages) {
1363
- if (page === "index") {
1364
- pushLocalized("index", (language) => indexContent(variables, language));
1365
- } else if (page === "framework/plugins") {
1366
- pushLocalized(
1367
- "framework/plugins",
1368
- (language) => pluginsContent(language)
1369
- );
1370
- } else if (page === "framework/themes") {
1371
- pushLocalized("framework/themes", (language) => themesContent(language));
1372
- } else if (page === "guide") {
1373
- pushEnglishOnly("guide", guideContent);
1374
- } else if (page === "examples") {
1375
- pushLocalized(
1376
- "examples",
1377
- (language) => examplesContent(preset, language)
1378
- );
1379
- } else if (page === "reference/plugins") {
1380
- pushEnglishOnly(
1381
- "reference/plugins",
1382
- () => referencePluginsContent(preset, variables)
1383
- );
1384
- } else if (page === "reference/themes") {
1385
- pushEnglishOnly("reference/themes", referenceThemesContent);
1386
- }
1409
+ function paths() {
1410
+ return `import path from "node:path";
1411
+ import { fileURLToPath } from "node:url";
1412
+ import { config } from "../config";
1413
+
1414
+ const appRoot =
1415
+ process.env.RIEBECKITE_APP_ROOT ??
1416
+ fileURLToPath(new URL("../../", import.meta.url));
1417
+
1418
+ export const CONTENT_DIR = path.resolve(appRoot, config.content.directory);
1419
+ export const ASSETS_ROOT = "public/";
1420
+ `;
1421
+ }
1422
+ function globalDeclarations() {
1423
+ return `import type { PluginHeadTag } from "@riebeckite/core";
1424
+
1425
+ declare module "virtual:riebeckite/client" {
1426
+ export function initRiebeckiteClient(): void;
1427
+ }
1428
+
1429
+ declare module "hono" {
1430
+ interface Env {
1431
+ Variables: {
1432
+ headTags?: readonly PluginHeadTag[];
1433
+ htmlLanguage?: string;
1434
+ };
1435
+ Bindings: Record<string, never>;
1387
1436
  }
1388
- return files;
1389
1437
  }
1390
- function read(text, language) {
1391
- return text[language];
1438
+ `;
1392
1439
  }
1393
- function frontmatter() {
1394
- return ["---", "publish: true", "---", ""].join("\n");
1440
+ function style(preset) {
1441
+ const imports = [];
1442
+ if (preset.plugins.length > 0) {
1443
+ imports.push('@import "./.riebeckite/plugin-styles.css";');
1444
+ }
1445
+ if (preset.theme) {
1446
+ imports.push('@import "./.riebeckite/theme-styles.css";');
1447
+ }
1448
+ const blocks = [
1449
+ "",
1450
+ "body {",
1451
+ " margin: 0;",
1452
+ " font-family: system-ui, sans-serif;",
1453
+ "}",
1454
+ ""
1455
+ ];
1456
+ if (preset.appFiles.includes("header")) {
1457
+ blocks.push(
1458
+ ".site-header {",
1459
+ " display: flex;",
1460
+ " align-items: center;",
1461
+ " justify-content: space-between;",
1462
+ " gap: 1rem;",
1463
+ " padding: 1rem;",
1464
+ " border-bottom: 1px solid #d1d5db;",
1465
+ "}",
1466
+ "",
1467
+ ".site-header__home {",
1468
+ " color: #111827;",
1469
+ " font-weight: 700;",
1470
+ " text-decoration: none;",
1471
+ "}",
1472
+ ""
1473
+ );
1474
+ }
1475
+ if (preset.appFiles.includes("article")) {
1476
+ blocks.push(
1477
+ ".site-article {",
1478
+ " display: block;",
1479
+ " max-width: 48rem;",
1480
+ " padding: 2rem 1rem;",
1481
+ " margin: 0 auto;",
1482
+ "}",
1483
+ ""
1484
+ );
1485
+ }
1486
+ if (!preset.theme) {
1487
+ blocks.push(
1488
+ ".riebeckite-empty {",
1489
+ " max-width: 48rem;",
1490
+ " padding: 4rem 1rem;",
1491
+ " margin: 0 auto;",
1492
+ "}",
1493
+ ""
1494
+ );
1495
+ }
1496
+ return [...imports, ...blocks].join("\n");
1395
1497
  }
1396
- function heading(level, text) {
1397
- return `${"#".repeat(level)} ${text}`;
1498
+ function siteHeader() {
1499
+ return `import { ColorModeToggle } from "@riebeckite/plugin-color-mode";
1500
+ import { config } from "../config";
1501
+
1502
+ export function SiteHeader() {
1503
+ return (
1504
+ <header class="site-header">
1505
+ <a href="/" class="site-header__home">
1506
+ {config.site.title}
1507
+ </a>
1508
+ <ColorModeToggle />
1509
+ </header>
1510
+ );
1398
1511
  }
1399
- function codeBlock(language, code) {
1400
- return `\`\`\`${language}
1401
- ${code}
1402
- \`\`\`
1403
1512
  `;
1404
1513
  }
1405
- var INDEX = {
1406
- lead: {
1407
- en: "Welcome to your Riebeckite site.",
1408
- ja: "あなたの Riebeckite サイトへようこそ。",
1409
- "zh-CN": "欢迎来到你的 Riebeckite 站点。",
1410
- es: "Bienvenido a tu sitio Riebeckite.",
1411
- de: "Willkommen auf deiner Riebeckite-Seite.",
1412
- fr: "Bienvenue sur votre site Riebeckite.",
1413
- ko: "Riebeckite 사이트에 오신 것을 환영합니다."
1414
- },
1514
+ function article() {
1515
+ return `import type { PostContent } from "@riebeckite/core";
1516
+ import { Article, ArticleContent, ArticleLayout } from "@riebeckite/honox/ui";
1517
+
1518
+ export function SiteArticle({
1519
+ post,
1520
+ afterMeta,
1521
+ }: {
1522
+ post: PostContent;
1523
+ afterMeta?: string;
1524
+ }) {
1525
+ return (
1526
+ <Article class="site-article">
1527
+ <ArticleLayout>
1528
+ <ArticleContent>
1529
+ {afterMeta ? (
1530
+ <div
1531
+ class="site-article__after-meta"
1532
+ dangerouslySetInnerHTML={{ __html: afterMeta }}
1533
+ />
1534
+ ) : null}
1535
+ <div dangerouslySetInnerHTML={{ __html: post.html ?? "" }} />
1536
+ </ArticleContent>
1537
+ </ArticleLayout>
1538
+ </Article>
1539
+ );
1540
+ }
1541
+ `;
1542
+ }
1543
+ function renderer(preset) {
1544
+ if (!preset.theme) return bareRenderer();
1545
+ const hasHeader = preset.appFiles.includes("header");
1546
+ const hasColorMode = preset.plugins.some(
1547
+ (plugin) => plugin.package === "@riebeckite/plugin-color-mode"
1548
+ );
1549
+ return `import type { PluginHeadTag } from "@riebeckite/core";
1550
+ import { jsxRenderer } from "hono/jsx-renderer";
1551
+ import { Link, Script } from "honox/server";
1552
+ ${hasColorMode ? `import { ColorModeScript } from "@riebeckite/plugin-color-mode";
1553
+ ` : ""}${hasHeader ? `import { SiteHeader } from "../components/site-header";
1554
+ ` : ""}import { config } from "../config";
1555
+
1556
+ function themeAttributes() {
1557
+ const { theme } = config;
1558
+
1559
+ return {
1560
+ ...theme.attributes,
1561
+ "data-theme": theme.colorMode === "system" ? undefined : theme.colorMode,
1562
+ "data-theme-name": theme.name,
1563
+ "data-typography": theme.typography,
1564
+ "data-article-layout": theme.articleLayout,
1565
+ };
1566
+ }
1567
+
1568
+ export default jsxRenderer(({ children }, c) => {
1569
+ const headTags: readonly PluginHeadTag[] = c.get("headTags") ?? [];
1570
+
1571
+ return (
1572
+ <html
1573
+ lang={c.get("htmlLanguage") ?? config.site.locale}
1574
+ {...themeAttributes()}
1575
+ >
1576
+ <head>
1577
+ <meta charset="utf-8" />
1578
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1579
+ <title>{config.site.title}</title>
1580
+ ${hasColorMode ? ` <ColorModeScript />
1581
+ ` : ""} <Link href="/app/style.css" rel="stylesheet" />
1582
+ {headTags.map(renderHeadTag)}
1583
+ <Script src="/app/client.ts" async />
1584
+ </head>
1585
+ <body class="riebeckite-page">
1586
+ ${hasHeader ? ` <SiteHeader />
1587
+ ` : ""} {children}
1588
+ </body>
1589
+ </html>
1590
+ );
1591
+ });
1592
+
1593
+ function renderHeadTag(tag: PluginHeadTag, index: number) {
1594
+ const key = \`\${tag.tag}-\${index}\`;
1595
+ if (tag.tag === "meta") return <meta {...tag.attrs} key={key} />;
1596
+ if (tag.tag === "link") return <link {...tag.attrs} key={key} />;
1597
+ return (
1598
+ <script
1599
+ {...tag.attrs}
1600
+ key={key}
1601
+ dangerouslySetInnerHTML={
1602
+ tag.children ? { __html: tag.children } : undefined
1603
+ }
1604
+ />
1605
+ );
1606
+ }
1607
+ `;
1608
+ }
1609
+ function bareRenderer() {
1610
+ return `import { jsxRenderer } from "hono/jsx-renderer";
1611
+ import { Link, Script } from "honox/server";
1612
+ import { config } from "../config";
1613
+
1614
+ export default jsxRenderer(({ children }, c) => (
1615
+ <html lang={c.get("htmlLanguage") ?? config.site.locale}>
1616
+ <head>
1617
+ <meta charset="utf-8" />
1618
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1619
+ <title>{config.site.title}</title>
1620
+ <Link href="/app/style.css" rel="stylesheet" />
1621
+ <Script src="/app/client.ts" async />
1622
+ </head>
1623
+ <body class="riebeckite-page">{children}</body>
1624
+ </html>
1625
+ ));
1626
+ `;
1627
+ }
1628
+ function indexRoute(preset) {
1629
+ if (!preset.appFiles.includes("article")) return staticIndexRoute();
1630
+ return `import { isPublished } from "@riebeckite/core";
1631
+ import { createRoute } from "honox/factory";
1632
+ import { SiteArticle } from "../components/article";
1633
+ import { config } from "../config";
1634
+ import { content } from "../content";
1635
+
1636
+ export default createRoute(async (c) => {
1637
+ const manifest = await content.getManifest();
1638
+ const indexEntry = manifest.bySlug.get("index");
1639
+ if (indexEntry && indexEntry.permalink !== "/") {
1640
+ return c.redirect(indexEntry.permalink, 308);
1641
+ }
1642
+
1643
+ const post = await content.getProcessedContent("index");
1644
+ if (!isPublished(config, post.frontmatter)) {
1645
+ return c.notFound();
1646
+ }
1647
+
1648
+ if (indexEntry) {
1649
+ c.set("htmlLanguage", indexEntry.publicLocation.metadata?.["l10n.lang"]);
1650
+ c.set("headTags", indexEntry.headTags ?? []);
1651
+ }
1652
+
1653
+ return c.render(
1654
+ <SiteArticle
1655
+ post={post}
1656
+ afterMeta={indexEntry?.bodySlots?.["article.after-meta"]}
1657
+ />,
1658
+ );
1659
+ });
1660
+ `;
1661
+ }
1662
+ function staticIndexRoute() {
1663
+ return `import { createRoute } from "honox/factory";
1664
+ import { config } from "../config";
1665
+
1666
+ export default createRoute((c) =>
1667
+ c.render(
1668
+ <main class="riebeckite-empty">
1669
+ <h1>{config.site.title}</h1>
1670
+ <p>This is a blank Riebeckite site. Add Markdown files under content/ to get started.</p>
1671
+ </main>,
1672
+ ),
1673
+ );
1674
+ `;
1675
+ }
1676
+ function slugRoute() {
1677
+ return `import { isPublished } from "@riebeckite/core";
1678
+ import {
1679
+ contentRouteSsgParams,
1680
+ resolveContentRoute,
1681
+ } from "@riebeckite/honox/server";
1682
+ import { createRoute } from "honox/factory";
1683
+ import { SiteArticle } from "../components/article";
1684
+ import { config } from "../config";
1685
+ import { content } from "../content";
1686
+
1687
+ export default createRoute(
1688
+ contentRouteSsgParams("/:slug{.+}", async () => {
1689
+ const manifest = await content.getManifest();
1690
+ return manifest.entries
1691
+ .filter((entry) => isPublished(config, entry.frontmatter))
1692
+ .filter((entry) => entry.permalink !== "/")
1693
+ .map((entry) => ({ slug: entry.permalink.replace(/^\\/+/, "") }));
1694
+ }),
1695
+ async (c) => {
1696
+ const requestedSlug = c.req.param("slug");
1697
+ if (!requestedSlug) return c.notFound();
1698
+ if (/\\.[a-zA-Z0-9]+$/.test(requestedSlug)) return c.notFound();
1699
+
1700
+ const manifest = await content.getManifest();
1701
+ const route = resolveContentRoute(manifest, c.req.path);
1702
+ if (!route) return c.notFound();
1703
+ if (route.kind === "redirect")
1704
+ return c.redirect(route.location, route.status);
1705
+
1706
+ const post = await content.getProcessedContent(route.entry.slug);
1707
+ if (!isPublished(config, post.frontmatter)) {
1708
+ return c.notFound();
1709
+ }
1710
+
1711
+ c.set("htmlLanguage", route.entry.publicLocation.metadata?.["l10n.lang"]);
1712
+ c.set("headTags", route.entry.headTags ?? []);
1713
+
1714
+ return c.render(
1715
+ <SiteArticle
1716
+ post={post}
1717
+ afterMeta={route.entry.bodySlots?.["article.after-meta"]}
1718
+ />,
1719
+ );
1720
+ },
1721
+ );
1722
+ `;
1723
+ }
1724
+
1725
+ // src/scaffold/localized-content.ts
1726
+ var HELPERS = {
1727
+ en: "https://github.com/Rerurate514/riebeckite/blob/main/docs/en/README.md",
1728
+ ja: "https://github.com/Rerurate514/riebeckite/blob/main/docs/ja/README.md"
1729
+ };
1730
+ var PLUGIN_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/plugins";
1731
+ var THEMES_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/themes";
1732
+ function pluginReadmeUrl(slug) {
1733
+ return `https://github.com/Rerurate514/riebeckite/blob/main/packages/plugins/${slug}/README.md`;
1734
+ }
1735
+ function themeReadmeUrl(slug) {
1736
+ return `https://github.com/Rerurate514/riebeckite/blob/main/packages/themes/${slug}/README.md`;
1737
+ }
1738
+ function localizedContentFiles(variables, preset) {
1739
+ const defaultLang = defaultLanguageForLocale(variables.locale);
1740
+ const files = [];
1741
+ const localized = preset.languages.length > 1;
1742
+ const pushLocalized = (basePath, build2) => {
1743
+ if (!localized) {
1744
+ files.push({
1745
+ path: `content/${basePath}.md`,
1746
+ content: build2(defaultLang)
1747
+ });
1748
+ return;
1749
+ }
1750
+ for (const language of SCAFFOLD_LANGUAGES) {
1751
+ const suffix = language === defaultLang ? "" : `.${language}`;
1752
+ files.push({
1753
+ path: `content/${basePath}${suffix}.md`,
1754
+ content: build2(language)
1755
+ });
1756
+ }
1757
+ };
1758
+ const pushEnglishOnly = (basePath, build2) => {
1759
+ const suffix = defaultLang === "en" ? "" : ".en";
1760
+ files.push({
1761
+ path: `content/${basePath}${suffix}.md`,
1762
+ content: build2()
1763
+ });
1764
+ };
1765
+ for (const page of preset.contentPages) {
1766
+ if (page === "index") {
1767
+ pushLocalized("index", (language) => indexContent(variables, language));
1768
+ } else if (page === "framework/plugins") {
1769
+ pushLocalized(
1770
+ "framework/plugins",
1771
+ (language) => pluginsContent(language)
1772
+ );
1773
+ } else if (page === "framework/themes") {
1774
+ pushLocalized("framework/themes", (language) => themesContent(language));
1775
+ } else if (page === "guide") {
1776
+ pushEnglishOnly("guide", guideContent);
1777
+ } else if (page === "examples") {
1778
+ pushLocalized(
1779
+ "examples",
1780
+ (language) => examplesContent(preset, language)
1781
+ );
1782
+ } else if (page === "reference/plugins") {
1783
+ pushEnglishOnly(
1784
+ "reference/plugins",
1785
+ () => referencePluginsContent(preset, variables)
1786
+ );
1787
+ } else if (page === "reference/themes") {
1788
+ pushEnglishOnly("reference/themes", referenceThemesContent);
1789
+ }
1790
+ }
1791
+ return files;
1792
+ }
1793
+ function read(text, language) {
1794
+ return text[language];
1795
+ }
1796
+ function frontmatter() {
1797
+ return ["---", "publish: true", "---", ""].join("\n");
1798
+ }
1799
+ function heading(level, text) {
1800
+ return `${"#".repeat(level)} ${text}`;
1801
+ }
1802
+ function codeBlock(language, code) {
1803
+ return `\`\`\`${language}
1804
+ ${code}
1805
+ \`\`\`
1806
+ `;
1807
+ }
1808
+ var INDEX = {
1809
+ lead: {
1810
+ en: "Welcome to your Riebeckite site.",
1811
+ ja: "あなたの Riebeckite サイトへようこそ。",
1812
+ "zh-CN": "欢迎来到你的 Riebeckite 站点。",
1813
+ es: "Bienvenido a tu sitio Riebeckite.",
1814
+ de: "Willkommen auf deiner Riebeckite-Seite.",
1815
+ fr: "Bienvenue sur votre site Riebeckite.",
1816
+ ko: "Riebeckite 사이트에 오신 것을 환영합니다."
1817
+ },
1415
1818
  translatedNote: {
1416
1819
  en: "Every page of this starter is available in seven languages. Switch with the selector below the page title.",
1417
1820
  ja: "このスターターのすべてのページは 7 言語で利用できます。ページタイトル下のセレクターで切り替えられます。",
@@ -2305,7 +2708,14 @@ function guideContent() {
2305
2708
  "",
2306
2709
  heading(2, "Run the site"),
2307
2710
  "",
2308
- codeBlock("sh", ["npm install", "npm run dev", "npm run build"].join("\n")),
2711
+ codeBlock(
2712
+ "sh",
2713
+ [
2714
+ "npm install",
2715
+ "npm exec riebeckite dev",
2716
+ "npm exec riebeckite build"
2717
+ ].join("\n")
2718
+ ),
2309
2719
  "",
2310
2720
  heading(2, "Localize a page"),
2311
2721
  "",
@@ -2399,7 +2809,7 @@ function referenceThemesContent() {
2399
2809
  }
2400
2810
 
2401
2811
  // src/scaffold/version.ts
2402
- var RIEBECKITE_VERSION = "^0.0.7";
2812
+ var RIEBECKITE_VERSION = "^0.0.9";
2403
2813
 
2404
2814
  // src/scaffold/templates.ts
2405
2815
  function siteTemplateFiles(preset, variables) {
@@ -2651,7 +3061,13 @@ function tsconfig() {
2651
3061
  `;
2652
3062
  }
2653
3063
  function gitignore() {
2654
- return ["node_modules/", "dist/", ".riebeckite/", ""].join("\n");
3064
+ return [
3065
+ "node_modules/",
3066
+ "dist/",
3067
+ ".riebeckite/",
3068
+ "app/.riebeckite/",
3069
+ ""
3070
+ ].join("\n");
2655
3071
  }
2656
3072
  var REPO = "https://github.com/Rerurate514/riebeckite";
2657
3073
  var README_INTRO = {
@@ -2707,7 +3123,7 @@ var README_WORDS = {
2707
3123
  demoPages: "Try the demos",
2708
3124
  demoPagesBody: "The generated site ships content pages that exercise these features:",
2709
3125
  copyDemos: "Copy-paste demos",
2710
- copyDemosBody: "Paste any of these snippets into a Markdown file under `content/` and run `npm run dev`. Each one renders through a plugin this preset registers."
3126
+ copyDemosBody: "Paste any of these snippets into a Markdown file under `content/` and run `npm exec riebeckite dev`. Each one renders through a plugin this preset registers."
2711
3127
  },
2712
3128
  ja: {
2713
3129
  included: "含まれているもの",
@@ -2731,7 +3147,7 @@ var README_WORDS = {
2731
3147
  demoPages: "デモを試す",
2732
3148
  demoPagesBody: "生成されたサイトには、各機能を体験できるコンテンツページが含まれています:",
2733
3149
  copyDemos: "コピーして使えるデモ",
2734
- copyDemosBody: "以下のスニペットを `content/` 配下の Markdown ファイルに貼り付けて `npm run dev` を実行してください。それぞれ、このプリセットが登録しているプラグインでレンダリングされます。"
3150
+ copyDemosBody: "以下のスニペットを `content/` 配下の Markdown ファイルに貼り付けて `npm exec riebeckite dev` を実行してください。それぞれ、このプリセットが登録しているプラグインでレンダリングされます。"
2735
3151
  }
2736
3152
  };
2737
3153
  function readme(preset, variables) {
@@ -2765,9 +3181,9 @@ function readmeEn(preset, variables) {
2765
3181
  lines.push(
2766
3182
  "```sh",
2767
3183
  "npm install",
2768
- "npm run check",
2769
- "npm run dev",
2770
- "npm run build",
3184
+ "npm exec riebeckite check",
3185
+ "npm exec riebeckite dev",
3186
+ "npm exec riebeckite build",
2771
3187
  "```",
2772
3188
  ""
2773
3189
  );
@@ -2813,9 +3229,9 @@ function readmeJa(preset, variables) {
2813
3229
  lines.push(
2814
3230
  "```sh",
2815
3231
  "npm install",
2816
- "npm run check",
2817
- "npm run dev",
2818
- "npm run build",
3232
+ "npm exec riebeckite check",
3233
+ "npm exec riebeckite dev",
3234
+ "npm exec riebeckite build",
2819
3235
  "```",
2820
3236
  ""
2821
3237
  );
@@ -3074,587 +3490,204 @@ var README_DEMOS = {
3074
3490
  " description: A clean, typographic theme.",
3075
3491
  " meta: v0.0.5",
3076
3492
  " href: https://example.com/themes/default/",
3077
- " - title: Minimal",
3078
- " description: Stripped back to the essentials.",
3079
- " meta: v0.0.5",
3080
- " href: https://example.com/themes/minimal/",
3081
- " - title: Gruvbox",
3082
- " description: A warm, high-contrast palette.",
3083
- " meta: v0.0.5",
3084
- " href: https://example.com/themes/gruvbox/"
3085
- ].join("\n")
3086
- )
3087
- },
3088
- "@riebeckite/plugin-dataview": {
3089
- title: { en: "Dataview", ja: "Dataview" },
3090
- intro: {
3091
- en: "A `dataview` query renders a table of notes from the manifest.",
3092
- ja: "`dataview` クエリがマニフェストからノート一覧を描画します。"
3093
- },
3094
- markdown: fence(
3095
- "dataview",
3096
- [
3097
- 'TABLE file.name AS "Name", status',
3098
- "FROM #project",
3099
- 'WHERE status = "active"',
3100
- "SORT file.name asc",
3101
- "LIMIT 10"
3102
- ].join("\n")
3103
- )
3104
- },
3105
- "@riebeckite/plugin-query": {
3106
- title: { en: "Query", ja: "Query" },
3107
- intro: {
3108
- en: "A `query` fence is YAML that filters and sorts entries from the manifest.",
3109
- ja: "`query` フェンスの YAML でマニフェストのエントリを絞り込み・並べ替えできます。"
3110
- },
3111
- markdown: fence(
3112
- "query",
3113
- [
3114
- "filter:",
3115
- " tags:",
3116
- " any: [diary]",
3117
- "sort:",
3118
- " field: date",
3119
- " order: desc",
3120
- "limit: 5"
3121
- ].join("\n")
3122
- )
3123
- },
3124
- "@riebeckite/plugin-bases": {
3125
- title: { en: "Base views", ja: "Base ビュー" },
3126
- intro: {
3127
- en: "A `base` YAML fence renders a Base table view.",
3128
- ja: "`base` YAML フェンスが Base のテーブルビューを描画します。"
3129
- },
3130
- markdown: fence(
3131
- "base",
3132
- [
3133
- "filters:",
3134
- " and:",
3135
- ' - file.hasTag("featured")',
3136
- "properties:",
3137
- " file.name:",
3138
- " displayName: Title",
3139
- "views:",
3140
- " - type: table",
3141
- " name: Featured",
3142
- " limit: 10"
3143
- ].join("\n")
3144
- )
3145
- },
3146
- "@riebeckite/plugin-kanban": {
3147
- title: { en: "Kanban boards", ja: "カンバンボード" },
3148
- intro: {
3149
- en: "A note whose body is `##` columns of task lists becomes a board; `#tags` and `[[wikilinks]]` work inside cards.",
3150
- ja: "本文が `##` 列とタスクリストでできたノートはボードになります。カード内では `#タグ` や `[[ウィキリンク]]` も使えます。"
3151
- },
3152
- markdown: fence(
3153
- "md",
3154
- [
3155
- "## Backlog",
3156
- "",
3157
- "- [ ] Draft the release notes",
3158
- "- [ ] Link to [[index]]",
3159
- "",
3160
- "## Done",
3161
- "",
3162
- "- [x] Publish the fixture"
3163
- ].join("\n")
3164
- )
3165
- }
3166
- };
3167
- var README_PAGE_LINKS = {
3168
- "framework/plugins": { en: "Plugin tour", ja: "プラグインツアー" },
3169
- "framework/themes": { en: "Theme tour", ja: "テーマツアー" },
3170
- guide: { en: "Getting-started guide", ja: "はじめにガイド" },
3171
- examples: { en: "Examples", ja: "サンプル集" },
3172
- "reference/plugins": { en: "Plugin reference", ja: "プラグインリファレンス" },
3173
- "reference/themes": { en: "Theme reference", ja: "テーマリファレンス" }
3174
- };
3175
- var ENGLISH_ONLY_PAGES = /* @__PURE__ */ new Set([
3176
- "guide",
3177
- "reference/plugins",
3178
- "reference/themes"
3179
- ]);
3180
- function fence(language, body) {
3181
- const tick = "```";
3182
- return `${tick}${language}
3183
- ${body}
3184
- ${tick}`;
3185
- }
3186
- function hasPlugin(preset, packageName) {
3187
- return preset.plugins.some((plugin) => plugin.package === packageName);
3188
- }
3189
- function demoPackage(key) {
3190
- return key.split("/", 2).join("/");
3191
- }
3192
- function readmePluginOptions(variables, preset, plugin) {
3193
- return renderOptions(plugin.options, optionContext(preset, variables));
3194
- }
3195
- function configurationReferenceLines(preset, variables, words) {
3196
- const lines = [
3197
- `## ${words.configReference}`,
3198
- "",
3199
- words.configReferenceBody,
3200
- ""
3201
- ];
3202
- if (preset.theme) {
3203
- const themeCall = preset.theme.options ? `${preset.theme.factory}(${preset.theme.options})` : `${preset.theme.factory}()`;
3204
- lines.push(`- **${words.theme}**: \`${themeCall}\``, "");
3205
- }
3206
- lines.push(
3207
- `| Package | ${words.factory} | ${words.options} |`,
3208
- "| --- | --- | --- |"
3209
- );
3210
- for (const plugin of preset.plugins) {
3211
- const options = readmePluginOptions(variables, preset, plugin);
3212
- const cell = options === null ? words.emDash : `\`${options}\``;
3213
- lines.push(`| \`${plugin.package}\` | \`${plugin.factory}\` | ${cell} |`);
3214
- }
3215
- lines.push("");
3216
- return lines;
3217
- }
3218
- function demoPagesLines(preset, variables, words, language) {
3219
- const lines = [
3220
- `## ${words.demoPages}`,
3221
- "",
3222
- words.demoPagesBody,
3223
- ""
3224
- ];
3225
- const defaultLang = defaultLanguageForLocale(variables.locale);
3226
- const pages = preset.contentPages.filter((page) => page !== "index");
3227
- for (const page of pages) {
3228
- const label = README_PAGE_LINKS[page]?.[language] ?? `/${page}/`;
3229
- const suffix = ENGLISH_ONLY_PAGES.has(page) && defaultLang !== "en" ? ".en" : "";
3230
- const source = `content/${page}${suffix}.md`;
3231
- const url = `/${page}/`;
3232
- lines.push(`- [**${label}**](${source}) — live at [\`${url}\`](${url})`);
3233
- }
3234
- lines.push("");
3235
- return lines;
3236
- }
3237
- var README_DEMO_ORDER = [
3238
- "@riebeckite/plugin-obsidian-markdown/callout",
3239
- "@riebeckite/plugin-obsidian-markdown/wikilinks",
3240
- "@riebeckite/plugin-code-enhance",
3241
- "@riebeckite/plugin-code-tabs",
3242
- "@riebeckite/plugin-mermaid",
3243
- "@riebeckite/plugin-d2",
3244
- "@riebeckite/plugin-graphviz",
3245
- "@riebeckite/plugin-chartjs",
3246
- "@riebeckite/plugin-vega-lite",
3247
- "@riebeckite/plugin-wavedrom",
3248
- "@riebeckite/plugin-markmap",
3249
- "@riebeckite/plugin-map",
3250
- "@riebeckite/plugin-marp",
3251
- "@riebeckite/plugin-qr-code",
3252
- "@riebeckite/plugin-rich-embed",
3253
- "@riebeckite/plugin-gallery",
3254
- "@riebeckite/plugin-dataview",
3255
- "@riebeckite/plugin-query",
3256
- "@riebeckite/plugin-bases",
3257
- "@riebeckite/plugin-kanban"
3258
- ];
3259
- function copyPasteDemoLines(preset, words, language) {
3260
- const lines = [
3261
- `## ${words.copyDemos}`,
3262
- "",
3263
- words.copyDemosBody,
3264
- ""
3265
- ];
3266
- for (const key of README_DEMO_ORDER) {
3267
- const packageName = demoPackage(key);
3268
- if (!hasPlugin(preset, packageName)) continue;
3269
- const demo = README_DEMOS[key];
3270
- lines.push(`### ${demo.title[language]}`, "");
3271
- lines.push(demo.intro[language], "");
3272
- lines.push(demo.markdown, "");
3273
- }
3274
- return lines;
3275
- }
3276
- function server() {
3277
- return `import { mountRiebeckiteEndpoints } from "@riebeckite/honox/server";
3278
- import { createApp } from "honox/server";
3279
- import { config } from "./config";
3280
- import { content } from "./content";
3281
-
3282
- const app = createApp({
3283
- init: (app) => {
3284
- mountRiebeckiteEndpoints(app, { config, content });
3285
- },
3286
- });
3287
-
3288
- export default app;
3289
- export { config, content };
3290
- `;
3291
- }
3292
- function client() {
3293
- return `import { initRiebeckiteClient } from "virtual:riebeckite/client";
3294
- import { createClient } from "honox/client";
3295
-
3296
- createClient();
3297
-
3298
- if (document.readyState === "loading") {
3299
- document.addEventListener("DOMContentLoaded", initPage, { once: true });
3300
- } else {
3301
- initPage();
3302
- }
3303
-
3304
- function initPage() {
3305
- initRiebeckiteClient();
3306
- }
3307
- `;
3308
- }
3309
- function appConfig() {
3310
- return `import path from "node:path";
3311
- import { fileURLToPath } from "node:url";
3312
- import { resolveConfigModule } from "@riebeckite/core";
3313
- import * as rawConfigModule from "../riebeckite.config";
3314
-
3315
- const appRoot =
3316
- process.env.RIEBECKITE_APP_ROOT ??
3317
- fileURLToPath(new URL("../", import.meta.url));
3318
- const resolvedConfig = resolveConfigModule(rawConfigModule);
3319
-
3320
- export const config = {
3321
- ...resolvedConfig,
3322
- content: {
3323
- ...resolvedConfig.content,
3324
- directory: path.resolve(appRoot, resolvedConfig.content.directory),
3493
+ " - title: Minimal",
3494
+ " description: Stripped back to the essentials.",
3495
+ " meta: v0.0.5",
3496
+ " href: https://example.com/themes/minimal/",
3497
+ " - title: Gruvbox",
3498
+ " description: A warm, high-contrast palette.",
3499
+ " meta: v0.0.5",
3500
+ " href: https://example.com/themes/gruvbox/"
3501
+ ].join("\n")
3502
+ )
3325
3503
  },
3326
- };
3327
- `;
3328
- }
3329
- function appContent() {
3330
- return `import { ContentManager } from "@riebeckite/core";
3331
- import { config } from "./config";
3332
- import { CONTENT_DIR } from "./constants/paths";
3333
-
3334
- export const content = new ContentManager(
3335
- CONTENT_DIR,
3336
- config.content.exclude,
3337
- {
3338
- config,
3339
- plugins: config.plugins,
3504
+ "@riebeckite/plugin-dataview": {
3505
+ title: { en: "Dataview", ja: "Dataview" },
3506
+ intro: {
3507
+ en: "A `dataview` query renders a table of notes from the manifest.",
3508
+ ja: "`dataview` クエリがマニフェストからノート一覧を描画します。"
3509
+ },
3510
+ markdown: fence(
3511
+ "dataview",
3512
+ [
3513
+ 'TABLE file.name AS "Name", status',
3514
+ "FROM #project",
3515
+ 'WHERE status = "active"',
3516
+ "SORT file.name asc",
3517
+ "LIMIT 10"
3518
+ ].join("\n")
3519
+ )
3340
3520
  },
3341
- );
3342
- `;
3343
- }
3344
- function paths() {
3345
- return `import path from "node:path";
3346
- import { fileURLToPath } from "node:url";
3347
- import { config } from "../config";
3348
-
3349
- const appRoot =
3350
- process.env.RIEBECKITE_APP_ROOT ??
3351
- fileURLToPath(new URL("../../", import.meta.url));
3352
-
3353
- export const CONTENT_DIR = path.resolve(appRoot, config.content.directory);
3354
- export const ASSETS_ROOT = "public/";
3355
- `;
3356
- }
3357
- function globalDeclarations() {
3358
- return `import type { PluginHeadTag } from "@riebeckite/core";
3359
-
3360
- declare module "virtual:riebeckite/client" {
3361
- export function initRiebeckiteClient(): void;
3362
- }
3363
-
3364
- declare module "hono" {
3365
- interface Env {
3366
- Variables: {
3367
- headTags?: readonly PluginHeadTag[];
3368
- htmlLanguage?: string;
3369
- };
3370
- Bindings: Record<string, never>;
3371
- }
3372
- }
3373
- `;
3374
- }
3375
- function style(preset) {
3376
- const imports = [];
3377
- if (preset.plugins.length > 0) {
3378
- imports.push('@import "./.riebeckite/plugin-styles.css";');
3379
- }
3380
- if (preset.theme) {
3381
- imports.push('@import "./.riebeckite/theme-styles.css";');
3382
- }
3383
- const blocks = [
3384
- "",
3385
- "body {",
3386
- " margin: 0;",
3387
- " font-family: system-ui, sans-serif;",
3388
- "}",
3389
- ""
3390
- ];
3391
- if (preset.appFiles.includes("header")) {
3392
- blocks.push(
3393
- ".site-header {",
3394
- " display: flex;",
3395
- " align-items: center;",
3396
- " justify-content: space-between;",
3397
- " gap: 1rem;",
3398
- " padding: 1rem;",
3399
- " border-bottom: 1px solid #d1d5db;",
3400
- "}",
3401
- "",
3402
- ".site-header__home {",
3403
- " color: #111827;",
3404
- " font-weight: 700;",
3405
- " text-decoration: none;",
3406
- "}",
3407
- ""
3408
- );
3409
- }
3410
- if (preset.appFiles.includes("article")) {
3411
- blocks.push(
3412
- ".site-article {",
3413
- " display: block;",
3414
- " max-width: 48rem;",
3415
- " padding: 2rem 1rem;",
3416
- " margin: 0 auto;",
3417
- "}",
3418
- ""
3419
- );
3420
- }
3421
- if (!preset.theme) {
3422
- blocks.push(
3423
- ".riebeckite-empty {",
3424
- " max-width: 48rem;",
3425
- " padding: 4rem 1rem;",
3426
- " margin: 0 auto;",
3427
- "}",
3428
- ""
3429
- );
3430
- }
3431
- return [...imports, ...blocks].join("\n");
3432
- }
3433
- function siteHeader() {
3434
- return `import { ColorModeToggle } from "@riebeckite/plugin-color-mode";
3435
- import { config } from "../config";
3436
-
3437
- export function SiteHeader() {
3438
- return (
3439
- <header class="site-header">
3440
- <a href="/" class="site-header__home">
3441
- {config.site.title}
3442
- </a>
3443
- <ColorModeToggle />
3444
- </header>
3445
- );
3446
- }
3447
- `;
3448
- }
3449
- function article() {
3450
- return `import type { PostContent } from "@riebeckite/core";
3451
- import { Article, ArticleContent, ArticleLayout } from "@riebeckite/honox/ui";
3452
-
3453
- export function SiteArticle({
3454
- post,
3455
- afterMeta,
3456
- }: {
3457
- post: PostContent;
3458
- afterMeta?: string;
3459
- }) {
3460
- return (
3461
- <Article class="site-article">
3462
- <ArticleLayout>
3463
- <ArticleContent>
3464
- {afterMeta ? (
3465
- <div
3466
- class="site-article__after-meta"
3467
- dangerouslySetInnerHTML={{ __html: afterMeta }}
3468
- />
3469
- ) : null}
3470
- <div dangerouslySetInnerHTML={{ __html: post.html ?? "" }} />
3471
- </ArticleContent>
3472
- </ArticleLayout>
3473
- </Article>
3474
- );
3475
- }
3476
- `;
3477
- }
3478
- function renderer(preset) {
3479
- if (!preset.theme) return bareRenderer();
3480
- const hasHeader = preset.appFiles.includes("header");
3481
- const hasColorMode = preset.plugins.some(
3482
- (plugin) => plugin.package === "@riebeckite/plugin-color-mode"
3483
- );
3484
- return `import type { PluginHeadTag } from "@riebeckite/core";
3485
- import { jsxRenderer } from "hono/jsx-renderer";
3486
- import { Link, Script } from "honox/server";
3487
- ${hasColorMode ? `import { ColorModeScript } from "@riebeckite/plugin-color-mode";
3488
- ` : ""}${hasHeader ? `import { SiteHeader } from "../components/site-header";
3489
- ` : ""}import { config } from "../config";
3490
-
3491
- function themeAttributes() {
3492
- const { theme } = config;
3493
-
3494
- return {
3495
- ...theme.attributes,
3496
- "data-theme": theme.colorMode === "system" ? undefined : theme.colorMode,
3497
- "data-theme-name": theme.name,
3498
- "data-typography": theme.typography,
3499
- "data-article-layout": theme.articleLayout,
3500
- };
3521
+ "@riebeckite/plugin-query": {
3522
+ title: { en: "Query", ja: "Query" },
3523
+ intro: {
3524
+ en: "A `query` fence is YAML that filters and sorts entries from the manifest.",
3525
+ ja: "`query` フェンスの YAML でマニフェストのエントリを絞り込み・並べ替えできます。"
3526
+ },
3527
+ markdown: fence(
3528
+ "query",
3529
+ [
3530
+ "filter:",
3531
+ " tags:",
3532
+ " any: [diary]",
3533
+ "sort:",
3534
+ " field: date",
3535
+ " order: desc",
3536
+ "limit: 5"
3537
+ ].join("\n")
3538
+ )
3539
+ },
3540
+ "@riebeckite/plugin-bases": {
3541
+ title: { en: "Base views", ja: "Base ビュー" },
3542
+ intro: {
3543
+ en: "A `base` YAML fence renders a Base table view.",
3544
+ ja: "`base` YAML フェンスが Base のテーブルビューを描画します。"
3545
+ },
3546
+ markdown: fence(
3547
+ "base",
3548
+ [
3549
+ "filters:",
3550
+ " and:",
3551
+ ' - file.hasTag("featured")',
3552
+ "properties:",
3553
+ " file.name:",
3554
+ " displayName: Title",
3555
+ "views:",
3556
+ " - type: table",
3557
+ " name: Featured",
3558
+ " limit: 10"
3559
+ ].join("\n")
3560
+ )
3561
+ },
3562
+ "@riebeckite/plugin-kanban": {
3563
+ title: { en: "Kanban boards", ja: "カンバンボード" },
3564
+ intro: {
3565
+ en: "A note whose body is `##` columns of task lists becomes a board; `#tags` and `[[wikilinks]]` work inside cards.",
3566
+ ja: "本文が `##` 列とタスクリストでできたノートはボードになります。カード内では `#タグ` や `[[ウィキリンク]]` も使えます。"
3567
+ },
3568
+ markdown: fence(
3569
+ "md",
3570
+ [
3571
+ "## Backlog",
3572
+ "",
3573
+ "- [ ] Draft the release notes",
3574
+ "- [ ] Link to [[index]]",
3575
+ "",
3576
+ "## Done",
3577
+ "",
3578
+ "- [x] Publish the fixture"
3579
+ ].join("\n")
3580
+ )
3581
+ }
3582
+ };
3583
+ var README_PAGE_LINKS = {
3584
+ "framework/plugins": { en: "Plugin tour", ja: "プラグインツアー" },
3585
+ "framework/themes": { en: "Theme tour", ja: "テーマツアー" },
3586
+ guide: { en: "Getting-started guide", ja: "はじめにガイド" },
3587
+ examples: { en: "Examples", ja: "サンプル集" },
3588
+ "reference/plugins": { en: "Plugin reference", ja: "プラグインリファレンス" },
3589
+ "reference/themes": { en: "Theme reference", ja: "テーマリファレンス" }
3590
+ };
3591
+ var ENGLISH_ONLY_PAGES = /* @__PURE__ */ new Set([
3592
+ "guide",
3593
+ "reference/plugins",
3594
+ "reference/themes"
3595
+ ]);
3596
+ function fence(language, body) {
3597
+ const tick = "```";
3598
+ return `${tick}${language}
3599
+ ${body}
3600
+ ${tick}`;
3501
3601
  }
3502
-
3503
- export default jsxRenderer(({ children }, c) => {
3504
- const headTags: readonly PluginHeadTag[] = c.get("headTags") ?? [];
3505
-
3506
- return (
3507
- <html
3508
- lang={c.get("htmlLanguage") ?? config.site.locale}
3509
- {...themeAttributes()}
3510
- >
3511
- <head>
3512
- <meta charset="utf-8" />
3513
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
3514
- <title>{config.site.title}</title>
3515
- ${hasColorMode ? ` <ColorModeScript />
3516
- ` : ""} <Link href="/app/style.css" rel="stylesheet" />
3517
- {headTags.map(renderHeadTag)}
3518
- <Script src="/app/client.ts" async />
3519
- </head>
3520
- <body class="riebeckite-page">
3521
- ${hasHeader ? ` <SiteHeader />
3522
- ` : ""} {children}
3523
- </body>
3524
- </html>
3525
- );
3526
- });
3527
-
3528
- function renderHeadTag(tag: PluginHeadTag, index: number) {
3529
- const key = \`\${tag.tag}-\${index}\`;
3530
- if (tag.tag === "meta") return <meta {...tag.attrs} key={key} />;
3531
- if (tag.tag === "link") return <link {...tag.attrs} key={key} />;
3532
- return (
3533
- <script
3534
- {...tag.attrs}
3535
- key={key}
3536
- dangerouslySetInnerHTML={
3537
- tag.children ? { __html: tag.children } : undefined
3538
- }
3539
- />
3540
- );
3602
+ function hasPlugin(preset, packageName) {
3603
+ return preset.plugins.some((plugin) => plugin.package === packageName);
3541
3604
  }
3542
- `;
3605
+ function demoPackage(key) {
3606
+ return key.split("/", 2).join("/");
3543
3607
  }
3544
- function bareRenderer() {
3545
- return `import { jsxRenderer } from "hono/jsx-renderer";
3546
- import { Link, Script } from "honox/server";
3547
- import { config } from "../config";
3548
-
3549
- export default jsxRenderer(({ children }, c) => (
3550
- <html lang={c.get("htmlLanguage") ?? config.site.locale}>
3551
- <head>
3552
- <meta charset="utf-8" />
3553
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
3554
- <title>{config.site.title}</title>
3555
- <Link href="/app/style.css" rel="stylesheet" />
3556
- <Script src="/app/client.ts" async />
3557
- </head>
3558
- <body class="riebeckite-page">{children}</body>
3559
- </html>
3560
- ));
3561
- `;
3608
+ function readmePluginOptions(variables, preset, plugin) {
3609
+ return renderOptions(plugin.options, optionContext(preset, variables));
3562
3610
  }
3563
- function indexRoute(preset) {
3564
- if (!preset.appFiles.includes("article")) return staticIndexRoute();
3565
- return `import { isPublished } from "@riebeckite/core";
3566
- import { createRoute } from "honox/factory";
3567
- import { SiteArticle } from "../components/article";
3568
- import { config } from "../config";
3569
- import { content } from "../content";
3570
-
3571
- export default createRoute(async (c) => {
3572
- const manifest = await content.getManifest();
3573
- const indexEntry = manifest.bySlug.get("index");
3574
- if (indexEntry && indexEntry.permalink !== "/") {
3575
- return c.redirect(indexEntry.permalink, 308);
3576
- }
3577
-
3578
- const post = await content.getProcessedContent("index");
3579
- if (!isPublished(config, post.frontmatter)) {
3580
- return c.notFound();
3581
- }
3582
-
3583
- if (indexEntry) {
3584
- c.set("htmlLanguage", indexEntry.publicLocation.metadata?.["l10n.lang"]);
3585
- c.set("headTags", indexEntry.headTags ?? []);
3611
+ function configurationReferenceLines(preset, variables, words) {
3612
+ const lines = [
3613
+ `## ${words.configReference}`,
3614
+ "",
3615
+ words.configReferenceBody,
3616
+ ""
3617
+ ];
3618
+ if (preset.theme) {
3619
+ const themeCall = preset.theme.options ? `${preset.theme.factory}(${preset.theme.options})` : `${preset.theme.factory}()`;
3620
+ lines.push(`- **${words.theme}**: \`${themeCall}\``, "");
3586
3621
  }
3587
-
3588
- return c.render(
3589
- <SiteArticle
3590
- post={post}
3591
- afterMeta={indexEntry?.bodySlots?.["article.after-meta"]}
3592
- />,
3622
+ lines.push(
3623
+ `| Package | ${words.factory} | ${words.options} |`,
3624
+ "| --- | --- | --- |"
3593
3625
  );
3594
- });
3595
- `;
3626
+ for (const plugin of preset.plugins) {
3627
+ const options = readmePluginOptions(variables, preset, plugin);
3628
+ const cell = options === null ? words.emDash : `\`${options}\``;
3629
+ lines.push(`| \`${plugin.package}\` | \`${plugin.factory}\` | ${cell} |`);
3630
+ }
3631
+ lines.push("");
3632
+ return lines;
3596
3633
  }
3597
- function staticIndexRoute() {
3598
- return `import { createRoute } from "honox/factory";
3599
- import { config } from "../config";
3600
-
3601
- export default createRoute((c) =>
3602
- c.render(
3603
- <main class="riebeckite-empty">
3604
- <h1>{config.site.title}</h1>
3605
- <p>This is a blank Riebeckite site. Add Markdown files under content/ to get started.</p>
3606
- </main>,
3607
- ),
3608
- );
3609
- `;
3634
+ function demoPagesLines(preset, variables, words, language) {
3635
+ const lines = [
3636
+ `## ${words.demoPages}`,
3637
+ "",
3638
+ words.demoPagesBody,
3639
+ ""
3640
+ ];
3641
+ const defaultLang = defaultLanguageForLocale(variables.locale);
3642
+ const pages = preset.contentPages.filter((page) => page !== "index");
3643
+ for (const page of pages) {
3644
+ const label = README_PAGE_LINKS[page]?.[language] ?? `/${page}/`;
3645
+ const suffix = ENGLISH_ONLY_PAGES.has(page) && defaultLang !== "en" ? ".en" : "";
3646
+ const source = `content/${page}${suffix}.md`;
3647
+ const url = `/${page}/`;
3648
+ lines.push(`- [**${label}**](${source}) — live at [\`${url}\`](${url})`);
3649
+ }
3650
+ lines.push("");
3651
+ return lines;
3610
3652
  }
3611
- function slugRoute() {
3612
- return `import { isPublished } from "@riebeckite/core";
3613
- import {
3614
- contentRouteSsgParams,
3615
- resolveContentRoute,
3616
- } from "@riebeckite/honox/server";
3617
- import { createRoute } from "honox/factory";
3618
- import { SiteArticle } from "../components/article";
3619
- import { config } from "../config";
3620
- import { content } from "../content";
3621
-
3622
- export default createRoute(
3623
- contentRouteSsgParams("/:slug{.+}", async () => {
3624
- const manifest = await content.getManifest();
3625
- return manifest.entries
3626
- .filter((entry) => isPublished(config, entry.frontmatter))
3627
- .filter((entry) => entry.permalink !== "/")
3628
- .map((entry) => ({ slug: entry.permalink.replace(/^\\/+/, "") }));
3629
- }),
3630
- async (c) => {
3631
- const requestedSlug = c.req.param("slug");
3632
- if (!requestedSlug) return c.notFound();
3633
- if (/\\.[a-zA-Z0-9]+$/.test(requestedSlug)) return c.notFound();
3634
-
3635
- const manifest = await content.getManifest();
3636
- const route = resolveContentRoute(manifest, c.req.path);
3637
- if (!route) return c.notFound();
3638
- if (route.kind === "redirect")
3639
- return c.redirect(route.location, route.status);
3640
-
3641
- const post = await content.getProcessedContent(route.entry.slug);
3642
- if (!isPublished(config, post.frontmatter)) {
3643
- return c.notFound();
3644
- }
3645
-
3646
- c.set("htmlLanguage", route.entry.publicLocation.metadata?.["l10n.lang"]);
3647
- c.set("headTags", route.entry.headTags ?? []);
3648
-
3649
- return c.render(
3650
- <SiteArticle
3651
- post={post}
3652
- afterMeta={route.entry.bodySlots?.["article.after-meta"]}
3653
- />,
3654
- );
3655
- },
3656
- );
3657
- `;
3653
+ var README_DEMO_ORDER = [
3654
+ "@riebeckite/plugin-obsidian-markdown/callout",
3655
+ "@riebeckite/plugin-obsidian-markdown/wikilinks",
3656
+ "@riebeckite/plugin-code-enhance",
3657
+ "@riebeckite/plugin-code-tabs",
3658
+ "@riebeckite/plugin-mermaid",
3659
+ "@riebeckite/plugin-d2",
3660
+ "@riebeckite/plugin-graphviz",
3661
+ "@riebeckite/plugin-chartjs",
3662
+ "@riebeckite/plugin-vega-lite",
3663
+ "@riebeckite/plugin-wavedrom",
3664
+ "@riebeckite/plugin-markmap",
3665
+ "@riebeckite/plugin-map",
3666
+ "@riebeckite/plugin-marp",
3667
+ "@riebeckite/plugin-qr-code",
3668
+ "@riebeckite/plugin-rich-embed",
3669
+ "@riebeckite/plugin-gallery",
3670
+ "@riebeckite/plugin-dataview",
3671
+ "@riebeckite/plugin-query",
3672
+ "@riebeckite/plugin-bases",
3673
+ "@riebeckite/plugin-kanban"
3674
+ ];
3675
+ function copyPasteDemoLines(preset, words, language) {
3676
+ const lines = [
3677
+ `## ${words.copyDemos}`,
3678
+ "",
3679
+ words.copyDemosBody,
3680
+ ""
3681
+ ];
3682
+ for (const key of README_DEMO_ORDER) {
3683
+ const packageName = demoPackage(key);
3684
+ if (!hasPlugin(preset, packageName)) continue;
3685
+ const demo = README_DEMOS[key];
3686
+ lines.push(`### ${demo.title[language]}`, "");
3687
+ lines.push(demo.intro[language], "");
3688
+ lines.push(demo.markdown, "");
3689
+ }
3690
+ return lines;
3658
3691
  }
3659
3692
 
3660
3693
  // src/scaffold/index.ts
@@ -3700,7 +3733,7 @@ async function assertTargetWritable(targetDirectory, files, overwrite) {
3700
3733
  try {
3701
3734
  entries = await fs6.readdir(targetDirectory);
3702
3735
  } catch (error) {
3703
- if (isNotFoundError(error)) return;
3736
+ if (isNotFoundError2(error)) return;
3704
3737
  throw error;
3705
3738
  }
3706
3739
  const conflicts = entries.filter(
@@ -3718,7 +3751,7 @@ function normalizePackageName(value) {
3718
3751
  const normalized = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[-_.]+/, "").replace(/[-_.]+$/, "");
3719
3752
  return normalized || "riebeckite-site";
3720
3753
  }
3721
- function isNotFoundError(error) {
3754
+ function isNotFoundError2(error) {
3722
3755
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3723
3756
  }
3724
3757
 
@@ -3729,9 +3762,9 @@ function formatScaffoldNextSteps(relativeDirectory) {
3729
3762
  lines.push(` cd ${relativeDirectory}`);
3730
3763
  }
3731
3764
  lines.push(" npm install");
3732
- lines.push(" npm run check");
3733
- lines.push(" npm run dev");
3734
- lines.push(" npm run build");
3765
+ lines.push(" npm exec riebeckite check");
3766
+ lines.push(" npm exec riebeckite dev");
3767
+ lines.push(" npm exec riebeckite build");
3735
3768
  return lines.join("\n");
3736
3769
  }
3737
3770
  export {