You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/12/12 19:38:52 UTC

[isis] branch master updated: ISIS-2473: adoc writer: support for footnotes

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/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 7edd582  ISIS-2473: adoc writer: support for footnotes
7edd582 is described below

commit 7edd582376d403896361ce34440a2c2d841ab9d0
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Dec 12 20:38:41 2020 +0100

    ISIS-2473: adoc writer: support for footnotes
---
 .../j2adoc/format/UnitFormatterAbstract.java       |   9 +-
 .../j2adoc/format/UnitFormatterCompact.java        |  10 --
 .../UnitFormatterWithSourceAndFootNotes.java       |  13 +--
 .../isis/tooling/model4adoc/AsciiDocFactory.java   |  27 +++--
 .../apache/isis/tooling/model4adoc/NodeWriter.java |  26 +++--
 .../apache/isis/tooling/adocmodel/test/Debug.java  |   1 +
 .../isis/tooling/adocmodel/test/FootnoteTest.java  | 115 +++++++++++++++++++++
 .../isis/tooling/adocmodel/test/footnote.adoc      |  21 ++++
 8 files changed, 185 insertions(+), 37 deletions(-)

diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterAbstract.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterAbstract.java
index 5506f00..d1c7b1d 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterAbstract.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterAbstract.java
@@ -21,6 +21,7 @@ package org.apache.isis.tooling.j2adoc.format;
 import java.util.Optional;
 
 import org.asciidoctor.ast.Document;
+import org.asciidoctor.ast.List;
 import org.asciidoctor.ast.StructuralNode;
 
 import org.apache.isis.commons.internal.base._Strings;
@@ -92,7 +93,13 @@ implements UnitFormatter {
     }
     
     protected abstract StructuralNode getMemberDescriptionContainer(StructuralNode parent);
-    protected abstract void appendMemberDescription(StructuralNode parent, String member, Document javadoc);
+    
+    protected void appendMemberDescription(StructuralNode ul, String member, Document javadoc) {
+        val li = AsciiDocFactory.listItem((List) ul, member);
+        val openBlock = AsciiDocFactory.openBlock(li);
+        val javaDocBlock = AsciiDocFactory.block(openBlock);
+        javaDocBlock.getBlocks().addAll(javadoc.getBlocks());
+    }
     
     protected void memberDescriptions(final J2AdocUnit unit, final StructuralNode parent) {
         
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterCompact.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterCompact.java
index e754583..9c7aaf3 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterCompact.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterCompact.java
@@ -18,8 +18,6 @@
  */
 package org.apache.isis.tooling.j2adoc.format;
 
-import org.asciidoctor.ast.Document;
-import org.asciidoctor.ast.List;
 import org.asciidoctor.ast.StructuralNode;
 
 import org.apache.isis.tooling.j2adoc.J2AdocContext;
@@ -40,12 +38,4 @@ extends UnitFormatterAbstract {
         return ul;
     }
 
-    @Override
-    protected void appendMemberDescription(StructuralNode ul, String member, Document javadoc) {
-        val li = AsciiDocFactory.listItem((List) ul, member);
-        val openBlock = AsciiDocFactory.openBlock(li);
-        val javaDocBlock = AsciiDocFactory.block(openBlock);
-        javaDocBlock.getBlocks().addAll(javadoc.getBlocks());
-    }
-
 }
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterWithSourceAndFootNotes.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterWithSourceAndFootNotes.java
index d9a799e..8df174a 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterWithSourceAndFootNotes.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterWithSourceAndFootNotes.java
@@ -20,8 +20,6 @@ package org.apache.isis.tooling.j2adoc.format;
 
 import java.util.Optional;
 
-import org.asciidoctor.ast.Document;
-import org.asciidoctor.ast.List;
 import org.asciidoctor.ast.StructuralNode;
 
 import org.apache.isis.tooling.j2adoc.J2AdocContext;
