Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
Fix codeblock parsing (#738)
Browse files Browse the repository at this point in the history
* add codeblock tests to Rust
* add tests and improve newline behaviour in TS
  • Loading branch information
alunturner committed Jun 30, 2023
1 parent a4da9ff commit 61cdc44
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@ impl MarkdownHTMLParser {
.replace("<br />\n", "<br />")
.replace("<blockquote>\n", "<blockquote>")
.replace("</blockquote>\n", "</blockquote>")
.replace("<pre>\n", "<pre>")
.replace("</pre>\n", "</pre>")
.replace("<p>\n", "<p>")
.replace("</p>\n", "</p>");

// Remove the newline from the end of the single code tag that wraps the content
// of a formatted codeblock
let html = html.replace("\n</code>", "</code>");

Ok(S::try_from(html).unwrap())
}
}
9 changes: 9 additions & 0 deletions crates/wysiwyg/src/tests/test_set_content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,12 @@ fn set_content_from_markdown_blockquote_multiline() {
"<blockquote><p>quote</p></blockquote><p>following text|</p>"
);
}

#[test]
fn set_content_from_markdown_codeblock_with_newlines() {
let mut model = cm("|");
model
.set_content_from_markdown(&utf16("```\nI am a code block\n```"))
.unwrap();
assert_eq!(tx(&model), "<pre><code>I am a code block|</code></pre>");
}
28 changes: 25 additions & 3 deletions platforms/web/lib/conversion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,30 @@ describe('Rich text <=> plain text', () => {

expect(convertedRichText).toBe(expectedRichText);
});

it('converts code spans from plain => rich', async () => {
const plainText = '```I am a code span```';
const convertedRichText = await plainToRich(plainText, false);
const expectedRichText = '<code>I am a code span</code>';

expect(convertedRichText).toBe(expectedRichText);
});

it('converts code blocks from plain => rich with newline separation', async () => {
const plainText = '```\nI am a code block\n```';
const convertedRichText = await plainToRich(plainText, false);
const expectedRichText = '<pre><code>I am a code block</code></pre>';

expect(convertedRichText).toBe(expectedRichText);
});

it('converts code blocks from plain => rich with div separation', async () => {
const plainText = '```<div>I codeblock</div><div>```</div>';
const convertedRichText = await plainToRich(plainText, false);
const expectedRichText = '<pre><code>I codeblock</code></pre>';

expect(convertedRichText).toBe(expectedRichText);
});
});

describe('markdownToPlain', () => {
Expand All @@ -92,11 +116,9 @@ describe('markdownToPlain', () => {
});

it('converts multiple linebreak for markdown => plain', () => {
// nb for correct display, there will be one \n more
// than \\\n at the end
const markdown = 'multiple\\\nline\\\n\\\nbreaks\\\n\\\n\\\n';
const convertedPlainText = markdownToPlain(markdown);
const expectedPlainText = 'multiple\nline\n\nbreaks\n\n\n\n';
const expectedPlainText = 'multiple\nline\n\nbreaks\n\n';

expect(convertedPlainText).toBe(expectedPlainText);
});
Expand Down
10 changes: 5 additions & 5 deletions platforms/web/lib/conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ import { initOnce } from './useComposerModel.js';
const NEWLINE_CHAR = '\n';

// In plain text, markdown newlines (displays '\' character followed by
// a newline character) will be represented as \n for display as the
// display box can not interpret markdown.
// We also may need to manually add a \n to account for trailing newlines.
// a newline character) will be represented as \n for setting in the composer.
// If we have a trailing newline character, we trim it off so that the cursor
// will always be at the last character of the string, not on a new line in the
// composer.
export const markdownToPlain = (markdown: string) => {
let plainText = markdown;
if (plainText.endsWith(NEWLINE_CHAR)) {
// for cursor positioning we need to manually add another linebreak
plainText = `${plainText}${NEWLINE_CHAR}`;
plainText = plainText.slice(0, -1);
}
return plainText.replaceAll(/\\/g, '');
};
Expand Down

0 comments on commit 61cdc44

Please sign in to comment.