From fbf87b8495d00723e8a62ba0824fd7df7fdf0ce5 Mon Sep 17 00:00:00 2001 From: Dan Wyand Date: Fri, 14 Jul 2023 14:34:44 -0400 Subject: [PATCH 1/2] add column width to TableCell nodes The width is determined by the number of dash and colon characters in the separator line of a table, and passed on to the consumer as an integer. This permits consumers of the AST to render tables that are more proportional the width in the source markdown. No changes have been made to the HTML render to make use of the width information, but the test for this feature demonstrates a possible usage. Should a cell be be created that is further to the right than the parsed separator columns are (i.e., when alignment would be null), then the width will be reported as 0. --- .../commonmark/ext/gfm/tables/TableCell.java | 12 ++++++ .../gfm/tables/internal/TableBlockParser.java | 39 +++++++++++++++---- .../commonmark/ext/gfm/tables/TablesTest.java | 36 +++++++++++++++++ 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TableCell.java b/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TableCell.java index 61880c6c3..623e30062 100644 --- a/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TableCell.java +++ b/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TableCell.java @@ -9,6 +9,7 @@ public class TableCell extends CustomNode { private boolean header; private Alignment alignment; + private int width; /** * @return whether the cell is a header or not @@ -32,6 +33,17 @@ public void setAlignment(Alignment alignment) { this.alignment = alignment; } + /** + * @return the cell width + */ + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + /** * How the cell is aligned horizontally. */ diff --git a/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java b/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java index b7cea14db..2ffa53109 100644 --- a/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java +++ b/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java @@ -17,11 +17,11 @@ public class TableBlockParser extends AbstractBlockParser { private final TableBlock block = new TableBlock(); private final List rowLines = new ArrayList<>(); - private final List columns; + private final List columns; private boolean canHaveLazyContinuationLines = true; - private TableBlockParser(List columns, SourceLine headerLine) { + private TableBlockParser(List columns, SourceLine headerLine) { this.columns = columns; this.rowLines.add(headerLine); } @@ -120,7 +120,9 @@ private TableCell parseCell(SourceLine cell, int column, InlineParser inlinePars } if (column < columns.size()) { - tableCell.setAlignment(columns.get(column)); + TableCellInfo cellInfo = columns.get(column); + tableCell.setAlignment(cellInfo.getAlignment()); + tableCell.setWidth(cellInfo.getWidth()); } CharSequence content = cell.getContent(); @@ -187,11 +189,12 @@ private static List split(SourceLine line) { // -|- // |-|-| // --- | --- - private static List parseSeparator(CharSequence s) { - List columns = new ArrayList<>(); + private static List parseSeparator(CharSequence s) { + List columns = new ArrayList<>(); int pipes = 0; boolean valid = false; int i = 0; + int width = 0; while (i < s.length()) { char c = s.charAt(i); switch (c) { @@ -216,10 +219,12 @@ private static List parseSeparator(CharSequence s) { if (c == ':') { left = true; i++; + width++; } boolean haveDash = false; while (i < s.length() && s.charAt(i) == '-') { i++; + width++; haveDash = true; } if (!haveDash) { @@ -229,8 +234,10 @@ private static List parseSeparator(CharSequence s) { if (i < s.length() && s.charAt(i) == ':') { right = true; i++; + width++; } - columns.add(getAlignment(left, right)); + columns.add(new TableCellInfo(getAlignment(left, right), width)); + width = 0; // Next, need another pipe pipes = 0; break; @@ -270,7 +277,7 @@ public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockPar if (paragraphLines.size() == 1 && Parsing.find('|', paragraphLines.get(0).getContent(), 0) != -1) { SourceLine line = state.getLine(); SourceLine separatorLine = line.substring(state.getIndex(), line.getContent().length()); - List columns = parseSeparator(separatorLine.getContent()); + List columns = parseSeparator(separatorLine.getContent()); if (columns != null && !columns.isEmpty()) { SourceLine paragraph = paragraphLines.get(0); List headerCells = split(paragraph); @@ -284,4 +291,22 @@ public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockPar return BlockStart.none(); } } + + private static class TableCellInfo { + private final TableCell.Alignment alignment; + private final int width; + + public TableCell.Alignment getAlignment() { + return alignment; + } + + public int getWidth() { + return width; + } + + public TableCellInfo(TableCell.Alignment alignment, int width) { + this.alignment = alignment; + this.width = width; + } + } } diff --git a/commonmark-ext-gfm-tables/src/test/java/org/commonmark/ext/gfm/tables/TablesTest.java b/commonmark-ext-gfm-tables/src/test/java/org/commonmark/ext/gfm/tables/TablesTest.java index bef3b8b6c..b03714d9a 100644 --- a/commonmark-ext-gfm-tables/src/test/java/org/commonmark/ext/gfm/tables/TablesTest.java +++ b/commonmark-ext-gfm-tables/src/test/java/org/commonmark/ext/gfm/tables/TablesTest.java @@ -749,6 +749,42 @@ public void setAttributes(Node node, String tagName, Map attribu "\n")); } + @Test + public void columnWidthIsRecorded() { + AttributeProviderFactory factory = new AttributeProviderFactory() { + @Override + public AttributeProvider create(AttributeProviderContext context) { + return new AttributeProvider() { + @Override + public void setAttributes(Node node, String tagName, Map attributes) { + if (node instanceof TableCell && "th".equals(tagName)) { + attributes.put("width", ((TableCell) node).getWidth() + "em"); + } + } + }; + } + }; + HtmlRenderer renderer = HtmlRenderer.builder() + .attributeProviderFactory(factory) + .extensions(EXTENSIONS) + .build(); + String rendered = renderer.render(PARSER.parse("Abc|Def\n-----|---\n1|2")); + assertThat(rendered, is("\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "
AbcDef
12
\n")); + } + @Test public void sourceSpans() { Parser parser = Parser.builder() From b13438921bf18c79e2cff3cf6c38a3aef0b73a8e Mon Sep 17 00:00:00 2001 From: Robin Stocker Date: Sat, 9 Mar 2024 11:49:44 +1100 Subject: [PATCH 2/2] Extend Javadoc --- .../src/main/java/org/commonmark/ext/gfm/tables/TableCell.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TableCell.java b/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TableCell.java index 623e30062..57184ca38 100644 --- a/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TableCell.java +++ b/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/TableCell.java @@ -34,7 +34,7 @@ public void setAlignment(Alignment alignment) { } /** - * @return the cell width + * @return the cell width (the number of dash and colon characters in the delimiter row of the table for this column) */ public int getWidth() { return width;