@fiduswriter/books-document 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/exporter/bits/index.d.ts +3 -1
  2. package/dist/exporter/bits/index.d.ts.map +1 -1
  3. package/dist/exporter/bits/index.js +16 -6
  4. package/dist/exporter/bits/index.js.map +1 -1
  5. package/dist/exporter/docx/index.d.ts +3 -1
  6. package/dist/exporter/docx/index.d.ts.map +1 -1
  7. package/dist/exporter/docx/index.js +16 -7
  8. package/dist/exporter/docx/index.js.map +1 -1
  9. package/dist/exporter/epub/index.d.ts +3 -1
  10. package/dist/exporter/epub/index.d.ts.map +1 -1
  11. package/dist/exporter/epub/index.js +13 -5
  12. package/dist/exporter/epub/index.js.map +1 -1
  13. package/dist/exporter/html/index.d.ts +3 -1
  14. package/dist/exporter/html/index.d.ts.map +1 -1
  15. package/dist/exporter/html/index.js +15 -6
  16. package/dist/exporter/html/index.js.map +1 -1
  17. package/dist/exporter/latex/index.d.ts +3 -1
  18. package/dist/exporter/latex/index.d.ts.map +1 -1
  19. package/dist/exporter/latex/index.js +11 -2
  20. package/dist/exporter/latex/index.js.map +1 -1
  21. package/dist/exporter/native/index.d.ts +4 -2
  22. package/dist/exporter/native/index.d.ts.map +1 -1
  23. package/dist/exporter/native/index.js +17 -7
  24. package/dist/exporter/native/index.js.map +1 -1
  25. package/dist/exporter/odt/index.d.ts +3 -1
  26. package/dist/exporter/odt/index.d.ts.map +1 -1
  27. package/dist/exporter/odt/index.js +16 -7
  28. package/dist/exporter/odt/index.js.map +1 -1
  29. package/dist/exporter/tools.d.ts +2 -0
  30. package/dist/exporter/tools.d.ts.map +1 -1
  31. package/dist/exporter/tools.js +8 -10
  32. package/dist/exporter/tools.js.map +1 -1
  33. package/package.json +2 -2
  34. package/src/exporter/bits/index.ts +20 -9
  35. package/src/exporter/docx/index.ts +23 -8
  36. package/src/exporter/epub/index.ts +18 -6
  37. package/src/exporter/html/index.ts +21 -8
  38. package/src/exporter/latex/index.ts +15 -2
  39. package/src/exporter/native/index.ts +33 -13
  40. package/src/exporter/odt/index.ts +23 -8
  41. package/src/exporter/tools.ts +17 -17
@@ -4,11 +4,12 @@
4
4
 
5
5
  import type {Schema} from "prosemirror-model"
6
6
  import type {CSL, User} from "@fiduswriter/document"
7
+ import type {ProgressCallback} from "@fiduswriter/document/exporter/tools/progress"
7
8
  import {HTMLExporter} from "@fiduswriter/document/exporter/html/index"
8
9
  import {createSlug} from "@fiduswriter/document/exporter/tools/file"
9
10
  import {ZipFileCreator} from "@fiduswriter/document/exporter/tools/zip"
10
11
  import {LANGUAGES} from "@fiduswriter/document/schema/const"
11
- import {addAlert, get, staticUrl} from "fwtoolkit"
12
+ import {gettext, get, staticUrl} from "fwtoolkit"
12
13
  import pretty from "pretty"
13
14
 
14
15
  import type {Book, BookStyle, BookStyles, DocumentListEntry} from "../../types.js"
