From df32291dc60257bfa8ad3ea9c6c68fc614635dad Mon Sep 17 00:00:00 2001 From: Maksim Ivanov Date: Sat, 30 Mar 2024 21:38:14 +0300 Subject: [PATCH] feat: add markdown extension (#937) --- projects/demo/src/app/app.pages.ts | 14 +- projects/demo/src/app/app.routes.ts | 5 + projects/demo/src/app/constants/demo-path.ts | 1 + .../markdown-extension/examples/1/index.html | 15 ++ .../markdown-extension/examples/1/index.ts | 86 ++++++++++ .../processing/markdown-extension/index.html | 11 ++ .../processing/markdown-extension/index.ts | 17 ++ .../app/pages/processing/markdown/index.html | 2 +- .../src/components/editor/editor.component.ts | 4 +- .../extensions/markdown/clipboard/index.ts | 51 ++++++ .../src/extensions/markdown/extensions/all.ts | 45 +++++ .../markdown/extensions/marks/bold.ts | 17 ++ .../markdown/extensions/marks/code.ts | 17 ++ .../markdown/extensions/marks/html.ts | 52 ++++++ .../markdown/extensions/marks/italic.ts | 17 ++ .../markdown/extensions/marks/link.ts | 17 ++ .../markdown/extensions/marks/strike.ts | 16 ++ .../markdown/extensions/nodes/blockquote.ts | 17 ++ .../markdown/extensions/nodes/bullet-list.ts | 28 +++ .../markdown/extensions/nodes/code-block.ts | 35 ++++ .../markdown/extensions/nodes/hard-break.ts | 36 ++++ .../markdown/extensions/nodes/heading.ts | 17 ++ .../extensions/nodes/horizontal-rule.ts | 17 ++ .../markdown/extensions/nodes/html.ts | 58 +++++++ .../markdown/extensions/nodes/image.ts | 17 ++ .../markdown/extensions/nodes/list-item.ts | 17 ++ .../markdown/extensions/nodes/ordered-list.ts | 45 +++++ .../markdown/extensions/nodes/paragraph.ts | 17 ++ .../markdown/extensions/nodes/table.ts | 90 ++++++++++ .../markdown/extensions/nodes/task-item.ts | 38 +++++ .../markdown/extensions/nodes/task-list.ts | 29 ++++ .../markdown/extensions/nodes/text.ts | 21 +++ .../src/extensions/markdown/index.ts | 3 + .../extensions/markdown/markdown.extension.ts | 75 +++++++++ .../src/extensions/markdown/ng-package.json | 5 + .../markdown/parse/markdown-parser.ts | 141 ++++++++++++++++ .../markdown/serialize/markdown-serializer.ts | 101 +++++++++++ .../extensions/markdown/serialize/state.ts | 71 ++++++++ .../extensions/markdown/tight-lists/index.ts | 47 ++++++ .../src/extensions/markdown/util/dom.ts | 38 +++++ .../extensions/markdown/util/extensions.ts | 16 ++ .../markdown/util/markdown-it-task-lists.ts | 159 ++++++++++++++++++ .../src/extensions/markdown/util/markdown.ts | 86 ++++++++++ .../extensions/markdown/util/prosemirror.ts | 3 + projects/tui-editor/src/index.ts | 1 + 45 files changed, 1611 insertions(+), 4 deletions(-) create mode 100644 projects/demo/src/app/pages/processing/markdown-extension/examples/1/index.html create mode 100644 projects/demo/src/app/pages/processing/markdown-extension/examples/1/index.ts create mode 100644 projects/demo/src/app/pages/processing/markdown-extension/index.html create mode 100644 projects/demo/src/app/pages/processing/markdown-extension/index.ts create mode 100644 projects/tui-editor/src/extensions/markdown/clipboard/index.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/all.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/marks/bold.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/marks/code.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/marks/html.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/marks/italic.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/marks/link.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/marks/strike.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/blockquote.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/bullet-list.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/code-block.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/hard-break.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/heading.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/horizontal-rule.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/html.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/image.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/list-item.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/ordered-list.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/paragraph.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/table.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/task-item.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/task-list.ts create mode 100644 projects/tui-editor/src/extensions/markdown/extensions/nodes/text.ts create mode 100644 projects/tui-editor/src/extensions/markdown/index.ts create mode 100644 projects/tui-editor/src/extensions/markdown/markdown.extension.ts create mode 100644 projects/tui-editor/src/extensions/markdown/ng-package.json create mode 100644 projects/tui-editor/src/extensions/markdown/parse/markdown-parser.ts create mode 100644 projects/tui-editor/src/extensions/markdown/serialize/markdown-serializer.ts create mode 100644 projects/tui-editor/src/extensions/markdown/serialize/state.ts create mode 100644 projects/tui-editor/src/extensions/markdown/tight-lists/index.ts create mode 100644 projects/tui-editor/src/extensions/markdown/util/dom.ts create mode 100644 projects/tui-editor/src/extensions/markdown/util/extensions.ts create mode 100644 projects/tui-editor/src/extensions/markdown/util/markdown-it-task-lists.ts create mode 100644 projects/tui-editor/src/extensions/markdown/util/markdown.ts create mode 100644 projects/tui-editor/src/extensions/markdown/util/prosemirror.ts diff --git a/projects/demo/src/app/app.pages.ts b/projects/demo/src/app/app.pages.ts index 44503d929..4a3377258 100644 --- a/projects/demo/src/app/app.pages.ts +++ b/projects/demo/src/app/app.pages.ts @@ -150,9 +150,21 @@ export const DEMO_PAGES: TuiDocPages = [ 'editor, processing, content, cleanup html, wysiwyg, редактор, текст, html, rich, text', route: `/${TuiDemoPath.ProcessingCleanupHtml}`, }, + ], + }, + { + section: 'Documentation', + title: 'Markdown', + subPages: [ + { + section: 'Documentation', + title: 'Extension', + keywords: 'editor, markdown, wysiwyg, редактор, текст, html, rich, text', + route: `/${TuiDemoPath.ProcessingMarkdownExtension}`, + }, { section: 'Documentation', - title: 'Markdown', + title: 'Custom parsing', keywords: 'editor, markdown, wysiwyg, редактор, текст, html, rich, text', route: `/${TuiDemoPath.ProcessingMarkdown}`, }, diff --git a/projects/demo/src/app/app.routes.ts b/projects/demo/src/app/app.routes.ts index 727ef485b..be115a69a 100644 --- a/projects/demo/src/app/app.routes.ts +++ b/projects/demo/src/app/app.routes.ts @@ -104,6 +104,11 @@ export const routes: Routes = [ loadComponent: async () => import('./pages/processing/markdown'), title: 'Editor — Markdown', }), + route({ + path: TuiDemoPath.ProcessingMarkdownExtension, + loadComponent: async () => import('./pages/processing/markdown-extension'), + title: 'Editor — Markdown', + }), route({ path: TuiDemoPath.HighlightCode, loadComponent: async () => import('./pages/highlight/code'), diff --git a/projects/demo/src/app/constants/demo-path.ts b/projects/demo/src/app/constants/demo-path.ts index 26db977dd..7e8ad1f2f 100644 --- a/projects/demo/src/app/constants/demo-path.ts +++ b/projects/demo/src/app/constants/demo-path.ts @@ -23,6 +23,7 @@ export const TuiDemoPath = { ProcessingCleanupHtml: 'processing/cleanup-html', ProcessingLegacyHtml: 'processing/legacy-html', ProcessingMarkdown: 'processing/markdown', + ProcessingMarkdownExtension: 'processing/markdown-extension', Stackblitz: 'stackblitz', StarterKit: 'starter-kit', UploadFiles: 'upload-files', diff --git a/projects/demo/src/app/pages/processing/markdown-extension/examples/1/index.html b/projects/demo/src/app/pages/processing/markdown-extension/examples/1/index.html new file mode 100644 index 000000000..ec41d53eb --- /dev/null +++ b/projects/demo/src/app/pages/processing/markdown-extension/examples/1/index.html @@ -0,0 +1,15 @@ + + Placeholder + + + + Markdown + diff --git a/projects/demo/src/app/pages/processing/markdown-extension/examples/1/index.ts b/projects/demo/src/app/pages/processing/markdown-extension/examples/1/index.ts new file mode 100644 index 000000000..3ec1960e8 --- /dev/null +++ b/projects/demo/src/app/pages/processing/markdown-extension/examples/1/index.ts @@ -0,0 +1,86 @@ +import type {OnInit} from '@angular/core'; +import {ChangeDetectionStrategy, Component, inject, ViewChild} from '@angular/core'; +import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {TuiDestroyService} from '@taiga-ui/cdk'; +import {TuiTextareaModule} from '@taiga-ui/kit'; +import { + TUI_EDITOR_EXTENSIONS, + TuiEditorComponent, + TuiEditorTool, +} from '@tinkoff/tui-editor'; +import type {Editor} from '@tiptap/core'; +import {debounceTime, Subject, takeUntil} from 'rxjs'; + +const markdown = `# h1 Heading 😎 + +## h2 Heading + +### h3 Heading + +#### h4 Heading + +##### h5 Heading + +###### h6 Heading + +---- + +![image info](./assets/icons/logo.svg) +`; + +@Component({ + standalone: true, + imports: [TuiEditorComponent, ReactiveFormsModule, TuiTextareaModule, FormsModule], + templateUrl: './index.html', + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ + { + provide: TUI_EDITOR_EXTENSIONS, + useValue: [ + import('@tiptap/starter-kit').then(({StarterKit}) => StarterKit), + import('@tiptap/extension-image').then(({Image}) => + Image.configure({inline: true}), + ), + import('@tinkoff/tui-editor').then(({TuiMarkdown}) => + TuiMarkdown.configure({ + html: true, // Allow HTML input/output + tightLists: true, // No

inside

  • in markdown output + tightListClass: 'tight', // Add class to