From d726f72916bcdcdc3b5fb8d49d97beb6aaf784c2 Mon Sep 17 00:00:00 2001 From: Robin Stocker <robin@nibor.org> Date: Tue, 6 Feb 2024 12:52:43 +1100 Subject: [PATCH] Change isTight/setTight to use push/pop pattern like other settings --- .../markdown/CoreMarkdownNodeRenderer.java | 10 ++-- .../renderer/markdown/MarkdownWriter.java | 49 +++++++++++-------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java b/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java index 714144e8..c7fa9be7 100644 --- a/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java +++ b/commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java @@ -205,23 +205,21 @@ public class CoreMarkdownNodeRenderer extends AbstractVisitor implements NodeRen @Override public void visit(BulletList bulletList) { - boolean oldTight = writer.getTight(); - writer.setTight(bulletList.isTight()); + writer.pushTight(bulletList.isTight()); listHolder = new BulletListHolder(listHolder, bulletList); visitChildren(bulletList); listHolder = listHolder.parent; - writer.setTight(oldTight); + writer.popTight(); writer.block(); } @Override public void visit(OrderedList orderedList) { - boolean oldTight = writer.getTight(); - writer.setTight(orderedList.isTight()); + writer.pushTight(orderedList.isTight()); listHolder = new OrderedListHolder(listHolder, orderedList); visitChildren(orderedList); listHolder = listHolder.parent; - writer.setTight(oldTight); + writer.popTight(); writer.block(); } diff --git a/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownWriter.java b/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownWriter.java index f648d9c4..1231a4a7 100644 --- a/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownWriter.java +++ b/commonmark/src/main/java/org/commonmark/renderer/markdown/MarkdownWriter.java @@ -13,10 +13,13 @@ public class MarkdownWriter { private final Appendable buffer; private int blockSeparator = 0; - private boolean tight; private char lastChar; private boolean atLineStart = true; + + // Stacks of settings that affect various rendering behaviors. The common pattern here is that callers use "push" to + // change a setting, render some nodes, and then "pop" the setting off the stack again to restore previous state. private final LinkedList<String> prefixes = new LinkedList<>(); + private final LinkedList<Boolean> tight = new LinkedList<>(); private final LinkedList<CharMatcher> rawEscapes = new LinkedList<>(); public MarkdownWriter(Appendable out) { @@ -72,7 +75,7 @@ public class MarkdownWriter { public void block() { // Remember whether this should be a tight or loose separator now because tight could get changed in between // this and the next flush. - blockSeparator = tight ? 1 : 2; + blockSeparator = isTight() ? 1 : 2; atLineStart = true; } @@ -104,6 +107,25 @@ public class MarkdownWriter { prefixes.removeLast(); } + /** + * Change whether blocks are tight or loose. Loose is the default where blocks are separated by a blank line. Tight + * is where blocks are not separated by a blank line. Tight blocks are used in lists, if there are no blank lines + * within the list. + * <p> + * Note that changing this does not affect block separators that have already been enqueued with {@link #block()}, + * only future ones. + */ + public void pushTight(boolean tight) { + this.tight.addLast(tight); + } + + /** + * Remove the last "tight" setting from the top of the stack. + */ + public void popTight() { + this.tight.removeLast(); + } + /** * Escape the characters matching the supplied matcher, in all text (text and raw). This might be useful to * extensions that add another layer of syntax, e.g. the tables extension that uses `|` to separate cells and needs @@ -136,25 +158,6 @@ public class MarkdownWriter { return atLineStart; } - /** - * @return whether blocks are currently set to tight or loose, see {@link #setTight(boolean)} - */ - public boolean getTight() { - return tight; - } - - /** - * Change whether blocks are tight or loose. Loose is the default where blocks are separated by a blank line. Tight - * is where blocks are not separated by a blank line. Tight blocks are used in lists, if there are no blank lines - * within the list. - * <p> - * Note that changing this does not affect block separators that have already been enqueued (with {@link #block()}, - * only future ones. - */ - public void setTight(boolean tight) { - this.tight = tight; - } - private void write(String s, CharMatcher escape) { try { if (rawEscapes.isEmpty() && escape == null) { @@ -224,6 +227,10 @@ public class MarkdownWriter { } } + private boolean isTight() { + return !tight.isEmpty() && tight.getLast(); + } + private boolean needsEscaping(char c, CharMatcher escape) { return (escape != null && escape.matches(c)) || rawNeedsEscaping(c); } -- GitLab