feat: ship v1.1.0 writer toolkit with templates, import, export, and inspiration capture
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>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user