@stacksjs/bunpress 0.0.5 → 0.1.0

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.
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Reset the global highlighter instance (useful when changing themes)
3
+ */
4
+ export declare function resetHighlighter(): void;
5
+ /**
6
+ * Normalizes a language identifier
7
+ */
8
+ export declare function normalizeLanguage(lang: string): string;
9
+ /**
10
+ * Checks if a language is supported by ts-syntax-highlighter
11
+ */
12
+ export declare function isLanguageSupported(lang: string): boolean;
13
+ /**
14
+ * Highlights code using ts-syntax-highlighter (async)
15
+ * IMPORTANT: Preserves original code structure and whitespace
16
+ */
17
+ export declare function highlightCode(code: string, language: string, theme?: string): Promise<string>;
18
+ /**
19
+ * Synchronous version of highlightCode
20
+ * Note: ts-syntax-highlighter doesn't have a sync API, so this uses a different approach
21
+ * For better performance, use the async version
22
+ */
23
+ export declare function highlightCodeSync(code: string, language: string): string;
24
+ /**
25
+ * Gets the CSS styles for syntax highlighting
26
+ * Note: ts-syntax-highlighter includes its own theme CSS
27
+ */
28
+ export declare function getSyntaxHighlightingStyles(): string;
29
+ /**
30
+ * Pre-warms the highlighter by creating the instance early
31
+ * Call this during application initialization for better performance
32
+ */
33
+ export declare function prewarmHighlighter(): Promise<void>;
34
+ /**
35
+ * Gets the highlighter instance for advanced usage
36
+ */
37
+ export declare function getHighlighterInstance(): Promise<TSHighlighter>;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from './config';
2
+ export * from './highlighter';
3
+ export * from './serve';
2
4
  export * from './toc';
3
5
  export * from './types';
@@ -0,0 +1,20 @@
1
+ import { config } from './config';
2
+ import type { BunPressConfig } from './types';
3
+ /**
4
+ * Start the BunPress documentation server
5
+ */
6
+ export declare function startServer(options?: {
7
+ port?: number
8
+ root?: string
9
+ watch?: boolean
10
+ config?: BunPressConfig
11
+ }): Promise<{ server: any, url: string, stop: () => void }>;
12
+ /**
13
+ * CLI-friendly server start function with graceful shutdown
14
+ */
15
+ export declare function serveCLI(options?: {
16
+ port?: number
17
+ root?: string
18
+ watch?: boolean
19
+ config?: BunPressConfig
20
+ }): Promise<void>;
package/dist/src/index.js CHANGED
@@ -1,243 +1,2 @@
1
1
  // @bun
