diff --git a/packages/markdown-common/lib/CommonMarkUtils.js b/packages/markdown-common/lib/CommonMarkUtils.js index 9ba772d8..1e508013 100644 --- a/packages/markdown-common/lib/CommonMarkUtils.js +++ b/packages/markdown-common/lib/CommonMarkUtils.js @@ -173,6 +173,15 @@ function mkATXHeading(level) { return Array(level).fill('#').join(''); } +/** + * Create table heading + * @param {number} col - the number of columns + * @return {string} the markup for the table heading + */ +function mkTableHeading(col) { + return Array(col).fill('|---------').join('') + '|'; +} + /** * Adding escapes for text nodes * @param {string} input - unescaped @@ -334,6 +343,7 @@ module.exports.mkNewLine = mkNewLine; module.exports.mkPrefix = mkPrefix; module.exports.mkSetextHeading = mkSetextHeading; module.exports.mkATXHeading = mkATXHeading; +module.exports.mkTableHeading = mkTableHeading; module.exports.escapeText = escapeText; module.exports.escapeCodeBlock = escapeCodeBlock; diff --git a/packages/markdown-common/lib/__snapshots__/CommonMarkTransformer.test.js.snap b/packages/markdown-common/lib/__snapshots__/CommonMarkTransformer.test.js.snap index 8631d0d3..be674f2b 100644 --- a/packages/markdown-common/lib/__snapshots__/CommonMarkTransformer.test.js.snap +++ b/packages/markdown-common/lib/__snapshots__/CommonMarkTransformer.test.js.snap @@ -3192,6 +3192,588 @@ Object { } `; +exports[`markdown converts table.md to concerto JSON 1`] = ` +Object { + "$class": "org.accordproject.commonmark.Document", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Table", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableHead", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Header1", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Header 2", + }, + ], + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableBody", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Simple", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Table", + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Paragraph", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Text", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + "xmlns": "http://commonmark.org/xml/1.0", +} +`; + +exports[`markdown converts table_bold.md to concerto JSON 1`] = ` +Object { + "$class": "org.accordproject.commonmark.Document", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Table", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableHead", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Syntax", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Description", + }, + ], + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableBody", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Strong", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Bold content", + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Title", + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Paragraph", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Text", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + "xmlns": "http://commonmark.org/xml/1.0", +} +`; + +exports[`markdown converts table_code.md to concerto JSON 1`] = ` +Object { + "$class": "org.accordproject.commonmark.Document", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Table", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableHead", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Column1", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Column 2", + }, + ], + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableBody", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Code", + "text": "code block", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Table", + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Paragraph", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Text", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + "xmlns": "http://commonmark.org/xml/1.0", +} +`; + +exports[`markdown converts table_image.md to concerto JSON 1`] = ` +Object { + "$class": "org.accordproject.commonmark.Document", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Table", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableHead", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Syntax", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Description", + }, + ], + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableBody", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Strong", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Bold content", + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Image", + "destination": "https://docs.accordproject.org/docs/assets/020/template.png", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "ap_logo", + }, + ], + "title": "AP triangle", + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Paragraph", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Text", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + "xmlns": "http://commonmark.org/xml/1.0", +} +`; + +exports[`markdown converts table_links.md to concerto JSON 1`] = ` +Object { + "$class": "org.accordproject.commonmark.Document", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Table", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableHead", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Column1", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Column 2", + }, + ], + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableBody", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Link", + "destination": "http://clause.io", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "link", + }, + ], + "title": "", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Table", + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Paragraph", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Text", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + "xmlns": "http://commonmark.org/xml/1.0", +} +`; + +exports[`markdown converts table_skewed.md to concerto JSON 1`] = ` +Object { + "$class": "org.accordproject.commonmark.Document", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Table", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableHead", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Header1", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.HeaderCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Header 2", + }, + ], + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableBody", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Simple", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Table", + }, + ], + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableRow", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Paragraph", + }, + ], + }, + Object { + "$class": "org.accordproject.commonmark.TableCell", + "nodes": Array [ + Object { + "$class": "org.accordproject.commonmark.Text", + "text": "Text", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + "xmlns": "http://commonmark.org/xml/1.0", +} +`; + exports[`markdown converts text.md to concerto JSON 1`] = ` Object { "$class": "org.accordproject.commonmark.Document", @@ -4165,6 +4747,48 @@ This is second paragraph." exports[`to plain text strong.md 1`] = `"This is some text."`; +exports[`to plain text table.md 1`] = ` +"| Header1 | Header 2 | +|---------|---------| +| Simple | Table | +| Paragraph | Text |" +`; + +exports[`to plain text table_bold.md 1`] = ` +"| Syntax | Description | +|---------|---------| +| **Bold content** | Title | +| Paragraph | Text |" +`; + +exports[`to plain text table_code.md 1`] = ` +"| Column1 | Column 2 | +|---------|---------| +| \`code block\` | Table | +| Paragraph | Text |" +`; + +exports[`to plain text table_image.md 1`] = ` +"| Syntax | Description | +|---------|---------| +| **Bold content** |  | +| Paragraph | Text |" +`; + +exports[`to plain text table_links.md 1`] = ` +"| Column1 | Column 2 | +|---------|---------| +| [link](http://clause.io \\"\\") | Table | +| Paragraph | Text |" +`; + +exports[`to plain text table_skewed.md 1`] = ` +"| Header1 | Header 2 | +|---------|---------| +| Simple | Table | +| Paragraph | Text |" +`; + exports[`to plain text text.md 1`] = `"This is some text."`; exports[`to plain text text2.md 1`] = ` diff --git a/packages/markdown-common/lib/fromcommonmarkrules.js b/packages/markdown-common/lib/fromcommonmarkrules.js index 86dad41c..2c3de6de 100644 --- a/packages/markdown-common/lib/fromcommonmarkrules.js +++ b/packages/markdown-common/lib/fromcommonmarkrules.js @@ -149,4 +149,43 @@ rules.Document = (visitor,thing,children,parameters,resultString,resultSeq) => { resultSeq(parameters,result); }; +rules.Table = (visitor,thing,children,parameters,resultString,resultSeq) => { + const result = [children]; + resultSeq(parameters,result); +}; + +rules.TableBody = (visitor,thing,children,parameters,resultString,resultSeq) => { + const result = [children]; + resultSeq(parameters,result); +}; + +rules.TableRow = (visitor,thing,children,parameters,resultString,resultSeq) => { + const next1 = '|'; + const newLine = CommonMarkUtils.mkNewLine(parameters); + const result = [children, resultString(next1), newLine]; + resultSeq(parameters,result); +}; + +rules.TableCell = (visitor,thing,children,parameters,resultString,resultSeq) => { + const next1 = '|'; + const next2 = ' '; + const result = [resultString(next1),resultString(next2),children, resultString(next2)]; + resultSeq(parameters,result); +}; + +rules.TableHead = (visitor,thing,children,parameters,resultString,resultSeq) => { + const col = thing.nodes[0].nodes.length; + const next1 = CommonMarkUtils.mkTableHeading(col); + const newLine = CommonMarkUtils.mkNewLine(parameters); + const result = [children, resultString(next1), resultString(newLine)]; + resultSeq(parameters,result); +}; + +rules.HeaderCell = (visitor,thing,children,parameters,resultString,resultSeq) => { + const next1 = '|'; + const next2 = ' '; + const result = [resultString(next1),resultString(next2),children, resultString(next2)]; + resultSeq(parameters,result); +}; + module.exports = rules; \ No newline at end of file diff --git a/packages/markdown-common/lib/tocommonmarkrules.js b/packages/markdown-common/lib/tocommonmarkrules.js index ccd6ef48..b849491b 100644 --- a/packages/markdown-common/lib/tocommonmarkrules.js +++ b/packages/markdown-common/lib/tocommonmarkrules.js @@ -243,6 +243,96 @@ const listItemCloseRule = { close: true, }; +const tableOpenRule = { + tag: NS_PREFIX_CommonMarkModel + 'Table', + leaf: false, + open: true, + close: false, + enter: (node, token, callback) => {}, +}; + +const tableCloseRule = { + tag: NS_PREFIX_CommonMarkModel + 'Table', + leaf: false, + open: false, + close: true, +}; + +const tableHeadOpenRule = { + tag: NS_PREFIX_CommonMarkModel + 'TableHead', + leaf: false, + open: true, + close: false, + enter: (node, token, callback) => {}, +}; + +const tableHeadCloseRule = { + tag: NS_PREFIX_CommonMarkModel + 'TableHead', + leaf: false, + open: false, + close: true, +}; + +const tableBodyOpenRule = { + tag: NS_PREFIX_CommonMarkModel + 'TableBody', + leaf: false, + open: true, + close: false, + enter: (node, token, callback) => {}, +}; + +const tableBodyCloseRule = { + tag: NS_PREFIX_CommonMarkModel + 'TableBody', + leaf: false, + open: false, + close: true, +}; + +const tableRowOpenRule = { + tag: NS_PREFIX_CommonMarkModel + 'TableRow', + leaf: false, + open: true, + close: false, + enter: (node, token, callback) => {}, +}; + +const tableRowCloseRule = { + tag: NS_PREFIX_CommonMarkModel + 'TableRow', + leaf: false, + open: false, + close: true, +}; + +const headerCellOpenRule = { + tag: NS_PREFIX_CommonMarkModel + 'HeaderCell', + leaf: false, + open: true, + close: false, + enter: (node, token, callback) => {}, +}; + +const headerCellCloseRule = { + tag: NS_PREFIX_CommonMarkModel + 'HeaderCell', + leaf: false, + open: false, + close: true, +}; + +const tableCellOpenRule = { + tag: NS_PREFIX_CommonMarkModel + 'TableCell', + leaf: false, + open: true, + close: false, + enter: (node, token, callback) => {}, +}; + +const tableCellCloseRule = { + tag: NS_PREFIX_CommonMarkModel + 'TableCell', + leaf: false, + open: false, + close: true, +}; + const rules = { inlines: {}, blocks: {}}; rules.inlines.text = textRule; rules.inlines.code_inline = codeInlineRule; @@ -273,5 +363,17 @@ rules.blocks.ordered_list_open = orderedListOpenRule; rules.blocks.ordered_list_close = orderedListCloseRule; rules.blocks.list_item_open = listItemOpenRule; rules.blocks.list_item_close = listItemCloseRule; +rules.blocks.table_open = tableOpenRule; +rules.blocks.table_close = tableCloseRule; +rules.blocks.thead_open = tableHeadOpenRule; +rules.blocks.thead_close = tableHeadCloseRule; +rules.blocks.tbody_open = tableBodyOpenRule; +rules.blocks.tbody_close = tableBodyCloseRule; +rules.blocks.tr_open = tableRowOpenRule; +rules.blocks.tr_close = tableRowCloseRule; +rules.blocks.th_open = headerCellOpenRule; +rules.blocks.th_close = headerCellCloseRule; +rules.blocks.td_open = tableCellOpenRule; +rules.blocks.td_close = tableCellCloseRule; module.exports = rules; diff --git a/packages/markdown-common/test/data/table.md b/packages/markdown-common/test/data/table.md new file mode 100644 index 00000000..bfb96236 --- /dev/null +++ b/packages/markdown-common/test/data/table.md @@ -0,0 +1,4 @@ +| Header1 | Header 2 | +| ----------- | ----------- | +| Simple | Table | +| Paragraph | Text | \ No newline at end of file diff --git a/packages/markdown-common/test/data/table_bold.md b/packages/markdown-common/test/data/table_bold.md new file mode 100644 index 00000000..cf4d1b7c --- /dev/null +++ b/packages/markdown-common/test/data/table_bold.md @@ -0,0 +1,4 @@ +| Syntax | Description | +| ---------------- | ----------- | +| **Bold content** | Title | +| Paragraph | Text | \ No newline at end of file diff --git a/packages/markdown-common/test/data/table_code.md b/packages/markdown-common/test/data/table_code.md new file mode 100644 index 00000000..ac2e66bf --- /dev/null +++ b/packages/markdown-common/test/data/table_code.md @@ -0,0 +1,4 @@ +| Column1 | Column 2 | +| ----------- | ----------- | +| `code block` | Table | +| Paragraph | Text | \ No newline at end of file diff --git a/packages/markdown-common/test/data/table_image.md b/packages/markdown-common/test/data/table_image.md new file mode 100644 index 00000000..a0e8286b --- /dev/null +++ b/packages/markdown-common/test/data/table_image.md @@ -0,0 +1,4 @@ +| Syntax | Description | +| ---------------- | ----------- | +| **Bold content** |  | +| Paragraph | Text | \ No newline at end of file diff --git a/packages/markdown-common/test/data/table_links.md b/packages/markdown-common/test/data/table_links.md new file mode 100644 index 00000000..f7aa7cd5 --- /dev/null +++ b/packages/markdown-common/test/data/table_links.md @@ -0,0 +1,4 @@ +| Column1 | Column 2 | +| ----------- | ----------- | +| [link](http://clause.io) | Table | +| Paragraph | Text | \ No newline at end of file diff --git a/packages/markdown-common/test/data/table_skewed.md b/packages/markdown-common/test/data/table_skewed.md new file mode 100644 index 00000000..a7262575 --- /dev/null +++ b/packages/markdown-common/test/data/table_skewed.md @@ -0,0 +1,4 @@ +| Header1 | Header 2 | +| ----------- | ----------- | +| Simple | Table | +| Paragraph | Text | \ No newline at end of file diff --git a/packages/markdown-html/src/ToHtmlStringVisitor.js b/packages/markdown-html/src/ToHtmlStringVisitor.js index 2bf4b2c4..b05dc143 100644 --- a/packages/markdown-html/src/ToHtmlStringVisitor.js +++ b/packages/markdown-html/src/ToHtmlStringVisitor.js @@ -205,6 +205,32 @@ class ToHtmlStringVisitor { case 'Item': parameters.result += `