@@ -43,7 +43,11 @@ const CHAPTER_PATTERNS = [
4343 / ^ 〖 .* 〗 $ / ,
4444 / ^ 《 .* 》 $ / ,
4545 / ^ 「 .* 」 $ / ,
46- / ^ 『 .* 』 $ /
46+ / ^ 『 .* 』 $ / ,
47+
48+ // 卷/篇/集 模式
49+ / ^ 第 [ 零 一 二 三 四 五 六 七 八 九 十 百 千 万 \d ] + [ 卷 篇 集 幕 ] / ,
50+ / ^ 卷 [ 零 一 二 三 四 五 六 七 八 九 十 百 千 万 \d ] + / ,
4751]
4852
4953/**
@@ -94,35 +98,41 @@ function isChapterTitle(line) {
9498 */
9599export function parseChapters ( content , options = { } ) {
96100 const {
97- minChapterLength = 500 , // 最小章节长度
101+ minChapterLength = 200 , // 最小章节长度(降低阈值以支持短章节)
98102 maxChapters = 1000 , // 最大章节数
99103 autoDetect = true // 是否自动检测章节
100104 } = options
101-
105+
102106 if ( ! content || typeof content !== 'string' ) {
103107 return [ ]
104108 }
105-
106- const lines = content . split ( / \r ? \n / )
109+
110+ // 预处理:清理下载内容中的分隔线
111+ let cleanContent = content . replace ( / \n - { 3 , } \n / g, '\n' )
112+
113+ const lines = cleanContent . split ( / \r ? \n / )
107114 const chapters = [ ]
108115 let currentChapter = null
109116 let chapterIndex = 0
110-
117+
111118 // 如果没有检测到章节标题,创建一个默认章节
112119 let hasChapterTitles = false
113-
120+
114121 for ( let i = 0 ; i < lines . length ; i ++ ) {
115122 const line = lines [ i ] . trim ( )
116-
123+
124+ // 跳过纯分隔线(--- 或 ***)
125+ if ( / ^ [ - = _ * ~ # ] { 3 , } $ / . test ( line ) ) continue
126+
117127 if ( autoDetect && isChapterTitle ( line ) ) {
118128 hasChapterTitles = true
119-
120- // 保存上一章节
121- if ( currentChapter && currentChapter . content . trim ( ) . length >= minChapterLength ) {
129+
130+ // 保存上一章节(即使内容较短也保存,避免丢失内容)
131+ if ( currentChapter && currentChapter . content . trim ( ) . length > 0 ) {
122132 chapters . push ( currentChapter )
123133 chapterIndex ++
124134 }
125-
135+
126136 // 创建新章节
127137 currentChapter = {
128138 id : chapterIndex ,
@@ -143,36 +153,58 @@ export function parseChapters(content, options = {}) {
143153 endLine : i
144154 }
145155 }
146-
156+
147157 if ( currentChapter . content ) {
148158 currentChapter . content += '\n'
149159 }
150160 currentChapter . content += line
151161 currentChapter . endLine = i
152162 }
153-
163+
154164 // 限制章节数量
155165 if ( chapters . length >= maxChapters ) {
156166 break
157167 }
158168 }
159-
169+
160170 // 添加最后一个章节
161- if ( currentChapter && currentChapter . content . trim ( ) . length >= minChapterLength ) {
171+ if ( currentChapter && currentChapter . content . trim ( ) . length > 0 ) {
162172 chapters . push ( currentChapter )
163173 }
164-
174+
175+ // 如果明确检测到章节标题,保留所有有内容的章节(不过滤短章节)
176+ // 仅在没有标题时才按长度过滤
177+ let filteredChapters
178+ if ( hasChapterTitles ) {
179+ filteredChapters = chapters . filter ( ch => ch . content . trim ( ) . length > 0 )
180+ } else {
181+ filteredChapters = chapters . filter ( ch => ch . content . trim ( ) . length >= minChapterLength )
182+ }
183+ if ( filteredChapters . length === 0 && chapters . length > 0 ) {
184+ filteredChapters = chapters
185+ }
186+
187+ // 如果第一章节内容很短(<100字符,通常是小说标题),合并到下一章节
188+ if ( filteredChapters . length >= 2 && filteredChapters [ 0 ] . content . trim ( ) . length < 100 && hasChapterTitles ) {
189+ filteredChapters [ 1 ] = {
190+ ...filteredChapters [ 1 ] ,
191+ content : filteredChapters [ 0 ] . content + '\n\n' + filteredChapters [ 1 ] . content
192+ }
193+ filteredChapters = filteredChapters . slice ( 1 )
194+ }
195+
165196 // 如果没有检测到章节标题,按长度自动分章
166- if ( ! hasChapterTitles && content . length > minChapterLength ) {
167- return autoSplitChapters ( content , options )
197+ if ( ! hasChapterTitles && cleanContent . length > minChapterLength ) {
198+ return autoSplitChapters ( cleanContent , options )
168199 }
169-
200+
170201 // 如果章节太少,尝试更宽松的检测
171- if ( chapters . length < 2 && content . length > minChapterLength * 2 ) {
172- return autoSplitChapters ( content , options )
202+ if ( filteredChapters . length < 2 && cleanContent . length > minChapterLength * 2 ) {
203+ return autoSplitChapters ( cleanContent , options )
173204 }
174-
175- return chapters
205+
206+ // 重新编号章节ID
207+ return filteredChapters . map ( ( ch , idx ) => ( { ...ch , id : idx } ) )
176208}
177209
178210/**
@@ -184,7 +216,7 @@ export function parseChapters(content, options = {}) {
184216function autoSplitChapters ( content , options = { } ) {
185217 const {
186218 chapterLength = 3000 , // 每章大约长度
187- minChapterLength = 500 // 最小章节长度
219+ minChapterLength = 200 // 最小章节长度
188220 } = options
189221
190222 const chapters = [ ]
0 commit comments