franta-hg@6: package cz.frantovo.xmlWebGenerator; franta-hg@6: franta-hg@6: import java.io.File; franta-hg@40: import java.io.FileInputStream; franta-hg@27: import java.io.IOException; franta-hg@27: import java.io.PrintStream; franta-hg@6: import java.util.Date; franta-hg@6: import java.net.URI; franta-hg@6: import java.net.URISyntaxException; franta-hg@38: import static cz.frantovo.xmlWebGenerator.NástrojeCLI.*; franta-hg@6: franta-hg@28: /** franta-hg@28: * Knihovna funkcí volaných z XSLT. franta-hg@28: * franta-hg@36: * TODO: franta-hg@32: * - rozdělit na více modulů (jmenných prostorů). franta-hg@32: * - CLI konektor franta-hg@28: * franta-hg@28: * @author fiki franta-hg@28: */ franta-hg@6: public class Funkce { franta-hg@27: franta-hg@30: private static final String PŘÍKAZ_PYGMENTIZE = "pygmentize"; franta-hg@32: private static final String PŘÍKAZ_DOT = "dot"; franta-hg@37: private static final String PŘÍKAZ_MARKDOWN = "markdown"; franta-hg@40: private static final String ADRESÁŘ_VSTUPNÍ = "vstup"; franta-hg@32: private static final String ADRESÁŘ_VÝSTUPNÍ = "výstup"; franta-hg@32: private static int počítadloDiagramů = 0; franta-hg@30: franta-hg@28: /** franta-hg@28: * Zjištuje, kdy byl naposledy daný soubor změněn. franta-hg@28: * @param soubor cesta k souboru franta-hg@28: * @return datum poslední změny franta-hg@28: * @throws URISyntaxException franta-hg@28: */ franta-hg@21: public static Date posledníZměna(String soubor) throws URISyntaxException { franta-hg@28: URI uri = new URI(soubor); franta-hg@28: File f = new File(uri); franta-hg@28: return new Date(f.lastModified()); franta-hg@21: } franta-hg@27: franta-hg@27: /** franta-hg@27: * Zvýrazňuje syntaxi zdrojového kódu. Používá k tomu externí program/knihovnu pygmentize. franta-hg@27: * @param zdroják zdrojový kód, který předáme příkazu pygmentize na standardním vstupu franta-hg@27: * @param jazyk předáme příkazu pygmentize jako parametr -l <lexer> franta-hg@28: * @return zvýrazněný text nebo null, pokud došlo k chybě. franta-hg@31: * TODO: franta-hg@36: * - vracet místo textu instanci com.icl.saxon.om.NodeInfo http://saxon.sourceforge.net/saxon6.5.3/extensibility.html franta-hg@31: * - nebo kontrolovat validitu vygenerovaného kódu (v současnosti se spoléháme na bezchybnost pygmentize) franta-hg@27: */ franta-hg@27: public static String zvýrazniSyntaxi(String zdroják, String jazyk) throws IOException, InterruptedException { franta-hg@28: if (jazyk == null || jazyk.length() == 0) { franta-hg@28: System.err.println("Není vyplněn atribut „jazyk“ → není jasné, jak se má zvýrazňovat."); franta-hg@28: return null; franta-hg@36: } else if (isPříkazDostupný(PŘÍKAZ_PYGMENTIZE)) { franta-hg@27: Runtime r = Runtime.getRuntime(); franta-hg@30: Process p = r.exec(new String[]{PŘÍKAZ_PYGMENTIZE, "-f", "html", "-l", jazyk}); franta-hg@27: franta-hg@27: PrintStream vstupProcesu = new PrintStream(p.getOutputStream()); franta-hg@27: vstupProcesu.print(zdroják); franta-hg@27: vstupProcesu.close(); franta-hg@27: franta-hg@27: String výsledek = načtiProud(p.getInputStream()); franta-hg@27: String chyby = načtiProud(p.getErrorStream()); franta-hg@27: franta-hg@27: p.waitFor(); franta-hg@27: franta-hg@27: if (chyby.length() == 0) { franta-hg@28: // Pozor: pygmentize má i při chybě návratový kód 0 → je potřeba kontrolovat chybový výstup. franta-hg@27: return výsledek; franta-hg@27: } else { franta-hg@28: System.err.print("Při zvýrazňování syntaxe došlo k chybě: " + chyby); franta-hg@28: return null; franta-hg@27: } franta-hg@27: } else { franta-hg@30: System.err.println("Příkaz " + PŘÍKAZ_PYGMENTIZE + " není na vašem systému dostupný → zvýrazňování syntaxe nebude fungovat."); franta-hg@28: System.err.println("Můžete ho nainstalovat pomocí:"); franta-hg@28: System.err.println("\t$ aptitude install python-pygments # (Debian/Ubuntu)"); franta-hg@28: System.err.println("\t$ yum install python-pygments # (Fedora/RedHat)"); franta-hg@28: return null; franta-hg@27: } franta-hg@27: } franta-hg@27: franta-hg@28: /** franta-hg@31: * Vygeneruje CSS styl pro zvýrazňování syntaxe. franta-hg@31: * @return obsah CSS souboru nebo null, pokud generování nebylo možné franta-hg@31: */ franta-hg@31: public static String generujCssSyntaxe() throws IOException, InterruptedException { franta-hg@36: if (isPříkazDostupný(PŘÍKAZ_PYGMENTIZE)) { franta-hg@31: Runtime r = Runtime.getRuntime(); franta-hg@31: Process p = r.exec(new String[]{PŘÍKAZ_PYGMENTIZE, "-S", "default", "-f", "html"}); franta-hg@31: return načtiProud(p.getInputStream()); franta-hg@31: } else { franta-hg@31: return null; franta-hg@31: } franta-hg@31: } franta-hg@31: franta-hg@31: /** franta-hg@32: * Vytvoří obrázek s diagramem. franta-hg@32: * @param zadání definice diagramu ve formátu dot franta-hg@32: * @param vodorovně zda má být graf orientovaný vodorovně franta-hg@32: * @return název souboru bez přípony, který byl vytvořen, nebo null, pokud došlo k chybě. franta-hg@32: */ franta-hg@32: public static String vytvořDiagram(String zadání, boolean vodorovně) throws IOException, InterruptedException { franta-hg@36: if (isPříkazDostupný(PŘÍKAZ_DOT)) { franta-hg@32: počítadloDiagramů++; franta-hg@32: String soubor = "diagram-" + počítadloDiagramů; franta-hg@32: String souborSložka = ADRESÁŘ_VÝSTUPNÍ + File.separator + soubor; franta-hg@32: franta-hg@32: StringBuilder zdroják = new StringBuilder(zadání.length() + 200); franta-hg@32: franta-hg@32: zdroják.append("digraph d {\n"); franta-hg@32: zdroják.append("\tbgcolor=\"transparent\";\n"); franta-hg@32: if (vodorovně) { franta-hg@32: zdroják.append("\trankdir=LR;"); franta-hg@32: } franta-hg@32: zdroják.append(zadání); franta-hg@32: zdroják.append("}\n"); franta-hg@32: franta-hg@32: Runtime r = Runtime.getRuntime(); franta-hg@32: Process p = r.exec(new String[]{PŘÍKAZ_DOT, "-T", "svg", "-o", souborSložka + ".svg"}); franta-hg@32: franta-hg@32: /** franta-hg@32: * TODO: generovat i PNG bitmapu franta-hg@32: */ franta-hg@32: PrintStream vstupProcesu = new PrintStream(p.getOutputStream()); franta-hg@32: vstupProcesu.print(zdroják.toString()); franta-hg@32: vstupProcesu.close(); franta-hg@32: franta-hg@32: String chyby = načtiProud(p.getErrorStream()); franta-hg@32: franta-hg@32: p.waitFor(); franta-hg@32: franta-hg@32: if (chyby.length() == 0) { franta-hg@32: return soubor; franta-hg@32: } else { franta-hg@32: System.err.print("Při vytváření diagramu došlo k chybě: " + chyby); franta-hg@32: return null; franta-hg@32: } franta-hg@32: } else { franta-hg@32: System.err.println("Příkaz " + PŘÍKAZ_DOT + " není na vašem systému dostupný → diagramy nelze vygreslit."); franta-hg@32: System.err.println("Můžete ho nainstalovat pomocí:"); franta-hg@32: System.err.println("\t$ aptitude install graphviz # (Debian/Ubuntu)"); franta-hg@32: System.err.println("\t$ yum install graphviz # (Fedora/RedHat)"); franta-hg@32: return null; franta-hg@32: } franta-hg@32: } franta-hg@32: franta-hg@32: /** franta-hg@37: * Převede text ve wiki syntaxi do XHTML. franta-hg@37: * @param wiki vstupní text v dané wiki syntaxi franta-hg@37: * @param syntaxe null nebo volitelně syntaxe (markdown, texy) franta-hg@37: * @return naformátované XHTML franta-hg@37: */ franta-hg@37: public static String formátujWiki(String wiki, String syntaxe) throws IOException { franta-hg@37: if (isPříkazDostupný(PŘÍKAZ_MARKDOWN)) { franta-hg@37: Runtime r = Runtime.getRuntime(); franta-hg@37: Process p = r.exec(new String[]{PŘÍKAZ_MARKDOWN}); franta-hg@37: franta-hg@37: /** franta-hg@37: * TODO: oříznout mezery na začátcích řádků, pokud je jich všude stejně? franta-hg@37: * (odsazení v XML) franta-hg@37: */ franta-hg@37: PrintStream vstupProcesu = new PrintStream(p.getOutputStream()); franta-hg@37: vstupProcesu.print(wiki); franta-hg@37: vstupProcesu.close(); franta-hg@37: franta-hg@37: String chyby = načtiProud(p.getErrorStream()); franta-hg@37: String xhtml = načtiProud(p.getInputStream()); franta-hg@37: franta-hg@37: if (chyby.length() == 0) { franta-hg@37: return xhtml; franta-hg@37: } else { franta-hg@37: System.err.print("Při zpracování wiki syntaxe došlo k chybě: " + chyby); franta-hg@37: return null; franta-hg@37: } franta-hg@37: } else { franta-hg@37: System.err.println("Příkaz " + PŘÍKAZ_MARKDOWN + " není na vašem systému dostupný → nelze formátovat texty ve wiki syntaxi."); franta-hg@37: System.err.println("Můžete ho nainstalovat pomocí:"); franta-hg@37: System.err.println("\t$ aptitude install markdown # (Debian/Ubuntu)"); franta-hg@37: System.err.println("\t$ yum install perl-Text-Markdown # (Fedora/RedHat)"); franta-hg@37: return null; franta-hg@37: } franta-hg@37: } franta-hg@6: }