bookish-press 0.4.0

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 (309) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/components/Auth.svelte +52 -0
  4. package/components/Auth.svelte.d.ts +16 -0
  5. package/components/Authentication.d.ts +8 -0
  6. package/components/Authentication.js +1 -0
  7. package/components/BookPreview.svelte +87 -0
  8. package/components/BookPreview.svelte.d.ts +18 -0
  9. package/components/External.svelte +4 -0
  10. package/components/External.svelte.d.ts +18 -0
  11. package/components/Link.svelte +5 -0
  12. package/components/Link.svelte.d.ts +19 -0
  13. package/components/chapter/Atom.svelte +36 -0
  14. package/components/chapter/Atom.svelte.d.ts +19 -0
  15. package/components/chapter/Block.svelte +32 -0
  16. package/components/chapter/Block.svelte.d.ts +17 -0
  17. package/components/chapter/Callout.svelte +10 -0
  18. package/components/chapter/Callout.svelte.d.ts +17 -0
  19. package/components/chapter/CaptionedCode.svelte +34 -0
  20. package/components/chapter/CaptionedCode.svelte.d.ts +17 -0
  21. package/components/chapter/ChapterBody.svelte +23 -0
  22. package/components/chapter/ChapterBody.svelte.d.ts +18 -0
  23. package/components/chapter/Citations.svelte +66 -0
  24. package/components/chapter/Citations.svelte.d.ts +17 -0
  25. package/components/chapter/Code.svelte +35 -0
  26. package/components/chapter/Code.svelte.d.ts +22 -0
  27. package/components/chapter/Comment.svelte +46 -0
  28. package/components/chapter/Comment.svelte.d.ts +17 -0
  29. package/components/chapter/Definition.svelte +38 -0
  30. package/components/chapter/Definition.svelte.d.ts +20 -0
  31. package/components/chapter/Embed.svelte +122 -0
  32. package/components/chapter/Embed.svelte.d.ts +18 -0
  33. package/components/chapter/ErrorMessage.svelte +4 -0
  34. package/components/chapter/ErrorMessage.svelte.d.ts +17 -0
  35. package/components/chapter/Footnote.svelte +37 -0
  36. package/components/chapter/Footnote.svelte.d.ts +19 -0
  37. package/components/chapter/Format.svelte +57 -0
  38. package/components/chapter/Format.svelte.d.ts +18 -0
  39. package/components/chapter/InlineCode.svelte +12 -0
  40. package/components/chapter/InlineCode.svelte.d.ts +17 -0
  41. package/components/chapter/Label.svelte +20 -0
  42. package/components/chapter/Label.svelte.d.ts +17 -0
  43. package/components/chapter/Link.svelte +51 -0
  44. package/components/chapter/Link.svelte.d.ts +17 -0
  45. package/components/chapter/List.svelte +14 -0
  46. package/components/chapter/List.svelte.d.ts +17 -0
  47. package/components/chapter/Marginal.svelte +48 -0
  48. package/components/chapter/Marginal.svelte.d.ts +19 -0
  49. package/components/chapter/Paragraph.svelte +15 -0
  50. package/components/chapter/Paragraph.svelte.d.ts +18 -0
  51. package/components/chapter/Python.svelte +81 -0
  52. package/components/chapter/Python.svelte.d.ts +18 -0
  53. package/components/chapter/Quote.svelte +16 -0
  54. package/components/chapter/Quote.svelte.d.ts +17 -0
  55. package/components/chapter/Rule.svelte +4 -0
  56. package/components/chapter/Rule.svelte.d.ts +17 -0
  57. package/components/chapter/Table.svelte +29 -0
  58. package/components/chapter/Table.svelte.d.ts +17 -0
  59. package/components/chapter/Text.svelte +62 -0
  60. package/components/chapter/Text.svelte.d.ts +17 -0
  61. package/components/chapter/renderPosition.d.ts +3 -0
  62. package/components/chapter/renderPosition.js +4 -0
  63. package/components/editor/BookishEditor.svelte +755 -0
  64. package/components/editor/BookishEditor.svelte.d.ts +22 -0
  65. package/components/editor/CalloutEditor.svelte +10 -0
  66. package/components/editor/CalloutEditor.svelte.d.ts +17 -0
  67. package/components/editor/CaptionedCodeEditor.svelte +22 -0
  68. package/components/editor/CaptionedCodeEditor.svelte.d.ts +17 -0
  69. package/components/editor/CaretContext.d.ts +18 -0
  70. package/components/editor/CaretContext.js +1 -0
  71. package/components/editor/CaretState.d.ts +47 -0
  72. package/components/editor/CaretState.js +1 -0
  73. package/components/editor/CaretUtilities.d.ts +5 -0
  74. package/components/editor/CaretUtilities.js +1 -0
  75. package/components/editor/CitationsEditor.svelte +42 -0
  76. package/components/editor/CitationsEditor.svelte.d.ts +17 -0
  77. package/components/editor/Clipboard.d.ts +3 -0
  78. package/components/editor/Clipboard.js +1 -0
  79. package/components/editor/Command.d.ts +18 -0
  80. package/components/editor/Command.js +1 -0
  81. package/components/editor/Commands.d.ts +3 -0
  82. package/components/editor/Commands.js +951 -0
  83. package/components/editor/ConfirmButton.svelte +43 -0
  84. package/components/editor/ConfirmButton.svelte.d.ts +18 -0
  85. package/components/editor/DefinitionEditor.svelte +28 -0
  86. package/components/editor/DefinitionEditor.svelte.d.ts +17 -0
  87. package/components/editor/EmbedEditor.svelte +87 -0
  88. package/components/editor/EmbedEditor.svelte.d.ts +17 -0
  89. package/components/editor/ImageChooser.svelte +70 -0
  90. package/components/editor/ImageChooser.svelte.d.ts +18 -0
  91. package/components/editor/InlineCodeEditor.svelte +9 -0
  92. package/components/editor/InlineCodeEditor.svelte.d.ts +17 -0
  93. package/components/editor/LabelEditor.svelte +23 -0
  94. package/components/editor/LabelEditor.svelte.d.ts +17 -0
  95. package/components/editor/LanguageEditor.svelte +11 -0
  96. package/components/editor/LanguageEditor.svelte.d.ts +17 -0
  97. package/components/editor/LinkEditor.svelte +75 -0
  98. package/components/editor/LinkEditor.svelte.d.ts +17 -0
  99. package/components/editor/Note.svelte +9 -0
  100. package/components/editor/Note.svelte.d.ts +23 -0
  101. package/components/editor/PositionEditor.svelte +14 -0
  102. package/components/editor/PositionEditor.svelte.d.ts +18 -0
  103. package/components/editor/QuoteEditor.svelte +5 -0
  104. package/components/editor/QuoteEditor.svelte.d.ts +17 -0
  105. package/components/editor/Switch.svelte +56 -0
  106. package/components/editor/Switch.svelte.d.ts +20 -0
  107. package/components/editor/TextEditor.svelte +193 -0
  108. package/components/editor/TextEditor.svelte.d.ts +23 -0
  109. package/components/editor/Toggle.svelte +38 -0
  110. package/components/editor/Toggle.svelte.d.ts +19 -0
  111. package/components/editor/Toolbar.svelte +202 -0
  112. package/components/editor/Toolbar.svelte.d.ts +20 -0
  113. package/components/editor/ToolbarGroup.svelte +41 -0
  114. package/components/editor/ToolbarGroup.svelte.d.ts +19 -0
  115. package/components/editor/ToolbarIcon.svelte +22 -0
  116. package/components/editor/ToolbarIcon.svelte.d.ts +16 -0
  117. package/components/editor/ToolbarSpacer.svelte +1 -0
  118. package/components/editor/ToolbarSpacer.svelte.d.ts +19 -0
  119. package/components/editor/URLEditor.svelte +15 -0
  120. package/components/editor/URLEditor.svelte.d.ts +18 -0
  121. package/components/editor/UndoState.d.ts +8 -0
  122. package/components/editor/UndoState.js +1 -0
  123. package/components/page/Acknowledgements.svelte +29 -0
  124. package/components/page/Acknowledgements.svelte.d.ts +14 -0
  125. package/components/page/Alert.svelte +11 -0
  126. package/components/page/Alert.svelte.d.ts +23 -0
  127. package/components/page/Authors.svelte +62 -0
  128. package/components/page/Authors.svelte.d.ts +20 -0
  129. package/components/page/BulkReferenceEditor.svelte +32 -0
  130. package/components/page/BulkReferenceEditor.svelte.d.ts +14 -0
  131. package/components/page/Chapter.svelte +301 -0
  132. package/components/page/Chapter.svelte.d.ts +18 -0
  133. package/components/page/ChapterContext.d.ts +10 -0
  134. package/components/page/ChapterContext.js +1 -0
  135. package/components/page/Contexts.d.ts +27 -0
  136. package/components/page/Contexts.js +21 -0
  137. package/components/page/DefinitionView.svelte +129 -0
  138. package/components/page/DefinitionView.svelte.d.ts +18 -0
  139. package/components/page/Description.svelte +22 -0
  140. package/components/page/Description.svelte.d.ts +14 -0
  141. package/components/page/Edition.svelte +106 -0
  142. package/components/page/Edition.svelte.d.ts +21 -0
  143. package/components/page/Glossary.svelte +61 -0
  144. package/components/page/Glossary.svelte.d.ts +14 -0
  145. package/components/page/Header.svelte +105 -0
  146. package/components/page/Header.svelte.d.ts +27 -0
  147. package/components/page/Index.svelte +117 -0
  148. package/components/page/Index.svelte.d.ts +14 -0
  149. package/components/page/Instructions.svelte +30 -0
  150. package/components/page/Instructions.svelte.d.ts +16 -0
  151. package/components/page/License.svelte +29 -0
  152. package/components/page/License.svelte.d.ts +14 -0
  153. package/components/page/Loading.svelte +13 -0
  154. package/components/page/Loading.svelte.d.ts +19 -0
  155. package/components/page/Media.svelte +76 -0
  156. package/components/page/Media.svelte.d.ts +14 -0
  157. package/components/page/MediaPreview.svelte +11 -0
  158. package/components/page/MediaPreview.svelte.d.ts +19 -0
  159. package/components/page/Outline.svelte +173 -0
  160. package/components/page/Outline.svelte.d.ts +19 -0
  161. package/components/page/Page.svelte +53 -0
  162. package/components/page/Page.svelte.d.ts +19 -0
  163. package/components/page/PossibleChapter.svelte +14 -0
  164. package/components/page/PossibleChapter.svelte.d.ts +14 -0
  165. package/components/page/PossibleReference.svelte +16 -0
  166. package/components/page/PossibleReference.svelte.d.ts +19 -0
  167. package/components/page/Print.svelte +8 -0
  168. package/components/page/Print.svelte.d.ts +14 -0
  169. package/components/page/Reference.svelte +145 -0
  170. package/components/page/Reference.svelte.d.ts +17 -0
  171. package/components/page/References.svelte +58 -0
  172. package/components/page/References.svelte.d.ts +14 -0
  173. package/components/page/Revisions.svelte +124 -0
  174. package/components/page/Revisions.svelte.d.ts +14 -0
  175. package/components/page/Search.svelte +108 -0
  176. package/components/page/Search.svelte.d.ts +14 -0
  177. package/components/page/Status.svelte +49 -0
  178. package/components/page/Status.svelte.d.ts +19 -0
  179. package/components/page/SubdomainEditor.svelte +30 -0
  180. package/components/page/SubdomainEditor.svelte.d.ts +14 -0
  181. package/components/page/TableOfContents.svelte +234 -0
  182. package/components/page/TableOfContents.svelte.d.ts +14 -0
  183. package/components/page/TableOfContentsImage.svelte +15 -0
  184. package/components/page/TableOfContentsImage.svelte.d.ts +16 -0
  185. package/components/page/TableOfContentsRow.svelte +57 -0
  186. package/components/page/TableOfContentsRow.svelte.d.ts +24 -0
  187. package/components/page/ThemeEditor.svelte +52 -0
  188. package/components/page/ThemeEditor.svelte.d.ts +14 -0
  189. package/components/page/ThemeEditorPreview.svelte +37 -0
  190. package/components/page/ThemeEditorPreview.svelte.d.ts +17 -0
  191. package/components/page/ThemeSetEditor.svelte +17 -0
  192. package/components/page/ThemeSetEditor.svelte.d.ts +18 -0
  193. package/components/page/ThemeVariableEditor.svelte +28 -0
  194. package/components/page/ThemeVariableEditor.svelte.d.ts +18 -0
  195. package/components/page/Unknown.svelte +29 -0
  196. package/components/page/Unknown.svelte.d.ts +16 -0
  197. package/components/page/margins.d.ts +2 -0
  198. package/components/page/margins.js +132 -0
  199. package/models/BookLoader.d.ts +2 -0
  200. package/models/BookLoader.js +67 -0
  201. package/models/Firebase.d.ts +4 -0
  202. package/models/Firebase.js +26 -0
  203. package/models/Firestore.d.ts +22 -0
  204. package/models/Firestore.js +194 -0
  205. package/models/book/Book.d.ts +60 -0
  206. package/models/book/Book.js +135 -0
  207. package/models/book/BookMedia.d.ts +23 -0
  208. package/models/book/BookMedia.js +102 -0
  209. package/models/book/Chapter.d.ts +70 -0
  210. package/models/book/Chapter.js +221 -0
  211. package/models/book/ChapterID.d.ts +10 -0
  212. package/models/book/ChapterID.js +10 -0
  213. package/models/book/Definition.d.ts +6 -0
  214. package/models/book/Definition.js +1 -0
  215. package/models/book/Edition.d.ts +111 -0
  216. package/models/book/Edition.js +466 -0
  217. package/models/book/Theme.d.ts +106 -0
  218. package/models/book/Theme.js +76 -0
  219. package/models/book/ThemeColors.d.ts +15 -0
  220. package/models/book/ThemeColors.js +1 -0
  221. package/models/chapter/AtomNode.d.ts +18 -0
  222. package/models/chapter/AtomNode.js +31 -0
  223. package/models/chapter/BlockNode.d.ts +21 -0
  224. package/models/chapter/BlockNode.js +117 -0
  225. package/models/chapter/BlocksNode.d.ts +50 -0
  226. package/models/chapter/BlocksNode.js +709 -0
  227. package/models/chapter/BlocksNode.test.d.ts +1 -0
  228. package/models/chapter/BlocksNode.test.js +302 -0
  229. package/models/chapter/Bookkeeping.d.ts +4 -0
  230. package/models/chapter/Bookkeeping.js +1 -0
  231. package/models/chapter/CalloutNode.d.ts +17 -0
  232. package/models/chapter/CalloutNode.js +36 -0
  233. package/models/chapter/Caret.d.ts +21 -0
  234. package/models/chapter/Caret.js +69 -0
  235. package/models/chapter/ChapterNode.d.ts +34 -0
  236. package/models/chapter/ChapterNode.js +80 -0
  237. package/models/chapter/CitationsNode.d.ts +16 -0
  238. package/models/chapter/CitationsNode.js +17 -0
  239. package/models/chapter/CodeNode.d.ts +30 -0
  240. package/models/chapter/CodeNode.js +64 -0
  241. package/models/chapter/CommentNode.d.ts +18 -0
  242. package/models/chapter/CommentNode.js +32 -0
  243. package/models/chapter/DefinitionNode.d.ts +12 -0
  244. package/models/chapter/DefinitionNode.js +20 -0
  245. package/models/chapter/Edit.d.ts +7 -0
  246. package/models/chapter/Edit.js +1 -0
  247. package/models/chapter/EmbedNode.d.ts +40 -0
  248. package/models/chapter/EmbedNode.js +89 -0
  249. package/models/chapter/ErrorNode.d.ts +17 -0
  250. package/models/chapter/ErrorNode.js +21 -0
  251. package/models/chapter/FootnoteNode.d.ts +18 -0
  252. package/models/chapter/FootnoteNode.js +29 -0
  253. package/models/chapter/FormatNode.d.ts +60 -0
  254. package/models/chapter/FormatNode.js +614 -0
  255. package/models/chapter/FormatNode.test.d.ts +1 -0
  256. package/models/chapter/FormatNode.test.js +54 -0
  257. package/models/chapter/InlineCodeNode.d.ts +12 -0
  258. package/models/chapter/InlineCodeNode.js +18 -0
  259. package/models/chapter/LabelNode.d.ts +17 -0
  260. package/models/chapter/LabelNode.js +22 -0
  261. package/models/chapter/LinkNode.d.ts +12 -0
  262. package/models/chapter/LinkNode.js +16 -0
  263. package/models/chapter/ListNode.d.ts +51 -0
  264. package/models/chapter/ListNode.js +370 -0
  265. package/models/chapter/ListNode.test.d.ts +1 -0
  266. package/models/chapter/ListNode.test.js +49 -0
  267. package/models/chapter/MetadataNode.d.ts +17 -0
  268. package/models/chapter/MetadataNode.js +24 -0
  269. package/models/chapter/Node.d.ts +36 -0
  270. package/models/chapter/Node.js +173 -0
  271. package/models/chapter/Node.test.d.ts +1 -0
  272. package/models/chapter/Node.test.js +27 -0
  273. package/models/chapter/ParagraphNode.d.ts +33 -0
  274. package/models/chapter/ParagraphNode.js +93 -0
  275. package/models/chapter/ParagraphNode.test.d.ts +1 -0
  276. package/models/chapter/ParagraphNode.test.js +21 -0
  277. package/models/chapter/Parser.d.ts +75 -0
  278. package/models/chapter/Parser.js +824 -0
  279. package/models/chapter/Parser.test.d.ts +1 -0
  280. package/models/chapter/Parser.test.js +25 -0
  281. package/models/chapter/Position.d.ts +2 -0
  282. package/models/chapter/Position.js +1 -0
  283. package/models/chapter/QuoteNode.d.ts +25 -0
  284. package/models/chapter/QuoteNode.js +61 -0
  285. package/models/chapter/ReferenceNode.d.ts +29 -0
  286. package/models/chapter/ReferenceNode.js +48 -0
  287. package/models/chapter/RootNode.d.ts +5 -0
  288. package/models/chapter/RootNode.js +1 -0
  289. package/models/chapter/RuleNode.d.ts +15 -0
  290. package/models/chapter/RuleNode.js +16 -0
  291. package/models/chapter/TableNode.d.ts +35 -0
  292. package/models/chapter/TableNode.js +176 -0
  293. package/models/chapter/TableNode.test.d.ts +1 -0
  294. package/models/chapter/TableNode.test.js +31 -0
  295. package/models/chapter/TextNode.d.ts +36 -0
  296. package/models/chapter/TextNode.js +136 -0
  297. package/models/chapter/TextNode.test.d.ts +1 -0
  298. package/models/chapter/TextNode.test.js +6 -0
  299. package/models/loadEdition.d.ts +5 -0
  300. package/models/loadEdition.js +16 -0
  301. package/package.json +189 -0
  302. package/util/getSubdomain.d.ts +3 -0
  303. package/util/getSubdomain.js +22 -0
  304. package/util/isMobile.d.ts +2 -0
  305. package/util/isMobile.js +6 -0
  306. package/util/mineReference.d.ts +3 -0
  307. package/util/mineReference.js +62 -0
  308. package/util/scrollToEyeLevel.d.ts +2 -0
  309. package/util/scrollToEyeLevel.js +5 -0
