react-native-marcus 0.1.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/LICENSE +201 -0
- package/README.md +227 -0
- package/RNMarcus.podspec +78 -0
- package/android/build.gradle +220 -0
- package/android/proguard-rules.pro +1 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/cpp/CMakeLists.txt +41 -0
- package/android/src/main/cpp/MarkdownParser.cpp +49 -0
- package/android/src/main/cpp/MarkdownParser.h +56 -0
- package/android/src/main/cpp/OnLoad.cpp +17 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusModule.kt +28 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusPackage.kt +31 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorView.kt +63 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorViewManager.kt +32 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorViewManagerSpec.kt +21 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownFormatter.kt +333 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownParseResult.kt +12 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownParser.kt +89 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownRange.kt +11 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownStyle.kt +81 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownTextWatcher.kt +17 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownUtils.kt +84 -0
- package/android/src/main/java/app/getbullet/marcus/ReactLineHeight.java +29 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundColorSpan.kt +6 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundSpan.kt +105 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBlockIndentSpan.kt +67 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBoldSpan.kt +6 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontFamilySpan.kt +28 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontSizeSpan.kt +7 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownForegroundColorSpan.kt +6 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownGapSpan.kt +57 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownItalicSpan.kt +6 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownLineHeightSpan.kt +21 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownSpan.kt +7 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownStrikethroughSpan.kt +5 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownUnderlineSpan.kt +5 -0
- package/android/src/main/new_arch/CMakeLists.txt +70 -0
- package/android/src/main/new_arch/RNMarcusSpec.cpp +43 -0
- package/android/src/main/new_arch/RNMarcusSpec.h +36 -0
- package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextInputDecoratorShadowNode.cpp +218 -0
- package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextInputDecoratorShadowNode.h +54 -0
- package/android/src/reactNativeVersionPatch/CustomMountingManager/81/app/getbullet/marcus/CustomFabricUIManager.java +156 -0
- package/android/src/reactNativeVersionPatch/CustomMountingManager/latest/app/getbullet/marcus/CustomFabricUIManager.java +130 -0
- package/android/src/test/java/app/getbullet/marcus/MarkdownFormatterTest.kt +205 -0
- package/android/src/test/java/app/getbullet/marcus/RenderModel.kt +78 -0
- package/android/src/test/resources/render-model.txt +583 -0
- package/apple/MarcusModule.h +8 -0
- package/apple/MarcusModule.mm +26 -0
- package/apple/MarcusRange.h +15 -0
- package/apple/MarcusRange.mm +15 -0
- package/apple/MarcusTextInputDecoratorComponentView.h +12 -0
- package/apple/MarcusTextInputDecoratorComponentView.mm +121 -0
- package/apple/MarcusTextInputDecoratorShadowNode.cpp +251 -0
- package/apple/MarcusTextInputDecoratorShadowNode.h +65 -0
- package/apple/MarcusTextInputDecoratorShadowNode.mm +204 -0
- package/apple/MarcusTextInputDecoratorViewManager.h +8 -0
- package/apple/MarcusTextInputDecoratorViewManager.mm +11 -0
- package/apple/MarkdownAdaptiveImageGlyph.swift +44 -0
- package/apple/MarkdownAttributes.h +31 -0
- package/apple/MarkdownAttributes.m +9 -0
- package/apple/MarkdownBackedTextInputDelegate.swift +117 -0
- package/apple/MarkdownDecorator.swift +316 -0
- package/apple/MarkdownFonts.swift +21 -0
- package/apple/MarkdownFormatter+React.swift +51 -0
- package/apple/MarkdownFormatter.swift +509 -0
- package/apple/MarkdownLog.h +10 -0
- package/apple/MarkdownLog.mm +6 -0
- package/apple/MarkdownParser.swift +200 -0
- package/apple/MarkdownSwiftInterop.h +23 -0
- package/apple/MarkdownTextBackground.swift +17 -0
- package/apple/MarkdownTextFieldObserver.swift +90 -0
- package/apple/MarkdownTextLayoutFragment.swift +205 -0
- package/apple/MarkdownTextLayoutManagerDelegate.swift +84 -0
- package/apple/MarkdownTextStorageDelegate.swift +32 -0
- package/apple/MarkdownTextViewObserver.swift +30 -0
- package/apple/RCTMarcusStyle+Codegen.h +18 -0
- package/apple/RCTMarcusStyle+Codegen.mm +64 -0
- package/apple/RCTMarcusStyle.h +41 -0
- package/apple/RCTMarcusStyle.m +5 -0
- package/apple/RCTMarcusUtils.h +26 -0
- package/apple/RCTMarcusUtils.mm +26 -0
- package/apple/RCTTextInput+AdaptiveImageGlyph.h +16 -0
- package/apple/RCTTextInput+AdaptiveImageGlyph.mm +79 -0
- package/apple/RCTTextInputComponentView+Marcus.h +11 -0
- package/apple/RCTTextInputComponentView+Marcus.mm +79 -0
- package/cpp/MarkdownCxx.modulemap +8 -0
- package/cpp/MarkdownGlobal.cpp +48 -0
- package/cpp/MarkdownGlobal.h +33 -0
- package/cpp/MarkdownWorkletParser.cpp +93 -0
- package/cpp/MarkdownWorkletParser.h +45 -0
- package/cpp/RuntimeDecorator.cpp +39 -0
- package/cpp/RuntimeDecorator.h +14 -0
- package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextInputDecoratorState.h +33 -0
- package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextInputDecoratorViewComponentDescriptor.h +17 -0
- package/lib/commonjs/MarcusTextInputDecoratorViewNativeComponent.ts +77 -0
- package/lib/commonjs/MarkdownTextInput.js +99 -0
- package/lib/commonjs/MarkdownTextInput.js.map +1 -0
- package/lib/commonjs/MarkdownTextInput.web.js +618 -0
- package/lib/commonjs/MarkdownTextInput.web.js.map +1 -0
- package/lib/commonjs/NativeMarcusModule.js +9 -0
- package/lib/commonjs/NativeMarcusModule.js.map +1 -0
- package/lib/commonjs/commonTypes.js +2 -0
- package/lib/commonjs/commonTypes.js.map +1 -0
- package/lib/commonjs/global.d.js +2 -0
- package/lib/commonjs/global.d.js.map +1 -0
- package/lib/commonjs/index.js +27 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/parser/index.js +7030 -0
- package/lib/commonjs/parser/index.js.map +7 -0
- package/lib/commonjs/rangeUtils.js +71 -0
- package/lib/commonjs/rangeUtils.js.map +1 -0
- package/lib/commonjs/react-native-web.d.js +2 -0
- package/lib/commonjs/react-native-web.d.js.map +1 -0
- package/lib/commonjs/styleUtils.js +91 -0
- package/lib/commonjs/styleUtils.js.map +1 -0
- package/lib/commonjs/web/InputHistory.js +111 -0
- package/lib/commonjs/web/InputHistory.js.map +1 -0
- package/lib/commonjs/web/MarkdownTextInput.css +72 -0
- package/lib/commonjs/web/utils/blockLayout.js +132 -0
- package/lib/commonjs/web/utils/blockLayout.js.map +1 -0
- package/lib/commonjs/web/utils/blockUtils.js +219 -0
- package/lib/commonjs/web/utils/blockUtils.js.map +1 -0
- package/lib/commonjs/web/utils/browserUtils.js +40 -0
- package/lib/commonjs/web/utils/browserUtils.js.map +1 -0
- package/lib/commonjs/web/utils/cursorUtils.js +157 -0
- package/lib/commonjs/web/utils/cursorUtils.js.map +1 -0
- package/lib/commonjs/web/utils/inputUtils.js +152 -0
- package/lib/commonjs/web/utils/inputUtils.js.map +1 -0
- package/lib/commonjs/web/utils/measureUtils.js +0 -0
- package/lib/commonjs/web/utils/measureUtils.js.map +1 -0
- package/lib/commonjs/web/utils/parserUtils.js +552 -0
- package/lib/commonjs/web/utils/parserUtils.js.map +1 -0
- package/lib/commonjs/web/utils/treeUtils.js +109 -0
- package/lib/commonjs/web/utils/treeUtils.js.map +1 -0
- package/lib/commonjs/web/utils/webStyleUtils.js +59 -0
- package/lib/commonjs/web/utils/webStyleUtils.js.map +1 -0
- package/lib/module/MarcusTextInputDecoratorViewNativeComponent.ts +77 -0
- package/lib/module/MarkdownTextInput.js +94 -0
- package/lib/module/MarkdownTextInput.js.map +1 -0
- package/lib/module/MarkdownTextInput.web.js +612 -0
- package/lib/module/MarkdownTextInput.web.js.map +1 -0
- package/lib/module/NativeMarcusModule.js +5 -0
- package/lib/module/NativeMarcusModule.js.map +1 -0
- package/lib/module/commonTypes.js +2 -0
- package/lib/module/commonTypes.js.map +1 -0
- package/lib/module/global.d.js +2 -0
- package/lib/module/global.d.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/parser/index.js +7029 -0
- package/lib/module/parser/index.js.map +7 -0
- package/lib/module/rangeUtils.js +66 -0
- package/lib/module/rangeUtils.js.map +1 -0
- package/lib/module/react-native-web.d.js +2 -0
- package/lib/module/react-native-web.d.js.map +1 -0
- package/lib/module/styleUtils.js +88 -0
- package/lib/module/styleUtils.js.map +1 -0
- package/lib/module/web/InputHistory.js +106 -0
- package/lib/module/web/InputHistory.js.map +1 -0
- package/lib/module/web/MarkdownTextInput.css +72 -0
- package/lib/module/web/utils/blockLayout.js +128 -0
- package/lib/module/web/utils/blockLayout.js.map +1 -0
- package/lib/module/web/utils/blockUtils.js +210 -0
- package/lib/module/web/utils/blockUtils.js.map +1 -0
- package/lib/module/web/utils/browserUtils.js +36 -0
- package/lib/module/web/utils/browserUtils.js.map +1 -0
- package/lib/module/web/utils/cursorUtils.js +150 -0
- package/lib/module/web/utils/cursorUtils.js.map +1 -0
- package/lib/module/web/utils/inputUtils.js +144 -0
- package/lib/module/web/utils/inputUtils.js.map +1 -0
- package/lib/module/web/utils/measureUtils.js +0 -0
- package/lib/module/web/utils/measureUtils.js.map +1 -0
- package/lib/module/web/utils/parserUtils.js +547 -0
- package/lib/module/web/utils/parserUtils.js.map +1 -0
- package/lib/module/web/utils/treeUtils.js +103 -0
- package/lib/module/web/utils/treeUtils.js.map +1 -0
- package/lib/module/web/utils/webStyleUtils.js +54 -0
- package/lib/module/web/utils/webStyleUtils.js.map +1 -0
- package/lib/typescript/commonjs/e2e/checks.test.d.ts +2 -0
- package/lib/typescript/commonjs/e2e/checks.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/e2e/editing.test.d.ts +2 -0
- package/lib/typescript/commonjs/e2e/editing.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/e2e/helpers.d.ts +23 -0
- package/lib/typescript/commonjs/e2e/helpers.d.ts.map +1 -0
- package/lib/typescript/commonjs/e2e/smoke.test.d.ts +2 -0
- package/lib/typescript/commonjs/e2e/smoke.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +63 -0
- package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts +22 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts +41 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/NativeMarcusModule.d.ts +7 -0
- package/lib/typescript/commonjs/src/NativeMarcusModule.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/commonTypes.d.ts +10 -0
- package/lib/typescript/commonjs/src/commonTypes.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +5 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/parser/index.d.ts +8 -0
- package/lib/typescript/commonjs/src/parser/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/parser/micromark-extension-mentions.d.ts +8 -0
- package/lib/typescript/commonjs/src/parser/micromark-extension-mentions.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/rangeUtils.d.ts +6 -0
- package/lib/typescript/commonjs/src/rangeUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/styleUtils.d.ts +8 -0
- package/lib/typescript/commonjs/src/styleUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/InputHistory.d.ts +24 -0
- package/lib/typescript/commonjs/src/web/InputHistory.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts +41 -0
- package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts +33 -0
- package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/browserUtils.d.ts +7 -0
- package/lib/typescript/commonjs/src/web/utils/browserUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/cursorUtils.d.ts +12 -0
- package/lib/typescript/commonjs/src/web/utils/cursorUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/inputUtils.d.ts +12 -0
- package/lib/typescript/commonjs/src/web/utils/inputUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/measureUtils.d.ts +22 -0
- package/lib/typescript/commonjs/src/web/utils/measureUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts +44 -0
- package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts +25 -0
- package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts +7 -0
- package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts.map +1 -0
- package/lib/typescript/module/e2e/checks.test.d.ts +2 -0
- package/lib/typescript/module/e2e/checks.test.d.ts.map +1 -0
- package/lib/typescript/module/e2e/editing.test.d.ts +2 -0
- package/lib/typescript/module/e2e/editing.test.d.ts.map +1 -0
- package/lib/typescript/module/e2e/helpers.d.ts +23 -0
- package/lib/typescript/module/e2e/helpers.d.ts.map +1 -0
- package/lib/typescript/module/e2e/smoke.test.d.ts +2 -0
- package/lib/typescript/module/e2e/smoke.test.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +63 -0
- package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/MarkdownTextInput.d.ts +22 -0
- package/lib/typescript/module/src/MarkdownTextInput.d.ts.map +1 -0
- package/lib/typescript/module/src/MarkdownTextInput.web.d.ts +41 -0
- package/lib/typescript/module/src/MarkdownTextInput.web.d.ts.map +1 -0
- package/lib/typescript/module/src/NativeMarcusModule.d.ts +7 -0
- package/lib/typescript/module/src/NativeMarcusModule.d.ts.map +1 -0
- package/lib/typescript/module/src/commonTypes.d.ts +10 -0
- package/lib/typescript/module/src/commonTypes.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +5 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/lib/typescript/module/src/parser/index.d.ts +8 -0
- package/lib/typescript/module/src/parser/index.d.ts.map +1 -0
- package/lib/typescript/module/src/parser/micromark-extension-mentions.d.ts +8 -0
- package/lib/typescript/module/src/parser/micromark-extension-mentions.d.ts.map +1 -0
- package/lib/typescript/module/src/rangeUtils.d.ts +6 -0
- package/lib/typescript/module/src/rangeUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/styleUtils.d.ts +8 -0
- package/lib/typescript/module/src/styleUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/InputHistory.d.ts +24 -0
- package/lib/typescript/module/src/web/InputHistory.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/blockLayout.d.ts +41 -0
- package/lib/typescript/module/src/web/utils/blockLayout.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/blockUtils.d.ts +33 -0
- package/lib/typescript/module/src/web/utils/blockUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/browserUtils.d.ts +7 -0
- package/lib/typescript/module/src/web/utils/browserUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/cursorUtils.d.ts +12 -0
- package/lib/typescript/module/src/web/utils/cursorUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/inputUtils.d.ts +12 -0
- package/lib/typescript/module/src/web/utils/inputUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/measureUtils.d.ts +22 -0
- package/lib/typescript/module/src/web/utils/measureUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/parserUtils.d.ts +44 -0
- package/lib/typescript/module/src/web/utils/parserUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/treeUtils.d.ts +25 -0
- package/lib/typescript/module/src/web/utils/treeUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts +7 -0
- package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts.map +1 -0
- package/package.json +167 -0
- package/react-native.config.js +10 -0
- package/src/MarcusTextInputDecoratorViewNativeComponent.ts +77 -0
- package/src/MarkdownTextInput.tsx +139 -0
- package/src/MarkdownTextInput.web.tsx +958 -0
- package/src/NativeMarcusModule.ts +8 -0
- package/src/commonTypes.ts +30 -0
- package/src/global.d.ts +1 -0
- package/src/index.tsx +4 -0
- package/src/parser/index.ts +556 -0
- package/src/parser/micromark-extension-mentions.ts +82 -0
- package/src/rangeUtils.ts +68 -0
- package/src/react-native-web.d.ts +1 -0
- package/src/styleUtils.ts +100 -0
- package/src/web/InputHistory.ts +137 -0
- package/src/web/MarkdownTextInput.css +72 -0
- package/src/web/utils/blockLayout.ts +163 -0
- package/src/web/utils/blockUtils.ts +245 -0
- package/src/web/utils/browserUtils.ts +41 -0
- package/src/web/utils/cursorUtils.ts +204 -0
- package/src/web/utils/inputUtils.ts +206 -0
- package/src/web/utils/measureUtils.ts +0 -0
- package/src/web/utils/parserUtils.ts +813 -0
- package/src/web/utils/treeUtils.ts +149 -0
- package/src/web/utils/webStyleUtils.ts +69 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"worklet"
|
|
2
|
+
|
|
3
|
+
import type { MarkdownRange } from "./commonTypes"
|
|
4
|
+
|
|
5
|
+
// A range is emitted when the construct it belongs to opens, so the parser's order is already
|
|
6
|
+
// containment order: whatever encloses something opened before it. `sortRanges` keeps that order
|
|
7
|
+
// for ranges it cannot separate, which is just as well, because for two containers of the same size
|
|
8
|
+
// the answer is not a property of their types at all -- `> - a` and `- > a` are the same pair over
|
|
9
|
+
// the same line, nested opposite ways.
|
|
10
|
+
//
|
|
11
|
+
// One pairing breaks the rule, deliberately. `flushLine` emits a container's `block-prefix` before
|
|
12
|
+
// the container itself, because the native formatters lay a line out in one left-to-right walk and
|
|
13
|
+
// hand each marker to the container that follows it; the `syntax` inside that marker is emitted
|
|
14
|
+
// earlier still, when the marker's own token opens. Typing a bare `>` therefore produces three
|
|
15
|
+
// ranges over one character, in exactly the wrong order for a tree.
|
|
16
|
+
//
|
|
17
|
+
// This table exists to invert that one pairing, and nothing else: a block container outranks the
|
|
18
|
+
// `block-prefix` holding its marker, which outranks the `syntax` of the marker itself. `heading`
|
|
19
|
+
// sits above the default so it encloses what a heading line contains, and `emoji` below everything
|
|
20
|
+
// because it is always innermost. A container type left out of the table sorts level with the
|
|
21
|
+
// marker it should contain, and the marker then renders once per range -- see
|
|
22
|
+
// `reportAmbiguousNesting`, which is the check for exactly that.
|
|
23
|
+
function getTagPriority(tag: string) {
|
|
24
|
+
switch (tag) {
|
|
25
|
+
case "blockquote":
|
|
26
|
+
case "list-ordered":
|
|
27
|
+
case "list-unordered":
|
|
28
|
+
return 3
|
|
29
|
+
case "block-prefix":
|
|
30
|
+
return 2
|
|
31
|
+
case "heading":
|
|
32
|
+
return 1
|
|
33
|
+
case "emoji":
|
|
34
|
+
return -1
|
|
35
|
+
default:
|
|
36
|
+
return 0
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Sorts into the containment order the web builder nests by: outermost first, and for anything the
|
|
41
|
+
// three keys below cannot separate, the order the parser emitted them in. That last step is load
|
|
42
|
+
// bearing rather than incidental -- `Array.prototype.sort` is required to be stable, and emission
|
|
43
|
+
// order is what decides which of two equally sized containers encloses the other.
|
|
44
|
+
function sortRanges(ranges: MarkdownRange[]) {
|
|
45
|
+
// sort ranges by start position, then by length, then by tag hierarchy
|
|
46
|
+
return ranges.sort(
|
|
47
|
+
(a, b) =>
|
|
48
|
+
a.start - b.start ||
|
|
49
|
+
b.length - a.length ||
|
|
50
|
+
getTagPriority(b.type) - getTagPriority(a.type) ||
|
|
51
|
+
0,
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function ungroupRanges(ranges: MarkdownRange[]): MarkdownRange[] {
|
|
56
|
+
const ungroupedRanges: MarkdownRange[] = []
|
|
57
|
+
ranges.forEach((range) => {
|
|
58
|
+
if (!range.depth) {
|
|
59
|
+
ungroupedRanges.push(range)
|
|
60
|
+
}
|
|
61
|
+
const { depth, ...rangeWithoutDepth } = range
|
|
62
|
+
Array.from({ length: depth! }).forEach(() => {
|
|
63
|
+
ungroupedRanges.push(rangeWithoutDepth)
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
return ungroupedRanges
|
|
67
|
+
}
|
|
68
|
+
export { getTagPriority, sortRanges, ungroupRanges }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module "react-native-web/dist/exports/StyleSheet/compiler/createReactDOMStyle"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Platform } from "react-native"
|
|
2
|
+
import type { MarkdownStyle } from "./MarcusTextInputDecoratorViewNativeComponent"
|
|
3
|
+
|
|
4
|
+
type PartialMarkdownStyle = Partial<{
|
|
5
|
+
[K in keyof MarkdownStyle]: Partial<MarkdownStyle[K]>
|
|
6
|
+
}>
|
|
7
|
+
|
|
8
|
+
const FONT_FAMILY_MONOSPACE = Platform.select({
|
|
9
|
+
ios: "Courier",
|
|
10
|
+
default: "monospace",
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const FONT_FAMILY_EMOJI = Platform.select({
|
|
14
|
+
ios: "System",
|
|
15
|
+
android: "Noto Color Emoji",
|
|
16
|
+
default: "System, Apple Color Emoji, Segoe UI Emoji, Noto Color Emoji",
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
function makeDefaultMarkdownStyle(): MarkdownStyle {
|
|
20
|
+
return {
|
|
21
|
+
syntax: {
|
|
22
|
+
color: "gray",
|
|
23
|
+
},
|
|
24
|
+
link: {
|
|
25
|
+
color: "blue",
|
|
26
|
+
},
|
|
27
|
+
heading: {
|
|
28
|
+
fontSize: 38,
|
|
29
|
+
scale: 0.85,
|
|
30
|
+
},
|
|
31
|
+
emoji: {
|
|
32
|
+
fontSize: 16,
|
|
33
|
+
fontFamily: FONT_FAMILY_EMOJI,
|
|
34
|
+
},
|
|
35
|
+
blockquote: {
|
|
36
|
+
borderColor: "gray",
|
|
37
|
+
borderWidth: 6,
|
|
38
|
+
marginLeft: 6,
|
|
39
|
+
paddingLeft: 6,
|
|
40
|
+
},
|
|
41
|
+
orderedList: {
|
|
42
|
+
marginLeft: 6,
|
|
43
|
+
paddingLeft: 18,
|
|
44
|
+
},
|
|
45
|
+
unorderedList: {
|
|
46
|
+
marginLeft: 6,
|
|
47
|
+
paddingLeft: 18,
|
|
48
|
+
},
|
|
49
|
+
code: {
|
|
50
|
+
fontFamily: FONT_FAMILY_MONOSPACE,
|
|
51
|
+
fontSize: 16,
|
|
52
|
+
color: "black",
|
|
53
|
+
backgroundColor: "lightgray",
|
|
54
|
+
},
|
|
55
|
+
pre: {
|
|
56
|
+
fontFamily: FONT_FAMILY_MONOSPACE,
|
|
57
|
+
fontSize: 16,
|
|
58
|
+
color: "black",
|
|
59
|
+
backgroundColor: "lightgray",
|
|
60
|
+
},
|
|
61
|
+
mentionHere: {
|
|
62
|
+
color: "green",
|
|
63
|
+
backgroundColor: "lime",
|
|
64
|
+
borderRadius: 5,
|
|
65
|
+
},
|
|
66
|
+
mentionUser: {
|
|
67
|
+
color: "blue",
|
|
68
|
+
backgroundColor: "cyan",
|
|
69
|
+
borderRadius: 5,
|
|
70
|
+
},
|
|
71
|
+
mentionReport: {
|
|
72
|
+
color: "red",
|
|
73
|
+
backgroundColor: "pink",
|
|
74
|
+
borderRadius: 5,
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function mergeMarkdownStyleWithDefault(input: PartialMarkdownStyle | undefined): MarkdownStyle {
|
|
80
|
+
const output = makeDefaultMarkdownStyle()
|
|
81
|
+
|
|
82
|
+
if (input !== undefined) {
|
|
83
|
+
Object.keys(input).forEach((key) => {
|
|
84
|
+
if (!(key in output)) {
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const outputValue = output[key as keyof MarkdownStyle]
|
|
89
|
+
if (outputValue) {
|
|
90
|
+
Object.assign(outputValue, input[key as keyof MarkdownStyle])
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return output
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type { PartialMarkdownStyle }
|
|
99
|
+
|
|
100
|
+
export { mergeMarkdownStyleWithDefault }
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
type HistoryItem = {
|
|
2
|
+
text: string
|
|
3
|
+
cursorPosition: number | null
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export default class InputHistory {
|
|
7
|
+
depth: number
|
|
8
|
+
|
|
9
|
+
items: HistoryItem[]
|
|
10
|
+
|
|
11
|
+
historyIndex: number
|
|
12
|
+
|
|
13
|
+
currentText: string | null = null
|
|
14
|
+
|
|
15
|
+
timeout: NodeJS.Timeout | null = null
|
|
16
|
+
|
|
17
|
+
debounceTime: number
|
|
18
|
+
|
|
19
|
+
constructor(depth: number, debounceTime = 150, startingText = "") {
|
|
20
|
+
this.depth = depth
|
|
21
|
+
this.items = [{ text: startingText, cursorPosition: startingText.length }]
|
|
22
|
+
this.historyIndex = 0
|
|
23
|
+
this.debounceTime = debounceTime
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getCurrentItem(): HistoryItem | null {
|
|
27
|
+
return this.items[this.historyIndex] || null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setHistory(newHistory: HistoryItem[]): void {
|
|
31
|
+
this.items = newHistory.slice(newHistory.length - this.depth)
|
|
32
|
+
this.historyIndex = newHistory.length - 1
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
setHistoryIndex(index: number): void {
|
|
36
|
+
this.historyIndex = index
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
clear(): void {
|
|
40
|
+
this.items = []
|
|
41
|
+
this.historyIndex = 0
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
throttledAdd(text: string, cursorPosition: number): void {
|
|
45
|
+
if (this.timeout) {
|
|
46
|
+
clearTimeout(this.timeout)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (this.currentText === null) {
|
|
50
|
+
this.timeout = null
|
|
51
|
+
this.add(text, cursorPosition)
|
|
52
|
+
} else {
|
|
53
|
+
this.items[this.historyIndex] = { text, cursorPosition }
|
|
54
|
+
}
|
|
55
|
+
this.currentText = text
|
|
56
|
+
|
|
57
|
+
this.timeout = setTimeout(() => {
|
|
58
|
+
this.currentText = null
|
|
59
|
+
}, this.debounceTime)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
stopTimeout(): void {
|
|
63
|
+
if (this.timeout) {
|
|
64
|
+
clearTimeout(this.timeout)
|
|
65
|
+
this.timeout = null
|
|
66
|
+
}
|
|
67
|
+
this.currentText = null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
add(text: string, cursorPosition: number): void {
|
|
71
|
+
if (this.items.length > 0) {
|
|
72
|
+
const currentItem = this.items[this.historyIndex]
|
|
73
|
+
if (currentItem && text === currentItem.text) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (this.historyIndex < this.items.length - 1) {
|
|
79
|
+
this.items.splice(this.historyIndex + 1)
|
|
80
|
+
this.historyIndex = this.items.length - 1
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.items.push({ text, cursorPosition })
|
|
84
|
+
if (this.items.length > this.depth) {
|
|
85
|
+
this.items.shift()
|
|
86
|
+
} else {
|
|
87
|
+
this.historyIndex += 1
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
undo(): HistoryItem | null {
|
|
92
|
+
this.stopTimeout()
|
|
93
|
+
|
|
94
|
+
if (this.items.length === 0 || this.historyIndex - 1 < 0) {
|
|
95
|
+
return null
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const currentHistoryItem = this.items[this.historyIndex]
|
|
99
|
+
const previousHistoryItem = this.items[this.historyIndex - 1]
|
|
100
|
+
|
|
101
|
+
const undoItem = previousHistoryItem
|
|
102
|
+
? {
|
|
103
|
+
text: previousHistoryItem.text,
|
|
104
|
+
cursorPosition: Math.min(
|
|
105
|
+
(currentHistoryItem?.cursorPosition ?? 0) -
|
|
106
|
+
((currentHistoryItem?.text ?? "").length -
|
|
107
|
+
(previousHistoryItem?.text ?? "").length),
|
|
108
|
+
(previousHistoryItem?.text ?? "").length,
|
|
109
|
+
),
|
|
110
|
+
}
|
|
111
|
+
: null
|
|
112
|
+
|
|
113
|
+
if (this.historyIndex > 0) {
|
|
114
|
+
this.historyIndex -= 1
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return undoItem
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
redo(): HistoryItem | null {
|
|
121
|
+
if (this.currentText !== null && this.timeout) {
|
|
122
|
+
this.stopTimeout()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (this.items.length === 0 || this.historyIndex + 1 > this.items.length) {
|
|
126
|
+
return null
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (this.historyIndex < this.items.length - 1) {
|
|
130
|
+
this.historyIndex += 1
|
|
131
|
+
} else {
|
|
132
|
+
return null
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return this.items[this.historyIndex] || null
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
.react-native-marcus-input-multiline {
|
|
2
|
+
white-space: pre-wrap;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.react-native-marcus-input-singleline p {
|
|
6
|
+
display: inline-block;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.react-native-marcus-input-multiline p {
|
|
10
|
+
display: block;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.react-native-marcus-input-singleline::-webkit-scrollbar {
|
|
14
|
+
display: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.react-native-marcus-input-singleline br {
|
|
18
|
+
display: none;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.react-native-marcus-input-singleline span[data-type='text'] {
|
|
22
|
+
vertical-align: middle;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.react-native-marcus-input-singleline span[data-type='link'] span[data-type='text'] {
|
|
26
|
+
vertical-align: top;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.react-native-marcus-input-singleline > p:last-child {
|
|
30
|
+
padding-right: 1px !important;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.react-native-marcus-input-singleline:empty::before,
|
|
34
|
+
.react-native-marcus-input-multiline:empty::before {
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
display: block; /* For Firefox */
|
|
37
|
+
content: attr(placeholder);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.react-native-marcus-input-multiline *[data-type='pre'] {
|
|
41
|
+
line-height: 1.3;
|
|
42
|
+
display: block;
|
|
43
|
+
width: fit-content;
|
|
44
|
+
max-width: 100%;
|
|
45
|
+
box-sizing: border-box;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.react-native-marcus-input-multiline *[data-type='codeblock'] {
|
|
49
|
+
position: relative;
|
|
50
|
+
width: fit-content;
|
|
51
|
+
max-width: 100%;
|
|
52
|
+
box-sizing: border-box;
|
|
53
|
+
z-index: 2;
|
|
54
|
+
display: block;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.react-native-marcus-input-singleline *[data-type='code'] > *[data-type='emoji'],
|
|
58
|
+
.react-native-marcus-input-multiline *[data-type='code'] > *[data-type='emoji'] {
|
|
59
|
+
font-size: inherit !important;
|
|
60
|
+
line-height: inherit !important;
|
|
61
|
+
vertical-align: unset !important;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.react-native-marcus-input-multiline *[data-type='line'] *[data-type='syntax']:has(+ *[data-type='pre']),
|
|
65
|
+
.react-native-marcus-input-multiline *[data-type='line'] *[data-type='pre'] + *[data-type='syntax'] {
|
|
66
|
+
display: block;
|
|
67
|
+
line-height: 1.3;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
[class^='react-native-marcus-input'] [data-type='strikethrough'] * {
|
|
71
|
+
text-decoration: inherit;
|
|
72
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { MarkdownRange, MarkdownType } from "../../commonTypes"
|
|
2
|
+
import type { PartialMarkdownStyle } from "../../styleUtils"
|
|
3
|
+
import type { TextMeasurer } from "./measureUtils"
|
|
4
|
+
|
|
5
|
+
const BLOCK_PREFIX = "block-prefix"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Where one line's text sits, and what has to be drawn in the space to its left.
|
|
9
|
+
*
|
|
10
|
+
* The same three numbers the native formatters produce: `firstLineIndent` is `firstLineHeadIndent`
|
|
11
|
+
* on iOS and `getLeadingMargin(true)` on Android, `indent` is the head indent the line resumes at
|
|
12
|
+
* when it wraps, and `ribbons` are the offsets `MarkdownTextLayoutFragment` and
|
|
13
|
+
* `MarkdownBlockIndentSpan` fill a blockquote's bars at.
|
|
14
|
+
*/
|
|
15
|
+
type LineLayout = {
|
|
16
|
+
firstLineIndent: number
|
|
17
|
+
indent: number
|
|
18
|
+
ribbons: number[]
|
|
19
|
+
/** Space to open after a marker, so the next container's gutter lands between the two. */
|
|
20
|
+
gaps: Map<number, number>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function toNumber(value: string | number | undefined | null): number {
|
|
24
|
+
if (typeof value === "number") {
|
|
25
|
+
return value
|
|
26
|
+
}
|
|
27
|
+
if (!value) {
|
|
28
|
+
return 0
|
|
29
|
+
}
|
|
30
|
+
const parsed = parseFloat(value)
|
|
31
|
+
return Number.isFinite(parsed) ? parsed : 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The gutter one level of a container reserves, or null if the type is not one. */
|
|
35
|
+
function stepOf(type: MarkdownType, markdownStyle: PartialMarkdownStyle): number | null {
|
|
36
|
+
switch (type) {
|
|
37
|
+
case "blockquote":
|
|
38
|
+
return (
|
|
39
|
+
toNumber(markdownStyle.blockquote?.marginLeft) +
|
|
40
|
+
toNumber(markdownStyle.blockquote?.borderWidth) +
|
|
41
|
+
toNumber(markdownStyle.blockquote?.paddingLeft)
|
|
42
|
+
)
|
|
43
|
+
case "list-ordered":
|
|
44
|
+
return (
|
|
45
|
+
toNumber(markdownStyle.orderedList?.marginLeft) +
|
|
46
|
+
toNumber(markdownStyle.orderedList?.paddingLeft)
|
|
47
|
+
)
|
|
48
|
+
case "list-unordered":
|
|
49
|
+
return (
|
|
50
|
+
toNumber(markdownStyle.unorderedList?.marginLeft) +
|
|
51
|
+
toNumber(markdownStyle.unorderedList?.paddingLeft)
|
|
52
|
+
)
|
|
53
|
+
default:
|
|
54
|
+
return null
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Places the containers of every line, left to right -- the web half of `BlockLayout` in
|
|
60
|
+
* `apple/MarkdownFormatter.swift` and `android/.../MarkdownFormatter.kt`, and deliberately the same
|
|
61
|
+
* walk.
|
|
62
|
+
*
|
|
63
|
+
* Each container reserves a gutter and is then followed by its own marker, which is text and so has
|
|
64
|
+
* to be stepped over rather than reserved: the container nested inside it starts after the marker,
|
|
65
|
+
* not in front of it. That is what puts a quote's ribbons after a list bullet, and a list's indent
|
|
66
|
+
* after a quote's `>`.
|
|
67
|
+
*
|
|
68
|
+
* A line continuing a block carries no marker of its own and reuses the one that opened it, which
|
|
69
|
+
* is why this runs across the whole document rather than per line: without it a continuation line
|
|
70
|
+
* would sit a marker's width to the left of the line above and break the block in two.
|
|
71
|
+
*
|
|
72
|
+
* It reads the ranges in the order the parser emits them -- marker, then the container it belongs
|
|
73
|
+
* to -- so it has to run before `sortRanges` rearranges them into the containment order the DOM
|
|
74
|
+
* builder needs.
|
|
75
|
+
*/
|
|
76
|
+
function layoutBlocks(
|
|
77
|
+
text: string,
|
|
78
|
+
ranges: MarkdownRange[],
|
|
79
|
+
markdownStyle: PartialMarkdownStyle,
|
|
80
|
+
measure: TextMeasurer,
|
|
81
|
+
): Map<number, LineLayout> {
|
|
82
|
+
const layouts = new Map<number, LineLayout>()
|
|
83
|
+
/** Last marker seen for each container type, for the lines that continue it. */
|
|
84
|
+
const markers = new Map<MarkdownType, MarkdownRange>()
|
|
85
|
+
const ribbonMargin = toNumber(markdownStyle.blockquote?.marginLeft)
|
|
86
|
+
|
|
87
|
+
let pendingPrefix: MarkdownRange | null = null
|
|
88
|
+
let line: LineLayout | null = null
|
|
89
|
+
let lineStart = -1
|
|
90
|
+
/** Offset reached so far, from the line's own left edge. */
|
|
91
|
+
let offset = 0
|
|
92
|
+
/**
|
|
93
|
+
* Where the line's first marker begins, if it has one. The text starts there; everything past it
|
|
94
|
+
* is held open with padding instead.
|
|
95
|
+
*/
|
|
96
|
+
let textStart = -1
|
|
97
|
+
/** Marker of the container placed most recently, if it is on this line and so has something to
|
|
98
|
+
* pad. */
|
|
99
|
+
let padded: MarkdownRange | null = null
|
|
100
|
+
|
|
101
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
102
|
+
const range = ranges[i] as MarkdownRange
|
|
103
|
+
|
|
104
|
+
if (range.type === BLOCK_PREFIX) {
|
|
105
|
+
pendingPrefix = range
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const step = stepOf(range.type, markdownStyle)
|
|
110
|
+
if (step === null) {
|
|
111
|
+
continue
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const depth = range.depth && range.depth > 0 ? range.depth : 1
|
|
115
|
+
const gutter = step * depth
|
|
116
|
+
|
|
117
|
+
if (range.start !== lineStart) {
|
|
118
|
+
lineStart = range.start
|
|
119
|
+
offset = 0
|
|
120
|
+
textStart = -1
|
|
121
|
+
padded = null
|
|
122
|
+
line = { firstLineIndent: 0, indent: 0, ribbons: [], gaps: new Map() }
|
|
123
|
+
layouts.set(lineStart, line)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const current = line as LineLayout
|
|
127
|
+
|
|
128
|
+
if (padded) {
|
|
129
|
+
current.gaps.set(padded.start, (current.gaps.get(padded.start) ?? 0) + gutter)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (range.type === "blockquote") {
|
|
133
|
+
for (let level = 0; level < depth; level++) {
|
|
134
|
+
current.ribbons.push(offset + ribbonMargin + step * level)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
offset += gutter
|
|
139
|
+
|
|
140
|
+
if (pendingPrefix) {
|
|
141
|
+
markers.set(range.type, pendingPrefix)
|
|
142
|
+
if (textStart < 0) {
|
|
143
|
+
textStart = offset
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const marker = pendingPrefix ?? markers.get(range.type)
|
|
148
|
+
if (marker) {
|
|
149
|
+
offset += measure(text.substring(marker.start, marker.start + marker.length))
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
padded = pendingPrefix
|
|
153
|
+
pendingPrefix = null
|
|
154
|
+
|
|
155
|
+
current.firstLineIndent = textStart >= 0 ? textStart : offset
|
|
156
|
+
current.indent = offset
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return layouts
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export { layoutBlocks, toNumber }
|
|
163
|
+
export type { LineLayout }
|