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 3108 2006-03-13 18:03:00Z gbevin $
007 */
008 package com.uwyn.jhighlight;
009
010 import com.uwyn.jhighlight.renderer.XhtmlRendererFactory;
011 import com.uwyn.jhighlight.tools.FileUtils;
012 import java.io.File;
013 import java.io.FileOutputStream;
014 import java.io.IOException;
015 import java.util.ArrayList;
016 import java.util.Iterator;
017 import java.util.Set;
018 import 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: 3108 $
051 * @since 1.0
052 */
053 public 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 }