bookish-press 0.4.45 → 0.4.47

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 (533) hide show
  1. package/.env.example +8 -0
  2. package/.firebaserc +8 -0
  3. package/.prettierignore +8 -0
  4. package/.prettierrc.json +5 -0
  5. package/_update-notifier-last-checked +0 -0
  6. package/firebase.json +46 -0
  7. package/firestore.indexes.json +4 -0
  8. package/firestore.rules +59 -0
  9. package/functions/.eslintrc.js +28 -0
  10. package/functions/package-lock.json +12595 -0
  11. package/functions/package.json +43 -0
  12. package/functions/src/index.ts +345 -0
  13. package/functions/tsconfig.dev.json +3 -0
  14. package/functions/tsconfig.json +15 -0
  15. package/package.json +53 -270
  16. package/scripts/claims.cjs +99 -0
  17. package/src/app.d.ts +9 -0
  18. package/src/app.html +24 -0
  19. package/src/lib/components/Auth.svelte +65 -0
  20. package/{components/Authentication.d.ts → src/lib/components/Authentication.ts} +2 -0
  21. package/{components → src/lib/components}/BookPreview.svelte +27 -22
  22. package/{components → src/lib/components}/External.svelte +2 -1
  23. package/src/lib/components/Link.svelte +58 -0
  24. package/{components → src/lib/components}/app/BookList.svelte +6 -3
  25. package/{components → src/lib/components}/app/Button.svelte +5 -4
  26. package/{components → src/lib/components}/app/Feedback.svelte +11 -7
  27. package/{components → src/lib/components}/app/Head.svelte +2 -1
  28. package/{components → src/lib/components}/app/Large.svelte +0 -0
  29. package/{components → src/lib/components}/app/Lead.svelte +0 -0
  30. package/{components → src/lib/components}/app/Link.svelte +4 -3
  31. package/{components → src/lib/components}/app/Options.svelte +5 -4
  32. package/{components → src/lib/components}/app/Paragraph.svelte +2 -1
  33. package/{components → src/lib/components}/app/Section.svelte +0 -0
  34. package/{components → src/lib/components}/app/Table.svelte +0 -0
  35. package/{components → src/lib/components}/app/TextInput.svelte +12 -9
  36. package/{components → src/lib/components}/chapter/Atom.svelte +18 -12
  37. package/src/lib/components/chapter/Block.svelte +42 -0
  38. package/{components → src/lib/components}/chapter/Callout.svelte +6 -3
  39. package/{components → src/lib/components}/chapter/CaptionedCode.svelte +21 -13
  40. package/{components → src/lib/components}/chapter/ChapterBody.svelte +13 -9
  41. package/{components → src/lib/components}/chapter/Citations.svelte +34 -33
  42. package/{components → src/lib/components}/chapter/Code.svelte +63 -58
  43. package/{components → src/lib/components}/chapter/Comment.svelte +30 -18
  44. package/{components → src/lib/components}/chapter/Definition.svelte +23 -17
  45. package/{components → src/lib/components}/chapter/Embed.svelte +97 -77
  46. package/src/lib/components/chapter/ErrorMessage.svelte +12 -0
  47. package/{components → src/lib/components}/chapter/ExtendedPrism.js +0 -0
  48. package/{components → src/lib/components}/chapter/Figure.svelte +34 -26
  49. package/{components → src/lib/components}/chapter/Footnote.svelte +32 -20
  50. package/{components → src/lib/components}/chapter/Format.svelte +39 -34
  51. package/{components → src/lib/components}/chapter/InlineCode.svelte +9 -5
  52. package/{components → src/lib/components}/chapter/Label.svelte +23 -14
  53. package/{components → src/lib/components}/chapter/Link.svelte +27 -21
  54. package/{components → src/lib/components}/chapter/List.svelte +5 -3
  55. package/{components → src/lib/components}/chapter/Marginal.svelte +54 -41
  56. package/{components → src/lib/components}/chapter/Paragraph.svelte +25 -20
  57. package/{components → src/lib/components}/chapter/Positioned.svelte +4 -1
  58. package/{components → src/lib/components}/chapter/Problem.svelte +0 -0
  59. package/src/lib/components/chapter/Python.svelte +144 -0
  60. package/{components → src/lib/components}/chapter/Quote.svelte +9 -5
  61. package/{components → src/lib/components}/chapter/Rule.svelte +4 -1
  62. package/{components → src/lib/components}/chapter/Table.svelte +11 -7
  63. package/src/lib/components/chapter/Text.svelte +109 -0
  64. package/src/lib/components/editor/BookishEditor.svelte +1101 -0
  65. package/src/lib/components/editor/CalloutEditor.svelte +14 -0
  66. package/{components → src/lib/components}/editor/CaptionedCodeEditor.svelte +10 -6
  67. package/src/lib/components/editor/CaretContext.ts +55 -0
  68. package/{components/editor/CaretState.d.ts → src/lib/components/editor/CaretState.ts} +6 -7
  69. package/{components/editor/CaretUtilities.d.ts → src/lib/components/editor/CaretUtilities.ts} +1 -0
  70. package/{components → src/lib/components}/editor/CaretView.svelte +25 -20
  71. package/src/lib/components/editor/CitationsEditor.svelte +64 -0
  72. package/{components/editor/Clipboard.d.ts → src/lib/components/editor/Clipboard.ts} +2 -1
  73. package/{components/editor/Command.d.ts → src/lib/components/editor/Command.ts} +8 -2
  74. package/{components/editor/Commands.js → src/lib/components/editor/Commands.ts} +730 -315
  75. package/src/lib/components/editor/ConfirmButton.svelte +51 -0
  76. package/src/lib/components/editor/DefinitionEditor.svelte +44 -0
  77. package/src/lib/components/editor/EmbedEditor.svelte +152 -0
  78. package/{components → src/lib/components}/editor/Icon.svelte +2 -1
  79. package/{components → src/lib/components}/editor/ImageChooser.svelte +24 -19
  80. package/src/lib/components/editor/InlineCodeEditor.svelte +16 -0
  81. package/{components → src/lib/components}/editor/LabelEditor.svelte +14 -9
  82. package/{components → src/lib/components}/editor/LanguageEditor.svelte +8 -5
  83. package/src/lib/components/editor/LinkEditor.svelte +110 -0
  84. package/{components → src/lib/components}/editor/Note.svelte +0 -0
  85. package/{components → src/lib/components}/editor/Permissions.svelte +43 -36
  86. package/src/lib/components/editor/PositionEditor.svelte +21 -0
  87. package/src/lib/components/editor/QuoteEditor.svelte +14 -0
  88. package/{components → src/lib/components}/editor/Switch.svelte +14 -11
  89. package/src/lib/components/editor/TableEditor.svelte +14 -0
  90. package/{components → src/lib/components}/editor/TextEditor.svelte +101 -89
  91. package/src/lib/components/editor/Toggle.svelte +47 -0
  92. package/src/lib/components/editor/Toolbar.svelte +297 -0
  93. package/{components → src/lib/components}/editor/ToolbarGroup.svelte +5 -3
  94. package/{components → src/lib/components}/editor/ToolbarSpacer.svelte +0 -0
  95. package/src/lib/components/editor/URLEditor.svelte +15 -0
  96. package/{components/editor/UndoState.d.ts → src/lib/components/editor/UndoState.ts} +3 -2
  97. package/{components → src/lib/components}/editor/icons/annotate.svg +0 -0
  98. package/{components → src/lib/components}/editor/icons/block.svg +0 -0
  99. package/{components → src/lib/components}/editor/icons/bold.svg +0 -0
  100. package/{components → src/lib/components}/editor/icons/bullets.svg +0 -0
  101. package/{components → src/lib/components}/editor/icons/callout.svg +0 -0
  102. package/{components → src/lib/components}/editor/icons/citation.svg +0 -0
  103. package/{components → src/lib/components}/editor/icons/clear.svg +0 -0
  104. package/{components → src/lib/components}/editor/icons/clipboard.svg +0 -0
  105. package/{components → src/lib/components}/editor/icons/code.svg +0 -0
  106. package/{components → src/lib/components}/editor/icons/columnafter.svg +0 -0
  107. package/{components → src/lib/components}/editor/icons/columnbefore.svg +0 -0
  108. package/{components → src/lib/components}/editor/icons/comment.svg +0 -0
  109. package/{components → src/lib/components}/editor/icons/copy.svg +0 -0
  110. package/{components → src/lib/components}/editor/icons/cut.svg +0 -0
  111. package/{components → src/lib/components}/editor/icons/define.svg +0 -0
  112. package/{components → src/lib/components}/editor/icons/deletecolumn.svg +0 -0
  113. package/{components → src/lib/components}/editor/icons/deleterow.svg +0 -0
  114. package/{components → src/lib/components}/editor/icons/footnote.svg +0 -0
  115. package/{components → src/lib/components}/editor/icons/header1.svg +0 -0
  116. package/{components → src/lib/components}/editor/icons/header2.svg +0 -0
  117. package/{components → src/lib/components}/editor/icons/header3.svg +0 -0
  118. package/{components → src/lib/components}/editor/icons/home.svg +0 -0
  119. package/{components → src/lib/components}/editor/icons/indent.svg +0 -0
  120. package/{components → src/lib/components}/editor/icons/italic.svg +0 -0
  121. package/{components → src/lib/components}/editor/icons/label.svg +0 -0
  122. package/{components → src/lib/components}/editor/icons/left.svg +0 -0
  123. package/{components → src/lib/components}/editor/icons/level.svg +0 -0
  124. package/{components → src/lib/components}/editor/icons/link.svg +0 -0
  125. package/{components → src/lib/components}/editor/icons/list.svg +0 -0
  126. package/{components → src/lib/components}/editor/icons/media.svg +0 -0
  127. package/{components → src/lib/components}/editor/icons/middle.svg +0 -0
  128. package/{components → src/lib/components}/editor/icons/numbers.svg +0 -0
  129. package/{components → src/lib/components}/editor/icons/paragraph.svg +0 -0
  130. package/{components → src/lib/components}/editor/icons/paste.svg +0 -0
  131. package/{components → src/lib/components}/editor/icons/quote.svg +0 -0
  132. package/{components → src/lib/components}/editor/icons/redo.svg +0 -0
  133. package/{components → src/lib/components}/editor/icons/right.svg +0 -0
  134. package/{components → src/lib/components}/editor/icons/rowabove.svg +0 -0
  135. package/{components → src/lib/components}/editor/icons/rowbelow.svg +0 -0
  136. package/{components → src/lib/components}/editor/icons/rule.svg +0 -0
  137. package/{components → src/lib/components}/editor/icons/sub.svg +0 -0
  138. package/{components → src/lib/components}/editor/icons/super.svg +0 -0
  139. package/{components → src/lib/components}/editor/icons/table.svg +0 -0
  140. package/{components → src/lib/components}/editor/icons/text.svg +0 -0
  141. package/{components → src/lib/components}/editor/icons/time.svg +0 -0
  142. package/{components → src/lib/components}/editor/icons/undo.svg +0 -0
  143. package/{components → src/lib/components}/editor/icons/unindent.svg +0 -0
  144. package/{components → src/lib/components}/editor/icons/unlink.svg +0 -0
  145. package/{components → src/lib/components}/page/Acknowledgements.svelte +19 -10
  146. package/src/lib/components/page/Authors.svelte +92 -0
  147. package/src/lib/components/page/BookLoader.svelte +77 -0
  148. package/src/lib/components/page/BulkReferenceEditor.svelte +86 -0
  149. package/src/lib/components/page/Chapter.svelte +449 -0
  150. package/src/lib/components/page/ChapterContext.ts +13 -0
  151. package/{components → src/lib/components}/page/ChapterNumber.svelte +0 -0
  152. package/{components → src/lib/components}/page/ChapterTitle.svelte +4 -2
  153. package/src/lib/components/page/Contexts.ts +176 -0
  154. package/{components → src/lib/components}/page/DefinitionView.svelte +52 -37
  155. package/{components → src/lib/components}/page/Description.svelte +15 -7
  156. package/src/lib/components/page/Edition.svelte +189 -0
  157. package/src/lib/components/page/EditionLoader.svelte +123 -0
  158. package/{components → src/lib/components}/page/Editions.svelte +22 -18
  159. package/{components → src/lib/components}/page/Glossary.svelte +33 -28
  160. package/{components → src/lib/components}/page/Header.svelte +59 -52
  161. package/{components → src/lib/components}/page/Index.svelte +48 -41
  162. package/{components → src/lib/components}/page/Instructions.svelte +2 -1
  163. package/{components → src/lib/components}/page/License.svelte +17 -9
  164. package/{components → src/lib/components}/page/Loading.svelte +0 -0
  165. package/{components → src/lib/components}/page/Media.svelte +44 -27
  166. package/{components → src/lib/components}/page/MediaPreview.svelte +3 -2
  167. package/{components → src/lib/components}/page/Muted.svelte +0 -0
  168. package/{components → src/lib/components}/page/Outline.svelte +140 -110
  169. package/src/lib/components/page/Page.svelte +94 -0
  170. package/{components → src/lib/components}/page/PageHeader.svelte +2 -1
  171. package/{components → src/lib/components}/page/PageParagraph.svelte +0 -0
  172. package/src/lib/components/page/PossibleChapter.svelte +16 -0
  173. package/src/lib/components/page/PossibleReference.svelte +14 -0
  174. package/{components → src/lib/components}/page/Print.svelte +5 -3
  175. package/{components → src/lib/components}/page/Publish.svelte +59 -52
  176. package/{components → src/lib/components}/page/Reference.svelte +39 -30
  177. package/{components → src/lib/components}/page/References.svelte +18 -14
  178. package/{components → src/lib/components}/page/Rows.svelte +0 -0
  179. package/src/lib/components/page/Search.svelte +153 -0
  180. package/{components → src/lib/components}/page/Status.svelte +5 -3
  181. package/{components → src/lib/components}/page/SubdomainEditor.svelte +16 -13
  182. package/{components → src/lib/components}/page/TableOfContents.svelte +79 -68
  183. package/src/lib/components/page/TableOfContentsImage.svelte +22 -0
  184. package/{components → src/lib/components}/page/TableOfContentsRow.svelte +34 -24
  185. package/{components → src/lib/components}/page/ThemeEditor.svelte +44 -33
  186. package/{components → src/lib/components}/page/ThemeEditorPreview.svelte +21 -12
  187. package/src/lib/components/page/ThemeSetEditor.svelte +21 -0
  188. package/{components → src/lib/components}/page/ThemeVariableEditor.svelte +18 -14
  189. package/{components → src/lib/components}/page/Title.svelte +0 -0
  190. package/{components → src/lib/components}/page/Unknown.svelte +10 -8
  191. package/{components/page/margins.js → src/lib/components/page/margins.ts} +79 -46
  192. package/{index.js → src/lib/index.js} +0 -0
  193. package/src/lib/models/CRUD.ts +469 -0
  194. package/{models/Firebase.js → src/lib/models/Firebase.ts} +26 -16
  195. package/src/lib/models/book/Book.ts +283 -0
  196. package/src/lib/models/book/BookMedia.ts +182 -0
  197. package/src/lib/models/book/BookSaveStatus.ts +8 -0
  198. package/src/lib/models/book/Chapter.ts +462 -0
  199. package/{models/book/ChapterID.js → src/lib/models/book/ChapterID.ts} +1 -0
  200. package/src/lib/models/book/Definition.ts +2 -0
  201. package/src/lib/models/book/Edition.ts +1216 -0
  202. package/src/lib/models/book/Reference.ts +171 -0
  203. package/{models/book/Schema.js → src/lib/models/book/Schema.ts} +1 -0
  204. package/{models/book/Theme.js → src/lib/models/book/Theme.ts} +111 -6
  205. package/{models/book/ThemeColors.d.ts → src/lib/models/book/ThemeColors.ts} +6 -0
  206. package/{models/book/Words.js → src/lib/models/book/Words.ts} +1 -0
  207. package/{models/chapter/AtomNode.js → src/lib/models/chapter/AtomNode.ts} +30 -10
  208. package/{models/chapter/BlockNode.js → src/lib/models/chapter/BlockNode.ts} +80 -47
  209. package/src/lib/models/chapter/BlocksNode.test.ts +867 -0
  210. package/{models/chapter/BlocksNode.js → src/lib/models/chapter/BlocksNode.ts} +571 -359
  211. package/{models/chapter/Bookkeeping.d.ts → src/lib/models/chapter/Bookkeeping.ts} +0 -0
  212. package/src/lib/models/chapter/CalloutNode.ts +79 -0
  213. package/{models/chapter/Caret.js → src/lib/models/chapter/Caret.ts} +50 -26
  214. package/src/lib/models/chapter/ChapterNode.ts +169 -0
  215. package/{models/chapter/CitationsNode.js → src/lib/models/chapter/CitationsNode.ts} +17 -10
  216. package/{models/chapter/CodeNode.js → src/lib/models/chapter/CodeNode.ts} +125 -62
  217. package/src/lib/models/chapter/CommentNode.ts +61 -0
  218. package/{models/chapter/DefinitionNode.js → src/lib/models/chapter/DefinitionNode.ts} +14 -8
  219. package/src/lib/models/chapter/Edit.ts +6 -0
  220. package/src/lib/models/chapter/EmbedNode.ts +257 -0
  221. package/{models/chapter/ErrorNode.js → src/lib/models/chapter/ErrorNode.ts} +15 -8
  222. package/src/lib/models/chapter/FootnoteNode.ts +59 -0
  223. package/src/lib/models/chapter/FormatNode.test.ts +137 -0
  224. package/{models/chapter/FormatNode.js → src/lib/models/chapter/FormatNode.ts} +443 -262
  225. package/{models/chapter/InlineCodeNode.js → src/lib/models/chapter/InlineCodeNode.ts} +17 -9
  226. package/{models/chapter/LabelNode.js → src/lib/models/chapter/LabelNode.ts} +26 -10
  227. package/{models/chapter/LinkNode.js → src/lib/models/chapter/LinkNode.ts} +12 -7
  228. package/{models/chapter/ListNode.test.js → src/lib/models/chapter/ListNode.test.ts} +57 -20
  229. package/{models/chapter/ListNode.js → src/lib/models/chapter/ListNode.ts} +277 -200
  230. package/src/lib/models/chapter/MetadataNode.ts +44 -0
  231. package/{models → src/lib/models}/chapter/Node.test.js +0 -0
  232. package/{models/chapter/Node.js → src/lib/models/chapter/Node.ts} +155 -71
  233. package/src/lib/models/chapter/ParagraphNode.test.ts +54 -0
  234. package/{models/chapter/ParagraphNode.js → src/lib/models/chapter/ParagraphNode.ts} +95 -58
  235. package/{models/chapter/Parser.test.js → src/lib/models/chapter/Parser.test.ts} +7 -0
  236. package/{models/chapter/Parser.js → src/lib/models/chapter/Parser.ts} +369 -184
  237. package/{models/chapter/Position.d.ts → src/lib/models/chapter/Position.ts} +0 -0
  238. package/src/lib/models/chapter/QuoteNode.ts +135 -0
  239. package/{models/chapter/RootNode.d.ts → src/lib/models/chapter/RootNode.ts} +2 -0
  240. package/{models/chapter/RuleNode.js → src/lib/models/chapter/RuleNode.ts} +9 -6
  241. package/{models/chapter/TableNode.test.js → src/lib/models/chapter/TableNode.test.ts} +27 -10
  242. package/{models/chapter/TableNode.js → src/lib/models/chapter/TableNode.ts} +141 -82
  243. package/{models/chapter/TextNode.test.js → src/lib/models/chapter/TextNode.test.ts} +2 -0
  244. package/{models/chapter/TextNode.js → src/lib/models/chapter/TextNode.ts} +117 -65
  245. package/{util/getSubdomain.js → src/lib/util/getSubdomain.ts} +14 -8
  246. package/{util/isMobile.js → src/lib/util/isMobile.ts} +1 -0
  247. package/{util/mineReference.js → src/lib/util/mineReference.ts} +45 -25
  248. package/{util/scrollToEyeLevel.js → src/lib/util/scrollToEyeLevel.ts} +4 -2
  249. package/src/params/edition.ts +3 -0
  250. package/src/routes/+error.svelte +12 -0
  251. package/src/routes/+layout.svelte +241 -0
  252. package/src/routes/+page.svelte +43 -0
  253. package/src/routes/Footer.svelte +0 -0
  254. package/src/routes/Header.svelte +112 -0
  255. package/src/routes/[bookid]/+layout.svelte +5 -0
  256. package/src/routes/[bookid]/[[editionid=edition]]/+error.svelte +14 -0
  257. package/src/routes/[bookid]/[[editionid=edition]]/+layout.svelte +7 -0
  258. package/src/routes/[bookid]/[[editionid=edition]]/+page.svelte +5 -0
  259. package/src/routes/[bookid]/[[editionid=edition]]/[chapterid]/+page.svelte +5 -0
  260. package/src/routes/[bookid]/[[editionid=edition]]/glossary/+page.svelte +5 -0
  261. package/src/routes/[bookid]/[[editionid=edition]]/index/[[letter]]/+page.svelte +5 -0
  262. package/src/routes/[bookid]/[[editionid=edition]]/media/+page.svelte +5 -0
  263. package/src/routes/[bookid]/[[editionid=edition]]/print/+page.svelte +5 -0
  264. package/src/routes/[bookid]/[[editionid=edition]]/references/+page.svelte +5 -0
  265. package/src/routes/[bookid]/[[editionid=edition]]/search/+page.svelte +5 -0
  266. package/src/routes/[bookid]/editions/+page.svelte +20 -0
  267. package/src/routes/about/+page.svelte +102 -0
  268. package/src/routes/confirm/+page.svelte +62 -0
  269. package/src/routes/email/+page.svelte +99 -0
  270. package/src/routes/login/+page.svelte +66 -0
  271. package/src/routes/read/+page.svelte +38 -0
  272. package/src/routes/write/+error.svelte +10 -0
  273. package/src/routes/write/+layout.svelte +11 -0
  274. package/src/routes/write/+page.svelte +114 -0
  275. package/src/routes/write/[bookid]/+layout.svelte +5 -0
  276. package/src/routes/write/[bookid]/[[editionid=edition]]/+layout.svelte +7 -0
  277. package/src/routes/write/[bookid]/[[editionid=edition]]/+page.svelte +5 -0
  278. package/src/routes/write/[bookid]/[[editionid=edition]]/[chapterid]/+page.svelte +5 -0
  279. package/src/routes/write/[bookid]/[[editionid=edition]]/glossary/+page.svelte +5 -0
  280. package/src/routes/write/[bookid]/[[editionid=edition]]/index/[[letter]]/+page.svelte +5 -0
  281. package/src/routes/write/[bookid]/[[editionid=edition]]/media/+page.svelte +5 -0
  282. package/src/routes/write/[bookid]/[[editionid=edition]]/print/+page.svelte +5 -0
  283. package/src/routes/write/[bookid]/[[editionid=edition]]/references/+page.svelte +5 -0
  284. package/src/routes/write/[bookid]/[[editionid=edition]]/search/+page.svelte +5 -0
  285. package/src/routes/write/[bookid]/[[editionid=edition]]/theme/+page.svelte +5 -0
  286. package/src/routes/write/[bookid]/[[editionid=edition]]/unknown/+page.svelte +5 -0
  287. package/src/routes/write/[bookid]/editions/+page.svelte +20 -0
  288. package/src/vite-env.d.ts +1 -0
  289. package/static/icons/favicon.png +0 -0
  290. package/static/icons/icon.png +0 -0
  291. package/static/icons/ios-icon.png +0 -0
  292. package/storage.rules +9 -0
  293. package/svelte.config.js +19 -0
  294. package/tsconfig.json +18 -0
  295. package/tsconfig.node.json +9 -0
  296. package/vite.config.ts +8 -0
  297. package/vite.reader.config.ts +32 -0
  298. package/components/Auth.svelte +0 -55
  299. package/components/Auth.svelte.d.ts +0 -16
  300. package/components/Authentication.js +0 -1
  301. package/components/BookPreview.svelte.d.ts +0 -18
  302. package/components/External.svelte.d.ts +0 -18
  303. package/components/Link.svelte +0 -51
  304. package/components/Link.svelte.d.ts +0 -18
  305. package/components/app/BookList.svelte.d.ts +0 -18
  306. package/components/app/Button.svelte.d.ts +0 -22
  307. package/components/app/Feedback.svelte.d.ts +0 -18
  308. package/components/app/Head.svelte.d.ts +0 -18
  309. package/components/app/Large.svelte.d.ts +0 -27
  310. package/components/app/Lead.svelte.d.ts +0 -27
  311. package/components/app/Link.svelte.d.ts +0 -20
  312. package/components/app/Options.svelte.d.ts +0 -19
  313. package/components/app/Paragraph.svelte.d.ts +0 -18
  314. package/components/app/Section.svelte.d.ts +0 -27
  315. package/components/app/Table.svelte.d.ts +0 -27
  316. package/components/app/TextInput.svelte.d.ts +0 -22
  317. package/components/chapter/Atom.svelte.d.ts +0 -19
  318. package/components/chapter/Block.svelte +0 -37
  319. package/components/chapter/Block.svelte.d.ts +0 -17
  320. package/components/chapter/Callout.svelte.d.ts +0 -17
  321. package/components/chapter/CaptionedCode.svelte.d.ts +0 -17
  322. package/components/chapter/ChapterBody.svelte.d.ts +0 -19
  323. package/components/chapter/Citations.svelte.d.ts +0 -17
  324. package/components/chapter/Code.svelte.d.ts +0 -22
  325. package/components/chapter/Comment.svelte.d.ts +0 -17
  326. package/components/chapter/Definition.svelte.d.ts +0 -17
  327. package/components/chapter/Embed.svelte.d.ts +0 -20
  328. package/components/chapter/ErrorMessage.svelte +0 -9
  329. package/components/chapter/ErrorMessage.svelte.d.ts +0 -17
  330. package/components/chapter/ExtendedPrism.d.ts +0 -2
  331. package/components/chapter/Figure.svelte.d.ts +0 -24
  332. package/components/chapter/Footnote.svelte.d.ts +0 -19
  333. package/components/chapter/Format.svelte.d.ts +0 -19
  334. package/components/chapter/InlineCode.svelte.d.ts +0 -17
  335. package/components/chapter/Label.svelte.d.ts +0 -17
  336. package/components/chapter/Link.svelte.d.ts +0 -17
  337. package/components/chapter/List.svelte.d.ts +0 -17
  338. package/components/chapter/Marginal.svelte.d.ts +0 -22
  339. package/components/chapter/Paragraph.svelte.d.ts +0 -18
  340. package/components/chapter/Positioned.svelte.d.ts +0 -19
  341. package/components/chapter/Problem.svelte.d.ts +0 -27
  342. package/components/chapter/Python.svelte +0 -128
  343. package/components/chapter/Python.svelte.d.ts +0 -18
  344. package/components/chapter/Quote.svelte.d.ts +0 -17
  345. package/components/chapter/Rule.svelte.d.ts +0 -17
  346. package/components/chapter/Table.svelte.d.ts +0 -17
  347. package/components/chapter/Text.svelte +0 -87
  348. package/components/chapter/Text.svelte.d.ts +0 -18
  349. package/components/editor/BookishEditor.svelte +0 -884
  350. package/components/editor/BookishEditor.svelte.d.ts +0 -25
  351. package/components/editor/CalloutEditor.svelte +0 -10
  352. package/components/editor/CalloutEditor.svelte.d.ts +0 -17
  353. package/components/editor/CaptionedCodeEditor.svelte.d.ts +0 -17
  354. package/components/editor/CaretContext.d.ts +0 -50
  355. package/components/editor/CaretContext.js +0 -1
  356. package/components/editor/CaretState.js +0 -1
  357. package/components/editor/CaretUtilities.js +0 -1
  358. package/components/editor/CaretView.svelte.d.ts +0 -25
  359. package/components/editor/CitationsEditor.svelte +0 -53
  360. package/components/editor/CitationsEditor.svelte.d.ts +0 -17
  361. package/components/editor/Clipboard.js +0 -1
  362. package/components/editor/Command.js +0 -1
  363. package/components/editor/Commands.d.ts +0 -3
  364. package/components/editor/ConfirmButton.svelte +0 -49
  365. package/components/editor/ConfirmButton.svelte.d.ts +0 -19
  366. package/components/editor/DefinitionEditor.svelte +0 -36
  367. package/components/editor/DefinitionEditor.svelte.d.ts +0 -17
  368. package/components/editor/EmbedEditor.svelte +0 -137
  369. package/components/editor/EmbedEditor.svelte.d.ts +0 -17
  370. package/components/editor/Icon.svelte.d.ts +0 -16
  371. package/components/editor/ImageChooser.svelte.d.ts +0 -18
  372. package/components/editor/InlineCodeEditor.svelte +0 -12
  373. package/components/editor/InlineCodeEditor.svelte.d.ts +0 -17
  374. package/components/editor/LabelEditor.svelte.d.ts +0 -17
  375. package/components/editor/LanguageEditor.svelte.d.ts +0 -17
  376. package/components/editor/LinkEditor.svelte +0 -100
  377. package/components/editor/LinkEditor.svelte.d.ts +0 -17
  378. package/components/editor/Note.svelte.d.ts +0 -27
  379. package/components/editor/Permissions.svelte.d.ts +0 -20
  380. package/components/editor/PositionEditor.svelte +0 -17
  381. package/components/editor/PositionEditor.svelte.d.ts +0 -18
  382. package/components/editor/QuoteEditor.svelte +0 -10
  383. package/components/editor/QuoteEditor.svelte.d.ts +0 -17
  384. package/components/editor/Switch.svelte.d.ts +0 -20
  385. package/components/editor/TableEditor.svelte +0 -10
  386. package/components/editor/TableEditor.svelte.d.ts +0 -17
  387. package/components/editor/TextEditor.svelte.d.ts +0 -24
  388. package/components/editor/Toggle.svelte +0 -41
  389. package/components/editor/Toggle.svelte.d.ts +0 -19
  390. package/components/editor/Toolbar.svelte +0 -249
  391. package/components/editor/Toolbar.svelte.d.ts +0 -17
  392. package/components/editor/ToolbarGroup.svelte.d.ts +0 -18
  393. package/components/editor/ToolbarSpacer.svelte.d.ts +0 -23
  394. package/components/editor/URLEditor.svelte +0 -13
  395. package/components/editor/URLEditor.svelte.d.ts +0 -18
  396. package/components/editor/UndoState.js +0 -1
  397. package/components/page/Acknowledgements.svelte.d.ts +0 -14
  398. package/components/page/Authors.svelte +0 -85
  399. package/components/page/Authors.svelte.d.ts +0 -21
  400. package/components/page/BookLoader.svelte +0 -59
  401. package/components/page/BookLoader.svelte.d.ts +0 -16
  402. package/components/page/BulkReferenceEditor.svelte +0 -63
  403. package/components/page/BulkReferenceEditor.svelte.d.ts +0 -14
  404. package/components/page/Chapter.svelte +0 -392
  405. package/components/page/Chapter.svelte.d.ts +0 -18
  406. package/components/page/ChapterContext.d.ts +0 -10
  407. package/components/page/ChapterContext.js +0 -1
  408. package/components/page/ChapterNumber.svelte.d.ts +0 -27
  409. package/components/page/ChapterTitle.svelte.d.ts +0 -18
  410. package/components/page/Contexts.d.ts +0 -47
  411. package/components/page/Contexts.js +0 -133
  412. package/components/page/DefinitionView.svelte.d.ts +0 -18
  413. package/components/page/Description.svelte.d.ts +0 -14
  414. package/components/page/Edition.svelte +0 -161
  415. package/components/page/Edition.svelte.d.ts +0 -20
  416. package/components/page/EditionLoader.svelte +0 -99
  417. package/components/page/EditionLoader.svelte.d.ts +0 -18
  418. package/components/page/Editions.svelte.d.ts +0 -14
  419. package/components/page/Glossary.svelte.d.ts +0 -14
  420. package/components/page/Header.svelte.d.ts +0 -29
  421. package/components/page/Index.svelte.d.ts +0 -14
  422. package/components/page/Instructions.svelte.d.ts +0 -18
  423. package/components/page/License.svelte.d.ts +0 -14
  424. package/components/page/Loading.svelte.d.ts +0 -23
  425. package/components/page/Media.svelte.d.ts +0 -14
  426. package/components/page/MediaPreview.svelte.d.ts +0 -19
  427. package/components/page/Muted.svelte.d.ts +0 -27
  428. package/components/page/Outline.svelte.d.ts +0 -19
  429. package/components/page/Page.svelte +0 -84
  430. package/components/page/Page.svelte.d.ts +0 -19
  431. package/components/page/PageHeader.svelte.d.ts +0 -18
  432. package/components/page/PageParagraph.svelte.d.ts +0 -27
  433. package/components/page/PossibleChapter.svelte +0 -14
  434. package/components/page/PossibleChapter.svelte.d.ts +0 -14
  435. package/components/page/PossibleReference.svelte +0 -11
  436. package/components/page/PossibleReference.svelte.d.ts +0 -18
  437. package/components/page/Print.svelte.d.ts +0 -14
  438. package/components/page/Publish.svelte.d.ts +0 -14
  439. package/components/page/Reference.svelte.d.ts +0 -17
  440. package/components/page/References.svelte.d.ts +0 -14
  441. package/components/page/Rows.svelte.d.ts +0 -27
  442. package/components/page/Search.svelte +0 -133
  443. package/components/page/Search.svelte.d.ts +0 -14
  444. package/components/page/Status.svelte.d.ts +0 -14
  445. package/components/page/SubdomainEditor.svelte.d.ts +0 -14
  446. package/components/page/TableOfContents.svelte.d.ts +0 -14
  447. package/components/page/TableOfContentsImage.svelte +0 -18
  448. package/components/page/TableOfContentsImage.svelte.d.ts +0 -16
  449. package/components/page/TableOfContentsRow.svelte.d.ts +0 -24
  450. package/components/page/ThemeEditor.svelte.d.ts +0 -14
  451. package/components/page/ThemeEditorPreview.svelte.d.ts +0 -17
  452. package/components/page/ThemeSetEditor.svelte +0 -19
  453. package/components/page/ThemeSetEditor.svelte.d.ts +0 -18
  454. package/components/page/ThemeVariableEditor.svelte.d.ts +0 -18
  455. package/components/page/Title.svelte.d.ts +0 -27
  456. package/components/page/Unknown.svelte.d.ts +0 -16
  457. package/components/page/margins.d.ts +0 -2
  458. package/index.d.ts +0 -15
  459. package/models/CRUD.d.ts +0 -27
  460. package/models/CRUD.js +0 -262
  461. package/models/Firebase.d.ts +0 -5
  462. package/models/book/Book.d.ts +0 -61
  463. package/models/book/Book.js +0 -135
  464. package/models/book/BookMedia.d.ts +0 -23
  465. package/models/book/BookMedia.js +0 -108
  466. package/models/book/BookSaveStatus.d.ts +0 -7
  467. package/models/book/BookSaveStatus.js +0 -8
  468. package/models/book/Chapter.d.ts +0 -81
  469. package/models/book/Chapter.js +0 -212
  470. package/models/book/ChapterID.d.ts +0 -10
  471. package/models/book/Definition.d.ts +0 -6
  472. package/models/book/Definition.js +0 -1
  473. package/models/book/Edition.d.ts +0 -139
  474. package/models/book/Edition.js +0 -620
  475. package/models/book/Reference.d.ts +0 -24
  476. package/models/book/Reference.js +0 -78
  477. package/models/book/Schema.d.ts +0 -174
  478. package/models/book/Theme.d.ts +0 -113
  479. package/models/book/ThemeColors.js +0 -1
  480. package/models/book/Words.d.ts +0 -2
  481. package/models/chapter/AtomNode.d.ts +0 -18
  482. package/models/chapter/BlockNode.d.ts +0 -20
  483. package/models/chapter/BlocksNode.d.ts +0 -50
  484. package/models/chapter/BlocksNode.test.d.ts +0 -1
  485. package/models/chapter/BlocksNode.test.js +0 -568
  486. package/models/chapter/Bookkeeping.js +0 -1
  487. package/models/chapter/CalloutNode.d.ts +0 -17
  488. package/models/chapter/CalloutNode.js +0 -58
  489. package/models/chapter/Caret.d.ts +0 -23
  490. package/models/chapter/ChapterNode.d.ts +0 -34
  491. package/models/chapter/ChapterNode.js +0 -117
  492. package/models/chapter/CitationsNode.d.ts +0 -16
  493. package/models/chapter/CodeNode.d.ts +0 -35
  494. package/models/chapter/CommentNode.d.ts +0 -18
  495. package/models/chapter/CommentNode.js +0 -48
  496. package/models/chapter/DefinitionNode.d.ts +0 -12
  497. package/models/chapter/Edit.d.ts +0 -7
  498. package/models/chapter/Edit.js +0 -1
  499. package/models/chapter/EmbedNode.d.ts +0 -45
  500. package/models/chapter/EmbedNode.js +0 -168
  501. package/models/chapter/ErrorNode.d.ts +0 -17
  502. package/models/chapter/FootnoteNode.d.ts +0 -18
  503. package/models/chapter/FootnoteNode.js +0 -47
  504. package/models/chapter/FormatNode.d.ts +0 -60
  505. package/models/chapter/FormatNode.test.d.ts +0 -1
  506. package/models/chapter/FormatNode.test.js +0 -96
  507. package/models/chapter/InlineCodeNode.d.ts +0 -12
  508. package/models/chapter/LabelNode.d.ts +0 -17
  509. package/models/chapter/LinkNode.d.ts +0 -12
  510. package/models/chapter/ListNode.d.ts +0 -51
  511. package/models/chapter/ListNode.test.d.ts +0 -1
  512. package/models/chapter/MetadataNode.d.ts +0 -17
  513. package/models/chapter/MetadataNode.js +0 -32
  514. package/models/chapter/Node.d.ts +0 -38
  515. package/models/chapter/Node.test.d.ts +0 -1
  516. package/models/chapter/ParagraphNode.d.ts +0 -33
  517. package/models/chapter/ParagraphNode.test.d.ts +0 -1
  518. package/models/chapter/ParagraphNode.test.js +0 -30
  519. package/models/chapter/Parser.d.ts +0 -75
  520. package/models/chapter/Parser.test.d.ts +0 -1
  521. package/models/chapter/Position.js +0 -1
  522. package/models/chapter/QuoteNode.d.ts +0 -25
  523. package/models/chapter/QuoteNode.js +0 -99
  524. package/models/chapter/RootNode.js +0 -1
  525. package/models/chapter/RuleNode.d.ts +0 -15
  526. package/models/chapter/TableNode.d.ts +0 -37
  527. package/models/chapter/TableNode.test.d.ts +0 -1
  528. package/models/chapter/TextNode.d.ts +0 -36
  529. package/models/chapter/TextNode.test.d.ts +0 -1
  530. package/util/getSubdomain.d.ts +0 -3
  531. package/util/isMobile.d.ts +0 -2
  532. package/util/mineReference.d.ts +0 -4
  533. package/util/scrollToEyeLevel.d.ts +0 -2
