serve-my-md 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serve-my-md",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "type": "module",
5
5
  "description": "Generate beautiful SEO-friendly static websites from Markdown files.",
6
6
  "repository": {
@@ -67,7 +67,6 @@
67
67
  "prettier": "^3.6.2",
68
68
  "tsup": "^8.5.1",
69
69
  "typescript": "^5.9.3",
70
- "vite": "^7.1.7",
71
70
  "vite-tsconfig-paths": "^6.1.1",
72
71
  "vitest": "^4.0.15",
73
72
  "web-vitals": "^5.1.0"
@@ -102,7 +101,8 @@
102
101
  "react-hotkeys-hook": "^5.2.1",
103
102
  "tailwind-merge": "^3.0.2",
104
103
  "tailwindcss": "^4.0.6",
105
- "tw-animate-css": "^1.3.6"
104
+ "tw-animate-css": "^1.3.6",
105
+ "vite": "^8.0.16"
106
106
  },
107
107
  "volta": {
108
108
  "node": "26.1.0",
package/web/index.html CHANGED
@@ -7,14 +7,15 @@
7
7
  <meta name="theme-color" content="#000000" />
8
8
  <meta
9
9
  name="description"
10
- content="Docs for serve-my-md."
10
+ content="A fixture for testing ghostly operations in SMM."
11
11
  />
12
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&display=swap" /><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Commissioner:wght@100..900&display=swap" /><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&display=swap" />
13
- <meta property="og:title" content="Serve My MD Docs">
14
- <meta property="og:description" content="Documentation for serve-my-md, a CLI tool to generate static docs sites from markdown.">
15
- <meta property="og:type" content="website">
16
- <meta property="og:site_name" content="Serve My MD Docs">
17
- <title>Serve My MD Docs</title>
12
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sorts+Mill+Goudy:ital@0;1&display=swap" /><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" />
13
+ <meta property="og:title" content="SMM Ghostly Fixture">
14
+ <meta property="og:description" content="A fixture for testing ghostly operations in SMM.">
15
+ <meta property="og:site_name" content="SMM Ghostly Store">
16
+ <meta property="og:determiner" content="the">
17
+ <meta property="og:image" content="/og-image.png">
18
+ <title>SMM Ghostly Fixture</title>
18
19
 
19
20
 
20
21
  <style>
@@ -1 +1 @@
1
- {"rootTitle":"Serve My MD Docs","description":"Docs for serve-my-md.","baseRoute":"/","defaultTheme":"dark","name":"Serve My MD","showNameWithLogo":true,"routes":[{"path":"/","content":"<h1>serve-my-md Docs</h1>\n<p>Welcome to the docs for <code>serve-my-md</code>.</p>\n<p>A tiny CLI to generate a static docs website from markdown files.</p>\n<ul>\n<li><a href=\"/why-serve-my-md\">Why serve-my-md?</a></li>\n<li><a href=\"/getting-started\">Getting Started</a></li>\n<li><a href=\"/cli-reference\">CLI Reference</a></li>\n<li><a href=\"/key-behaviors\">Key Behaviors</a></li>\n</ul>\n<h3>Guide</h3>\n<ul>\n<li><a href=\"/routing-and-sidebar-patterns\">Routing and Sidebar Patterns</a></li>\n<li><a href=\"/markdown-and-rendering\">Markdown and Rendering</a></li>\n<li><a href=\"/build-output-and-assets\">Build Output and Assets</a></li>\n</ul>\n<h3>Configuration</h3>\n<ul>\n<li><a href=\"/smm-config\">SMM Config</a></li>\n<li><a href=\"/smm-ignore\">SMM Ignore</a></li>\n</ul>\n<h3>Examples</h3>\n<ul>\n<li><a href=\"/structure-examples\">Structure Examples</a></li>\n<li><a href=\"/config-examples\">Config Examples</a></li>\n</ul>\n<h2>Future goals</h2>\n<ul>\n<li><strong>Search Indexing</strong> — structured search index for smarter results</li>\n<li><strong>Config validation</strong> — Zod-based schema validation of <code>smm.config.json</code> with JSON Schema export</li>\n<li><strong>Sitemap</strong> — automatic <code>sitemap.xml</code> generation</li>\n<li><strong>Per-page Open Graph</strong> — page-level og tags from frontmatter</li>\n<li><strong>Doctor command</strong> — health checks: config validation, route discovery, broken link detection, and more</li>\n<li><strong>Link validation</strong> — flag invalid internal links at build-time</li>\n<li><strong>Optional RSS</strong> — config-enableable RSS feed for blog/changelog content</li>\n<li><strong>SchemaStore upload</strong> — publish JSON Schema to SchemaStore once stable</li>\n</ul>\n"},{"path":"/getting-started","content":"<h1>Getting Started</h1>\n<h2>Install</h2>\n<pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i <span class=\"token parameter variable\">-g</span> serve-my-md\n</code></pre>\n<h2>Run</h2>\n<pre class=\"language-bash\"><code class=\"language-bash\">serve-my-md <span class=\"token parameter variable\">--directory</span> <span class=\"token builtin class-name\">.</span>\n</code></pre>\n<p>The CLI scans markdown files in the target directory and generates a static website there. Every page is a standalone HTML file (SSG) — deploy to any static host or CDN.</p>\n<h2>What gets read automatically</h2>\n<ul>\n<li><code>smm.config.json</code> at docs root (if present)</li>\n<li><code>.smmignore</code> at docs root (if present)</li>\n<li>fallback to built-in defaults when these files are missing</li>\n</ul>\n<h2>Important <code>index.md</code> behavior</h2>\n<ul>\n<li><code>index.md</code> is the landing page for its directory.</li>\n<li><code>index</code> is never included in the pathname.</li>\n<li>Internally, an <code>index.md</code> entry is treated as <code>&quot;&quot;</code> (empty string) in route tree naming.</li>\n</ul>\n<p>Example:</p>\n<pre class=\"language-text\"><code class=\"language-text\">docs/\n index.md\n guides/\n index.md\n install.md\n</code></pre>\n<p>Routes:</p>\n<ul>\n<li><code>/</code></li>\n<li><code>/guides</code></li>\n<li><code>/guides/install</code></li>\n</ul>\n<h2>Future goals</h2>\n<ul>\n<li><strong>Search Indexing</strong> — structured search index for smarter results</li>\n<li><strong>Config validation</strong> — Zod-based schema validation of <code>smm.config.json</code> with JSON Schema export</li>\n<li><strong>Sitemap</strong> — automatic <code>sitemap.xml</code> generation</li>\n<li><strong>Per-page Open Graph</strong> — page-level og tags from frontmatter</li>\n<li><strong>Doctor command</strong> — health checks: config validation, route discovery, broken link detection, and more</li>\n<li><strong>Link validation</strong> — flag invalid internal links at build-time</li>\n<li><strong>Optional RSS</strong> — config-enableable RSS feed for blog/changelog content</li>\n<li><strong>SchemaStore upload</strong> — publish JSON Schema to SchemaStore once stable</li>\n</ul>\n"},{"path":"/cli-reference","content":"<h1>CLI Reference</h1>\n<h2>Main command</h2>\n<ul>\n<li><code>serve-my-md</code>: build a static docs website from markdown files.</li>\n</ul>\n<h2>Options</h2>\n<ul>\n<li><code>-d, --directory &lt;path&gt;</code>: docs root path (default <code>.</code>).</li>\n<li><code>-i, --interactive</code>: prompt for docs root.</li>\n</ul>\n<h2>Build output (SSG)</h2>\n<p>The CLI generates a fully static site:</p>\n<ul>\n<li>Each route gets its own <code>.html</code> file with pre-rendered markdown content in the HTML</li>\n<li>Assets (CSS, JS) are built via Vite and placed under <code>dist/assets/</code></li>\n<li>The final <code>dist/</code> directory is copied to your docs root — ready to deploy</li>\n</ul>\n<h2>Config and ignore loading</h2>\n<ul>\n<li>Loads config from <code>./smm.config.json</code> relative to target directory.</li>\n<li>Loads ignore rules from <code>./.smmignore</code> relative to target directory.</li>\n<li>If <code>publicPath</code> is set in config, copies that directory into app public assets before build.</li>\n</ul>\n<h2>Markdown pipeline</h2>\n<ul>\n<li>Uses markdown-it with task lists and footnotes plugins enabled.</li>\n<li>Prism.js syntax highlighting with auto-loading for unknown languages.</li>\n<li>Generates OG/meta/font tags in HTML from config values.</li>\n</ul>\n<h2>Runtime/navigation behaviors</h2>\n<ul>\n<li>Markdown links with non-HTTP hrefs are intercepted and navigated client-side.</li>\n<li>Intent-based link preloading for faster navigation.</li>\n<li>Keyboard shortcuts:\n<ul>\n<li>Search: <code>Ctrl+Shift+F</code></li>\n<li>Next page: <code>Alt+Enter</code></li>\n<li>Previous page: <code>Alt+Shift+Enter</code></li>\n</ul>\n</li>\n<li>Search returns matches in current page and across other pages.</li>\n</ul>\n<h2>Test-only option</h2>\n<ul>\n<li><code>--skip-build</code> exists only in vitest mode, not in normal CLI usage.</li>\n</ul>\n<h2>Future goals</h2>\n<ul>\n<li><strong>Search Indexing</strong> — structured search index for smarter results</li>\n<li><strong>Config validation</strong> — Zod-based schema validation of <code>smm.config.json</code> with JSON Schema export</li>\n<li><strong>Sitemap</strong> — automatic <code>sitemap.xml</code> generation</li>\n<li><strong>Per-page Open Graph</strong> — page-level og tags from frontmatter</li>\n<li><strong>Doctor command</strong> — health checks: config validation, route discovery, broken link detection, and more</li>\n<li><strong>Link validation</strong> — flag invalid internal links at build-time</li>\n<li><strong>Optional RSS</strong> — config-enableable RSS feed for blog/changelog content</li>\n<li><strong>SchemaStore upload</strong> — publish JSON Schema to SchemaStore once stable</li>\n</ul>\n"},{"path":"/key-behaviors","content":"<h1>Key Behaviors</h1>\n<h2>Internal links auto-prepend <code>baseRoute</code></h2>\n<p>When you set a <code>baseRoute</code> in <code>smm.config.json</code> (e.g. <code>/docs</code>), any internal markdown link (<code>[text](/some-page)</code>) automatically has that base prepended during navigation. You never need to manually prefix links with the base route — change it in one place and all links adapt.</p>\n<h2>Sorting and indexing</h2>\n<p>Pages, directories, and groupers are sorted automatically when <code>sortRoutes: true</code>:</p>\n<ol>\n<li><code>index.md</code> always comes first.</li>\n<li>Regular files and directories come next, sorted lexicographically.</li>\n<li>Groupers <code>(Name)</code> come last, after all regular items.</li>\n</ol>\n<p>Numeric prefixes on filenames (<code>1. intro.md</code>, <code>2. setup.md</code>) control ordering within each tier. The prefix is stripped from the emitted URL when <code>trimIndexFromPath: true</code>.</p>\n<p>Grouper indexes only affect order among other groupers — they never collide with file/directory indexes since groupers always sort after regular items.</p>\n<h2>SSG pre-rendering</h2>\n<p>Every page is a standalone <code>.html</code> file with pre-rendered markdown content baked into the DOM. Search engines see the full content immediately. After the page loads, the React SPA hydrates and takes over for seamless client-side navigation.</p>\n<h2>Groupers</h2>\n<p>Directories named <code>(Name)</code> act as groupers:</p>\n<ul>\n<li>Rendered as a labeled section in the sidebar (not collapsible).</li>\n<li>Skipped from URL pathnames — files inside sit at the grouper's parent URL level.</li>\n<li>Cannot contain <code>index.md</code>.</li>\n<li>Can be ordered with numeric prefixes: <code>(1. Guide)</code>, <code>(2. Reference)</code>.</li>\n</ul>\n<h2>Client-side link interception</h2>\n<p>Internal markdown links (<code>[text](/path)</code>) are intercepted by the SPA router — navigating them does not cause a full page reload. External links (<code>https://...</code>) open normally.</p>\n<h2>Intent-based preloading</h2>\n<p>When you hover over or touch a link, its content is preloaded in the background. Navigation feels instant because the data is ready before you click.</p>\n<h2>Auto-slug generation</h2>\n<p>Route path segments are automatically normalized:</p>\n<ul>\n<li>Lowercased</li>\n<li>Spaces and underscores become <code>-</code></li>\n<li>Punctuation (<code>.,;&quot;'\\\\:&lt;&gt;</code>?!`) is removed</li>\n<li>Grouper directory names like <code>(Group)</code> are excluded entirely</li>\n</ul>\n<p>No need to manually craft URL-safe filenames.</p>\n<h2><code>index.md</code> as landing page</h2>\n<ul>\n<li><code>index.md</code> represents the landing page for its directory.</li>\n<li>It is never included in the URL pathname — internally maps to <code>&quot;&quot;</code>.</li>\n<li>If a directory contains only <code>index.md</code> and no other files, it collapses to a leaf node (no collapsible).</li>\n</ul>\n<h2><code>publicPath</code> auto-copy and auto-exclude</h2>\n<p>If <code>publicPath</code> is set in config, that directory is:</p>\n<ul>\n<li>Copied into the web app's public assets before the Vite build.</li>\n<li>Automatically excluded from markdown scanning — no need to also add it to <code>.smmignore</code>.</li>\n</ul>\n<h2>Config merge with sensible defaults</h2>\n<p><code>smm.config.json</code> is merged over built-in defaults. You only need to specify what you want to override. Missing options fall back to the CLI's internal defaults — the config file is entirely optional.</p>\n<h2><code>.smmignore</code> glob patterns</h2>\n<p>Create <code>.smmignore</code> at your docs root to exclude paths during markdown traversal:</p>\n<ul>\n<li>Lines starting with <code>#</code> are comments.</li>\n<li>Empty lines are ignored.</li>\n<li>Prefix with <code>!</code> to un-ignore.</li>\n<li>Patterns are evaluated top-to-bottom, last match wins.</li>\n</ul>\n"},{"path":"/why-serve-my-md","content":"<h1>Why serve-my-md?</h1>\n<h2>Zero-friction static site</h2>\n<p>serve-my-md generates a <strong>completely static site</strong> — every page is a standalone HTML file with pre-rendered content. No server, no database, no build-time backend. Deploy anywhere: CDN, GitHub Pages, Netlify, Vercel, S3, or a simple static file server.</p>\n<h2>Blazing fast</h2>\n<p>Static HTML means instant first paint. After load, the React SPA takes over for seamless client-side navigation with intent-based preloading.</p>\n<h2>Rich markdown support</h2>\n<ul>\n<li>Full markdown-it pipeline with footnotes, task lists, and configurable options</li>\n<li>Prism.js syntax highlighting for dozens of languages</li>\n<li>Configurable markdown-it options via <code>smm.config.json</code></li>\n</ul>\n<h2>Custom ordering</h2>\n<p>Control your page order with numeric filename prefixes:</p>\n<pre class=\"language-text\"><code class=\"language-text\">1. intro.md\n2. setup.md\n3. advanced.md\n</code></pre>\n<p>Set <code>trimIndexFromPath: true</code> in config and the prefixes are stripped from URLs while ordering is preserved.</p>\n<h2>Minimal yet powerful config</h2>\n<p>A single <code>smm.config.json</code> at your docs root is all you need. Override titles, theme, fonts, Open Graph tags, and more — or use the sensible defaults and get going immediately.</p>\n<h2>SEO built-in</h2>\n<p>Every page is a full HTML document with:</p>\n<ul>\n<li>Unique <code>&lt;title&gt;</code> and <code>&lt;meta description&gt;</code></li>\n<li>Open Graph tags for social previews</li>\n<li>Pre-rendered content in the HTML — search engines see everything</li>\n<li>Semantic HTML structure</li>\n</ul>\n<h2>Great user experience</h2>\n<ul>\n<li><strong>Site-wide search</strong> — instant full-text search with keyboard shortcut (Ctrl+Shift+F)</li>\n<li><strong>Accessibility</strong> — keyboard navigation, ARIA labels, semantic landmarks</li>\n<li><strong>Light/dark themes</strong> — automatic or user-toggleable</li>\n<li><strong>Responsive</strong> — works on desktop and mobile</li>\n<li><strong>Breadcrumbs</strong> — clear navigation context</li>\n<li><strong>Keyboard shortcuts</strong> — quick navigation between pages</li>\n</ul>\n"},{"path":"/routing-and-sidebar-patterns","content":"<h1>Routing and Sidebar Patterns</h1>\n<h2><code>index.md</code> is landing page</h2>\n<ul>\n<li><code>index.md</code> represents the landing page for its directory.</li>\n<li><code>index</code> is not part of URL pathnames.</li>\n<li>In nested name handling, <code>index.md</code> maps to <code>&quot;&quot;</code> (empty string).</li>\n<li>If a directory contains only an <code>index.md</code> and no other files, the directory collapses to a leaf node (no collapsible in sidebar).</li>\n</ul>\n<h2>Grouping directories with parentheses (groupers)</h2>\n<p>Directory names wrapped in <code>()</code> act as <strong>groupers</strong>:</p>\n<ul>\n<li>shown as a labeled section in the sidebar (not collapsible)</li>\n<li>skipped from route pathname segments</li>\n<li>should not contain <code>index.md</code></li>\n<li>can be ordered with numeric prefixes: <code>(2. Category)</code></li>\n</ul>\n<p>Groupers are useful for visually grouping related pages without adding extra URL segments.</p>\n<p>Example:</p>\n<pre class=\"language-text\"><code class=\"language-text\">docs/\n (Guides)/\n setup.md\n usage.md\n</code></pre>\n<p>Routes:</p>\n<ul>\n<li><code>/setup</code></li>\n<li><code>/usage</code></li>\n</ul>\n<p>Sidebar:</p>\n<pre class=\"language-text\"><code class=\"language-text\">Guides ← grouper label (not a link)\n Setup\n Usage\n</code></pre>\n<h2>Grouper ordering and index collision rules</h2>\n<p>Numeric prefixes on groupers only control ordering among other groupers — they never collide with indexes on regular files or directories. This is because the sort algorithm always places groupers after every regular file and directory at the same level, regardless of what prefix you give them.</p>\n<p>Similarly, numeric prefixes on regular files and directories only control ordering among their own kind.</p>\n<p>In short:</p>\n<ul>\n<li><code>index.md</code> is always sorted first.</li>\n<li>Regular files and directories are sorted next (by label).</li>\n<li>Groupers are sorted last (by label), after all regular files and directories.</li>\n<li>Within each group (regulars and groupers), ordering is controlled by numeric prefixes and <code>localeCompare</code>.</li>\n</ul>\n<p>Example:</p>\n<pre class=\"language-text\"><code class=\"language-text\">docs/\n index.md\n 1. Getting Started.md\n 2. CLI Reference.md\n (1. Guide)/\n routing.md\n (2. Configuration)/\n smm-config.md\n (3. Examples)/\n structure.md\n</code></pre>\n<p>Sidebar order:</p>\n<pre class=\"language-text\"><code class=\"language-text\">Home ← index.md first\nGetting Started\nCLI Reference\nGuide ← grouper label (after all regular files)\n Routing\nConfiguration ← next grouper\n SMM Config\nExamples ← last grouper\n Structure\n</code></pre>\n<h2>Regular directories (without parentheses)</h2>\n<ul>\n<li>appear as collapsible sidebar containers</li>\n<li>can have <code>index.md</code> and be clickable landing pages</li>\n<li>are included in pathname segments of child files</li>\n</ul>\n<p>Example:</p>\n<pre class=\"language-text\"><code class=\"language-text\">docs/\n guides/\n index.md\n setup.md\n</code></pre>\n<p>Routes:</p>\n<ul>\n<li><code>/guides</code></li>\n<li><code>/guides/setup</code></li>\n</ul>\n<h2>Ordered filenames with index prefixes</h2>\n<p>If you use names like:</p>\n<ul>\n<li><code>1. blahblah.md</code></li>\n<li><code>2. blhalbhablah.md</code></li>\n</ul>\n<p>and set <code>trimIndexFromPath: true</code> in config, names can be ordered while emitted as clean paths.</p>\n<p>The index prefix in filenames does not conflict with grouper indexes — they operate in separate sort tiers.</p>\n<h2>Directories vs groupers summary</h2>\n<table>\n<thead>\n<tr>\n<th></th>\n<th>Sidebar rendering</th>\n<th>In URL path</th>\n<th>Can have <code>index.md</code></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Regular directory</td>\n<td>Collapsible</td>\n<td>Yes</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td>Grouper <code>(Name)</code></td>\n<td>Labeled section</td>\n<td>No</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n<h2>Slug generation rules</h2>\n<p>Route path segments are normalized by the CLI:</p>\n<ul>\n<li>converted to lowercase</li>\n<li>spaces/underscores become <code>-</code></li>\n<li>punctuation like <code>.,;&quot;'\\\\:&lt;&gt;</code>?!` is removed</li>\n<li>grouper directory names like <code>(Group)</code> are excluded from final pathname</li>\n</ul>\n"},{"path":"/markdown-and-rendering","content":"<h1>Markdown and Rendering</h1>\n<p>The CLI uses <code>markdown-it</code> and includes:</p>\n<ul>\n<li>footnotes support</li>\n<li>task lists support</li>\n</ul>\n<p>Code highlighting is enabled through Prism with language classes like <code>language-js</code>.</p>\n<p>Useful notes:</p>\n<ul>\n<li><code>linkify</code> is enabled by default in config options.</li>\n<li><code>fuzzyEmail</code> linkification is disabled.</li>\n<li>You can override markdown-it behavior via <code>markdownItOptions</code> in <code>smm.config.json</code>.</li>\n</ul>\n<p>Additional rendering behavior from the web app:</p>\n<ul>\n<li>Heading elements are assigned generated ids for anchor navigation.</li>\n<li>Other extracted elements can receive internal labels for in-page search scroll targets.</li>\n</ul>\n"},{"path":"/build-output-and-assets","content":"<h1>Build Output and Assets</h1>\n<h2>Static site generation (SSG)</h2>\n<p>The CLI generates a fully static site. Every route gets its own <code>.html</code> file with pre-rendered markdown content baked into the DOM. The site works without JavaScript — search engines see all content, and the page is immediately readable.</p>\n<p>Once the JS bundle loads, the React SPA hydrates and takes over navigation for seamless client-side transitions.</p>\n<h2>Build flow</h2>\n<ol>\n<li>Markdown files are scanned and parsed into route/content JSON.</li>\n<li>Generated route data is written under <code>web/src/.generated/</code>.</li>\n<li>Vite builds the web app (CSS + JS bundles).</li>\n<li>Static HTML pages are generated for each route via <code>buildDistRoutesFromRouteTree</code>.</li>\n<li>The built <code>dist/</code> directory is copied to the target docs directory.</li>\n</ol>\n<h2>Generated files</h2>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>.generated/output.json</code></td>\n<td>Route metadata and parsed markdown content for all pages</td>\n</tr>\n<tr>\n<td><code>.generated/paths.json</code></td>\n<td>Nested route tree used to render sidebar groups and collapsibles</td>\n</tr>\n</tbody>\n</table>\n<h2>Public assets</h2>\n<p>If <code>publicPath</code> is configured in <code>smm.config.json</code> and the directory exists, its contents are copied into the web app's <code>public/</code> directory before the Vite build. This is useful for images, fonts, or other static files.</p>\n<h2>Output structure</h2>\n<pre class=\"language-text\"><code class=\"language-text\">dist/\n index.html ← home page (pre-rendered)\n getting-started.html ← each route gets its own .html\n cli-reference.html\n smm-config/\n index.html\n defaults-and-options.html\n trim-and-ordering.html\n assets/\n index-abc123.css ← Vite-built CSS\n index-abc123.js ← Vite-built JS (hydration)\n</code></pre>\n<h2>Defaults</h2>\n<p>If no <code>smm.config.json</code> or <code>.smmignore</code> exists, built-in defaults are used automatically.</p>\n"},{"path":"/smm-config","content":"<h1>smm.config.json</h1>\n<p>Place <code>smm.config.json</code> at docs root.</p>\n<p>Defaults are merged with your overrides.</p>\n<p>Default values come from the CLI's built-in config at <code>cli/src/smm.config.json</code>.</p>\n<p>This is the complete schema:</p>\n<pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">interface</span> <span class=\"token class-name\">SmmConfig</span> <span class=\"token punctuation\">{</span>\n rootTitle<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n description<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n markdownItOptions<span class=\"token operator\">?</span><span class=\"token operator\">:</span> Record<span class=\"token operator\">&lt;</span><span class=\"token builtin\">string</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">any</span><span class=\"token operator\">></span><span class=\"token punctuation\">;</span>\n baseRoute<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n outDir<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n publicPath<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n defaultTheme<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n favicon<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n logo<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n name<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n showNameWithLogo<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">boolean</span><span class=\"token punctuation\">;</span>\n og<span class=\"token operator\">?</span><span class=\"token operator\">:</span> OpenGraph<span class=\"token punctuation\">;</span>\n sortRoutes<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">boolean</span><span class=\"token punctuation\">;</span>\n trimIndexFromPath<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">boolean</span><span class=\"token punctuation\">;</span>\n version<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n fonts<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n title<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n name<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n url<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n body<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n name<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n url<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n mono<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n name<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n url<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<p>Read next:</p>\n<ul>\n<li><a href=\"/smm-config/defaults-and-options\">Defaults and Options</a></li>\n<li><a href=\"/smm-config/trim-and-ordering\">Trim and Ordering</a></li>\n<li><a href=\"/smm-config/opengraph\">OpenGraph</a></li>\n</ul>\n"},{"path":"/smm-config/defaults-and-options","content":"<h1>Defaults and Options</h1>\n<p><code>smm.config.json</code> supports these useful options:</p>\n<ul>\n<li><code>rootTitle</code>: document title.</li>\n<li><code>description</code>: default description.</li>\n<li><code>markdownItOptions</code>: markdown-it constructor options.</li>\n<li><code>baseRoute</code>: route base prefix.</li>\n<li><code>outDir</code>: output directory name for built artefacts (default <code>&quot;dist&quot;</code>).</li>\n<li><code>publicPath</code>: directory to copy as public assets.</li>\n<li><code>defaultTheme</code>: initial theme.</li>\n<li><code>favicon</code>: favicon URL/path.</li>\n<li><code>logo</code>: logo URL/path.</li>\n<li><code>name</code>: brand/app name.</li>\n<li><code>showNameWithLogo</code>: show name near logo.</li>\n<li><code>og</code>: Open Graph tags object.</li>\n<li><code>sortRoutes</code>: sort routes tree.</li>\n<li><code>trimIndexFromPath</code>: trims filename numeric prefixes from route names.</li>\n<li><code>version</code>: docs/site version string.</li>\n<li><code>fonts</code>: title/body/mono font names and optional stylesheet URLs.</li>\n</ul>\n<h2>Default values used when user config is missing</h2>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"rootTitle\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Serve My MD\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"A simple markdown to static site builder.\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"baseRoute\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"/\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"defaultTheme\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"dark\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"markdownItOptions\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"html\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"xhtmlOut\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"breaks\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"langPrefix\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"language-\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"linkify\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"typographer\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span>\n <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"outDir\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"dist\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"favicon\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"logo\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Serve My MD\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"showNameWithLogo\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"sortRoutes\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"trimIndexFromPath\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<p>Example:</p>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"rootTitle\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"My Docs\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Team documentation\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"baseRoute\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"/\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"defaultTheme\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"dark\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"sortRoutes\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"trimIndexFromPath\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"publicPath\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"public\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"outDir\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"my-site\"</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n"},{"path":"/smm-config/trim-and-ordering","content":"<h1>Trim and Ordering</h1>\n<p>Use numbered file names to force custom ordering:</p>\n<ul>\n<li><code>1. intro.md</code></li>\n<li><code>2. install.md</code></li>\n</ul>\n<p>When <code>trimIndexFromPath</code> is <code>true</code>, the numeric prefixes are removed from emitted route names while order stays controlled by your naming.</p>\n<p>Input files:</p>\n<pre class=\"language-text\"><code class=\"language-text\">1. blahblah.md\n2. blhalbhablah.md\n</code></pre>\n<p>Emitted routes:</p>\n<ul>\n<li><code>/blahblah</code></li>\n<li><code>/blhalbhablah</code></li>\n</ul>\n<p>If <code>trimIndexFromPath</code> is <code>false</code>, or not present, then the emitted routes would be:</p>\n<ul>\n<li><code>/1-blahblah</code></li>\n<li><code>/2-blhalbhablah</code></li>\n</ul>\n<p>If route sorting is enabled, routes are sorted lexicographically, with grouped <code>(Name)</code> directories ordered after regular names at the same level. Indexing can also be used for Grouper directories(directories whose names are enclosed within parenthesis) to determine their order.</p>\n"},{"path":"/smm-config/opengraph","content":"<h1>OpenGraph</h1>\n<p>The <code>og</code> field in <code>smm.config.json</code> controls Open Graph meta tags in the generated HTML. These tags control how your site appears when shared on social platforms (Twitter, Discord, Telegram, etc.) and in search results.</p>\n<h2>Schema</h2>\n<pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">interface</span> <span class=\"token class-name\">OpenGraph</span> <span class=\"token punctuation\">{</span>\n title<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n type<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n url<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n description<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n site_name<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n determiner<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token string\">\"a\"</span> <span class=\"token operator\">|</span> <span class=\"token string\">\"an\"</span> <span class=\"token operator\">|</span> <span class=\"token string\">\"the\"</span> <span class=\"token operator\">|</span> <span class=\"token string\">\"auto\"</span> <span class=\"token operator\">|</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">;</span>\n locale<span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"locale:alternate\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n images<span class=\"token operator\">?</span><span class=\"token operator\">:</span> OpenGraphImage<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n videos<span class=\"token operator\">?</span><span class=\"token operator\">:</span> OpenGraphVideo<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n audios<span class=\"token operator\">?</span><span class=\"token operator\">:</span> OpenGraphAudio<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">OpenGraphImage</span> <span class=\"token punctuation\">{</span>\n image<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"image:secure_url\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"image:type\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"image:width\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">number</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"image:height\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">number</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"image:alt\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">OpenGraphVideo</span> <span class=\"token punctuation\">{</span>\n video<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"video:secure_url\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"video:type\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"video:width\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">number</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"video:height\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">number</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">OpenGraphAudio</span> <span class=\"token punctuation\">{</span>\n audio<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"audio:secure_url\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n <span class=\"token string\">\"audio:type\"</span><span class=\"token operator\">?</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<h2>Basic usage</h2>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"og\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"title\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"My Docs\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Documentation for my project.\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"type\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"website\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"site_name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"My Docs\"</span>\n <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<p>This generates:</p>\n<pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">property</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>og:title<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>My Docs<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">property</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>og:description<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Documentation for my project.<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">property</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>og:type<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>website<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">property</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>og:site_name<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>My Docs<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n</code></pre>\n<h2>With images</h2>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"og\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"title\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"My Docs\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Documentation for my project.\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"images\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n <span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"image\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"https://example.com/og-image.png\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"image:width\"</span><span class=\"token operator\">:</span> <span class=\"token number\">1200</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"image:height\"</span><span class=\"token operator\">:</span> <span class=\"token number\">630</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"image:alt\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"My Docs preview\"</span>\n <span class=\"token punctuation\">}</span>\n <span class=\"token punctuation\">]</span>\n <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<h2>With videos and audio</h2>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"og\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"title\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Video Docs\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"videos\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n <span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"video\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"https://example.com/trailer.mp4\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"video:type\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"video/mp4\"</span>\n <span class=\"token punctuation\">}</span>\n <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"audios\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n <span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"audio\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"https://example.com/song.mp3\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"audio:type\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"audio/mpeg\"</span>\n <span class=\"token punctuation\">}</span>\n <span class=\"token punctuation\">]</span>\n <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<h2>Locale</h2>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"og\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"locale\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"en_US\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"locale:alternate\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"fr_FR\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"es_ES\"</span><span class=\"token punctuation\">]</span>\n <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<h2>How it works</h2>\n<p>The CLI reads the <code>og</code> field from <code>smm.config.json</code> and renders each entry as <code>&lt;meta property=&quot;og:key&quot; content=&quot;value&quot;&gt;</code> tags in the HTML <code>&lt;head&gt;</code>. Arrays (like <code>locale:alternate</code>) produce one meta tag per value. Image, video, and audio objects render their properties as flat <code>og:*</code> meta tags.</p>\n"},{"path":"/smm-ignore","content":"<h1>.smmignore</h1>\n<p>Create <code>.smmignore</code> at docs root to skip paths during markdown traversal.</p>\n<p>Rules are glob-like, processed top-to-bottom.</p>\n<ul>\n<li>Lines starting with <code>#</code> are comments.</li>\n<li>Empty lines are ignored.</li>\n<li>Prefix with <code>!</code> to un-ignore.</li>\n</ul>\n<p>Example:</p>\n<pre class=\"language-text\"><code class=\"language-text\">drafts/**\nprivate/**\n!private/keep.md\n</code></pre>\n<p>Paths are evaluated against traversal targets in the docs tree; ignored paths are skipped during route/content generation.</p>\n"},{"path":"/structure-examples","content":"<h1>Structure Examples</h1>\n<h2>Group directory (not in pathname)</h2>\n<pre class=\"language-text\"><code class=\"language-text\">docs/\n (Category)/\n tos.md\n</code></pre>\n<p>Route: <code>/tos</code></p>\n<h2>Normal directory with landing page</h2>\n<pre class=\"language-text\"><code class=\"language-text\">docs/\n features/\n index.md\n tea.md\n</code></pre>\n<p>Routes:</p>\n<ul>\n<li><code>/features</code></li>\n<li><code>/features/tea</code></li>\n</ul>\n<h2>Root landing page</h2>\n<pre class=\"language-text\"><code class=\"language-text\">docs/\n index.md\n about.md\n</code></pre>\n<p>Routes:</p>\n<ul>\n<li><code>/</code></li>\n<li><code>/about</code></li>\n</ul>\n"},{"path":"/config-examples","content":"<h1>Config Examples</h1>\n<h2>Basic customization</h2>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"rootTitle\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Company Docs\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Internal knowledge base\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"defaultTheme\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"dark\"</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"sortRoutes\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<h2>Ordered file naming + trimmed paths</h2>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"sortRoutes\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n <span class=\"token property\">\"trimIndexFromPath\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<h2>Public assets</h2>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n <span class=\"token property\">\"publicPath\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"public\"</span>\n<span class=\"token punctuation\">}</span>\n</code></pre>\n<p>This copies <code>public</code> from docs root into build public assets, also ignores it for routes building.</p>\n"}],"outDir":"docs","fonts":{"title":"Exo","body":"Commissioner","mono":"Fira Code"}}
1
+ {"rootTitle":"SMM Ghostly Fixture","description":"A fixture for testing ghostly operations in SMM.","baseRoute":"/","defaultTheme":"light","name":"Ghostly Store","showNameWithLogo":true,"routes":[{"path":"/","content":"<h1>hello this is main md</h1>\n<p><a href=\"/features\">features</a></p>\n"},{"path":"/features","content":"<h1>features</h1>\n<p>browse features:</p>\n<ul>\n<li><a href=\"/features/coffee\">coffee</a></li>\n<li><a href=\"/features/tea\">tea</a></li>\n<li><a href=\"/features/choorma\">choorma</a></li>\n<li><a href=\"/features/ghee-dudh\">ghee dudh</a></li>\n</ul>\n"},{"path":"/features/choorma","content":"<h1>choorma khao body bnao</h1>\n<p>price: nani dedo 10 minute choorma bnane ke liye :moon:</p>\n"},{"path":"/features/coffee","content":"<h1>co-fee</h1>\n<p>price: $2</p>\n"},{"path":"/features/ghee-dudh","content":"<h1>ghee dudh kha ladle</h1>\n<p>price: 1 lakh de bhais le</p>\n"},{"path":"/features/tea","content":"<h1>tea-tty</h1>\n<p>price: $69</p>\n"},{"path":"/muah","content":"<h1>Markdown Feature Showcase</h1>\n<h2>Headings</h2>\n<h1>H1 Heading</h1>\n<h2>H2 Heading</h2>\n<h3>H3 Heading</h3>\n<h4>H4 Heading</h4>\n<hr />\n<h2>Text Styles</h2>\n<ul>\n<li><em>Italic</em></li>\n<li><strong>Bold</strong></li>\n<li><em><strong>Bold Italic</strong></em></li>\n<li><s>Strikethrough</s></li>\n</ul>\n<hr />\n<h2>Links</h2>\n<p><a href=\"https://openai.com\">OpenAI</a></p>\n<hr />\n<h2>Images</h2>\n<p><img src=\"https://thumbs.dreamstime.com/b/fearsome-ancient-spartan-warrior-greece-red-cloak-spartan-helmet-night-spartan-movie-scene-action-sequence-spartan-helmet-284208996.jpg?w=360\" alt=\"Placeholder\" /></p>\n<hr />\n<h2>Blockquote</h2>\n<blockquote>\n<p>This is a blockquote example.<br />\nIt spans multiple lines.</p>\n</blockquote>\n<hr />\n<h2>Code (using indentation, not backticks)</h2>\n<p>Inline code example: <code>print(&quot;Hello World&quot;)</code></p>\n<pre class=\"language-python\"><code class=\"language-python\"> <span class=\"token keyword\">def</span> <span class=\"token function\">greet</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n <span class=\"token keyword\">return</span> <span class=\"token string\">\"Hello \"</span> <span class=\"token operator\">+</span> name\n\n <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>greet<span class=\"token punctuation\">(</span><span class=\"token string\">\"Markdown\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n</code></pre>\n<hr />\n<h2>Lists</h2>\n<h3>Unordered List</h3>\n<ul>\n<li>Item A</li>\n<li>Item B\n<ul>\n<li>Subitem B1</li>\n<li>Subitem B2</li>\n</ul>\n</li>\n</ul>\n<h3>Ordered List</h3>\n<ol>\n<li>Step One</li>\n<li>Step Two</li>\n<li>Step Three</li>\n</ol>\n<hr />\n<h2>Checkboxes</h2>\n<ul class=\"contains-task-list\">\n<li class=\"task-list-item\"><input class=\"task-list-item-checkbox\" checked=\"\" disabled=\"\" type=\"checkbox\"> Completed</li>\n<li class=\"task-list-item\"><input class=\"task-list-item-checkbox\" disabled=\"\" type=\"checkbox\"> Not Completed</li>\n<li class=\"task-list-item\"><input class=\"task-list-item-checkbox\" disabled=\"\" type=\"checkbox\"> Pending</li>\n</ul>\n<hr />\n<h2>Table</h2>\n<table>\n<thead>\n<tr>\n<th>Product</th>\n<th>Price</th>\n<th>In Stock</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Apple</td>\n<td>$1</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td>Banana</td>\n<td>$0.5</td>\n<td>No</td>\n</tr>\n<tr>\n<td>Orange</td>\n<td>$0.8</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n<hr />\n<h2>Horizontal Rule</h2>\n<hr />\n<hr />\n<h2>Emoji</h2>\n<p>😀 🚀 🎉 ❤️🔥</p>\n<hr />\n<h2>Footnotes</h2>\n<p>This is a sentence with a footnote.<sup class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\">[1]</a></sup></p>\n<hr />\n<h2>HTML Support</h2>\n<div style=\"color: green;\">This line uses HTML styling.</div>\n<hr />\n<h2>Done Checklist</h2>\n<ul class=\"contains-task-list\">\n<li class=\"task-list-item\"><input class=\"task-list-item-checkbox\" checked=\"\" disabled=\"\" type=\"checkbox\"> Includes tables</li>\n<li class=\"task-list-item\"><input class=\"task-list-item-checkbox\" checked=\"\" disabled=\"\" type=\"checkbox\"> Includes checkboxes</li>\n<li class=\"task-list-item\"><input class=\"task-list-item-checkbox\" checked=\"\" disabled=\"\" type=\"checkbox\"> Includes code (indent-based)</li>\n<li class=\"task-list-item\"><input class=\"task-list-item-checkbox\" checked=\"\" disabled=\"\" type=\"checkbox\"> Includes emojis</li>\n<li class=\"task-list-item\"><input class=\"task-list-item-checkbox\" checked=\"\" disabled=\"\" type=\"checkbox\"> Includes all Markdown features</li>\n</ul>\n<hr class=\"footnotes-sep\" />\n<section class=\"footnotes\">\n<ol class=\"footnotes-list\">\n<li id=\"fn1\" class=\"footnote-item\"><p>This is the footnote explanation. <a href=\"#fnref1\" class=\"footnote-backref\">↩︎</a></p>\n</li>\n</ol>\n</section>\n"},{"path":"/zaram-chand","content":"<h1>Mohandas Karam Chand Gandhi</h1>\n<p>He was also known as Mahatma Gandhi Thaave Aandhi.</p>\n"},{"path":"/tos","content":"<h1>Terms of Services</h1>\n<p>We only serve people with a knack for cooking. If you don't cook, you're not welcome.</p>\n"}],"outDir":"dist","fonts":{"title":"Sorts Mill Goudy","body":"Montserrat","mono":"monospace"},"version":"1.0.0 LTS"}
@@ -1 +1 @@
1
- [{"label":"","children":null,"pathSegment":""},{"label":"Getting Started","children":null,"pathSegment":"getting-started"},{"label":"CLI Reference","children":null,"pathSegment":"cli-reference"},{"label":"Key Behaviors","children":null,"pathSegment":"key-behaviors"},{"label":"Why serve-my-md","children":null,"pathSegment":"why-serve-my-md"},{"label":"Guide","children":[{"label":"Routing and Sidebar Patterns","children":null,"pathSegment":"routing-and-sidebar-patterns"},{"label":"Markdown and Rendering","children":null,"pathSegment":"markdown-and-rendering"},{"label":"Build Output and Assets","children":null,"pathSegment":"build-output-and-assets"}],"pathSegment":"","isGrouper":true},{"label":"Configuration","children":[{"label":"SMM Config","children":[{"label":"","children":null,"pathSegment":""},{"label":"Defaults and Options","children":null,"pathSegment":"defaults-and-options"},{"label":"Trim and Ordering","children":null,"pathSegment":"trim-and-ordering"},{"label":"OpenGraph","children":null,"pathSegment":"opengraph"}],"pathSegment":"smm-config","isGrouper":false},{"label":"SMM Ignore","children":null,"pathSegment":"smm-ignore","isGrouper":false}],"pathSegment":"","isGrouper":true},{"label":"Examples","children":[{"label":"Structure Examples","children":null,"pathSegment":"structure-examples"},{"label":"Config Examples","children":null,"pathSegment":"config-examples"}],"pathSegment":"","isGrouper":true}]
1
+ [{"label":"","children":null,"pathSegment":""},{"label":"features","children":[{"label":"","children":null,"pathSegment":""},{"label":"choorma","children":null,"pathSegment":"choorma"},{"label":"coffee","children":null,"pathSegment":"coffee"},{"label":"ghee-dudh","children":null,"pathSegment":"ghee-dudh"},{"label":"tea","children":null,"pathSegment":"tea"}],"pathSegment":"features","isGrouper":false},{"label":"muah","children":null,"pathSegment":"muah"},{"label":"Category","children":[{"label":"zaram Chand","children":null,"pathSegment":"zaram-chand"},{"label":"tos","children":null,"pathSegment":"tos"}],"pathSegment":"","isGrouper":true}]