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