@@ -0,0 +1,1216 @@
1
+ import Chapter from './Chapter';
2
+ import type { ChapterSpecification } from './Chapter';
3
+ import Parser from '../chapter/Parser';
4
+ import EmbedNode from '../chapter/EmbedNode';
5
+ import Reference from './Reference';
6
+ import type Theme from './Theme';
7
+ import type Definition from './Definition.js';
8
+ import ChapterIDs from './ChapterID.js';
9
+ import type { DocumentReference } from 'firebase/firestore';
10
+ import type Book from './Book';
11
+ import type FormatNode from '../chapter/FormatNode';
12
+ import type { EditionInfo } from './Book';
13
+
14
+ export type EditionSpecification = {
15
+ bookRef: DocumentReference;
16
+ // The title of the book.
17
+ title: string;
18
+ // A numerical string indicating the version of the book. Can be any string, but is sorted alphanumerically.
19
+ number: number;
20
+ // A summary of the revisions in the edition
21
+ summary: string;
22
+ // A time stamp or nothing, indicating when the book was published.
23
+ published: number | null;
24
+ authors: string[];
25
+ images: Record<string, string | null>;
26
+ description: string;
27
+ chapters: ChapterSpecification[];
28
+ license: string;
29
+ acknowledgements: string;
30
+ tags: string[];
31
+ sources: Record<string, string>;
32
+ references: Record<string, string | string[]>;
33
+ symbols: Record<string, string>;
34
+ glossary: Record<string, Definition>;
35
+ theme: Theme | null;
36
+ base: string | null;
37
+ uids: string[];
38
+ chapteruids: string[];
39
+ active: Record<string, string>;
40
+ };
41
+
42
+ export default class Edition {
43
+ readonly bookRef: DocumentReference;
44
+ readonly editionRef: DocumentReference | undefined;
45
+ readonly uids: string[];
46
+ readonly title: string;
47
+ readonly authors: string[];
48
+ readonly number: number;
49
+ readonly summary: string;
50
+ readonly published: number | null;
51
+ readonly images: Record<string, string | null>;
52
+ readonly description: string;
53
+ readonly chapters: Chapter[];
54
+ readonly license: string;
55
+ readonly acknowledgements: string;
56
+ readonly tags: string[];
57
+ readonly sources: Record<string, string>;
58
+ readonly references: Record<string, Reference | FormatNode>;
59
+ readonly symbols: Record<string, string>;
60
+ readonly glossary: Record<string, Definition>;
61
+ readonly theme: Theme | null;
62
+ readonly base: string | null;
63
+ readonly active: Record<string, string>;
64
+
65
+ // Given an object with a valid specification and an object mapping chapter IDs to chapter text,
66
+ // construct an object representing a book.
67
+ constructor(
68
+ bookRef: DocumentReference,
69
+ editionRef: DocumentReference | undefined,
70
+ uids: string[],
71
+ title: string,
72
+ authors: string[],
73
+ number: number,
74
+ summary: string,
75
+ published: number | null,
76
+ images: Record<string, string | null>,
77
+ description: string,
78
+ chapters: Chapter[],
79
+ license: string,
80
+ acknowledgements: string,
81
+ tags: string[],
82
+ sources: Record<string, string>,
83
+ references:
84
+ | Record<string, string | string[]>
85
+ | Record<string, FormatNode | Reference>,
86
+ symbols: Record<string, string>,
87
+ glossary: Record<string, Definition>,
88
+ theme: Theme | null,
89
+ base: string | null,
90
+ active: Record<string, string>
91
+ ) {
92
+ this.bookRef = bookRef;
93
+ this.editionRef = editionRef;
94
+ this.uids = uids;
95
+ this.title = title;
96
+ this.authors = authors;
97
+ this.number = number;
98
+ this.summary = summary;
99
+ this.published = published;
100
+ this.images = images;
101
+ this.description = description;
102
+ this.chapters = chapters.slice();
103
+ this.license = license;
104
+ this.acknowledgements = acknowledgements;
105
+ this.tags = tags.slice();
106
+ this.sources = Object.assign({}, sources);
107
+ this.references = {};
108
+ for (const [citationID, ref] of Object.entries(references)) {
109
+ this.references[citationID] =
110
+ ref instanceof Reference
111
+ ? ref
112
+ : Edition.parseReference(citationID, ref, this);
113
+ }
114
+ this.symbols = Object.assign({}, symbols);
115
+ this.glossary = Object.assign({}, glossary);
116
+ this.theme = theme;
117
+ this.base = base;
118
+ this.active = active;
119
+ }
120
+
121
+ static fromJSON(
122
+ editionRef: DocumentReference | undefined,
123
+ spec: EditionSpecification
124
+ ) {
125
+ // Copy all of the specification metadata to fields.
126
+ // Choose suitable defaults if the spec is lacking a field.
127
+ return new Edition(
128
+ spec.bookRef,
129
+ editionRef,
130
+ spec.uids,
131
+ spec.title,
132
+ spec.authors,
133
+ spec.number,
134
+ spec.summary,
135
+ spec.published,
136
+ spec.images,
137
+ spec.description,
138
+ spec.chapters.map((chap) => Chapter.fromJSON(chap, '')),
139
+ spec.license,
140
+ spec.acknowledgements,
141
+ spec.tags ?? [],
142
+ spec.sources ?? {},
143
+ spec.references ?? {},
144
+ spec.symbols ?? {},
145
+ spec.glossary ?? {},
146
+ spec.theme,
147
+ spec.base ?? '',
148
+ spec.active
149
+ );
150
+ }
151
+
152
+ static parseReference(
153
+ citationID: string,
154
+ ref: string | string[],
155
+ edition: Edition,
156
+ short = false
157
+ ) {
158
+ if (typeof ref === 'string') return Parser.parseFormat(edition, ref);
159
+ else {
160
+ // APA Format. Could eventually support multiple formats.
161
+ let [authors, year, title, source, url, summary] = ref;
162
+
163
+ if (source.charAt(0) === '#') {
164
+ let src = edition.getSource(source);
165
+ if (src !== null) source = src;
166
+ }
167
+
168
+ return new Reference(
169
+ citationID,
170
+ authors ?? '',
171
+ year ?? '',
172
+ title ?? '',
173
+ source ?? '',
174
+ url ?? '',
175
+ summary ?? '',
176
+ short
177
+ );
178
+ }
179
+ }
180
+
181
+ // Convert the book to an object for storage.
182
+ toObject(): EditionSpecification {
183
+ const references: Record<string, string | string[]> = {};
184
+ for (const [citationID, ref] of Object.entries(this.references))
185
+ references[citationID] =
186
+ ref instanceof Reference ? ref.toList() : ref.toBookdown();
187
+
188
+ const editionJSON: EditionSpecification = {
189
+ bookRef: this.bookRef,
190
+ title: this.title,
191
+ authors: this.authors,
192
+ number: this.number,
193
+ summary: this.summary,
194
+ published: this.published,
195
+ images: Object.assign({}, this.images),
196
+ description: this.description,
197
+ chapters: this.chapters.map((chap) => chap.toJSON()),
198
+ license: this.license,
199
+ acknowledgements: this.acknowledgements,
200
+ tags: this.tags.slice(),
201
+ sources: Object.assign({}, this.sources),
202
+ references: references,
203
+ symbols: Object.assign({}, this.symbols),
204
+ glossary: Object.assign({}, this.glossary),
205
+ theme: this.theme,
206
+ base: this.base,
207
+ uids: this.uids.slice(),
208
+ chapteruids: this.getChapterUIDS(),
209
+ active: this.active,
210
+ };
211
+ return editionJSON;
212
+ }
213
+
214
+ getBookRef() {
215
+ return this.bookRef;
216
+ }
217
+
218
+ getEditionRef() {
219
+ return this.editionRef;
220
+ }
221
+
222
+ getChapterUIDS() {
223
+ return Array.from(
224
+ new Set(this.chapters.map((chapter) => chapter.uids).flat())
225
+ );
226
+ }
227
+
228
+ withRef(editionRef: DocumentReference | undefined) {
229
+ return new Edition(
230
+ this.bookRef,
231
+ editionRef,
232
+ this.uids,
233
+ this.title,
234
+ this.authors,
235
+ this.number,
236
+ this.summary,
237
+ this.published,
238
+ this.images,
239
+ this.description,
240
+ this.chapters,
241
+ this.license,
242
+ this.acknowledgements,
243
+ this.tags,
244
+ this.sources,
245
+ this.references,
246
+ this.symbols,
247
+ this.glossary,
248
+ this.theme,
249
+ this.base,
250
+ this.active
251
+ );
252
+ }
253
+
254
+ getTitle() {
255
+ return this.title;
256
+ }
257
+
258
+ withTitle(title: string): Edition {
259
+ return new Edition(
260
+ this.bookRef,
261
+ this.editionRef,
262
+ this.uids,
263
+ title,
264
+ this.authors,
265
+ this.number,
266
+ this.summary,
267
+ this.published,
268
+ this.images,
269
+ this.description,
270
+ this.chapters,
271
+ this.license,
272
+ this.acknowledgements,
273
+ this.tags,
274
+ this.sources,
275
+ this.references,
276
+ this.symbols,
277
+ this.glossary,
278
+ this.theme,
279
+ this.base,
280
+ this.active
281
+ );
282
+ }
283
+
284
+ getDescription() {
285
+ return this.description;
286
+ }
287
+ setDescription(description: string): Edition {
288
+ return new Edition(
289
+ this.bookRef,
290
+ this.editionRef,
291
+ this.uids,
292
+ this.title,
293
+ this.authors,
294
+ this.number,
295
+ this.summary,
296
+ this.published,
297
+ this.images,
298
+ description,
299
+ this.chapters,
300
+ this.license,
301
+ this.acknowledgements,
302
+ this.tags,
303
+ this.sources,
304
+ this.references,
305
+ this.symbols,
306
+ this.glossary,
307
+ this.theme,
308
+ this.base,
309
+ this.active
310
+ );
311
+ }
312
+
313
+ getAcknowledgements() {
314
+ return this.acknowledgements;
315
+ }
316
+
317
+ withAcknowledgements(acks: string) {
318
+ return new Edition(
319
+ this.bookRef,
320
+ this.editionRef,
321
+ this.uids,
322
+ this.title,
323
+ this.authors,
324
+ this.number,
325
+ this.summary,
326
+ this.published,
327
+ this.images,
328
+ this.description,
329
+ this.chapters,
330
+ this.license,
331
+ acks,
332
+ this.tags,
333
+ this.sources,
334
+ this.references,
335
+ this.symbols,
336
+ this.glossary,
337
+ this.theme,
338
+ this.base,
339
+ this.active
340
+ );
341
+ }
342
+
343
+ withSummary(summary: string) {
344
+ return new Edition(
345
+ this.bookRef,
346
+ this.editionRef,
347
+ this.uids,
348
+ this.title,
349
+ this.authors,
350
+ this.number,
351
+ summary,
352
+ this.published,
353
+ this.images,
354
+ this.description,
355
+ this.chapters,
356
+ this.license,
357
+ this.acknowledgements,
358
+ this.tags,
359
+ this.sources,
360
+ this.references,
361
+ this.symbols,
362
+ this.glossary,
363
+ this.theme,
364
+ this.base,
365
+ this.active
366
+ );
367
+ }
368
+
369
+ asPublished(published: boolean) {
370
+ return new Edition(
371
+ this.bookRef,
372
+ this.editionRef,
373
+ this.uids,
374
+ this.title,
375
+ this.authors,
376
+ this.number,
377
+ this.summary,
378
+ published ? Date.now() : null,
379
+ this.images,
380
+ this.description,
381
+ this.chapters,
382
+ this.license,
383
+ this.acknowledgements,
384
+ this.tags,
385
+ this.sources,
386
+ this.references,
387
+ this.symbols,
388
+ this.glossary,
389
+ this.theme,
390
+ this.base,
391
+ this.active
392
+ );
393
+ }
394
+
395
+ getLicense() {
396
+ return this.license;
397
+ }
398
+ setLicense(license: string) {
399
+ return new Edition(
400
+ this.bookRef,
401
+ this.editionRef,
402
+ this.uids,
403
+ this.title,
404
+ this.authors,
405
+ this.number,
406
+ this.summary,
407
+ this.published,
408
+ this.images,
409
+ this.description,
410
+ this.chapters,
411
+ license,
412
+ this.acknowledgements,
413
+ this.tags,
414
+ this.sources,
415
+ this.references,
416
+ this.symbols,
417
+ this.glossary,
418
+ this.theme,
419
+ this.base,
420
+ this.active
421
+ );
422
+ }
423
+
424
+ getChapters() {
425
+ return this.chapters.slice();
426
+ }
427
+
428
+ hasChapter(chapterID: string): boolean {
429
+ return (
430
+ this.getChapter(chapterID) !== undefined ||
431
+ ['references', 'glossary', 'index', 'search', 'media'].includes(
432
+ chapterID
433
+ )
434
+ );
435
+ }
436
+
437
+ getChapter(chapterID: string): Chapter | undefined {
438
+ return this.chapters.find((chapter) => chapter.getID() === chapterID);
439
+ }
440
+
441
+ getChapterByRef(ref: DocumentReference): Chapter | undefined {
442
+ return this.chapters.find(
443
+ (chap) => chap.ref !== undefined && chap.ref.id === ref.id
444
+ );
445
+ }
446
+
447
+ getChapterPosition(chapterID: string): number | undefined {
448
+ var position = 0;
449
+ for (; position < this.chapters.length; position++)
450
+ if (this.chapters[position].getID() === chapterID) return position;
451
+
452
+ return undefined;
453
+ }
454
+
455
+ getChapterCount() {
456
+ return this.chapters.length;
457
+ }
458
+
459
+ withChapters(chapters: Chapter[]) {
460
+ return new Edition(
461
+ this.bookRef,
462
+ this.editionRef,
463
+ this.uids,
464
+ this.title,
465
+ this.authors,
466
+ this.number,
467
+ this.summary,
468
+ this.published,
469
+ this.images,
470
+ this.description,
471
+ chapters,
472
+ this.license,
473
+ this.acknowledgements,
474
+ this.tags,
475
+ this.sources,
476
+ this.references,
477
+ this.symbols,
478
+ this.glossary,
479
+ this.theme,
480
+ this.base,
481
+ this.active
482
+ );
483
+ }
484
+
485
+ withChapterText(text: [DocumentReference, string][]) {
486
+ return this.withChapters(
487
+ this.chapters.map((chapter) => {
488
+ if (chapter.ref === undefined) return chapter;
489
+ const match = text.find(
490
+ ([ref, text]) =>
491
+ chapter.ref !== undefined &&
492
+ chapter.ref.id === ref.id &&
493
+ chapter.text !== text &&
494
+ text !== undefined
495
+ );
496
+ return match ? chapter.withText(match[1]) : chapter;
497
+ })
498
+ );
499
+ }
500
+
501
+ withRevisedChapter(previous: Chapter, edited: Chapter) {
502
+ const index = this.chapters.indexOf(previous);
503
+ if (index < 0) return this;
504
+ return this.withChapters([
505
+ ...this.chapters.slice(0, index),
506
+ edited,
507
+ ...this.chapters.slice(index + 1),
508
+ ]);
509
+ }
510
+
511
+ withoutRefs() {
512
+ return this.withRef(undefined).withChapters(
513
+ this.chapters.map((chap) => chap.withoutRef())
514
+ );
515
+ }
516
+
517
+ withIncrementedEditionNumber() {
518
+ return new Edition(
519
+ this.bookRef,
520
+ this.editionRef,
521
+ this.uids,
522
+ this.title,
523
+ this.authors,
524
+ this.number + 1,
525
+ this.summary,
526
+ this.published,
527
+ this.images,
528
+ this.description,
529
+ this.chapters,
530
+ this.license,
531
+ this.acknowledgements,
532
+ this.tags,
533
+ this.sources,
534
+ this.references,
535
+ this.symbols,
536
+ this.glossary,
537
+ this.theme,
538
+ this.base,
539
+ this.active
540
+ );
541
+ }
542
+
543
+ withNewChapter() {
544
+ // Synthesize a chapter ID placeholder that doesn't overlap with existing chapter names
545
+ let number = 1;
546
+ while (this.hasChapter('chapter' + number)) number++;
547
+
548
+ // Create a default chapter on this model. Remember the document reference so we can modify it later.
549
+ const newChapter = new Chapter(
550
+ undefined,
551
+ `chapter${number}`,
552
+ 'Untitled Chapter',
553
+ [],
554
+ null,
555
+ true,
556
+ false,
557
+ undefined,
558
+ '',
559
+ []
560
+ );
561
+ return this.withChapters([...this.chapters, newChapter]);
562
+ }
563
+
564
+ withoutChapter(chapterID: string): Edition {
565
+ let index = this.chapters.findIndex(
566
+ (chapter) => chapter.getID() === chapterID
567
+ );
568
+ if (index < 0) return this;
569
+
570
+ return this.withChapters([
571
+ ...this.chapters.slice(0, index),
572
+ ...this.chapters.slice(index + 1),
573
+ ]);
574
+ }
575
+
576
+ withMovedChapter(chapterID: string, increment: number): Edition {
577
+ // Get the index of the chapter.
578
+ let index = this.chapters.findIndex(
579
+ (chapter) => chapter.getID() === chapterID
580
+ );
581
+ if (index + increment < 0 || index + increment >= this.chapters.length)
582
+ return this;
583
+
584
+ const newChapters = this.chapters.slice();
585
+ const temp = newChapters[index + increment];
586
+ newChapters[index + increment] = newChapters[index];
587
+ newChapters[index] = temp;
588
+
589
+ return new Edition(
590
+ this.bookRef,
591
+ this.editionRef,
592
+ this.uids,
593
+ this.title,
594
+ this.authors,
595
+ this.number,
596
+ this.summary,
597
+ this.published,
598
+ this.images,
599
+ this.description,
600
+ newChapters,
601
+ this.license,
602
+ this.acknowledgements,
603
+ this.tags,
604
+ this.sources,
605
+ this.references,
606
+ this.symbols,
607
+ this.glossary,
608
+ this.theme,
609
+ this.base,
610
+ this.active
611
+ );
612
+ }
613
+
614
+ getSymbols() {
615
+ return this.symbols;
616
+ }
617
+
618
+ hasReferences() {
619
+ return Object.keys(this.references).length > 0;
620
+ }
621
+
622
+ getReferences() {
623
+ return Object.assign({}, this.references);
624
+ }
625
+
626
+ getReference(citationID: string) {
627
+ return citationID in this.references
628
+ ? this.references[citationID]
629
+ : undefined;
630
+ }
631
+
632
+ withReferences(newReferences: Record<string, FormatNode | Reference>) {
633
+ return new Edition(
634
+ this.bookRef,
635
+ this.editionRef,
636
+ this.uids,
637
+ this.title,
638
+ this.authors,
639
+ this.number,
640
+ this.summary,
641
+ this.published,
642
+ this.images,
643
+ this.description,
644
+ this.chapters,
645
+ this.license,
646
+ this.acknowledgements,
647
+ this.tags,
648
+ this.sources,
649
+ newReferences,
650
+ this.symbols,
651
+ this.glossary,
652
+ this.theme,
653
+ this.base,
654
+ this.active
655
+ );
656
+ }
657
+
658
+ withNewReferences(references: Reference[]): Edition {
659
+ const newReferences = Object.assign({}, this.references);
660
+ // Generate a unique ID for the reference.
661
+ for (const newRef of references)
662
+ newReferences[newRef.citationID] = newRef;
663
+ return this.withReferences(newReferences);
664
+ }
665
+
666
+ withEditedReference(ref: Reference) {
667
+ if (!(ref.citationID in this.references)) return this;
668
+ const newReferences = Object.assign({}, this.references);
669
+ newReferences[ref.citationID] = ref;
670
+ return this.withReferences(newReferences);
671
+ }
672
+
673
+ withEditedReferenceID(newCitationID: string, ref: Reference) {
674
+ if (!(ref.citationID in this.references)) return;
675
+ const newReferences = Object.assign({}, this.references);
676
+ delete newReferences[ref.citationID];
677
+ newReferences[newCitationID] = ref.withCitationID(newCitationID);
678
+ return this.withReferences(newReferences);
679
+ }
680
+
681
+ withoutReference(citationID: string) {
682
+ if (!(citationID in this.references)) return this;
683
+ const newReferences = Object.assign({}, this.references);
684
+ delete newReferences[citationID];
685
+ return this.withReferences(newReferences);
686
+ }
687
+
688
+ hasGlossary() {
689
+ return Object.keys(this.glossary).length > 0;
690
+ }
691
+
692
+ getGlossary() {
693
+ return Object.assign({}, this.glossary);
694
+ }
695
+
696
+ hasDefinition(id: string) {
697
+ return id in this.glossary;
698
+ }
699
+
700
+ withGlossary(glossary: Record<string, Definition>) {
701
+ return new Edition(
702
+ this.bookRef,
703
+ this.editionRef,
704
+ this.uids,
705
+ this.title,
706
+ this.authors,
707
+ this.number,
708
+ this.summary,
709
+ this.published,
710
+ this.images,
711
+ this.description,
712
+ this.chapters,
713
+ this.license,
714
+ this.acknowledgements,
715
+ this.tags,
716
+ this.sources,
717
+ this.references,
718
+ this.symbols,
719
+ glossary,
720
+ this.theme,
721
+ this.base,
722
+ this.active
723
+ );
724
+ }
725
+
726
+ withDefinition(
727
+ id: string,
728
+ phrase: string,
729
+ definition: string,
730
+ synonyms: string[]
731
+ ): Edition {
732
+ const newGlossary = Object.assign({}, this.glossary);
733
+ newGlossary[id] = {
734
+ phrase: phrase,
735
+ definition: definition,
736
+ synonyms: synonyms,
737
+ };
738
+ return this.withGlossary(newGlossary);
739
+ }
740
+
741
+ withoutDefinition(id: string): Edition {
742
+ const newGlossary = Object.assign({}, this.glossary);
743
+ delete newGlossary[id];
744
+ return this.withGlossary(newGlossary);
745
+ }
746
+
747
+ withEditedDefinition(id: string, definition: Definition): Edition {
748
+ const newGlossary = Object.assign({}, this.glossary);
749
+ newGlossary[id] = definition;
750
+ return this.withGlossary(newGlossary);
751
+ }
752
+
753
+ withEditedDefinitionID(id: string, newID: string) {
754
+ if (!(id in this.glossary)) return;
755
+ const newGlossary = Object.assign({}, this.glossary);
756
+ const definition = newGlossary[id];
757
+ delete newGlossary[id];
758
+ newGlossary[newID] = definition;
759
+ return this.withGlossary(newGlossary);
760
+ }
761
+
762
+ getTags() {
763
+ return this.tags;
764
+ }
765
+
766
+ getTheme() {
767
+ return this.theme;
768
+ }
769
+
770
+ withTheme(theme: Theme | null) {
771
+ return new Edition(
772
+ this.bookRef,
773
+ this.editionRef,
774
+ this.uids,
775
+ this.title,
776
+ this.authors,
777
+ this.number,
778
+ this.summary,
779
+ this.published,
780
+ this.images,
781
+ this.description,
782
+ this.chapters,
783
+ this.license,
784
+ this.acknowledgements,
785
+ this.tags,
786
+ this.sources,
787
+ this.references,
788
+ this.symbols,
789
+ this.glossary,
790
+ theme,
791
+ this.base,
792
+ this.active
793
+ );
794
+ }
795
+
796
+ withThemeValue(group: string, name: string, value: string) {
797
+ if (this.theme === null) return this;
798
+ if (group === 'imports') return this;
799
+ const newTheme: Record<string, Record<string, string>> = Object.assign(
800
+ {},
801
+ this.theme as Record<string, Record<string, string>>
802
+ );
803
+ const newGroup: Record<string, string> = Object.assign(
804
+ {},
805
+ (this.theme as Record<string, Record<string, string>>)[group]
806
+ );
807
+ newGroup[name] = value;
808
+ newTheme[group] = newGroup;
809
+ return this.withTheme(newTheme);
810
+ }
811
+
812
+ // Don't let callers get their sneaky hands on this mutable array...
813
+ getAuthors() {
814
+ return [...this.authors];
815
+ }
816
+
817
+ withAuthors(authors: string[]) {
818
+ return new Edition(
819
+ this.bookRef,
820
+ this.editionRef,
821
+ this.uids,
822
+ this.title,
823
+ authors,
824
+ this.number,
825
+ this.summary,
826
+ this.published,
827
+ this.images,
828
+ this.description,
829
+ this.chapters,
830
+ this.license,
831
+ this.acknowledgements,
832
+ this.tags,
833
+ this.sources,
834
+ this.references,
835
+ this.symbols,
836
+ this.glossary,
837
+ this.theme,
838
+ this.base,
839
+ this.active
840
+ );
841
+ }
842
+
843
+ withAuthor(name: string) {
844
+ return this.withAuthors([...this.authors, name]);
845
+ }
846
+
847
+ withAuthorName(index: number, name: string) {
848
+ if (index < 0 || index >= this.authors.length) return this;
849
+ return this.withAuthors([
850
+ ...this.authors.slice(0, index),
851
+ name,
852
+ ...this.authors.slice(index + 1),
853
+ ]);
854
+ }
855
+
856
+ withoutAuthor(index: number) {
857
+ if (index < 0 || index >= this.authors.length) return this;
858
+ return this.withAuthors([
859
+ ...this.authors.slice(0, index),
860
+ ...this.authors.slice(index + 1),
861
+ ]);
862
+ }
863
+
864
+ withEditors(uids: string[]) {
865
+ return new Edition(
866
+ this.bookRef,
867
+ this.editionRef,
868
+ uids,
869
+ this.title,
870
+ this.authors,
871
+ this.number,
872
+ this.summary,
873
+ this.published,
874
+ this.images,
875
+ this.description,
876
+ this.chapters,
877
+ this.license,
878
+ this.acknowledgements,
879
+ this.tags,
880
+ this.sources,
881
+ this.references,
882
+ this.symbols,
883
+ this.glossary,
884
+ this.theme,
885
+ this.base,
886
+ this.active
887
+ );
888
+ }
889
+
890
+ hasImage(id: string) {
891
+ return this.images[id] !== null;
892
+ }
893
+
894
+ getImage(id: string) {
895
+ return this.images[id] ?? null;
896
+ }
897
+
898
+ withImage(id: string, embed: string | null) {
899
+ const newImages = Object.assign({}, this.images);
900
+ newImages[id] = embed;
901
+ return new Edition(
902
+ this.bookRef,
903
+ this.editionRef,
904
+ this.uids,
905
+ this.title,
906
+ this.authors,
907
+ this.number,
908
+ this.summary,
909
+ this.published,
910
+ newImages,
911
+ this.description,
912
+ this.chapters,
913
+ this.license,
914
+ this.acknowledgements,
915
+ this.tags,
916
+ this.sources,
917
+ this.references,
918
+ this.symbols,
919
+ this.glossary,
920
+ this.theme,
921
+ this.base,
922
+ this.active
923
+ );
924
+ }
925
+
926
+ isEditor(uid: string) {
927
+ return this.uids.includes(uid);
928
+ }
929
+
930
+ isChapterEditor(uid: string) {
931
+ return this.getChapterUIDS().includes(uid);
932
+ }
933
+
934
+ getLeasee(content: string): string | undefined {
935
+ return this.active[content];
936
+ }
937
+
938
+ hasLease(uid: string, content: string) {
939
+ return this.active[content] === uid;
940
+ }
941
+
942
+ isLeased(contentID: string) {
943
+ return contentID in this.active;
944
+ }
945
+
946
+ withLock(uid: string, content: string, lock: boolean) {
947
+ const newActive = Object.assign({}, this.active);
948
+ if (lock) newActive[content] = uid;
949
+ else delete newActive[content];
950
+
951
+ return new Edition(
952
+ this.bookRef,
953
+ this.editionRef,
954
+ this.uids,
955
+ this.title,
956
+ this.authors,
957
+ this.number,
958
+ this.summary,
959
+ this.published,
960
+ this.images,
961
+ this.description,
962
+ this.chapters,
963
+ this.license,
964
+ this.acknowledgements,
965
+ this.tags,
966
+ this.sources,
967
+ this.references,
968
+ this.symbols,
969
+ this.glossary,
970
+ this.theme,
971
+ this.base,
972
+ newActive
973
+ );
974
+ }
975
+
976
+ getBookReadingTime() {
977
+ return this.chapters
978
+ .map((chapter) => chapter.getReadingTime(this))
979
+ .reduce(
980
+ (total, time) =>
981
+ total === undefined
982
+ ? 0
983
+ : time === undefined
984
+ ? total
985
+ : total + time,
986
+ 0
987
+ );
988
+ }
989
+
990
+ getChapterNumber(chapterID: string) {
991
+ let chapterNumber = 1;
992
+ let match = null;
993
+ this.chapters.forEach((chapter) => {
994
+ // If we found a match...
995
+ if (chapter.getID() === chapterID) {
996
+ match = chapterNumber;
997
+ // And it's an unnumbered chapter, set to null.
998
+ if (!chapter.isNumbered()) match = null;
999
+ }
1000
+ // Otherwise, increment if it's numbered.
1001
+ else if (chapter.isNumbered()) chapterNumber++;
1002
+ });
1003
+ // Remember the number if we found it.
1004
+ if (match !== null) return match;
1005
+ else return undefined;
1006
+ }
1007
+
1008
+ getSource(sourceID: string) {
1009
+ return sourceID.charAt(0) === '#' &&
1010
+ sourceID.substring(1) in this.sources
1011
+ ? this.sources[sourceID.substring(1)]
1012
+ : null;
1013
+ }
1014
+
1015
+ getChapterName(chapterID: string): string | undefined {
1016
+ const chapter = this.getChapter(chapterID);
1017
+ return chapter?.getTitle();
1018
+ }
1019
+
1020
+ getChapterSection(chapterID: string): string | undefined {
1021
+ const chapter = this.getChapter(chapterID);
1022
+ return chapter?.getSection();
1023
+ }
1024
+
1025
+ getFootnoteSymbol(number: number) {
1026
+ let symbols = 'abcdefghijklmnopqrstuvwxyz';
1027
+ // Let's hope there are never more than 26^2 footnotes in a single chapter...
1028
+ return number < symbols.length
1029
+ ? symbols.charAt(number)
1030
+ : symbols.charAt(Math.floor(number / symbols.length) - 1) +
1031
+ symbols.charAt(number % symbols.length);
1032
+ }
1033
+
1034
+ getBookIndex(): Record<string, Set<string>> {
1035
+ // A map from word to a map of chapters containing the word
1036
+ const bookIndex: Record<string, Set<string>> = {};
1037
+
1038
+ // Construct the index by building a dictionary of chapters in which each word appears.
1039
+ this.chapters.forEach((chapter) => {
1040
+ let index = chapter.getIndex(this);
1041
+ if (index)
1042
+ Object.keys(index).forEach((word) => {
1043
+ if (word !== '' && word.length > 2) {
1044
+ if (!(word in bookIndex)) bookIndex[word] = new Set();
1045
+ bookIndex[word].add(chapter.getID());
1046
+ }
1047
+ });
1048
+ });
1049
+
1050
+ return bookIndex;
1051
+ }
1052
+
1053
+ // Given the current chapter, find the available chapter after it.
1054
+ getNextChapterID(chapterID: string) {
1055
+ // Handle back matter chapters.
1056
+ switch (chapterID) {
1057
+ case ChapterIDs.ReferencesID:
1058
+ return this.hasGlossary()
1059
+ ? ChapterIDs.GlossaryID
1060
+ : ChapterIDs.IndexID;
1061
+ case ChapterIDs.GlossaryID:
1062
+ return ChapterIDs.IndexID;
1063
+ case ChapterIDs.IndexID:
1064
+ return ChapterIDs.SearchID;
1065
+ case ChapterIDs.SearchID:
1066
+ return ChapterIDs.MediaID;
1067
+ case ChapterIDs.MediaID:
1068
+ return ChapterIDs.TableOfContentsID;
1069
+ case ChapterIDs.TableOfContentsID:
1070
+ return this.chapters.length > 0
1071
+ ? this.chapters[0].getID()
1072
+ : null;
1073
+ default:
1074
+ let after = false;
1075
+ for (let i = 0; i < this.chapters.length; i++) {
1076
+ let chapter = this.chapters[i];
1077
+ if (chapter.getID() === chapterID) after = true;
1078
+ // If we're after the given chapter and it's not forthcoming.
1079
+ else if (after && !chapter.isForthcoming())
1080
+ return chapter.getID();
1081
+ }
1082
+ // If the given ID was the last chapter, go to the next back matter chapter.
1083
+ if (after)
1084
+ return this.hasReferences()
1085
+ ? ChapterIDs.ReferencesID
1086
+ : this.hasGlossary()
1087
+ ? ChapterIDs.GlossaryID
1088
+ : ChapterIDs.IndexID;
1089
+ // Otherwise, it wasn't a valid ID
1090
+ else return null;
1091
+ }
1092
+ }
1093
+
1094
+ // Given a chapter id, find the available chapter before it.
1095
+ getPreviousChapterID(chapterID: string) {
1096
+ switch (chapterID) {
1097
+ // Handle back matter chapters.
1098
+ case ChapterIDs.ReferencesID:
1099
+ return this.chapters.length > 0
1100
+ ? this.chapters[this.chapters.length - 1].getID()
1101
+ : null; // Last chapter of the book
1102
+ case ChapterIDs.GlossaryID:
1103
+ return this.hasReferences()
1104
+ ? ChapterIDs.ReferencesID
1105
+ : this.chapters.length > 0
1106
+ ? this.chapters[this.chapters.length - 1].getID()
1107
+ : ChapterIDs.TableOfContentsID;
1108
+ case ChapterIDs.IndexID:
1109
+ return this.hasGlossary()
1110
+ ? ChapterIDs.GlossaryID
1111
+ : this.hasReferences()
1112
+ ? ChapterIDs.ReferencesID
1113
+ : this.chapters.length > 0
1114
+ ? this.chapters[this.chapters.length - 1].getID()
1115
+ : ChapterIDs.TableOfContentsID;
1116
+ case ChapterIDs.SearchID:
1117
+ return ChapterIDs.IndexID;
1118
+ case ChapterIDs.MediaID:
1119
+ return ChapterIDs.SearchID;
1120
+ default:
1121
+ let before = false;
1122
+ for (let i = this.chapters.length - 1; i >= 0; i--) {
1123
+ let chapter = this.chapters[i];
1124
+ if (chapter.getID() === chapterID) before = true;
1125
+ // If we're before the given chapter and it's not forthcoming.
1126
+ else if (before && !chapter.isForthcoming())
1127
+ return chapter.getID();
1128
+ }
1129
+ // If the given ID was the last chapter, go to the next back matter chapter.
1130
+ if (before) return ChapterIDs.TableOfContentsID;
1131
+ // Otherwise, it wasn't a valid ID
1132
+ else return null;
1133
+ }
1134
+ }
1135
+
1136
+ // Get all of the embeds in the book
1137
+ getEmbeds(): EmbedNode[] {
1138
+ let embeds: EmbedNode[] = [];
1139
+
1140
+ // Add the book cover
1141
+ const cover = this.getImage('cover');
1142
+ if (cover) {
1143
+ let coverNode = Parser.parseEmbed(this, cover);
1144
+ if (coverNode instanceof EmbedNode) embeds.push(coverNode);
1145
+ }
1146
+
1147
+ // Add the cover and images from each chapter.
1148
+ this.getChapters().forEach((c) => {
1149
+ const image = c.getImage();
1150
+ let cover =
1151
+ image === null ? undefined : Parser.parseEmbed(this, image);
1152
+ if (cover && cover instanceof EmbedNode) embeds.push(cover);
1153
+
1154
+ // Get the chapter body's embeds
1155
+ let bodyEmbeds = c?.getAST(this)?.getEmbeds();
1156
+ if (bodyEmbeds)
1157
+ bodyEmbeds.forEach((embed: EmbedNode) => embeds.push(embed));
1158
+ });
1159
+
1160
+ // Add the back matter covers
1161
+ let backmatter = ['references', 'glossary', 'index', 'search', 'media'];
1162
+ backmatter.forEach((id) => {
1163
+ const img = this.getImage(id);
1164
+ if (img) {
1165
+ let image = Parser.parseEmbed(this, img);
1166
+ if (image instanceof EmbedNode) embeds.push(image);
1167
+ }
1168
+ });
1169
+
1170
+ return embeds;
1171
+ }
1172
+
1173
+ isLatestEdition(book: Book): boolean {
1174
+ const latestEditionID = book.getLatestEditionID();
1175
+ return (
1176
+ latestEditionID !== undefined &&
1177
+ latestEditionID === this.editionRef?.id
1178
+ );
1179
+ }
1180
+
1181
+ isLatestPublishedEdition(book: Book): boolean {
1182
+ const latestEditionID = book.getLatestPublishedEditionID();
1183
+ return (
1184
+ latestEditionID !== undefined &&
1185
+ latestEditionID === this.editionRef?.id
1186
+ );
1187
+ }
1188
+
1189
+ getEditionNumber() {
1190
+ return this.number;
1191
+ }
1192
+
1193
+ getEditionLabel() {
1194
+ const num = this.number;
1195
+ return `${num}${
1196
+ num === 1 ? 'st' : num === 2 ? 'nd' : num === 3 ? 'rd' : ''
1197
+ }`;
1198
+ }
1199
+
1200
+ getInfo(): EditionInfo | undefined {
1201
+ return this.editionRef === undefined
1202
+ ? undefined
1203
+ : {
1204
+ ref: this.editionRef,
1205
+ summary: this.summary,
1206
+ number: this.number,
1207
+ published: this.published,
1208
+ editionuids: this.uids,
1209
+ chapteruids: Array.from(
1210
+ new Set(
1211
+ this.chapters.map((chapter) => chapter.uids).flat()
1212
+ )
1213
+ ),
1214
+ };
1215
+ }
1216
+ }