bookish-press 0.4.1 → 0.4.3
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 +3 -1
- package/components/Auth.svelte +27 -24
- package/components/Auth.svelte.d.ts +4 -4
- package/components/Authentication.d.ts +2 -2
- package/components/BookPreview.svelte +75 -59
- package/components/BookPreview.svelte.d.ts +5 -5
- package/components/External.svelte +1 -1
- package/components/External.svelte.d.ts +3 -3
- package/components/Link.svelte +49 -3
- package/components/Link.svelte.d.ts +3 -4
- package/components/app/BookList.svelte +19 -0
- package/components/app/BookList.svelte.d.ts +18 -0
- package/components/app/Button.svelte +49 -0
- package/components/app/Button.svelte.d.ts +22 -0
- package/components/app/Feedback.svelte +47 -0
- package/components/app/Feedback.svelte.d.ts +18 -0
- package/components/app/Head.svelte +15 -0
- package/components/app/Head.svelte.d.ts +18 -0
- package/components/app/Large.svelte +8 -0
- package/components/app/Large.svelte.d.ts +27 -0
- package/components/app/Lead.svelte +12 -0
- package/components/app/Lead.svelte.d.ts +27 -0
- package/components/app/Link.svelte +24 -0
- package/components/app/Link.svelte.d.ts +20 -0
- package/components/app/Options.svelte +24 -0
- package/components/app/Options.svelte.d.ts +19 -0
- package/components/app/Paragraph.svelte +20 -0
- package/components/app/Paragraph.svelte.d.ts +18 -0
- package/components/app/Section.svelte +12 -0
- package/components/app/Section.svelte.d.ts +27 -0
- package/components/app/Table.svelte +32 -0
- package/components/app/Table.svelte.d.ts +27 -0
- package/components/app/TextInput.svelte +38 -0
- package/components/app/TextInput.svelte.d.ts +22 -0
- package/components/chapter/Atom.svelte +20 -6
- package/components/chapter/Atom.svelte.d.ts +3 -3
- package/components/chapter/Block.svelte +26 -21
- package/components/chapter/Block.svelte.d.ts +4 -4
- package/components/chapter/Callout.svelte +38 -7
- package/components/chapter/Callout.svelte.d.ts +4 -4
- package/components/chapter/CaptionedCode.svelte +67 -24
- package/components/chapter/CaptionedCode.svelte.d.ts +4 -4
- package/components/chapter/ChapterBody.svelte +62 -9
- package/components/chapter/ChapterBody.svelte.d.ts +5 -4
- package/components/chapter/Citations.svelte +86 -20
- package/components/chapter/Citations.svelte.d.ts +4 -4
- package/components/chapter/Code.svelte +152 -21
- package/components/chapter/Code.svelte.d.ts +3 -3
- package/components/chapter/Comment.svelte +39 -17
- package/components/chapter/Comment.svelte.d.ts +3 -3
- package/components/chapter/Definition.svelte +52 -18
- package/components/chapter/Definition.svelte.d.ts +5 -8
- package/components/chapter/Embed.svelte +155 -67
- package/components/chapter/Embed.svelte.d.ts +6 -4
- package/components/chapter/ErrorMessage.svelte +7 -2
- package/components/chapter/ErrorMessage.svelte.d.ts +4 -4
- package/components/chapter/ExtendedPrism.d.ts +2 -0
- package/components/chapter/ExtendedPrism.js +69 -0
- package/components/chapter/Figure.svelte +90 -0
- package/components/chapter/Figure.svelte.d.ts +24 -0
- package/components/chapter/Footnote.svelte +75 -12
- package/components/chapter/Footnote.svelte.d.ts +4 -4
- package/components/chapter/Format.svelte +63 -38
- package/components/chapter/Format.svelte.d.ts +5 -4
- package/components/chapter/InlineCode.svelte +16 -6
- package/components/chapter/InlineCode.svelte.d.ts +4 -4
- package/components/chapter/Label.svelte +38 -9
- package/components/chapter/Label.svelte.d.ts +4 -4
- package/components/chapter/Link.svelte +24 -19
- package/components/chapter/Link.svelte.d.ts +4 -4
- package/components/chapter/List.svelte +75 -8
- package/components/chapter/List.svelte.d.ts +4 -4
- package/components/chapter/Marginal.svelte +169 -27
- package/components/chapter/Marginal.svelte.d.ts +6 -3
- package/components/chapter/Paragraph.svelte +79 -6
- package/components/chapter/Paragraph.svelte.d.ts +4 -4
- package/components/chapter/Positioned.svelte +33 -0
- package/components/chapter/Positioned.svelte.d.ts +19 -0
- package/components/chapter/Problem.svelte +15 -0
- package/components/chapter/Problem.svelte.d.ts +27 -0
- package/components/chapter/Python.svelte +68 -21
- package/components/chapter/Python.svelte.d.ts +4 -4
- package/components/chapter/Quote.svelte +64 -11
- package/components/chapter/Quote.svelte.d.ts +4 -4
- package/components/chapter/Rule.svelte +12 -1
- package/components/chapter/Rule.svelte.d.ts +4 -4
- package/components/chapter/Table.svelte +36 -25
- package/components/chapter/Table.svelte.d.ts +4 -4
- package/components/chapter/Text.svelte +61 -36
- package/components/chapter/Text.svelte.d.ts +5 -4
- package/components/editor/BookishEditor.svelte +373 -244
- package/components/editor/BookishEditor.svelte.d.ts +9 -6
- package/components/editor/CalloutEditor.svelte +5 -5
- package/components/editor/CalloutEditor.svelte.d.ts +4 -4
- package/components/editor/CaptionedCodeEditor.svelte +16 -12
- package/components/editor/CaptionedCodeEditor.svelte.d.ts +4 -4
- package/components/editor/CaretContext.d.ts +48 -16
- package/components/editor/CaretState.d.ts +16 -44
- package/components/editor/CaretUtilities.d.ts +2 -2
- package/components/editor/CaretView.svelte +82 -0
- package/components/editor/CaretView.svelte.d.ts +25 -0
- package/components/editor/CitationsEditor.svelte +36 -25
- package/components/editor/CitationsEditor.svelte.d.ts +4 -4
- package/components/editor/Clipboard.d.ts +2 -2
- package/components/editor/Command.d.ts +13 -12
- package/components/editor/Commands.d.ts +1 -1
- package/components/editor/Commands.js +1114 -571
- package/components/editor/ConfirmButton.svelte +18 -12
- package/components/editor/ConfirmButton.svelte.d.ts +5 -4
- package/components/editor/DefinitionEditor.svelte +29 -21
- package/components/editor/DefinitionEditor.svelte.d.ts +4 -4
- package/components/editor/EmbedEditor.svelte +93 -43
- package/components/editor/EmbedEditor.svelte.d.ts +3 -3
- package/components/editor/Icon.svelte +17 -0
- package/components/editor/Icon.svelte.d.ts +16 -0
- package/components/editor/ImageChooser.svelte +53 -34
- package/components/editor/ImageChooser.svelte.d.ts +3 -3
- package/components/editor/InlineCodeEditor.svelte +7 -4
- package/components/editor/InlineCodeEditor.svelte.d.ts +4 -4
- package/components/editor/LabelEditor.svelte +20 -11
- package/components/editor/LabelEditor.svelte.d.ts +4 -4
- package/components/editor/LanguageEditor.svelte +10 -7
- package/components/editor/LanguageEditor.svelte.d.ts +3 -3
- package/components/editor/LinkEditor.svelte +64 -39
- package/components/editor/LinkEditor.svelte.d.ts +4 -4
- package/components/editor/Note.svelte +4 -3
- package/components/editor/Note.svelte.d.ts +6 -2
- package/components/editor/Permissions.svelte +95 -0
- package/components/editor/Permissions.svelte.d.ts +20 -0
- package/components/editor/PositionEditor.svelte +9 -6
- package/components/editor/PositionEditor.svelte.d.ts +4 -4
- package/components/editor/QuoteEditor.svelte +7 -2
- package/components/editor/QuoteEditor.svelte.d.ts +4 -4
- package/components/editor/Switch.svelte +55 -28
- package/components/editor/Switch.svelte.d.ts +4 -4
- package/components/editor/TableEditor.svelte +10 -0
- package/components/editor/TableEditor.svelte.d.ts +17 -0
- package/components/editor/TextEditor.svelte +83 -45
- package/components/editor/TextEditor.svelte.d.ts +5 -4
- package/components/editor/Toggle.svelte +11 -8
- package/components/editor/Toggle.svelte.d.ts +4 -4
- package/components/editor/Toolbar.svelte +191 -144
- package/components/editor/Toolbar.svelte.d.ts +5 -8
- package/components/editor/ToolbarGroup.svelte +17 -23
- package/components/editor/ToolbarGroup.svelte.d.ts +3 -4
- package/components/editor/ToolbarSpacer.svelte +8 -1
- package/components/editor/ToolbarSpacer.svelte.d.ts +6 -2
- package/components/editor/URLEditor.svelte +6 -8
- package/components/editor/URLEditor.svelte.d.ts +3 -3
- package/components/editor/UndoState.d.ts +3 -3
- package/components/editor/icons/annotate.svg +1 -0
- package/components/editor/icons/block.svg +1 -0
- package/components/editor/icons/bold.svg +1 -0
- package/components/editor/icons/bullets.svg +1 -0
- package/components/editor/icons/callout.svg +1 -0
- package/components/editor/icons/citation.svg +8 -0
- package/components/editor/icons/clear.svg +1 -0
- package/components/editor/icons/clipboard.svg +1 -0
- package/components/editor/icons/code.svg +1 -0
- package/components/editor/icons/columnafter.svg +1 -0
- package/components/editor/icons/columnbefore.svg +1 -0
- package/components/editor/icons/comment.svg +1 -0
- package/components/editor/icons/copy.svg +1 -0
- package/components/editor/icons/cut.svg +1 -0
- package/components/editor/icons/define.svg +7 -0
- package/components/editor/icons/deletecolumn.svg +1 -0
- package/components/editor/icons/deleterow.svg +1 -0
- package/components/editor/icons/footnote.svg +8 -0
- package/components/editor/icons/header1.svg +7 -0
- package/components/editor/icons/header2.svg +7 -0
- package/components/editor/icons/header3.svg +7 -0
- package/components/editor/icons/home.svg +1 -0
- package/components/editor/icons/indent.svg +1 -0
- package/components/editor/icons/italic.svg +1 -0
- package/components/editor/icons/label.svg +1 -0
- package/components/editor/icons/left.svg +1 -0
- package/components/editor/icons/level.svg +1 -0
- package/components/editor/icons/link.svg +1 -0
- package/components/editor/icons/list.svg +1 -0
- package/components/editor/icons/media.svg +1 -0
- package/components/editor/icons/middle.svg +1 -0
- package/components/editor/icons/numbers.svg +10 -0
- package/components/editor/icons/paragraph.svg +1 -0
- package/components/editor/icons/paste.svg +10 -0
- package/components/editor/icons/quote.svg +1 -0
- package/components/editor/icons/redo.svg +1 -0
- package/components/editor/icons/right.svg +1 -0
- package/components/editor/icons/rowabove.svg +1 -0
- package/components/editor/icons/rowbelow.svg +1 -0
- package/components/editor/icons/rule.svg +1 -0
- package/components/editor/icons/sub.svg +1 -0
- package/components/editor/icons/super.svg +1 -0
- package/components/editor/icons/table.svg +1 -0
- package/components/editor/icons/text.svg +1 -0
- package/components/editor/icons/time.svg +1 -0
- package/components/editor/icons/undo.svg +1 -0
- package/components/editor/icons/unindent.svg +1 -0
- package/components/editor/icons/unlink.svg +1 -0
- package/components/page/Acknowledgements.svelte +35 -24
- package/components/page/Acknowledgements.svelte.d.ts +4 -4
- package/components/page/Authors.svelte +34 -17
- package/components/page/Authors.svelte.d.ts +7 -6
- package/components/page/BookLoader.svelte +59 -0
- package/components/page/BookLoader.svelte.d.ts +16 -0
- package/components/page/BulkReferenceEditor.svelte +54 -23
- package/components/page/BulkReferenceEditor.svelte.d.ts +4 -4
- package/components/page/Chapter.svelte +234 -143
- package/components/page/Chapter.svelte.d.ts +3 -3
- package/components/page/ChapterContext.d.ts +4 -4
- package/components/page/ChapterNumber.svelte +9 -0
- package/components/page/ChapterNumber.svelte.d.ts +27 -0
- package/components/page/ChapterTitle.svelte +16 -0
- package/components/page/ChapterTitle.svelte.d.ts +18 -0
- package/components/page/Contexts.d.ts +42 -22
- package/components/page/Contexts.js +129 -17
- package/components/page/DefinitionView.svelte +129 -90
- package/components/page/DefinitionView.svelte.d.ts +3 -3
- package/components/page/Description.svelte +31 -19
- package/components/page/Description.svelte.d.ts +4 -4
- package/components/page/Edition.svelte +135 -81
- package/components/page/Edition.svelte.d.ts +5 -6
- package/components/page/EditionLoader.svelte +99 -0
- package/components/page/EditionLoader.svelte.d.ts +18 -0
- package/components/page/Editions.svelte +106 -0
- package/components/page/Editions.svelte.d.ts +14 -0
- package/components/page/Glossary.svelte +65 -49
- package/components/page/Glossary.svelte.d.ts +4 -4
- package/components/page/Header.svelte +143 -56
- package/components/page/Header.svelte.d.ts +8 -6
- package/components/page/Index.svelte +116 -80
- package/components/page/Index.svelte.d.ts +4 -4
- package/components/page/Instructions.svelte +18 -17
- package/components/page/Instructions.svelte.d.ts +6 -4
- package/components/page/License.svelte +39 -23
- package/components/page/License.svelte.d.ts +4 -4
- package/components/page/Loading.svelte +102 -12
- package/components/page/Loading.svelte.d.ts +6 -2
- package/components/page/Media.svelte +81 -53
- package/components/page/Media.svelte.d.ts +4 -4
- package/components/page/MediaPreview.svelte +26 -8
- package/components/page/MediaPreview.svelte.d.ts +3 -3
- package/components/page/Muted.svelte +10 -0
- package/components/page/Muted.svelte.d.ts +27 -0
- package/components/page/Outline.svelte +279 -59
- package/components/page/Outline.svelte.d.ts +3 -3
- package/components/page/Page.svelte +40 -9
- package/components/page/Page.svelte.d.ts +3 -3
- package/components/page/PageHeader.svelte +14 -0
- package/components/page/PageHeader.svelte.d.ts +18 -0
- package/components/page/PageParagraph.svelte +18 -0
- package/components/page/PageParagraph.svelte.d.ts +27 -0
- package/components/page/PossibleChapter.svelte +7 -7
- package/components/page/PossibleChapter.svelte.d.ts +4 -4
- package/components/page/PossibleReference.svelte +6 -11
- package/components/page/PossibleReference.svelte.d.ts +6 -7
- package/components/page/Print.svelte +27 -3
- package/components/page/Print.svelte.d.ts +4 -4
- package/components/page/Publish.svelte +134 -0
- package/components/page/Publish.svelte.d.ts +14 -0
- package/components/page/Reference.svelte +259 -117
- package/components/page/Reference.svelte.d.ts +5 -5
- package/components/page/References.svelte +45 -48
- package/components/page/References.svelte.d.ts +4 -4
- package/components/page/Rows.svelte +54 -0
- package/components/page/Rows.svelte.d.ts +27 -0
- package/components/page/Search.svelte +88 -63
- package/components/page/Search.svelte.d.ts +4 -4
- package/components/page/Status.svelte +46 -39
- package/components/page/Status.svelte.d.ts +4 -9
- package/components/page/SubdomainEditor.svelte +41 -27
- package/components/page/SubdomainEditor.svelte.d.ts +4 -4
- package/components/page/TableOfContents.svelte +264 -191
- package/components/page/TableOfContents.svelte.d.ts +4 -4
- package/components/page/TableOfContentsImage.svelte +8 -8
- package/components/page/TableOfContentsImage.svelte.d.ts +3 -3
- package/components/page/TableOfContentsRow.svelte +97 -34
- package/components/page/TableOfContentsRow.svelte.d.ts +4 -4
- package/components/page/ThemeEditor.svelte +177 -39
- package/components/page/ThemeEditor.svelte.d.ts +4 -4
- package/components/page/ThemeEditorPreview.svelte +35 -23
- package/components/page/ThemeEditorPreview.svelte.d.ts +5 -5
- package/components/page/ThemeSetEditor.svelte +15 -13
- package/components/page/ThemeSetEditor.svelte.d.ts +4 -4
- package/components/page/ThemeVariableEditor.svelte +24 -15
- package/components/page/ThemeVariableEditor.svelte.d.ts +3 -3
- package/components/page/Title.svelte +12 -0
- package/components/page/Title.svelte.d.ts +27 -0
- package/components/page/Unknown.svelte +28 -21
- package/components/page/Unknown.svelte.d.ts +4 -4
- package/components/page/margins.js +50 -33
- package/index.d.ts +13 -0
- package/index.js +14 -0
- package/models/CRUD.d.ts +27 -0
- package/models/CRUD.js +262 -0
- package/models/Firebase.d.ts +1 -0
- package/models/Firebase.js +26 -16
- package/models/book/Book.d.ts +40 -39
- package/models/book/Book.js +121 -121
- package/models/book/BookMedia.d.ts +3 -3
- package/models/book/BookMedia.js +22 -16
- package/models/book/BookSaveStatus.d.ts +7 -0
- package/models/book/BookSaveStatus.js +8 -0
- package/models/book/Chapter.d.ts +50 -39
- package/models/book/Chapter.js +189 -198
- package/models/book/ChapterID.js +7 -7
- package/models/book/Definition.d.ts +1 -1
- package/models/book/Edition.d.ts +87 -61
- package/models/book/Edition.js +460 -309
- package/models/book/Reference.d.ts +24 -0
- package/models/book/Reference.js +78 -0
- package/models/book/Schema.d.ts +168 -0
- package/models/book/Schema.js +115 -0
- package/models/book/Theme.d.ts +44 -37
- package/models/book/Theme.js +452 -52
- package/models/book/ThemeColors.d.ts +1 -1
- package/models/book/Words.d.ts +2 -0
- package/models/book/Words.js +110 -0
- package/models/chapter/AtomNode.d.ts +4 -4
- package/models/chapter/AtomNode.js +20 -13
- package/models/chapter/BlockNode.d.ts +9 -10
- package/models/chapter/BlockNode.js +32 -13
- package/models/chapter/BlocksNode.d.ts +10 -10
- package/models/chapter/BlocksNode.js +315 -120
- package/models/chapter/BlocksNode.test.js +494 -228
- package/models/chapter/Bookkeeping.d.ts +1 -1
- package/models/chapter/CalloutNode.d.ts +3 -3
- package/models/chapter/CalloutNode.js +34 -12
- package/models/chapter/Caret.d.ts +9 -7
- package/models/chapter/Caret.js +11 -6
- package/models/chapter/ChapterNode.d.ts +11 -11
- package/models/chapter/ChapterNode.js +70 -33
- package/models/chapter/CitationsNode.d.ts +3 -3
- package/models/chapter/CitationsNode.js +31 -12
- package/models/chapter/CodeNode.d.ts +11 -6
- package/models/chapter/CodeNode.js +143 -34
- package/models/chapter/CommentNode.d.ts +5 -5
- package/models/chapter/CommentNode.js +29 -13
- package/models/chapter/DefinitionNode.d.ts +2 -2
- package/models/chapter/DefinitionNode.js +15 -7
- package/models/chapter/Edit.d.ts +3 -3
- package/models/chapter/EmbedNode.d.ts +9 -5
- package/models/chapter/EmbedNode.js +108 -35
- package/models/chapter/ErrorNode.d.ts +2 -2
- package/models/chapter/ErrorNode.js +34 -12
- package/models/chapter/FootnoteNode.d.ts +5 -5
- package/models/chapter/FootnoteNode.js +34 -16
- package/models/chapter/FormatNode.d.ts +10 -10
- package/models/chapter/FormatNode.js +237 -106
- package/models/chapter/FormatNode.test.js +87 -45
- package/models/chapter/InlineCodeNode.d.ts +2 -2
- package/models/chapter/InlineCodeNode.js +22 -9
- package/models/chapter/LabelNode.d.ts +4 -4
- package/models/chapter/LabelNode.js +31 -13
- package/models/chapter/LinkNode.d.ts +2 -2
- package/models/chapter/LinkNode.js +21 -9
- package/models/chapter/ListNode.d.ts +8 -8
- package/models/chapter/ListNode.js +99 -38
- package/models/chapter/ListNode.test.js +29 -24
- package/models/chapter/MetadataNode.d.ts +3 -3
- package/models/chapter/MetadataNode.js +13 -5
- package/models/chapter/Node.d.ts +5 -3
- package/models/chapter/Node.js +76 -29
- package/models/chapter/Node.test.js +20 -18
- package/models/chapter/ParagraphNode.d.ts +6 -6
- package/models/chapter/ParagraphNode.js +84 -29
- package/models/chapter/ParagraphNode.test.js +22 -13
- package/models/chapter/Parser.d.ts +27 -27
- package/models/chapter/Parser.js +220 -206
- package/models/chapter/Parser.test.js +16 -16
- package/models/chapter/Position.d.ts +1 -1
- package/models/chapter/QuoteNode.d.ts +6 -6
- package/models/chapter/QuoteNode.js +61 -23
- package/models/chapter/RootNode.d.ts +4 -4
- package/models/chapter/RuleNode.d.ts +2 -2
- package/models/chapter/RuleNode.js +31 -11
- package/models/chapter/TableNode.d.ts +8 -6
- package/models/chapter/TableNode.js +89 -34
- package/models/chapter/TableNode.test.js +22 -24
- package/models/chapter/TextNode.d.ts +6 -6
- package/models/chapter/TextNode.js +72 -32
- package/models/chapter/TextNode.test.js +4 -4
- package/package.json +108 -26
- package/util/getSubdomain.js +8 -6
- package/util/isMobile.js +1 -1
- package/util/mineReference.d.ts +3 -2
- package/util/mineReference.js +67 -29
- package/util/scrollToEyeLevel.js +6 -1
- package/components/chapter/renderPosition.d.ts +0 -3
- package/components/chapter/renderPosition.js +0 -4
- package/components/editor/ToolbarIcon.svelte +0 -22
- package/components/editor/ToolbarIcon.svelte.d.ts +0 -16
- package/components/page/Alert.svelte +0 -11
- package/components/page/Alert.svelte.d.ts +0 -23
- package/components/page/Revisions.svelte +0 -124
- package/components/page/Revisions.svelte.d.ts +0 -14
- package/models/BookLoader.d.ts +0 -2
- package/models/BookLoader.js +0 -67
- package/models/Firestore.d.ts +0 -22
- package/models/Firestore.js +0 -194
- package/models/chapter/ReferenceNode.d.ts +0 -29
- package/models/chapter/ReferenceNode.js +0 -48
- package/models/loadEdition.d.ts +0 -5
- package/models/loadEdition.js +0 -16
package/models/chapter/Parser.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import CalloutNode from
|
|
2
|
-
import ChapterNode from
|
|
3
|
-
import CitationsNode from
|
|
4
|
-
import CodeNode from
|
|
5
|
-
import CommentNode from
|
|
6
|
-
import DefinitionNode from
|
|
7
|
-
import EmbedNode from
|
|
8
|
-
import ErrorNode from
|
|
9
|
-
import FootnoteNode from
|
|
10
|
-
import FormatNode from
|
|
11
|
-
import InlineCodeNode from
|
|
12
|
-
import LabelNode from
|
|
13
|
-
import LinkNode from
|
|
14
|
-
import ListNode from
|
|
15
|
-
import ParagraphNode from
|
|
16
|
-
import QuoteNode from
|
|
17
|
-
import
|
|
18
|
-
import RuleNode from
|
|
19
|
-
import TableNode from
|
|
20
|
-
import TextNode from
|
|
1
|
+
import CalloutNode from './CalloutNode';
|
|
2
|
+
import ChapterNode from './ChapterNode';
|
|
3
|
+
import CitationsNode from './CitationsNode';
|
|
4
|
+
import CodeNode from './CodeNode';
|
|
5
|
+
import CommentNode from './CommentNode';
|
|
6
|
+
import DefinitionNode from './DefinitionNode';
|
|
7
|
+
import EmbedNode from './EmbedNode';
|
|
8
|
+
import ErrorNode from './ErrorNode';
|
|
9
|
+
import FootnoteNode from './FootnoteNode';
|
|
10
|
+
import FormatNode from './FormatNode';
|
|
11
|
+
import InlineCodeNode from './InlineCodeNode';
|
|
12
|
+
import LabelNode from './LabelNode';
|
|
13
|
+
import LinkNode from './LinkNode';
|
|
14
|
+
import ListNode from './ListNode';
|
|
15
|
+
import ParagraphNode from './ParagraphNode';
|
|
16
|
+
import QuoteNode from './QuoteNode';
|
|
17
|
+
import Reference from '../book/Reference';
|
|
18
|
+
import RuleNode from './RuleNode';
|
|
19
|
+
import TableNode from './TableNode';
|
|
20
|
+
import TextNode from './TextNode';
|
|
21
21
|
const numberedRE = /^[0-9]+\.+/;
|
|
22
22
|
const bulletRE = /^\*+\s+/;
|
|
23
23
|
// TODO This grammar is slightly out of date.
|
|
@@ -53,14 +53,14 @@ export default class Parser {
|
|
|
53
53
|
// We pass this to all parsing functions to gather information strewn about the document.
|
|
54
54
|
metadata;
|
|
55
55
|
constructor(book, text) {
|
|
56
|
-
if (typeof text !==
|
|
57
|
-
throw
|
|
56
|
+
if (typeof text !== 'string')
|
|
57
|
+
throw 'Parser expected a string but received ' + typeof text;
|
|
58
58
|
this.book = book;
|
|
59
59
|
this.text = text;
|
|
60
60
|
this.index = 0; // Start at the first character.
|
|
61
61
|
this.openedDoubleQuote = false; // Track most recently observed quotes.
|
|
62
62
|
this.metadata = {
|
|
63
|
-
symbols: {}
|
|
63
|
+
symbols: {},
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
static preprocessSymbols(book, text) {
|
|
@@ -69,46 +69,19 @@ export default class Parser {
|
|
|
69
69
|
for (const [symbol, definition] of Object.entries(book.getSymbols())) {
|
|
70
70
|
// Don't replace escaped at symbols. Otherwise, be liberal in replacing any matching symbol that starts with the symbol
|
|
71
71
|
// name and ends with a word boundary.
|
|
72
|
-
text = text.replace(new RegExp(
|
|
72
|
+
text = text.replace(new RegExp('([^\\\\])@' + symbol + '\\b', 'g'), '$1' + definition);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
return text;
|
|
76
76
|
}
|
|
77
77
|
static parseChapter(book, text) {
|
|
78
|
-
return
|
|
78
|
+
return new Parser(book, book === undefined ? text : Parser.preprocessSymbols(book, text)).parseChapter();
|
|
79
79
|
}
|
|
80
80
|
static parseFormat(book, text) {
|
|
81
|
-
return
|
|
81
|
+
return new Parser(book, book === undefined ? text : Parser.preprocessSymbols(book, text)).parseFormat();
|
|
82
82
|
}
|
|
83
83
|
static parseEmbed(book, text) {
|
|
84
|
-
return
|
|
85
|
-
}
|
|
86
|
-
static parseReference(citationID, ref, edition, short = false) {
|
|
87
|
-
if (typeof ref === "string")
|
|
88
|
-
return Parser.parseFormat(edition, ref);
|
|
89
|
-
else if (Array.isArray(ref)) {
|
|
90
|
-
// APA Format. Could eventually support multiple formats.
|
|
91
|
-
if (ref.length >= 4) {
|
|
92
|
-
let authors = ref[0];
|
|
93
|
-
let year = ref[1];
|
|
94
|
-
let title = ref[2];
|
|
95
|
-
let source = ref[3];
|
|
96
|
-
let url = ref.length === 5 ? ref[4] : "";
|
|
97
|
-
let summary = ref.length === 6 ? ref[5] : "";
|
|
98
|
-
if (source.charAt(0) === "#") {
|
|
99
|
-
let src = edition.getSource(source);
|
|
100
|
-
if (src === null)
|
|
101
|
-
return new ErrorNode(undefined, "Unknown source " + source);
|
|
102
|
-
else
|
|
103
|
-
source = src;
|
|
104
|
-
}
|
|
105
|
-
return new ReferenceNode(citationID, authors, year, title, source, url, summary, short);
|
|
106
|
-
}
|
|
107
|
-
else
|
|
108
|
-
return new ErrorNode(undefined, "Expected at least 4 items in the reference array, but found " + ref.length + ": " + ref.toString());
|
|
109
|
-
}
|
|
110
|
-
else
|
|
111
|
-
return new ErrorNode(undefined, "Invalid reference: " + ref);
|
|
84
|
+
return new Parser(book, book === undefined ? text : Parser.preprocessSymbols(book, text)).parseEmbed();
|
|
112
85
|
}
|
|
113
86
|
// Get the next character, if there is one, null otherwise.
|
|
114
87
|
peek() {
|
|
@@ -118,37 +91,50 @@ export default class Parser {
|
|
|
118
91
|
more() {
|
|
119
92
|
return this.index < this.text.length;
|
|
120
93
|
}
|
|
94
|
+
nextIsEmptyParagraph() {
|
|
95
|
+
return (this.text.charAt(this.index) === '\n' &&
|
|
96
|
+
this.text.charAt(this.index + 1) === '\n' &&
|
|
97
|
+
this.text.charAt(this.index + 2) === '\n');
|
|
98
|
+
}
|
|
99
|
+
nextIsWhitespace() {
|
|
100
|
+
return ((this.peek() === ' ' ||
|
|
101
|
+
this.peek() === '\t' ||
|
|
102
|
+
this.peek() === '\n') &&
|
|
103
|
+
!this.nextIsEmptyParagraph());
|
|
104
|
+
}
|
|
121
105
|
// Return the current character--if there is one-- and increment the index.
|
|
122
106
|
read(smarten = true) {
|
|
123
107
|
if (!this.more())
|
|
124
108
|
return null;
|
|
125
109
|
let char = this.text.charAt(this.index);
|
|
126
110
|
if (smarten) {
|
|
127
|
-
if (char ===
|
|
111
|
+
if (char === '\n')
|
|
128
112
|
this.openedDoubleQuote = false;
|
|
129
113
|
// As we read, replace straight quotes with smart quotes.
|
|
130
114
|
if (char === '"') {
|
|
131
115
|
// Replace left quotes after whitespace.
|
|
132
116
|
if (this.openedDoubleQuote) {
|
|
133
|
-
char =
|
|
117
|
+
char = '\u201d';
|
|
134
118
|
}
|
|
135
119
|
else {
|
|
136
|
-
char =
|
|
120
|
+
char = '\u201c';
|
|
137
121
|
}
|
|
138
122
|
this.openedDoubleQuote = !this.openedDoubleQuote;
|
|
139
123
|
}
|
|
140
124
|
else if (char === "'") {
|
|
141
125
|
// If there's whitespace before this, it's a left single quote.
|
|
142
126
|
if (/\s/.test(this.text.charAt(this.index - 1)))
|
|
143
|
-
char =
|
|
127
|
+
char = '\u2018';
|
|
144
128
|
// Otherwise, it's a right single quote.
|
|
145
129
|
else {
|
|
146
|
-
char =
|
|
130
|
+
char = '\u2019';
|
|
147
131
|
}
|
|
148
132
|
}
|
|
149
|
-
if (char === '-' &&
|
|
133
|
+
if (char === '-' &&
|
|
134
|
+
this.text.charAt(this.index + 1) === '-' &&
|
|
135
|
+
this.text.charAt(this.index) !== '\n') {
|
|
150
136
|
this.index++;
|
|
151
|
-
char =
|
|
137
|
+
char = '\u2014';
|
|
152
138
|
}
|
|
153
139
|
}
|
|
154
140
|
// Advance to the next character in the document.
|
|
@@ -168,11 +154,13 @@ export default class Parser {
|
|
|
168
154
|
}
|
|
169
155
|
// The character after
|
|
170
156
|
charAfterNext() {
|
|
171
|
-
return this.index === this.text.length - 1
|
|
157
|
+
return this.index === this.text.length - 1
|
|
158
|
+
? null
|
|
159
|
+
: this.text.charAt(this.index + 1);
|
|
172
160
|
}
|
|
173
161
|
// All the text until the next newline
|
|
174
162
|
restOfLine() {
|
|
175
|
-
const nextNewline = this.text.substring(this.index).indexOf(
|
|
163
|
+
const nextNewline = this.text.substring(this.index).indexOf('\n') + this.index;
|
|
176
164
|
if (nextNewline < 0)
|
|
177
165
|
return this.text.substring(this.index);
|
|
178
166
|
else
|
|
@@ -182,25 +170,27 @@ export default class Parser {
|
|
|
182
170
|
nextIs(text) {
|
|
183
171
|
if (!this.more())
|
|
184
172
|
return false;
|
|
185
|
-
return this.text.substring(this.index, this.index + text.length) === text;
|
|
173
|
+
return (this.text.substring(this.index, this.index + text.length) === text);
|
|
186
174
|
}
|
|
187
175
|
// A critical list that tells inline formatting parsers to stop being greedy.
|
|
188
176
|
nextIsContentDelimiter() {
|
|
189
177
|
const next = this.peek();
|
|
190
178
|
const charAfterNext = this.charAfterNext();
|
|
191
|
-
return next ===
|
|
192
|
-
next ===
|
|
193
|
-
next ===
|
|
194
|
-
next ===
|
|
195
|
-
next ===
|
|
196
|
-
next ===
|
|
197
|
-
(next ===
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
next ===
|
|
201
|
-
|
|
202
|
-
next ===
|
|
203
|
-
next ===
|
|
179
|
+
return (next === '\n' ||
|
|
180
|
+
next === '_' ||
|
|
181
|
+
next === '*' ||
|
|
182
|
+
next === '`' ||
|
|
183
|
+
next === '@' ||
|
|
184
|
+
next === '~' ||
|
|
185
|
+
(next === ':' &&
|
|
186
|
+
charAfterNext !== null &&
|
|
187
|
+
charAfterNext.match(/[a-z]/i) !== null) ||
|
|
188
|
+
next === '^' ||
|
|
189
|
+
next === '<' ||
|
|
190
|
+
next === '{' ||
|
|
191
|
+
(this.charBeforeNext() === ' ' && next === '%') ||
|
|
192
|
+
next === '[' ||
|
|
193
|
+
next === '\\');
|
|
204
194
|
}
|
|
205
195
|
// True if the next part of this string matches the given regular expression.
|
|
206
196
|
nextMatches(regex) {
|
|
@@ -210,7 +200,7 @@ export default class Parser {
|
|
|
210
200
|
}
|
|
211
201
|
// Returns true if all of the text between the current character and the next newline is whitespace.
|
|
212
202
|
isBlankLine() {
|
|
213
|
-
return this.restOfLine().trim() ===
|
|
203
|
+
return this.restOfLine().trim() === '';
|
|
214
204
|
}
|
|
215
205
|
// Read until encountering something other than a tab or a space.
|
|
216
206
|
readWhitespace() {
|
|
@@ -222,15 +212,15 @@ export default class Parser {
|
|
|
222
212
|
}
|
|
223
213
|
// Read until the end of the line.
|
|
224
214
|
readUntilNewLine() {
|
|
225
|
-
let text =
|
|
226
|
-
while (this.more() && this.peek() !==
|
|
215
|
+
let text = '';
|
|
216
|
+
while (this.more() && this.peek() !== '\n')
|
|
227
217
|
text = text + this.read();
|
|
228
218
|
return text;
|
|
229
219
|
}
|
|
230
220
|
// Read until encountering the given string and return the read text.
|
|
231
221
|
readUntilNewlineOr(string) {
|
|
232
|
-
let text =
|
|
233
|
-
while (this.more() && !this.nextIs(
|
|
222
|
+
let text = '';
|
|
223
|
+
while (this.more() && !this.nextIs('\n') && !this.nextIs(string))
|
|
234
224
|
text = text + this.read();
|
|
235
225
|
return text;
|
|
236
226
|
}
|
|
@@ -243,7 +233,7 @@ export default class Parser {
|
|
|
243
233
|
let rest = this.rest();
|
|
244
234
|
// First, replace any occurrences of the symbol with the symbol's text.
|
|
245
235
|
for (const [symbol, text] of Object.entries(this.metadata.symbols)) {
|
|
246
|
-
rest = rest.replace(new RegExp(
|
|
236
|
+
rest = rest.replace(new RegExp('([^\\\\])@' + symbol + '\\b', 'g'), '$1' + text);
|
|
247
237
|
}
|
|
248
238
|
// Replace all of the remaining symbols using book symbol definitions.
|
|
249
239
|
if (this.book)
|
|
@@ -254,11 +244,11 @@ export default class Parser {
|
|
|
254
244
|
let trailingNewlines = 0;
|
|
255
245
|
while (this.more()) {
|
|
256
246
|
trailingNewlines = 0;
|
|
257
|
-
// Read a
|
|
247
|
+
// Read a block and add it to the list if we parsed something.
|
|
258
248
|
blocks.push(this.parseBlock());
|
|
259
249
|
// Read whitespace until we find the next thing.
|
|
260
|
-
while (this.
|
|
261
|
-
if (this.peek() ===
|
|
250
|
+
while (this.nextIsWhitespace()) {
|
|
251
|
+
if (this.peek() === '\n')
|
|
262
252
|
trailingNewlines++;
|
|
263
253
|
this.read();
|
|
264
254
|
}
|
|
@@ -273,22 +263,24 @@ export default class Parser {
|
|
|
273
263
|
// Read whitespace before the symbols
|
|
274
264
|
this.readWhitespace();
|
|
275
265
|
// Keep reading symbols
|
|
276
|
-
while (this.nextIs(
|
|
266
|
+
while (this.nextIs('@')) {
|
|
277
267
|
// Read the @
|
|
278
268
|
this.read();
|
|
279
269
|
// Read the name.
|
|
280
|
-
let name = this.readUntilNewlineOr(
|
|
270
|
+
let name = this.readUntilNewlineOr(':');
|
|
281
271
|
// Names need to be letter and numbers only.
|
|
282
272
|
if (!/^[a-zA-Z0-9]+$/.test(name)) {
|
|
283
|
-
new ErrorNode(this.readUntilNewLine(), name.trim() ===
|
|
284
|
-
|
|
285
|
-
"'" +
|
|
273
|
+
new ErrorNode(this.readUntilNewLine(), name.trim() === ''
|
|
274
|
+
? 'Did you mean to declare a symbol? Use an @ symbol, then a name of only numbers and letters, then a colon, then whatever content you want it to represent.'
|
|
275
|
+
: "'" +
|
|
276
|
+
name +
|
|
277
|
+
"' isn't a valid name for a symbol; letters and numbers only");
|
|
286
278
|
return;
|
|
287
279
|
}
|
|
288
280
|
// Read any whitespace until the colon.
|
|
289
281
|
this.readWhitespace();
|
|
290
282
|
// Name declarations need to be terminated with a colon before the block starts.
|
|
291
|
-
if (!this.nextIs(
|
|
283
|
+
if (!this.nextIs(':')) {
|
|
292
284
|
new ErrorNode(this.readUntilNewLine(), "Symbol names are to be followed by a ':'");
|
|
293
285
|
return;
|
|
294
286
|
}
|
|
@@ -301,27 +293,27 @@ export default class Parser {
|
|
|
301
293
|
// Parse a block, any block.
|
|
302
294
|
this.parseBlock();
|
|
303
295
|
// Remember the text we parsed.
|
|
304
|
-
this.metadata.symbols[name] = this.text
|
|
296
|
+
this.metadata.symbols[name] = this.text
|
|
297
|
+
.substring(startIndex, this.index)
|
|
298
|
+
.trim();
|
|
305
299
|
// Read whitespace until we find the next non-whitespace thing.
|
|
306
|
-
while (this.
|
|
300
|
+
while (this.nextIsWhitespace())
|
|
307
301
|
this.read();
|
|
308
302
|
}
|
|
309
303
|
}
|
|
310
304
|
parseBlock() {
|
|
311
|
-
// Read whitespace before the block.
|
|
312
|
-
this.readWhitespace();
|
|
313
305
|
// Read comment lines
|
|
314
|
-
while (this.nextIs(
|
|
306
|
+
while (this.nextIs('%')) {
|
|
315
307
|
this.readUntilNewLine();
|
|
316
308
|
}
|
|
317
309
|
// Parse and return a header if it starts with a hash
|
|
318
|
-
if (this.nextIs(
|
|
310
|
+
if (this.nextIs('#'))
|
|
319
311
|
return this.parseHeader();
|
|
320
312
|
// Parse and return a horizontal rule if it starts with a dash
|
|
321
|
-
else if (this.nextIs(
|
|
313
|
+
else if (this.nextIs('-'))
|
|
322
314
|
return this.parseRule();
|
|
323
315
|
// Parse and return an embed if it starts with a bar
|
|
324
|
-
else if (this.nextIs(
|
|
316
|
+
else if (this.nextIs('|'))
|
|
325
317
|
return this.parseEmbed();
|
|
326
318
|
// Parse and return a bulleted or numbered list
|
|
327
319
|
else if (this.nextMatches(bulletRE) || this.nextMatches(numberedRE))
|
|
@@ -336,19 +328,25 @@ export default class Parser {
|
|
|
336
328
|
else if (this.nextMatches(/^=[ \t]*\n/))
|
|
337
329
|
return this.parseCallout();
|
|
338
330
|
// Parse and return a table if the line starts with a ,
|
|
339
|
-
else if (this.nextIs(
|
|
331
|
+
else if (this.nextIs(','))
|
|
340
332
|
return this.parseTable();
|
|
341
333
|
// Parse the text as paragraph;
|
|
342
334
|
else
|
|
343
335
|
return this.parseParagraph();
|
|
344
336
|
}
|
|
345
337
|
parseParagraph() {
|
|
346
|
-
|
|
338
|
+
if (this.nextIsEmptyParagraph()) {
|
|
339
|
+
this.read();
|
|
340
|
+
this.read();
|
|
341
|
+
return new ParagraphNode(0, new FormatNode('', [new TextNode()]));
|
|
342
|
+
}
|
|
343
|
+
else
|
|
344
|
+
return new ParagraphNode(0, this.parseFormat());
|
|
347
345
|
}
|
|
348
346
|
parseHeader() {
|
|
349
347
|
// Read a sequence of hashes
|
|
350
348
|
let count = 0;
|
|
351
|
-
while (this.nextIs(
|
|
349
|
+
while (this.nextIs('#')) {
|
|
352
350
|
this.read();
|
|
353
351
|
count++;
|
|
354
352
|
}
|
|
@@ -378,10 +376,10 @@ export default class Parser {
|
|
|
378
376
|
if (numbered) {
|
|
379
377
|
// Read the digits and remember how many there were so we can backtrack.
|
|
380
378
|
digits = this.index;
|
|
381
|
-
this.readUntilNewlineOr(
|
|
379
|
+
this.readUntilNewlineOr('.');
|
|
382
380
|
digits = this.index - digits;
|
|
383
381
|
// Figure out this level.
|
|
384
|
-
while (this.nextIs(
|
|
382
|
+
while (this.nextIs('.')) {
|
|
385
383
|
this.read();
|
|
386
384
|
currentLevel++;
|
|
387
385
|
}
|
|
@@ -389,7 +387,7 @@ export default class Parser {
|
|
|
389
387
|
else {
|
|
390
388
|
// Figure out this level.
|
|
391
389
|
currentLevel = 0;
|
|
392
|
-
while (this.nextIs(
|
|
390
|
+
while (this.nextIs('*')) {
|
|
393
391
|
this.read();
|
|
394
392
|
currentLevel++;
|
|
395
393
|
}
|
|
@@ -400,7 +398,9 @@ export default class Parser {
|
|
|
400
398
|
this.readWhitespace();
|
|
401
399
|
// Parse content after the bullet.
|
|
402
400
|
const format = this.parseFormat();
|
|
403
|
-
items.push(format.isEmpty()
|
|
401
|
+
items.push(format.isEmpty()
|
|
402
|
+
? format.withSegmentAppended(new TextNode())
|
|
403
|
+
: format);
|
|
404
404
|
}
|
|
405
405
|
// Otherwise, unread the stars, then either stop parsing or parse nested list.
|
|
406
406
|
else {
|
|
@@ -427,14 +427,17 @@ export default class Parser {
|
|
|
427
427
|
currentLevel = lastLevel;
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
|
-
// Read trailing whitespace and newlines.
|
|
430
|
+
// Read trailing whitespace and newlines.
|
|
431
431
|
this.readWhitespace();
|
|
432
|
-
while (this.
|
|
432
|
+
while (this.nextIsWhitespace()) {
|
|
433
433
|
// Read the newline
|
|
434
434
|
this.read();
|
|
435
435
|
// Read whitespace before the next block.
|
|
436
436
|
this.readWhitespace();
|
|
437
437
|
}
|
|
438
|
+
// Stop if we reach an empty paragraph.
|
|
439
|
+
if (this.nextIsEmptyParagraph())
|
|
440
|
+
break;
|
|
438
441
|
}
|
|
439
442
|
return new ListNode(items, numbered);
|
|
440
443
|
}
|
|
@@ -446,13 +449,13 @@ export default class Parser {
|
|
|
446
449
|
// Read the newline
|
|
447
450
|
this.read();
|
|
448
451
|
// Read until we encounter a closing back tick.
|
|
449
|
-
let code =
|
|
450
|
-
while (this.more() && !this.nextIs(
|
|
452
|
+
let code = '';
|
|
453
|
+
while (this.more() && !this.nextIs('`')) {
|
|
451
454
|
let next = this.read(false);
|
|
452
|
-
if (next ===
|
|
453
|
-
if (this.nextIs(
|
|
455
|
+
if (next === '\\') {
|
|
456
|
+
if (this.nextIs('`')) {
|
|
454
457
|
this.read();
|
|
455
|
-
next =
|
|
458
|
+
next = '`';
|
|
456
459
|
}
|
|
457
460
|
}
|
|
458
461
|
code = code + next;
|
|
@@ -460,23 +463,23 @@ export default class Parser {
|
|
|
460
463
|
// Trim the code.
|
|
461
464
|
code = code.trim();
|
|
462
465
|
// Read the backtick.
|
|
463
|
-
if (this.nextIs(
|
|
466
|
+
if (this.nextIs('`'))
|
|
464
467
|
this.read();
|
|
465
468
|
let position = this.parsePosition();
|
|
466
|
-
// Read the caption. Note that parsing inline content stops at a newline,
|
|
469
|
+
// Read the caption. Note that parsing inline content stops at a newline,
|
|
467
470
|
// so if there's a line break after the last row, there won't be a caption.
|
|
468
471
|
const caption = this.parseFormat();
|
|
469
472
|
return new CodeNode(new TextNode(code), language, position, caption);
|
|
470
473
|
}
|
|
471
474
|
parsePosition() {
|
|
472
|
-
let position =
|
|
475
|
+
let position = '|';
|
|
473
476
|
// Is there a position indicator?
|
|
474
|
-
if (this.nextIs(
|
|
475
|
-
position =
|
|
477
|
+
if (this.nextIs('<')) {
|
|
478
|
+
position = '<';
|
|
476
479
|
this.read();
|
|
477
480
|
}
|
|
478
|
-
else if (this.nextIs(
|
|
479
|
-
position =
|
|
481
|
+
else if (this.nextIs('>')) {
|
|
482
|
+
position = '>';
|
|
480
483
|
this.read();
|
|
481
484
|
}
|
|
482
485
|
return position;
|
|
@@ -489,14 +492,14 @@ export default class Parser {
|
|
|
489
492
|
this.readWhitespace();
|
|
490
493
|
// Then read the newline.
|
|
491
494
|
this.read();
|
|
492
|
-
while (this.more() && !this.nextIs("
|
|
495
|
+
while (this.more() && !this.nextIs('"')) {
|
|
493
496
|
// Read a block
|
|
494
497
|
const block = this.parseBlock();
|
|
495
498
|
// Add it to the list if we parsed something.
|
|
496
499
|
if (block !== null)
|
|
497
500
|
blocks.push(block);
|
|
498
501
|
// Read whitespace until we find the next thing.
|
|
499
|
-
while (this.
|
|
502
|
+
while (this.nextIsWhitespace())
|
|
500
503
|
this.read();
|
|
501
504
|
}
|
|
502
505
|
// Read the closing " and the whitespace that follows.
|
|
@@ -506,7 +509,7 @@ export default class Parser {
|
|
|
506
509
|
// Read any whitespace after the position indicator.
|
|
507
510
|
this.readWhitespace();
|
|
508
511
|
// Read the credit.
|
|
509
|
-
const credit = this.nextIs(
|
|
512
|
+
const credit = this.nextIs('\n') ? undefined : this.parseFormat();
|
|
510
513
|
return new QuoteNode(blocks, credit, position);
|
|
511
514
|
}
|
|
512
515
|
parseCallout() {
|
|
@@ -518,14 +521,16 @@ export default class Parser {
|
|
|
518
521
|
// ...then read the newline.
|
|
519
522
|
this.read();
|
|
520
523
|
// Then, read until we find a closing _
|
|
521
|
-
while (this.more() && !this.nextIs(
|
|
524
|
+
while (this.more() && !this.nextIs('=')) {
|
|
522
525
|
// Read a block
|
|
523
526
|
const block = this.parseBlock();
|
|
524
527
|
// Add it to the list if we parsed something.
|
|
525
528
|
if (block !== null)
|
|
526
529
|
blocks.push(block);
|
|
527
530
|
// Read whitespace until we find the next thing.
|
|
528
|
-
while (this.peek() ===
|
|
531
|
+
while (this.peek() === ' ' ||
|
|
532
|
+
this.peek() === '\t' ||
|
|
533
|
+
this.peek() === '\n')
|
|
529
534
|
this.read();
|
|
530
535
|
}
|
|
531
536
|
// Read the closing =
|
|
@@ -535,29 +540,28 @@ export default class Parser {
|
|
|
535
540
|
// Read whitespace that follows.
|
|
536
541
|
this.readWhitespace();
|
|
537
542
|
return new CalloutNode(blocks, position);
|
|
538
|
-
;
|
|
539
543
|
}
|
|
540
544
|
parseTable() {
|
|
541
545
|
const rows = [];
|
|
542
546
|
// Parse rows until the lines stop starting with ,
|
|
543
|
-
while (this.more() && this.nextIs(
|
|
547
|
+
while (this.more() && this.nextIs(',')) {
|
|
544
548
|
let row = [];
|
|
545
|
-
while (this.more() && !this.nextIs(
|
|
549
|
+
while (this.more() && !this.nextIs('\n')) {
|
|
546
550
|
// Read the starting , or next |
|
|
547
551
|
this.read();
|
|
548
552
|
// Read whitespace that follows.
|
|
549
553
|
this.readWhitespace();
|
|
550
554
|
// Read content until reaching another | or the end of the line.
|
|
551
|
-
row.push(this.parseFormat(
|
|
555
|
+
row.push(this.parseFormat('|'));
|
|
552
556
|
}
|
|
553
557
|
// Add the row.
|
|
554
558
|
rows.push(row);
|
|
555
559
|
// Read the newline
|
|
556
560
|
this.read();
|
|
557
561
|
}
|
|
558
|
-
// Read the position indicator if there is one.
|
|
562
|
+
// Read the position indicator if there is one.
|
|
559
563
|
const position = this.parsePosition();
|
|
560
|
-
// Read the caption. Note that parsing inline content stops at a newline,
|
|
564
|
+
// Read the caption. Note that parsing inline content stops at a newline,
|
|
561
565
|
// so if there's a line break after the last row, there won't be a caption.
|
|
562
566
|
const caption = this.parseFormat();
|
|
563
567
|
// Return the new table.
|
|
@@ -568,38 +572,38 @@ export default class Parser {
|
|
|
568
572
|
parseFormat(awaiting) {
|
|
569
573
|
const segments = [];
|
|
570
574
|
// Read until hitting a delimiter.
|
|
571
|
-
while (this.more() && !this.nextIs(
|
|
575
|
+
while (this.more() && !this.nextIs('\n')) {
|
|
572
576
|
const next = this.peek();
|
|
573
577
|
const charAfterNext = this.charAfterNext();
|
|
574
578
|
// Parse some bold, italic, subscript, superscript
|
|
575
|
-
if (next ===
|
|
579
|
+
if (next === '_' || next === '*' || next === '^')
|
|
576
580
|
segments.push(this.parseStyle(next));
|
|
577
581
|
// Parse unformatted text
|
|
578
|
-
else if (this.nextIs(
|
|
582
|
+
else if (this.nextIs('`'))
|
|
579
583
|
segments.push(this.parseInlineCode());
|
|
580
584
|
// Parse a citation list
|
|
581
|
-
else if (this.nextIs(
|
|
585
|
+
else if (this.nextIs('<'))
|
|
582
586
|
segments.push(this.parseCitations());
|
|
583
587
|
// Parse a footnote
|
|
584
|
-
else if (this.nextIs(
|
|
588
|
+
else if (this.nextIs('{'))
|
|
585
589
|
segments.push(this.parseFootnote());
|
|
586
590
|
// Parse a definition
|
|
587
|
-
else if (this.nextIs(
|
|
591
|
+
else if (this.nextIs('~'))
|
|
588
592
|
segments.push(this.parseDefinition());
|
|
589
593
|
// Parse an escaped character
|
|
590
|
-
else if (this.nextIs(
|
|
594
|
+
else if (this.nextIs('\\'))
|
|
591
595
|
segments.push(this.parseEscaped());
|
|
592
596
|
// Parse a link
|
|
593
|
-
else if (this.nextIs(
|
|
597
|
+
else if (this.nextIs('['))
|
|
594
598
|
segments.push(this.parseLink());
|
|
595
599
|
// Parse inline comments
|
|
596
|
-
else if (this.charBeforeNext() ===
|
|
600
|
+
else if (this.charBeforeNext() === ' ' && this.nextIs('%'))
|
|
597
601
|
segments.push(this.parseComment());
|
|
598
602
|
// Parse an unresolved symbol
|
|
599
|
-
else if (next ===
|
|
603
|
+
else if (next === '@') {
|
|
600
604
|
// Read the @, then the symbol name.
|
|
601
605
|
this.read();
|
|
602
|
-
let symbol =
|
|
606
|
+
let symbol = '';
|
|
603
607
|
// Stop at the end of the name or file.
|
|
604
608
|
let next = this.peek();
|
|
605
609
|
while (next !== null && /[a-zA-Z0-9]/.test(next)) {
|
|
@@ -609,13 +613,18 @@ export default class Parser {
|
|
|
609
613
|
segments.push(new ErrorNode(undefined, "Couldn't find symbol @" + symbol));
|
|
610
614
|
}
|
|
611
615
|
// Parse a label
|
|
612
|
-
else if (next ===
|
|
616
|
+
else if (next === ':' &&
|
|
617
|
+
charAfterNext !== null &&
|
|
618
|
+
charAfterNext.match(/[a-z]/i)) {
|
|
613
619
|
segments.push(this.parseLabel());
|
|
614
620
|
}
|
|
615
621
|
// Keep reading text until finding a delimiter.
|
|
616
622
|
else {
|
|
617
|
-
let text =
|
|
618
|
-
while (this.more() &&
|
|
623
|
+
let text = '';
|
|
624
|
+
while (this.more() &&
|
|
625
|
+
(!awaiting || !this.nextIs(awaiting)) &&
|
|
626
|
+
!this.nextIsContentDelimiter() &&
|
|
627
|
+
!this.nextIs('\n'))
|
|
619
628
|
text = text + this.read();
|
|
620
629
|
segments.push(new TextNode(text));
|
|
621
630
|
}
|
|
@@ -623,47 +632,49 @@ export default class Parser {
|
|
|
623
632
|
if (this.peek() === awaiting)
|
|
624
633
|
break;
|
|
625
634
|
}
|
|
626
|
-
return new FormatNode(
|
|
635
|
+
return new FormatNode('', segments);
|
|
627
636
|
}
|
|
628
637
|
parseEmbed() {
|
|
629
638
|
// Read |
|
|
630
639
|
this.read();
|
|
631
640
|
// Read the URL
|
|
632
|
-
const url = this.readUntilNewlineOr(
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
this.
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
641
|
+
const url = this.readUntilNewlineOr('|');
|
|
642
|
+
let description;
|
|
643
|
+
let caption;
|
|
644
|
+
let credit;
|
|
645
|
+
if (this.peek() === '|') {
|
|
646
|
+
// Read a |
|
|
647
|
+
this.read();
|
|
648
|
+
// Read the description
|
|
649
|
+
description = this.readUntilNewlineOr('|');
|
|
650
|
+
if (this.peek() === '|') {
|
|
651
|
+
// Read a |
|
|
652
|
+
this.read();
|
|
653
|
+
// Parse the caption
|
|
654
|
+
caption = this.parseFormat('|');
|
|
655
|
+
if (this.peek() === '|') {
|
|
656
|
+
// Read a |
|
|
657
|
+
this.read();
|
|
658
|
+
// Parse the credit
|
|
659
|
+
credit = this.parseFormat('|');
|
|
660
|
+
// Check for the closing delimeter
|
|
661
|
+
if (this.peek() === '|')
|
|
662
|
+
// Read a |
|
|
663
|
+
this.read();
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
656
667
|
// Is there a position indicator?
|
|
657
668
|
const position = this.parsePosition();
|
|
658
|
-
return new EmbedNode(url, description, caption, credit, position);
|
|
669
|
+
return new EmbedNode(url, description ?? '', caption, credit, position);
|
|
659
670
|
}
|
|
660
671
|
parseComment() {
|
|
661
672
|
// Consume the opening %
|
|
662
673
|
this.read();
|
|
663
674
|
// Consume everything until the next %.
|
|
664
|
-
const comment = this.parseFormat(
|
|
675
|
+
const comment = this.parseFormat('%');
|
|
665
676
|
// Consume the closing %, if we didn't reach the end of input or a newline.
|
|
666
|
-
if (this.peek() ===
|
|
677
|
+
if (this.peek() === '%')
|
|
667
678
|
this.read();
|
|
668
679
|
return new CommentNode(comment);
|
|
669
680
|
}
|
|
@@ -671,7 +682,7 @@ export default class Parser {
|
|
|
671
682
|
// Consume the :
|
|
672
683
|
this.read();
|
|
673
684
|
// Consume everything until it's not a letter.
|
|
674
|
-
let id =
|
|
685
|
+
let id = '';
|
|
675
686
|
let next = this.peek();
|
|
676
687
|
while (next !== null && next.match(/[a-z]/i)) {
|
|
677
688
|
id = id + this.read();
|
|
@@ -684,26 +695,26 @@ export default class Parser {
|
|
|
684
695
|
const delimeter = this.read();
|
|
685
696
|
let subscript = false;
|
|
686
697
|
const segments = [];
|
|
687
|
-
let text =
|
|
698
|
+
let text = '';
|
|
688
699
|
// Special case subscript, which has an extra delimeter.
|
|
689
|
-
if (this.peek() ===
|
|
700
|
+
if (delimeter === '^' && this.peek() === 'v') {
|
|
690
701
|
this.read();
|
|
691
702
|
subscript = true;
|
|
692
703
|
}
|
|
693
704
|
if (delimeter === null)
|
|
694
|
-
return new ErrorNode(undefined,
|
|
705
|
+
return new ErrorNode(undefined, 'Somehow parsing formatted text at end of file.');
|
|
695
706
|
// Read some content until reaching the delimiter or the end of the line
|
|
696
|
-
while (this.more() && this.peek() !== delimeter && !this.nextIs(
|
|
697
|
-
// If this is more formatted text, make a text node with whatever we've accumulated so far,
|
|
707
|
+
while (this.more() && this.peek() !== delimeter && !this.nextIs('\n')) {
|
|
708
|
+
// If this is more formatted text, make a text node with whatever we've accumulated so far,
|
|
698
709
|
// then parse the formatted text, then reset the accumulator.
|
|
699
710
|
if (this.nextIsContentDelimiter()) {
|
|
700
711
|
// If the text is a non-empty string, make a text node with what we've accumulated.
|
|
701
|
-
if (text !==
|
|
712
|
+
if (text !== '')
|
|
702
713
|
segments.push(new TextNode(text));
|
|
703
714
|
// Parse the formatted content.
|
|
704
715
|
segments.push(this.parseFormat(awaiting));
|
|
705
716
|
// Reset the accumulator.
|
|
706
|
-
text =
|
|
717
|
+
text = '';
|
|
707
718
|
}
|
|
708
719
|
// Add the next character to the accumulator.
|
|
709
720
|
else {
|
|
@@ -711,36 +722,36 @@ export default class Parser {
|
|
|
711
722
|
}
|
|
712
723
|
}
|
|
713
724
|
// If there's more text, save it!
|
|
714
|
-
if (text !==
|
|
725
|
+
if (text !== '')
|
|
715
726
|
segments.push(new TextNode(text));
|
|
716
727
|
// Read the closing delimeter
|
|
717
728
|
if (this.nextIs(delimeter))
|
|
718
729
|
this.read();
|
|
719
730
|
// If it wasn't closed, add an error
|
|
720
731
|
else
|
|
721
|
-
segments.push(new ErrorNode(undefined,
|
|
722
|
-
return new FormatNode(subscript ?
|
|
732
|
+
segments.push(new ErrorNode(undefined, 'Unclosed ' + delimeter));
|
|
733
|
+
return new FormatNode(subscript ? 'v' : delimeter, segments);
|
|
723
734
|
}
|
|
724
735
|
parseInlineCode() {
|
|
725
736
|
// Parse the back tick
|
|
726
737
|
this.read();
|
|
727
738
|
// Read until we encounter a closing back tick.
|
|
728
|
-
let code =
|
|
729
|
-
while (this.more() && !this.nextIs(
|
|
739
|
+
let code = '';
|
|
740
|
+
while (this.more() && !this.nextIs('`')) {
|
|
730
741
|
let next = this.read(false);
|
|
731
|
-
if (next ===
|
|
732
|
-
if (this.nextIs(
|
|
742
|
+
if (next === '\\') {
|
|
743
|
+
if (this.nextIs('`')) {
|
|
733
744
|
this.read();
|
|
734
|
-
next =
|
|
745
|
+
next = '`';
|
|
735
746
|
}
|
|
736
747
|
}
|
|
737
748
|
code = code + next;
|
|
738
749
|
}
|
|
739
750
|
// Read the backtick.
|
|
740
|
-
if (this.nextIs(
|
|
751
|
+
if (this.nextIs('`'))
|
|
741
752
|
this.read();
|
|
742
753
|
// If there's a letter immediately after a backtick, it's a language for an inline code name
|
|
743
|
-
let language =
|
|
754
|
+
let language = '';
|
|
744
755
|
let next = this.peek();
|
|
745
756
|
if (next !== null && /^[a-z]$/.test(next)) {
|
|
746
757
|
do {
|
|
@@ -749,26 +760,29 @@ export default class Parser {
|
|
|
749
760
|
} while (next !== null && /^[a-z]$/.test(next));
|
|
750
761
|
}
|
|
751
762
|
else
|
|
752
|
-
language =
|
|
763
|
+
language = 'plaintext';
|
|
753
764
|
return new InlineCodeNode(new TextNode(code), language);
|
|
754
765
|
}
|
|
755
766
|
parseCitations() {
|
|
756
|
-
let citations =
|
|
767
|
+
let citations = '';
|
|
757
768
|
// Read the <
|
|
758
769
|
this.read();
|
|
759
770
|
// Read the citations.
|
|
760
|
-
citations = this.readUntilNewlineOr(
|
|
761
|
-
if (this.peek() ===
|
|
771
|
+
citations = this.readUntilNewlineOr('>');
|
|
772
|
+
if (this.peek() === '>')
|
|
762
773
|
this.read();
|
|
763
774
|
// Trim any whitespace, then split by commas, then remove any empty IDs.
|
|
764
|
-
const citationList = citations
|
|
775
|
+
const citationList = citations
|
|
776
|
+
.split(',')
|
|
777
|
+
.map((citation) => citation.trim())
|
|
778
|
+
.filter((citationID) => citationID.length > 0);
|
|
765
779
|
return new CitationsNode(citationList);
|
|
766
780
|
}
|
|
767
781
|
parseFootnote() {
|
|
768
782
|
// Read the {
|
|
769
783
|
this.read();
|
|
770
784
|
// Read the footnote content.
|
|
771
|
-
const footnote = this.parseFormat(
|
|
785
|
+
const footnote = this.parseFormat('}');
|
|
772
786
|
// Read the closing }
|
|
773
787
|
this.read();
|
|
774
788
|
return new FootnoteNode(footnote);
|
|
@@ -777,11 +791,11 @@ export default class Parser {
|
|
|
777
791
|
// Read the ~
|
|
778
792
|
this.read();
|
|
779
793
|
// Read the phrase
|
|
780
|
-
const text = this.readUntilNewlineOr(
|
|
794
|
+
const text = this.readUntilNewlineOr('~');
|
|
781
795
|
// Read the closing ~
|
|
782
796
|
this.read();
|
|
783
797
|
// Read the glossary entry ID
|
|
784
|
-
let glossaryID =
|
|
798
|
+
let glossaryID = '';
|
|
785
799
|
// Stop at the end of the name or file.
|
|
786
800
|
let next = this.peek();
|
|
787
801
|
while (next !== null && /[a-zA-Z]/.test(next)) {
|
|
@@ -796,26 +810,26 @@ export default class Parser {
|
|
|
796
810
|
const char = this.read();
|
|
797
811
|
if (char)
|
|
798
812
|
return new TextNode(char);
|
|
799
|
-
return new ErrorNode(undefined,
|
|
813
|
+
return new ErrorNode(undefined, 'Unterminated escape.');
|
|
800
814
|
}
|
|
801
815
|
parseLink() {
|
|
802
816
|
// Read the [
|
|
803
817
|
this.read();
|
|
804
818
|
// Read pure text until funding |
|
|
805
|
-
const text = this.readUntilNewlineOr(
|
|
819
|
+
const text = this.readUntilNewlineOr('|');
|
|
806
820
|
// Catch missing bars
|
|
807
|
-
if (this.peek() !==
|
|
821
|
+
if (this.peek() !== '|') {
|
|
808
822
|
this.readUntilNewLine();
|
|
809
823
|
return new ErrorNode(undefined, "Missing '|' in link");
|
|
810
824
|
}
|
|
811
825
|
// Read the |
|
|
812
826
|
this.read();
|
|
813
827
|
// Read the link
|
|
814
|
-
let url = this.readUntilNewlineOr(
|
|
828
|
+
let url = this.readUntilNewlineOr(']');
|
|
815
829
|
// Catch missing closing
|
|
816
|
-
if (this.peek() !==
|
|
830
|
+
if (this.peek() !== ']') {
|
|
817
831
|
this.readUntilNewLine();
|
|
818
|
-
return new ErrorNode(undefined,
|
|
832
|
+
return new ErrorNode(undefined, 'Missing ] in link');
|
|
819
833
|
}
|
|
820
834
|
// Read the ]
|
|
821
835
|
this.read();
|