fix: each non-empty line as paragraph for Chinese novels, strip editorial notes

This commit is contained in:
YuanShiJiLoong committed 2026-02-24 22:23:23 +09:00
1 parent 44b5448124
commit 3e6bf362e4
2 files changed
+12 -16

No files matched your search

+8 -8
View File
@@ -896,16 +896,16 @@ export default function AiSidebar({ onInsertText }) {
className="btn-mini"
onClick={(e) => {
e.stopPropagation();
// 提取纯文本:去掉 [SETTINGS_ACTION]...[/SETTINGS_ACTION] 块和 markdown 标记
// 提取正文:去掉系统块、markdown标记、编辑点评
let text = (msg.content || '')
.replace(/\[SETTINGS_ACTION\][\s\S]*?\[\\?\/SETTINGS_ACTION\]/g, '')
.replace(/^#{1,6}\s+/gm, '') // 去掉标题 #
.replace(/\*\*(.+?)\*\*/g, '$1') // **粗体** → 粗体
.replace(/\*(.+?)\*/g, '$1') // *斜体* → 斜体
.replace(/`(.+?)`/g, '$1') // `代码` → 代码
.replace(/^[-*]\s+/gm, '') // 去掉无序列表标记
.replace(/^\d+\.\s+/gm, '') // 去掉有序列表标记
.replace(/\n{3,}/g, '\n\n') // 合并连续空行
.replace(/\n---[\s\S]*$/g, '') // 去掉 --- 分隔线以后的编辑点评
.replace(/^#{1,6}\s+/gm, '') // 去掉标题 #
.replace(/\*\*(.+?)\*\*/g, '$1') // **粗体** → 粗体
.replace(/\*(.+?)\*/g, '$1') // *斜体* → 斜体
.replace(/`(.+?)`/g, '$1') // `代码` → 代码
.replace(/^[-*]\s+/gm, '') // 去掉无序列表标记
.replace(/^\d+\.\s+/gm, '') // 去掉有序列表标记
.trim();
if (text) onInsertText?.(text);
}}
+4 -8
View File
@@ -160,18 +160,14 @@ const Editor = forwardRef(function Editor({ content, onUpdate, editable = true,
useImperativeHandle(ref, () => ({
insertText: (text) => {
if (!editor) return;
// 规范化:\r\n → \n,去掉每行首尾空白,合并所有连续空行为单个段落分隔
const normalized = text
// 每个非空行视为一个段落(中文小说标准格式),跳过空行
const lines = text
.replace(/\r\n/g, '\n')
.replace(/\r/g, '\n')
.split('\n')
.map(line => line.trim())
.join('\n')
.replace(/\n{2,}/g, '\n\n') // 2个以上换行 → 恰好2个
.trim();
// 按双换行分段,过滤空段
const paragraphs = normalized.split('\n\n').filter(p => p);
const html = paragraphs.map(p => `<p>${p}</p>`).join('');
.filter(line => line.length > 0);
const html = lines.map(line => `<p>${line}</p>`).join('');
editor.chain().focus().insertContent(html).run();
},
}), [editor]);