001/* 002 * Copyright 2004-2006 Geert Bevin <gbevin[remove] at uwyn dot com> 003 * Distributed under the terms of either: 004 * - the common development and distribution license (CDDL), v1.0; or 005 * - the GNU Lesser General Public License, v2.1 or later 006 * $Id: JHighlight.java 3106 2006-03-13 17:53:50Z gbevin $ 007 */ 008package com.uwyn.jhighlight; 009 010import com.uwyn.jhighlight.renderer.XhtmlRendererFactory; 011import com.uwyn.jhighlight.tools.FileUtils; 012import java.io.File; 013import java.io.FileOutputStream; 014import java.io.IOException; 015import java.util.ArrayList; 016import java.util.Iterator; 017import java.util.Set; 018import java.util.regex.Pattern; 019 020/** 021 * Provides console access to the source code syntax highlighting for Java, 022 * HTML, XHTML, XML and LZX files. The rendering will be done in HTML. 023 * <p>The following file extensions will be processed: <code>.java</code>, 024 * <code>.html</code>, <code>.htm</code>, <code>.xhtml</code>, 025 * <code>.xml</code> and <code>.lzx</code>. 026 * <p>Execute the highlighting with the following syntax: 027 * <pre>java com.uwyn.jhighlight.JHighlight [--verbose] [--fragment] [-d destdir] [-e encoding] file|dir ...</pre> 028 * <table border="0"> 029 * <tr> 030 * <td><code>--verbose</code></td> 031 * <td>Output messages about what the parser is doing.</td> 032 * </tr> 033 * <tr> 034 * <td><code>--fragment</code></td> 035 * <td>Output fragments instead of complete documents.</td> 036 * </tr> 037 * <tr> 038 * <td><code>-d</code></td> 039 * <td>Specify the destination directory</td> 040 * </tr> 041 * <tr> 042 * <td><code>-e</code></td> 043 * <td>Specify the encoding of the files</td> 044 * </tr> 045 * </table> 046 * <p><a href="https://rife.dev.java.net">RIFE</a> template tags are also 047 * supported and will be clearly highlighted. 048 * 049 * @author Geert Bevin (gbevin[remove] at uwyn dot com) 050 * @version $Revision: 3106 $ 051 * @since 1.0 052 */ 053public class JHighlight 054{ 055 public static void main(String[] arguments) throws Throwable 056 { 057 String destdir_name = null; 058 boolean verbose = false; 059 String encoding = null; 060 boolean fragment = false; 061 ArrayList names = new ArrayList(); 062 063 boolean valid_arguments = true; 064 if (arguments.length < 1) 065 { 066 valid_arguments = false; 067 } 068 else 069 { 070 boolean next_is_destdir = false; 071 boolean next_is_encoding = false; 072 String argument; 073 for (int i = 0; i < arguments.length; i++) 074 { 075 argument = arguments[i]; 076 if (next_is_destdir) 077 { 078 destdir_name = argument; 079 next_is_destdir = false; 080 continue; 081 } 082 083 if (next_is_encoding) 084 { 085 encoding = argument; 086 next_is_encoding = false; 087 continue; 088 } 089 090 if (argument.equals("-d")) 091 { 092 next_is_destdir = true; 093 continue; 094 } 095 096 if (argument.equals("-e")) 097 { 098 next_is_encoding = true; 099 continue; 100 } 101 102 if (argument.equals("--verbose")) 103 { 104 verbose = true; 105 continue; 106 } 107 108 if (argument.equals("--fragment")) 109 { 110 fragment = true; 111 continue; 112 } 113 114 names.add(argument); 115 } 116 } 117 118 if (0 == names.size()) 119 { 120 valid_arguments = false; 121 } 122 123 if (!valid_arguments) 124 { 125 System.err.println("Usage : java " + JHighlight.class.getName() + " [--verbose] [--fragment] [-d destdir] [-e encoding] file|dir ..."); 126 System.err.println("Generates highlighted XHTML files from all Java and XML source files"); 127 System.err.println("in the specified directories."); 128 System.err.println(" --verbose Output messages about what the parser is doing"); 129 System.err.println(" --fragment Output fragments instead of complete documents"); 130 System.err.println(" -d Specify the destination directory"); 131 System.err.println(" -e Specify the encoding of the files"); 132 System.exit(1); 133 } 134 135 File destdir = null; 136 if (destdir_name != null) 137 { 138 destdir = new File(destdir_name); 139 if (!destdir.exists()) 140 { 141 throw new IOException("The destination directory '" + destdir_name + "' doesn't exist."); 142 } 143 if (!destdir.canWrite()) 144 { 145 throw new IOException("The destination directory '" + destdir_name + "' is not writable."); 146 } 147 if (!destdir.isDirectory()) 148 { 149 throw new IOException("The destination directory '" + destdir_name + "' is not a directory."); 150 } 151 } 152 153 Iterator names_it = names.iterator(); 154 String name; 155 while (names_it.hasNext()) 156 { 157 name = (String)names_it.next(); 158 159 File location = new File(name); 160 if (!location.exists()) 161 { 162 throw new IOException("The source location '" + name + "' doesn't exist."); 163 } 164 if (!location.canRead()) 165 { 166 throw new IOException("The source location '" + name + "' is not readable."); 167 } 168 169 if (!location.isDirectory()) 170 { 171 File out = null; 172 if (null == destdir) 173 { 174 out = new File(location.getAbsolutePath() + ".html"); 175 } 176 else 177 { 178 out = new File(destdir, location.getName() + ".html"); 179 } 180 181 highlightFile(location.getName(), location, out, encoding, fragment, verbose); 182 } 183 else 184 { 185 Set supported_types = XhtmlRendererFactory.getSupportedTypes(); 186 Pattern[] included = new Pattern[supported_types.size()]; 187 Pattern[] excluded = new Pattern[supported_types.size()+5]; 188 excluded[0] = Pattern.compile(".*SCCS.*"); 189 excluded[0] = Pattern.compile(".*svn.*"); 190 excluded[0] = Pattern.compile(".*CVS.*"); 191 excluded[0] = Pattern.compile(".*jetty.*"); 192 excluded[0] = Pattern.compile(".*tomcat.*"); 193 194 Iterator types_it = supported_types.iterator(); 195 String type; 196 int counter = 0; 197 while (types_it.hasNext()) 198 { 199 type = (String)types_it.next(); 200 included[counter] = Pattern.compile(".*\\."+type+"$"); 201 excluded[counter+5] = Pattern.compile(".*\\."+type+"\\.html\\.*"); 202 203 counter++; 204 } 205 206 ArrayList file_names = FileUtils.getFileList(location, included, excluded); 207 208 Iterator file_names_it = file_names.iterator(); 209 String file_name; 210 while (file_names_it.hasNext()) 211 { 212 file_name = (String)file_names_it.next(); 213 214 File in = new File(location.getAbsolutePath() + File.separator + file_name); 215 File out = null; 216 if (null == destdir) 217 { 218 out = new File(location.getAbsolutePath() + File.separator + file_name + ".html"); 219 } 220 else 221 { 222 out = new File(destdir, location.getName() + File.separator + file_name + ".html"); 223 } 224 225 highlightFile(location.getName() + File.separator + file_name, in, out, encoding, fragment, verbose); 226 } 227 } 228 } 229 } 230 231 private static void highlightFile(String name, File in, File out, String encoding, boolean fragment, boolean verbose) 232 throws IOException 233 { 234 out.getParentFile().mkdirs(); 235 236 if (verbose) 237 { 238 System.out.print(name + " ... "); 239 } 240 241 XhtmlRendererFactory.getRenderer(FileUtils.getExtension(name)) 242 .highlight(name, 243 in.toURL().openStream(), 244 new FileOutputStream(out), 245 encoding, 246 fragment); 247 248 if (verbose) 249 { 250 System.out.println("done."); 251 } 252 } 253}