bible-note 0.5.0 → 0.6.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.
- package/README.md +349 -293
- package/dist/bible-note.cjs +110 -110
- package/dist/bible-note.mjs +6503 -6383
- package/knowledge/development.md +221 -6
- package/knowledge/ui-rag.md +135 -133
- package/package.json +1 -1
- package/types/AppComp.d.ts +4 -2
- package/types/BibleNote.d.ts +31 -5
- package/types/actionButtonList.d.ts +23 -0
- package/types/bibleNoteHelpers.d.ts +3 -1
- package/types/floatingActionButtons.d.ts +118 -0
- package/types/lib.d.ts +1 -0
package/README.md
CHANGED
|
@@ -1,293 +1,349 @@
|
|
|
1
|
-
# Bible Note
|
|
2
|
-
|
|
3
|
-
A Bible study tool for taking notes and organizing your thoughts.
|
|
4
|
-
|
|
5
|
-
It extends the [Lexical playground](https://playground.lexical.dev/): the
|
|
6
|
-
playground editor packaged as a drop-in component and built out with
|
|
7
|
-
Bible-specific features — name and location lookup, sticky notes, footer action
|
|
8
|
-
buttons and pluggable storage. The MIT license and Meta's copyright carry over
|
|
9
|
-
from upstream Lexical.
|
|
10
|
-
|
|
11
|
-
MIT license
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install bible-note react react-dom bootstrap bootstrap-icons
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
The peer dependencies are React ^19.2.8, React DOM, and Bootstrap ^5.3.8 with
|
|
18
|
-
its icon font. React has to be the host's copy so there is only one of it;
|
|
19
|
-
Bootstrap and bootstrap-icons are global stylesheets the host imports itself, so
|
|
20
|
-
it keeps control of cascade order and can theme or pin its own version.
|
|
21
|
-
Everything else the editor needs — Lexical, Excalidraw, KaTeX, Shiki — is
|
|
22
|
-
bundled.
|
|
23
|
-
|
|
24
|
-
### Releasing to npm
|
|
25
|
-
|
|
26
|
-
For maintainers, from a clean `main`:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm test
|
|
30
|
-
npm pack --dry-run # check which files go in the package
|
|
31
|
-
npm whoami # run `npm login` if this fails
|
|
32
|
-
npm version patch --tag-version-prefix="" # or minor / major
|
|
33
|
-
npm publish
|
|
34
|
-
git push origin main --follow-tags
|
|
35
|
-
npm view bible-note version # confirm the new version is live
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Import
|
|
39
|
-
|
|
40
|
-
```js
|
|
41
|
-
const { BibleNote } = require("bible-note");
|
|
42
|
-
// or module
|
|
43
|
-
import { BibleNote } from "bible-note";
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
import { BibleNote } from "bible-note";
|
|
48
|
-
import type {
|
|
49
|
-
BibleNoteFooterActionButton,
|
|
50
|
-
FilePathResolver,
|
|
51
|
-
FileRevealer,
|
|
52
|
-
ExtraFontFamilyOption,
|
|
53
|
-
MentionNameMatch,
|
|
54
|
-
MentionLocationMatch,
|
|
55
|
-
} from "bible-note";
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Stylesheets
|
|
59
|
-
|
|
60
|
-
Three, in this order — Bootstrap first, then the icon font, then the editor's
|
|
61
|
-
own stylesheet last so its overrides win:
|
|
62
|
-
|
|
63
|
-
```js
|
|
64
|
-
import "bootstrap/dist/css/bootstrap.min.css";
|
|
65
|
-
import "bootstrap-icons/font/bootstrap-icons.css";
|
|
66
|
-
import "bible-note/styles.css";
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Skipping the first two does not throw — it renders a broken editor: the toolbar
|
|
70
|
-
and footer lose their layout, and with no `@font-face` for the icon font every
|
|
71
|
-
`bi bi-*` glyph falls back to tofu. `bible-note/styles.css` carries the
|
|
72
|
-
editor, KaTeX and Excalidraw rules, and needs no configuration.
|
|
73
|
-
|
|
74
|
-
## Usage
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
import {
|
|
78
|
-
BibleNote,
|
|
79
|
-
createBrowserStorageManager,
|
|
80
|
-
LocationsLookupManager,
|
|
81
|
-
NamesLookupManager,
|
|
82
|
-
} from "bible-note";
|
|
83
|
-
import "bootstrap/dist/css/bootstrap.min.css";
|
|
84
|
-
import "bootstrap-icons/font/bootstrap-icons.css";
|
|
85
|
-
import "bible-note/styles.css";
|
|
86
|
-
|
|
87
|
-
// fromRawDataset takes the generated dataset files exactly as fetched. Use the
|
|
88
|
-
// plain constructors when you already hold MentionNameMatch/MentionLocationMatch
|
|
89
|
-
// records.
|
|
90
|
-
const namesLookupManager = NamesLookupManager.fromRawDataset(
|
|
91
|
-
{ en: namesMap },
|
|
92
|
-
"en",
|
|
93
|
-
);
|
|
94
|
-
const locationsLookupManager = LocationsLookupManager.fromRawDataset(
|
|
95
|
-
{ en: locationsMap },
|
|
96
|
-
"en",
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
const bibleNote = new BibleNote({
|
|
100
|
-
namesLookupManager,
|
|
101
|
-
locationsLookupManager,
|
|
102
|
-
getLangCode: (text) => (/[\u1780-\u17FF]/u.test(text) ? "km" : "en"),
|
|
103
|
-
editorExtraFontFamilies: [],
|
|
104
|
-
stickyNoteExtraFontFamilies: [],
|
|
105
|
-
storageManager: createBrowserStorageManager(),
|
|
106
|
-
loadData: () => localStorage.getItem("bible-note") ?? "",
|
|
107
|
-
saveData: (data) => localStorage.setItem("bible-note", data),
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
bibleNote.render(document.getElementById("root")!);
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
###
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
and
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
1
|
+
# Bible Note
|
|
2
|
+
|
|
3
|
+
A Bible study tool for taking notes and organizing your thoughts.
|
|
4
|
+
|
|
5
|
+
It extends the [Lexical playground](https://playground.lexical.dev/): the
|
|
6
|
+
playground editor packaged as a drop-in component and built out with
|
|
7
|
+
Bible-specific features — name and location lookup, sticky notes, footer action
|
|
8
|
+
buttons and pluggable storage. The MIT license and Meta's copyright carry over
|
|
9
|
+
from upstream Lexical.
|
|
10
|
+
|
|
11
|
+
MIT license
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install bible-note react react-dom bootstrap bootstrap-icons
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The peer dependencies are React ^19.2.8, React DOM, and Bootstrap ^5.3.8 with
|
|
18
|
+
its icon font. React has to be the host's copy so there is only one of it;
|
|
19
|
+
Bootstrap and bootstrap-icons are global stylesheets the host imports itself, so
|
|
20
|
+
it keeps control of cascade order and can theme or pin its own version.
|
|
21
|
+
Everything else the editor needs — Lexical, Excalidraw, KaTeX, Shiki — is
|
|
22
|
+
bundled.
|
|
23
|
+
|
|
24
|
+
### Releasing to npm
|
|
25
|
+
|
|
26
|
+
For maintainers, from a clean `main`:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm test
|
|
30
|
+
npm pack --dry-run # check which files go in the package
|
|
31
|
+
npm whoami # run `npm login` if this fails
|
|
32
|
+
npm version patch --tag-version-prefix="" # or minor / major
|
|
33
|
+
npm publish
|
|
34
|
+
git push origin main --follow-tags
|
|
35
|
+
npm view bible-note version # confirm the new version is live
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Import
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
const { BibleNote } = require("bible-note");
|
|
42
|
+
// or module
|
|
43
|
+
import { BibleNote } from "bible-note";
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { BibleNote } from "bible-note";
|
|
48
|
+
import type {
|
|
49
|
+
BibleNoteFooterActionButton,
|
|
50
|
+
FilePathResolver,
|
|
51
|
+
FileRevealer,
|
|
52
|
+
ExtraFontFamilyOption,
|
|
53
|
+
MentionNameMatch,
|
|
54
|
+
MentionLocationMatch,
|
|
55
|
+
} from "bible-note";
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Stylesheets
|
|
59
|
+
|
|
60
|
+
Three, in this order — Bootstrap first, then the icon font, then the editor's
|
|
61
|
+
own stylesheet last so its overrides win:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import "bootstrap/dist/css/bootstrap.min.css";
|
|
65
|
+
import "bootstrap-icons/font/bootstrap-icons.css";
|
|
66
|
+
import "bible-note/styles.css";
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Skipping the first two does not throw — it renders a broken editor: the toolbar
|
|
70
|
+
and footer lose their layout, and with no `@font-face` for the icon font every
|
|
71
|
+
`bi bi-*` glyph falls back to tofu. `bible-note/styles.css` carries the
|
|
72
|
+
editor, KaTeX and Excalidraw rules, and needs no configuration.
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import {
|
|
78
|
+
BibleNote,
|
|
79
|
+
createBrowserStorageManager,
|
|
80
|
+
LocationsLookupManager,
|
|
81
|
+
NamesLookupManager,
|
|
82
|
+
} from "bible-note";
|
|
83
|
+
import "bootstrap/dist/css/bootstrap.min.css";
|
|
84
|
+
import "bootstrap-icons/font/bootstrap-icons.css";
|
|
85
|
+
import "bible-note/styles.css";
|
|
86
|
+
|
|
87
|
+
// fromRawDataset takes the generated dataset files exactly as fetched. Use the
|
|
88
|
+
// plain constructors when you already hold MentionNameMatch/MentionLocationMatch
|
|
89
|
+
// records.
|
|
90
|
+
const namesLookupManager = NamesLookupManager.fromRawDataset(
|
|
91
|
+
{ en: namesMap },
|
|
92
|
+
"en",
|
|
93
|
+
);
|
|
94
|
+
const locationsLookupManager = LocationsLookupManager.fromRawDataset(
|
|
95
|
+
{ en: locationsMap },
|
|
96
|
+
"en",
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const bibleNote = new BibleNote({
|
|
100
|
+
namesLookupManager,
|
|
101
|
+
locationsLookupManager,
|
|
102
|
+
getLangCode: (text) => (/[\u1780-\u17FF]/u.test(text) ? "km" : "en"),
|
|
103
|
+
editorExtraFontFamilies: [],
|
|
104
|
+
stickyNoteExtraFontFamilies: [],
|
|
105
|
+
storageManager: createBrowserStorageManager(),
|
|
106
|
+
loadData: () => localStorage.getItem("bible-note") ?? "",
|
|
107
|
+
saveData: (data) => localStorage.setItem("bible-note", data),
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
bibleNote.render(document.getElementById("root")!);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Buttons on the selected-text toolbar
|
|
114
|
+
|
|
115
|
+
Selecting text in the note pops up a small toolbar over it — Bold, Italic,
|
|
116
|
+
Underline, …, Insert comment. A host adds its own buttons to it with
|
|
117
|
+
`appendFloatingActionButton` (after the built-in buttons) or
|
|
118
|
+
`prependFloatingActionButton` (before them). The editor renders the `<button>`
|
|
119
|
+
itself, so it matches the built-in ones: `children` is only its content, and
|
|
120
|
+
`description` is its tooltip and accessible name. Give a Bootstrap icon the
|
|
121
|
+
`format` class to size and tint it like the others.
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
bibleNote.appendFloatingActionButton({
|
|
125
|
+
id: "copy-selected-text",
|
|
126
|
+
description: "Copy selected text",
|
|
127
|
+
children: <i className="bi bi-clipboard format" />,
|
|
128
|
+
onClick: async ({ selection }) => {
|
|
129
|
+
await navigator.clipboard.writeText(selection.text);
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
bibleNote.appendFloatingActionButton({
|
|
134
|
+
id: "uppercase-selected-text",
|
|
135
|
+
description: "Make selected text uppercase",
|
|
136
|
+
isHiddenWhenReadOnly: true,
|
|
137
|
+
children: <i className="bi bi-alphabet-uppercase format" />,
|
|
138
|
+
onClick: ({ selection, replaceText }) => {
|
|
139
|
+
replaceText(selection.text.toUpperCase());
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
bibleNote.getFloatingActionButton("copy-selected-text"); // the descriptor, or null
|
|
144
|
+
bibleNote.removeFloatingActionButton("copy-selected-text"); // false when absent
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`onClick` receives a `BibleNoteFloatingActionButtonClickEvent`, captured at the
|
|
148
|
+
click:
|
|
149
|
+
|
|
150
|
+
| Field | What it holds |
|
|
151
|
+
| --- | --- |
|
|
152
|
+
| `id` | The clicked button's `id` |
|
|
153
|
+
| `selection.text` | The selected text as plain text, paragraphs separated by `\n` — what Copy puts on the clipboard as `text/plain` |
|
|
154
|
+
| `selection.html` | The selection as HTML, formatting included — what Copy puts on the clipboard as `text/html` |
|
|
155
|
+
| `selection.start`, `selection.end` | The selection's two ends in document order, each `{ key, offset, type }`: the editor's node key, the character offset in a `'text'` node or the child index in an `'element'` node. Keys identify nodes of the note as it is open now; they are not saved with `content` |
|
|
156
|
+
| `selection.isBackward` | `true` when the user selected from the end back to the start |
|
|
157
|
+
| `selection.domRange` | A copy of the browser's DOM `Range` for the selection, or `null`. Measure the text on screen with `domRange.getBoundingClientRect()`; it stops matching once the note changes |
|
|
158
|
+
| `replaceText(text)` | Replaces the captured range with `text`, inserted the way `addText` inserts it — plain text, paste rules applied, `\n` starts a paragraph; `""` deletes the selected text. It restores the range first, so it works after an `await` or after the user clicked elsewhere. Returns `false`, changing nothing, when the note is read-only or the range no longer holds `selection.text` |
|
|
159
|
+
| `mouseEvent` | The React click event |
|
|
160
|
+
|
|
161
|
+
Buttons show in a read-only note too, as Insert comment does, unless
|
|
162
|
+
`isHiddenWhenReadOnly` is set. Ids are unique per editor: re-adding an `id`
|
|
163
|
+
replaces that button in place. Like footer buttons, they can be added before
|
|
164
|
+
`render` and are kept across `unmount`. Unlike footer buttons, they take no
|
|
165
|
+
`shortcutKey`.
|
|
166
|
+
|
|
167
|
+
### Microsoft Word round trips
|
|
168
|
+
|
|
169
|
+
The editor footer has separate Word import and export buttons. Export creates a
|
|
170
|
+
standard `.docx` that opens in Microsoft Word and includes a private BibleNote
|
|
171
|
+
round-trip copy of the editor state. Importing that file back restores the full
|
|
172
|
+
editable document, including editor-specific content that Word cannot represent
|
|
173
|
+
natively. If Word has removed that private data, or the file came from another
|
|
174
|
+
application, BibleNote falls back to Word-content conversion and preserves the
|
|
175
|
+
document's text, headings, emphasis, lists, tables, links, and embedded images;
|
|
176
|
+
Word-only layout details may be simplified.
|
|
177
|
+
|
|
178
|
+
Because a Word document has no hover cards, the export spells out what they
|
|
179
|
+
show. Every person, place and Bible-verse mention links to an entry in a
|
|
180
|
+
**References** appendix after the note: the name or location record from
|
|
181
|
+
`namesMap` / `locationsMap` (description, family, locations, links,
|
|
182
|
+
coordinates) and the verse text, with verse references resolved through
|
|
183
|
+
`shortToVerseData` and related people and places through
|
|
184
|
+
`verseFullTextToListShorts`. Each mention also carries a short screen tip.
|
|
185
|
+
Equations become editable Word equations. Sticky notes, drawings and embed
|
|
186
|
+
thumbnails are packaged as pictures. Checklists, collapsibles, column layouts,
|
|
187
|
+
highlights and code blocks are rewritten into forms Word renders. Re-importing
|
|
188
|
+
the file leaves the appendix out.
|
|
189
|
+
|
|
190
|
+
The existing Import and Export buttons remain the lossless JSON backup path.
|
|
191
|
+
In the Electron app, both Word and lossless editor files use native Open and
|
|
192
|
+
Save dialogs; browser builds continue to use the browser picker and download.
|
|
193
|
+
|
|
194
|
+
`namesMap` and `locationsMap` are the host's own datasets — the package bundles
|
|
195
|
+
none of its own.
|
|
196
|
+
|
|
197
|
+
The two managers own every search, ranking and index the built-in mention and
|
|
198
|
+
lookup UI uses, and they carry no editor dependency. To build your own mention
|
|
199
|
+
or lookup UI, construct them and call their methods directly — no `BibleNote`
|
|
200
|
+
import required:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { NamesLookupManager } from "bible-note";
|
|
204
|
+
|
|
205
|
+
const names = NamesLookupManager.fromRawDataset({ en: namesMap }, "en");
|
|
206
|
+
|
|
207
|
+
names.searchNames("Mos", { limit: 20 }); // ranked MentionNameMatch[]
|
|
208
|
+
names.searchNamesPagination({ query: "Mos", page: 2, pageSize: 20 });
|
|
209
|
+
names.getRecordById("name-moses");
|
|
210
|
+
names.searchByShortVerse("EXO 6:23"); // the names that verse mentions
|
|
211
|
+
names.nameTypes; // types present in the data, most common first
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Translated datasets
|
|
215
|
+
|
|
216
|
+
A record in a translated dataset carries the KJV English name in `kjvName`
|
|
217
|
+
alongside its own translated `name`. The managers index both, so the same
|
|
218
|
+
manager answers a query in either language, ranking an English hit exactly the
|
|
219
|
+
way it ranks a native-language one:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
const names = NamesLookupManager.fromRawDataset({ km: khmerNamesMap }, "km");
|
|
223
|
+
|
|
224
|
+
names.searchNames("Genesis"); // finds the record named "លោកុប្បត្តិ"
|
|
225
|
+
names.searchNames("លោកុប្បត្តិ"); // and so does its own name
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The built-in UI shows the English name beside the translated one — in the
|
|
229
|
+
lookup panel, the mention typeahead, the hover card and the advanced panel.
|
|
230
|
+
`getMentionKjvName(record)` is the rule it follows: the English name, or `null`
|
|
231
|
+
when there is nothing to add (an untranslated dataset, or a record whose
|
|
232
|
+
translated name is the English one anyway).
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { getMentionKjvName } from "bible-note";
|
|
236
|
+
|
|
237
|
+
getMentionKjvName(record); // "Genesis" | null
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
An untranslated dataset such as the KJV one carries no `kjvName` at all, and
|
|
241
|
+
everything above is a no-op for it.
|
|
242
|
+
|
|
243
|
+
### Styling a dataset
|
|
244
|
+
|
|
245
|
+
Both managers take an optional third argument: a plain CSS style object, merged
|
|
246
|
+
into every surface the built-in UI renders that dataset on — the mention
|
|
247
|
+
typeahead popup, the hover card, the advanced panel, and the lookup panel's list
|
|
248
|
+
and search box. A dataset in a script the editor's own font does not cover can
|
|
249
|
+
therefore carry its own `fontFamily`:
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
const locations = LocationsLookupManager.fromRawDataset(
|
|
253
|
+
{ km: khmerLocationsMap },
|
|
254
|
+
"km",
|
|
255
|
+
{ fontFamily: "Battambang, serif" },
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
locations.style; // read it back; assignable, too
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
The two managers are styled independently, so a Khmer location dataset can sit
|
|
262
|
+
beside an English name one. Anything a React `style` prop accepts works, but a
|
|
263
|
+
hover card's own positioning always wins over the style. Plugins read `style` as
|
|
264
|
+
they render, so replacing it after the editor is mounted only shows up on the
|
|
265
|
+
next render.
|
|
266
|
+
|
|
267
|
+
`BibleNote.getAllShortVersesFromText` bridges the two: it reads every verse a
|
|
268
|
+
note refers to — Bible verse mentions and references written in the prose alike
|
|
269
|
+
— and returns them as the short keys the managers index by. It is static, so it
|
|
270
|
+
also works on plain text such as a pasted passage:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
BibleNote.getAllShortVersesFromText(bibleNote.content);
|
|
274
|
+
// ["GEN 1:1", "GEN 1:2", "GEN 1:3", "JHN 3:16"]
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
References are returned in document order without duplicates. A range inside
|
|
278
|
+
one chapter is expanded verse by verse; a range crossing a chapter boundary
|
|
279
|
+
(`Genesis 1:31-2:3`) keeps only its two endpoints, since the package bundles no
|
|
280
|
+
per-chapter verse counts.
|
|
281
|
+
|
|
282
|
+
## Exports
|
|
283
|
+
|
|
284
|
+
| Export | Kind | Purpose |
|
|
285
|
+
| --- | --- | --- |
|
|
286
|
+
| `BibleNote` | class | The editor: `render`, `unmount`, `addText`, `searchText`, `content`, `isReadOnly`, footer action buttons, selected-text toolbar buttons, colour scheme, and the static `getAllShortVersesFromText` |
|
|
287
|
+
| `BibleNoteSettings` | component | Settings panel, passed through `render(el, { settings })` |
|
|
288
|
+
| `createBrowserStorageManager` | function | `localStorage`-backed `BibleNoteStorageManager` |
|
|
289
|
+
| `applyBibleNoteColorScheme` / `clearBibleNoteColorScheme` | function | Toggle the `light`/`dark` body classes |
|
|
290
|
+
| `EDITOR_STATE_LOCAL_STORAGE_KEY` | constant | Storage key the editor state is saved under |
|
|
291
|
+
| `BibleNoteProps`, `BibleNoteRenderOptions` | type | Constructor and `render` options |
|
|
292
|
+
| `BibleNoteFooterActionButton`, `BibleNoteFooterActionButtons` | type | Footer action button descriptors |
|
|
293
|
+
| `BibleNoteFloatingActionButton`, `BibleNoteFloatingActionButtons` | type | Selected-text toolbar button descriptors |
|
|
294
|
+
| `BibleNoteFloatingActionButtonClickEvent`, `BibleNoteTextSelection`, `BibleNoteSelectionPoint` | type | What a selected-text toolbar button's `onClick` receives: the selection's text, HTML and range, and `replaceText` |
|
|
295
|
+
| `NamesLookupManager`, `LocationsLookupManager` | class | Own the name/location datasets: ranked search, id/name lookup, pagination, verse lookup |
|
|
296
|
+
| `parseMentionNameMatch(es)`, `parseMentionLocationMatch(es)`, `getLookupRecordValues`, `normalizeMentionNameType` | function | Dataset normalization helpers the managers use |
|
|
297
|
+
| `getMentionKjvName` | function | The KJV English name to show beside a translated record's name, or `null` |
|
|
298
|
+
| `MentionNameMatch`, `MentionLocationMatch`, `MentionNamePreview`, `MentionLocationPreview` | type | Name/location record shapes |
|
|
299
|
+
| `NamesLookupManagerDataMap`, `LocationsLookupManagerDataMap`, `LookupPaginationResult` | type | Manager constructor input and search results |
|
|
300
|
+
| `LookupManagerStyle` | type | The extra CSS style a manager renders its dataset with |
|
|
301
|
+
| `FilePathResolver`, `FileRevealer`, `FilePathResolverContext` | type | Media file path hooks |
|
|
302
|
+
| `ExtraFontFamilyOption`, `FontFamilyOption` | type | Extra font families for the editor and sticky notes |
|
|
303
|
+
| `BibleNoteStorageManager` | type | Storage adapter contract |
|
|
304
|
+
| `BibleNoteColorScheme` | type | `'light' | 'dark'` |
|
|
305
|
+
|
|
306
|
+
## Knowledge files
|
|
307
|
+
|
|
308
|
+
The package ships two markdown files describing itself, generated on every
|
|
309
|
+
build:
|
|
310
|
+
|
|
311
|
+
| File | For |
|
|
312
|
+
| --- | --- |
|
|
313
|
+
| `bible-note/knowledge/development.md` | Developers: architecture, installation, every prop and hook grouped by feature, datasets and lookup managers, persistence, Electron integration, working on the editor, and a full API reference generated from the type declarations |
|
|
314
|
+
| `bible-note/knowledge/ui-rag.md` | A retrieval (RAG) pipeline behind an in-app assistant: end-user help for the editor UI — formatting, the slash menu, mentions, Bible verses, the lookup panel, inserting content, shortcuts, import/export, comments, settings |
|
|
315
|
+
|
|
316
|
+
Both are exposed through `exports`, so they resolve like any other subpath:
|
|
317
|
+
|
|
318
|
+
```js
|
|
319
|
+
import { readFile } from "node:fs/promises";
|
|
320
|
+
import { fileURLToPath } from "node:url";
|
|
321
|
+
|
|
322
|
+
const ragPath = fileURLToPath(import.meta.resolve("bible-note/knowledge/ui-rag.md"));
|
|
323
|
+
// CommonJS: require.resolve("bible-note/knowledge/ui-rag.md")
|
|
324
|
+
const corpus = await readFile(ragPath, "utf8");
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
`ui-rag.md` is pre-chunked. It opens with YAML front matter (`package`,
|
|
328
|
+
`version`, `chunks`), and every `## ` heading starts one self-contained chunk.
|
|
329
|
+
The heading is a breadcrumb (`## Mentions › Mention a person with @`), and the
|
|
330
|
+
line under it is an HTML comment holding the chunk's metadata as JSON:
|
|
331
|
+
|
|
332
|
+
```markdown
|
|
333
|
+
## Mentions › Mention a person with @
|
|
334
|
+
|
|
335
|
+
<!-- chunk {"id":"ui/mentions/mention-a-person-with","section":"Mentions","title":"Mention a person with @","tags":["mentions","names"],"source":"knowledge/ui/04-mentions.md","package":"bible-note@0.5.0"} -->
|
|
336
|
+
|
|
337
|
+
Type @ followed by a few letters of the name…
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Split on `^## ` (a markdown-header splitter does this out of the box), parse
|
|
341
|
+
`<!-- chunk (.*) -->` for metadata, and index the rest. Chunk `id`s are stable
|
|
342
|
+
across releases as long as the section heading is unchanged; every chunk is
|
|
343
|
+
under 4,000 characters. The text is written for the person using the editor and
|
|
344
|
+
names buttons as they appear on screen.
|
|
345
|
+
|
|
346
|
+
`dist/`, `types/` and `knowledge/` here are generated by `npm run pack` from the
|
|
347
|
+
sources under `src/` and `knowledge/` — edit those, not the build output. This
|
|
348
|
+
file, `package.json` and `LICENSE` are maintained by hand and are the only files
|
|
349
|
+
in this folder that git tracks.
|