/* http-adoc - Asciidoctor extensions to jdk.httpserver Copyright (C) 2021 Ulrich Hilger This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package de.uhilger.httpserver.adoc; import com.sun.net.httpserver.HttpExchange; import de.uhilger.httpserver.base.HttpResponder; import java.io.File; import java.io.IOException; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import static org.asciidoctor.Asciidoctor.Factory.create; import org.asciidoctor.Asciidoctor; import static org.asciidoctor.AttributesBuilder.attributes; import static org.asciidoctor.OptionsBuilder.options; import org.asciidoctor.SafeMode; /** * Der AdocActor transformiert den Asciidoctor-Quellcode aus einer * gegebenen Datei zu HTML oder PDF und legt das Ergebnis als HTML- oder * PDF-Datei ab. * * Der AdocActor benötigt AsciidoctorJ im Classpath. * * @author Ulrich Hilger * @version 1, 16.06.2021 */ public class AdocActor { private static final Logger logger = Logger.getLogger(AdocActor.class.getName()); private static final String DOT = "."; public static final String HTML = "html"; public static final String PDF = "pdf"; public void handle(HttpExchange e, String fileBase, String fileName) throws IOException { File adocfile = new File(fileBase, fileName); logger.fine("adocfile: " + adocfile.getAbsolutePath()); AdocActor actor = new AdocActor(); File outfile = actor.getTargetFile(adocfile, AdocActor.HTML); logger.fine("outfile: " + outfile.getAbsolutePath()); HttpResponder fs = new HttpResponder(); fs.serveFile(e, outfile); } public File getTargetFile(File adocfile, String ext) { String nameext = adocfile.getName(); String fname = nameext.substring(0, nameext.lastIndexOf(DOT)); File outfile = new File(adocfile.getParentFile(), fname + DOT + ext); logger.log(Level.FINE, "out: {0}", outfile.getAbsolutePath()); return outfile; } public void processAdocFile(File adocfile, String pdf) { String absname = adocfile.getAbsolutePath(); logger.log(Level.FINE, "in: {0}", absname); // HTML-Datei ermitteln //String nameext = adocfile.getName(); //String fname = nameext.substring(0, nameext.lastIndexOf(DOT)); //File htmlfile = new File(adocfile.getParentFile(), fname + DOT + HTML); //File outfile = htmlfile; // Standardmaessig wird HTML zurueckgegeben //logger.fine("out: " + outfile.getAbsolutePath()); //response.setCharacterEncoding("UTF-8"); File outfile = getTargetFile(adocfile, HTML); File htmlfile = outfile; /* nach HTML transformieren, wenn die Quelle sich geandert hat oder die HTML-Datei noch nicht existiert */ if(!htmlfile.exists() || adocfile.lastModified() > htmlfile.lastModified()) { logger.fine("calling transform for " + absname); transform(absname); } /* nach PDF transformieren, wenn der Parameter pdf=true existiert und wenn die Quelle sich geandert hat oder die PDF-Datei noch nicht existiert */ if(null != pdf && pdf.equalsIgnoreCase(Boolean.TRUE.toString())) { //File pdffile = new File(adocfile.getParentFile(), fname + DOT + PDF); File pdffile = getTargetFile(adocfile, PDF); outfile = pdffile; // PDF soll zurueckgegeben werden if(!pdffile.exists() || adocfile.lastModified() > pdffile.lastModified()) { //response.setContentType("application/pdf"); transform(absname, PDF); } //ServletOutputStream os = response.getOutputStream(); //InputStream bytes = new FileInputStream(outfile); //int b = bytes.read(); //while(b > -1 ) { // os.write(b); // b = bytes.read(); //} } else { //PrintWriter out = response.getWriter(); //InputStreamReader in = new InputStreamReader(new FileInputStream(outfile), "UTF-8"); //in.transferTo(out); } } /** * Nach HTML transformieren * @param fileName der Dateiname der Quelldatei samt absoluter Pfadangabe */ private void transform(String fileName) { transform(fileName, null); } /** * In ein Format transformieren, das von einem 'Backend' von Asciidoctor * unterstuetzt wird * @param fileName der Dateiname der Quelldatei samt absoluter Pfadangabe * @param backend das Kuerzel des Backends, z.B. der String 'pdf', wenn * nach PDF transformiert werden soll */ private void transform(String fileName, String backend) { logger.fine("fileName: " + fileName + ", backend: " + backend); Map attributes; File outFile = new File(fileName); String thisDirName = outFile.getParent(); File pdfStyles = new File(outFile.getParentFile(), "custom-theme.yml"); if(pdfStyles.exists()) { attributes = attributes() .attribute("pdf-themesdir", thisDirName) .attribute("pdf-theme","custom") .attribute("pdf-fontsdir", thisDirName + "/fonts") .attribute("allow-uri-read") .sourceHighlighter("highlightjs") .asMap(); } else { attributes = attributes() .sourceHighlighter("highlightjs") .asMap(); } Map options; if(null != backend) { options = options().inPlace(false) .safe(SafeMode.SERVER) .backend(backend).attributes(attributes).asMap(); } else { options = options().inPlace(false) .safe(SafeMode.SERVER) .attributes(attributes).asMap(); } File adcf = new File(fileName); logger.fine("before asciidoctor create, adcf: " + adcf.getAbsolutePath()); Asciidoctor asciidoctor = create(); logger.fine("asciidoctor created."); asciidoctor.requireLibrary("asciidoctor-diagram"); logger.fine("asciidoctor requireLibrary diagram passed."); logger.fine("calling asciidoctor.convert for file " + adcf.getAbsolutePath()); asciidoctor.convertFile(adcf, options); } }