From e50d09db50128011b053850dbf89755212819e4a Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Fri, 21 Mar 2025 01:38:08 +0000 Subject: [PATCH] feat(editor): latex inline package (#11051) --- blocksuite/affine/all/package.json | 2 + blocksuite/affine/all/src/effects.ts | 2 + blocksuite/affine/all/src/inlines/latex.ts | 1 + blocksuite/affine/all/tsconfig.json | 1 + .../affine/blocks/block-code/package.json | 1 + .../block-code/src/code-block-inline.ts | 2 +- .../affine/blocks/block-code/tsconfig.json | 1 + .../affine/blocks/block-latex/package.json | 2 +- .../block-latex/src/configs/slash-menu.ts | 2 +- .../affine/blocks/block-latex/tsconfig.json | 2 +- .../affine/blocks/block-root/package.json | 1 + .../src/widgets/keyboard-toolbar/config.ts | 2 +- .../affine/blocks/block-root/tsconfig.json | 1 + blocksuite/affine/inlines/latex/package.json | 52 ++++ .../inlines/latex/src/adapters/index.ts | 3 + .../src/adapters/markdown/inline-delta.ts | 21 ++ .../src/adapters/markdown/markdown-inline.ts | 12 + .../src/adapters/plain-text/inline-delta.ts | 21 ++ .../src/command.ts} | 0 .../affine/inlines/latex/src/effects.ts | 17 ++ blocksuite/affine/inlines/latex/src/exts.ts | 11 + blocksuite/affine/inlines/latex/src/index.ts | 10 + .../affine/inlines/latex/src/inline-spec.ts | 36 +++ .../src}/latex-node/latex-editor-menu.ts | 5 +- .../src}/latex-node/latex-editor-unit.ts | 0 .../src}/latex-node/latex-node.ts | 0 .../affine/inlines/latex/src/markdown.ts | 173 +++++++++++++ blocksuite/affine/inlines/latex/tsconfig.json | 19 ++ blocksuite/affine/inlines/link/src/index.ts | 1 + .../affine/inlines/link/src/markdown.ts | 62 +++++ blocksuite/affine/inlines/preset/package.json | 1 + .../src/adapters/markdown/inline-delta.ts | 24 +- .../src/adapters/markdown/markdown-inline.ts | 12 +- .../src/adapters/plain-text/inline-delta.ts | 22 +- .../inlines/preset/src/command/index.ts | 1 - .../preset/src/default-inline-manager.ts | 2 +- .../affine/inlines/preset/src/effects.ts | 9 - blocksuite/affine/inlines/preset/src/exts.ts | 2 - .../affine/inlines/preset/src/inline-spec.ts | 36 +-- .../affine/inlines/preset/src/markdown.ts | 233 +----------------- .../affine/inlines/preset/tsconfig.json | 1 + tools/utils/src/workspace.gen.ts | 21 +- tsconfig.json | 1 + yarn.lock | 40 ++- 44 files changed, 526 insertions(+), 342 deletions(-) create mode 100644 blocksuite/affine/all/src/inlines/latex.ts create mode 100644 blocksuite/affine/inlines/latex/package.json create mode 100644 blocksuite/affine/inlines/latex/src/adapters/index.ts create mode 100644 blocksuite/affine/inlines/latex/src/adapters/markdown/inline-delta.ts create mode 100644 blocksuite/affine/inlines/latex/src/adapters/markdown/markdown-inline.ts create mode 100644 blocksuite/affine/inlines/latex/src/adapters/plain-text/inline-delta.ts rename blocksuite/affine/inlines/{preset/src/command/insert-inline-latex.ts => latex/src/command.ts} (100%) create mode 100644 blocksuite/affine/inlines/latex/src/effects.ts create mode 100644 blocksuite/affine/inlines/latex/src/exts.ts create mode 100644 blocksuite/affine/inlines/latex/src/index.ts create mode 100644 blocksuite/affine/inlines/latex/src/inline-spec.ts rename blocksuite/affine/inlines/{preset/src/nodes => latex/src}/latex-node/latex-editor-menu.ts (96%) rename blocksuite/affine/inlines/{preset/src/nodes => latex/src}/latex-node/latex-editor-unit.ts (100%) rename blocksuite/affine/inlines/{preset/src/nodes => latex/src}/latex-node/latex-node.ts (100%) create mode 100644 blocksuite/affine/inlines/latex/src/markdown.ts create mode 100644 blocksuite/affine/inlines/latex/tsconfig.json create mode 100644 blocksuite/affine/inlines/link/src/markdown.ts diff --git a/blocksuite/affine/all/package.json b/blocksuite/affine/all/package.json index 2c2cb413e6..5ac93e0d7a 100644 --- a/blocksuite/affine/all/package.json +++ b/blocksuite/affine/all/package.json @@ -36,6 +36,7 @@ "@blocksuite/affine-gfx-text": "workspace:*", "@blocksuite/affine-gfx-turbo-renderer": "workspace:*", "@blocksuite/affine-inline-footnote": "workspace:*", + "@blocksuite/affine-inline-latex": "workspace:*", "@blocksuite/affine-inline-link": "workspace:*", "@blocksuite/affine-inline-preset": "workspace:*", "@blocksuite/affine-inline-reference": "workspace:*", @@ -99,6 +100,7 @@ "./inlines/reference": "./src/inlines/reference.ts", "./inlines/preset": "./src/inlines/preset.ts", "./inlines/footnote": "./src/inlines/footnote.ts", + "./inlines/latex": "./src/inlines/latex.ts", "./widgets/drag-handle": "./src/widgets/drag-handle.ts", "./widgets/edgeless-auto-connect": "./src/widgets/edgeless-auto-connect.ts", "./widgets/frame-title": "./src/widgets/frame-title.ts", diff --git a/blocksuite/affine/all/src/effects.ts b/blocksuite/affine/all/src/effects.ts index faac554d39..fcbdfe45f8 100644 --- a/blocksuite/affine/all/src/effects.ts +++ b/blocksuite/affine/all/src/effects.ts @@ -46,6 +46,7 @@ import { effects as fragmentDocTitleEffects } from '@blocksuite/affine-fragment- import { effects as fragmentFramePanelEffects } from '@blocksuite/affine-fragment-frame-panel/effects'; import { effects as fragmentOutlineEffects } from '@blocksuite/affine-fragment-outline/effects'; import { effects as inlineFootnoteEffects } from '@blocksuite/affine-inline-footnote/effects'; +import { effects as inlineLatexEffects } from '@blocksuite/affine-inline-latex/effects'; import { effects as inlineLinkEffects } from '@blocksuite/affine-inline-link/effects'; import { effects as inlinePresetEffects } from '@blocksuite/affine-inline-preset/effects'; import { effects as inlineReferenceEffects } from '@blocksuite/affine-inline-reference/effects'; @@ -121,6 +122,7 @@ export function effects() { inlinePresetEffects(); inlineLinkEffects(); inlineFootnoteEffects(); + inlineLatexEffects(); blockNoteEffects(); blockAttachmentEffects(); diff --git a/blocksuite/affine/all/src/inlines/latex.ts b/blocksuite/affine/all/src/inlines/latex.ts new file mode 100644 index 0000000000..0b61155185 --- /dev/null +++ b/blocksuite/affine/all/src/inlines/latex.ts @@ -0,0 +1 @@ +export * from '@blocksuite/affine-inline-latex'; diff --git a/blocksuite/affine/all/tsconfig.json b/blocksuite/affine/all/tsconfig.json index 2c5175220d..531467f280 100644 --- a/blocksuite/affine/all/tsconfig.json +++ b/blocksuite/affine/all/tsconfig.json @@ -33,6 +33,7 @@ { "path": "../gfx/text" }, { "path": "../gfx/turbo-renderer" }, { "path": "../inlines/footnote" }, + { "path": "../inlines/latex" }, { "path": "../inlines/link" }, { "path": "../inlines/preset" }, { "path": "../inlines/reference" }, diff --git a/blocksuite/affine/blocks/block-code/package.json b/blocksuite/affine/blocks/block-code/package.json index 81e4a57b76..a1eae7218f 100644 --- a/blocksuite/affine/blocks/block-code/package.json +++ b/blocksuite/affine/blocks/block-code/package.json @@ -11,6 +11,7 @@ "license": "MIT", "dependencies": { "@blocksuite/affine-components": "workspace:*", + "@blocksuite/affine-inline-latex": "workspace:*", "@blocksuite/affine-inline-link": "workspace:*", "@blocksuite/affine-inline-preset": "workspace:*", "@blocksuite/affine-model": "workspace:*", diff --git a/blocksuite/affine/blocks/block-code/src/code-block-inline.ts b/blocksuite/affine/blocks/block-code/src/code-block-inline.ts index 2c6f908b5c..6a604cfb72 100644 --- a/blocksuite/affine/blocks/block-code/src/code-block-inline.ts +++ b/blocksuite/affine/blocks/block-code/src/code-block-inline.ts @@ -1,3 +1,4 @@ +import { LatexInlineSpecExtension } from '@blocksuite/affine-inline-latex'; import { LinkInlineSpecExtension } from '@blocksuite/affine-inline-link'; import { BackgroundInlineSpecExtension, @@ -5,7 +6,6 @@ import { CodeInlineSpecExtension, ColorInlineSpecExtension, ItalicInlineSpecExtension, - LatexInlineSpecExtension, StrikeInlineSpecExtension, UnderlineInlineSpecExtension, } from '@blocksuite/affine-inline-preset'; diff --git a/blocksuite/affine/blocks/block-code/tsconfig.json b/blocksuite/affine/blocks/block-code/tsconfig.json index fa21e142d4..0487cffc2b 100644 --- a/blocksuite/affine/blocks/block-code/tsconfig.json +++ b/blocksuite/affine/blocks/block-code/tsconfig.json @@ -8,6 +8,7 @@ "include": ["./src"], "references": [ { "path": "../../components" }, + { "path": "../../inlines/latex" }, { "path": "../../inlines/link" }, { "path": "../../inlines/preset" }, { "path": "../../model" }, diff --git a/blocksuite/affine/blocks/block-latex/package.json b/blocksuite/affine/blocks/block-latex/package.json index 25cf1bb67f..2358ba140a 100644 --- a/blocksuite/affine/blocks/block-latex/package.json +++ b/blocksuite/affine/blocks/block-latex/package.json @@ -12,7 +12,7 @@ "dependencies": { "@blocksuite/affine-block-note": "workspace:*", "@blocksuite/affine-components": "workspace:*", - "@blocksuite/affine-inline-preset": "workspace:*", + "@blocksuite/affine-inline-latex": "workspace:*", "@blocksuite/affine-model": "workspace:*", "@blocksuite/affine-rich-text": "workspace:*", "@blocksuite/affine-shared": "workspace:*", diff --git a/blocksuite/affine/blocks/block-latex/src/configs/slash-menu.ts b/blocksuite/affine/blocks/block-latex/src/configs/slash-menu.ts index b976e90ee7..f37ff6becf 100644 --- a/blocksuite/affine/blocks/block-latex/src/configs/slash-menu.ts +++ b/blocksuite/affine/blocks/block-latex/src/configs/slash-menu.ts @@ -1,4 +1,4 @@ -import { insertInlineLatex } from '@blocksuite/affine-inline-preset'; +import { insertInlineLatex } from '@blocksuite/affine-inline-latex'; import { getSelectedModelsCommand, getTextSelectionCommand, diff --git a/blocksuite/affine/blocks/block-latex/tsconfig.json b/blocksuite/affine/blocks/block-latex/tsconfig.json index 85b2d659da..83790cc158 100644 --- a/blocksuite/affine/blocks/block-latex/tsconfig.json +++ b/blocksuite/affine/blocks/block-latex/tsconfig.json @@ -9,7 +9,7 @@ "references": [ { "path": "../block-note" }, { "path": "../../components" }, - { "path": "../../inlines/preset" }, + { "path": "../../inlines/latex" }, { "path": "../../model" }, { "path": "../../rich-text" }, { "path": "../../shared" }, diff --git a/blocksuite/affine/blocks/block-root/package.json b/blocksuite/affine/blocks/block-root/package.json index 283de42cf3..377934d028 100644 --- a/blocksuite/affine/blocks/block-root/package.json +++ b/blocksuite/affine/blocks/block-root/package.json @@ -28,6 +28,7 @@ "@blocksuite/affine-components": "workspace:*", "@blocksuite/affine-fragment-doc-title": "workspace:*", "@blocksuite/affine-gfx-text": "workspace:*", + "@blocksuite/affine-inline-latex": "workspace:*", "@blocksuite/affine-inline-link": "workspace:*", "@blocksuite/affine-inline-preset": "workspace:*", "@blocksuite/affine-inline-reference": "workspace:*", diff --git a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/config.ts b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/config.ts index 06fab32381..798dacc87e 100644 --- a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/config.ts +++ b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/config.ts @@ -20,13 +20,13 @@ import { getSurfaceBlock } from '@blocksuite/affine-block-surface'; import { insertSurfaceRefBlockCommand } from '@blocksuite/affine-block-surface-ref'; import { toggleEmbedCardCreateModal } from '@blocksuite/affine-components/embed-card-modal'; import { toast } from '@blocksuite/affine-components/toast'; +import { insertInlineLatex } from '@blocksuite/affine-inline-latex'; import { toggleLink } from '@blocksuite/affine-inline-link'; import { formatBlockCommand, formatNativeCommand, formatTextCommand, getTextStyle, - insertInlineLatex, toggleBold, toggleCode, toggleItalic, diff --git a/blocksuite/affine/blocks/block-root/tsconfig.json b/blocksuite/affine/blocks/block-root/tsconfig.json index fb0cd62006..772da73811 100644 --- a/blocksuite/affine/blocks/block-root/tsconfig.json +++ b/blocksuite/affine/blocks/block-root/tsconfig.json @@ -25,6 +25,7 @@ { "path": "../../components" }, { "path": "../../fragments/fragment-doc-title" }, { "path": "../../gfx/text" }, + { "path": "../../inlines/latex" }, { "path": "../../inlines/link" }, { "path": "../../inlines/preset" }, { "path": "../../inlines/reference" }, diff --git a/blocksuite/affine/inlines/latex/package.json b/blocksuite/affine/inlines/latex/package.json new file mode 100644 index 0000000000..b6ff6ad5cf --- /dev/null +++ b/blocksuite/affine/inlines/latex/package.json @@ -0,0 +1,52 @@ +{ + "name": "@blocksuite/affine-inline-latex", + "description": "Inline latex for BlockSuite.", + "type": "module", + "scripts": { + "build": "tsc" + }, + "sideEffects": false, + "keywords": [], + "author": "toeverything", + "license": "MIT", + "dependencies": { + "@blocksuite/affine-components": "workspace:*", + "@blocksuite/affine-inline-reference": "workspace:*", + "@blocksuite/affine-model": "workspace:*", + "@blocksuite/affine-rich-text": "workspace:*", + "@blocksuite/affine-shared": "workspace:*", + "@blocksuite/block-std": "workspace:*", + "@blocksuite/global": "workspace:*", + "@blocksuite/icons": "^2.2.6", + "@blocksuite/store": "workspace:*", + "@floating-ui/dom": "^1.6.13", + "@lit/context": "^1.1.2", + "@preact/signals-core": "^1.8.0", + "@toeverything/theme": "^1.1.12", + "@types/hast": "^3.0.4", + "@types/katex": "^0.16.7", + "@types/lodash-es": "^4.17.12", + "collapse-white-space": "^2.1.0", + "date-fns": "^4.0.0", + "katex": "^0.16.11", + "lit": "^3.2.0", + "lit-html": "^3.2.1", + "lodash-es": "^4.17.21", + "remark-math": "^6.0.0", + "rxjs": "^7.8.1", + "shiki": "^3.0.0", + "yjs": "^13.6.21", + "zod": "^3.23.8" + }, + "exports": { + ".": "./src/index.ts", + "./effects": "./src/effects.ts" + }, + "files": [ + "src", + "dist", + "!src/__tests__", + "!dist/__tests__" + ], + "version": "0.20.0" +} diff --git a/blocksuite/affine/inlines/latex/src/adapters/index.ts b/blocksuite/affine/inlines/latex/src/adapters/index.ts new file mode 100644 index 0000000000..468416bb87 --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/adapters/index.ts @@ -0,0 +1,3 @@ +export * from './markdown/inline-delta'; +export * from './markdown/markdown-inline'; +export * from './plain-text/inline-delta'; diff --git a/blocksuite/affine/inlines/latex/src/adapters/markdown/inline-delta.ts b/blocksuite/affine/inlines/latex/src/adapters/markdown/inline-delta.ts new file mode 100644 index 0000000000..4ad09353e7 --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/adapters/markdown/inline-delta.ts @@ -0,0 +1,21 @@ +import { InlineDeltaToMarkdownAdapterExtension } from '@blocksuite/affine-shared/adapters'; +import type { PhrasingContent } from 'mdast'; + +export const latexDeltaToMarkdownAdapterMatcher = + InlineDeltaToMarkdownAdapterExtension({ + name: 'inlineLatex', + match: delta => !!delta.attributes?.latex, + toAST: delta => { + const mdast: PhrasingContent = { + type: 'text', + value: delta.insert, + }; + if (delta.attributes?.latex) { + return { + type: 'inlineMath', + value: delta.attributes.latex, + }; + } + return mdast; + }, + }); diff --git a/blocksuite/affine/inlines/latex/src/adapters/markdown/markdown-inline.ts b/blocksuite/affine/inlines/latex/src/adapters/markdown/markdown-inline.ts new file mode 100644 index 0000000000..87de3c5113 --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/adapters/markdown/markdown-inline.ts @@ -0,0 +1,12 @@ +import { MarkdownASTToDeltaExtension } from '@blocksuite/affine-shared/adapters'; + +export const markdownInlineMathToDeltaMatcher = MarkdownASTToDeltaExtension({ + name: 'inlineMath', + match: ast => ast.type === 'inlineMath', + toDelta: ast => { + if (!('value' in ast)) { + return []; + } + return [{ insert: ' ', attributes: { latex: ast.value } }]; + }, +}); diff --git a/blocksuite/affine/inlines/latex/src/adapters/plain-text/inline-delta.ts b/blocksuite/affine/inlines/latex/src/adapters/plain-text/inline-delta.ts new file mode 100644 index 0000000000..6881d07870 --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/adapters/plain-text/inline-delta.ts @@ -0,0 +1,21 @@ +import { + InlineDeltaToPlainTextAdapterExtension, + type TextBuffer, +} from '@blocksuite/affine-shared/adapters'; + +export const latexDeltaMarkdownAdapterMatch = + InlineDeltaToPlainTextAdapterExtension({ + name: 'inlineLatex', + match: delta => !!delta.attributes?.latex, + toAST: delta => { + const node: TextBuffer = { + content: delta.insert, + }; + if (!delta.attributes?.latex) { + return node; + } + return { + content: delta.attributes?.latex, + }; + }, + }); diff --git a/blocksuite/affine/inlines/preset/src/command/insert-inline-latex.ts b/blocksuite/affine/inlines/latex/src/command.ts similarity index 100% rename from blocksuite/affine/inlines/preset/src/command/insert-inline-latex.ts rename to blocksuite/affine/inlines/latex/src/command.ts diff --git a/blocksuite/affine/inlines/latex/src/effects.ts b/blocksuite/affine/inlines/latex/src/effects.ts new file mode 100644 index 0000000000..b10b4a1e8c --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/effects.ts @@ -0,0 +1,17 @@ +import { LatexEditorMenu } from './latex-node/latex-editor-menu'; +import { LatexEditorUnit } from './latex-node/latex-editor-unit'; +import { AffineLatexNode } from './latex-node/latex-node'; + +export function effects() { + customElements.define('latex-editor-menu', LatexEditorMenu); + customElements.define('latex-editor-unit', LatexEditorUnit); + customElements.define('affine-latex-node', AffineLatexNode); +} + +declare global { + interface HTMLElementTagNameMap { + 'affine-latex-node': AffineLatexNode; + 'latex-editor-unit': LatexEditorUnit; + 'latex-editor-menu': LatexEditorMenu; + } +} diff --git a/blocksuite/affine/inlines/latex/src/exts.ts b/blocksuite/affine/inlines/latex/src/exts.ts new file mode 100644 index 0000000000..4c4f9f76a8 --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/exts.ts @@ -0,0 +1,11 @@ +import { + LatexEditorUnitSpecExtension, + LatexInlineSpecExtension, +} from './inline-spec'; +import { LatexEditorInlineManagerExtension } from './latex-node/latex-editor-menu'; + +export const inlineLatexExtensions = [ + LatexInlineSpecExtension, + LatexEditorUnitSpecExtension, + LatexEditorInlineManagerExtension, +]; diff --git a/blocksuite/affine/inlines/latex/src/index.ts b/blocksuite/affine/inlines/latex/src/index.ts new file mode 100644 index 0000000000..5dfb28b826 --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/index.ts @@ -0,0 +1,10 @@ +import type * as RichTextEffects from '@blocksuite/affine-rich-text/effects'; +import type RemarkMath from 'remark-math'; + +export * from './adapters'; +export * from './command'; +export * from './exts'; +export * from './inline-spec'; +export * from './markdown'; + +declare type _GLOBAL_ = typeof RichTextEffects | typeof RemarkMath; diff --git a/blocksuite/affine/inlines/latex/src/inline-spec.ts b/blocksuite/affine/inlines/latex/src/inline-spec.ts new file mode 100644 index 0000000000..3554244dd4 --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/inline-spec.ts @@ -0,0 +1,36 @@ +import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; +import { StdIdentifier } from '@blocksuite/block-std'; +import { InlineSpecExtension } from '@blocksuite/block-std/inline'; +import { html } from 'lit'; +import { z } from 'zod'; + +export const LatexInlineSpecExtension = + InlineSpecExtension('latex', provider => { + const std = provider.get(StdIdentifier); + return { + name: 'latex', + schema: z.string().optional().nullable().catch(undefined), + match: delta => typeof delta.attributes?.latex === 'string', + renderer: ({ delta, selected, editor, startOffset, endOffset }) => { + return html``; + }, + embed: true, + }; + }); + +export const LatexEditorUnitSpecExtension = + InlineSpecExtension({ + name: 'latex-editor-unit', + schema: z.undefined(), + match: () => true, + renderer: ({ delta }) => { + return html``; + }, + }); diff --git a/blocksuite/affine/inlines/preset/src/nodes/latex-node/latex-editor-menu.ts b/blocksuite/affine/inlines/latex/src/latex-node/latex-editor-menu.ts similarity index 96% rename from blocksuite/affine/inlines/preset/src/nodes/latex-node/latex-editor-menu.ts rename to blocksuite/affine/inlines/latex/src/latex-node/latex-editor-menu.ts index ba33cfe8c3..ae8527e981 100644 --- a/blocksuite/affine/inlines/preset/src/nodes/latex-node/latex-editor-menu.ts +++ b/blocksuite/affine/inlines/latex/src/latex-node/latex-editor-menu.ts @@ -1,4 +1,5 @@ import { ColorScheme } from '@blocksuite/affine-model'; +import type { RichText } from '@blocksuite/affine-rich-text'; import { ThemeProvider } from '@blocksuite/affine-shared/services'; import { unsafeCSSVar } from '@blocksuite/affine-shared/theme'; import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; @@ -13,7 +14,7 @@ import { property } from 'lit/decorators.js'; import { codeToTokensBase, type ThemedToken } from 'shiki'; import * as Y from 'yjs'; -import { LatexEditorUnitSpecExtension } from '../../inline-spec'; +import { LatexEditorUnitSpecExtension } from '../inline-spec'; export const LatexEditorInlineManagerExtension = InlineManagerExtension({ @@ -93,7 +94,7 @@ export class LatexEditorMenu extends SignalWatcher( } get richText() { - return this.querySelector('rich-text'); + return this.querySelector('rich-text'); } private _updateHighlightTokens(text: string) { diff --git a/blocksuite/affine/inlines/preset/src/nodes/latex-node/latex-editor-unit.ts b/blocksuite/affine/inlines/latex/src/latex-node/latex-editor-unit.ts similarity index 100% rename from blocksuite/affine/inlines/preset/src/nodes/latex-node/latex-editor-unit.ts rename to blocksuite/affine/inlines/latex/src/latex-node/latex-editor-unit.ts diff --git a/blocksuite/affine/inlines/preset/src/nodes/latex-node/latex-node.ts b/blocksuite/affine/inlines/latex/src/latex-node/latex-node.ts similarity index 100% rename from blocksuite/affine/inlines/preset/src/nodes/latex-node/latex-node.ts rename to blocksuite/affine/inlines/latex/src/latex-node/latex-node.ts diff --git a/blocksuite/affine/inlines/latex/src/markdown.ts b/blocksuite/affine/inlines/latex/src/markdown.ts new file mode 100644 index 0000000000..ef78a2376c --- /dev/null +++ b/blocksuite/affine/inlines/latex/src/markdown.ts @@ -0,0 +1,173 @@ +import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; +import type { BlockComponent } from '@blocksuite/block-std'; +import { InlineMarkdownExtension } from '@blocksuite/block-std/inline'; + +export const LatexExtension = InlineMarkdownExtension({ + name: 'latex', + + pattern: + /(?:\$\$)(?[^$]+)(?:\$\$)$|(?\$\$\$\$)|(?\$\$)$/g, + action: ({ inlineEditor, prefixText, inlineRange, pattern, undoManager }) => { + const match = pattern.exec(prefixText); + if (!match || !match.groups) return; + const content = match.groups['content']; + const inlinePrefix = match.groups['inlinePrefix']; + const blockPrefix = match.groups['blockPrefix']; + + if (blockPrefix === '$$$$') { + inlineEditor.insertText( + { + index: inlineRange.index, + length: 0, + }, + ' ' + ); + inlineEditor.setInlineRange({ + index: inlineRange.index + 1, + length: 0, + }); + + undoManager.stopCapturing(); + + if (!inlineEditor.rootElement) return; + const blockComponent = + inlineEditor.rootElement.closest('[data-block-id]'); + if (!blockComponent) return; + + const doc = blockComponent.doc; + const parentComponent = blockComponent.parentComponent; + if (!parentComponent) return; + + const index = parentComponent.model.children.indexOf( + blockComponent.model + ); + if (index === -1) return; + + inlineEditor.deleteText({ + index: inlineRange.index - 4, + length: 5, + }); + + const id = doc.addBlock( + 'affine:latex', + { + latex: '', + }, + parentComponent.model, + index + 1 + ); + blockComponent.host.updateComplete + .then(() => { + const latexBlock = blockComponent.std.view.getBlock(id); + if (!latexBlock || latexBlock.flavour !== 'affine:latex') return; + + //FIXME(@Flrande): wait for refactor + // @ts-expect-error BS-2241 + latexBlock.toggleEditor(); + }) + .catch(console.error); + + return; + } + + if (inlinePrefix === '$$') { + inlineEditor.insertText( + { + index: inlineRange.index, + length: 0, + }, + ' ' + ); + inlineEditor.setInlineRange({ + index: inlineRange.index + 1, + length: 0, + }); + + undoManager.stopCapturing(); + + inlineEditor.deleteText({ + index: inlineRange.index - 2, + length: 3, + }); + inlineEditor.insertText( + { + index: inlineRange.index - 2, + length: 0, + }, + ' ' + ); + inlineEditor.formatText( + { + index: inlineRange.index - 2, + length: 1, + }, + { + latex: '', + } + ); + + inlineEditor + .waitForUpdate() + .then(async () => { + await inlineEditor.waitForUpdate(); + + const textPoint = inlineEditor.getTextPoint( + inlineRange.index - 2 + 1 + ); + if (!textPoint) return; + + const [text] = textPoint; + const latexNode = text.parentElement?.closest('affine-latex-node'); + if (!latexNode) return; + + latexNode.toggleEditor(); + }) + .catch(console.error); + + return; + } + + if (!content || content.length === 0) return; + + inlineEditor.insertText( + { + index: inlineRange.index, + length: 0, + }, + ' ' + ); + inlineEditor.setInlineRange({ + index: inlineRange.index + 1, + length: 0, + }); + + undoManager.stopCapturing(); + + const startIndex = inlineRange.index - 2 - content.length - 2; + inlineEditor.deleteText({ + index: startIndex, + length: 2 + content.length + 2 + 1, + }); + inlineEditor.insertText( + { + index: startIndex, + length: 0, + }, + ' ' + ); + inlineEditor.formatText( + { + index: startIndex, + length: 1, + }, + { + latex: String.raw`${content}`, + } + ); + + inlineEditor.setInlineRange({ + index: startIndex + 1, + length: 0, + }); + }, +}); diff --git a/blocksuite/affine/inlines/latex/tsconfig.json b/blocksuite/affine/inlines/latex/tsconfig.json new file mode 100644 index 0000000000..6bc887bdab --- /dev/null +++ b/blocksuite/affine/inlines/latex/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo" + }, + "include": ["./src"], + "references": [ + { "path": "../../components" }, + { "path": "../reference" }, + { "path": "../../model" }, + { "path": "../../rich-text" }, + { "path": "../../shared" }, + { "path": "../../../framework/block-std" }, + { "path": "../../../framework/global" }, + { "path": "../../../framework/store" } + ] +} diff --git a/blocksuite/affine/inlines/link/src/index.ts b/blocksuite/affine/inlines/link/src/index.ts index 77e3423d9c..45b4a160dc 100644 --- a/blocksuite/affine/inlines/link/src/index.ts +++ b/blocksuite/affine/inlines/link/src/index.ts @@ -3,4 +3,5 @@ export * from './command'; export * from './exts'; export * from './inline-spec'; export * from './link-node'; +export * from './markdown'; export * from './toolbar'; diff --git a/blocksuite/affine/inlines/link/src/markdown.ts b/blocksuite/affine/inlines/link/src/markdown.ts new file mode 100644 index 0000000000..e347f62283 --- /dev/null +++ b/blocksuite/affine/inlines/link/src/markdown.ts @@ -0,0 +1,62 @@ +import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; +import { InlineMarkdownExtension } from '@blocksuite/block-std/inline'; + +export const LinkExtension = InlineMarkdownExtension({ + name: 'link', + pattern: /.*\[(.+?)\]\((.+?)\)$/, + action: ({ inlineEditor, prefixText, inlineRange, pattern, undoManager }) => { + const match = prefixText.match(pattern); + if (!match) return; + + const linkText = match[1]; + const linkUrl = match[2]; + const annotatedText = match[0].slice(-linkText.length - linkUrl.length - 4); + const startIndex = inlineRange.index - annotatedText.length; + + inlineEditor.insertText( + { + index: inlineRange.index, + length: 0, + }, + ' ' + ); + inlineEditor.setInlineRange({ + index: inlineRange.index + 1, + length: 0, + }); + + undoManager.stopCapturing(); + + // aaa[bbb](baidu.com) + space + + // delete (baidu.com) + space + inlineEditor.deleteText({ + index: startIndex + 1 + linkText.length + 1, + length: 1 + linkUrl.length + 1 + 1, + }); + // delete [ and ] + inlineEditor.deleteText({ + index: startIndex + 1 + linkText.length, + length: 1, + }); + inlineEditor.deleteText({ + index: startIndex, + length: 1, + }); + + inlineEditor.formatText( + { + index: startIndex, + length: linkText.length, + }, + { + link: linkUrl, + } + ); + + inlineEditor.setInlineRange({ + index: startIndex + linkText.length, + length: 0, + }); + }, +}); diff --git a/blocksuite/affine/inlines/preset/package.json b/blocksuite/affine/inlines/preset/package.json index c5406769ed..d8193742fe 100644 --- a/blocksuite/affine/inlines/preset/package.json +++ b/blocksuite/affine/inlines/preset/package.json @@ -12,6 +12,7 @@ "dependencies": { "@blocksuite/affine-components": "workspace:*", "@blocksuite/affine-inline-footnote": "workspace:*", + "@blocksuite/affine-inline-latex": "workspace:*", "@blocksuite/affine-inline-link": "workspace:*", "@blocksuite/affine-inline-reference": "workspace:*", "@blocksuite/affine-model": "workspace:*", diff --git a/blocksuite/affine/inlines/preset/src/adapters/markdown/inline-delta.ts b/blocksuite/affine/inlines/preset/src/adapters/markdown/inline-delta.ts index c2d5b47e1c..4da24dabd1 100644 --- a/blocksuite/affine/inlines/preset/src/adapters/markdown/inline-delta.ts +++ b/blocksuite/affine/inlines/preset/src/adapters/markdown/inline-delta.ts @@ -1,11 +1,8 @@ import { footnoteReferenceDeltaToMarkdownAdapterMatcher } from '@blocksuite/affine-inline-footnote'; +import { latexDeltaToMarkdownAdapterMatcher } from '@blocksuite/affine-inline-latex'; import { linkDeltaToMarkdownAdapterMatcher } from '@blocksuite/affine-inline-link'; import { referenceDeltaToMarkdownAdapterMatcher } from '@blocksuite/affine-inline-reference'; import { InlineDeltaToMarkdownAdapterExtension } from '@blocksuite/affine-shared/adapters'; -import type { PhrasingContent } from 'mdast'; -import type RemarkMath from 'remark-math'; - -declare type _GLOBAL_ = typeof RemarkMath; export const boldDeltaToMarkdownAdapterMatcher = InlineDeltaToMarkdownAdapterExtension({ @@ -56,25 +53,6 @@ export const inlineCodeDeltaToMarkdownAdapterMatcher = }), }); -export const latexDeltaToMarkdownAdapterMatcher = - InlineDeltaToMarkdownAdapterExtension({ - name: 'inlineLatex', - match: delta => !!delta.attributes?.latex, - toAST: delta => { - const mdast: PhrasingContent = { - type: 'text', - value: delta.insert, - }; - if (delta.attributes?.latex) { - return { - type: 'inlineMath', - value: delta.attributes.latex, - }; - } - return mdast; - }, - }); - export const InlineDeltaToMarkdownAdapterExtensions = [ referenceDeltaToMarkdownAdapterMatcher, linkDeltaToMarkdownAdapterMatcher, diff --git a/blocksuite/affine/inlines/preset/src/adapters/markdown/markdown-inline.ts b/blocksuite/affine/inlines/preset/src/adapters/markdown/markdown-inline.ts index 6a92aea673..923aa5c417 100644 --- a/blocksuite/affine/inlines/preset/src/adapters/markdown/markdown-inline.ts +++ b/blocksuite/affine/inlines/preset/src/adapters/markdown/markdown-inline.ts @@ -1,4 +1,5 @@ import { markdownFootnoteReferenceToDeltaMatcher } from '@blocksuite/affine-inline-footnote'; +import { markdownInlineMathToDeltaMatcher } from '@blocksuite/affine-inline-latex'; import { markdownLinkToDeltaMatcher } from '@blocksuite/affine-inline-link'; import { MarkdownASTToDeltaExtension } from '@blocksuite/affine-shared/adapters'; @@ -78,17 +79,6 @@ export const markdownListToDeltaMatcher = MarkdownASTToDeltaExtension({ toDelta: () => [], }); -export const markdownInlineMathToDeltaMatcher = MarkdownASTToDeltaExtension({ - name: 'inlineMath', - match: ast => ast.type === 'inlineMath', - toDelta: ast => { - if (!('value' in ast)) { - return []; - } - return [{ insert: ' ', attributes: { latex: ast.value } }]; - }, -}); - export const MarkdownInlineToDeltaAdapterExtensions = [ markdownTextToDeltaMatcher, markdownInlineCodeToDeltaMatcher, diff --git a/blocksuite/affine/inlines/preset/src/adapters/plain-text/inline-delta.ts b/blocksuite/affine/inlines/preset/src/adapters/plain-text/inline-delta.ts index 19d78f7d98..cd191dd5f8 100644 --- a/blocksuite/affine/inlines/preset/src/adapters/plain-text/inline-delta.ts +++ b/blocksuite/affine/inlines/preset/src/adapters/plain-text/inline-delta.ts @@ -1,28 +1,8 @@ +import { latexDeltaMarkdownAdapterMatch } from '@blocksuite/affine-inline-latex'; import { linkDeltaMarkdownAdapterMatch } from '@blocksuite/affine-inline-link'; import { referenceDeltaMarkdownAdapterMatch } from '@blocksuite/affine-inline-reference'; -import { - InlineDeltaToPlainTextAdapterExtension, - type TextBuffer, -} from '@blocksuite/affine-shared/adapters'; import type { ExtensionType } from '@blocksuite/store'; -export const latexDeltaMarkdownAdapterMatch = - InlineDeltaToPlainTextAdapterExtension({ - name: 'inlineLatex', - match: delta => !!delta.attributes?.latex, - toAST: delta => { - const node: TextBuffer = { - content: delta.insert, - }; - if (!delta.attributes?.latex) { - return node; - } - return { - content: delta.attributes?.latex, - }; - }, - }); - export const InlineDeltaToPlainTextAdapterExtensions: ExtensionType[] = [ referenceDeltaMarkdownAdapterMatch, linkDeltaMarkdownAdapterMatch, diff --git a/blocksuite/affine/inlines/preset/src/command/index.ts b/blocksuite/affine/inlines/preset/src/command/index.ts index ebaafab5f3..51550bfdc2 100644 --- a/blocksuite/affine/inlines/preset/src/command/index.ts +++ b/blocksuite/affine/inlines/preset/src/command/index.ts @@ -9,7 +9,6 @@ export { deleteTextCommand } from './delete-text.js'; export { formatBlockCommand } from './format-block.js'; export { formatNativeCommand } from './format-native.js'; export { formatTextCommand } from './format-text.js'; -export { insertInlineLatex } from './insert-inline-latex.js'; export { getTextStyle, isTextStyleActive, diff --git a/blocksuite/affine/inlines/preset/src/default-inline-manager.ts b/blocksuite/affine/inlines/preset/src/default-inline-manager.ts index f30e971b91..b4351d9d83 100644 --- a/blocksuite/affine/inlines/preset/src/default-inline-manager.ts +++ b/blocksuite/affine/inlines/preset/src/default-inline-manager.ts @@ -1,4 +1,5 @@ import { FootNoteInlineSpecExtension } from '@blocksuite/affine-inline-footnote'; +import { LatexInlineSpecExtension } from '@blocksuite/affine-inline-latex'; import { LinkInlineSpecExtension } from '@blocksuite/affine-inline-link'; import { ReferenceInlineSpecExtension } from '@blocksuite/affine-inline-reference'; import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; @@ -10,7 +11,6 @@ import { CodeInlineSpecExtension, ColorInlineSpecExtension, ItalicInlineSpecExtension, - LatexInlineSpecExtension, StrikeInlineSpecExtension, UnderlineInlineSpecExtension, } from './inline-spec'; diff --git a/blocksuite/affine/inlines/preset/src/effects.ts b/blocksuite/affine/inlines/preset/src/effects.ts index 16d43674ef..253b87ce38 100644 --- a/blocksuite/affine/inlines/preset/src/effects.ts +++ b/blocksuite/affine/inlines/preset/src/effects.ts @@ -1,20 +1,11 @@ import { AffineText } from './nodes/affine-text'; -import { LatexEditorMenu } from './nodes/latex-node/latex-editor-menu'; -import { LatexEditorUnit } from './nodes/latex-node/latex-editor-unit'; -import { AffineLatexNode } from './nodes/latex-node/latex-node'; export function effects() { customElements.define('affine-text', AffineText); - customElements.define('latex-editor-menu', LatexEditorMenu); - customElements.define('latex-editor-unit', LatexEditorUnit); - customElements.define('affine-latex-node', AffineLatexNode); } declare global { interface HTMLElementTagNameMap { - 'affine-latex-node': AffineLatexNode; 'affine-text': AffineText; - 'latex-editor-unit': LatexEditorUnit; - 'latex-editor-menu': LatexEditorMenu; } } diff --git a/blocksuite/affine/inlines/preset/src/exts.ts b/blocksuite/affine/inlines/preset/src/exts.ts index a864a20b76..325433a37c 100644 --- a/blocksuite/affine/inlines/preset/src/exts.ts +++ b/blocksuite/affine/inlines/preset/src/exts.ts @@ -2,12 +2,10 @@ import { InlineAdapterExtensions } from './adapters/extensions'; import { DefaultInlineManagerExtension } from './default-inline-manager'; import { InlineSpecExtensions } from './inline-spec'; import { MarkdownExtensions } from './markdown'; -import { LatexEditorInlineManagerExtension } from './nodes/latex-node/latex-editor-menu'; export const inlinePresetExtensions = [ DefaultInlineManagerExtension, ...MarkdownExtensions, - LatexEditorInlineManagerExtension, ...InlineSpecExtensions, ...InlineAdapterExtensions, ]; diff --git a/blocksuite/affine/inlines/preset/src/inline-spec.ts b/blocksuite/affine/inlines/preset/src/inline-spec.ts index 4c2d878448..1200e09666 100644 --- a/blocksuite/affine/inlines/preset/src/inline-spec.ts +++ b/blocksuite/affine/inlines/preset/src/inline-spec.ts @@ -1,8 +1,8 @@ import { inlineFootnoteExtensions } from '@blocksuite/affine-inline-footnote'; +import { inlineLatexExtensions } from '@blocksuite/affine-inline-latex'; import { inlineLinkExtensions } from '@blocksuite/affine-inline-link'; import { inlineReferenceExtensions } from '@blocksuite/affine-inline-reference'; import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; -import { StdIdentifier } from '@blocksuite/block-std'; import { type InlineRootElement, InlineSpecExtension, @@ -97,37 +97,6 @@ export const ColorInlineSpecExtension = }, }); -export const LatexInlineSpecExtension = - InlineSpecExtension('latex', provider => { - const std = provider.get(StdIdentifier); - return { - name: 'latex', - schema: z.string().optional().nullable().catch(undefined), - match: delta => typeof delta.attributes?.latex === 'string', - renderer: ({ delta, selected, editor, startOffset, endOffset }) => { - return html``; - }, - embed: true, - }; - }); - -export const LatexEditorUnitSpecExtension = - InlineSpecExtension({ - name: 'latex-editor-unit', - schema: z.undefined(), - match: () => true, - renderer: ({ delta }) => { - return html``; - }, - }); - export const InlineSpecExtensions: ExtensionType[] = [ BoldInlineSpecExtension, ItalicInlineSpecExtension, @@ -136,9 +105,8 @@ export const InlineSpecExtensions: ExtensionType[] = [ CodeInlineSpecExtension, BackgroundInlineSpecExtension, ColorInlineSpecExtension, - LatexInlineSpecExtension, ...inlineLinkExtensions, ...inlineReferenceExtensions, - LatexEditorUnitSpecExtension, + ...inlineLatexExtensions, ...inlineFootnoteExtensions, ]; diff --git a/blocksuite/affine/inlines/preset/src/markdown.ts b/blocksuite/affine/inlines/preset/src/markdown.ts index 689f3f49be..936559266c 100644 --- a/blocksuite/affine/inlines/preset/src/markdown.ts +++ b/blocksuite/affine/inlines/preset/src/markdown.ts @@ -1,5 +1,6 @@ +import { LatexExtension } from '@blocksuite/affine-inline-latex'; +import { LinkExtension } from '@blocksuite/affine-inline-link'; import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; -import type { BlockComponent } from '@blocksuite/block-std'; import { InlineMarkdownExtension } from '@blocksuite/block-std/inline'; import type { ExtensionType } from '@blocksuite/store'; @@ -363,236 +364,6 @@ export const CodeExtension = InlineMarkdownExtension({ }, }); -export const LinkExtension = InlineMarkdownExtension({ - name: 'link', - pattern: /.*\[(.+?)\]\((.+?)\)$/, - action: ({ inlineEditor, prefixText, inlineRange, pattern, undoManager }) => { - const match = prefixText.match(pattern); - if (!match) return; - - const linkText = match[1]; - const linkUrl = match[2]; - const annotatedText = match[0].slice(-linkText.length - linkUrl.length - 4); - const startIndex = inlineRange.index - annotatedText.length; - - inlineEditor.insertText( - { - index: inlineRange.index, - length: 0, - }, - ' ' - ); - inlineEditor.setInlineRange({ - index: inlineRange.index + 1, - length: 0, - }); - - undoManager.stopCapturing(); - - // aaa[bbb](baidu.com) + space - - // delete (baidu.com) + space - inlineEditor.deleteText({ - index: startIndex + 1 + linkText.length + 1, - length: 1 + linkUrl.length + 1 + 1, - }); - // delete [ and ] - inlineEditor.deleteText({ - index: startIndex + 1 + linkText.length, - length: 1, - }); - inlineEditor.deleteText({ - index: startIndex, - length: 1, - }); - - inlineEditor.formatText( - { - index: startIndex, - length: linkText.length, - }, - { - link: linkUrl, - } - ); - - inlineEditor.setInlineRange({ - index: startIndex + linkText.length, - length: 0, - }); - }, -}); - -export const LatexExtension = InlineMarkdownExtension({ - name: 'latex', - - pattern: - /(?:\$\$)(?[^$]+)(?:\$\$)$|(?\$\$\$\$)|(?\$\$)$/g, - action: ({ inlineEditor, prefixText, inlineRange, pattern, undoManager }) => { - const match = pattern.exec(prefixText); - if (!match || !match.groups) return; - const content = match.groups['content']; - const inlinePrefix = match.groups['inlinePrefix']; - const blockPrefix = match.groups['blockPrefix']; - - if (blockPrefix === '$$$$') { - inlineEditor.insertText( - { - index: inlineRange.index, - length: 0, - }, - ' ' - ); - inlineEditor.setInlineRange({ - index: inlineRange.index + 1, - length: 0, - }); - - undoManager.stopCapturing(); - - if (!inlineEditor.rootElement) return; - const blockComponent = - inlineEditor.rootElement.closest('[data-block-id]'); - if (!blockComponent) return; - - const doc = blockComponent.doc; - const parentComponent = blockComponent.parentComponent; - if (!parentComponent) return; - - const index = parentComponent.model.children.indexOf( - blockComponent.model - ); - if (index === -1) return; - - inlineEditor.deleteText({ - index: inlineRange.index - 4, - length: 5, - }); - - const id = doc.addBlock( - 'affine:latex', - { - latex: '', - }, - parentComponent.model, - index + 1 - ); - blockComponent.host.updateComplete - .then(() => { - const latexBlock = blockComponent.std.view.getBlock(id); - if (!latexBlock || latexBlock.flavour !== 'affine:latex') return; - - //FIXME(@Flrande): wait for refactor - // @ts-expect-error BS-2241 - latexBlock.toggleEditor(); - }) - .catch(console.error); - - return; - } - - if (inlinePrefix === '$$') { - inlineEditor.insertText( - { - index: inlineRange.index, - length: 0, - }, - ' ' - ); - inlineEditor.setInlineRange({ - index: inlineRange.index + 1, - length: 0, - }); - - undoManager.stopCapturing(); - - inlineEditor.deleteText({ - index: inlineRange.index - 2, - length: 3, - }); - inlineEditor.insertText( - { - index: inlineRange.index - 2, - length: 0, - }, - ' ' - ); - inlineEditor.formatText( - { - index: inlineRange.index - 2, - length: 1, - }, - { - latex: '', - } - ); - - inlineEditor - .waitForUpdate() - .then(async () => { - await inlineEditor.waitForUpdate(); - - const textPoint = inlineEditor.getTextPoint( - inlineRange.index - 2 + 1 - ); - if (!textPoint) return; - - const [text] = textPoint; - const latexNode = text.parentElement?.closest('affine-latex-node'); - if (!latexNode) return; - - latexNode.toggleEditor(); - }) - .catch(console.error); - - return; - } - - if (!content || content.length === 0) return; - - inlineEditor.insertText( - { - index: inlineRange.index, - length: 0, - }, - ' ' - ); - inlineEditor.setInlineRange({ - index: inlineRange.index + 1, - length: 0, - }); - - undoManager.stopCapturing(); - - const startIndex = inlineRange.index - 2 - content.length - 2; - inlineEditor.deleteText({ - index: startIndex, - length: 2 + content.length + 2 + 1, - }); - inlineEditor.insertText( - { - index: startIndex, - length: 0, - }, - ' ' - ); - inlineEditor.formatText( - { - index: startIndex, - length: 1, - }, - { - latex: String.raw`${content}`, - } - ); - - inlineEditor.setInlineRange({ - index: startIndex + 1, - length: 0, - }); - }, -}); - export const MarkdownExtensions: ExtensionType[] = [ BoldItalicMarkdown, BoldMarkdown, diff --git a/blocksuite/affine/inlines/preset/tsconfig.json b/blocksuite/affine/inlines/preset/tsconfig.json index 6ecaf673d9..a2d342afa1 100644 --- a/blocksuite/affine/inlines/preset/tsconfig.json +++ b/blocksuite/affine/inlines/preset/tsconfig.json @@ -9,6 +9,7 @@ "references": [ { "path": "../../components" }, { "path": "../footnote" }, + { "path": "../latex" }, { "path": "../link" }, { "path": "../reference" }, { "path": "../../model" }, diff --git a/tools/utils/src/workspace.gen.ts b/tools/utils/src/workspace.gen.ts index 58c65dd496..7fbdd9aec4 100644 --- a/tools/utils/src/workspace.gen.ts +++ b/tools/utils/src/workspace.gen.ts @@ -31,6 +31,7 @@ export const PackageList = [ 'blocksuite/affine/gfx/text', 'blocksuite/affine/gfx/turbo-renderer', 'blocksuite/affine/inlines/footnote', + 'blocksuite/affine/inlines/latex', 'blocksuite/affine/inlines/link', 'blocksuite/affine/inlines/preset', 'blocksuite/affine/inlines/reference', @@ -101,6 +102,7 @@ export const PackageList = [ name: '@blocksuite/affine-block-code', workspaceDependencies: [ 'blocksuite/affine/components', + 'blocksuite/affine/inlines/latex', 'blocksuite/affine/inlines/link', 'blocksuite/affine/inlines/preset', 'blocksuite/affine/model', @@ -223,7 +225,7 @@ export const PackageList = [ workspaceDependencies: [ 'blocksuite/affine/blocks/block-note', 'blocksuite/affine/components', - 'blocksuite/affine/inlines/preset', + 'blocksuite/affine/inlines/latex', 'blocksuite/affine/model', 'blocksuite/affine/rich-text', 'blocksuite/affine/shared', @@ -302,6 +304,7 @@ export const PackageList = [ 'blocksuite/affine/components', 'blocksuite/affine/fragments/fragment-doc-title', 'blocksuite/affine/gfx/text', + 'blocksuite/affine/inlines/latex', 'blocksuite/affine/inlines/link', 'blocksuite/affine/inlines/preset', 'blocksuite/affine/inlines/reference', @@ -469,6 +472,20 @@ export const PackageList = [ 'blocksuite/framework/store', ], }, + { + location: 'blocksuite/affine/inlines/latex', + name: '@blocksuite/affine-inline-latex', + workspaceDependencies: [ + 'blocksuite/affine/components', + 'blocksuite/affine/inlines/reference', + 'blocksuite/affine/model', + 'blocksuite/affine/rich-text', + 'blocksuite/affine/shared', + 'blocksuite/framework/block-std', + 'blocksuite/framework/global', + 'blocksuite/framework/store', + ], + }, { location: 'blocksuite/affine/inlines/link', name: '@blocksuite/affine-inline-link', @@ -488,6 +505,7 @@ export const PackageList = [ workspaceDependencies: [ 'blocksuite/affine/components', 'blocksuite/affine/inlines/footnote', + 'blocksuite/affine/inlines/latex', 'blocksuite/affine/inlines/link', 'blocksuite/affine/inlines/reference', 'blocksuite/affine/model', @@ -1005,6 +1023,7 @@ export type PackageName = | '@blocksuite/affine-gfx-text' | '@blocksuite/affine-gfx-turbo-renderer' | '@blocksuite/affine-inline-footnote' + | '@blocksuite/affine-inline-latex' | '@blocksuite/affine-inline-link' | '@blocksuite/affine-inline-preset' | '@blocksuite/affine-inline-reference' diff --git a/tsconfig.json b/tsconfig.json index cff390bc93..6dae7c5932 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -78,6 +78,7 @@ { "path": "./blocksuite/affine/gfx/text" }, { "path": "./blocksuite/affine/gfx/turbo-renderer" }, { "path": "./blocksuite/affine/inlines/footnote" }, + { "path": "./blocksuite/affine/inlines/latex" }, { "path": "./blocksuite/affine/inlines/link" }, { "path": "./blocksuite/affine/inlines/preset" }, { "path": "./blocksuite/affine/inlines/reference" }, diff --git a/yarn.lock b/yarn.lock index 830d812c86..33edeac5ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2395,6 +2395,7 @@ __metadata: resolution: "@blocksuite/affine-block-code@workspace:blocksuite/affine/blocks/block-code" dependencies: "@blocksuite/affine-components": "workspace:*" + "@blocksuite/affine-inline-latex": "workspace:*" "@blocksuite/affine-inline-link": "workspace:*" "@blocksuite/affine-inline-preset": "workspace:*" "@blocksuite/affine-model": "workspace:*" @@ -2611,7 +2612,7 @@ __metadata: dependencies: "@blocksuite/affine-block-note": "workspace:*" "@blocksuite/affine-components": "workspace:*" - "@blocksuite/affine-inline-preset": "workspace:*" + "@blocksuite/affine-inline-latex": "workspace:*" "@blocksuite/affine-model": "workspace:*" "@blocksuite/affine-rich-text": "workspace:*" "@blocksuite/affine-shared": "workspace:*" @@ -2739,6 +2740,7 @@ __metadata: "@blocksuite/affine-components": "workspace:*" "@blocksuite/affine-fragment-doc-title": "workspace:*" "@blocksuite/affine-gfx-text": "workspace:*" + "@blocksuite/affine-inline-latex": "workspace:*" "@blocksuite/affine-inline-link": "workspace:*" "@blocksuite/affine-inline-preset": "workspace:*" "@blocksuite/affine-inline-reference": "workspace:*" @@ -3038,6 +3040,40 @@ __metadata: languageName: unknown linkType: soft +"@blocksuite/affine-inline-latex@workspace:*, @blocksuite/affine-inline-latex@workspace:blocksuite/affine/inlines/latex": + version: 0.0.0-use.local + resolution: "@blocksuite/affine-inline-latex@workspace:blocksuite/affine/inlines/latex" + dependencies: + "@blocksuite/affine-components": "workspace:*" + "@blocksuite/affine-inline-reference": "workspace:*" + "@blocksuite/affine-model": "workspace:*" + "@blocksuite/affine-rich-text": "workspace:*" + "@blocksuite/affine-shared": "workspace:*" + "@blocksuite/block-std": "workspace:*" + "@blocksuite/global": "workspace:*" + "@blocksuite/icons": "npm:^2.2.6" + "@blocksuite/store": "workspace:*" + "@floating-ui/dom": "npm:^1.6.13" + "@lit/context": "npm:^1.1.2" + "@preact/signals-core": "npm:^1.8.0" + "@toeverything/theme": "npm:^1.1.12" + "@types/hast": "npm:^3.0.4" + "@types/katex": "npm:^0.16.7" + "@types/lodash-es": "npm:^4.17.12" + collapse-white-space: "npm:^2.1.0" + date-fns: "npm:^4.0.0" + katex: "npm:^0.16.11" + lit: "npm:^3.2.0" + lit-html: "npm:^3.2.1" + lodash-es: "npm:^4.17.21" + remark-math: "npm:^6.0.0" + rxjs: "npm:^7.8.1" + shiki: "npm:^3.0.0" + yjs: "npm:^13.6.21" + zod: "npm:^3.23.8" + languageName: unknown + linkType: soft + "@blocksuite/affine-inline-link@workspace:*, @blocksuite/affine-inline-link@workspace:blocksuite/affine/inlines/link": version: 0.0.0-use.local resolution: "@blocksuite/affine-inline-link@workspace:blocksuite/affine/inlines/link" @@ -3072,6 +3108,7 @@ __metadata: dependencies: "@blocksuite/affine-components": "workspace:*" "@blocksuite/affine-inline-footnote": "workspace:*" + "@blocksuite/affine-inline-latex": "workspace:*" "@blocksuite/affine-inline-link": "workspace:*" "@blocksuite/affine-inline-reference": "workspace:*" "@blocksuite/affine-model": "workspace:*" @@ -3399,6 +3436,7 @@ __metadata: "@blocksuite/affine-gfx-text": "workspace:*" "@blocksuite/affine-gfx-turbo-renderer": "workspace:*" "@blocksuite/affine-inline-footnote": "workspace:*" + "@blocksuite/affine-inline-latex": "workspace:*" "@blocksuite/affine-inline-link": "workspace:*" "@blocksuite/affine-inline-preset": "workspace:*" "@blocksuite/affine-inline-reference": "workspace:*"