adf877861d
Implement chapter templates, txt/md/docx import, submission export presets, and global inspiration shortcut. Split import handlers into a separate main bundle and fix EditorLayout setTarget loop that broke E2E. Co-authored-by: Cursor <cursoragent@cursor.com>
50 lines
1.1 KiB
TypeScript
50 lines
1.1 KiB
TypeScript
export interface TemplateContext {
|
|
chapterNumber: number
|
|
chapterTitle: string
|
|
penName: string
|
|
date: string
|
|
volumeName: string
|
|
previousChapterTitle: string
|
|
outlineItem: string
|
|
characterList: string
|
|
}
|
|
|
|
const VARS = [
|
|
'chapterNumber',
|
|
'chapterTitle',
|
|
'penName',
|
|
'date',
|
|
'volumeName',
|
|
'previousChapterTitle',
|
|
'outlineItem',
|
|
'characterList'
|
|
] as const
|
|
|
|
export function replaceChapterTemplate(body: string, ctx: TemplateContext): string {
|
|
let out = body
|
|
for (const key of VARS) {
|
|
out = out.split(`{${key}}`).join(String(ctx[key]))
|
|
}
|
|
return out
|
|
}
|
|
|
|
export function plainTextToEditorHtml(text: string): string {
|
|
const trimmed = text.trim()
|
|
if (!trimmed) return '<p></p>'
|
|
return trimmed
|
|
.split(/\n{2,}/)
|
|
.map((p) => `<p>${escapeHtml(p).replace(/\n/g, '<br>')}</p>`)
|
|
.join('')
|
|
}
|
|
|
|
function escapeHtml(text: string): string {
|
|
return text
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
}
|
|
|
|
export function bodyPlainToChapterHtml(bodyPlain: string): string {
|
|
return plainTextToEditorHtml(bodyPlain)
|
|
}
|