]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.help.core/src/org/simantics/help/core/HelpUtils.java
(refs #7358) Initial 4.7 update commit
[simantics/platform.git] / bundles / org.simantics.help.core / src / org / simantics / help / core / HelpUtils.java
index 730fd4240cb5408fe8f581c7845663f36c036b09..b4e33c8af8da755bd2cf260452790eecd9fefca4 100644 (file)
-package org.simantics.help.core;\r
-\r
-import java.io.IOException;\r
-import java.io.StringWriter;\r
-import java.net.URL;\r
-import java.net.URLDecoder;\r
-import java.nio.charset.StandardCharsets;\r
-import java.nio.file.Files;\r
-import java.nio.file.Path;\r
-import java.nio.file.StandardOpenOption;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Map.Entry;\r
-import java.util.TreeMap;\r
-\r
-import org.eclipse.mylyn.wikitext.core.parser.MarkupParser;\r
-import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder;\r
-import org.eclipse.mylyn.wikitext.mediawiki.core.MediaWikiLanguage;\r
-import org.eclipse.ui.PlatformUI;\r
-import org.eclipse.ui.help.IWorkbenchHelpSystem;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.BindingException;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
-import org.simantics.db.exception.ServiceException;\r
-import org.simantics.document.base.ontology.DocumentationResource;\r
-import org.simantics.help.HelpResources;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingUtils;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-\r
-import winterwell.markdown.pagemodel.MarkdownPage;\r
-\r
-public class HelpUtils {\r
-\r
-    public static Resource createHelpLibrary(WriteGraph graph, Resource parent) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        HelpResources HELP = HelpResources.getInstance(graph);\r
-        Resource library = graph.newResource();\r
-        graph.claim(library, L0.InstanceOf, null, HELP.HelpLibrary);\r
-        graph.addLiteral(library, L0.HasName, L0.NameOf, "Help Library", Bindings.STRING);\r
-        graph.claim(parent, L0.ConsistsOf, L0.PartOf, library);\r
-        return library;\r
-    }\r
-    \r
-    public static Resource createHelpTutorial(WriteGraph graph, Resource parent, String name) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        HelpResources HELP = HelpResources.getInstance(graph);\r
-        Resource tutorialFile = graph.newResource();\r
-        graph.claim(tutorialFile, L0.InstanceOf, null, HELP.TutorialFile);\r
-        graph.addLiteral(tutorialFile, L0.HasName, L0.NameOf, name, Bindings.STRING);\r
-        graph.claim(parent, L0.ConsistsOf, L0.PartOf, tutorialFile);\r
-        return tutorialFile;\r
-    }\r
-\r
-    public static List<Path> collectHelps(ReadGraph graph, Resource indexRoot) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        HelpResources HELP = HelpResources.getInstance(graph);\r
-        List<Resource> tutorialFiles = ModelingUtils.searchByType(graph, indexRoot, HELP.TutorialFile);\r
-        if (tutorialFiles.isEmpty())\r
-            return Collections.emptyList();\r
-        List<Path> result = new ArrayList<>(tutorialFiles.size());\r
-        for (Resource tutorialFile : tutorialFiles) {\r
-            StringBuilder sb = new StringBuilder();\r
-            \r
-            htmlHead(sb, graph.getRelatedValue2(tutorialFile, L0.HasName, Bindings.STRING));\r
-            sb.append(HelpUtils.markdownToHtml(graph, tutorialFile));\r
-            htmlHeadClose(sb);\r
-            \r
-            String indexRootURI = graph.getURI(indexRoot);\r
-            String indexRootName = graph.getRelatedValue2(indexRoot, L0.HasName, Bindings.STRING);\r
-            String tutorialFileURI = graph.getURI(tutorialFile);\r
-            String suffix = tutorialFileURI.substring(indexRootURI.length());\r
-            try {\r
-                if (suffix.startsWith("/"))\r
-                    suffix = suffix.substring(1);\r
-                suffix = URLDecoder.decode(suffix, StandardCharsets.UTF_8.name());\r
-                Path outputPath = Activator.getHtmlDirectory().resolve(indexRootName).resolve(suffix + ".html");\r
-                createDirsRec(outputPath.getParent());\r
-                if (!Files.exists(outputPath))\r
-                    Files.createFile(outputPath);\r
-                Files.write(outputPath, sb.toString().getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);\r
-                result.add(outputPath);\r
-            } catch (IOException e) {\r
-                e.printStackTrace();\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    private static void createDirsRec(Path path) throws IOException {\r
-        Path parent = path.getParent();\r
-        if (!Files.exists(parent)) {\r
-            createDirsRec(parent);\r
-        }\r
-        if (!Files.exists(path))\r
-            Files.createDirectory(path);\r
-    }\r
-\r
-    public static Map<String, List<Path>> collectHelpsFromSharedLibraries(ReadGraph graph) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        Collection<Resource> sharedLibraries = graph.syncRequest(new ObjectsWithType(graph.getRootLibrary(), L0.ConsistsOf, L0.SharedOntology));\r
-        if (sharedLibraries.isEmpty())\r
-            return Collections.emptyMap();\r
-        Map<String, List<Path>> result = new HashMap<>(sharedLibraries.size());\r
-        for (Resource library : sharedLibraries) {\r
-            String libraryName = graph.getRelatedValue2(library, L0.HasName, Bindings.STRING);\r
-            List<Path> paths = collectHelps(graph, library);\r
-            result.put(libraryName, paths);\r
-        }\r
-        return result;\r
-    }\r
-    \r
-    public static Map<String, Path> collectWidgetReferencesFromSharedLibraries(ReadGraph graph) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        Collection<Resource> sharedLibraries = graph.syncRequest(new ObjectsWithType(graph.getRootLibrary(), L0.ConsistsOf, L0.SharedOntology));\r
-        if (sharedLibraries.isEmpty())\r
-            return Collections.emptyMap();\r
-        Map<String, Path> result = new HashMap<>(sharedLibraries.size());\r
-        for (Resource library : sharedLibraries) {\r
-            String html = createWidgetReference(graph, library, "Widget Reference");\r
-            String indexRootName = graph.getRelatedValue2(library, L0.HasName, Bindings.STRING);\r
-            try {\r
-                Path outputPath = Activator.getHtmlDirectory().resolve(indexRootName).resolve("widgetReference.html");\r
-                createDirsRec(outputPath.getParent());\r
-                if (!Files.exists(outputPath))\r
-                    Files.createFile(outputPath);\r
-                Files.write(outputPath, html.getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);\r
-                result.put(indexRootName, outputPath);\r
-            } catch (IOException e) {\r
-                e.printStackTrace();\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-    \r
-    private static void htmlHead(StringBuilder sb, String title) {\r
-        sb.append("<!DOCTYPE html PUBLIC \"-//IETF//DTD HTML//EN\">\n");\r
-        sb.append("<html><head><title>" + title + " Tutorial</title>\n");\r
-        sb.append("<link rel=\"Stylesheet\" type=\"text/css\" media=\"all\" href=\"../style.css\">\n");\r
-        sb.append("</head>\n");\r
-        sb.append("<body style=\"background-color: white;\">\n");\r
-        sb.append("<h1 align=\"center\">" + title + "</h1>\n");\r
-        sb.append("<hr>\n");\r
-    }\r
-    \r
-    private static void htmlHeadClose(StringBuilder sb) {\r
-        sb.append("</body></html>\n");\r
-    }\r
-\r
-    public static String createWidgetReference(ReadGraph graph, Resource indexRoot, String title) throws DatabaseException {\r
-\r
-        String ontologyDesc = NameUtils.getSafeLabel(graph, indexRoot);\r
-        \r
-        StringBuilder sb = new StringBuilder();\r
-        \r
-        sb.append("<!DOCTYPE html PUBLIC \"-//IETF//DTD HTML//EN\">\n");\r
-        sb.append("<html><head><title>" + ontologyDesc+ " Widget Reference</title>\n");\r
-        sb.append("<link rel=\"Stylesheet\" type=\"text/css\" media=\"all\" href=\"../style.css\">\n");\r
-        sb.append("</head>\n");\r
-        sb.append("<body style=\"background-color: white;\">\n");\r
-        sb.append("<h1 align=\"center\">" + ontologyDesc+ "</h1>\n");\r
-        sb.append("<h2 align=\"center\">Widget Reference</h2>\n");\r
-        sb.append("<hr>\n");\r
-        sb.append("<h1 align=\"center\">" + title + "</h1>\n");\r
-        \r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-        DocumentationResource DOC = DocumentationResource.getInstance(graph);\r
-        \r
-        List<Resource> types = ModelingUtils.searchByType(graph, indexRoot, DOC.DocumentComponentType);\r
-        for(Resource type : types) {\r
-\r
-            \r
-            String label = NameUtils.getSafeLabel(graph, type);\r
-\r
-            sb.append("<h2><a name=\"" + label + "\"></a>" + label + "</h2>\n");\r
-            sb.append("<h3>Description</h3>\n");\r
-\r
-            String desc = graph.getPossibleRelatedValue(type, L0.HasDescription);\r
-            if(desc == null) desc = "";\r
-            \r
-            sb.append("<p>" + WikiParser.parseToHtml(desc, false) + "</p>\n");\r
-            \r
-            sb.append("<h3>Base Types</h3>\n");\r
-            \r
-            Map<String,String> names = new HashMap<String,String>();\r
-\r
-            for(Resource r : graph.getSupertypes(type)) {\r
-\r
-                if(graph.isInheritedFrom(r, STR.Component)) {\r
-                    \r
-                    String label2 = NameUtils.getSafeLabel(graph, r);\r
-                    String name = graph.getRelatedValue(r, L0.HasName);\r
-                    //if("Component".equals(name)) continue;\r
-                    if("Element".equals(name)) continue;\r
-                    if("DefinedElement".equals(name)) continue;\r
-                    if("PrimitiveComponent".equals(name)) continue;\r
-                    if("DocumentComponent".equals(name)) continue;\r
-                    \r
-                    names.put(name, label2);\r
-\r
-                }\r
-                \r
-            }\r
-\r
-            for(Map.Entry<String, String> entry : names.entrySet()) {\r
-                String stuff = "predefined/baseWidgets.html#";\r
-                sb.append("<a href=\"" + stuff + entry.getKey() + "\">" + entry.getValue() + "</a>\n");\r
-                //sb.append("<a href=\"baseWidgets.html#" + entry.getKey() + "\">" + entry.getValue() + "</a>\n");\r
-            }\r
-\r
-            sb.append("<h3>Properties</h3>\n");\r
-            sb.append("<table style=\"width: 100%;\" border=\"1\" cellpadding=\"0\" cellspacing=\"0\">\n");\r
-            sb.append("<tbody>\n");\r
-            sb.append("  <tr style=\"background-color: silver;\">\n");\r
-            sb.append("  <td valign=\"top\"><br><strong>Property Name</strong></td>\n");\r
-            sb.append("  <td valign=\"top\"><br><strong>Type</strong></td>\n");\r
-            sb.append("  <td valign=\"top\"><br><strong>Default Value</strong></td>\n");\r
-            sb.append("  <td valign=\"top\"><br><strong>Description</strong></td>\n");\r
-            sb.append("  </tr>\n");\r
-            \r
-            Map<String, Resource> propertyMap = new TreeMap<String, Resource>();\r
-            \r
-            for(Resource ass : graph.getObjects(type, L0.Asserts)) {\r
-                \r
-                Resource object = graph.getSingleObject(ass, L0.HasObject);\r
-                \r
-                if(graph.isInstanceOf(object, L0.SCLValue)) continue;\r
-                if(graph.isInstanceOf(object, L0.Function)) continue;\r
-                if(graph.isInstanceOf(object, L0.ExternalValue)) continue;\r
-\r
-                Resource pred = graph.getSingleObject(ass, L0.HasPredicate);\r
-                String pName = NameUtils.getSafeLabel(graph, pred);\r
-                propertyMap.put(pName, ass);\r
-            }\r
-            \r
-            for (Entry<String, Resource> entry : propertyMap.entrySet()) {\r
-                Resource ass = entry.getValue();\r
-                Resource object = graph.getSingleObject(ass, L0.HasObject);\r
-                \r
-                Resource pred = graph.getSingleObject(ass, L0.HasPredicate);\r
-                String pName = NameUtils.getSafeLabel(graph, pred);\r
-                String valueType = graph.getPossibleRelatedValue(pred, L0.RequiresValueType);\r
-\r
-                Object jObject = graph.getValue(object);\r
-                String objectName = jObject.toString();\r
-                if(jObject.getClass().isArray()) {\r
-                    Class<?> c1 = jObject.getClass().getComponentType();\r
-                    boolean p1 = c1.isPrimitive();\r
-                    if (!p1)\r
-                        objectName = Arrays.toString((Object[])jObject);\r
-                    if (boolean.class.equals(c1))\r
-                        objectName = Arrays.toString((boolean[])jObject);\r
-                    else if (byte.class.equals(c1))\r
-                        objectName = Arrays.toString((byte[])jObject);\r
-                    else if (int.class.equals(c1))\r
-                        objectName = Arrays.toString((int[])jObject);\r
-                    else if (long.class.equals(c1))\r
-                        objectName = Arrays.toString((long[])jObject);\r
-                    else if (float.class.equals(c1))\r
-                        objectName = Arrays.toString((float[])jObject);\r
-                    else if (double.class.equals(c1))\r
-                        objectName = Arrays.toString((double[])jObject);\r
-                }\r
-\r
-                String pDesc = graph.getPossibleRelatedValue(pred, L0.HasDescription);\r
-                if(pDesc == null) pDesc = "";\r
-                \r
-                sb.append("  <tr>\n");\r
-                sb.append("  <td valign=\"top\">" + pName + "</td>\n");\r
-                sb.append("  <td valign=\"top\">" + valueType + "</td>\n");\r
-                sb.append("  <td valign=\"top\">" + objectName + "</td>\n");\r
-                sb.append("  <td valign=\"top\">" + WikiParser.parseToHtml(pDesc, false) + "</td>\n");\r
-                sb.append("  </tr>\n");\r
-            }\r
-\r
-            sb.append("  </tbody></table><br>\n");\r
-        }\r
-\r
-        sb.append("</body></html>\n");\r
-        return sb.toString();\r
-    }\r
-    \r
-    public static void clearHelpTocCache() {\r
-        SimanticsTocProvider.clearTocCache();\r
-    }\r
-    \r
-    public static void saveHelpFileContents(WriteGraph graph, Resource helpFile, String currentText) throws BindingException, ManyObjectsForFunctionalRelationException, ServiceException {\r
-        HelpResources HELP = HelpResources.getInstance(graph);\r
-        graph.claimLiteral(helpFile, HELP.HelpFile_contents, currentText, Bindings.STRING);\r
-    }\r
-    \r
-    public static String readHelpFileContents(ReadGraph graph, Resource helpFile) throws DatabaseException {\r
-        HelpResources HELP = HelpResources.getInstance(graph);\r
-        String content = graph.getPossibleRelatedValue2(helpFile, HELP.HelpFile_contents, Bindings.STRING);\r
-        return content != null ? content : "";\r
-    }\r
-    \r
-    public static String markdownToHtml(ReadGraph graph, Resource tutorialFile) throws DatabaseException {\r
-        HelpResources HELP = HelpResources.getInstance(graph);\r
-        String markdown = graph.getRelatedValue2(tutorialFile, HELP.HelpFile_contents, Bindings.STRING);\r
-        MarkdownPage page = new MarkdownPage(markdown);\r
-        return page.html();\r
-    }\r
-    \r
-    public static URL getHelpBrowserUrl() {\r
-        IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();\r
-        URL url = helpSystem.resolve("", false);\r
-        return url;\r
-    }\r
-\r
-    private static class WikiParser {\r
-        \r
-        private static MarkupParser markupParser = new MarkupParser(new MediaWikiLanguage());\r
-        \r
-        private WikiParser() {}\r
-        \r
-        public static String parseToHtml(String wiki, boolean asDocument) {\r
-            StringWriter writer = new StringWriter();\r
-            HtmlDocumentBuilder builder = new HtmlDocumentBuilder(writer);\r
-            markupParser.setBuilder(builder);\r
-            markupParser.parse(wiki, asDocument);\r
-            return writer.toString();\r
-        }\r
-    }\r
-}\r
+package org.simantics.help.core;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.eclipse.mylyn.wikitext.parser.MarkupParser;
+import org.eclipse.mylyn.wikitext.parser.builder.HtmlDocumentBuilder;
+import org.eclipse.mylyn.wikitext.mediawiki.MediaWikiLanguage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.BindingException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
+import org.simantics.db.exception.ServiceException;
+import org.simantics.document.base.ontology.DocumentationResource;
+import org.simantics.help.HelpResources;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingUtils;
+import org.simantics.structural.stubs.StructuralResource2;
+
+import winterwell.markdown.pagemodel.MarkdownPage;
+
+public class HelpUtils {
+
+    public static Resource createHelpLibrary(WriteGraph graph, Resource parent) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        HelpResources HELP = HelpResources.getInstance(graph);
+        Resource library = graph.newResource();
+        graph.claim(library, L0.InstanceOf, null, HELP.HelpLibrary);
+        graph.addLiteral(library, L0.HasName, L0.NameOf, "Help Library", Bindings.STRING);
+        graph.claim(parent, L0.ConsistsOf, L0.PartOf, library);
+        return library;
+    }
+    
+    public static Resource createHelpTutorial(WriteGraph graph, Resource parent, String name) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        HelpResources HELP = HelpResources.getInstance(graph);
+        Resource tutorialFile = graph.newResource();
+        graph.claim(tutorialFile, L0.InstanceOf, null, HELP.TutorialFile);
+        graph.addLiteral(tutorialFile, L0.HasName, L0.NameOf, name, Bindings.STRING);
+        graph.claim(parent, L0.ConsistsOf, L0.PartOf, tutorialFile);
+        return tutorialFile;
+    }
+
+    public static List<Path> collectHelps(ReadGraph graph, Resource indexRoot) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        HelpResources HELP = HelpResources.getInstance(graph);
+        List<Resource> tutorialFiles = ModelingUtils.searchByType(graph, indexRoot, HELP.TutorialFile);
+        if (tutorialFiles.isEmpty())
+            return Collections.emptyList();
+        List<Path> result = new ArrayList<>(tutorialFiles.size());
+        for (Resource tutorialFile : tutorialFiles) {
+            StringBuilder sb = new StringBuilder();
+            
+            htmlHead(sb, graph.getRelatedValue2(tutorialFile, L0.HasName, Bindings.STRING));
+            sb.append(HelpUtils.markdownToHtml(graph, tutorialFile));
+            htmlHeadClose(sb);
+            
+            String indexRootURI = graph.getURI(indexRoot);
+            String indexRootName = graph.getRelatedValue2(indexRoot, L0.HasName, Bindings.STRING);
+            String tutorialFileURI = graph.getURI(tutorialFile);
+            String suffix = tutorialFileURI.substring(indexRootURI.length());
+            try {
+                if (suffix.startsWith("/"))
+                    suffix = suffix.substring(1);
+                suffix = URLDecoder.decode(suffix, StandardCharsets.UTF_8.name());
+                Path outputPath = Activator.getHtmlDirectory().resolve(indexRootName).resolve(suffix + ".html");
+                createDirsRec(outputPath.getParent());
+                if (!Files.exists(outputPath))
+                    Files.createFile(outputPath);
+                Files.write(outputPath, sb.toString().getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
+                result.add(outputPath);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return result;
+    }
+
+    private static void createDirsRec(Path path) throws IOException {
+        Path parent = path.getParent();
+        if (!Files.exists(parent)) {
+            createDirsRec(parent);
+        }
+        if (!Files.exists(path))
+            Files.createDirectory(path);
+    }
+
+    public static Map<String, List<Path>> collectHelpsFromSharedLibraries(ReadGraph graph) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        Collection<Resource> sharedLibraries = graph.syncRequest(new ObjectsWithType(graph.getRootLibrary(), L0.ConsistsOf, L0.SharedOntology));
+        if (sharedLibraries.isEmpty())
+            return Collections.emptyMap();
+        Map<String, List<Path>> result = new HashMap<>(sharedLibraries.size());
+        for (Resource library : sharedLibraries) {
+            String libraryName = graph.getRelatedValue2(library, L0.HasName, Bindings.STRING);
+            List<Path> paths = collectHelps(graph, library);
+            result.put(libraryName, paths);
+        }
+        return result;
+    }
+    
+    public static Map<String, Path> collectWidgetReferencesFromSharedLibraries(ReadGraph graph) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        Collection<Resource> sharedLibraries = graph.syncRequest(new ObjectsWithType(graph.getRootLibrary(), L0.ConsistsOf, L0.SharedOntology));
+        if (sharedLibraries.isEmpty())
+            return Collections.emptyMap();
+        Map<String, Path> result = new HashMap<>(sharedLibraries.size());
+        for (Resource library : sharedLibraries) {
+            String html = createWidgetReference(graph, library, "Widget Reference");
+            String indexRootName = graph.getRelatedValue2(library, L0.HasName, Bindings.STRING);
+            try {
+                Path outputPath = Activator.getHtmlDirectory().resolve(indexRootName).resolve("widgetReference.html");
+                createDirsRec(outputPath.getParent());
+                if (!Files.exists(outputPath))
+                    Files.createFile(outputPath);
+                Files.write(outputPath, html.getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
+                result.put(indexRootName, outputPath);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return result;
+    }
+    
+    private static void htmlHead(StringBuilder sb, String title) {
+        sb.append("<!DOCTYPE html PUBLIC \"-//IETF//DTD HTML//EN\">\n");
+        sb.append("<html><head><title>" + title + " Tutorial</title>\n");
+        sb.append("<link rel=\"Stylesheet\" type=\"text/css\" media=\"all\" href=\"../style.css\">\n");
+        sb.append("</head>\n");
+        sb.append("<body style=\"background-color: white;\">\n");
+        sb.append("<h1 align=\"center\">" + title + "</h1>\n");
+        sb.append("<hr>\n");
+    }
+    
+    private static void htmlHeadClose(StringBuilder sb) {
+        sb.append("</body></html>\n");
+    }
+
+    public static String createWidgetReference(ReadGraph graph, Resource indexRoot, String title) throws DatabaseException {
+
+        String ontologyDesc = NameUtils.getSafeLabel(graph, indexRoot);
+        
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append("<!DOCTYPE html PUBLIC \"-//IETF//DTD HTML//EN\">\n");
+        sb.append("<html><head><title>" + ontologyDesc+ " Widget Reference</title>\n");
+        sb.append("<link rel=\"Stylesheet\" type=\"text/css\" media=\"all\" href=\"../style.css\">\n");
+        sb.append("</head>\n");
+        sb.append("<body style=\"background-color: white;\">\n");
+        sb.append("<h1 align=\"center\">" + ontologyDesc+ "</h1>\n");
+        sb.append("<h2 align=\"center\">Widget Reference</h2>\n");
+        sb.append("<hr>\n");
+        sb.append("<h1 align=\"center\">" + title + "</h1>\n");
+        
+        Layer0 L0 = Layer0.getInstance(graph);
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);
+        DocumentationResource DOC = DocumentationResource.getInstance(graph);
+        
+        List<Resource> types = ModelingUtils.searchByType(graph, indexRoot, DOC.DocumentComponentType);
+        for(Resource type : types) {
+
+            
+            String label = NameUtils.getSafeLabel(graph, type);
+
+            sb.append("<h2><a name=\"" + label + "\"></a>" + label + "</h2>\n");
+            sb.append("<h3>Description</h3>\n");
+
+            String desc = graph.getPossibleRelatedValue(type, L0.HasDescription);
+            if(desc == null) desc = "";
+            
+            sb.append("<p>" + WikiParser.parseToHtml(desc, false) + "</p>\n");
+            
+            sb.append("<h3>Base Types</h3>\n");
+            
+            Map<String,String> names = new HashMap<String,String>();
+
+            for(Resource r : graph.getSupertypes(type)) {
+
+                if(graph.isInheritedFrom(r, STR.Component)) {
+                    
+                    String label2 = NameUtils.getSafeLabel(graph, r);
+                    String name = graph.getRelatedValue(r, L0.HasName);
+                    //if("Component".equals(name)) continue;
+                    if("Element".equals(name)) continue;
+                    if("DefinedElement".equals(name)) continue;
+                    if("PrimitiveComponent".equals(name)) continue;
+                    if("DocumentComponent".equals(name)) continue;
+                    
+                    names.put(name, label2);
+
+                }
+                
+            }
+
+            for(Map.Entry<String, String> entry : names.entrySet()) {
+                String stuff = "predefined/baseWidgets.html#";
+                sb.append("<a href=\"" + stuff + entry.getKey() + "\">" + entry.getValue() + "</a>\n");
+                //sb.append("<a href=\"baseWidgets.html#" + entry.getKey() + "\">" + entry.getValue() + "</a>\n");
+            }
+
+            sb.append("<h3>Properties</h3>\n");
+            sb.append("<table style=\"width: 100%;\" border=\"1\" cellpadding=\"0\" cellspacing=\"0\">\n");
+            sb.append("<tbody>\n");
+            sb.append("  <tr style=\"background-color: silver;\">\n");
+            sb.append("  <td valign=\"top\"><br><strong>Property Name</strong></td>\n");
+            sb.append("  <td valign=\"top\"><br><strong>Type</strong></td>\n");
+            sb.append("  <td valign=\"top\"><br><strong>Default Value</strong></td>\n");
+            sb.append("  <td valign=\"top\"><br><strong>Description</strong></td>\n");
+            sb.append("  </tr>\n");
+            
+            Map<String, Resource> propertyMap = new TreeMap<String, Resource>();
+            
+            for(Resource ass : graph.getObjects(type, L0.Asserts)) {
+                
+                Resource object = graph.getSingleObject(ass, L0.HasObject);
+                
+                if(graph.isInstanceOf(object, L0.SCLValue)) continue;
+                if(graph.isInstanceOf(object, L0.Function)) continue;
+                if(graph.isInstanceOf(object, L0.ExternalValue)) continue;
+
+                Resource pred = graph.getSingleObject(ass, L0.HasPredicate);
+                String pName = NameUtils.getSafeLabel(graph, pred);
+                propertyMap.put(pName, ass);
+            }
+            
+            for (Entry<String, Resource> entry : propertyMap.entrySet()) {
+                Resource ass = entry.getValue();
+                Resource object = graph.getSingleObject(ass, L0.HasObject);
+                
+                Resource pred = graph.getSingleObject(ass, L0.HasPredicate);
+                String pName = NameUtils.getSafeLabel(graph, pred);
+                String valueType = graph.getPossibleRelatedValue(pred, L0.RequiresValueType);
+
+                Object jObject = graph.getValue(object);
+                String objectName = jObject.toString();
+                if(jObject.getClass().isArray()) {
+                    Class<?> c1 = jObject.getClass().getComponentType();
+                    boolean p1 = c1.isPrimitive();
+                    if (!p1)
+                        objectName = Arrays.toString((Object[])jObject);
+                    if (boolean.class.equals(c1))
+                        objectName = Arrays.toString((boolean[])jObject);
+                    else if (byte.class.equals(c1))
+                        objectName = Arrays.toString((byte[])jObject);
+                    else if (int.class.equals(c1))
+                        objectName = Arrays.toString((int[])jObject);
+                    else if (long.class.equals(c1))
+                        objectName = Arrays.toString((long[])jObject);
+                    else if (float.class.equals(c1))
+                        objectName = Arrays.toString((float[])jObject);
+                    else if (double.class.equals(c1))
+                        objectName = Arrays.toString((double[])jObject);
+                }
+
+                String pDesc = graph.getPossibleRelatedValue(pred, L0.HasDescription);
+                if(pDesc == null) pDesc = "";
+                
+                sb.append("  <tr>\n");
+                sb.append("  <td valign=\"top\">" + pName + "</td>\n");
+                sb.append("  <td valign=\"top\">" + valueType + "</td>\n");
+                sb.append("  <td valign=\"top\">" + objectName + "</td>\n");
+                sb.append("  <td valign=\"top\">" + WikiParser.parseToHtml(pDesc, false) + "</td>\n");
+                sb.append("  </tr>\n");
+            }
+
+            sb.append("  </tbody></table><br>\n");
+        }
+
+        sb.append("</body></html>\n");
+        return sb.toString();
+    }
+    
+    public static void clearHelpTocCache() {
+        SimanticsTocProvider.clearTocCache();
+    }
+    
+    public static void saveHelpFileContents(WriteGraph graph, Resource helpFile, String currentText) throws BindingException, ManyObjectsForFunctionalRelationException, ServiceException {
+        HelpResources HELP = HelpResources.getInstance(graph);
+        graph.claimLiteral(helpFile, HELP.HelpFile_contents, currentText, Bindings.STRING);
+    }
+    
+    public static String readHelpFileContents(ReadGraph graph, Resource helpFile) throws DatabaseException {
+        HelpResources HELP = HelpResources.getInstance(graph);
+        String content = graph.getPossibleRelatedValue2(helpFile, HELP.HelpFile_contents, Bindings.STRING);
+        return content != null ? content : "";
+    }
+    
+    public static String markdownToHtml(ReadGraph graph, Resource tutorialFile) throws DatabaseException {
+        HelpResources HELP = HelpResources.getInstance(graph);
+        String markdown = graph.getRelatedValue2(tutorialFile, HELP.HelpFile_contents, Bindings.STRING);
+        MarkdownPage page = new MarkdownPage(markdown);
+        return page.html();
+    }
+    
+    public static URL getHelpBrowserUrl() {
+        IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();
+        URL url = helpSystem.resolve("", false);
+        return url;
+    }
+
+    private static class WikiParser {
+        
+        private static MarkupParser markupParser = new MarkupParser(new MediaWikiLanguage());
+        
+        private WikiParser() {}
+        
+        public static String parseToHtml(String wiki, boolean asDocument) {
+            StringWriter writer = new StringWriter();
+            HtmlDocumentBuilder builder = new HtmlDocumentBuilder(writer);
+            markupParser.setBuilder(builder);
+            markupParser.parse(wiki, asDocument);
+            return writer.toString();
+        }
+    }
+}