source: trunk/gli/src/org/greenstone/gatherer/util/Generator.java@ 4364

Last change on this file since 4364 was 4364, checked in by mdewsnip, 21 years ago

Fixed tabbing.

  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37
38
39
40
41
42
43package org.greenstone.gatherer.util;
44
45import java.io.BufferedReader;
46import java.io.File;
47import java.io.FileOutputStream;
48import java.io.FileReader;
49import java.lang.Exception;
50import java.lang.String;
51import java.lang.StringBuffer;
52import java.util.HashMap;
53/** Automatically generates html help documents given an input text file using markup and a template defining what the markup means.
54 * @author John Thompson, Greenstone Digital Library, University of Waikato
55 * @version 1.0
56 */
57public class Generator {
58
59 private FileOutputStream file_output_stream = null;
60
61 private TemplateManager template_manager = null;
62
63 public Generator(File test_file, File template_file) {
64 template_manager = new TemplateManager(template_file);
65 File files[] = null;
66 // If test_file is a file, goody.
67 if(test_file.isFile()) {
68 files = new File[1];
69 files[0] = test_file;
70 }
71 // Otherwise we use all of test_files children.
72 else {
73 files = test_file.listFiles();
74 }
75 // Its unfortunate we test this twice for the basic case, but we need to ensure that source managers are only contructed for non-directory files.
76 for(int i = 0; i < files.length; i++) {
77 if(files[i].isFile()) {
78 SourceManager source_manager = new SourceManager(files[i]);
79 source_manager = null;
80 }
81 }
82 // All done.
83 }
84
85 public void exit() {
86 if(file_output_stream != null) {
87 try {
88 file_output_stream.close();
89 file_output_stream = null;
90 }
91 catch(Exception error) {
92 error.printStackTrace();
93 }
94 }
95 System.exit(0);
96 }
97
98 public void out(String msg) {
99 System.err.println(msg);
100 try {
101 if(file_output_stream == null) {
102 file_output_stream = new FileOutputStream("output.txt");
103 }
104 file_output_stream.write((msg + "\n").getBytes());
105 }
106 catch(Exception error) {
107 error.printStackTrace();
108 System.err.println("An error has occured. View output.txt for more information.");
109 exit();
110 }
111 }
112
113 static public void main(String args[]) {
114 System.err.println("Rapid repeated HTML generation tool.");
115 System.err.println(" written by John Thompson, 2002\n");
116 boolean usage = false;
117 // Attempt to generate html from text
118 if(args.length == 2) {
119 File text_file = new File(args[0]);
120 File template_file = new File(args[1]);
121 if(!text_file.exists() || !template_file.exists() || !template_file.isFile()) {
122 usage = true;
123 }
124 else {
125 Generator generator = new Generator(text_file, template_file);
126 generator.exit();
127 }
128 }
129 else {
130 usage = true;
131 }
132 // Print usage message
133 if(usage) {
134 System.err.println("Usage: GenHelp <text_file> <template_file>");
135 System.err.println("text_file - A file containing text marked up using special tags.");
136 System.err.println("template_file - An HTML file using tags to specify where to insert text.");
137 }
138 }
139
140 /** An HTML block object is essentially a String buffer containing several places where it demands further text be appended. To this end you can ask if an HTML block is ready, and if not provide it with a further text fragment and try again. */
141 private class HTMLBlock {
142 /** Prevent the original HTML block being changed. */
143 private boolean original;
144
145 private int insertion_position = -1;
146 /** The name of this HTML block as taken from the template file. */
147 private String name = null;
148 private String paragraph_tag = null;
149 /** The HTML block itself. */
150 private StringBuffer data = null;
151 /** Constructor takes the HTML blocks name as extracted from the template file.
152 * @param name The name of this HTML block as a <strong>String</strong>.
153 */
154 public HTMLBlock(String name) {
155 this.data = new StringBuffer("");
156 this.name = name;
157 this.original = true;
158 }
159 /** Copy constructor takes the HTML block and its name as extracted from the template file.
160 * @param name The name of this HTML block as a <strong>String</strong>.
161 * @param raw The raw HTML code as a <strong>String</strong>.
162 */
163 public HTMLBlock(String name, String raw) {
164 this.data = new StringBuffer(raw);
165 this.name = name;
166 this.original = false;
167 }
168 /** Append this text to the end of the current block.
169 * @param text The <strong>String</strong> to add.
170 */
171 public void addLine(String text) {
172 if(original) {
173 data.append(text);
174 data.append("\n");
175 }
176 }
177 /** Retrieve the name of this HTML block.
178 * @return A <strong>String</strong> representing the name.
179 */
180 public String getName() {
181 return name;
182 }
183 /** Insert a text fragment into this HTML block.
184 * @param fragment The <strong>String</strong> to insert.
185 * @return <i>true</i> if an insertion occured, <i>false</i> otherwise.
186 */
187 public boolean insert(String fragment) {
188 if(!original) {
189 // Find the start of an insertion tag.
190 int start = data.indexOf("<$");
191 if(start != -1) {
192 // Find the end of an insertion tag.
193 int end = data.indexOf(">", start) + 1;
194 // Determine the tag, and search for any paragraphing information.
195 String tag = data.substring(start, end);
196 if(tag.length() > 7) {
197 paragraph_tag = "<p " + tag.substring(7) + "\n";
198 fragment = paragraph_tag + fragment + "\n</p>\n";
199 }
200 // Substitue the fragment for the tag.
201 data.replace(start, end, fragment);
202 // Now set insertion position
203 insertion_position = start + fragment.length();
204 return true;
205 }
206 // Its possible that we've already got enough text to output this block. Essentially this new fragment is meant to be another paragraph. Such fragments are always added immediately after the last fragment inserted.
207 else if(insertion_position != -1) {
208 if(paragraph_tag != null) {
209 fragment = paragraph_tag + fragment + "\n</p>\n";
210 }
211 data.insert(insertion_position, fragment);
212 insertion_position = insertion_position + fragment.length();
213 }
214 }
215 return false;
216 }
217 /** Is this block ready to written out.
218 * @return <i>true</i> if we can write this block out, <i>false</i> if text insertion points still exist.
219 */
220 public boolean ready() {
221 return data.indexOf("<$") == -1;
222 }
223 /** Produce a copy of this block with all text insertions intact.
224 * @return A new <strong>HTMLBlock</strong>.
225 */
226 public HTMLBlock spawn() {
227 return new HTMLBlock(name, data.toString());
228 }
229 /** Return the HTML block within this object.
230 * @return A <strong>String</strong> containing the HTML code.
231 */
232 public String toString() {
233 return data.toString();
234 }
235 }
236 /** Reads in the given text file, outputing HTML by utilizing HTML blocks stored in the TemplateManager. The manager understands one extra tag <$FILE name=<filename>> which is used to indicate the presence of several output files within one input file. If this tag is not found the default name for the output file is "<text_file_name>.htm". */
237 private class SourceManager {
238 private File text_file = null;
239
240 private FileOutputStream output_file = null;
241
242 public SourceManager(File text_file) {
243 out("Building Source Manager:");
244 this.text_file = text_file;
245 try {
246 out(" reading from: " + text_file.getName());
247 // Create input stream from the text file which we read a line at a time.
248 FileReader file_reader = new FileReader(text_file);
249 BufferedReader buffered_reader = new BufferedReader(file_reader);
250 HTMLBlock block = null;
251 String line = null;
252 StringBuffer paragraph = null;
253 while((line = buffered_reader.readLine()) != null) {
254 boolean done = false;
255 // What we do here depends on what state we are in and what tag or text we are reading.
256 // The first case to consider is a file open command tag. This tells us the next block of html should be written to a certain file.
257 if(line.startsWith("<$FILE")) {
258 // Close any existing output file.
259 if(output_file != null) {
260 // Write any existing block
261 if(block != null) {
262 if(paragraph != null) {
263 block.insert(paragraph.toString());
264 paragraph = null;
265 }
266 out(" write: " + block.getName());
267 output_file.write((block.toString()).getBytes());
268 block = null;
269 }
270 output_file.close();
271 output_file = null;
272 }
273 // Determine the new file name.
274 String name = line.substring(12, line.lastIndexOf(">"));
275 // Create new file.
276 output_file = new FileOutputStream(name);
277 // Dealt with
278 out(" writing to: " + name);
279 name = null;
280 done = true;
281 }
282 else if(line.startsWith("<$")) {
283 // If we have a block open its time to write it out.
284 if(block != null) {
285 if(paragraph != null) {
286 block.insert(paragraph.toString());
287 paragraph = null;
288 }
289 // Check we have somewhere to write to.
290 if(output_file == null) {
291 output_file = new FileOutputStream(text_file.getName() + ".htm");
292 }
293 out(" write: " + block.getName());
294 output_file.write((block.toString()).getBytes());
295 block = null;
296 }
297 // Now determine the new blocks name.
298 String name = line.substring(2, line.lastIndexOf(">"));
299 // Retrieve that block
300 block = template_manager.getHTMLBlock(name);
301 if(block == null) {
302 // Somethings gone wrong, most likely an unidentified block name.
303 out(" no such block: " + name);
304 }
305 name = null;
306 done = true;
307 }
308 // Its just text. However we want text in paragraph blocks. A paragraph is delimited by a "\n\n" or the start of a tag.
309 if(!done) {
310 // If the line read is "" it means we've encountered a "\n\n".
311 if(line.equals("")) {
312 // Add paragraph to open block.
313 if(block != null && paragraph != null) {
314 block.insert(paragraph.toString());
315 paragraph = null;
316 }
317 }
318 // Any other case just add to paragraph. Ensure that there is at least one space between the two fragments
319 else {
320 if(paragraph == null) {
321 paragraph = new StringBuffer(line);
322 }
323 else {
324 if(paragraph.charAt(paragraph.length() - 1) != ' ' && line.charAt(0) != ' ') {
325 paragraph.append(" ");
326 }
327 paragraph.append(line);
328 }
329 }
330 }
331 }
332 // Write out any outstanding blocks.
333 if(block != null) {
334 if(paragraph != null) {
335 block.insert(paragraph.toString());
336 paragraph = null;
337 }
338 // Check we have somewhere to write to.
339 if(output_file == null) {
340 output_file = new FileOutputStream(text_file.getName() + ".htm");
341 }
342 out(" write: " + block.getName());
343 output_file.write((block.toString()).getBytes());
344 }
345 block = null;
346 paragraph = null;
347 line = null;
348 output_file.close();
349 output_file = null;
350 }
351 catch (Exception error) {
352 error.printStackTrace();
353 System.err.println("An error has occured. View output.txt for more information.");
354 exit();
355 }
356 }
357 }
358 /** Reads in a template file, extracting HTMLBlocks and storing them. It then allows the program to retrieve a block by its name and process it accordingly. */
359 private class TemplateManager
360 extends HashMap {
361 /** Constructor.
362 * @param template_file The <strong>File</strong> template information will be extracted from.
363 */
364 public TemplateManager(File template_file) {
365 out("Building Template Manager:");
366 try {
367 FileReader file_reader = new FileReader(template_file);
368 BufferedReader buffered_reader = new BufferedReader(file_reader);
369 HTMLBlock block = null;
370 String line = null;
371 while((line = buffered_reader.readLine()) != null) {
372 boolean done = false;
373 // Detect a template command.
374 if(line.startsWith("<$")) {
375 // See if this is an open block tag, text insertion tag, or a block closing tag and react appropriately.
376 if(line.startsWith("<$TEXT")) {
377 // Text tag. deal with it below.
378 }
379 else if(line.startsWith("<$/")) {
380 // Block closing tag. If we have an open block close it.
381 if(block != null) {
382 out(" parsed: " + block.getName());
383 // Add to our hashmapping of known blocks.
384 put(block.getName(), block);
385 block = null;
386 done = true;
387 }
388 // Otherwise deal with it below.
389 }
390 // The last option is an open block tag.
391 else {
392 // If have a block open, close it.
393 if(block != null) {
394 out(" parsed: " + block.getName());
395 put(block.getName(), block);
396 block = null;
397 }
398 // Now create a new block with the appropriate name.
399 String name = line.substring(2, line.indexOf(">"));
400 block = new HTMLBlock(name);
401 done = true;
402 }
403 }
404 // Otherwise its just HTML.
405 if(!done) {
406 // If we are building a block append this line.
407 if(block != null) {
408 block.addLine(line);
409 }
410 // Otherwise we just ignore it.
411 else {
412 if(line.length() > 0) {
413 out(" can't parse: " + line);
414 }
415 // Otherwise we're just chewing up blank space.
416 }
417 }
418 }
419 // If we have a block open close it.
420 if(block != null) {
421 out(" parsed: " + block.getName());
422 put(block.getName(), block);
423 }
424 line = null;
425 block = null;
426 buffered_reader.close();
427 buffered_reader = null;
428 file_reader.close();
429 file_reader = null;
430 }
431 catch (Exception error) {
432 error.printStackTrace();
433 System.err.println("An error has occured. View output.txt for more information.");
434 exit();
435 }
436 }
437 /** Retrieve the block indicated by the given name.
438 * @param name The name of the block as a <strong>String</strong>.
439 * @return The <strong>HTMLBlock</strong> asked for or <i>null</i> if no such block.
440 */
441 public HTMLBlock getHTMLBlock(String name) {
442 HTMLBlock block = (HTMLBlock) get(name);
443 // Don't return the original, but a copy.
444 if(block != null) {
445 block = block.spawn();
446 }
447 return block;
448 }
449 }
450}
Note: See TracBrowser for help on using the repository browser.