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 = 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("
\n"); b.append(navigation); b.append("\n"); } addContentsTree(b, result); result.toHtml(HtmlGenerationContext.DEFAULT, b); if(navigation != null) b.append("
\n"); addHTMLFooter(b); return b.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } private static void addContentsTree(StringBuilder b, Node node) { List 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("
"); b.append("

Contents

\n"); int level = minLevel-1; for(HeaderNode header : headers) { if(header.level < minLevel) continue; while(header.level != level) { if(header.level > level) { b.append("
    \n"); ++level; } else { b.append("
\n"); --level; } } b.append("
  • "); header.toPlainText(b); b.append("
  • \n"); } while(level >= minLevel) { b.append("\n"); --level; } b.append("
    "); } } private static void addHTMLHeader(StringBuilder b) { b.append("\n"); b.append("\n"); b.append("\n"); b.append("\n"); b.append("\n"); /*b.append("\n");*/ b.append("\n"); b.append("\n"); b.append("\n"); } private static void addHTMLFooter(StringBuilder b) { b.append("\n"); b.append("\n"); } }