Skip to content

Commit d386300

Browse files
Fix Code Block syntax highlighting for imported text (#1388)
* Don't insert hard breaks into Code Blocks * Add a code block with newlines to the test cases * Code improvements * Updated snapshots * Updated snapshot and small fix * Re-added accidentally deleted snapshots --------- Co-authored-by: matthewlipski <[email protected]>
1 parent f9c0f9c commit d386300

File tree

8 files changed

+89
-13
lines changed

8 files changed

+89
-13
lines changed

packages/core/src/api/blockManipulation/commands/updateBlock/updateBlock.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,15 +141,17 @@ function updateBlockContentNode<
141141
content = inlineContentToNodes(
142142
[block.content],
143143
state.schema,
144-
editor.schema.styleSchema
144+
editor.schema.styleSchema,
145+
newNodeType.name
145146
);
146147
} else if (Array.isArray(block.content)) {
147148
// Adds a text node with the provided styles converted into marks to the content,
148149
// for each InlineContent object.
149150
content = inlineContentToNodes(
150151
block.content,
151152
state.schema,
152-
editor.schema.styleSchema
153+
editor.schema.styleSchema,
154+
newNodeType.name
153155
);
154156
} else if (block.content.type === "tableContent") {
155157
content = tableContentToNodes(
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<pre><code class="bn-inline-content language-javascript">const hello = 'world';<br>console.log(hello);<br></code></pre>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="codeBlock"><pre><code class="bn-inline-content language-javascript">const hello = 'world';
2+
console.log(hello);
3+
</code></pre></div></div></div></div>

packages/core/src/api/exporters/html/util/serializeBlocksInternalHTML.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export function serializeInlineContentInternalHTML<
2121
editor: BlockNoteEditor<any, I, S>,
2222
blockContent: PartialBlock<BSchema, I, S>["content"],
2323
serializer: DOMSerializer,
24+
blockType?: string,
2425
options?: { document?: Document }
2526
) {
2627
let nodes: any;
@@ -32,13 +33,15 @@ export function serializeInlineContentInternalHTML<
3233
nodes = inlineContentToNodes(
3334
[blockContent],
3435
editor.pmSchema,
35-
editor.schema.styleSchema
36+
editor.schema.styleSchema,
37+
blockType
3638
);
3739
} else if (Array.isArray(blockContent)) {
3840
nodes = inlineContentToNodes(
3941
blockContent,
4042
editor.pmSchema,
41-
editor.schema.styleSchema
43+
editor.schema.styleSchema,
44+
blockType
4245
);
4346
} else if (blockContent.type === "tableContent") {
4447
nodes = tableContentToNodes(
@@ -102,6 +105,7 @@ function serializeBlock<
102105
editor,
103106
block.content as any, // TODO
104107
serializer,
108+
block.type,
105109
options
106110
);
107111
ret.contentDOM.appendChild(ic);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
```javascript
2+
const hello = 'world';
3+
console.log(hello);
4+
```

packages/core/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,33 @@ exports[`Test BlockNote-Prosemirror conversion > Case: custom style schema > Con
662662
}
663663
`;
664664

665+
exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert codeBlock/contains-newlines to/from prosemirror 1`] = `
666+
{
667+
"attrs": {
668+
"backgroundColor": "default",
669+
"id": "1",
670+
"textColor": "default",
671+
},
672+
"content": [
673+
{
674+
"attrs": {
675+
"language": "javascript",
676+
},
677+
"content": [
678+
{
679+
"text": "const hello = 'world';
680+
console.log(hello);
681+
",
682+
"type": "text",
683+
},
684+
],
685+
"type": "codeBlock",
686+
},
687+
],
688+
"type": "blockContainer",
689+
}
690+
`;
691+
665692
exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert codeBlock/defaultLanguage to/from prosemirror 1`] = `
666693
{
667694
"attrs": {

packages/core/src/api/nodeConversions/blockToNode.ts

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import { UnreachableCaseError } from "../../util/typescript.js";
2525
function styledTextToNodes<T extends StyleSchema>(
2626
styledText: StyledText<T>,
2727
schema: Schema,
28-
styleSchema: T
28+
styleSchema: T,
29+
blockType?: string
2930
): Node[] {
3031
const marks: Mark[] = [];
3132

@@ -44,6 +45,12 @@ function styledTextToNodes<T extends StyleSchema>(
4445
}
4546
}
4647

48+
const parseHardBreaks = !blockType || !schema.nodes[blockType].spec.code;
49+
50+
if (!parseHardBreaks) {
51+
return [schema.text(styledText.text, marks)];
52+
}
53+
4754
return (
4855
styledText.text
4956
// Splits text & line breaks.
@@ -96,7 +103,8 @@ function linkToNodes(
96103
function styledTextArrayToNodes<S extends StyleSchema>(
97104
content: string | StyledText<S>[],
98105
schema: Schema,
99-
styleSchema: S
106+
styleSchema: S,
107+
blockType?: string
100108
): Node[] {
101109
const nodes: Node[] = [];
102110

@@ -105,14 +113,17 @@ function styledTextArrayToNodes<S extends StyleSchema>(
105113
...styledTextToNodes(
106114
{ type: "text", text: content, styles: {} },
107115
schema,
108-
styleSchema
116+
styleSchema,
117+
blockType
109118
)
110119
);
111120
return nodes;
112121
}
113122

114123
for (const styledText of content) {
115-
nodes.push(...styledTextToNodes(styledText, schema, styleSchema));
124+
nodes.push(
125+
...styledTextToNodes(styledText, schema, styleSchema, blockType)
126+
);
116127
}
117128
return nodes;
118129
}
@@ -126,17 +137,22 @@ export function inlineContentToNodes<
126137
>(
127138
blockContent: PartialInlineContent<I, S>,
128139
schema: Schema,
129-
styleSchema: S
140+
styleSchema: S,
141+
blockType?: string
130142
): Node[] {
131143
const nodes: Node[] = [];
132144

133145
for (const content of blockContent) {
134146
if (typeof content === "string") {
135-
nodes.push(...styledTextArrayToNodes(content, schema, styleSchema));
147+
nodes.push(
148+
...styledTextArrayToNodes(content, schema, styleSchema, blockType)
149+
);
136150
} else if (isPartialLinkInlineContent(content)) {
137151
nodes.push(...linkToNodes(content, schema, styleSchema));
138152
} else if (isStyledTextInlineContent(content)) {
139-
nodes.push(...styledTextArrayToNodes([content], schema, styleSchema));
153+
nodes.push(
154+
...styledTextArrayToNodes([content], schema, styleSchema, blockType)
155+
);
140156
} else {
141157
nodes.push(
142158
blockOrInlineContentToContentNode(content, schema, styleSchema)
@@ -217,10 +233,20 @@ function blockOrInlineContentToContentNode(
217233
if (!block.content) {
218234
contentNode = schema.nodes[type].createChecked(block.props);
219235
} else if (typeof block.content === "string") {
220-
const nodes = inlineContentToNodes([block.content], schema, styleSchema);
236+
const nodes = inlineContentToNodes(
237+
[block.content],
238+
schema,
239+
styleSchema,
240+
type
241+
);
221242
contentNode = schema.nodes[type].createChecked(block.props, nodes);
222243
} else if (Array.isArray(block.content)) {
223-
const nodes = inlineContentToNodes(block.content, schema, styleSchema);
244+
const nodes = inlineContentToNodes(
245+
block.content,
246+
schema,
247+
styleSchema,
248+
type
249+
);
224250
contentNode = schema.nodes[type].createChecked(block.props, nodes);
225251
} else if (block.content.type === "tableContent") {
226252
const nodes = tableContentToNodes(block.content, schema, styleSchema);

packages/core/src/api/testUtil/cases/defaultSchema.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,15 @@ export const defaultSchemaTestCases: EditorTestCases<
208208
},
209209
],
210210
},
211+
{
212+
name: "codeBlock/contains-newlines",
213+
blocks: [
214+
{
215+
type: "codeBlock",
216+
content: "const hello = 'world';\nconsole.log(hello);\n",
217+
},
218+
],
219+
},
211220
{
212221
name: "pageBreak/basic",
213222
blocks: [

0 commit comments

Comments
 (0)