001/* 002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 */ 009 010package org.eclipse.golo.doc; 011 012import org.eclipse.golo.compiler.parser.ASTCompilationUnit; 013import gololang.FunctionReference; 014import gololang.Predefined; 015 016import java.nio.file.Path; 017import java.util.Map; 018import java.util.List; 019 020 021import com.github.rjeschke.txtmark.BlockEmitter; 022import com.github.rjeschke.txtmark.Configuration; 023import com.github.rjeschke.txtmark.Processor; 024 025 026public class HtmlProcessor extends AbstractProcessor { 027 028 private Path srcFile; 029 private final DocIndex globalIndex = new DocIndex(); 030 031 @Override 032 protected String fileExtension() { 033 return "html"; 034 } 035 036 public DocIndex globalIndex() { 037 return globalIndex; 038 } 039 040 /** 041 * Returns the direct link to the given documentation element from a given filename. 042 */ 043 public String linkToDoc(String src, DocumentationElement dst) { 044 Path out = outputFile(src); 045 if (out.getParent() != null) { 046 out = out.getParent(); 047 } 048 return out.relativize(docFile(dst)).toString() 049 + (dst.id().isEmpty() ? "" : ("#" + dst.id())); 050 } 051 052 @Override 053 public String render(ModuleDocumentation documentation) throws Throwable { 054 FunctionReference template = template("template", fileExtension()); 055 globalIndex.update(documentation); 056 addModule(documentation); 057 Path doc = docFile(documentation); 058 if (doc.getParent() != null) { 059 doc = doc.getParent(); 060 } 061 return (String) template.invoke(this, documentation, doc.relativize(srcFile)); 062 } 063 064 @Override 065 public void process(Map<String, ModuleDocumentation> docs, Path targetFolder) throws Throwable { 066 setTargetFolder(targetFolder); 067 for (Map.Entry<String, ModuleDocumentation> doc : docs.entrySet()) { 068 renderModule(doc.getKey(), doc.getValue()); 069 } 070 renderIndex("index"); 071 renderIndex("index-all"); 072 } 073 074 private void renderModule(String sourceFile, ModuleDocumentation doc) throws Throwable { 075 String moduleName = doc.moduleName(); 076 srcFile = outputFile(moduleName + "-src"); 077 Predefined.textToFile(renderSource(moduleName, sourceFile), srcFile); 078 Predefined.textToFile(render(doc), outputFile(moduleName)); 079 } 080 081 private String renderSource(String moduleName, String filename) throws Throwable { 082 FunctionReference template = template("src", fileExtension()); 083 String content = (String) Predefined.fileToText(filename, "UTF-8"); 084 int nbLines = 0; 085 for (int i = 0; i < content.length(); i++) { 086 if (content.charAt(i) == '\n') { 087 nbLines++; 088 } 089 } 090 return (String) template.invoke(moduleName, content, nbLines); 091 } 092 093 public static BlockEmitter blockHighlighter() { 094 return new BlockEmitter() { 095 @Override 096 public void emitBlock(StringBuilder out, List<String> lines, String meta) { 097 String language; 098 if ("".equals(meta)) { 099 language = "golo"; 100 } else { 101 language = meta; 102 } 103 out.append("<pre class=\"listing\">"); 104 out.append(String.format("<code class=\"lang-%s\" data-lang=\"%s\">", language, language)); 105 for (String rawLine : lines) { 106 String line = rawLine 107 .replace("&", "&") 108 .replace(">", ">") 109 .replace("<", "<"); 110 out.append(line); 111 out.append('\n'); 112 } 113 out.append("</code></pre>"); 114 out.append('\n'); 115 } 116 }; 117 } 118 119 public static String sectionTitle(int level, DocumentationElement doc, Path src) { 120 String permalink = String.format("<a class=\"permalink\" href=\"#%s\" title=\"link to this section\">¶</a>", 121 doc.id()); 122 String srclink = src == null ? "" 123 : String.format("<nav class=\"srclink\"><a href=\"%s#l-%s\" rel=\"source\" title=\"Link to the corresponding source\">Source</a></nav>", 124 src, doc.line()); 125 return String.format("<h%s id=\"%s\">%s%s</h%s>%s", level, doc.id(), doc.label(), permalink, level, srclink); 126 } 127 128 public static String tocItem(DocumentationElement doc) { 129 return String.format("<a href=\"#%s\">%s</a>", doc.id(), doc.label()); 130 } 131 132 public static String process(String documentation, int rootLevel, Configuration configuration) { 133 return Processor.process(AbstractProcessor.adaptSections(documentation, rootLevel), configuration); 134 } 135}