2
- import{a as f,b as r,c as h}from"../chunk-z2xpw4s7.js";var O={enabled:!0,position:["sidebar"],title:"Table of Contents",maxDepth:6,minDepth:2,className:"table-of-contents",smoothScroll:!0,activeHighlight:!0,collapsible:!0,exclude:[]};function q(A){return A.toLowerCase().trim().replace(/<[^>]*>/g,"").replace(/what's new\?\s*\(v2\.0\)/g,"whats-new-v2-0").replace(/features\s*&\s*benefits/g,"features-benefits").replace(/vue\.js\s*\+\s*typescript\s*=\s*\u2764\uFE0F/g,"vue-js-typescript").replace(/\./g,"-").replace(/[^\w\s-]/g,"").replace(/[\s_]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function _(A,z){let j=q(A),B=j,E=1;while(z.has(j))j=`${B}-${E}`,E++;return z.add(j),j}function I(A){let z=[],j=new Set,B=/^(#{1,6})\s+(.+)$/gm,E;while((E=B.exec(A))!==null){let K=E[1].length,Q=E[2].trim();if(!Q)continue;if(Q.includes("toc-ignore"))continue;let P=Q.replace(/\s*<!-- toc-ignore -->\s*/g,"").trim();P=P.replace(/`([^`]+)`/g,"<code>$1</code>");let M=P.includes("<code>"),W=_(P.replace(/<[^>]*>/g,""),j);z.push({level:K,text:P,id:W,children:[],hasCode:M})}return z}function L(A){let z=[],j=[];for(let B of A){while(j.length>0&&j[j.length-1].level>=B.level)j.pop();if(j.length===0)z.push(B);else j[j.length-1].children.push(B);j.push(B)}return z}function U(A,z){let{minDepth:j=2,maxDepth:B=6,exclude:E=[]}=z,K=(Q)=>{let P=[];for(let M of Q){if(E.some((X)=>{if(X.startsWith("/")&&X.endsWith("/"))return new RegExp(X.slice(1,-1)).test(M.text);else return M.text===X}))continue;if(M.level>B)continue;let W=K(M.children);if(M.level>=j&&M.level<=B)P.push({...M,children:W});else P.push(...W)}return P};return K(A)}function Y(A){let{items:z,title:j,config:B}=A,{className:E,collapsible:K}=B,Q=(P,M=0)=>{if(P.length===0)return"";let W=M===0?"toc-list":"toc-sublist",X=M===0?"toc-item":"toc-subitem";return`<ul class="${W}">
3
- ${P.map((V)=>{let Z=V.children.length>0,w=Z&&K?"toc-expand":"",F=Z?Q(V.children,M+1):"",k=50,G=V.text.length>50?`${V.text.substring(0,50)}...`:V.text,J=V.text.length>50?"toc-truncate":"",N=V.hasCode?"toc-code":"";return`<li class="${X} ${w} ${J} ${N}">
4
- <a href="#${V.id}" class="toc-link" title="${V.text.replace(/<[^>]*>/g,"")}">${G}</a>
5
- ${F}
6
- </li>`}).join(`
7
- `)}
8
- </ul>`};return`<nav class="${E}" role="navigation" aria-label="${j}">
9
- <div class="toc-container">
10
- <h2 class="toc-title">${j}</h2>
11
- ${Q(z)}
12
- </div>
13
- </nav>`}function $(A){return Y(A).replace("table-of-contents","table-of-contents toc-inline inline-toc")}function b(A){return Y(A).replace("table-of-contents","table-of-contents toc-sidebar sidebar-toc")}function R(A){return Y(A).replace("table-of-contents","table-of-contents toc-floating floating-toc")}function y(A,z={}){let j={...z};if(typeof j.position==="string")j.position=[j.position];let B={...O,...j},E=I(A),K=L(E),Q=U(K,B);return{title:B.title,items:Q,config:B}}function D(A,z={}){let j=y(A,z);return(Array.isArray(z.position)?z.position:[z.position||"sidebar"]).map((E)=>{let K;switch(E){case"inline":K=$(j);break;case"sidebar":K=b(j);break;case"floating":K=R(j);break;default:K=Y(j)}return{position:E,data:j,html:K}})}function S(A,z){let j=$(z);return A.replace(/\[\[toc\]\]/gi,j)}function H(A){let z=new Set;return A.replace(/<h([1-6])>(.*?)<\/h[1-6]>/gi,(j,B,E)=>{let K=_(E.replace(/<[^>]*>/g,""),z);return`<h${B} id="${K}"><a href="#${K}" class="heading-anchor">#</a>${E}</h${B}>`})}function v(){return`
14
- .table-of-contents {
15
- position: sticky;
16
- top: 60px; /* Match navbar height */
17
- height: calc(100vh - 60px);
18
- width: 200px;
19
- overflow-y: auto;
20
- padding: 1rem;
21
- }
22
-
23
- .toc-container {
24
- padding: 0;
25
- }
26
-
27
- .toc-title {
28
- margin: 0 0 1rem 0;
29
- font-size: 1.2rem;
30
- font-weight: 600;
31
- }
32
-
33
- .toc-list,
34
- .toc-sublist {
35
- list-style: none;
36
- padding: 0;
37
- margin: 0;
38
- }
39
-
40
- .toc-list {
41
- padding-left: 0;
42
- }
43
-
44
- .toc-sublist {
45
- padding-left: 1rem;
46
- margin-top: 0.5rem;
47
- }
48
-
49
- .toc-item,
50
- .toc-subitem {
51
- margin-bottom: 0.5rem;
52
- }
53
-
54
- .toc-link {
55
- color: inherit;
56
- text-decoration: none;
57
- display: block;
58
- padding: 0.25rem 0;
59
- border-radius: 0.25rem;
60
- transition: background-color 0.2s;
61
- }
62
-
63
- .toc-link:hover {
64
- background-color: rgba(0, 0, 0, 0.05);
65
- }
66
-
67
- .toc-active .toc-link,
68
- .active-toc-item .toc-link {
69
- background-color: rgba(0, 123, 255, 0.1);
70
- font-weight: 500;
71
- }
72
-
73
- .toc-truncate {
74
- /* Styles for truncated TOC items */
75
- }
76
-
77
- .toc-truncate .toc-link {
78
- white-space: nowrap;
79
- overflow: hidden;
80
- text-overflow: ellipsis;
81
- }
82
-
83
- .toc-collapse .toc-link::before {
84
- content: '\u25B6';
85
- margin-right: 0.5rem;
86
- transition: transform 0.2s;
87
- }
88
-
89
- .toc-collapse.collapsed .toc-link::before {
90
- transform: rotate(90deg);
91
- }
92
-
93
- .toc-expand .toc-link::before {
94
- content: '\u25BC';
95
- margin-right: 0.5rem;
96
- }
97
-
98
- .heading-anchor {
99
- color: inherit;
100
- text-decoration: none;
101
- opacity: 0;
102
- margin-left: -1rem;
103
- padding-right: 0.5rem;
104
- transition: opacity 0.2s;
105
- }
106
-
107
- h1:hover .heading-anchor,
108
- h2:hover .heading-anchor,
109
- h3:hover .heading-anchor,
110
- h4:hover .heading-anchor,
111
- h5:hover .heading-anchor,
112
- h6:hover .heading-anchor {
113
- opacity: 0.7;
114
- }
115
-
116
- .heading-anchor:hover {
117
- opacity: 1;
118
- }
119
-
120
- /* Smooth scrolling */
121
- html {
122
- scroll-behavior: smooth;
123
- }
124
-
125
- /* Responsive adjustments */
126
- @media (max-width: 768px) {
127
- .toc-sidebar {
128
- display: none;
129
- }
130
-
131
- .toc-floating {
132
- position: fixed;
133
- bottom: 1rem;
134
- right: 1rem;
135
- background: white;
136
- border: 1px solid #ddd;
137
- border-radius: 0.5rem;
138
- padding: 1rem;
139
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
140
- max-width: 250px;
141
- }
142
- }
143
- `}function T(){return`
144
- function initToc() {
145
- const tocLinks = document.querySelectorAll('.toc-link')
146
-
147
- // Smooth scrolling for TOC links
148
- tocLinks.forEach(link => {
149
- link.addEventListener('click', function(e) {
150
- e.preventDefault()
151
- const targetId = this.getAttribute('href')?.substring(1)
152
- const targetElement = document.getElementById(targetId)
153
-
154
- if (targetElement) {
155
- targetElement.scrollIntoView({
156
- behavior: 'smooth',
157
- block: 'start'
158
- })
159
-
160
- // Update URL without page reload
161
- history.pushState(null, '', '#' + targetId)
162
- }
163
- })
164
- })
165
-
166
- // Active TOC item highlighting on scroll
167
- function updateActiveTocItem() {
168
- const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
169
- const tocLinks = document.querySelectorAll('.toc-link')
170
-
171
- let currentActive = null
172
- let currentDistance = Infinity
173
-
174
- headings.forEach((heading, index) => {
175
- const rect = heading.getBoundingClientRect()
176
- const distance = Math.abs(rect.top)
177
-
178
- if (distance < currentDistance && rect.top <= 100) {
179
- currentActive = heading.id
180
- currentDistance = distance
181
- }
182
- })
183
-
184
- tocLinks.forEach(link => {
185
- const parent = link.parentElement
186
- if (parent) {
187
- parent.classList.remove('toc-active', 'active-toc-item')
188
- const href = link.getAttribute('href')?.substring(1)
189
- if (href === currentActive) {
190
- parent.classList.add('toc-active', 'active-toc-item')
191
- }
192
- }
193
- })
194
- }
195
-
196
- // Throttle scroll events
197
- let scrollTimeout
198
- function throttledUpdate() {
199
- if (!scrollTimeout) {
200
- scrollTimeout = setTimeout(() => {
201
- updateActiveTocItem()
202
- scrollTimeout = null
203
- }, 100)
204
- }
205
- }
206
-
207
- window.addEventListener('scroll', throttledUpdate)
208
- updateActiveTocItem()
209
-
210
- // TOC collapse/expand functionality
211
- const expandableItems = document.querySelectorAll('.toc-expand')
212
-
213
- expandableItems.forEach(item => {
214
- item.addEventListener('click', function(e) {
215
- if (e.target === this || e.target.closest('.toc-link')) {
216
- this.classList.toggle('collapsed')
217
- }
218
- })
219
- })
220
-
221
- // Handle URL hash on page load
222
- if (window.location.hash) {
223
- const targetId = window.location.hash.substring(1)
224
- const targetElement = document.getElementById(targetId)
225
-
226
- if (targetElement) {
227
- setTimeout(() => {
228
- targetElement.scrollIntoView({
229
- behavior: 'smooth',
230
- block: 'start'
231
- })
232
- }, 100)
233
- }
234
- }
235
- }
236
-
237
- // Initialize TOC when DOM is ready
238
- if (document.readyState === 'loading') {
239
- document.addEventListener('DOMContentLoaded', initToc)
240
- } else {
241
- initToc()
242
- }
243
- `}export{S as processInlineTocSyntax,h as getConfig,_ as generateUniqueSlug,v as generateTocStyles,T as generateTocScripts,D as generateTocPositions,Y as generateTocHtml,y as generateTocData,q as generateSlug,b as generateSidebarTocHtml,$ as generateInlineTocHtml,R as generateFloatingTocHtml,U as filterHeadings,I as extractHeadings,H as enhanceHeadingsWithAnchors,O as defaultTocConfig,f as defaultConfig,r as config,L as buildTocHierarchy};
2
+ import{A as P,B as Q,C as R,a as t,b as e,c as b,d as g,e as h,f as j,g as k,h as n,i as q,j as s,k as u,l as z,m as A,n as B,o as D,p as E,q as F,r as G,s as H,t as I,u as J,v as K,w as L,x as M,y as N,z as O}from"../chunk-he6c5f4e.js";export{Q as startServer,R as serveCLI,g as resetHighlighter,M as processInlineTocSyntax,s as prewarmHighlighter,h as normalizeLanguage,j as isLanguageSupported,n as highlightCodeSync,k as highlightCode,q as getSyntaxHighlightingStyles,u as getHighlighterInstance,b as getConfig,B as generateUniqueSlug,O as generateTocStyles,P as generateTocScripts,L as generateTocPositions,G as generateTocHtml,K as generateTocData,A as generateSlug,I as generateSidebarTocHtml,H as generateInlineTocHtml,J as generateFloatingTocHtml,F as filterHeadings,D as extractHeadings,N as enhanceHeadingsWithAnchors,z as defaultTocConfig,t as defaultConfig,e as config,E as buildTocHierarchy};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Load a template file from the templates directory
3
+ */
4
+ export declare function loadTemplate(name: string): Promise<string>;
5
+ /**
6
+ * Render a template with data
7
+ */
8
+ export declare function renderTemplate(template: string, data: Record<string, any>): string;
9
+ /**
10
+ * Load and render a template in one step
11
+ */
12
+ export declare function render(templateName: string, data: Record<string, any>): Promise<string>;
13
+ /**
14
+ * Clear the template cache (useful for development/hot reloading)
15
+ */
16
+ export declare function clearTemplateCache(): void;
package/dist/types.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { marked } from 'marked';
2
1
  export declare interface BunPressConfig {
3
2
  verbose: boolean
4
3
  markdown: MarkdownPluginConfig
@@ -16,15 +15,17 @@ export declare interface MarkdownPluginConfig {
16
15
  scripts?: string[]
17
16
  title?: string
18
17
  meta?: Record<string, string>
19
- markedOptions?: Parameters<typeof marked.parse>[1]
18
+ markedOptions?: any
20
19
  preserveDirectoryStructure?: boolean
21
20
  toc?: TocConfig
22
21
  sidebar?: Record<string, SidebarItem[]>
23
22
  nav?: NavItem[]
24
23
  search?: SearchConfig
25
24
  themeConfig?: ThemeConfig
25
+ syntaxHighlightTheme?: 'github-light' | 'github-dark'
26
26
  sitemap?: SitemapConfig
27
27
  robots?: RobotsConfig
28
+ features?: MarkdownFeaturesConfig
28
29
  }
29
30
  /**
30
31
  * Sidebar navigation item
@@ -94,6 +95,73 @@ export declare interface TocConfig {
94
95
  collapsible?: boolean
95
96
  exclude?: string[]
96
97
  }
98
+ /**
99
+ * Markdown features configuration
100
+ * Controls which VitePress-compatible features are enabled
101
+ */
102
+ export declare interface MarkdownFeaturesConfig {
103
+ inlineFormatting?: boolean
104
+ containers?: boolean | ContainersConfig
105
+ githubAlerts?: boolean | GitHubAlertsConfig
106
+ codeBlocks?: boolean | CodeBlocksConfig
107
+ codeGroups?: boolean
108
+ codeImports?: boolean
109
+ inlineToc?: boolean
110
+ customAnchors?: boolean
111
+ emoji?: boolean
112
+ badges?: boolean
113
+ includes?: boolean
114
+ externalLinks?: boolean | ExternalLinksConfig
115
+ imageLazyLoading?: boolean
116
+ tables?: boolean | TablesConfig
117
+ }
118
+ /**
119
+ * Custom containers configuration
120
+ */
121
+ export declare interface ContainersConfig {
122
+ info?: boolean
123
+ tip?: boolean
124
+ warning?: boolean
125
+ danger?: boolean
126
+ details?: boolean
127
+ raw?: boolean
128
+ }
129
+ /**
130
+ * GitHub alerts configuration
131
+ */
132
+ export declare interface GitHubAlertsConfig {
133
+ note?: boolean
134
+ tip?: boolean
135
+ important?: boolean
136
+ warning?: boolean
137
+ caution?: boolean
138
+ }
139
+ /**
140
+ * Code blocks configuration
141
+ */
142
+ export declare interface CodeBlocksConfig {
143
+ lineHighlighting?: boolean
144
+ lineNumbers?: boolean
145
+ focus?: boolean
146
+ diffs?: boolean
147
+ errorWarningMarkers?: boolean
148
+ }
149
+ /**
150
+ * External links configuration
151
+ */
152
+ export declare interface ExternalLinksConfig {
153
+ autoTarget?: boolean
154
+ autoRel?: boolean
155
+ showIcon?: boolean
156
+ }
157
+ /**
158
+ * Tables configuration
159
+ */
160
+ export declare interface TablesConfig {
161
+ alignment?: boolean
162
+ enhancedStyling?: boolean
163
+ responsive?: boolean
164
+ }
97
165
  /**
98
166
  * Search configuration
99
167
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/bunpress",
3
3
  "type": "module",
4
- "version": "0.0.5",
4
+ "version": "0.1.0",
5
5
  "description": "Modern documentation engine. Powered by Bun.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
@@ -57,22 +57,25 @@
57
57
  "lint:fix": "bunx --bun eslint . --fix",
58
58
  "changelog": "bunx logsmith --verbose",
59
59
  "changelog:generate": "bunx logsmith --output CHANGELOG.md",
60
- "release": "bun run changelog:generate && bunx --bun bumpx prompt --recursive",
60
+ "release": "bunx --bun bumpx prompt --recursive",
61
61
  "dev:docs": "bun bin/cli.ts dev",
62
62
  "build:docs": "bun build.ts",
63
63
  "preview:docs": "bun serve --port 3000 dist",
64
64
  "typecheck": "bun --bun tsc --noEmit"
65
65
  },
66
66
  "devDependencies": {
67
- "@stacksjs/bumpx": "^0.1.84",
67
+ "@stacksjs/bumpx": "^0.2.2",
68
68
  "@stacksjs/eslint-config": "^4.14.0-beta.3",
69
69
  "@stacksjs/gitlint": "^0.1.5",
70
- "@stacksjs/headwind": "^0.1.1",
71
- "@stacksjs/logsmith": "^0.1.18",
70
+ "@stacksjs/headwind": "^0.1.3",
71
+ "@stacksjs/logsmith": "^0.2.0",
72
72
  "@stacksjs/ts-i18n": "^0.0.0",
73
73
  "bun-git-hooks": "^0.3.1",
74
74
  "bun-plugin-dtsx": "0.9.5",
75
+ "bun-plugin-stx": "0.1.16",
76
+ "bun-types": "^1.3.1",
75
77
  "bunfig": "^0.15.0",
78
+ "ts-syntax-highlighter": "^0.2.0",
76
79
  "typescript": "^5.9.3"
77
80
  },
78
81
  "git-hooks": {
@@ -82,5 +85,8 @@
82
85
  }
83
86
  },
84
87
  "commit-msg": "bunx gitlint --edit .git/COMMIT_EDITMSG"
88
+ },
89
+ "overrides": {
90
+ "bun-plugin-stx": "0.1.16"
85
91
  }
86
92
  }