@@ -134,18 +132,9 @@ extends UnitFormatterAbstract {
 
     @Override
     protected StructuralNode getMemberDescriptionContainer(StructuralNode parent) {
-        val ul = AsciiDocFactory.list(parent);
+        val ul = AsciiDocFactory.footnotes(parent);
         return ul;
     }
-
-    @Override
-    protected void appendMemberDescription(StructuralNode ul, String member, Document javadoc) {
-        val li = AsciiDocFactory.listItem((List) ul, member);
-        li.getRoles().add("footnote");
-        val openBlock = AsciiDocFactory.openBlock(li);
-        val javaDocBlock = AsciiDocFactory.block(openBlock);
-        javaDocBlock.getBlocks().addAll(javadoc.getBlocks());
-    }
     
     // -- HELPER
     
diff --git a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/AsciiDocFactory.java b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/AsciiDocFactory.java
index 6a2fe0c..0d110d9 100644
--- a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/AsciiDocFactory.java
+++ b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/AsciiDocFactory.java
@@ -136,10 +136,22 @@ public class AsciiDocFactory {
     
     public static Block openBlock(ListItem listItem) {
         val openBlock = block(listItem);
-        openBlock.setAttribute("style", "open", true);
+        openBlock.setStyle("open");
         return openBlock;
     }
     
+    // -- FOOTNOTES
+    
+    public static org.asciidoctor.ast.List footnotes(StructuralNode parent) {
+        val footnoteList = list(parent);
+        footnoteList.setStyle("arabic");
+        return footnoteList;
+    }
+    
+    public static ListItem footnote(org.asciidoctor.ast.List parent, @NonNull String source) {
+        return listItem(parent, source);
+    }
+    
     // -- TABLE
     
     public static Table table(StructuralNode parent) {
@@ -215,15 +227,14 @@ public class AsciiDocFactory {
     }
     
     public static ListItem listItem(org.asciidoctor.ast.List parent) {
+        return listItem(parent, null);
+    }
+    
+    public static ListItem listItem(org.asciidoctor.ast.List parent, String source) {
         val listItem = new SimpleListItem();
         listItem.setLevel(parent.getLevel());
         parent.getItems().add(listItem);
         listItem.setParent(parent);
-        return listItem;
-    }
-    
-    public static ListItem listItem(org.asciidoctor.ast.List parent, String source) {
-        val listItem = listItem(parent);
         listItem.setSource(source);
         return listItem;
     }
@@ -323,11 +334,13 @@ public class AsciiDocFactory {
 
     private static Block admonition(String label, StructuralNode parent, String source) {
         val admonition = block(parent, source);
+        admonition.setStyle(label.toUpperCase());
         admonition.setAttribute("textlabel", label, true);
         admonition.setAttribute("name", label.toLowerCase(), true);
-        admonition.setAttribute("style", label.toUpperCase(), true);
         return admonition;
     }
 
     
+
+    
 }
diff --git a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/NodeWriter.java b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/NodeWriter.java
index 9b33132..125524d 100644
--- a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/NodeWriter.java
+++ b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/NodeWriter.java
@@ -23,6 +23,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Stack;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -88,6 +89,7 @@ final class NodeWriter implements StructuralNodeVisitor {
     @RequiredArgsConstructor
     private static enum Style {
         OPEN_BLOCK("open"::equals),
+        FOOTNOTE_LIST("arabic"::equals),
         ADMONITION_NOTE("NOTE"::equals),
         ADMONITION_TIP("TIP"::equals),
         ADMONITION_IMPORTANT("IMPORTANT"::equals),
@@ -97,7 +99,7 @@ final class NodeWriter implements StructuralNodeVisitor {
         ;
         private final Predicate<String> matcher;
         public static Style parse(StructuralNode node) {
-            val styleAttribute = (String)node.getAttribute("style");
+            val styleAttribute = node.getStyle();
             return Stream.of(Style.values())
             .filter(style->style.matcher.test(styleAttribute))
             .findFirst()
@@ -106,6 +108,9 @@ final class NodeWriter implements StructuralNodeVisitor {
         public boolean isOpenBlock() {
             return this==Style.OPEN_BLOCK;
         }
+        public boolean isFootnoteList() {
+            return this==Style.FOOTNOTE_LIST;
+        }
         public boolean isAdmonition() {
             return name().startsWith("ADMONITION_");
         }
@@ -120,6 +125,8 @@ final class NodeWriter implements StructuralNodeVisitor {
             println("+");
             println("--");
             isContinuation = true; // set continuation flag, so other blocks don't add newlines
+            bulletCountStack.push(bulletCount);
+            bulletCount = 0;
         } else if(!isContinuation) {
             if(newLineCount<=1) {
                 printNewLine();
@@ -128,11 +135,11 @@ final class NodeWriter implements StructuralNodeVisitor {
         
         if(style.isAdmonition()){
             if(block.getBlocks().size()>0) {
-                printfln("[%s]", (String)block.getAttribute("style"));
+                printfln("[%s]", block.getStyle());
                 println("====");    
                 isContinuation = true; // set continuation flag, so other blocks don't add newlines
             } else {
-                printf("%s: ", (String)block.getAttribute("style"));
+                printf("%s: ", block.getStyle());
             }
         } 
         
@@ -149,6 +156,7 @@ final class NodeWriter implements StructuralNodeVisitor {
         
         if(style.isOpenBlock()){
             println("--");
+            bulletCount = bulletCountStack.pop();
         } else if(style.isAdmonition()){
             if(block.getBlocks().size()>0) {
                 println("====");    
@@ -179,11 +187,14 @@ final class NodeWriter implements StructuralNodeVisitor {
     @Override
     public void listItemHead(ListItem listItem, int depth) {
         
-        val isFootNoteRole = bulletCount==1 
-                && listItem.getRoles().contains("footnote"); // non standard conform jack yet
+        //TODO, there is a special use case, if source is null
+        //the first block replaces the source
+        
+        val isFootnoteStyle = Style.parse((org.asciidoctor.ast.List)(listItem.getParent()))
+                .isFootnoteList(); 
         
-        val bullets = isFootNoteRole
-                ? "<.> "
+        val bullets = isFootnoteStyle
+                ? "<.>"
                 : _Strings.padEnd("", bulletCount, '*');
       
       _Strings.nonEmpty(listItem.getSource())
@@ -293,6 +304,7 @@ final class NodeWriter implements StructuralNodeVisitor {
 
     private boolean hasWrittenAnythingYet = false;
     private boolean isContinuation = false;
+    private Stack<Integer> bulletCountStack = new Stack<>();
     
     // -- PRINTING
     
diff --git a/tooling/model4adoc/src/test/java/org/apache/isis/tooling/adocmodel/test/Debug.java b/tooling/model4adoc/src/test/java/org/apache/isis/tooling/adocmodel/test/Debug.java
index d0091b6..45a8f32 100644
--- a/tooling/model4adoc/src/test/java/org/apache/isis/tooling/adocmodel/test/Debug.java
+++ b/tooling/model4adoc/src/test/java/org/apache/isis/tooling/adocmodel/test/Debug.java
@@ -43,6 +43,7 @@ final class Debug {
         
         print(level, "node type: %s", node.getClass());
         print(level, "%s title: %s", simpleName, node.getTitle());
+        print(level, "%s style: %s", simpleName, node.getStyle());
         sourceFor(node).ifPresent(x->print(level, "%s source: %s", simpleName, x));
         print(level, "%s attributes: %d", simpleName, node.getAttributes().size());
         node.getAttributes()
diff --git a/tooling/model4adoc/src/test/java/org/apache/isis/tooling/adocmodel/test/FootnoteTest.java b/tooling/model4adoc/src/test/java/org/apache/isis/tooling/adocmodel/test/FootnoteTest.java
new file mode 100644
index 0000000..931eb18
--- /dev/null
+++ b/tooling/model4adoc/src/test/java/org/apache/isis/tooling/adocmodel/test/FootnoteTest.java
@@ -0,0 +1,115 @@
+/*
+ *  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.isis.tooling.adocmodel.test;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+
+import org.asciidoctor.Asciidoctor;
+import org.asciidoctor.ast.Document;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.base._Text;
+import org.apache.isis.tooling.model4adoc.AsciiDocFactory;
+import org.apache.isis.tooling.model4adoc.AsciiDocWriter;
+
+import static org.apache.isis.tooling.model4adoc.AsciiDocFactory.doc;
+
+import lombok.val;
+
+class FootnoteTest {
+
+    private Document doc;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        doc = doc();
+    }
+
+    //<.> fn-1
+    //+
+    //--
+    //[WARNING]
+    //====
+    //warn-1
+    //
+    //warn-2
+    //====
+    //
+    //para-1
+    //
+    //para-2
+    //
+    //* li-1
+    //* li-2
+    //
+    //para-3
+    //--
+    @Test
+    void testFootnote() throws IOException {
+        
+        val footnotes = AsciiDocFactory.footnotes(doc);
+        val footnoteLI = AsciiDocFactory.footnote(footnotes, "fn-1");
+        val footnote = AsciiDocFactory.openBlock(footnoteLI);
+        
+        
+        val note = AsciiDocFactory.warning(footnote);
+        AsciiDocFactory.block(note, "warn-1");
+        AsciiDocFactory.block(note, "warn-2");
+        
+        AsciiDocFactory.block(footnote, "para-1");
+        AsciiDocFactory.block(footnote, "para-2");
+        
+        val nestedList = AsciiDocFactory.list(footnote);
+        AsciiDocFactory.listItem(nestedList, "li-1");
+        AsciiDocFactory.listItem(nestedList, "li-2");
+        
+        AsciiDocFactory.block(footnote, "para-3");
+        
+        AsciiDocFactory.tip(doc, "Here's something worth knowing...");
+        
+        String actualAdoc = AsciiDocWriter.toString(doc);
+        System.out.println(actualAdoc); //debug
+        
+        _Text.assertTextEquals(
+                _Text.readLinesFromResource(this.getClass(), "footnote.adoc", StandardCharsets.UTF_8), 
+                actualAdoc);
+    }
+    
+    @Test //@Disabled
+    void reverseTestFootnote() throws IOException {
+    
+        val adocRef = _Strings.readFromResource(this.getClass(), "footnote.adoc", StandardCharsets.UTF_8);
+        val asciidoctor = Asciidoctor.Factory.create();
+        val refDoc = asciidoctor.load(adocRef, new HashMap<String, Object>());
+        
+        Debug.debug(refDoc);
+        
+        String actualAdoc = AsciiDocWriter.toString(refDoc);
+        System.out.println(actualAdoc); //debug
+        
+        _Text.assertTextEquals(adocRef, actualAdoc);
+    }
+    
+    
+
+}
diff --git a/tooling/model4adoc/src/test/resources/org/apache/isis/tooling/adocmodel/test/footnote.adoc b/tooling/model4adoc/src/test/resources/org/apache/isis/tooling/adocmodel/test/footnote.adoc
new file mode 100644
index 0000000..951256b
--- /dev/null
+++ b/tooling/model4adoc/src/test/resources/org/apache/isis/tooling/adocmodel/test/footnote.adoc
@@ -0,0 +1,21 @@
+<.> fn-1
++
+--
+[WARNING]
+====
+warn-1
+
+warn-2
+====
+
+para-1
+
+para-2
+
+* li-1
+* li-2
+
+para-3
+--
+
+TIP: Here's something worth knowing...