001package Torello.JavaDoc.SyntaxHiLite; 002 003import Torello.Java.OSCommands; 004import Torello.Java.OSExtras; 005import Torello.Java.OSResponse; 006import Torello.Java.StrCmpr; 007import Torello.Java.OSJavaPipe; 008import Torello.Java.FileRW; 009 010import Torello.Java.ReadOnly.ReadOnlyArrayList; 011import Torello.Java.ReadOnly.ReadOnlyList; 012import Torello.JavaDoc.LinkJavaSource; 013import Torello.HTML.HTMLNode; 014import Torello.HTML.HTMLPage; 015import Torello.HTML.Util; 016 017import java.util.Objects; 018import java.util.Vector; 019import java.io.IOException; 020 021/** 022 * Java-Adapter for a Python-Tool which Hi-Lites Source Code. 023 * 024 * <BR /><BR />Visit <A HREF='pygments.org' TARGET=_blank>http://Pygments.org</A> for details. 025 * 026 * <EMBED CLASS='external-html' DATA-FILE-ID=CLI_HELP> 027 * @see OSCommands 028 * @see OSJavaPipe 029 */ 030public class Pygmentize extends OSCommands 031{ 032 public static final ReadOnlyList<String> CODE_TYPES = new ReadOnlyArrayList<>( 033 "java", "html", "js", "css", "json", "properties", "xml", "py", "c", "cpp", "csharp", "go", 034 "php", "ruby", "bash", "sh", "sql", "yaml", "toml", "ini", "docker", "make", "gradle", 035 "swift", "kotlin", "rust", "scala", "perl", "r", "ts", "tsx", "jsx", "md", "txt" 036 ); 037 038 039 // ******************************************************************************************** 040 // ******************************************************************************************** 041 // Constructor 042 // ******************************************************************************************** 043 // ******************************************************************************************** 044 045 046 public static void main(String[] argv) throws IOException 047 { 048 if (argv.length != 1) 049 { 050 System.out.println("You must pass the file-name of a Java-File"); 051 System.exit(1); 052 } 053 054 final Pygmentize p = new Pygmentize(); 055 final String f = FileRW.loadFileToString(argv[0]); 056 final Vector<HTMLNode> h = p.hiLite(f, "java", true, (byte) 1); 057 final String s = Util.pageToString(h); 058 059 System.out.println(s); 060 } 061 062 public Pygmentize() { super(null, null); } 063 064 public Pygmentize clone() 065 { throw new RuntimeException(new CloneNotSupportedException()); } 066 067 068 // ******************************************************************************************** 069 // ******************************************************************************************** 070 // Convert Source-Code (as a String) into an HiLited HTML-String 071 // ******************************************************************************************** 072 // ******************************************************************************************** 073 074 075 // NON-HTML-TEXT Output Save ... 076 // new String[] { "pygmentize", "-l", codeTypeParam, "-O", dashO } 077 078 @LinkJavaSource(handle="CleanHTML", name="clean") 079 public synchronized Vector<HTMLNode> hiLite( 080 final String codeText, 081 final String codeTypeParam, 082 final boolean useLineNumbers, 083 final byte styleNum 084 ) 085 throws IOException 086 { 087 Objects.requireNonNull(codeText, "'codeText' Parameter has been passed null."); 088 Objects.requireNonNull(codeTypeParam, "'codeTypeParam' Parameter has been passed null."); 089 090 final String dashO = 091 "classprefix=H" + styleNum + "-" + 092 (useLineNumbers ? ",linenos=table" : ""); 093 094 final String[] cmdArr = 095 { "pygmentize", "-l", codeTypeParam, "-f", "html", "-O", dashO }; 096 097 // This "Pipes" the input to the CLI Command 098 this.osExtras = new OSExtras(); 099 this.osExtras.javaPipe = new OSJavaPipe(codeText); 100 101 // Run Python's "pygmentize" - downloaded via 'pip' from Pygments.org 102 final OSResponse osr = super.printAndRun(cmdArr); 103 104 if (osr.response != 0) throw new PygmentizeException( 105 "The O/S Process for 'pygmentize' has returned a non-zero Status\n" + 106 THROW.HORIZ_SEP + 107 "OSResponse.response: " + osr.response + '\n' + 108 "OSResponse.errorOutpu:\n" + osr.errorOutput + '\n' + 109 THROW.paramsAsStr(codeText, codeTypeParam, styleNum, useLineNumbers) 110 ); 111 112 try 113 { 114 final String html = osr.standardOutput; 115 final Vector<HTMLNode> retVec = HTMLPage.getPageTokens(html, false); 116 117 CleanHTML.clean(retVec, useLineNumbers); 118 119 return retVec; 120 } 121 122 catch (Exception e) 123 { 124 throw new PygmentizeException( 125 "An error has occured while attempting to parse and simplify the returned HTML" + 126 THROW.paramsAsStr(codeText, codeTypeParam, styleNum, useLineNumbers), 127 e 128 ); 129 } 130 } 131 132 public synchronized Vector<HTMLNode> hiLite( 133 final String codeText, 134 final String codeTypeParam, 135 final boolean includeLineNumbers, 136 final byte styleNum, 137 final HiLiteCache cache 138 ) 139 throws IOException 140 { 141 Objects.requireNonNull(codeText, "'codeText' Parameter has been passed null."); 142 Objects.requireNonNull(codeTypeParam, "'codeTypeParam' Parameter has been passed null."); 143 Objects.requireNonNull(cache, "'cache' Parameter has been passed null."); 144 145 // FIRST: Check the Cache, to see if the exact String has been hilited! 146 final String cached = 147 cache.get(codeText, codeTypeParam, includeLineNumbers, styleNum); 148 149 // If there was a Cache hit -> return that String rather than querying the server. 150 if (cached != null) return HTMLPage.getPageTokens(cached, false); 151 152 153 // NO? ==> Then query the server. 154 // 155 // final Vector<HTMLNode> retVec = RESTToVector.run 156 // (codeText, codeTypeParam, styleTypeParam, includeLineNumbers); 157 158 final Vector<HTMLNode> html = 159 this.hiLite(codeText, codeTypeParam, includeLineNumbers, styleNum); 160 161 // Make sure to save the response in the Cache for next time 162 cache.checkIn 163 (codeText, Util.pageToString(html), codeTypeParam, includeLineNumbers, styleNum); 164 165 return html; 166 } 167}