Asciidoctor mit Neon transformieren
ulrich
2022-01-09 1d695f99b80503bd6efbf181e6b8733ba3d1fb25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
  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 <https://www.gnu.org/licenses/>.
 */
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 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 String DOT = ".";
  public static final String HTML = "html";
  public static final String PDF = "pdf";
  
  public void handle(HttpExchange e, String fileBase, String fileName, boolean pdf) throws IOException {
    File adocfile = new File(fileBase, fileName);
    //logger.fine("adocfile: " + adocfile.getAbsolutePath());
    AdocActor actor = new AdocActor();
    File outfile;
    if(pdf) {
      outfile = actor.getTargetFile(adocfile, AdocActor.PDF);
    } else {
      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
    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);
      }
    }
  }
  
  /**
   * 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<String, Object> 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<String, Object> 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);    
  }
  
}