| 59 | | |
| 60 | | /** |
| 61 | | * Zvýrazňuje syntaxi zdrojového kódu. Používá k tomu externí program/knihovnu pygmentize. |
| 62 | | * @param zdroják zdrojový kód, který předáme příkazu pygmentize na standardním vstupu |
| 63 | | * @param jazyk předáme příkazu pygmentize jako parametr -l <lexer> |
| 64 | | * @return zvýrazněný text nebo null, pokud došlo k chybě. |
| 65 | | * TODO: |
| 66 | | * - vracet místo textu instanci com.icl.saxon.om.NodeInfo http://saxon.sourceforge.net/saxon6.5.3/extensibility.html |
| 67 | | * - nebo kontrolovat validitu vygenerovaného kódu (v současnosti se spoléháme na bezchybnost pygmentize) |
| 68 | | */ |
| 69 | | public static String zvýrazniSyntaxi(String zdroják, String jazyk) throws IOException, InterruptedException { |
| 70 | | if (jazyk == null || jazyk.length() == 0) { |
| 71 | | System.err.println("Není vyplněn atribut „jazyk“ → není jasné, jak se má zvýrazňovat."); |
| 72 | | return null; |
| 73 | | } else if (isPříkazDostupný(PŘÍKAZ_PYGMENTIZE)) { |
| 74 | | Runtime r = Runtime.getRuntime(); |
| 75 | | Process p = r.exec(new String[]{PŘÍKAZ_PYGMENTIZE, "-f", "html", "-l", jazyk}); |
| 76 | | |
| 77 | | PrintStream vstupProcesu = new PrintStream(p.getOutputStream()); |
| 78 | | vstupProcesu.print(zdroják); |
| 79 | | vstupProcesu.close(); |
| 80 | | |
| 81 | | String výsledek = načtiProud(p.getInputStream()); |
| 82 | | String chyby = načtiProud(p.getErrorStream()); |
| 83 | | |
| 84 | | p.waitFor(); |
| 85 | | |
| 86 | | if (chyby.length() == 0) { |
| 87 | | // Pozor: pygmentize má i při chybě návratový kód 0 → je potřeba kontrolovat chybový výstup. |
| 88 | | return výsledek; |
| 89 | | } else { |
| 90 | | System.err.print("Při zvýrazňování syntaxe došlo k chybě: " + chyby); |
| 91 | | return null; |
| 92 | | } |
| 93 | | } else { |
| 94 | | System.err.println("Příkaz " + PŘÍKAZ_PYGMENTIZE + " není na vašem systému dostupný → zvýrazňování syntaxe nebude fungovat."); |
| 95 | | System.err.println("Můžete ho nainstalovat pomocí:"); |
| 96 | | System.err.println("\t$ aptitude install python-pygments # (Debian/Ubuntu)"); |
| 97 | | System.err.println("\t$ yum install python-pygments # (Fedora/RedHat)"); |
| 98 | | return null; |
| 99 | | } |
| 100 | | } |
| 101 | | |
| 102 | | /** |
| 103 | | * Vygeneruje CSS styl pro zvýrazňování syntaxe. |
| 104 | | * @return obsah CSS souboru nebo null, pokud generování nebylo možné |
| 105 | | */ |
| 106 | | public static String generujCssSyntaxe() throws IOException, InterruptedException { |
| 107 | | if (isPříkazDostupný(PŘÍKAZ_PYGMENTIZE)) { |
| 108 | | Runtime r = Runtime.getRuntime(); |
| 109 | | Process p = r.exec(new String[]{PŘÍKAZ_PYGMENTIZE, "-S", "default", "-f", "html"}); |
| 110 | | return načtiProud(p.getInputStream()); |
| 111 | | } else { |
| 112 | | return null; |
| 113 | | } |
| 114 | | } |
| 115 | | |
| 116 | | /** |
| 117 | | * Vytvoří obrázek s diagramem. |
| 118 | | * @param zadání definice diagramu ve formátu dot |
| 119 | | * @param vodorovně zda má být graf orientovaný vodorovně (funguje jen při <code>kompletní = false</code>) |
| 120 | | * @param kompletní false, pokud k zadání chceme doplnit <code>digraph d {…}</code> |
| 121 | | * @param kontext kam diagram patří – typicky název stránky, do které je vložen |
| 122 | | * diagramy se pak budou číslovat v rámci tohoto kontextu |
| 123 | | * → nebude docházet k přepisování diagramů jiných stránek při částečném přegenerování webu. |
| 124 | | * @param souborZadání null pokud chceme automatické číslování | nebo zadáme název souboru se zadáním diagramu – vygenerovaný diagram se pak bude jmenovat stejně |
| 125 | | * @return název souboru bez přípony, který byl vytvořen, nebo null, pokud došlo k chybě. |
| 126 | | */ |
| 127 | | public static String vytvořDiagram(String zadání, boolean vodorovně, boolean kompletní, String kontext, String souborZadání) throws IOException, InterruptedException { |
| 128 | | if (isPříkazDostupný(PŘÍKAZ_DOT)) { |
| 129 | | |
| 130 | | String soubor; |
| 131 | | if (souborZadání == null) { |
| 132 | | if (kontext == null) { |
| 133 | | počítadloDiagramů++; |
| 134 | | soubor = "diagram-" + počítadloDiagramů; |
| 135 | | } else { |
| 136 | | // TODO: tohle by se mělo udělat v XSLT |
| 137 | | kontext = URLDecoder.decode(kontext, Charset.defaultCharset().name()); |
| 138 | | |
| 139 | | // Každá stránka bude mít svoje diagramy číslované od 1 |
| 140 | | if (!počítadloDiagramůKontext.equals(kontext)) { |
| 141 | | počítadloDiagramůKontext = kontext; |
| 142 | | počítadloDiagramů = 0; |
| 143 | | } |
| 144 | | |
| 145 | | počítadloDiagramů++; |
| 146 | | soubor = "diagram-" + kontext + "-" + počítadloDiagramů; |
| 147 | | } |
| 148 | | } else { |
| 149 | | soubor = souborZadání; |
| 150 | | } |
| 151 | | String souborSložka = ADRESÁŘ_VÝSTUPNÍ + File.separator + soubor; |
| 152 | | |
| 153 | | String zdroják; |
| 154 | | if (kompletní) { |
| 155 | | zdroják = zadání; |
| 156 | | } else { |
| 157 | | StringBuilder b = new StringBuilder(zadání.length() + 200); |
| 158 | | b.append("digraph d {\n"); |
| 159 | | b.append("\tbgcolor=\"transparent\";\n"); |
| 160 | | if (vodorovně) { |
| 161 | | b.append("\trankdir=LR;"); |
| 162 | | } |
| 163 | | b.append(zadání); |
| 164 | | b.append("}\n"); |
| 165 | | zdroják = b.toString(); |
| 166 | | } |
| 167 | | |
| 168 | | Runtime r = Runtime.getRuntime(); |
| 169 | | Process p = r.exec(new String[]{PŘÍKAZ_DOT, "-T", "svg", "-o", souborSložka + ".svg"}); |
| 170 | | |
| 171 | | /** |
| 172 | | * TODO: generovat i PNG bitmapu |
| 173 | | */ |
| 174 | | PrintStream vstupProcesu = new PrintStream(p.getOutputStream()); |
| 175 | | vstupProcesu.print(zdroják.toString()); |
| 176 | | vstupProcesu.close(); |
| 177 | | |
| 178 | | String chyby = načtiProud(p.getErrorStream()); |
| 179 | | |
| 180 | | p.waitFor(); |
| 181 | | |
| 182 | | if (chyby.length() == 0) { |
| 183 | | return soubor; |
| 184 | | } else { |
| 185 | | System.err.print("Při vytváření diagramu došlo k chybě: " + chyby); |
| 186 | | return null; |
| 187 | | } |
| 188 | | } else { |
| 189 | | System.err.println("Příkaz " + PŘÍKAZ_DOT + " není na vašem systému dostupný → diagramy nelze vygreslit."); |
| 190 | | System.err.println("Můžete ho nainstalovat pomocí:"); |
| 191 | | System.err.println("\t$ aptitude install graphviz # (Debian/Ubuntu)"); |
| 192 | | System.err.println("\t$ yum install graphviz # (Fedora/RedHat)"); |
| 193 | | return null; |
| 194 | | } |
| 195 | | } |
| 196 | | |
| 197 | | /** |
| 198 | | * Převede text ve wiki syntaxi do XHTML. |
| 199 | | * @param wiki vstupní text v dané wiki syntaxi |
| 200 | | * @param syntaxe null nebo volitelně syntaxe (markdown, texy) |
| 201 | | * @return naformátované XHTML |
| 202 | | */ |
| 203 | | public static String formátujWiki(String wiki, String syntaxe) throws IOException { |
| 204 | | if (isPříkazDostupný(PŘÍKAZ_MARKDOWN)) { |
| 205 | | Runtime r = Runtime.getRuntime(); |
| 206 | | Process p = r.exec(new String[]{PŘÍKAZ_MARKDOWN}); |
| 207 | | |
| 208 | | /** |
| 209 | | * TODO: oříznout mezery na začátcích řádků, pokud je jich všude stejně? |
| 210 | | * (odsazení v XML) |
| 211 | | */ |
| 212 | | PrintStream vstupProcesu = new PrintStream(p.getOutputStream()); |
| 213 | | vstupProcesu.print(wiki); |
| 214 | | vstupProcesu.close(); |
| 215 | | |
| 216 | | String chyby = načtiProud(p.getErrorStream()); |
| 217 | | String xhtml = načtiProud(p.getInputStream()); |
| 218 | | |
| 219 | | if (chyby.length() == 0) { |
| 220 | | return xhtml; |
| 221 | | } else { |
| 222 | | System.err.print("Při zpracování wiki syntaxe došlo k chybě: " + chyby); |
| 223 | | return null; |
| 224 | | } |
| 225 | | } else { |
| 226 | | System.err.println("Příkaz " + PŘÍKAZ_MARKDOWN + " není na vašem systému dostupný → nelze formátovat texty ve wiki syntaxi."); |
| 227 | | System.err.println("Můžete ho nainstalovat pomocí:"); |
| 228 | | System.err.println("\t$ aptitude install markdown # (Debian/Ubuntu)"); |
| 229 | | System.err.println("\t$ yum install perl-Text-Markdown # (Fedora/RedHat)"); |
| 230 | | return null; |
| 231 | | } |
| 232 | | } |