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

Markdown Package #2937

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Markdown Package #2937

wants to merge 10 commits into from

Conversation

juliaroldi
Copy link
Contributor

@juliaroldi juliaroldi commented Feb 5, 2025

This change introduces the rooosterjs-content-model-markdown package, which is responsible for converting plain text written in Markdown into a content model structure. All the basic syntax except for alternative heading, HTML and code are supported. The package provides a single public function, convertMarkdownToContentModel, which handles the conversion of plain text and inserts it into the editor.

The conversion process involves dividing the plain text by line breaks and identifying the appropriate content model blocks based on the Markdown syntax. The text is divided by the regex /\r\n|\r|\\n|\n/, but the splitLinesPattern parameter allows to replace this regex with another one.

image

All the created content model blocks are inserted into a new model document in the order they appear in the plain text, and after all the plain text is processed, the new content model document is merged in the editor.

MardownTranformation

@juliaroldi juliaroldi changed the title [WIP] Markdown Markdown Package Feb 19, 2025
@juliaroldi juliaroldi marked this pull request as ready for review February 19, 2025 21:44
text: string,
blockquote?: ContentModelFormatContainer
): ContentModelFormatContainer {
text = text.replace('>', '');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace function only replace the first element found, to replace all we need to use />/g

* @internal
*/
export function applyLink(textSegment: ContentModelText): ContentModelText {
const linkRegex = /\[([^\[]+)\]\((https?:\/\/[^\s\)]+)\)/g;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already regex matches in splitLinkAndImages, so I think we just need to match once there, then create segments at once, no need to split then match again.

text: string,
splitLinesPattern?: string
) {
editor.formatContentModel(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest this API does not have dependency to editor. It should just take string as input, and ContentModelDocument as output

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole package should not have dependency to editor

* @internal
*/
export function createImageSegment(textSegment: ContentModelText): ContentModelImage | undefined {
const imageRegex = /\!\[([^\[]+)\]\((https?:\/\/[^\)]+)\)/g;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

/**
* @internal
*/
export function createListFromMarkdown(text: string, patternName: string): ContentModelListItem {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better make the patternName strong-typed

*/
export function createListFromMarkdown(text: string, patternName: string): ContentModelListItem {
const listType = patternName === 'ordered_list' ? 'OL' : 'UL';
const itemText = text.trim().substring(listType == 'OL' ? 2 : 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why 2? what if list item "100"

*/
export function createTableFromMarkdown(tableLines: string[]): ContentModelTable {
const tableDivider = tableLines[1].split('|').filter(content => content.trim() !== '');
const tableModel = tableLines.filter(line => tableLines.indexOf(line) !== 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks weird. If you want to remove lines[1], just use tableLines.splice(1,1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants