Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add paste from markdown experimental #15393

Merged
merged 39 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
4dce8d9
Feature: Paste from markdown PoC.
martnpaneq Oct 20, 2023
229d8ca
Added tests for paste from markdown.
martnpaneq Oct 23, 2023
80464f7
Cleaned up tests for a previous version.
martnpaneq Oct 30, 2023
aeb964e
Improved paste from markdown to detect markdown in HTML clipboard.
martnpaneq Oct 30, 2023
d97203d
Addded tests for paste from markdown.
martnpaneq Oct 31, 2023
c80ce50
Merge branch 'master' into ck/2321-paste-from-markdown
pomek Nov 7, 2023
0d94ac1
Extracted paste from markdown to a separate plugin as PasteFromMarkdo…
martnpaneq Nov 9, 2023
6b8b1ab
Added manual test for paste from markdown.
martnpaneq Nov 9, 2023
8ed8509
Added missing type augmentation for paste from markdown.
martnpaneq Nov 9, 2023
d178734
Added docs snippets for paste from markdown.
martnpaneq Nov 9, 2023
be999a3
Review fixes.
pomek Nov 10, 2023
2f41f3a
Merge branch 'master' into ck/2321-paste-from-markdown
pomek Nov 10, 2023
27312f0
Updated paste from markdown component to handle lists copied as `text…
martnpaneq Nov 10, 2023
e588a2a
Docs: guide placeholder. [short flow]
godai78 Nov 10, 2023
e925a0d
Docs: link fix. [short flow]
godai78 Nov 13, 2023
01ec018
Docs: adjustments. [short flow]
godai78 Nov 13, 2023
e819d1c
Clean up.
pomek Nov 13, 2023
4e4d357
Docs: link fixes; demo unification; various updates. [short flow]
godai78 Nov 14, 2023
0ac5e90
Docs: a typo.
godai78 Nov 14, 2023
96cca19
Docs: markdown example file.
godai78 Nov 15, 2023
43c9a3f
Merge branch 'master' into ck/2321-paste-from-markdown
godai78 Nov 16, 2023
80e4a7b
Docs: rename; crosslinking. [short flow]
godai78 Nov 17, 2023
40fa4bf
Merge branch 'master' into ck/2321-paste-from-markdown
pomek Nov 22, 2023
a0e11ad
Fixed pasting block quotes and fixed test coverage for paste from mar…
martnpaneq Nov 22, 2023
fe9db28
Removed todos from docs and manual tests.
martnpaneq Nov 22, 2023
2890cba
Review fixes.
pomek Nov 23, 2023
393ed71
Removed not needed `@private` tags in JSDoc.
martnpaneq Nov 23, 2023
82770e9
Addressed docs issues.
pomek Nov 24, 2023
6d8f1bf
Merge branch 'master' into ck/2321-paste-from-markdown
godai78 Nov 24, 2023
0fb3cdb
Docs: updating demos; meta data. [short flow]
godai78 Nov 24, 2023
003c5ee
Paste markdown logic improvements after review.
martnpaneq Nov 24, 2023
288837c
Fix test.
martnpaneq Nov 24, 2023
fec4a16
Changed logic to not parse markdown for first level formatting tags.
martnpaneq Nov 29, 2023
8730c57
Merge branch 'master' into ck/2321-paste-from-markdown
godai78 Dec 1, 2023
f68a762
Changed list of exclusions to list of accepted first level markdown t…
martnpaneq Dec 1, 2023
2f320d2
Added `CODE` to `ALLOWED_MARKDOWN_FIRST_LEVEL_TAGS` for Windows compa…
martnpaneq Dec 1, 2023
6c380b3
Changed logic in `_containsOnlyAllowedTags()` to use regex and not `D…
martnpaneq Dec 1, 2023
56606fe
Revert "Changed logic in `_containsOnlyAllowedTags()` to use regex an…
martnpaneq Dec 1, 2023
663babb
Final refactoring.
martnpaneq Dec 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Feel free to open a [new feature request](https://github.com/ckeditor/ckeditor5/
## Related features

CKEditor 5 supports a wider range of paste features, including:
* {@link features/paste-markdown Paste Markdown} – Paste Markdown formatted content straight into the editor.
* {@link features/paste-from-office Paste from Office} – Paste content from Microsoft Word and maintain the original structure and formatting.
* {@link features/paste-from-google-docs Paste from Google Docs} – Paste content from Google Docs, maintaining the original formatting and structure.
* {@link features/import-word Import from Word} – Convert Word files directly into HTML content.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { CodeBlock } from '@ckeditor/ckeditor5-code-block';
import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
import { CKBox, CKBoxImageEdit } from '@ckeditor/ckeditor5-ckbox';
import { HorizontalLine } from '@ckeditor/ckeditor5-horizontal-line';
import { ImageUpload, ImageInsert, PictureEditing } from '@ckeditor/ckeditor5-image';
import { ImageUpload, ImageInsert, PictureEditing, AutoImage } from '@ckeditor/ckeditor5-image';
import { TodoList } from '@ckeditor/ckeditor5-list';
import { SourceEditing } from '@ckeditor/ckeditor5-source-editing';

Expand All @@ -23,8 +23,8 @@ import { Markdown } from '@ckeditor/ckeditor5-markdown-gfm';
ClassicEditor
.create( document.querySelector( '#snippet-markdown' ), {
plugins: [
ArticlePluginSet, SourceEditing, CKBox, CKBoxImageEdit, ImageInsert, ImageUpload, PictureEditing, CloudServices, Markdown,
Code, CodeBlock, TodoList, Strikethrough, HorizontalLine
ArticlePluginSet, SourceEditing, CKBox, CKBoxImageEdit, ImageInsert, ImageUpload, PictureEditing, AutoImage,
CloudServices, Markdown, Code, CodeBlock, TodoList, Strikethrough, HorizontalLine
],
toolbar: {
items: [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script src="https://cdn.ckbox.io/ckbox/latest/ckbox.js"></script>
<textarea id="snippet-paste-from-markdown">

&lt;h2&gt;Markdown output 🛫&lt;/h2&gt;

</textarea>

<p>Output:</p>

<pre><code id="snippet-paste-from-markdown-output"></code></pre>
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/* globals console, window, document, setTimeout */

import { Code, Strikethrough, Underline } from '@ckeditor/ckeditor5-basic-styles';
import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
import { CodeBlock } from '@ckeditor/ckeditor5-code-block';
import { HorizontalLine } from '@ckeditor/ckeditor5-horizontal-line';
import { SourceEditing } from '@ckeditor/ckeditor5-source-editing';
import { DocumentList, TodoDocumentList, AdjacentListsSupport } from '@ckeditor/ckeditor5-list';
import { Markdown, PasteFromMarkdownExperimental } from '@ckeditor/ckeditor5-markdown-gfm';
import { CKBox, CKBoxImageEdit } from '@ckeditor/ckeditor5-ckbox';
import { PictureEditing, ImageInsert, ImageResize, AutoImage } from '@ckeditor/ckeditor5-image';
import { LinkImage } from '@ckeditor/ckeditor5-link';
import { Font } from '@ckeditor/ckeditor5-font';

// Umberto combines all `packages/*/docs` into the `docs/` directory. The import path must be valid after merging all directories.
import ClassicEditor from '../build-classic';

const plugins = ClassicEditor.builtinPlugins
// Remove the `List` plugin as in a single demo we want to use the Document list feature.
martnpaneq marked this conversation as resolved.
Show resolved Hide resolved
.filter( pluginConstructor => {
if ( pluginConstructor.pluginName === 'List' ) {
return false;
}

return true;
} )
// Then, add Markdown-specific features.
.concat( [
SourceEditing, Code, Strikethrough, Underline, Markdown, CodeBlock, HorizontalLine, DocumentList, TodoDocumentList,
AdjacentListsSupport, PasteFromMarkdownExperimental, CKBox, CKBoxImageEdit,
PictureEditing, ImageInsert, ImageResize, AutoImage, LinkImage, Font
] );

ClassicEditor
.create( document.querySelector( '#snippet-paste-from-markdown' ), {
plugins,
toolbar: {
items: [
'undo', 'redo', '|', 'sourceEditing', '|', 'heading',
'|', 'bold', 'italic', 'underline', 'strikethrough', 'code',
'-', 'link', 'insertImage', 'insertTable', 'mediaEmbed', 'blockQuote', 'codeBlock', 'horizontalLine',
'|', 'bulletedList', 'numberedList', 'todoList', 'outdent', 'indent'
],
shouldNotGroupWhenFull: true
},
cloudServices: CS_CONFIG,
image: {
toolbar: [
'imageStyle:inline',
'imageStyle:block',
'imageStyle:side',
'|',
'toggleImageCaption',
'imageTextAlternative',
'|',
'ckboxImageEdit'
]
},
codeBlock: {
languages: [
{ language: 'css', label: 'CSS' },
{ language: 'html', label: 'HTML' },
{ language: 'javascript', label: 'JavaScript' },
{ language: 'php', label: 'PHP' }
]
},
ui: {
viewportOffset: {
top: window.getViewportTopOffsetConfig()
}
}
} )
.then( editor => {
window.editor = editor;

const outputElement = document.querySelector( '#snippet-paste-from-markdown-output' );

editor.model.document.on( 'change', () => {
outputElement.innerText = editor.getData();
} );

// Set the initial data with delay so hightlight.js doesn't catch it.
setTimeout( () => {
outputElement.innerText = editor.getData();
}, 500 );
} )
.catch( err => {
console.error( err.stack );
} );
72 changes: 72 additions & 0 deletions packages/ckeditor5-markdown-gfm/docs/assets/markdown.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Headings of various kinds
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading


## Various ways to create horizontal rules

___

---

***

## Basic formatting

**This is bold text**

__This is bold text__

*This is italic text*

_This is italic text_

~~Strikethrough~~


## Block quotes

> Basic block quotes


## Lists

Unordered lists

+ A list is created by starting a line with `+`, `-`, or `*`.
+ Indenting an item by two spaces will turn it into a sub-list.
+ That can be nested further:
+ Like this!

Ordered lists

1. You can create ordered lists...
2. ...with sequential numbers...
3. ...incrementing by 1.


1. Or you can just use 1...
1. ...for all the items.

## Code formatting

This covers either inline `code`...

```
Or a code block.
```

## Tables

| Header | Header |
| ------ | ----------- |
| Tables are tricky | And need some special care |

## Links
[CKEditor 5 main site](https://ckeditor.com/)

## Images

![CKEditor 5](https://user-images.githubusercontent.com/1099479/179190754-f4aaf2b3-21cc-49c4-a454-8de4a00cc70e.jpg)
4 changes: 3 additions & 1 deletion packages/ckeditor5-markdown-gfm/docs/features/markdown.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: Markdown output
meta-title: Markdown output | CKEditor 5 Documentation
meta-description: The Markdown plugin lets you switch the default CKEditor 5 output from HTML to Markdown.
category: features
---

Expand Down Expand Up @@ -41,7 +42,7 @@ editor.setData( 'This is **bold**.' );

The data processor outputs the GFM Markdown syntax. "GFM" stands for "GitHub Flavored Markdown" &ndash; a Markdown dialect used by [GitHub](https://github.com). Markdown lacks any formal specification (although the [CommonMark](https://commonmark.org/) initiative aims to close this gap) and has many dialects, often incompatible with one another.

When converting the output produced by this data processor, make sure to use a compatible Markdown-to-HTML converter (for example the [marked](https://www.npmjs.com/package/marked) library).
When converting the output produced by this data processor, make sure to use a compatible Markdown-to-HTML converter (for example, the [marked](https://www.npmjs.com/package/marked) library).

<info-box info>
While the CKEditor&nbsp;5 architecture supports changing the data format, in most scenarios we do recommend sticking to the default format which is HTML (supported by the {@link module:engine/dataprocessor/htmldataprocessor~HtmlDataProcessor}). HTML remains [the best standard for rich-text data](https://medium.com/content-uneditable/a-standard-for-rich-text-data-4b3a507af552).
Expand Down Expand Up @@ -116,6 +117,7 @@ Some other ways to output the edited content include:
* {@link features/export-word Export to Word} &ndash; Generate editable `.docx` files out of your editor-created content.
* {@link features/export-pdf Export to PDF} &ndash; Generate portable PDF files out of your editor-created content.
* {@link features/autoformat Autoformatting} &ndash; Use Markdown syntax shortcodes to automatically format your content as you type!
* {@link features/paste-markdown Paste Markdown} &ndash; Paste Markdown formatted content straight into the editor.

## Contribute

Expand Down
88 changes: 88 additions & 0 deletions packages/ckeditor5-markdown-gfm/docs/features/paste-markdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
menu-title: Paste Markdown
meta-title: Paste Markdown | CKEditor 5 Documentation
meta-description: The paste Markdown feature lets users paste Markdown-formatted content straight into CKEditor 5.
category: features-pasting
order: 40
modified_at: 2023-11-24
---

# Paste Markdown

The paste Markdown feature lets users paste Markdown-formatted content straight into the editor. It will be then converted into rich text on the fly.

<info-box warning>
This feature is still in the experimental phase. See the [known issues](#known-issues) section to learn more.
</info-box>

## Demo

Simply paste some Markdown-formatted content into the demo editor below and see it turn into rich text on the fly. You can copy [this document](%BASE_PATH%/assets/markdown.txt) for convenience.

{@snippet features/paste-from-markdown}

<info-box info>
This demo only presents a limited set of features. Visit the {@link examples/builds/full-featured-editor feature-rich editor example} to see more in action.
</info-box>

## Installation

<info-box info>
This feature is not available in any of the {@link installation/getting-started/predefined-builds predefined builds}.
</info-box>

To enable this data processor in your editor, install the [`@ckeditor/ckeditor5-markdown-gfm`](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm) package:

```
npm install --save @ckeditor/ckeditor5-markdown-gfm
```

Then add the {@link module:markdown-gfm/pastefrommarkdownexperimental~PasteFromMarkdownExperimental} plugin to the editor configuration:

```js
import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic';

import { Bold, Italic } from '@ckeditor/ckeditor5-basic-styles';
import { Essentials } from '@ckeditor/ckeditor5-essentials';
// More imports.
// ...

import { PasteFromMarkdownExperimental } from '@ckeditor/ckeditor5-markdown-gfm';

ClassicEditor
.create( document.querySelector( '#snippet-markdown' ), {
plugins: [
PasteFromMarkdownExperimental,
Essentials,
Bold,
Italic,
// More plugins.
// ...
],
// More of editor's config.
// ...
} )
.then( /* ... */ )
.catch( /* ... */ );

```

<info-box info>
Read more about {@link installation/plugins/installing-plugins installing plugins}.
</info-box>

## Known issues

While the Paste Markdown feature is already stable enough to use it, please remember it still needs some more testing. We are now mostly concentrating on testing it in connection with other tools and plugins. If you have any observations, suggestions or other piece of information you want to share with us, feel free to put them in [this GitHub issue](https://github.com/ckeditor/ckeditor5/issues/2321).

## Related features

CKEditor&nbsp;5 supports a wider range of paste features, including:
* {@link features/paste-from-office Paste from Office} &ndash; Paste content from Microsoft Word and maintain the original structure and formatting.
* {@link features/paste-from-google-docs Paste from Google Docs} &ndash; Paste content from Google Docs, maintaining the original formatting and structure.
* {@link features/paste-plain-text Paste plain text} &ndash; Paste text without formatting that will inherit the style of the content it was pasted into.
* {@link features/autoformat Autoformatting} &ndash; Format your content on the go with Markdown-like shortcodes.

## Contribute

The source code of the feature is available on GitHub at [https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-markdown-gfm](https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-markdown-gfm)
14 changes: 14 additions & 0 deletions packages/ckeditor5-markdown-gfm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,29 @@
"turndown-plugin-gfm": "1.0.2"
},
"devDependencies": {
"@ckeditor/ckeditor5-autoformat":"40.1.0",
"@ckeditor/ckeditor5-basic-styles": "40.1.0",
"@ckeditor/ckeditor5-block-quote": "40.1.0",
"@ckeditor/ckeditor5-clipboard": "40.1.0",
"@ckeditor/ckeditor5-code-block": "40.1.0",
"@ckeditor/ckeditor5-core": "40.1.0",
"@ckeditor/ckeditor5-dev-utils": "^39.0.0",
"@ckeditor/ckeditor5-editor-classic": "40.1.0",
"@ckeditor/ckeditor5-engine": "40.1.0",
"@ckeditor/ckeditor5-essentials": "40.1.0",
"@ckeditor/ckeditor5-font": "40.1.0",
"@ckeditor/ckeditor5-heading":"40.1.0",
"@ckeditor/ckeditor5-horizontal-line": "40.1.0",
"@ckeditor/ckeditor5-image": "40.1.0",
"@ckeditor/ckeditor5-indent":"40.1.0",
"@ckeditor/ckeditor5-link": "40.1.0",
"@ckeditor/ckeditor5-list": "40.1.0",
"@ckeditor/ckeditor5-media-embed":"40.1.0",
"@ckeditor/ckeditor5-paragraph": "40.1.0",
"@ckeditor/ckeditor5-table": "40.1.0",
"@ckeditor/ckeditor5-theme-lark": "40.1.0",
"@ckeditor/ckeditor5-undo": "40.1.0",
"@ckeditor/ckeditor5-utils": "40.1.0",
"@types/marked": "^4.0.8",
"typescript": "^4.8.4",
"webpack": "^5.58.1",
Expand Down
3 changes: 2 additions & 1 deletion packages/ckeditor5-markdown-gfm/src/augmentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

import type { Markdown } from './index';
import type { Markdown, PasteFromMarkdownExperimental } from './index';

declare module '@ckeditor/ckeditor5-core' {
interface PluginsMap {
[ Markdown.pluginName ]: Markdown;
[ PasteFromMarkdownExperimental.pluginName ]: PasteFromMarkdownExperimental;
}
}
1 change: 1 addition & 0 deletions packages/ckeditor5-markdown-gfm/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
*/

export { default as Markdown } from './markdown';
export { default as PasteFromMarkdownExperimental } from './pastefrommarkdownexperimental';

import './augmentation';
Loading