mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 505b9e5dbb | |||
| aadf47f2d7 | |||
| 4da4cd7f6a |
@@ -635,6 +635,121 @@ This is a [test paragraph](https://example.net)`,
|
||||
expect(result).toContain("[x] done");
|
||||
});
|
||||
|
||||
it("should export code fences inside table cells on a single line", async () => {
|
||||
const document = await buildDocument({
|
||||
content: {
|
||||
type: "doc",
|
||||
content: [
|
||||
{
|
||||
type: "table",
|
||||
content: [
|
||||
{
|
||||
type: "tr",
|
||||
content: [
|
||||
{
|
||||
type: "th",
|
||||
attrs: { colspan: 1, rowspan: 1 },
|
||||
content: [
|
||||
{
|
||||
type: "paragraph",
|
||||
content: [{ type: "text", text: "Header" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "tr",
|
||||
content: [
|
||||
{
|
||||
type: "td",
|
||||
attrs: { colspan: 1, rowspan: 1 },
|
||||
content: [
|
||||
{
|
||||
type: "code_fence",
|
||||
attrs: { language: "abap" },
|
||||
content: [
|
||||
{ type: "text", text: "a | b\nc \\ d\nline 2" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const result = await DocumentHelper.toMarkdown(document, {
|
||||
includeTitle: false,
|
||||
});
|
||||
// Code fences inside tables should use <br> tags rather than literal
|
||||
// newlines that would break the table row structure, with pipes and
|
||||
// backslashes escaped so the content cannot break out of the column.
|
||||
expect(result).toContain(
|
||||
"```abap<br>a \\| b<br>c \\\\ d<br>line 2<br>```"
|
||||
);
|
||||
// The fence content must not introduce raw newlines inside the table.
|
||||
expect(result).not.toMatch(/```abap\n/);
|
||||
});
|
||||
|
||||
it("should export math blocks inside table cells on a single line", async () => {
|
||||
const document = await buildDocument({
|
||||
content: {
|
||||
type: "doc",
|
||||
content: [
|
||||
{
|
||||
type: "table",
|
||||
content: [
|
||||
{
|
||||
type: "tr",
|
||||
content: [
|
||||
{
|
||||
type: "th",
|
||||
attrs: { colspan: 1, rowspan: 1 },
|
||||
content: [
|
||||
{
|
||||
type: "paragraph",
|
||||
content: [{ type: "text", text: "Header" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "tr",
|
||||
content: [
|
||||
{
|
||||
type: "td",
|
||||
attrs: { colspan: 1, rowspan: 1 },
|
||||
content: [
|
||||
{
|
||||
type: "math_block",
|
||||
content: [
|
||||
{ type: "text", text: "a | b\n\\frac{1}{2}" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const result = await DocumentHelper.toMarkdown(document, {
|
||||
includeTitle: false,
|
||||
});
|
||||
// Math blocks inside tables should use <br> tags rather than literal
|
||||
// newlines that would break the table row structure, with pipes and
|
||||
// backslashes escaped so the content cannot break out of the column.
|
||||
expect(result).toContain("$$<br>a \\| b<br>\\\\frac{1}{2}<br>$$");
|
||||
// The block content must not introduce raw newlines inside the table.
|
||||
expect(result).not.toMatch(/\$\$\n/);
|
||||
});
|
||||
|
||||
it("should include collection title by default", async () => {
|
||||
const collection = await buildCollection({
|
||||
name: "Test Collection",
|
||||
|
||||
@@ -694,6 +694,19 @@ export default class CodeFence extends Node<CodeFenceOptions> {
|
||||
}
|
||||
|
||||
toMarkdown(state: MarkdownSerializerState, node: ProsemirrorNode) {
|
||||
// Inside table cells literal newlines break the row structure, so encode
|
||||
// the fence on a single line using <br> for line breaks. Backslashes and
|
||||
// pipes are escaped so the cell content cannot break out of the column.
|
||||
if (state.inTable) {
|
||||
const code = node.textContent
|
||||
.replace(/[\\|]/g, "\\$&")
|
||||
.replace(/\n/g, "<br>");
|
||||
state.write(
|
||||
"```" + (node.attrs.language || "") + "<br>" + code + "<br>```"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
state.write("```" + (node.attrs.language || "") + "\n");
|
||||
state.text(node.textContent, false);
|
||||
state.ensureNewLine();
|
||||
|
||||
@@ -46,6 +46,17 @@ export default class MathBlock extends Node {
|
||||
}
|
||||
|
||||
toMarkdown(state: MarkdownSerializerState, node: ProsemirrorNode) {
|
||||
// Inside table cells literal newlines break the row structure, so encode
|
||||
// the block on a single line using <br> for line breaks. Backslashes and
|
||||
// pipes are escaped so the cell content cannot break out of the column.
|
||||
if (state.inTable) {
|
||||
const math = node.textContent
|
||||
.replace(/[\\|]/g, "\\$&")
|
||||
.replace(/\n/g, "<br>");
|
||||
state.write("$$<br>" + math + "<br>$$");
|
||||
return;
|
||||
}
|
||||
|
||||
state.write("$$\n");
|
||||
state.text(node.textContent, false);
|
||||
state.ensureNewLine();
|
||||
|
||||
Reference in New Issue
Block a user