diff --git a/src/main/ipcHandlers.ts b/src/main/ipcHandlers.ts
index 464f7f0..18479a2 100644
--- a/src/main/ipcHandlers.ts
+++ b/src/main/ipcHandlers.ts
@@ -370,6 +370,7 @@ export function registerIpcHandlers(): void {
ipcMain.handle('export:projectPdf', async (event, opts: {
romanNumerals: boolean
+ showChapterTitle: boolean
includeCover: boolean
includeFrontMatter: boolean
pageFrom: number | null
@@ -507,21 +508,35 @@ export function registerIpcHandlers(): void {
})
}
- let chapterTitle: string
+ const fileName = doc.relativePath.split('/').pop()?.replace(/\.md$/, '') ?? doc.relativePath
let headerTitle: string
- if (!isFrontMatter && opts.romanNumerals) {
+ let headingHtml: string
+ if (!isFrontMatter) {
chapterIndex++
- chapterTitle = toRoman(chapterIndex)
- headerTitle = toRoman(chapterIndex)
+ const numeral = opts.romanNumerals ? toRoman(chapterIndex) : null
+ const title = opts.showChapterTitle ? fileName : null
+ const safe = (s: string): string => s.replace(/&/g, '&').replace(/${safe(numeral)}
${safe(title)}
`
+ headerTitle = `${numeral} — ${title}`
+ } else if (numeral) {
+ headingHtml = `${safe(numeral)}
`
+ headerTitle = numeral
+ } else if (title) {
+ headingHtml = `${safe(title)}
`
+ headerTitle = title
+ } else {
+ headingHtml = ''
+ headerTitle = fileName
+ }
} else {
- chapterTitle = doc.relativePath.split('/').pop()?.replace(/\.md$/, '') ?? doc.relativePath
- headerTitle = chapterTitle
+ headingHtml = `${fileName.replace(/&/g, '&').replace(/`
+ headerTitle = fileName
}
- const safeChapterTitle = chapterTitle.replace(/&/g, '&').replace(/${safeChapterTitle}
${contentHtml}`
+ bodyHtml: `
${headingHtml}${contentHtml}
`
})
}
diff --git a/src/renderer/components/Export/ExportDialog.tsx b/src/renderer/components/Export/ExportDialog.tsx
index df5a04a..dcfaa91 100644
--- a/src/renderer/components/Export/ExportDialog.tsx
+++ b/src/renderer/components/Export/ExportDialog.tsx
@@ -3,21 +3,34 @@ import './Export.css'
export interface ExportOptions {
romanNumerals: boolean
+ showChapterTitle: boolean
includeCover: boolean
includeFrontMatter: boolean
pageFrom: number | null
pageTo: number | null
}
+const STORAGE_KEY = 'exportDialogPrefs'
+
+function loadPrefs(): Pick {
+ try {
+ const raw = localStorage.getItem(STORAGE_KEY)
+ if (raw) return JSON.parse(raw)
+ } catch { /* ignore */ }
+ return { romanNumerals: true, showChapterTitle: false, includeCover: true, includeFrontMatter: true }
+}
+
interface Props {
onClose: () => void
onExport: (opts: ExportOptions) => void
}
export function ExportDialog({ onClose, onExport }: Props): JSX.Element {
- const [romanNumerals, setRomanNumerals] = useState(true)
- const [includeCover, setIncludeCover] = useState(true)
- const [includeFrontMatter, setIncludeFrontMatter] = useState(true)
+ const prefs = loadPrefs()
+ const [romanNumerals, setRomanNumerals] = useState(prefs.romanNumerals)
+ const [showChapterTitle, setShowChapterTitle] = useState(prefs.showChapterTitle)
+ const [includeCover, setIncludeCover] = useState(prefs.includeCover)
+ const [includeFrontMatter, setIncludeFrontMatter] = useState(prefs.includeFrontMatter)
const [pageFrom, setPageFrom] = useState('')
const [pageTo, setPageTo] = useState('')
const overlayRef = useRef(null)
@@ -34,10 +47,15 @@ export function ExportDialog({ onClose, onExport }: Props): JSX.Element {
if (e.target === overlayRef.current) onClose()
}
+ const savePrefs = (patch: Partial): void => {
+ const next = { romanNumerals, showChapterTitle, includeCover, includeFrontMatter, ...patch }
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(next))
+ }
+
const handleExport = (): void => {
const from = pageFrom.trim() ? parseInt(pageFrom, 10) : null
const to = pageTo.trim() ? parseInt(pageTo, 10) : null
- onExport({ romanNumerals, includeCover, includeFrontMatter, pageFrom: from, pageTo: to })
+ onExport({ romanNumerals, showChapterTitle, includeCover, includeFrontMatter, pageFrom: from, pageTo: to })
}
const pageRangeValid = (): boolean => {
@@ -63,17 +81,27 @@ export function ExportDialog({ onClose, onExport }: Props): JSX.Element {
setRomanNumerals(e.target.checked)}
+ onChange={e => { setRomanNumerals(e.target.checked); savePrefs({ romanNumerals: e.target.checked }) }}
/>
- Roman numeral chapter titles
- I, II, III… instead of file names
+ Roman numeral chapter numbers
+ I, II, III… before the chapter heading
+
+
+