@@ -0,0 +1,129 @@
1
+ <script>import Parser from '../../models/chapter/Parser';
2
+ import ConfirmButton from '../editor/ConfirmButton.svelte';
3
+ import TextEditor from '../editor/TextEditor.svelte';
4
+ import BookishEditor from '../editor/BookishEditor.svelte';
5
+ import Format from '../chapter/Format.svelte';
6
+ import Note from '../editor/Note.svelte';
7
+ import { afterUpdate } from 'svelte';
8
+ import { getEdition, isEditable } from './Contexts';
9
+ export let id;
10
+ export let definition;
11
+ let edition = getEdition();
12
+ let editable = isEditable();
13
+ // Focus after adding a new synonym.
14
+ let newSynonym = false;
15
+ let synonymsEditor = null;
16
+ afterUpdate(() => {
17
+ if (newSynonym && synonymsEditor) {
18
+ const editors = synonymsEditor.querySelectorAll("input");
19
+ if (editors.length > 0) {
20
+ const last = editors[editors.length - 1];
21
+ if (last instanceof HTMLElement)
22
+ last.focus();
23
+ }
24
+ newSynonym = false;
25
+ }
26
+ });
27
+ $: format = Parser.parseFormat(undefined, definition.definition).withTextIfEmpty();
28
+ function addSynonym() {
29
+ if ($edition && definition.synonyms) {
30
+ $edition.editDefinition(id, {
31
+ phrase: definition.phrase,
32
+ definition: definition.definition,
33
+ synonyms: [...definition.synonyms, ""]
34
+ });
35
+ }
36
+ newSynonym = true;
37
+ }
38
+ $: syns = definition.synonyms || [];
39
+ </script>
40
+
41
+ <tr>
42
+ <td>
43
+ {#if editable && edition }
44
+ <ConfirmButton
45
+ commandLabel="x"
46
+ confirmLabel="Confirm"
47
+ command={() => $edition.removeDefinition(id)}
48
+ />
49
+ {/if}
50
+ {#if editable && edition }
51
+ <strong>
52
+ <TextEditor
53
+ startText={definition.phrase}
54
+ label={'Glossary phrase editor.'}
55
+ placeholder="Phrase"
56
+ valid={ text => {
57
+ if(text.length === 0) return "Phrase can't be empty";
58
+ }}
59
+ save={text => $edition.editDefinition(id, {
60
+ phrase: text,
61
+ definition: definition.definition,
62
+ synonyms: definition.synonyms
63
+ })}
64
+ />
65
+ </strong>
66
+ {:else}
67
+ <strong>{#if definition.phrase }{definition.phrase}{:else}<em>Phrase</em>{/if}</strong>
68
+ {/if}
69
+ </td>
70
+ <td>
71
+ {#if editable && edition }
72
+ <BookishEditor
73
+ ast={format}
74
+ save={node => $edition.editDefinition(id, {
75
+ phrase: definition.phrase,
76
+ definition: node.toBookdown(),
77
+ synonyms: definition.synonyms
78
+ })}
79
+ chapter={false}
80
+ component={Format}
81
+ placeholder="How would you define this?"
82
+ />
83
+ {:else}
84
+ {#if definition.definition === ""}
85
+ <em>Definition</em>
86
+ {:else}
87
+ <Format node={format}/>
88
+ {/if}
89
+ {/if}
90
+ <br/>
91
+ {#if edition && editable }
92
+ <span bind:this={synonymsEditor}>
93
+ <button on:click={addSynonym}>+</button>&nbsp;
94
+ {#if syns.length === 0 }
95
+ <em>No synonyms</em>
96
+ {:else}
97
+ {#each syns as syn, index }
98
+ <Note>
99
+ <TextEditor
100
+ startText={syn}
101
+ label={'Synonym editor.'}
102
+ placeholder="Synonym"
103
+ valid={ () => undefined }
104
+ save={text => {
105
+ const newSyns = [ ...syns ];
106
+ // Remove the synonym if it's empty but wasn't before
107
+ if(syn.length > 0 && text.length === 0)
108
+ newSyns.splice(index, 1);
109
+ else
110
+ newSyns[index] = text;
111
+ return $edition.editDefinition(id, {
112
+ phrase: definition.phrase,
113
+ definition: definition.definition,
114
+ synonyms: newSyns
115
+ });
116
+ }}
117
+ />
118
+ </Note>
119
+ {#if syns.length > 1 && index < syns.length - 1 },&nbsp;{/if}
120
+ {/each}
121
+ {/if}
122
+ </span>
123
+ {:else}
124
+ {#if definition.synonyms !== undefined && definition.synonyms.length > 0 }
125
+ <Note>{definition.synonyms.join(", ")}</Note>
126
+ {/if}
127
+ {/if}
128
+ </td>
129
+ </tr>
@@ -0,0 +1,18 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type Definition from '../../models/book/Definition';
3
+ declare const __propDef: {
4
+ props: {
5
+ id: string;
6
+ definition: Definition;
7
+ };
8
+ events: {
9
+ [evt: string]: CustomEvent<any>;
10
+ };
11
+ slots: {};
12
+ };
13
+ export declare type DefinitionViewProps = typeof __propDef.props;
14
+ export declare type DefinitionViewEvents = typeof __propDef.events;
15
+ export declare type DefinitionViewSlots = typeof __propDef.slots;
16
+ export default class DefinitionView extends SvelteComponentTyped<DefinitionViewProps, DefinitionViewEvents, DefinitionViewSlots> {
17
+ }
18
+ export {};
@@ -0,0 +1,22 @@
1
+ <script>import Parser from "../../models/chapter/Parser";
2
+ import ChapterBody from "../chapter/ChapterBody.svelte";
3
+ import BookishEditor from "../editor/BookishEditor.svelte";
4
+ import { getEdition, isEditable } from "./Contexts";
5
+ let editable = isEditable();
6
+ let edition = getEdition();
7
+ $: descriptionNode = Parser.parseChapter($edition, $edition.getDescription());
8
+ </script>
9
+
10
+ <div class="bookish-description">
11
+ {#if editable}
12
+ <BookishEditor
13
+ ast={descriptionNode}
14
+ save={node => $edition.setDescription(node.toBookdown())}
15
+ chapter={false}
16
+ component={ChapterBody}
17
+ placeholder="What this book about?"
18
+ />
19
+ {:else}
20
+ <ChapterBody node={descriptionNode}/>
21
+ {/if}
22
+ </div>
@@ -0,0 +1,14 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {};
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ };
9
+ export declare type DescriptionProps = typeof __propDef.props;
10
+ export declare type DescriptionEvents = typeof __propDef.events;
11
+ export declare type DescriptionSlots = typeof __propDef.slots;
12
+ export default class Description extends SvelteComponentTyped<DescriptionProps, DescriptionEvents, DescriptionSlots> {
13
+ }
14
+ export {};
@@ -0,0 +1,106 @@
1
+ <script>import smoothscroll from 'smoothscroll-polyfill';
2
+ import { goto } from '$app/navigation';
3
+ import Status from "./Status.svelte";
4
+ import { onMount, setContext } from 'svelte';
5
+ import { writable } from "svelte/store";
6
+ import { BASE, BOOK, DARK_MODE, EDITABLE, EDITION } from "./Contexts";
7
+ // Poly fill smooth scrolling for Safari.
8
+ smoothscroll.polyfill();
9
+ // True if the edition should be editable. Distributed as context.
10
+ export let editable = false;
11
+ // When editable changes, update the context.
12
+ $: setContext(EDITABLE, editable);
13
+ // The base path allows links to adjust to different routing contexts in which a book is placed.
14
+ // For example, when the book is hosted alone, all routes might start with the bare root "/",
15
+ // but when the book is being viewed or edited in the Bookish app, it needs a prefix for the
16
+ // route in the app.
17
+ export let base = "";
18
+ // When the base changes, update the context.
19
+ $: setContext(BASE, base);
20
+ // The book edition to render.
21
+ export let edition;
22
+ // Expose the edition to descendents in a store and update the context when the edition changes.
23
+ let currentEdition = writable(edition);
24
+ setContext(EDITION, currentEdition);
25
+ // Expose the book to descendents in a store and update the context when the edition changes.
26
+ $: setContext(BOOK, edition.getBook());
27
+ // When edition changes, unsubscribe to the previous edition and subscribe to the new one.
28
+ // We use a simple assignment to tell Svelte about the change.
29
+ let editionChanged = () => currentEdition.set(edition);
30
+ $: {
31
+ // Remove the listeners from the old edition
32
+ $currentEdition.removeListener(editionChanged);
33
+ $currentEdition.getBook()?.removeListener(editionChanged);
34
+ // Update the current edition.
35
+ currentEdition.set(edition);
36
+ // Listen to the new edition
37
+ $currentEdition.getBook()?.addListener(editionChanged);
38
+ $currentEdition.addListener(editionChanged);
39
+ }
40
+ // Create a timer that saves the current edition periodically and stops when unmounted.
41
+ onMount(() => {
42
+ const saveListener = setInterval(() => {
43
+ $currentEdition.saveEdits();
44
+ $currentEdition.getBook()?.saveEdits();
45
+ }, 500);
46
+ // On unmount, stop listening.
47
+ return () => clearInterval(saveListener);
48
+ });
49
+ // Default dark mode to whatever's stored in local storage, if anything.
50
+ // respect user choice on the website despite the system theme
51
+ let darkMode = writable(localStorage.getItem("bookish-dark") !== "false" && (localStorage.getItem("bookish-dark") === "true" || // A previous setting
52
+ window.matchMedia("(prefers-color-scheme: dark)").matches // Operating system is set to dark
53
+ ));
54
+ // Expose dark mode to descendants
55
+ setContext(DARK_MODE, darkMode);
56
+ // When dark mode changes, update the body's class list.
57
+ $: {
58
+ if ($darkMode) {
59
+ document.body.classList.add("bookish-dark");
60
+ localStorage.setItem("bookish-dark", "true");
61
+ }
62
+ else {
63
+ document.body.classList.remove("bookish-dark");
64
+ localStorage.setItem("bookish-dark", "false");
65
+ }
66
+ }
67
+ // Redirect old hash routes by simply replacing their hash before routing.
68
+ if (typeof window !== "undefined" && window.location.hash.startsWith('#/'))
69
+ goto(location.hash.replace('#', ''));
70
+ // Set the theme, whatever it is, and change it when the edition changes.
71
+ $: setTheme(edition.getTheme());
72
+ function setTheme(theme) {
73
+ // Remove any existing theme.
74
+ document.getElementById("bookish-theme")?.remove();
75
+ // If the theme is being unset, make sure we've removed any overrding style declaration.
76
+ // This let's the default theme kick in.
77
+ if (theme === null)
78
+ return;
79
+ // If it's being set, create a new style tag.
80
+ const themeTag = document.createElement("style");
81
+ themeTag.setAttribute("id", "bookish-theme");
82
+ const css = `:root {
83
+ ${toRules(theme.light)}
84
+ ${toRules(theme.fonts)}
85
+ ${toRules(theme.sizes)}
86
+ ${toRules(theme.weights)}
87
+ ${toRules(theme.spacing)}
88
+ }
89
+ .bookish-dark {
90
+ ${toRules(theme.dark)}
91
+ }`;
92
+ themeTag.appendChild(document.createTextNode(css));
93
+ document.head.appendChild(themeTag);
94
+ }
95
+ function toRules(set) {
96
+ return Object.keys(set).map(name => {
97
+ const cssVariable = "--bookish-" + name.replace(/([a-z])([A-Z])/g, "$1 $2").split(" ").map(s => s.toLowerCase()).join("-");
98
+ return `${cssVariable}: ${set[name]};`;
99
+ }).join("\n\t\t");
100
+ }
101
+ </script>
102
+
103
+ <div class={"bookish" + ($darkMode ? " bookish-dark" : "")}>
104
+ <slot></slot>
105
+ <Status book={edition.getBook()} edition={edition}/>
106
+ </div>
@@ -0,0 +1,21 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type EditionModel from "../../models/book/Edition";
3
+ declare const __propDef: {
4
+ props: {
5
+ editable?: boolean | undefined;
6
+ base?: string | undefined;
7
+ edition: EditionModel;
8
+ };
9
+ events: {
10
+ [evt: string]: CustomEvent<any>;
11
+ };
12
+ slots: {
13
+ default: {};
14
+ };
15
+ };
16
+ export declare type EditionProps = typeof __propDef.props;
17
+ export declare type EditionEvents = typeof __propDef.events;
18
+ export declare type EditionSlots = typeof __propDef.slots;
19
+ export default class Edition extends SvelteComponentTyped<EditionProps, EditionEvents, EditionSlots> {
20
+ }
21
+ export {};
@@ -0,0 +1,61 @@
1
+ <script>import Header from "./Header.svelte";
2
+ import Outline from './Outline.svelte';
3
+ import Page from './Page.svelte';
4
+ import ChapterIDs from '../../models/book/ChapterID';
5
+ import DefinitionView from "./DefinitionView.svelte";
6
+ import { getEdition, isEditable } from "./Contexts";
7
+ import Instructions from "./Instructions.svelte";
8
+ let edition = getEdition();
9
+ let editable = isEditable();
10
+ $: glossary = $edition.getGlossary();
11
+ // Sort by canonical phrases
12
+ $: keys = glossary === undefined || Object.keys(glossary).length === 0 ? null : Object.keys(glossary).sort((a, b) => glossary[a].phrase.localeCompare(glossary[b].phrase));
13
+ function addEmptyDefinition() {
14
+ // Generate an ID.
15
+ const letters = "abcdefghijklmnopqrstuvwxyz".split("");
16
+ let id = "";
17
+ while (id.length < 4 || $edition.hasDefinition(id))
18
+ id = id + letters[Math.round(Math.random() * 26)];
19
+ $edition.addDefinition(id, "", "", []);
20
+ }
21
+ </script>
22
+
23
+ <Page title={`${$edition.getTitle()} - Glossary`}>
24
+ <Header
25
+ label="Glossary title"
26
+ getImage={() => $edition.getImage(ChapterIDs.GlossaryID)}
27
+ setImage={(embed) => $edition.setImage(ChapterIDs.GlossaryID, embed)}
28
+ header="Glossary"
29
+ tags={$edition.getTags()}
30
+ >
31
+ <Outline
32
+ slot="outline"
33
+ previous={$edition.getPreviousChapterID(ChapterIDs.GlossaryID)}
34
+ next={$edition.getNextChapterID(ChapterIDs.GlossaryID)}
35
+ />
36
+ </Header>
37
+ {#if editable }
38
+ <Instructions>
39
+ Add definitions and then link to them in a chapter's text.
40
+ </Instructions>
41
+ <p><button on:click={addEmptyDefinition}>+</button></p>
42
+ {/if}
43
+ {#if keys === null }
44
+ <p>This book has no glossary.</p>
45
+ {:else}
46
+ <div>
47
+ <br/>
48
+ <div class="bookish-table">
49
+ <table>
50
+ <colgroup>
51
+ <col style="width: 40%" />
52
+ <col style="width: 60%" />
53
+ </colgroup>
54
+ <tbody>
55
+ {#each keys as id }<DefinitionView id={id} definition={glossary[id]} />{/each}
56
+ </tbody>
57
+ </table>
58
+ </div>
59
+ </div>
60
+ {/if}
61
+ </Page>
@@ -0,0 +1,14 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {};
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ };
9
+ export declare type GlossaryProps = typeof __propDef.props;
10
+ export declare type GlossaryEvents = typeof __propDef.events;
11
+ export declare type GlossarySlots = typeof __propDef.slots;
12
+ export default class Glossary extends SvelteComponentTyped<GlossaryProps, GlossaryEvents, GlossarySlots> {
13
+ }
14
+ export {};
@@ -0,0 +1,105 @@
1
+ <script>import EmbedNode from '../../models/chapter/EmbedNode';
2
+ import Parser from "../../models/chapter/Parser";
3
+ import Embed from '../chapter/Embed.svelte';
4
+ import ErrorMessage from '../chapter/ErrorMessage.svelte';
5
+ import BookishEditor from '../editor/BookishEditor.svelte';
6
+ import { onMount } from 'svelte';
7
+ import TextEditor from '../editor/TextEditor.svelte';
8
+ import { getEdition, isEditable } from './Contexts';
9
+ export let label;
10
+ export let header;
11
+ export let subtitle = undefined;
12
+ export let print = false;
13
+ export let tags = undefined;
14
+ export let getImage;
15
+ export let setImage;
16
+ export let save = null;
17
+ let title = null;
18
+ let reminder = null;
19
+ let edition = getEdition();
20
+ let editable = isEditable();
21
+ function updateScrollReminder() {
22
+ if (title && reminder) {
23
+ // If the bottom of the window is below the top of the title, hide the reminder.
24
+ if (window.scrollY + window.innerHeight > title.getBoundingClientRect().top + window.scrollY)
25
+ reminder.classList.add("bookish-past-title");
26
+ else
27
+ reminder.classList.remove("bookish-past-title");
28
+ }
29
+ }
30
+ function addCover() { if (setImage)
31
+ setImage("|||||"); }
32
+ function removeCover() { if (setImage)
33
+ setImage(null); }
34
+ // When the title becomes visible or hidden, update the scroll reminder.
35
+ onMount(() => {
36
+ const intersectionObserver = new IntersectionObserver(() => updateScrollReminder());
37
+ if (title)
38
+ intersectionObserver.observe(title);
39
+ updateScrollReminder();
40
+ // Stop observing when unmounted.
41
+ return () => { if (title)
42
+ intersectionObserver.unobserve(title); };
43
+ });
44
+ // Get the embed, update when getImage function prop changes.
45
+ let embedNode = undefined;
46
+ $: {
47
+ let embed = getImage();
48
+ embedNode = embed ? Parser.parseEmbed($edition, embed) : undefined;
49
+ }
50
+ </script>
51
+
52
+ <div class="bookish-chapter-header">
53
+ {#if embedNode }
54
+ <div class="bookish-figure-full">
55
+ {#if edition && editable && embedNode instanceof EmbedNode}
56
+ <BookishEditor
57
+ ast={embedNode}
58
+ save={node => setImage ? setImage(node.toBookdown()) : undefined }
59
+ chapter={false}
60
+ component={Embed}
61
+ placeholder=""
62
+ />
63
+ {:else if embedNode instanceof EmbedNode }
64
+ <Embed node={embedNode}/>
65
+ {:else}
66
+ <ErrorMessage node={embedNode} />
67
+ {/if}
68
+ {#if !print }<div bind:this={reminder} class="bookish-scroll-reminder"></div>{/if}
69
+ </div>
70
+ {:else}
71
+ <!-- Add a bit of space to account for the lack of an image. -->
72
+ <p>&nbsp;</p>
73
+ {/if}
74
+ {#if !print}
75
+ <slot name="outline"></slot>
76
+ {/if}
77
+ {#if editable }
78
+ {#if embedNode === undefined }
79
+ <button on:click={addCover}>+ cover image</button>
80
+ {:else}
81
+ <button on:click={removeCover}>x cover image</button>
82
+ {/if}
83
+ {/if}
84
+ <div class="bookish-chapter-header-text">
85
+ <slot name="before"></slot>
86
+ <h1 bind:this={title} class="bookish-title">
87
+ {#if editable && save }
88
+ <TextEditor
89
+ label={label}
90
+ startText={header + (subtitle ? ": " + subtitle : "")}
91
+ placeholder="Title"
92
+ valid={text => text.length === 0 ? "Titles have to be at least one character long." : undefined }
93
+ save={save}
94
+ />
95
+ {:else}
96
+ { header }
97
+ {#if subtitle }<div class="bookish-subtitle">{subtitle}</div>{/if}
98
+ {/if}
99
+ </h1>
100
+ <slot name="after"></slot>
101
+ {#if tags }
102
+ <div>{#each tags as tag}<span class="bookish-tag">{tag}</span>{/each}</div>
103
+ {/if}
104
+ </div>
105
+ </div>
@@ -0,0 +1,27 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ label: string;
5
+ header: string;
6
+ subtitle?: string | undefined;
7
+ print?: boolean | undefined;
8
+ tags?: string[] | undefined;
9
+ getImage: (() => string | null);
10
+ setImage: (embed: string | null) => Promise<void> | undefined;
11
+ save?: ((text: string) => Promise<void> | undefined) | null | undefined;
12
+ };
13
+ events: {
14
+ [evt: string]: CustomEvent<any>;
15
+ };
16
+ slots: {
17
+ outline: {};
18
+ before: {};
19
+ after: {};
20
+ };
21
+ };
22
+ export declare type HeaderProps = typeof __propDef.props;
23
+ export declare type HeaderEvents = typeof __propDef.events;
24
+ export declare type HeaderSlots = typeof __propDef.slots;
25
+ export default class Header extends SvelteComponentTyped<HeaderProps, HeaderEvents, HeaderSlots> {
26
+ }
27
+ export {};
@@ -0,0 +1,117 @@
1
+ <script>import Header from "./Header.svelte";
2
+ import Outline from './Outline.svelte';
3
+ import Page from './Page.svelte';
4
+ import Instructions from './Instructions.svelte';
5
+ import ChapterIDs from '../../models/book/ChapterID';
6
+ import Link from "../Link.svelte";
7
+ import { getBase, getEdition } from "./Contexts";
8
+ import { page } from "$app/stores";
9
+ let edition = getEdition();
10
+ let base = getBase();
11
+ // What letter are we matching?
12
+ $: letter = $page.params.letter;
13
+ $: bookIndex = $edition.getBookIndex();
14
+ let letters = {};
15
+ // Figure out what letters have words
16
+ $: {
17
+ for (const word of Object.keys(bookIndex).sort((a, b) => a.localeCompare(b)))
18
+ letters[word.charAt(0).toLocaleLowerCase()] = true;
19
+ }
20
+ let words = [];
21
+ $: {
22
+ words = [];
23
+ let count = 0;
24
+ Object.keys(bookIndex).sort((a, b) => a.localeCompare(b)).forEach(word => {
25
+ const firstLetter = word.charAt(0).toLowerCase();
26
+ if (letter === firstLetter) {
27
+ count++;
28
+ if (count % 20 === 0)
29
+ words.push(true);
30
+ words.push(word);
31
+ }
32
+ });
33
+ }
34
+ </script>
35
+
36
+ <Page title={`${$edition.getTitle()} - Index`}>
37
+ <Header
38
+ label="Index title"
39
+ getImage={() => $edition.getImage(ChapterIDs.IndexID)}
40
+ setImage={(embed) => $edition.setImage(ChapterIDs.IndexID, embed)}
41
+ header="Index"
42
+ tags={$edition.getTags()}
43
+ >
44
+ <Outline
45
+ slot="outline"
46
+ previous={$edition.getPreviousChapterID(ChapterIDs.IndexID)}
47
+ next={$edition.getNextChapterID(ChapterIDs.IndexID)}
48
+ />
49
+ </Header>
50
+
51
+ <Instructions>
52
+ This index is created automatically.
53
+ It's not perfect; we may add more control over it in the future.
54
+ </Instructions>
55
+
56
+ <p><em>This index includes all words, excluding common English words, words with apostrophes, and words ending in -ly.</em></p>
57
+
58
+ {#if Object.keys(letters).length === 0 }
59
+ <p>There are no words in this book, so there's no index.</p>
60
+ {:else}
61
+ <p>Pick a letter to browse:</p>
62
+
63
+ <p>
64
+ {#each "abcdefghijklmnopqrstuvwxyz".split("") as symbol, index}
65
+ <span style="display: inline-block">
66
+ {#if symbol in letters && letter !== symbol }
67
+ <Link to={base + "/index/" + symbol}>{symbol}</Link>
68
+ {:else}
69
+ <span>
70
+ {#if letter === symbol }
71
+ <strong><span style="font-size: 200%">{symbol}</span></strong>
72
+ {:else}
73
+ <span class={"bookish-muted"}>{symbol}</span>
74
+ {/if}
75
+ </span>
76
+ {/if}
77
+ {#if index < 26 - 1 }
78
+ <span>&sdot;</span>
79
+ {/if}
80
+ </span>
81
+ {/each}
82
+ </p>
83
+
84
+ <div class="bookish-table">
85
+ <table>
86
+ <tbody>
87
+ {#each words as word, index }
88
+ {#if word === true}
89
+ <tr><td colspan={2}><h2 class="bookish-header">{words[index + 1]}</h2></td></tr>
90
+ {:else}
91
+ <tr>
92
+ <td>{word}</td>
93
+ <td>
94
+ <!-- Sort the chapters by chapter number -->
95
+ {#each Array.from(bookIndex[word])
96
+ .sort((a, b) => {
97
+ let numberA = $edition.getChapterNumber(a);
98
+ let numberB = $edition.getChapterNumber(b);
99
+ if(numberA === undefined) return -1;
100
+ if(numberB === undefined) return 1;
101
+ return numberA - numberB;
102
+ }) as chapterID, index }
103
+ <!-- Map them to links to the first occurrence in the chapter. -->
104
+ <span>
105
+ Chapter {#if $edition.getChapterNumber(chapterID) !== undefined}<span> {$edition.getChapterNumber(chapterID)}. </span>{/if}<Link to={`${base}/${chapterID}?word=${word}`}>{$edition.getChapterName(chapterID)}</Link>
106
+ {#if index < bookIndex[word].size - 1 }<br/>{/if}
107
+ </span>
108
+ {/each}
109
+ </td>
110
+ </tr>
111
+ {/if}
112
+ {/each}
113
+ </tbody>
114
+ </table>
115
+ </div>
116
+ {/if}
117
+ </Page>
@@ -0,0 +1,14 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {};
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ };
9
+ export declare type IndexProps = typeof __propDef.props;
10
+ export declare type IndexEvents = typeof __propDef.events;
11
+ export declare type IndexSlots = typeof __propDef.slots;
12
+ export default class Index extends SvelteComponentTyped<IndexProps, IndexEvents, IndexSlots> {
13
+ }
14
+ export {};