Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
84 changes: 84 additions & 0 deletions src/editor/customMarkdownConverter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2685,6 +2685,90 @@ describe("markdownToBlocks", () => {
},
]);
});

it("preserves opening-fence content when it is not a clean language identifier", () => {
const markdown = [
"```curl `http://localhost:3000/projects/classic-project/test/e1c1b38c/edit` \\",
"{{baseURL}}/endpoint?query_param_one=value_one&query_param_two=value_two",
"```",
].join("\n");
const blocks = markdownToBlocks(markdown);
expect(blocks).toEqual([
{
type: "codeBlock",
props: { language: "" },
content: [
{
type: "text",
text: [
"curl `http://localhost:3000/projects/classic-project/test/e1c1b38c/edit` \\",
"{{baseURL}}/endpoint?query_param_one=value_one&query_param_two=value_two",
].join("\n"),
styles: {},
},
],
children: [],
},
]);
});

it("round-trips an opening-fence-with-content code block to stable markdown", () => {
const markdown = [
"```curl `http://localhost:3000/projects/classic-project/test/e1c1b38c/edit` \\",
"{{baseURL}}/endpoint?query_param_one=value_one&query_param_two=value_two",
"```",
].join("\n");
const blocks = markdownToBlocks(markdown);
const serialized = blocksToMarkdown(blocks as CustomEditorBlock[]);
expect(serialized).toBe(
[
"```",
"curl `http://localhost:3000/projects/classic-project/test/e1c1b38c/edit` \\",
"{{baseURL}}/endpoint?query_param_one=value_one&query_param_two=value_two",
"```",
].join("\n"),
);
expect(markdownToBlocks(serialized)).toEqual(blocks);
});

it("preserves hyphenated language identifiers like shell-session", () => {
const markdown = ["```shell-session", "$ ls", "```"].join("\n");
const blocks = markdownToBlocks(markdown);
expect(blocks).toEqual([
{
type: "codeBlock",
props: { language: "shell-session" },
content: [{ type: "text", text: "$ ls", styles: {} }],
children: [],
},
]);
});

it("preserves digit-prefixed language identifiers like 1c-enterprise", () => {
const markdown = ["```1c-enterprise", "code", "```"].join("\n");
const blocks = markdownToBlocks(markdown);
expect(blocks).toEqual([
{
type: "codeBlock",
props: { language: "1c-enterprise" },
content: [{ type: "text", text: "code", styles: {} }],
children: [],
},
]);
});

it("sanitizes a malformed in-memory language prop on serialize", () => {
const blocks: CustomEditorBlock[] = [
{
id: "1",
type: "codeBlock",
props: { ...baseProps, language: "curl http://x" } as any,
content: [{ type: "text", text: "body", styles: {} }] as any,
children: [],
},
];
expect(blocksToMarkdown(blocks)).toBe(["```", "body", "```"].join("\n"));
});
});

describe("file block serialization", () => {
Expand Down
13 changes: 11 additions & 2 deletions src/editor/customMarkdownConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,8 @@ function serializeBlock(
return lines;
}
case "codeBlock": {
const language = (block.props as any).language || "";
const rawLanguage = (block.props as any).language || "";
const language = /[\s`]/.test(rawLanguage) ? "" : rawLanguage;
const fence = "```" + language;
const body = inlineContentToPlainText(block.content);
lines.push(fence);
Expand Down Expand Up @@ -1290,8 +1291,16 @@ function parseCodeBlock(lines: string[], index: number): { block: CustomPartialB
};
}

const language = afterOpening.trim();
const info = afterOpening.trim();
let language = "";
const body: string[] = [];
if (info.length > 0) {
if (/[\s`]/.test(info)) {
body.push(afterOpening);
} else {
language = info;
}
}
let next = index + 1;
while (next < lines.length && !lines[next].startsWith("```") ) {
body.push(lines[next]);
Expand Down
Loading