You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/10/11 17:40:40 UTC

[causeway] branch master updated: CAUSEWAY-3629: [ValueTypes] AsciiDocFactory: Support for Sections

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/master by this push:
     new 374cebae9d CAUSEWAY-3629: [ValueTypes] AsciiDocFactory: Support for Sections
374cebae9d is described below

commit 374cebae9d1259ae0776f74bd2f206ba32a09d8e
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Oct 11 19:40:29 2023 +0200

    CAUSEWAY-3629: [ValueTypes] AsciiDocFactory: Support for Sections
---
 .../asciidoc/builder/AsciiDocFactory.java          | 12 ++-
 .../valuetypes/asciidoc/builder/NodeWriter.java    |  8 ++
 .../asciidoc/builder/StructuralNodeVisitor.java    | 36 ++++++---
 .../asciidoc/builder/ast/SimpleSection.java        | 77 ++++++++++++++++++
 .../builder/test/ast/SimpleExampleTest.java        | 90 ++++++++++++++++++++++
 .../asciidoc/builder/test/ast/_Debug.java          | 32 +++++---
 .../src/test/resources/approved/sections.adoc      | 21 +++++
 7 files changed, 254 insertions(+), 22 deletions(-)

diff --git a/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/AsciiDocFactory.java b/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/AsciiDocFactory.java
index 3d53b18708..bf1ca94504 100644
--- a/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/AsciiDocFactory.java
+++ b/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/AsciiDocFactory.java
@@ -27,6 +27,7 @@ import org.asciidoctor.ast.Column;
 import org.asciidoctor.ast.Document;
 import org.asciidoctor.ast.ListItem;
 import org.asciidoctor.ast.Row;
+import org.asciidoctor.ast.Section;
 import org.asciidoctor.ast.StructuralNode;
 import org.asciidoctor.ast.Table;
 import org.springframework.lang.Nullable;
@@ -43,6 +44,7 @@ import org.apache.causeway.valuetypes.asciidoc.builder.ast.SimpleDocument;
 import org.apache.causeway.valuetypes.asciidoc.builder.ast.SimpleList;
 import org.apache.causeway.valuetypes.asciidoc.builder.ast.SimpleListItem;
 import org.apache.causeway.valuetypes.asciidoc.builder.ast.SimpleRow;
+import org.apache.causeway.valuetypes.asciidoc.builder.ast.SimpleSection;
 import org.apache.causeway.valuetypes.asciidoc.builder.ast.SimpleTable;
 
 import lombok.NonNull;
@@ -141,6 +143,15 @@ public class AsciiDocFactory {
         return admonition("Warning", parent, source);
     }
 
+    public static Section section(final StructuralNode parent, final String title) {
+        val section = new SimpleSection();
+        section.setTitle(title);
+        section.setLevel(parent.getLevel() + 1);
+        parent.getBlocks().add(section);
+        section.setParent(parent);
+        return section;
+    }
+
     // -- BLOCK
 
     public static Block block(final StructuralNode parent) {
@@ -471,5 +482,4 @@ public class AsciiDocFactory {
         return admonition;
     }
 
-
 }
diff --git a/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/NodeWriter.java b/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/NodeWriter.java
index 95aafcef4f..ee8381c406 100644
--- a/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/NodeWriter.java
+++ b/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/NodeWriter.java
@@ -34,6 +34,7 @@ import java.util.stream.Stream;
 import org.asciidoctor.ast.Block;
 import org.asciidoctor.ast.Document;
 import org.asciidoctor.ast.ListItem;
+import org.asciidoctor.ast.Section;
 import org.asciidoctor.ast.StructuralNode;
 import org.asciidoctor.ast.Table;
 
@@ -166,6 +167,13 @@ final class NodeWriter implements StructuralNodeVisitor {
         }
     }
 
