1
1
import type { GitBookSiteContext } from '@/lib/context' ;
2
2
import { throwIfDataError } from '@/lib/data' ;
3
- import { isNodeEmpty } from '@/lib/document' ;
4
3
import { resolvePagePathDocumentOrGroup } from '@/lib/pages' ;
5
4
import { getIndexablePages } from '@/lib/sitemap' ;
6
5
import { getMarkdownForPagesTree } from '@/routes/llms' ;
7
6
import { type RevisionPageDocument , type RevisionPageGroup , RevisionPageType } from '@gitbook/api' ;
8
7
import type { Root } from 'mdast' ;
8
+ import { fromMarkdown } from 'mdast-util-from-markdown' ;
9
+ import { frontmatterFromMarkdown } from 'mdast-util-frontmatter' ;
10
+ import { gfmFromMarkdown } from 'mdast-util-gfm' ;
9
11
import { toMarkdown } from 'mdast-util-to-markdown' ;
12
+ import { frontmatter } from 'micromark-extension-frontmatter' ;
13
+ import { gfm } from 'micromark-extension-gfm' ;
14
+ import { remove } from 'unist-util-remove' ;
10
15
11
16
/**
12
17
* Generate a markdown version of a page.
@@ -26,13 +31,11 @@ export async function servePageMarkdown(context: GitBookSiteContext, pagePath: s
26
31
return new Response ( `Page "${ pagePath } " is not a document or group` , { status : 404 } ) ;
27
32
}
28
33
29
- // Handle group pages and empty document pages with children
30
- const isGroupPage = await shouldTreatAsGroupPage ( context , page ) ;
31
- if ( isGroupPage ) {
34
+ // Handle group pages
35
+ if ( page . type === RevisionPageType . Group ) {
32
36
return servePageGroup ( context , page ) ;
33
37
}
34
38
35
- // Handle regular document pages
36
39
const markdown = await throwIfDataError (
37
40
context . dataFetcher . getRevisionPageMarkdown ( {
38
41
spaceId : context . space . id ,
@@ -41,6 +44,11 @@ export async function servePageMarkdown(context: GitBookSiteContext, pagePath: s
41
44
} )
42
45
) ;
43
46
47
+ // Handle empty document pages which have children
48
+ if ( isEmptyPage ( markdown ) && page . pages . length > 0 ) {
49
+ return servePageGroup ( context , page ) ;
50
+ }
51
+
44
52
return new Response ( markdown , {
45
53
headers : {
46
54
'Content-Type' : 'text/markdown; charset=utf-8' ,
@@ -49,28 +57,33 @@ export async function servePageMarkdown(context: GitBookSiteContext, pagePath: s
49
57
}
50
58
51
59
/**
52
- * Determine if a page should be treated as a group page.
53
- * A page is treated as a group if:
54
- * 1. It's explicitly a group page type, OR
55
- * 2. It's a document page but has empty content (acts as a container)
60
+ * Determine if a page is empty.
61
+ * A page is empty if it has no content or only a title.
56
62
*/
57
- async function shouldTreatAsGroupPage (
58
- context : GitBookSiteContext ,
59
- page : RevisionPageDocument | RevisionPageGroup
60
- ) : Promise < boolean > {
61
- if ( page . type === RevisionPageType . Group ) {
63
+ function isEmptyPage ( pageMarkdown : string ) : boolean {
64
+ const trimmedMarkdown = pageMarkdown . trim ( ) ;
65
+
66
+ // Check if the markdown is empty
67
+ if ( ! trimmedMarkdown ) {
62
68
return true ;
63
69
}
64
70
65
- const document = await throwIfDataError (
66
- context . dataFetcher . getRevisionPageDocument ( {
67
- spaceId : context . space . id ,
68
- revisionId : context . revision . id ,
69
- pageId : page . id ,
70
- } )
71
- ) ;
71
+ // Parse the markdown to check if it only contains a title
72
+
73
+ const tree = fromMarkdown ( pageMarkdown , {
74
+ extensions : [ frontmatter ( [ 'yaml' ] ) , gfm ( ) ] ,
75
+ mdastExtensions : [ frontmatterFromMarkdown ( [ 'yaml' ] ) , gfmFromMarkdown ( ) ] ,
76
+ } ) ;
77
+
78
+ // Remove frontmatter
79
+ remove ( tree , 'yaml' ) ;
80
+
81
+ // If the page has no content or only a title, it is empty
82
+ if ( tree . children . length <= 1 && tree . children [ 0 ] ?. type === 'heading' ) {
83
+ return true ;
84
+ }
72
85
73
- return isNodeEmpty ( document ) ;
86
+ return false ;
74
87
}
75
88
76
89
/**
@@ -88,6 +101,7 @@ async function servePageGroup(
88
101
89
102
const indexablePages = getIndexablePages ( page . pages ) ;
90
103
104
+ // Create a markdown tree with the page title as heading and a list of child pages
91
105
const markdownTree : Root = {
92
106
type : 'root' ,
93
107
children : [
0 commit comments