nrdocs 0.1.2 → 0.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.
Files changed (2) hide show
  1. package/dist/bin.mjs +70 -18
  2. package/package.json +1 -1
package/dist/bin.mjs CHANGED
@@ -6108,9 +6108,33 @@ function rewriteMdLink(href, basePath, owner, repo) {
6108
6108
  }
6109
6109
 
6110
6110
  // src/renderer/template.ts
6111
+ function extractToc(html) {
6112
+ const toc = [];
6113
+ const regex = /<h([2-3])[^>]*id="([^"]*)"[^>]*>(.*?)<\/h[2-3]>/gi;
6114
+ let match2;
6115
+ while ((match2 = regex.exec(html)) !== null) {
6116
+ toc.push({
6117
+ level: parseInt(match2[1], 10),
6118
+ id: match2[2],
6119
+ text: match2[3].replace(/<[^>]*>/g, "")
6120
+ });
6121
+ }
6122
+ return toc;
6123
+ }
6124
+ function addHeadingIds(html) {
6125
+ return html.replace(/<h([2-3])([^>]*)>(.*?)<\/h[2-3]>/gi, (_match, level, attrs, text2) => {
6126
+ if (attrs.includes("id=")) return _match;
6127
+ const plainText = text2.replace(/<[^>]*>/g, "");
6128
+ const id = plainText.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
6129
+ return `<h${level} id="${id}"${attrs}>${text2}</h${level}>`;
6130
+ });
6131
+ }
6111
6132
  function wrapInTemplate(options) {
6112
6133
  const { title, siteTitle, content, nav, canonicalUrl, baseUrl } = options;
6113
6134
  const pageTitle = title === siteTitle ? siteTitle : `${title} - ${siteTitle}`;
6135
+ const contentWithIds = addHeadingIds(content);
6136
+ const toc = extractToc(contentWithIds);
6137
+ const hasToc = toc.length > 1;
6114
6138
  return `<!DOCTYPE html>
6115
6139
  <html lang="en">
6116
6140
  <head>
@@ -6119,34 +6143,46 @@ function wrapInTemplate(options) {
6119
6143
  <meta http-equiv="X-Content-Type-Options" content="nosniff">
6120
6144
  <meta http-equiv="X-Frame-Options" content="DENY">
6121
6145
  <meta name="referrer" content="no-referrer">
6146
+ <meta name="generator" content="nrdocs">
6122
6147
  <title>${escapeHtml2(pageTitle)}</title>
6123
6148
  <link rel="canonical" href="${escapeHtml2(canonicalUrl)}">
6124
6149
  <style>
6125
6150
  *{margin:0;padding:0;box-sizing:border-box}
6126
- body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;line-height:1.6;color:#1a1a1a;display:flex;min-height:100vh}
6127
- nav.sidebar{width:260px;padding:1.5rem;border-right:1px solid #e0e0e0;background:#fafafa;overflow-y:auto;flex-shrink:0}
6151
+ body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:1.0625rem;line-height:1.7;color:#1a1a1a;display:flex;min-height:100vh}
6152
+ nav.sidebar{width:260px;padding:1.5rem;border-right:1px solid #e0e0e0;background:#fafafa;overflow-y:auto;flex-shrink:0;position:sticky;top:0;height:100vh}
6128
6153
  nav.sidebar .site-title{font-weight:700;font-size:1.1rem;margin-bottom:1rem;color:#111}
6129
6154
  nav.sidebar ul{list-style:none}
6130
6155
  nav.sidebar li{margin-bottom:0.25rem}
6131
- nav.sidebar a{color:#333;text-decoration:none;padding:0.25rem 0.5rem;display:block;border-radius:4px}
6156
+ nav.sidebar a{color:#333;text-decoration:none;padding:0.3rem 0.6rem;display:block;border-radius:4px;font-size:0.95rem}
6132
6157
  nav.sidebar a:hover{background:#e8e8e8}
6133
6158
  nav.sidebar a.active{background:#e0e7ff;color:#1d4ed8;font-weight:500}
6134
- main{flex:1;padding:2rem 3rem;max-width:52rem;overflow-wrap:break-word}
6135
- main h1{font-size:2rem;margin-bottom:1rem;border-bottom:1px solid #e0e0e0;padding-bottom:0.5rem}
6136
- main h2{font-size:1.5rem;margin-top:2rem;margin-bottom:0.75rem}
6137
- main h3{font-size:1.25rem;margin-top:1.5rem;margin-bottom:0.5rem}
6138
- main p{margin-bottom:1rem}
6159
+ .content-wrapper{flex:1;display:flex;min-width:0}
6160
+ main{flex:1;padding:2.5rem 3rem;max-width:52rem;min-width:0;overflow-wrap:break-word}
6161
+ main h1{font-size:2.2rem;margin-bottom:1.2rem;border-bottom:1px solid #e0e0e0;padding-bottom:0.5rem;line-height:1.3}
6162
+ main h2{font-size:1.6rem;margin-top:2.5rem;margin-bottom:0.75rem;line-height:1.3}
6163
+ main h3{font-size:1.3rem;margin-top:1.8rem;margin-bottom:0.5rem;line-height:1.4}
6164
+ main p{margin-bottom:1.1rem}
6139
6165
  main a{color:#1d4ed8;text-decoration:underline}
6140
- main code{background:#f3f4f6;padding:0.15rem 0.35rem;border-radius:3px;font-size:0.9em}
6141
- main pre{background:#1e1e1e;color:#d4d4d4;padding:1rem;border-radius:6px;overflow-x:auto;margin-bottom:1rem}
6142
- main pre code{background:none;padding:0;color:inherit}
6143
- main table{border-collapse:collapse;width:100%;margin-bottom:1rem}
6144
- main th,main td{border:1px solid #d0d0d0;padding:0.5rem 0.75rem;text-align:left}
6166
+ main code{background:#f3f4f6;padding:0.2rem 0.4rem;border-radius:3px;font-size:0.88em}
6167
+ main pre{background:#1e1e1e;color:#d4d4d4;padding:1.2rem;border-radius:6px;overflow-x:auto;margin-bottom:1.2rem;font-size:0.9rem;line-height:1.5}
6168
+ main pre code{background:none;padding:0;color:inherit;font-size:inherit}
6169
+ main table{border-collapse:collapse;width:100%;margin-bottom:1.2rem}
6170
+ main th,main td{border:1px solid #d0d0d0;padding:0.6rem 0.85rem;text-align:left}
6145
6171
  main th{background:#f5f5f5;font-weight:600}
6146
- main img{max-width:100%;height:auto}
6147
- main blockquote{border-left:4px solid #d0d0d0;padding-left:1rem;margin-bottom:1rem;color:#555}
6148
- main ul,main ol{margin-bottom:1rem;padding-left:1.5rem}
6149
- @media(max-width:768px){body{flex-direction:column}nav.sidebar{width:100%;border-right:none;border-bottom:1px solid #e0e0e0}main{padding:1rem}}
6172
+ main img{max-width:100%;height:auto;border-radius:4px}
6173
+ main blockquote{border-left:4px solid #d0d0d0;padding-left:1rem;margin-bottom:1.1rem;color:#555;font-style:italic}
6174
+ main ul,main ol{margin-bottom:1.1rem;padding-left:1.5rem}
6175
+ main li{margin-bottom:0.3rem}
6176
+ aside.toc{width:220px;padding:1.5rem 1rem;position:sticky;top:0;height:100vh;overflow-y:auto;flex-shrink:0;border-left:1px solid #e8e8e8}
6177
+ aside.toc .toc-title{font-size:0.8rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:#666;margin-bottom:0.75rem}
6178
+ aside.toc ul{list-style:none}
6179
+ aside.toc li{margin-bottom:0.3rem}
6180
+ aside.toc a{color:#555;text-decoration:none;font-size:0.85rem;display:block;padding:0.15rem 0;border-radius:2px}
6181
+ aside.toc a:hover{color:#1d4ed8}
6182
+ aside.toc .toc-h3{padding-left:0.75rem}
6183
+ footer{padding:1.5rem 3rem;border-top:1px solid #e8e8e8;color:#888;font-size:0.8rem;text-align:center}
6184
+ @media(max-width:1100px){aside.toc{display:none}}
6185
+ @media(max-width:768px){body{flex-direction:column}nav.sidebar{width:100%;border-right:none;border-bottom:1px solid #e0e0e0;position:static;height:auto}main{padding:1.5rem}}
6150
6186
  </style>
6151
6187
  </head>
6152
6188
  <body>
@@ -6156,12 +6192,28 @@ main ul,main ol{margin-bottom:1rem;padding-left:1.5rem}
6156
6192
  ${renderNavItems(nav, baseUrl)}
6157
6193
  </ul>
6158
6194
  </nav>
6195
+ <div class="content-wrapper">
6159
6196
  <main>
6160
- ${content}
6197
+ ${contentWithIds}
6198
+ <footer>Generated with <a href="https://github.com/noam-r/nrdocs">nrdocs</a></footer>
6161
6199
  </main>
6200
+ ${hasToc ? renderToc(toc) : ""}
6201
+ </div>
6162
6202
  </body>
6163
6203
  </html>`;
6164
6204
  }
6205
+ function renderToc(toc) {
6206
+ const items = toc.map((entry) => {
6207
+ const cls = entry.level === 3 ? ' class="toc-h3"' : "";
6208
+ return `<li${cls}><a href="#${escapeHtml2(entry.id)}">${escapeHtml2(entry.text)}</a></li>`;
6209
+ }).join("\n");
6210
+ return `<aside class="toc">
6211
+ <div class="toc-title">On this page</div>
6212
+ <ul>
6213
+ ${items}
6214
+ </ul>
6215
+ </aside>`;
6216
+ }
6165
6217
  function renderNavItems(items, baseUrl) {
6166
6218
  return items.map((item) => {
6167
6219
  const href = baseUrl + item.href;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nrdocs",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "CLI for nrdocs - serverless docs publishing for private GitHub repos",
5
5
  "type": "module",
6
6
  "bin": {