+    @Override
+    public boolean sectionHead(final Section section, final int depth) {
+        println("");
+        printChapterTitle(section.getTitle(), depth+1);
+        return true; // continue visit
+    }
+
     @Override
     public boolean blockHead(final Block block, final int depth) {
 
diff --git a/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/StructuralNodeVisitor.java b/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/StructuralNodeVisitor.java
index 0f92596761..5cf1ff0e67 100644
--- a/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/StructuralNodeVisitor.java
+++ b/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/StructuralNodeVisitor.java
@@ -21,6 +21,7 @@ package org.apache.causeway.valuetypes.asciidoc.builder;
 import org.asciidoctor.ast.Block;
 import org.asciidoctor.ast.Document;
 import org.asciidoctor.ast.ListItem;
+import org.asciidoctor.ast.Section;
 import org.asciidoctor.ast.StructuralNode;
 import org.asciidoctor.ast.Table;
 
@@ -45,7 +46,7 @@ interface StructuralNodeVisitor {
      * @param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node
      * of that will have depth 1.
      */
-    default boolean head(StructuralNode node, int depth) {
+    default boolean head(final StructuralNode node, final int depth) {
         if(node instanceof Document) {
             return documentHead((Document)node, depth);
         }
@@ -61,20 +62,25 @@ interface StructuralNodeVisitor {
         if(node instanceof Block) {
             return blockHead((Block)node, depth);
         }
+        if(node instanceof Section) {
+            return sectionHead((Section)node, depth);
+        }
         throw _Exceptions.unsupportedOperation("node type not supported %s", node.getClass());
     }
 
     // -- HEAD SPECIALISATIONS
 
-    default boolean documentHead(Document doc, int depth) { return true; }
+    default boolean documentHead(final Document doc, final int depth) { return true; }
+
+    default boolean blockHead(final Block block, final int depth) { return true; }
 
-    default boolean blockHead(Block block, int depth) { return true; }
+    default boolean sectionHead(final Section section, final int depth) { return true; }
 
-    default boolean listHead(org.asciidoctor.ast.List list, int depth) { return true; }
+    default boolean listHead(final org.asciidoctor.ast.List list, final int depth) { return true; }
 
-    default boolean listItemHead(ListItem listItem, int depth) { return true; }
+    default boolean listItemHead(final ListItem listItem, final int depth) { return true; }
 
-    default boolean tableHead(Table table, int depth) { return true; }
+    default boolean tableHead(final Table table, final int depth) { return true; }
 
    // -- TAIL
 
@@ -85,7 +91,7 @@ interface StructuralNodeVisitor {
      * @param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node
      * of that will have depth 1.
      */
-    default void tail(StructuralNode node, int depth) {
+    default void tail(final StructuralNode node, final int depth) {
         if(node instanceof Document) {
             documentTail((Document)node, depth);
             return;
@@ -106,20 +112,26 @@ interface StructuralNodeVisitor {
             blockTail((Block)node, depth);
             return;
         }
+        if(node instanceof Section) {
+            sectionTail((Section)node, depth);
+            return;
+        }
         throw _Exceptions.unsupportedOperation("node type not supported %s", node.getClass());
     }
 
     // -- TAIL SPECIALISATIONS
 
-    default void documentTail(Document doc, int depth) {}
+    default void documentTail(final Document doc, final int depth) {}
+
+    default void blockTail(final Block block, final int depth) {}
 
-    default void blockTail(Block block, int depth) {}
+    default void sectionTail(final Section section, final int depth) {}
 
-    default void listTail(org.asciidoctor.ast.List list, int depth) {}
+    default void listTail(final org.asciidoctor.ast.List list, final int depth) {}
 
-    default void listItemTail(ListItem listItem, int depth) {}
+    default void listItemTail(final ListItem listItem, final int depth) {}
 
-    default void tableTail(Table table, int depth) {}
+    default void tableTail(final Table table, final int depth) {}
 
 
 }
\ No newline at end of file
diff --git a/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/ast/SimpleSection.java b/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/ast/SimpleSection.java
new file mode 100644
index 0000000000..bb948d86a5
--- /dev/null
+++ b/valuetypes/asciidoc/builder/src/main/java/org/apache/causeway/valuetypes/asciidoc/builder/ast/SimpleSection.java
@@ -0,0 +1,77 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.causeway.valuetypes.asciidoc.builder.ast;
+
+import org.asciidoctor.ast.Section;
+
+import lombok.ToString;
+
+@ToString(callSuper = true)
+public class SimpleSection extends SimpleStructuralNode implements Section {
+
+    @Override public int index() {
+        return getIndex();
+    }
+    @Override public int getIndex() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override public int number() {
+        return getNumber();
+    }
+    @Override public int getNumber() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getNumeral() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override public String sectname() {
+        return getSectionName();
+    }
+    @Override public String getSectionName() {
+        return "section";
+    }
+
+    @Override public boolean special() {
+        return isSpecial();
+    }
+    @Override public boolean isSpecial() {
+        return false;
+    }
+
+    @Override public boolean numbered() {
+        return isNumbered();
+    }
+    @Override public boolean isNumbered() {
+        return false;
+    }
+
+    @Override
+    public void setTitle(final String title) {
+        super.setTitle(title);
+        setAttribute("title", title, true);
+    }
+
+}
diff --git a/valuetypes/asciidoc/builder/src/test/java/org/apache/causeway/valuetypes/asciidoc/builder/test/ast/SimpleExampleTest.java b/valuetypes/asciidoc/builder/src/test/java/org/apache/causeway/valuetypes/asciidoc/builder/test/ast/SimpleExampleTest.java
new file mode 100644
index 0000000000..fe43508b25
--- /dev/null
+++ b/valuetypes/asciidoc/builder/src/test/java/org/apache/causeway/valuetypes/asciidoc/builder/test/ast/SimpleExampleTest.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.causeway.valuetypes.asciidoc.builder.test.ast;
+
+import java.io.IOException;
+
+import org.asciidoctor.ast.Document;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.causeway.valuetypes.asciidoc.builder.AsciiDocFactory;
+
+import static org.apache.causeway.valuetypes.asciidoc.builder.AsciiDocFactory.doc;
+
+import lombok.val;
+
+class SimpleExampleTest extends AbstractAsciiDocWriterTest {
+
+    private Document doc;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        doc = doc();
+        super.adocSourceResourceLocation = "sections.adoc";
+        super.debugEnabled = false;
+    }
+
+    /*
+    = Example Document
+
+    Text of the first block.
+
+    Text of the second block.
+
+    == Section 1
+
+    Text of the first block under section 1.
+
+    == Section 2
+
+    Text of the first block under section 2.
+
+    === Sub Section 2.1
+
+    Text of the first block under section 2.1.
+
+    == Section 3
+
+    Text of the first block under section 3.
+     */
+    @Test
+    void testSimpleExample() throws IOException {
+
+        doc.setTitle("Example Document");
+
+        AsciiDocFactory.block(doc, "Text of the first block.");
+        AsciiDocFactory.block(doc, "Text of the second block.");
+
+        val section1 = AsciiDocFactory.section(doc, "Section 1");
+        AsciiDocFactory.block(section1, "Text of the first block under section 1.");
+
+        val section2 = AsciiDocFactory.section(doc, "Section 2");
+        AsciiDocFactory.block(section2, "Text of the first block under section 2.");
+
+        val section21 = AsciiDocFactory.section(section2, "Sub Section 2.1");
+        AsciiDocFactory.block(section21, "Text of the first block under section 2.1.");
+
+        val section3 = AsciiDocFactory.section(doc, "Section 3");
+        AsciiDocFactory.block(section3, "Text of the first block under section 3.");
+
+        assertDocumentIsCorrectlyWritten(doc);
+    }
+
+}
diff --git a/valuetypes/asciidoc/builder/src/test/java/org/apache/causeway/valuetypes/asciidoc/builder/test/ast/_Debug.java b/valuetypes/asciidoc/builder/src/test/java/org/apache/causeway/valuetypes/asciidoc/builder/test/ast/_Debug.java
index 186bb8acc3..8d269136b4 100644
--- a/valuetypes/asciidoc/builder/src/test/java/org/apache/causeway/valuetypes/asciidoc/builder/test/ast/_Debug.java
+++ b/valuetypes/asciidoc/builder/src/test/java/org/apache/causeway/valuetypes/asciidoc/builder/test/ast/_Debug.java
@@ -23,6 +23,7 @@ import java.util.Optional;
 import org.asciidoctor.ast.Block;
 import org.asciidoctor.ast.Document;
 import org.asciidoctor.ast.ListItem;
+import org.asciidoctor.ast.Section;
 import org.asciidoctor.ast.StructuralNode;
 import org.asciidoctor.ast.Table;
 
@@ -33,11 +34,11 @@ import lombok.val;
 
 final class _Debug {
 
-    static void debug(Document node) {
+    static void debug(final Document node) {
         debug(node, 0);
     }
 
-    static void debug(StructuralNode node, int level) {
+    static void debug(final StructuralNode node, final int level) {
 
         val simpleName = node.getClass().getSimpleName();
 
@@ -61,7 +62,7 @@ final class _Debug {
         }
     }
 
-    private static Optional<String> sourceFor(StructuralNode node) {
+    private static Optional<String> sourceFor(final StructuralNode node) {
         if(node instanceof Document) {
             //((Document)node);
             return Optional.empty();
@@ -80,10 +81,13 @@ final class _Debug {
         if(node instanceof Block) {
             return Optional.ofNullable(((Block)node).getSource());
         }
-        throw _Exceptions.unsupportedOperation("node type not supported %s", node.getClass());
+        if(node instanceof Section) {
+            return Optional.empty();
+        }
+        throw _Exceptions.unsupportedOperation("node type %s not supported for debugging", node.getClass());
     }
 
-    private static void printAdditionalFor(StructuralNode node, int level) {
+    private static void printAdditionalFor(final StructuralNode node, final int level) {
         if(node instanceof Document) {
             //((Document)node);
             return;
@@ -103,10 +107,20 @@ final class _Debug {
         if(node instanceof Block) {
             return;
         }
-        throw _Exceptions.unsupportedOperation("node type not supported %s", node.getClass());
+        if(node instanceof Section) {
+            debug((Section)node, level);
+            return;
+        }
+        throw _Exceptions.unsupportedOperation("node type %s not supported for debugging", node.getClass());
+    }
+
+    private static void debug(final Section section, final int level) {
+        print(level, "section index: " + section.getIndex());
+        print(level, "section numeral: " + section.getNumeral());
+        print(level, "section name: " + section.getSectionName());
     }
 
-    private static void debug(Table table, int level) {
+    private static void debug(final Table table, final int level) {
         val refCol = table.getColumns().get(0);
         val refRow = table.getBody().get(0);
         val refCell = refRow.getCells().get(0);
@@ -127,13 +141,13 @@ final class _Debug {
         print(level, "head source: " + refHead.getCells().get(0).getSource());
     }
 
-    private static void debug(org.asciidoctor.ast.List list, int level) {
+    private static void debug(final org.asciidoctor.ast.List list, final int level) {
         print(level, "%d list blocks: ", list.getBlocks().size());
         print(level, "%d list items: ", list.getItems().size());
         print(level, "%d list level: ", list.getLevel());
     }
 
-    private static void print(int level, String format, Object... args) {
+    private static void print(final int level, final String format, final Object... args) {
         val indent = _Strings.of(level*2, ' ');
         System.out.println(String.format("%s%s", indent, String.format(format, args)));
     }
diff --git a/valuetypes/asciidoc/builder/src/test/resources/approved/sections.adoc b/valuetypes/asciidoc/builder/src/test/resources/approved/sections.adoc
new file mode 100644
index 0000000000..6cc7517ce9
--- /dev/null
+++ b/valuetypes/asciidoc/builder/src/test/resources/approved/sections.adoc
@@ -0,0 +1,21 @@
+= Example Document
+
+Text of the first block.
+
+Text of the second block.
+
+== Section 1
+
+Text of the first block under section 1.
+
+== Section 2
+
+Text of the first block under section 2.
+
+=== Sub Section 2.1
+
+Text of the first block under section 2.1.
+
+== Section 3
+
+Text of the first block under section 3.
\ No newline at end of file