From e74615ac1dfe1aadbf84a89eb4b5a6486448fdbc Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Wed, 4 Feb 2026 14:50:40 +0800 Subject: [PATCH] feat(export): add an option to export annotations as plain text, closes #3147 (#3165) --- .../public/locales/ar/translation.json | 4 +- .../public/locales/bn/translation.json | 4 +- .../public/locales/bo/translation.json | 4 +- .../public/locales/de/translation.json | 4 +- .../public/locales/el/translation.json | 4 +- .../public/locales/es/translation.json | 4 +- .../public/locales/fa/translation.json | 4 +- .../public/locales/fr/translation.json | 4 +- .../public/locales/hi/translation.json | 4 +- .../public/locales/id/translation.json | 4 +- .../public/locales/it/translation.json | 4 +- .../public/locales/ja/translation.json | 4 +- .../public/locales/ko/translation.json | 4 +- .../public/locales/ms/translation.json | 4 +- .../public/locales/nl/translation.json | 4 +- .../public/locales/pl/translation.json | 4 +- .../public/locales/pt/translation.json | 4 +- .../public/locales/ru/translation.json | 4 +- .../public/locales/si/translation.json | 4 +- .../public/locales/sv/translation.json | 4 +- .../public/locales/ta/translation.json | 4 +- .../public/locales/th/translation.json | 4 +- .../public/locales/tr/translation.json | 4 +- .../public/locales/uk/translation.json | 4 +- .../public/locales/vi/translation.json | 4 +- .../public/locales/zh-CN/translation.json | 4 +- .../public/locales/zh-TW/translation.json | 4 +- .../annotator/ExportMarkdownDialog.tsx | 182 +++++++++++------- apps/readest-app/src/services/constants.ts | 1 + apps/readest-app/src/types/book.ts | 1 + 30 files changed, 193 insertions(+), 99 deletions(-) diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 0d34fed3..1b5b93c0 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -1060,5 +1060,7 @@ "Library Sync Progress": "تقدم تزامن المكتبة", "Back to library": "العودة إلى المكتبة", "Manual": "يدوي", - "Group by...": "تجميع حسب..." + "Group by...": "تجميع حسب...", + "Export as Plain Text": "تصدير كنص بسيط", + "Export as Markdown": "تصدير بصيغة Markdown" } diff --git a/apps/readest-app/public/locales/bn/translation.json b/apps/readest-app/public/locales/bn/translation.json index 200e21b3..d2fc8da6 100644 --- a/apps/readest-app/public/locales/bn/translation.json +++ b/apps/readest-app/public/locales/bn/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "লাইব্রেরি সিঙ্ক অগ্রগতি", "Back to library": "লাইব্রেরিতে ফিরে যান", "Manual": "ম্যানুয়াল", - "Group by...": "গ্রুপ অনুযায়ী..." + "Group by...": "গ্রুপ অনুযায়ী...", + "Export as Plain Text": "সাধারণ টেক্সট হিসেবে এক্সপোর্ট করুন", + "Export as Markdown": "Markdown হিসেবে এক্সপোর্ট করুন" } diff --git a/apps/readest-app/public/locales/bo/translation.json b/apps/readest-app/public/locales/bo/translation.json index c2c578c6..0aed9c0d 100644 --- a/apps/readest-app/public/locales/bo/translation.json +++ b/apps/readest-app/public/locales/bo/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "དཔེ་མཛོད་མཉམ་འབྱུང་གི་རིམ་པ།", "Back to library": "དཔེ་མཛོད་ལ་ལོག་པ།", "Manual": "ལག་བཟོས།", - "Group by...": "དབྱེ་བ་འབྱེད་སྟངས།..." + "Group by...": "དབྱེ་བ་འབྱེད་སྟངས།...", + "Export as Plain Text": "ཡིག་རྐྱང་དཀྱུས་མར་ཕྱིར་འདྲེན།", + "Export as Markdown": "Markdown དུ་ཕྱིར་འདྲེན།" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index fabe9ea4..7b6a0ef0 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -1013,6 +1013,6 @@ "Back to library": "Zurück zur Bibliothek", "Manual": "Manuell", "Group by...": "Gruppieren nach...", - "Group By": "Gruppieren nach", - "Sort": "Sortieren" + "Export as Plain Text": "Als reinen Text exportieren", + "Export as Markdown": "Als Markdown exportieren" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index d92c281e..58ebe1d7 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "Πρόοδος συγχρονισμού βιβλιοθήκης", "Back to library": "Επιστροφή στη βιβλιοθήκη", "Manual": "Χειροκίνητα", - "Group by...": "Ομαδοποίηση κατά..." + "Group by...": "Ομαδοποίηση κατά...", + "Export as Plain Text": "Αποστολή ως απλό κείμενο", + "Export as Markdown": "Αποστολή ως Markdown" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index e37b9b5c..45a9c41a 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -1024,5 +1024,7 @@ "Library Sync Progress": "Progreso de sincronización de la biblioteca", "Back to library": "Volver a la biblioteca", "Manual": "Manual", - "Group by...": "Agrupar por..." + "Group by...": "Agrupar por...", + "Export as Plain Text": "Exportar como texto sin formato", + "Export as Markdown": "Exportar como Markdown" } diff --git a/apps/readest-app/public/locales/fa/translation.json b/apps/readest-app/public/locales/fa/translation.json index a85ff299..cc68ba99 100644 --- a/apps/readest-app/public/locales/fa/translation.json +++ b/apps/readest-app/public/locales/fa/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "پیشرفت همگام‌سازی کتابخانه", "Back to library": "بازگشت به کتابخانه", "Manual": "دستی", - "Group by...": "گروه‌بندی بر اساس..." + "Group by...": "گروه‌بندی بر اساس...", + "Export as Plain Text": "خروجی به صورت متن ساده", + "Export as Markdown": "خروجی به صورت Markdown" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 8c8b4baf..0ce114c6 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -1024,5 +1024,7 @@ "Library Sync Progress": "Progression de la synchronisation de la bibliothèque", "Back to library": "Retour à la bibliothèque", "Manual": "Manuel", - "Group by...": "Grouper par..." + "Group by...": "Grouper par...", + "Export as Plain Text": "Exporter en texte brut", + "Export as Markdown": "Exporter en Markdown" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 397d5b4e..817b084b 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "पुस्तकालय सिंक प्रगति", "Back to library": "लाइब्रेरी पर वापस जाएं", "Manual": "मैनुअल", - "Group by...": "इसके द्वारा समूहबद्ध करें..." + "Group by...": "इसके द्वारा समूहबद्ध करें...", + "Export as Plain Text": "प्लेन टेक्स्ट के रूप में एक्सपोर्ट करें", + "Export as Markdown": "Markdown के रूप में एक्सपोर्ट करें" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index 55603b13..8acd3d58 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "Kemajuan Sinkronisasi Pustaka", "Back to library": "Kembali ke perpustakaan", "Manual": "Manual", - "Group by...": "Kelompokkan menurut..." + "Group by...": "Kelompokkan menurut...", + "Export as Plain Text": "Ekspor sebagai Teks Biasa", + "Export as Markdown": "Ekspor sebagai Markdown" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index 1eabadd9..7c7ad062 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -1024,5 +1024,7 @@ "Library Sync Progress": "Avanzamento sincronizzazione libreria", "Back to library": "Torna alla libreria", "Manual": "Manuale", - "Group by...": "Raggruppa per..." + "Group by...": "Raggruppa per...", + "Export as Plain Text": "Esporta come testo normale", + "Export as Markdown": "Esporta come Markdown" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index b16410b3..2399007f 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "ライブラリ同期の進捗", "Back to library": "ライブラリに戻る", "Manual": "手動", - "Group by...": "グループ化..." + "Group by...": "グループ化...", + "Export as Plain Text": "プレーンテキストとして書き出し", + "Export as Markdown": "Markdownとして書き出し" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index 9c7d5118..e1d3e3d8 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "라이브러리 동기화 진행 상황", "Back to library": "라이브러리로 돌아가기", "Manual": "수동", - "Group by...": "그룹화 기준..." + "Group by...": "그룹화 기준...", + "Export as Plain Text": "일반 텍스트로 내보내기", + "Export as Markdown": "Markdown으로 내보내기" } diff --git a/apps/readest-app/public/locales/ms/translation.json b/apps/readest-app/public/locales/ms/translation.json index dc77a673..4b3bd8d0 100644 --- a/apps/readest-app/public/locales/ms/translation.json +++ b/apps/readest-app/public/locales/ms/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "Kemajuan Segerak Perpustakaan", "Back to library": "Kembali ke perpustakaan", "Manual": "Manual", - "Group by...": "Kumpulan mengikut..." + "Group by...": "Kumpulan mengikut...", + "Export as Plain Text": "Eksport sebagai Teks Biasa", + "Export as Markdown": "Eksport sebagai Markdown" } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index 58d7c0a6..3693dba2 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "Voortgang bibliotheeksynchronisatie", "Back to library": "Terug naar bibliotheek", "Manual": "Handmatig", - "Group by...": "Groeperen op..." + "Group by...": "Groeperen op...", + "Export as Plain Text": "Exporteren als platte tekst", + "Export as Markdown": "Exporteren als Markdown" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index ed1b0d0b..ed9f8072 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -1036,5 +1036,7 @@ "Library Sync Progress": "Postęp synchronizacji biblioteki", "Back to library": "Powrót do biblioteki", "Manual": "Ręcznie", - "Group by...": "Grupuj według..." + "Group by...": "Grupuj według...", + "Export as Plain Text": "Eksportuj jako zwykły tekst", + "Export as Markdown": "Eksportuj jako Markdown" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index b1a4f52a..a57e4dc4 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -1024,5 +1024,7 @@ "Library Sync Progress": "Progresso de sincronização da biblioteca", "Back to library": "Voltar à biblioteca", "Manual": "Manual", - "Group by...": "Agrupar por..." + "Group by...": "Agrupar por...", + "Export as Plain Text": "Exportar como texto simples", + "Export as Markdown": "Exportar como Markdown" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index ee886ce7..de484d59 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -1036,5 +1036,7 @@ "Library Sync Progress": "Прогресс синхронизации библиотеки", "Back to library": "Назад в библиотеку", "Manual": "Вручную", - "Group by...": "Группировать по..." + "Group by...": "Группировать по...", + "Export as Plain Text": "Экспортировать как обычный текст", + "Export as Markdown": "Экспортировать как Markdown" } diff --git a/apps/readest-app/public/locales/si/translation.json b/apps/readest-app/public/locales/si/translation.json index 277b17a8..da7aae83 100644 --- a/apps/readest-app/public/locales/si/translation.json +++ b/apps/readest-app/public/locales/si/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "පුස්තකාල සමමුහුර්ත කිරීමේ ප්‍රගතිය", "Back to library": "පුස්තකාලයට ආපසු", "Manual": "අත්පොත", - "Group by...": "මගින් සමූහනය කරන්න..." + "Group by...": "මගින් සමූහනය කරන්න...", + "Export as Plain Text": "සාමාන්‍ය පෙළ ලෙස අපනයනය කරන්න", + "Export as Markdown": "Markdown ලෙස අපනයනය කරන්න" } diff --git a/apps/readest-app/public/locales/sv/translation.json b/apps/readest-app/public/locales/sv/translation.json index e0d26bff..f8e1713f 100644 --- a/apps/readest-app/public/locales/sv/translation.json +++ b/apps/readest-app/public/locales/sv/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "Synkroniseringsframsteg för bibliotek", "Back to library": "Tillbaka till biblioteket", "Manual": "Manuellt", - "Group by...": "Gruppera efter..." + "Group by...": "Gruppera efter...", + "Export as Plain Text": "Exportera som vanlig text", + "Export as Markdown": "Exportera som Markdown" } diff --git a/apps/readest-app/public/locales/ta/translation.json b/apps/readest-app/public/locales/ta/translation.json index 59239543..6a81cd9f 100644 --- a/apps/readest-app/public/locales/ta/translation.json +++ b/apps/readest-app/public/locales/ta/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "நூலக ஒத்திசைவு நிலை", "Back to library": "நூலகத்திற்குத் திரும்பு", "Manual": "கையேடு", - "Group by...": "இதன் படி குழுவாக்கு..." + "Group by...": "இதன் படி குழுவாக்கு...", + "Export as Plain Text": "எளிய உரையாக ஏற்றுமதி செய்", + "Export as Markdown": "Markdown ஆக ஏற்றுமதி செய்" } diff --git a/apps/readest-app/public/locales/th/translation.json b/apps/readest-app/public/locales/th/translation.json index adf43733..487b91d2 100644 --- a/apps/readest-app/public/locales/th/translation.json +++ b/apps/readest-app/public/locales/th/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "ความคืบหน้าการซิงค์ห้องสมุด", "Back to library": "กลับไปที่ห้องสมุด", "Manual": "ทำเอง", - "Group by...": "จัดกลุ่มตาม..." + "Group by...": "จัดกลุ่มตาม...", + "Export as Plain Text": "ส่งออกเป็นข้อความธรรมดา", + "Export as Markdown": "ส่งออกเป็น Markdown" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index af9c26e1..5a707367 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -1012,5 +1012,7 @@ "Library Sync Progress": "Kütüphane Senkronizasyon İlerlemesi", "Back to library": "Kütüphaneye dön", "Manual": "Manuel", - "Group by...": "Şuna göre grupla..." + "Group by...": "Şuna göre grupla...", + "Export as Plain Text": "Düz Metin Olarak Dışa Aktar", + "Export as Markdown": "Markdown Olarak Dışa Aktar" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index 59b26950..869b5821 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -1036,5 +1036,7 @@ "Library Sync Progress": "Прогрес синхронізації бібліотеки", "Back to library": "Назад до бібліотеки", "Manual": "Вручну", - "Group by...": "Групувати за..." + "Group by...": "Групувати за...", + "Export as Plain Text": "Експортувати як звичайний текст", + "Export as Markdown": "Експортувати як Markdown" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 1ce2c795..a44b0629 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "Tiến trình đồng bộ hóa thư viện", "Back to library": "Quay lại thư viện", "Manual": "Thủ công", - "Group by...": "Nhóm theo..." + "Group by...": "Nhóm theo...", + "Export as Plain Text": "Xuất dưới dạng văn bản thuần túy", + "Export as Markdown": "Xuất dưới dạng Markdown" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index bc13edc1..52aa99a3 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "库同步进度", "Back to library": "返回书库", "Manual": "手动", - "Group by...": "分组方式..." + "Group by...": "分组方式...", + "Export as Plain Text": "导出为纯文本", + "Export as Markdown": "导出为 Markdown" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 00fa2043..1245d32b 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -1000,5 +1000,7 @@ "Library Sync Progress": "資料庫同步進度", "Back to library": "返回書庫", "Manual": "手動", - "Group by...": "分組方式..." + "Group by...": "分組方式...", + "Export as Plain Text": "匯出為純文字", + "Export as Markdown": "匯出為 Markdown" } diff --git a/apps/readest-app/src/app/reader/components/annotator/ExportMarkdownDialog.tsx b/apps/readest-app/src/app/reader/components/annotator/ExportMarkdownDialog.tsx index f8bc81e4..f10238da 100644 --- a/apps/readest-app/src/app/reader/components/annotator/ExportMarkdownDialog.tsx +++ b/apps/readest-app/src/app/reader/components/annotator/ExportMarkdownDialog.tsx @@ -94,8 +94,23 @@ const ExportMarkdownDialog: React.FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [exportConfig, envConfig, bookKey]); + // Helper function to strip markdown formatting + const stripMarkdown = (text: string): string => { + return text + .replace(/^#{1,6}\s+/gm, '') // Remove headers + .replace(/\*\*(.+?)\*\*/g, '$1') // Remove bold + .replace(/\*(.+?)\*/g, '$1') // Remove italic + .replace(/^>\s+/gm, '') // Remove blockquotes + .replace(/^---$/gm, '') // Remove horizontal rules + .replace(/^\s*[-*+]\s+/gm, '') // Remove list markers + .replace(/\[(.+?)\]\(.+?\)/g, '$1') // Remove links + .trim(); + }; + // Generate markdown preview based on current format settings const markdownPreview = useMemo(() => { + let output = ''; + if (exportConfig.useCustomTemplate) { // Prepare data for template rendering const sortedGroups = Object.values(booknoteGroups).sort((a, b) => a.id - b.id); @@ -116,75 +131,82 @@ const ExportMarkdownDialog: React.FC = ({ })), }; - return renderNoteTemplate(exportConfig.customTemplate, templateData); - } + output = renderNoteTemplate(exportConfig.customTemplate, templateData); + } else { + // Default formatting (non-template mode) + const sortedGroups = Object.values(booknoteGroups).sort((a, b) => a.id - b.id); - // Default formatting (non-template mode) - const sortedGroups = Object.values(booknoteGroups).sort((a, b) => a.id - b.id); + const lines: string[] = []; - const lines: string[] = []; - - // Add title - if (exportConfig.includeTitle) { - lines.push(`# ${bookTitle}`); - } - - // Add author - if (exportConfig.includeAuthor && bookAuthor) { - lines.push(`**${_('Author')}**: ${bookAuthor}`); - lines.push(''); - } - - // Add export date - if (exportConfig.includeDate) { - lines.push(`**${_('Exported from Readest')}**: ${new Date().toISOString().slice(0, 10)}`); - lines.push(''); - } - - if (exportConfig.includeTitle || exportConfig.includeAuthor || exportConfig.includeDate) { - lines.push('---'); - lines.push(''); - } - - lines.push(`## ${_('Highlights & Annotations')}`); - lines.push(''); - - for (const group of sortedGroups) { - // Add chapter title - if (exportConfig.includeChapterTitles) { - const chapterTitle = group.label || _('Untitled'); - lines.push(`### ${chapterTitle}`); + // Add title + if (exportConfig.includeTitle) { + lines.push(`# ${bookTitle}`); } - for (const note of group.booknotes) { - // Add quote - if (exportConfig.includeQuotes && note.text) { - lines.push(`> ${note.text}`); - } - - // Add note - if (exportConfig.includeNotes && note.note) { - lines.push(''); - lines.push(`**${_('Note')}**:: ${note.note}`); - } - - // Add timestamp - if (exportConfig.includeTimestamp && note.updatedAt) { - const timestamp = new Date(note.updatedAt).toLocaleString(); - lines.push(''); - lines.push(`*${_('Time:')} ${timestamp}*`); - } - - lines.push(exportConfig.noteSeparator); + // Add author + if (exportConfig.includeAuthor && bookAuthor) { + lines.push(`**${_('Author')}**: ${bookAuthor}`); + lines.push(''); } - if (exportConfig.includeChapterSeparator) { + // Add export date + if (exportConfig.includeDate) { + lines.push(`**${_('Exported from Readest')}**: ${new Date().toISOString().slice(0, 10)}`); + lines.push(''); + } + + if (exportConfig.includeTitle || exportConfig.includeAuthor || exportConfig.includeDate) { lines.push('---'); lines.push(''); } + + lines.push(`## ${_('Highlights & Annotations')}`); + lines.push(''); + + for (const group of sortedGroups) { + // Add chapter title + if (exportConfig.includeChapterTitles) { + const chapterTitle = group.label || _('Untitled'); + lines.push(`### ${chapterTitle}`); + } + + for (const note of group.booknotes) { + // Add quote + if (exportConfig.includeQuotes && note.text) { + lines.push(`> ${note.text}`); + } + + // Add note + if (exportConfig.includeNotes && note.note) { + lines.push(''); + lines.push(`**${_('Note')}**: ${note.note}`); + } + + // Add timestamp + if (exportConfig.includeTimestamp && note.updatedAt) { + const timestamp = new Date(note.updatedAt).toLocaleString(); + lines.push(''); + lines.push(`*${_('Time:')} ${timestamp}*`); + } + + lines.push(exportConfig.noteSeparator); + } + + if (exportConfig.includeChapterSeparator) { + lines.push('---'); + lines.push(''); + } + } + + output = lines.join('\n'); } - return lines.join('\n'); + // Strip markdown if plain text export is enabled + if (exportConfig.exportAsPlainText) { + output = stripMarkdown(output); + } + + return output; }, [exportConfig, booknoteGroups, bookTitle, bookAuthor, _]); // Convert markdown to HTML for preview @@ -493,11 +515,12 @@ const ExportMarkdownDialog: React.FC = ({ {_('Show Source')} - {showSource ? ( + {showSource || exportConfig.exportAsPlainText ? (
{markdownPreview || _('No content to preview')} @@ -518,17 +541,34 @@ const ExportMarkdownDialog: React.FC = ({
{/* Footer Actions */} -
- - +
+
+ +
+
+ + +
diff --git a/apps/readest-app/src/services/constants.ts b/apps/readest-app/src/services/constants.ts index 1908028d..179ddc26 100644 --- a/apps/readest-app/src/services/constants.ts +++ b/apps/readest-app/src/services/constants.ts @@ -297,6 +297,7 @@ export const DEFAULT_NOTE_EXPORT_CONFIG: NoteExportConfig = { noteSeparator: '\n\n', useCustomTemplate: false, customTemplate: '', + exportAsPlainText: false, }; export const DEFAULT_ANNOTATOR_CONFIG: AnnotatorConfig = { diff --git a/apps/readest-app/src/types/book.ts b/apps/readest-app/src/types/book.ts index 384cbd13..f47394d6 100644 --- a/apps/readest-app/src/types/book.ts +++ b/apps/readest-app/src/types/book.ts @@ -246,6 +246,7 @@ export interface NoteExportConfig { noteSeparator: string; useCustomTemplate: boolean; customTemplate: string; + exportAsPlainText: boolean; } export interface AnnotatorConfig {