bookish-press 0.5.5 → 0.5.7
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 +30 -1
- package/dist/components/Auth.svelte.d.ts +2 -2
- package/dist/components/BookPreview.svelte.d.ts +2 -2
- package/dist/components/Link.svelte.d.ts +2 -2
- package/dist/components/app/BookList.svelte.d.ts +2 -2
- package/dist/components/app/Button.svelte.d.ts +2 -2
- package/dist/components/app/Feedback.svelte.d.ts +2 -2
- package/dist/components/app/Head.svelte.d.ts +2 -2
- package/dist/components/app/Large.svelte.d.ts +2 -2
- package/dist/components/app/Lead.svelte.d.ts +2 -2
- package/dist/components/app/Link.svelte.d.ts +2 -2
- package/dist/components/app/Options.svelte +1 -0
- package/dist/components/app/Options.svelte.d.ts +2 -2
- package/dist/components/app/Paragraph.svelte.d.ts +2 -2
- package/dist/components/app/Section.svelte.d.ts +2 -2
- package/dist/components/app/Table.svelte +0 -1
- package/dist/components/app/Table.svelte.d.ts +2 -2
- package/dist/components/app/TextInput.svelte.d.ts +2 -2
- package/dist/components/chapter/Atom.svelte.d.ts +2 -2
- package/dist/components/chapter/Block.svelte.d.ts +2 -2
- package/dist/components/chapter/Callout.svelte.d.ts +2 -2
- package/dist/components/chapter/CaptionedCode.svelte +21 -19
- package/dist/components/chapter/CaptionedCode.svelte.d.ts +2 -2
- package/dist/components/chapter/ChapterBody.svelte +2 -0
- package/dist/components/chapter/ChapterBody.svelte.d.ts +2 -2
- package/dist/components/chapter/Citations.svelte.d.ts +2 -2
- package/dist/components/chapter/Code.svelte.d.ts +2 -2
- package/dist/components/chapter/Comment.svelte.d.ts +2 -2
- package/dist/components/chapter/Definition.svelte +6 -7
- package/dist/components/chapter/Definition.svelte.d.ts +2 -2
- package/dist/components/chapter/Embed.svelte.d.ts +2 -2
- package/dist/components/chapter/ErrorMessage.svelte.d.ts +2 -2
- package/dist/components/chapter/Figure.svelte +5 -3
- package/dist/components/chapter/Figure.svelte.d.ts +3 -2
- package/dist/components/chapter/Footnote.svelte.d.ts +2 -2
- package/dist/components/chapter/Format.svelte +21 -16
- package/dist/components/chapter/Format.svelte.d.ts +2 -2
- package/dist/components/chapter/InlineCode.svelte.d.ts +2 -2
- package/dist/components/chapter/Label.svelte.d.ts +2 -2
- package/dist/components/chapter/LineBreak.svelte +6 -0
- package/dist/components/chapter/LineBreak.svelte.d.ts +17 -0
- package/dist/components/chapter/Link.svelte.d.ts +2 -2
- package/dist/components/chapter/List.svelte.d.ts +2 -2
- package/dist/components/chapter/Marginal.svelte +1 -3
- package/dist/components/chapter/Marginal.svelte.d.ts +2 -2
- package/dist/components/chapter/Paragraph.svelte.d.ts +2 -2
- package/dist/components/chapter/Positioned.svelte.d.ts +2 -2
- package/dist/components/chapter/Problem.svelte.d.ts +2 -2
- package/dist/components/chapter/Python.svelte.d.ts +2 -2
- package/dist/components/chapter/Quote.svelte.d.ts +2 -2
- package/dist/components/chapter/Rule.svelte +2 -2
- package/dist/components/chapter/Rule.svelte.d.ts +2 -2
- package/dist/components/chapter/Table.svelte.d.ts +2 -2
- package/dist/components/chapter/Text.svelte.d.ts +2 -2
- package/dist/components/controls/DarkToggle.svelte.d.ts +2 -2
- package/dist/components/editor/BookishEditor.svelte +10 -12
- package/dist/components/editor/BookishEditor.svelte.d.ts +2 -2
- package/dist/components/editor/CalloutEditor.svelte.d.ts +2 -2
- package/dist/components/editor/CaptionedCodeEditor.svelte.d.ts +2 -2
- package/dist/components/editor/CaretContext.d.ts +1 -1
- package/dist/components/editor/CaretView.svelte +8 -3
- package/dist/components/editor/CaretView.svelte.d.ts +2 -2
- package/dist/components/editor/CitationsEditor.svelte.d.ts +2 -2
- package/dist/components/editor/Commands.js +109 -43
- package/dist/components/editor/ConfirmButton.svelte.d.ts +2 -2
- package/dist/components/editor/DefinitionEditor.svelte.d.ts +2 -2
- package/dist/components/editor/EmbedEditor.svelte.d.ts +2 -2
- package/dist/components/editor/Icon.svelte.d.ts +2 -2
- package/dist/components/editor/ImageChooser.svelte.d.ts +2 -2
- package/dist/components/editor/ImageThumbnail.svelte.d.ts +2 -2
- package/dist/components/editor/InlineCodeEditor.svelte.d.ts +2 -2
- package/dist/components/editor/LabelEditor.svelte.d.ts +2 -2
- package/dist/components/editor/LanguageEditor.svelte.d.ts +2 -2
- package/dist/components/editor/LinkEditor.svelte +4 -3
- package/dist/components/editor/LinkEditor.svelte.d.ts +2 -2
- package/dist/components/editor/Note.svelte.d.ts +2 -2
- package/dist/components/editor/Permissions.svelte.d.ts +2 -2
- package/dist/components/editor/PositionEditor.svelte.d.ts +2 -2
- package/dist/components/editor/QuoteEditor.svelte.d.ts +2 -2
- package/dist/components/editor/Switch.svelte.d.ts +2 -2
- package/dist/components/editor/TableEditor.svelte.d.ts +2 -2
- package/dist/components/editor/TextEditor.svelte.d.ts +2 -2
- package/dist/components/editor/Toggle.svelte.d.ts +2 -2
- package/dist/components/editor/Toolbar.svelte.d.ts +2 -2
- package/dist/components/editor/ToolbarGroup.svelte.d.ts +2 -2
- package/dist/components/editor/ToolbarSpacer.svelte.d.ts +2 -2
- package/dist/components/editor/URLEditor.svelte.d.ts +2 -2
- package/dist/components/page/Acknowledgements.svelte.d.ts +2 -2
- package/dist/components/page/Authors.svelte.d.ts +2 -2
- package/dist/components/page/BookLoader.svelte.d.ts +2 -2
- package/dist/components/page/BulkReferenceEditor.svelte +1 -1
- package/dist/components/page/BulkReferenceEditor.svelte.d.ts +2 -2
- package/dist/components/page/Chapter.svelte +4 -5
- package/dist/components/page/Chapter.svelte.d.ts +2 -2
- package/dist/components/page/ChapterNumber.svelte.d.ts +2 -2
- package/dist/components/page/ChapterTitle.svelte.d.ts +2 -2
- package/dist/components/page/DefinitionView.svelte.d.ts +2 -2
- package/dist/components/page/Description.svelte.d.ts +2 -2
- package/dist/components/page/Edition.svelte.d.ts +2 -2
- package/dist/components/page/EditionLoader.svelte +9 -18
- package/dist/components/page/EditionLoader.svelte.d.ts +2 -2
- package/dist/components/page/Editions.svelte +4 -3
- package/dist/components/page/Editions.svelte.d.ts +2 -2
- package/dist/components/page/Glossary.svelte +8 -2
- package/dist/components/page/Glossary.svelte.d.ts +2 -2
- package/dist/components/page/Header.svelte.d.ts +2 -2
- package/dist/components/page/Index.svelte +5 -2
- package/dist/components/page/Index.svelte.d.ts +2 -2
- package/dist/components/page/Instructions.svelte.d.ts +2 -2
- package/dist/components/page/License.svelte.d.ts +2 -2
- package/dist/components/page/Loading.svelte.d.ts +2 -2
- package/dist/components/page/Media.svelte +5 -2
- package/dist/components/page/Media.svelte.d.ts +2 -2
- package/dist/components/page/MediaPreview.svelte.d.ts +2 -2
- package/dist/components/page/Muted.svelte.d.ts +2 -2
- package/dist/components/page/Outline.svelte.d.ts +2 -2
- package/dist/components/page/Page.svelte.d.ts +2 -2
- package/dist/components/page/PageHeader.svelte.d.ts +2 -2
- package/dist/components/page/PageParagraph.svelte.d.ts +2 -2
- package/dist/components/page/PossibleChapter.svelte.d.ts +2 -2
- package/dist/components/page/PossibleReference.svelte.d.ts +2 -2
- package/dist/components/page/Print.svelte.d.ts +2 -2
- package/dist/components/page/Publish.svelte.d.ts +2 -2
- package/dist/components/page/Reference.svelte +24 -15
- package/dist/components/page/Reference.svelte.d.ts +2 -2
- package/dist/components/page/References.svelte +6 -2
- package/dist/components/page/References.svelte.d.ts +2 -2
- package/dist/components/page/Rows.svelte.d.ts +2 -2
- package/dist/components/page/Search.svelte +5 -3
- package/dist/components/page/Search.svelte.d.ts +2 -2
- package/dist/components/page/Status.svelte.d.ts +2 -2
- package/dist/components/page/SubdomainEditor.svelte +4 -3
- package/dist/components/page/SubdomainEditor.svelte.d.ts +2 -2
- package/dist/components/page/TableOfContents.svelte +9 -3
- package/dist/components/page/TableOfContents.svelte.d.ts +2 -2
- package/dist/components/page/TableOfContentsImage.svelte.d.ts +2 -2
- package/dist/components/page/TableOfContentsRow.svelte +3 -1
- package/dist/components/page/TableOfContentsRow.svelte.d.ts +2 -2
- package/dist/components/page/ThemeEditor.svelte.d.ts +2 -2
- package/dist/components/page/ThemeEditorPreview.svelte.d.ts +2 -2
- package/dist/components/page/ThemeSetEditor.svelte.d.ts +2 -2
- package/dist/components/page/ThemeVariableEditor.svelte.d.ts +2 -2
- package/dist/components/page/Title.svelte.d.ts +2 -2
- package/dist/components/page/Unknown.svelte.d.ts +2 -2
- package/dist/models/CRUD.d.ts +1 -2
- package/dist/models/CRUD.js +3 -5
- package/dist/models/book/BookMedia.js +8 -3
- package/dist/models/book/Chapter.d.ts +1 -1
- package/dist/models/book/Chapter.js +2 -3
- package/dist/models/book/Edition.d.ts +7 -5
- package/dist/models/book/Edition.js +10 -15
- package/dist/models/chapter/Caret.d.ts +2 -1
- package/dist/models/chapter/Caret.js +20 -6
- package/dist/models/chapter/FormatNode.d.ts +4 -1
- package/dist/models/chapter/FormatNode.js +53 -9
- package/dist/models/chapter/LineBreakNode.d.ts +15 -0
- package/dist/models/chapter/LineBreakNode.js +37 -0
- package/dist/models/chapter/Parser.d.ts +2 -0
- package/dist/models/chapter/Parser.js +12 -2
- package/dist/models/chapter/Symbols.d.ts +1 -0
- package/dist/models/chapter/Symbols.js +1 -0
- package/dist/util/mineReference.js +8 -6
- package/package.json +16 -15
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import AtomNode from './AtomNode';
|
|
2
2
|
import TextNode from './TextNode';
|
|
3
3
|
import FormatNode from './FormatNode';
|
|
4
|
-
|
|
4
|
+
import LineBreakNode from './LineBreakNode';
|
|
5
|
+
export function getNavigableNodes(node) {
|
|
5
6
|
return node
|
|
6
7
|
.getNodes()
|
|
7
|
-
.filter((n) => n instanceof TextNode ||
|
|
8
|
+
.filter((n) => n instanceof TextNode ||
|
|
9
|
+
n instanceof AtomNode ||
|
|
10
|
+
n instanceof LineBreakNode);
|
|
8
11
|
}
|
|
9
12
|
function getFormatRoots(node) {
|
|
10
13
|
const roots = [];
|
|
@@ -22,7 +25,7 @@ export function caretToIndex(node, caret) {
|
|
|
22
25
|
roots = [node];
|
|
23
26
|
let currentIndex = 0;
|
|
24
27
|
for (let n = 0; n < roots.length; n++) {
|
|
25
|
-
const nodes =
|
|
28
|
+
const nodes = getNavigableNodes(roots[n]);
|
|
26
29
|
for (let i = 0; i < nodes.length; i++) {
|
|
27
30
|
const t = nodes[i];
|
|
28
31
|
if (t !== caret.node)
|
|
@@ -40,9 +43,9 @@ export function indexToCaret(node, index) {
|
|
|
40
43
|
roots = [node];
|
|
41
44
|
let currentIndex = 0;
|
|
42
45
|
for (let n = 0; n < roots.length; n++) {
|
|
43
|
-
const nodes =
|
|
46
|
+
const nodes = getNavigableNodes(roots[n]);
|
|
44
47
|
for (let i = 0; i < nodes.length; i++) {
|
|
45
|
-
|
|
48
|
+
let t = nodes[i];
|
|
46
49
|
if (index >= currentIndex &&
|
|
47
50
|
index <= currentIndex + t.getCaretPositionCount()) {
|
|
48
51
|
// Prefer empty nodes to enable zero width formats.
|
|
@@ -51,7 +54,18 @@ export function indexToCaret(node, index) {
|
|
|
51
54
|
if (next instanceof TextNode && next.getLength() === 0)
|
|
52
55
|
return { node: next, index: 0 };
|
|
53
56
|
}
|
|
54
|
-
|
|
57
|
+
// If it's a line break node, find the next non-line break node.
|
|
58
|
+
if (t instanceof LineBreakNode) {
|
|
59
|
+
while (i < nodes.length &&
|
|
60
|
+
nodes[i] instanceof LineBreakNode)
|
|
61
|
+
i++;
|
|
62
|
+
t = nodes[i];
|
|
63
|
+
if (i === nodes.length || t instanceof LineBreakNode)
|
|
64
|
+
return undefined;
|
|
65
|
+
return { node: t, index: 0 };
|
|
66
|
+
}
|
|
67
|
+
else
|
|
68
|
+
return { node: t, index: index - currentIndex };
|
|
55
69
|
}
|
|
56
70
|
currentIndex += t.getCaretPositionCount();
|
|
57
71
|
}
|
|
@@ -6,8 +6,9 @@ import { type CaretRange } from './Caret';
|
|
|
6
6
|
import MetadataNode from './MetadataNode';
|
|
7
7
|
import AtomNode from './AtomNode';
|
|
8
8
|
import type Edit from './Edit';
|
|
9
|
+
import LineBreakNode from './LineBreakNode';
|
|
9
10
|
export type Format = '' | '*' | '_' | '^' | 'v';
|
|
10
|
-
export type FormatNodeSegmentType = FormatNode | TextNode | ErrorNode | MetadataNode<any> | AtomNode<any>;
|
|
11
|
+
export type FormatNodeSegmentType = FormatNode | TextNode | LineBreakNode | ErrorNode | MetadataNode<any> | AtomNode<any>;
|
|
11
12
|
export default class FormatNode extends Node {
|
|
12
13
|
#private;
|
|
13
14
|
constructor(format: Format, segments: FormatNodeSegmentType[]);
|
|
@@ -57,4 +58,6 @@ export default class FormatNode extends Node {
|
|
|
57
58
|
withoutAdjacentContent(caret: Caret, next: boolean): Edit | undefined;
|
|
58
59
|
withoutCharacter(caret: Caret, next: boolean): Edit | undefined;
|
|
59
60
|
withNodeInserted(caret: Caret, node: Node): Edit;
|
|
61
|
+
getSegmentAfter(segment: FormatNodeSegmentType): FormatNodeSegmentType | undefined;
|
|
62
|
+
getSegmentBefore(segment: FormatNodeSegmentType): FormatNodeSegmentType | undefined;
|
|
60
63
|
}
|
|
@@ -3,6 +3,7 @@ import TextNode from './TextNode';
|
|
|
3
3
|
import { caretRangeToIndexRange, caretToIndex, indexToCaret, } from './Caret';
|
|
4
4
|
import MetadataNode from './MetadataNode';
|
|
5
5
|
import AtomNode from './AtomNode';
|
|
6
|
+
import LineBreakNode from './LineBreakNode';
|
|
6
7
|
export default class FormatNode extends Node {
|
|
7
8
|
#format;
|
|
8
9
|
#segments;
|
|
@@ -10,14 +11,22 @@ export default class FormatNode extends Node {
|
|
|
10
11
|
super();
|
|
11
12
|
this.#format = format;
|
|
12
13
|
// Remove consecutive empty text nodes.
|
|
13
|
-
this.#segments = segments
|
|
14
|
+
this.#segments = segments
|
|
15
|
+
.filter((item, position, list) => {
|
|
14
16
|
if (position === 0 ||
|
|
15
17
|
!(item instanceof TextNode) ||
|
|
16
18
|
item.getLength() > 0)
|
|
17
19
|
return true;
|
|
18
20
|
const previous = list[position - 1];
|
|
19
21
|
return !(previous instanceof TextNode && previous.getLength() === 0);
|
|
20
|
-
})
|
|
22
|
+
})
|
|
23
|
+
// Insert text nodes between consecutive line breaks without them.
|
|
24
|
+
.map((item, position, list) => item instanceof LineBreakNode &&
|
|
25
|
+
list[position + 1] instanceof LineBreakNode
|
|
26
|
+
? [item, new TextNode()]
|
|
27
|
+
: [item])
|
|
28
|
+
// Flatten the mapped list we made.
|
|
29
|
+
.flat();
|
|
21
30
|
// Always ensure an empty text node.
|
|
22
31
|
if (this.#segments.length === 0)
|
|
23
32
|
this.#segments.push(new TextNode());
|
|
@@ -127,6 +136,11 @@ export default class FormatNode extends Node {
|
|
|
127
136
|
}
|
|
128
137
|
// If there's not, is there an adjacent caret in the sequence of text and atom nodes?
|
|
129
138
|
const adjacentNode = this.getAdjacentTextOrAtom(caret.node, next);
|
|
139
|
+
// If there's a line break adjacent to the next node, account for it.
|
|
140
|
+
const linebreak = adjacentNode &&
|
|
141
|
+
(next
|
|
142
|
+
? this.getSegmentBefore(adjacentNode) instanceof LineBreakNode
|
|
143
|
+
: this.getSegmentAfter(adjacentNode) instanceof LineBreakNode);
|
|
130
144
|
if (adjacentNode !== undefined) {
|
|
131
145
|
// Normally we skip over node boundaries because they look identical to each other.
|
|
132
146
|
// But some nodes are zero length, so we have to account for that.
|
|
@@ -134,18 +148,20 @@ export default class FormatNode extends Node {
|
|
|
134
148
|
node: adjacentNode,
|
|
135
149
|
index: next
|
|
136
150
|
? adjacentNode instanceof TextNode
|
|
137
|
-
? adjacentNode.isEmpty()
|
|
151
|
+
? adjacentNode.isEmpty() || linebreak
|
|
138
152
|
? 0
|
|
139
153
|
: 1
|
|
140
154
|
: 0
|
|
141
155
|
: adjacentNode instanceof TextNode
|
|
142
156
|
? adjacentNode.isEmpty()
|
|
143
157
|
? 0
|
|
144
|
-
:
|
|
158
|
+
: linebreak
|
|
159
|
+
? adjacentNode.getLength()
|
|
160
|
+
: adjacentNode.getLength() - 1
|
|
145
161
|
: 0,
|
|
146
162
|
};
|
|
147
163
|
}
|
|
148
|
-
// Otherwise, there is no
|
|
164
|
+
// Otherwise, there is no adjacent caret.
|
|
149
165
|
return undefined;
|
|
150
166
|
}
|
|
151
167
|
getFirstCaret() {
|
|
@@ -519,6 +535,19 @@ export default class FormatNode extends Node {
|
|
|
519
535
|
// Increment the text index; atoms count for one character.
|
|
520
536
|
textIndex++;
|
|
521
537
|
}
|
|
538
|
+
// Line break? Preserve the node, unless it's being deleted.
|
|
539
|
+
else if (node instanceof LineBreakNode) {
|
|
540
|
+
// Save any text prior to the line break as a text node in the current format.
|
|
541
|
+
saveText();
|
|
542
|
+
// Insert the line break unless we're deleting
|
|
543
|
+
if (format !== undefined ||
|
|
544
|
+
textIndex < selectionStartIndex ||
|
|
545
|
+
textIndex > selectionEndIndex) {
|
|
546
|
+
newFormats[0].segments.push(node);
|
|
547
|
+
}
|
|
548
|
+
// Increment the text index; atoms count for one character.
|
|
549
|
+
textIndex++;
|
|
550
|
+
}
|
|
522
551
|
});
|
|
523
552
|
// Save any remaining text that we've accumulated.
|
|
524
553
|
saveText();
|
|
@@ -726,18 +755,33 @@ export default class FormatNode extends Node {
|
|
|
726
755
|
if (!(node instanceof FormatNode ||
|
|
727
756
|
node instanceof TextNode ||
|
|
728
757
|
node instanceof MetadataNode ||
|
|
758
|
+
node instanceof LineBreakNode ||
|
|
729
759
|
node instanceof AtomNode))
|
|
730
760
|
return;
|
|
731
761
|
const newFormat = this.withSegmentAt(node, caret);
|
|
762
|
+
if (newFormat === undefined)
|
|
763
|
+
return;
|
|
764
|
+
const segmentAfter = newFormat.getSegmentAfter(node);
|
|
732
765
|
const newCaret = node instanceof AtomNode
|
|
733
766
|
? node.getDefaultCaret()
|
|
734
767
|
: node instanceof FormatNode
|
|
735
768
|
? node.getLastCaret()
|
|
736
|
-
: node
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
769
|
+
: // Line break? Place the caret just after the line break, whether a text node or something else
|
|
770
|
+
node instanceof LineBreakNode
|
|
771
|
+
? segmentAfter !== undefined && segmentAfter instanceof TextNode
|
|
772
|
+
? { node: segmentAfter, index: 0 }
|
|
773
|
+
: undefined
|
|
774
|
+
: node instanceof MetadataNode
|
|
775
|
+
? { node: node.getText(), index: node.getText().getLength() }
|
|
776
|
+
: { node: node, index: node.getLength() };
|
|
777
|
+
if (newCaret === undefined)
|
|
740
778
|
return;
|
|
741
779
|
return { root: newFormat, range: { start: newCaret, end: newCaret } };
|
|
742
780
|
}
|
|
781
|
+
getSegmentAfter(segment) {
|
|
782
|
+
return this.#segments[this.#segments.indexOf(segment) + 1];
|
|
783
|
+
}
|
|
784
|
+
getSegmentBefore(segment) {
|
|
785
|
+
return this.#segments[this.#segments.indexOf(segment) - 1];
|
|
786
|
+
}
|
|
743
787
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CaretRange } from './Caret';
|
|
2
|
+
import Node from './Node';
|
|
3
|
+
export default class LineBreakNode extends Node {
|
|
4
|
+
constructor();
|
|
5
|
+
getType(): string;
|
|
6
|
+
getParentOf(): Node | undefined;
|
|
7
|
+
toText(): string;
|
|
8
|
+
toBookdown(): string;
|
|
9
|
+
getCaretPositionCount(): number;
|
|
10
|
+
toHTML(): string;
|
|
11
|
+
getChildren(): never[];
|
|
12
|
+
copy(): this;
|
|
13
|
+
withChildReplaced(): this | undefined;
|
|
14
|
+
withContentInRange(range: CaretRange): this | undefined;
|
|
15
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Node from './Node';
|
|
2
|
+
import { LINE_BREAK } from './Symbols';
|
|
3
|
+
export default class LineBreakNode extends Node {
|
|
4
|
+
constructor() {
|
|
5
|
+
super();
|
|
6
|
+
}
|
|
7
|
+
getType() {
|
|
8
|
+
return 'linebreak';
|
|
9
|
+
}
|
|
10
|
+
getParentOf() {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
toText() {
|
|
14
|
+
return LINE_BREAK;
|
|
15
|
+
}
|
|
16
|
+
toBookdown() {
|
|
17
|
+
return LINE_BREAK;
|
|
18
|
+
}
|
|
19
|
+
getCaretPositionCount() {
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
toHTML() {
|
|
23
|
+
return '<br/>';
|
|
24
|
+
}
|
|
25
|
+
getChildren() {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
copy() {
|
|
29
|
+
return new LineBreakNode();
|
|
30
|
+
}
|
|
31
|
+
withChildReplaced() {
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
withContentInRange(range) {
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -21,6 +21,7 @@ import TextNode from './TextNode';
|
|
|
21
21
|
import type Position from './Position';
|
|
22
22
|
import type BlockNode from './BlockNode';
|
|
23
23
|
import type Bookkeeping from './Bookkeeping';
|
|
24
|
+
import LineBreakNode from './LineBreakNode';
|
|
24
25
|
export default class Parser {
|
|
25
26
|
book: Edition | undefined;
|
|
26
27
|
text: string;
|
|
@@ -62,6 +63,7 @@ export default class Parser {
|
|
|
62
63
|
parseCallout(): CalloutNode;
|
|
63
64
|
parseTable(): TableNode;
|
|
64
65
|
parseFormat(awaiting?: string): FormatNode;
|
|
66
|
+
parseLineBreak(): LineBreakNode;
|
|
65
67
|
parseEmbed(): EmbedNode;
|
|
66
68
|
parseComment(): CommentNode;
|
|
67
69
|
parseLabel(): LabelNode | ErrorNode;
|
|
@@ -14,10 +14,11 @@ import LinkNode from './LinkNode';
|
|
|
14
14
|
import ListNode from './ListNode';
|
|
15
15
|
import ParagraphNode from './ParagraphNode';
|
|
16
16
|
import QuoteNode from './QuoteNode';
|
|
17
|
-
import Reference from '../book/Reference';
|
|
18
17
|
import RuleNode from './RuleNode';
|
|
19
18
|
import TableNode from './TableNode';
|
|
20
19
|
import TextNode from './TextNode';
|
|
20
|
+
import LineBreakNode from './LineBreakNode';
|
|
21
|
+
import { LINE_BREAK } from './Symbols';
|
|
21
22
|
const numberedRE = /^[0-9]+\.+/;
|
|
22
23
|
const bulletRE = /^\*+\s+/;
|
|
23
24
|
// TODO This grammar is slightly out of date.
|
|
@@ -181,6 +182,7 @@ export default class Parser {
|
|
|
181
182
|
next === '*' ||
|
|
182
183
|
next === '`' ||
|
|
183
184
|
next === '@' ||
|
|
185
|
+
next === LINE_BREAK ||
|
|
184
186
|
next === '~' ||
|
|
185
187
|
(next === ':' &&
|
|
186
188
|
charAfterNext !== null &&
|
|
@@ -578,7 +580,10 @@ export default class Parser {
|
|
|
578
580
|
// Parse some bold, italic, subscript, superscript
|
|
579
581
|
if (next === '_' || next === '*' || next === '^')
|
|
580
582
|
segments.push(this.parseStyle(next));
|
|
581
|
-
// Parse
|
|
583
|
+
// Parse a line break
|
|
584
|
+
else if (this.nextIs(LINE_BREAK))
|
|
585
|
+
segments.push(this.parseLineBreak());
|
|
586
|
+
// Parse inline code text
|
|
582
587
|
else if (this.nextIs('`'))
|
|
583
588
|
segments.push(this.parseInlineCode());
|
|
584
589
|
// Parse a citation list
|
|
@@ -634,6 +639,11 @@ export default class Parser {
|
|
|
634
639
|
}
|
|
635
640
|
return new FormatNode('', segments);
|
|
636
641
|
}
|
|
642
|
+
parseLineBreak() {
|
|
643
|
+
// Read the line break
|
|
644
|
+
this.read();
|
|
645
|
+
return new LineBreakNode();
|
|
646
|
+
}
|
|
637
647
|
parseEmbed() {
|
|
638
648
|
// Read |
|
|
639
649
|
this.read();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LINE_BREAK = "\u21A9";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const LINE_BREAK = '↩';
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import Reference from '../models/book/Reference';
|
|
2
2
|
export function mineReference(ids, text) {
|
|
3
3
|
// First find the year, since it's the most easily detected. Optional parens.
|
|
4
|
-
let yearMatches = text.match(/(\(?[0-9]{4}
|
|
4
|
+
let yearMatches = text.match(/(\(?[0-9]{4}(,[a-zA-Z ]+)?\)?)/);
|
|
5
5
|
let year = yearMatches !== null && yearMatches.length > 0
|
|
6
6
|
? yearMatches[1].replace('(', '').replace(')', '')
|
|
7
7
|
: undefined;
|
|
8
|
-
if (year && yearMatches)
|
|
8
|
+
if (year && yearMatches) {
|
|
9
|
+
const digits = year.match(/([0-9]{4})/);
|
|
10
|
+
if (digits !== null)
|
|
11
|
+
year = digits[1];
|
|
9
12
|
text = text.replace(yearMatches[1], '');
|
|
13
|
+
}
|
|
10
14
|
// Next, find the URL
|
|
11
15
|
let url = null;
|
|
12
16
|
let urlMatches = text.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/);
|
|
@@ -38,9 +42,7 @@ export function mineReference(ids, text) {
|
|
|
38
42
|
source = source.trim();
|
|
39
43
|
}
|
|
40
44
|
// If there's anything left, fall back to just a string.
|
|
41
|
-
return
|
|
42
|
-
? new Reference(getUniqueReferenceID(ids), text)
|
|
43
|
-
: new Reference(getUniqueReferenceID(ids, authors, year), authors || '', year || '', title || '', source || '', url || '', '', false);
|
|
45
|
+
return new Reference(getUniqueReferenceID(ids, authors, year), authors || '', year || '', title || '', source || '', url || '', '', false);
|
|
44
46
|
}
|
|
45
47
|
export function splitIntoSentences(text) {
|
|
46
48
|
// Split the remaining text by period-space sequences, assuming chunks of information are segmented by sentences
|
|
@@ -92,7 +94,7 @@ export function getUniqueReferenceID(ids, authors, year) {
|
|
|
92
94
|
return revisedID;
|
|
93
95
|
}
|
|
94
96
|
else {
|
|
95
|
-
let id = '
|
|
97
|
+
let id = '00';
|
|
96
98
|
for (let i = 0; i < 4; i++)
|
|
97
99
|
id = id + Math.round(Math.random() * 9);
|
|
98
100
|
return id;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bookish-press",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.7",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "A platform for reading and writing readable, accessible, beautiful online books.",
|
|
7
7
|
"license": "MIT",
|
|
@@ -28,30 +28,31 @@
|
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@sveltejs/adapter-static": "^2.0",
|
|
31
|
-
"@sveltejs/
|
|
32
|
-
"@sveltejs/
|
|
31
|
+
"@sveltejs/adapter-auto": "^2.1.1",
|
|
32
|
+
"@sveltejs/kit": "^1.27",
|
|
33
|
+
"@sveltejs/package": "^2.2",
|
|
33
34
|
"@types/prismjs": "^1.26",
|
|
34
|
-
"@types/smoothscroll-polyfill": "^0
|
|
35
|
+
"@types/smoothscroll-polyfill": "^0",
|
|
35
36
|
"@types/uuid": "^9.0",
|
|
36
|
-
"prettier": "^
|
|
37
|
-
"prettier-plugin-svelte": "^
|
|
37
|
+
"prettier": "^3",
|
|
38
|
+
"prettier-plugin-svelte": "^3",
|
|
38
39
|
"svelte-adapter-firebase": "^0.15.0",
|
|
39
|
-
"svelte-check": "^3.
|
|
40
|
-
"svelte-preprocess": "^5.
|
|
41
|
-
"tslib": "^2
|
|
40
|
+
"svelte-check": "^3.6",
|
|
41
|
+
"svelte-preprocess": "^5.1",
|
|
42
|
+
"tslib": "^2",
|
|
42
43
|
"typescript": "^5",
|
|
43
|
-
"vite": "^4
|
|
44
|
-
"vitest": "^0
|
|
44
|
+
"vite": "^4",
|
|
45
|
+
"vitest": "^0"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"
|
|
48
|
-
"ajv
|
|
48
|
+
"@sveltejs/kit": "^1.27",
|
|
49
|
+
"ajv": "^8",
|
|
50
|
+
"ajv-formats": "^2",
|
|
49
51
|
"firebase": "latest",
|
|
50
52
|
"firebase-functions": "latest",
|
|
51
53
|
"prismjs": "^1.29",
|
|
52
54
|
"smoothscroll-polyfill": "^0.4",
|
|
53
|
-
"svelte": "^4.
|
|
54
|
-
"@sveltejs/kit": "^1.20",
|
|
55
|
+
"svelte": "^4.2",
|
|
55
56
|
"uuid": "^9.0"
|
|
56
57
|
},
|
|
57
58
|
"types": "./dist/index.d.ts",
|