@@ -74,6 +75,7 @@ export class HTMLBookExporter {
74
75
  singleFileHTMLBookTemplate: (...args: any[]) => string
75
76
  singleFileHTMLBookCSSTemplate: (...args: any[]) => string
76
77
  styleSheets: StyleSheet[]
78
+ progressCallback?: ProgressCallback
77
79
 
78
80
  constructor(
79
81
  schema: Schema,
@@ -112,16 +114,21 @@ export class HTMLBookExporter {
112
114
  this.styleSheets = [{url: staticUrl("css/book.css")}]
113
115
  }
114
116
 
115
- async init(): Promise<Blob | false | void> {
117
+ async init(progressCallback?: ProgressCallback): Promise<Blob | false | void> {
118
+ this.progressCallback = progressCallback
119
+ this.progressCallback?.(
120
+ gettext("HTML book export has been initiated."),
121
+ 0
122
+ )
116
123
  if (this.book.chapters.length === 0) {
117
- addAlert(
118
- "error",
124
+ throw new Error(
119
125
  gettext("Book cannot be exported due to lack of chapters.")
120
126
  )
121
- return false
122
127
  }
123
128
 
124
- await getMissingChapterData(this.book, this.docList, this.schema)
129
+ await getMissingChapterData(this.book, this.docList, this.schema, {
130
+ progressCallback: this.progressCallback
131
+ })
125
132
 
126
133
  this.addBookStyle()
127
134
 
@@ -147,6 +154,7 @@ export class HTMLBookExporter {
147
154
  }
148
155
 
149
156
  async exportChapters(): Promise<Blob | void> {
157
+ this.progressCallback?.(gettext("Exporting book chapters..."), 20)
150
158
  let footnoteCounter = 0,
151
159
  affiliationCounter = 0,
152
160
  figureCounter = 0,
@@ -154,9 +162,11 @@ export class HTMLBookExporter {
154
162
  photoCounter = 0,
155
163
  tableCounter = 0
156
164
 
157
- for (const chapterInfo of this.book.chapters.sort(
165
+ const sortedChapters = this.book.chapters.sort(
158
166
  (a, b) => a.number - b.number
159
- )) {
167
+ )
168
+
169
+ for (const chapterInfo of sortedChapters) {
160
170
  const chapterNumber = chapterInfo.number
161
171
  const chapterPart = chapterInfo.part || ""
162
172
  const doc = this.docList.find(d => d.id === chapterInfo.text)
@@ -254,10 +264,12 @@ export class HTMLBookExporter {
254
264
  })
255
265
  }
256
266
 
267
+ this.progressCallback?.(gettext("Assembling HTML book..."), 80)
257
268
  return this.exportBook()
258
269
  }
259
270
 
260
271
  async exportBook(): Promise<Blob | void> {
272
+ this.progressCallback?.(gettext("Finalizing HTML book..."), 90)
261
273
  if (this.math) {
262
274
  this.includeZips.push({
263
275
  directory: "css",
@@ -426,6 +438,7 @@ export class HTMLBookExporter {
426
438
  new Date(this.updated * 1000)
427
439
  )
428
440
  const blob = await zipper.init()
441
+ this.progressCallback?.(gettext("HTML book export complete."), 100)
429
442
  return this.download(blob)
430
443
  }
431
444
 
@@ -4,11 +4,13 @@
4
4
 
5
5
  import type {Schema} from "prosemirror-model"
6
6
  import type {User} from "@fiduswriter/document"
7
+ import type {ProgressCallback} from "@fiduswriter/document/exporter/tools/progress"
7
8
  import {BibLatexExporter} from "biblatex-csl-converter"
8
9
  import {LatexExporterConvert} from "@fiduswriter/document/exporter/latex/convert"
9
10
  import {removeHidden} from "@fiduswriter/document/exporter/tools/doc_content"
10
11
  import {createSlug} from "@fiduswriter/document/exporter/tools/file"
11
12
  import {ZipFileCreator} from "@fiduswriter/document/exporter/tools/zip"
13
+ import {gettext} from "fwtoolkit"
12
14
 
13
15
  import type {Book, DocumentListEntry} from "../../types.js"
14
16
  import {getMissingChapterData} from "../tools.js"
@@ -33,6 +35,7 @@ export class LatexBookExporter {
33
35
  textFiles: TextFile[]
34
36
  httpFiles: HttpFile[]
35
37
  zipFileName: string
38
+ progressCallback?: ProgressCallback
36
39
 
37
40
  constructor(
38
41
  schema: Schema,
@@ -53,13 +56,19 @@ export class LatexBookExporter {
53
56
  this.zipFileName = ""
54
57
  }
55
58
 
56
- init(): Promise<Blob> {
59
+ init(progressCallback?: ProgressCallback): Promise<Blob> {
60
+ this.progressCallback = progressCallback
61
+ this.progressCallback?.(
62
+ gettext("LaTeX book export has been initiated."),
63
+ 0
64
+ )
57
65
  return getMissingChapterData(this.book, this.docList, this.schema).then(
58
66
  () => this.export()
59
67
  )
60
68
  }
61
69
 
62
70
  export(): Promise<Blob> {
71
+ this.progressCallback?.(gettext("Preparing LaTeX book..."), 10)
63
72
  this.zipFileName = `${createSlug(this.book.title)}.latex.zip`
64
73
  let bibIds: string[] = []
65
74
  let imageIds: string[] = []
@@ -140,6 +149,7 @@ export class LatexBookExporter {
140
149
  }
141
150
 
142
151
  createZip(): Promise<Blob> {
152
+ this.progressCallback?.(gettext("Finalizing LaTeX book..."), 90)
143
153
  const zipper = new ZipFileCreator(
144
154
  this.textFiles,
145
155
  this.httpFiles,
@@ -148,7 +158,10 @@ export class LatexBookExporter {
148
158
  this.updated
149
159
  )
150
160
 
151
- return zipper.init().then(blob => this.download(blob))
161
+ return zipper.init().then(blob => {
162
+ this.progressCallback?.(gettext("LaTeX book export complete."), 100)
163
+ return this.download(blob)
164
+ })
152
165
  }
153
166
 
154
167
  download(blob: Blob): Blob {
@@ -6,11 +6,12 @@ import type {Schema} from "prosemirror-model"
6
6
  import {ShrinkFidus} from "@fiduswriter/document/exporter/native/shrink"
7
7
  import {createSlug} from "@fiduswriter/document/exporter/tools/file"
8
8
  import {ZipFileCreator} from "@fiduswriter/document/exporter/tools/zip"
9
- import {addAlert} from "fwtoolkit"
9
+ import {gettext} from "fwtoolkit"
10
10
 
11
11
  import {FIDUSBOOK_VERSION} from "../../schema/index.js"
12
12
  import type {Book, DocumentListEntry, User} from "../../types.js"
13
13
  import {getMissingChapterData} from "../tools.js"
14
+ import type {ProgressCallback} from "@fiduswriter/document/exporter/native/shrink"
14
15
 
15
16
  interface FileInclude {
16
17
  url: string
@@ -31,40 +32,54 @@ export class NativeBookExporter {
31
32
  documentList: DocumentListEntry[]
32
33
  updated: any
33
34
 
35
+ progressCallback?: ProgressCallback
36
+
34
37
  constructor(
35
38
  schema: Schema,
36
39
  book: Book,
37
40
  user: User,
38
41
  documentList: DocumentListEntry[],
39
- updated: any
42
+ updated: any,
43
+ progressCallback?: ProgressCallback
40
44
  ) {
41
45
  this.schema = schema
42
46
  this.book = book
43
47
  this.user = user
44
48
  this.documentList = documentList
45
49
  this.updated = updated
50
+ this.progressCallback = progressCallback
46
51
  }
47
52
 
48
- init(): Promise<Blob> {
53
+ init(progressCallback?: ProgressCallback): Promise<Blob> {
54
+ if (progressCallback) {
55
+ this.progressCallback = progressCallback
56
+ }
49
57
  if (this.book.chapters.length === 0) {
50
- addAlert(
51
- "error",
52
- gettext("Book cannot be exported due to lack of chapters.")
58
+ this.progressCallback?.(
59
+ gettext("Book cannot be exported due to lack of chapters."),
60
+ 100
53
61
  )
54
62
  return Promise.resolve(new Blob([]))
55
63
  }
56
64
 
57
- addAlert(
58
- "info",
59
- `${this.book.title}: ${gettext("Fidusbook export has been initiated.")}`
65
+ this.progressCallback?.(
66
+ `${this.book.title}: ${gettext("Fidusbook export has been initiated.")}`,
67
+ 0
60
68
  )
61
69
 
62
70
  return getMissingChapterData(this.book, this.documentList, this.schema)
63
71
  .then(() => this.exportContents())
72
+ .then(blob => {
73
+ this.progressCallback?.(
74
+ `${this.book.title}: ${gettext("Fidusbook export complete.")}`,
75
+ 100
76
+ )
77
+ return blob
78
+ })
64
79
  .catch(error => {
65
- addAlert(
66
- "error",
67
- `${this.book.title}: ${gettext("Fidusbook export failed.")}`
80
+ this.progressCallback?.(
81
+ `${this.book.title}: ${gettext("Fidusbook export failed.")}`,
82
+ 100
68
83
  )
69
84
  throw error
70
85
  })
@@ -113,11 +128,16 @@ export class NativeBookExporter {
113
128
  return processChapter(index + 1)
114
129
  }
115
130
 
131
+ this.progressCallback?.(
132
+ gettext("Exporting chapter %s of %s..."),
133
+ Math.round((index / sortedChapters.length) * 90)
134
+ )
135
+
116
136
  const shrinker = new ShrinkFidus(
117
137
  doc as any,
118
138
  {db: doc.images || {}},
119
139
  {db: doc.bibliography || {}},
120
- true
140
+ this.progressCallback
121
141
  )
122
142
 
123
143
  return shrinker
@@ -4,13 +4,14 @@
4
4
 
5
5
  import type {Schema} from "prosemirror-model"
6
6
  import type {CSL, User} from "@fiduswriter/document"
7
+ import type {ProgressCallback} from "@fiduswriter/document/exporter/tools/progress"
7
8
  import {
8
9
  fixTables,
9
10
  removeHidden
10
11
  } from "@fiduswriter/document/exporter/tools/doc_content"
11
12
  import {createSlug} from "@fiduswriter/document/exporter/tools/file"
12
13
  import {XmlZip} from "@fiduswriter/document/exporter/tools/xml_zip"
13
- import {addAlert} from "fwtoolkit"
14
+ import {gettext} from "fwtoolkit"
14
15
 
15
16
  import {ODTExporterCitations} from "@fiduswriter/document/exporter/odt/citations"
16
17
  import {ODTExporterImages} from "@fiduswriter/document/exporter/odt/images"
@@ -36,6 +37,7 @@ export class ODTBookExporter {
36
37
  textFiles: Array<Record<string, unknown>>
37
38
  httpFiles: Array<Record<string, unknown>>
38
39
  mimeType: string
40
+ progressCallback?: ProgressCallback
39
41
 
40
42
  constructor(
41
43
  schema: Schema,
@@ -58,23 +60,27 @@ export class ODTBookExporter {
58
60
  this.mimeType = "application/vnd.oasis.opendocument.text"
59
61
  }
60
62
 
61
- init(): Promise<Blob> | false {
63
+ init(progressCallback?: ProgressCallback): Promise<Blob> | false {
64
+ this.progressCallback = progressCallback
65
+ this.progressCallback?.(
66
+ gettext("ODT book export has been initiated."),
67
+ 0
68
+ )
62
69
  if (this.book.chapters.length === 0) {
63
- addAlert(
64
- "error",
70
+ throw new Error(
65
71
  gettext("Book cannot be exported due to lack of chapters.")
66
72
  )
67
- return false
68
73
  }
69
74
  return getMissingChapterData(
70
75
  this.book,
71
76
  this.docList,
72
77
  this.schema,
73
- {rawContent: true}
78
+ {rawContent: true, progressCallback: this.progressCallback}
74
79
  ).then(() => this.export())
75
80
  }
76
81
 
77
82
  export(): Promise<Blob> {
83
+ this.progressCallback?.(gettext("Preparing ODT book..."), 10)
78
84
  this.book.chapters.sort((a, b) => (a.number > b.number ? 1 : -1))
79
85
  const xml = new XmlZip(this.templateUrl, this.mimeType)
80
86
  const styles = new ODTExporterStyles(xml as any)
@@ -95,8 +101,17 @@ export class ODTBookExporter {
95
101
  .then(() => metadata.init())
96
102
  .then(() => math.init())
97
103
  .then(() => this.exportChapters(xml as any, render, styles, math, tracks))
98
- .then(() => xml.prepareBlob())
99
- .then(blob => this.download(blob))
104
+ .then(() => {
105
+ this.progressCallback?.(gettext("Finalizing ODT book..."), 90)
106
+ return xml.prepareBlob()
107
+ })
108
+ .then(blob => {
109
+ this.progressCallback?.(
110
+ gettext("ODT book export complete."),
111
+ 100
112
+ )
113
+ return this.download(blob)
114
+ })
100
115
  }
101
116
 
102
117
  exportChapters(
@@ -10,7 +10,8 @@
10
10
  import type {Schema} from "prosemirror-model"
11
11
  import {getSettings} from "@fiduswriter/document/schema/convert"
12
12
  import {acceptAllNoInsertions} from "@fiduswriter/document/transform"
13
- import {addAlert} from "fwtoolkit"
13
+ import {gettext} from "fwtoolkit"
14
+ import type {ProgressCallback} from "@fiduswriter/document/exporter/tools/progress"
14
15
 
15
16
  import type {
16
17
  ChapterLoader,
@@ -58,30 +59,35 @@ export async function getMissingChapterData(
58
59
  rawContent?: boolean
59
60
  loader?: ChapterLoader
60
61
  e2ee?: E2EEStrategy
62
+ progressCallback?: ProgressCallback
61
63
  } = {}
62
64
  ): Promise<void> {
63
- const {rawContent = false, loader = noopChapterLoader, e2ee = noopE2EEStrategy} =
64
- options
65
+ const {
66
+ rawContent = false,
67
+ loader = noopChapterLoader,
68
+ e2ee = noopE2EEStrategy,
69
+ progressCallback
70
+ } = options
71
+
72
+ progressCallback?.(gettext("Loading chapter data..."), 0)
65
73
 
66
74
  const bookDocuments = book.chapters.map(chapter =>
67
75
  documentList.find(doc => doc.id === chapter.text)
68
76
  )
69
77
 
70
78
  if (bookDocuments.some(doc => doc === undefined)) {
71
- addAlert(
72
- "error",
79
+ throw new Error(
73
80
  gettext(
74
81
  "Cannot produce book as you lack access rights to its chapters."
75
82
  )
76
83
  )
77
- throw new Error(
78
- "Cannot produce book as you lack access rights to its chapters."
79
- )
80
84
  }
81
85
 
82
86
  const docIds = book.chapters.map(chapter => chapter.text)
83
87
  await loader.loadChapters(docIds, documentList, schema, rawContent)
84
88
  await decryptE2EEChapters(book, documentList, schema, rawContent, e2ee)
89
+
90
+ progressCallback?.(gettext("Chapter data loaded."), 50)
85
91
  }
86
92
 
87
93
  /**
@@ -106,13 +112,11 @@ async function decryptE2EEChapters(
106
112
 
107
113
  const unlocked = await e2ee.ensurePassphraseUnlocked()
108
114
  if (!unlocked) {
109
- addAlert(
110
- "error",
115
+ throw new Error(
111
116
  gettext(
112
117
  "A personal passphrase is required to work with books that contain encrypted chapters. Please set up or unlock your personal passphrase in your profile settings."
113
118
  )
114
119
  )
115
- throw new Error("Passphrase required for encrypted chapters")
116
120
  }
117
121
 
118
122
  await Promise.all(
@@ -127,11 +131,9 @@ async function decryptE2EEChapters(
127
131
 
128
132
  const password = await e2ee.getDocumentPassword(Number(doc.id))
129
133
  if (!password) {
130
- addAlert(
131
- "error",
134
+ throw new Error(
132
135
  `${gettext("No encryption key found for chapter:")} ${chapterLabel}. ${gettext("The key may not have been shared with you.")}`
133
136
  )
134
- throw new Error(`No encryption key for document ${String(doc.id)}`)
135
137
  }
136
138
 
137
139
  if (!doc.e2ee_salt) {
@@ -213,11 +215,9 @@ async function decryptE2EEChapters(
213
215
  ) {
214
216
  throw err
215
217
  }
216
- addAlert(
217
- "error",
218
+ throw new Error(
218
219
  `${gettext("Could not decrypt chapter:")} ${chapterLabel}. ${gettext("The document may have been re-encrypted with a different password.")}`
219
220
  )
220
- throw err
221
221
  }
222
222
  })
223
223
  )