]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlDocumentationGeneration.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / markdown / html / HtmlDocumentationGeneration.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlDocumentationGeneration.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlDocumentationGeneration.java
new file mode 100644 (file)
index 0000000..e92f4d3
--- /dev/null
@@ -0,0 +1,144 @@
+package org.simantics.scl.compiler.markdown.html;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.List;
+
+import org.simantics.scl.compiler.errors.Failable;
+import org.simantics.scl.compiler.markdown.internal.MarkdownParser;
+import org.simantics.scl.compiler.markdown.nodes.HeaderNode;
+import org.simantics.scl.compiler.markdown.nodes.Node;
+import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.module.repository.ModuleRepository;
+
+public class HtmlDocumentationGeneration {
+    
+    private static String STYLESHEET;
+    static {
+        try {
+            InputStream stream = HtmlDocumentationGeneration.class.getResourceAsStream("SclDoc.css");
+            try {
+                byte[] buffer = new byte[2048];
+                int pos = 0;
+                while(true) {
+                    int count = stream.read(buffer, pos, buffer.length-pos);
+                    if(count <= 0)
+                        break;
+                    pos += count;
+                    if(pos == buffer.length)
+                        buffer = Arrays.copyOf(buffer, 2*buffer.length);
+                }
+                STYLESHEET = new String(buffer, Charset.forName("UTF-8"));
+            } finally {
+                stream.close();
+            }
+        } catch(IOException e) {
+            e.printStackTrace();
+        }
+    }
+    
+    public static String generate(ModuleRepository moduleRepository, String documentationName, String navigation) {
+        String documentation = moduleRepository.getDocumentation(documentationName);
+        if(documentation == null || documentation.isEmpty()) {
+            Failable<Module> module = moduleRepository.getModule(documentationName);
+            if(!module.didSucceed())
+                return "Didn't find documentation or module for " + documentationName + ".";
+            documentation = "# Module "+documentationName+"\n\nThis module is undocumented. This is a list of its definitions.\n\n::undocumented[]";
+        }
+        MarkdownParser parser = new MarkdownParser();
+        try {
+            Node result = parser.parseDocument(new StringReader(documentation));
+            result.processExtensionNodes(new SCLDocumentationExtensionNodeHandler(moduleRepository, documentationName));
+            
+            StringBuilder b = new StringBuilder();
+            addHTMLHeader(b);
+
+            if(navigation != null) {
+                b.append("<table class=\"pagestructure\"><tr><td class=\"navi\">\n");
+                b.append(navigation);
+                b.append("</td><td class=\"content\">\n");
+            }
+            addContentsTree(b, result);
+            result.toHtml(b);
+            if(navigation != null)
+                b.append("</td></tr></table>\n");
+            
+            addHTMLFooter(b);
+            
+            return b.toString();
+        } catch (IOException e) {
+            e.printStackTrace();
+            return "";
+        }
+    }
+    
+    private static void addContentsTree(StringBuilder b, Node node) {
+        List<HeaderNode> headers = node.extractHeaders();
+        if(headers.size() > 1) {
+            int minLevel=Integer.MAX_VALUE, minLevelCount=0;
+            for(HeaderNode header : headers) {
+                if(header.level == minLevel)
+                    ++minLevelCount;
+                else if(header.level < minLevel) {
+                    minLevel = header.level;
+                    minLevelCount = 1;
+                }
+            }
+            if(minLevelCount == 1)
+                ++minLevel;
+            
+            b.append("<div id=\"contentspanel\">");
+            b.append("<h2>Contents</h2>\n");
+            int level = minLevel-1;
+            for(HeaderNode header : headers) {
+                if(header.level < minLevel)
+                    continue;
+                while(header.level != level) {
+                    if(header.level > level) {
+                        b.append("<ul>\n");
+                        ++level;
+                    }
+                    else {
+                        b.append("</ul>\n");
+                        --level;
+                    }
+                }
+                 
+                b.append("<li><a href=\"#");
+                header.toPlainText(b);
+                b.append("\">");
+                header.toPlainText(b);
+                b.append("</a></li>\n");
+            }
+            while(level >= minLevel) {
+                b.append("</ul>\n");
+                --level;
+            }
+            b.append("</div>");
+        }
+    }
+
+    private static void addHTMLHeader(StringBuilder b) {
+        b.append("<!DOCTYPE html>\n");
+        b.append("<html>\n");
+        b.append("<head>\n");
+        b.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n");
+        b.append("<meta http-equiv=\"x-ua-compatible\" content=\"IE=Edge\" />\n");
+        /*b.append("<script type=\"text/javascript\"\n");
+        b.append("  src=\"https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\">\n");
+        b.append("</script>\n");*/
+        b.append("<style type=\"text/css\">\n");
+        b.append(STYLESHEET);
+        b.append("</style>\n");
+        b.append("</head>\n");
+        b.append("<body>\n");
+    }
+    
+    private static void addHTMLFooter(StringBuilder b) {
+        b.append("</body>\n");
+        b.append("</html>\n");
+    }
+}