w2phtml/source/java/writer2latex/Application.java
henrikjust 44f4c68801 Change license to GPLv3
git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@272 f0f2a975-2e09-46c8-9428-3b39399b9f3c
2018-03-06 20:06:05 +00:00

441 lines
18 KiB
Java

/************************************************************************
*
* Application.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-01-09)
*
*/
package writer2latex;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
//import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;
import java.util.Vector;
import writer2latex.api.BatchConverter;
import writer2latex.api.Converter;
import writer2latex.api.ConverterFactory;
import writer2latex.api.ConverterResult;
import writer2latex.api.MIMETypes;
//import writer2latex.api.OutputFile;
import writer2latex.util.Misc;
/**
* <p>Command line utility to convert an OpenOffice.org Writer XML file into XHTML/LaTeX/BibTeX</p>
* <p>The utility is invoked with the following command line:</p>
* <pre>java -jar writer2latex.jar [options] source [target]</pre>
* <p>Where the available options are
* <ul>
* <li><code>-latex</code>, <code>-bibtex</code>, <code>-html5</code>, <code>-xhtml</code>,
<code>-xhtml+mathml</code>, <code>-epub</code>, <code>-epub3</code>
* <li><code>-recurse</code>
* <li><code>-ultraclean</code>, <code>-clean</code>, <code>-pdfscreen</code>,
* <code>-pdfprint</code>, <code>-cleanxhtml</code>
* <li><code>-config[=]filename</code>
* <li><code>-template[=]filename</code>
* <li><code>-stylesheet[=]filename</code>
* <li><code>-resource[=]filename[::media type]</code>
* <li><code>-option[=]value</code>
* </ul>
* <p>where <code>option</code> can be any simple option known to Writer2LaTeX
* (see documentation for the configuration file).</p>
*/
public final class Application {
/* Based on command-line parameters. */
private String sTargetMIME = MIMETypes.LATEX;
private boolean bRecurse = false;
private Vector<String> configFileNames = new Vector<String>();
private String sTemplateFileName = null;
private String sStyleSheetFileName = null;
private Set<String> resources = new HashSet<String>();
private Hashtable<String,String> options = new Hashtable<String,String>();
private String sSource = null;
private String sTarget = null;
/**
* Main method
*
* @param args The argument passed on the command line.
*/
public static final void main (String[] args){
try {
//long time = System.currentTimeMillis();
Application app = new Application();
app.parseCommandLine(args);
app.doConversion();
//System.out.println("Total conversion time was "+(System.currentTimeMillis()-time)+" miliseconds");
} catch (IllegalArgumentException ex) {
String msg = ex.getMessage();
showUsage(msg);
}
}
// Convert the directory or file
private void doConversion() {
// Step 1: Say hello...
String sOutputFormat;
if (MIMETypes.LATEX.equals(sTargetMIME)) { sOutputFormat = "LaTeX"; }
else if (MIMETypes.BIBTEX.equals(sTargetMIME)) { sOutputFormat = "BibTeX"; }
else { sOutputFormat = "xhtml"; }
System.out.println();
System.out.println("This is Writer2" + sOutputFormat +
", Version " + ConverterFactory.getVersion() +
" (" + ConverterFactory.getDate() + ")");
System.out.println();
System.out.println("Starting conversion...");
// Step 2: Examine source
File source = new File(sSource);
if (!source.exists()) {
System.out.println("I'm sorry, I can't find "+sSource);
System.exit(1);
}
if (!source.canRead()) {
System.out.println("I'm sorry, I can't read "+sSource);
System.exit(1);
}
boolean bBatch = source.isDirectory();
// Step 3: Examine target
File target;
if (bBatch) {
if (sTarget==null) {
target=source;
}
else {
target = new File(sTarget);
}
}
else {
if (sTarget==null) {
target = new File(source.getParent(),Misc.removeExtension(source.getName()));
}
else {
target = new File(sTarget);
if (sTarget.endsWith(File.separator)) {
target = new File(target,Misc.removeExtension(source.getName()));
}
}
}
// Step 4: Create converters
Converter converter = ConverterFactory.createConverter(sTargetMIME);
if (converter==null) {
System.out.println("Failed to create converter for "+sTargetMIME);
System.exit(1);
}
BatchConverter batchCv = null;
if (bBatch) {
batchCv = ConverterFactory.createBatchConverter(MIMETypes.XHTML);
if (batchCv==null) {
System.out.println("Failed to create batch converter");
System.exit(1);
}
batchCv.setConverter(converter);
}
// Step 5a: Read template
if (sTemplateFileName!=null) {
try {
System.out.println("Reading template "+sTemplateFileName);
byte [] templateBytes = Misc.inputStreamToByteArray(new FileInputStream(sTemplateFileName));
converter.readTemplate(new ByteArrayInputStream(templateBytes));
if (batchCv!=null) {
// Currently we use the same template for the directory and the files
batchCv.readTemplate(new ByteArrayInputStream(templateBytes));
}
}
catch (FileNotFoundException e) {
System.out.println("--> This file does not exist!");
System.out.println(" "+e.getMessage());
}
catch (IOException e) {
System.out.println("--> Failed to read the template file!");
System.out.println(" "+e.getMessage());
}
}
// Step 5b: Read style sheet
if (sStyleSheetFileName!=null) {
try {
System.out.println("Reading style sheet "+sStyleSheetFileName);
byte [] styleSheetBytes = Misc.inputStreamToByteArray(new FileInputStream(sStyleSheetFileName));
converter.readStyleSheet(new ByteArrayInputStream(styleSheetBytes));
}
catch (FileNotFoundException e) {
System.out.println("--> This file does not exist!");
System.out.println(" "+e.getMessage());
}
catch (IOException e) {
System.out.println("--> Failed to read the style sheet file!");
System.out.println(" "+e.getMessage());
}
}
// Step 5c: Read style resources
for (String sResource : resources) {
String sMediaType;
String sFileName;
int nSeparator = sResource.indexOf("::");
if (nSeparator>-1) {
sFileName = sResource.substring(0,nSeparator);
sMediaType = sResource.substring(nSeparator+2);
}
else {
sFileName = sResource;
sMediaType = null;
}
System.out.println("Reading resource file "+sFileName);
try {
byte [] resourceBytes = Misc.inputStreamToByteArray(new FileInputStream(sFileName));
converter.readResource(new ByteArrayInputStream(resourceBytes),sFileName,sMediaType);
} catch (IOException e) {
System.out.println("--> Failed to read the resource file!");
System.out.println(" "+e.getMessage());
}
}
// Step 6: Read config
for (int i=0; i<configFileNames.size(); i++) {
String sConfigFileName = (String) configFileNames.get(i);
if (sConfigFileName.startsWith("*")) {
sConfigFileName = sConfigFileName.substring(1);
System.out.println("Reading default configuration "+sConfigFileName);
try {
converter.getConfig().readDefaultConfig(sConfigFileName);
}
catch (IllegalArgumentException e) {
System.err.println("--> This configuration is unknown!");
System.out.println(" "+e.getMessage());
}
}
else {
System.out.println("Reading configuration file "+sConfigFileName);
try {
byte[] configBytes = Misc.inputStreamToByteArray(new FileInputStream(sConfigFileName));
converter.getConfig().read(new ByteArrayInputStream(configBytes));
if (bBatch) {
// Currently we use the same configuration for the directory and the files
batchCv.getConfig().read(new ByteArrayInputStream(configBytes));
}
}
catch (IOException e) {
System.err.println("--> Failed to read the configuration!");
System.out.println(" "+e.getMessage());
}
}
}
// Step 7: Set options from command line
Enumeration<String> keys = options.keys();
while (keys.hasMoreElements()) {
String sKey = keys.nextElement();
String sValue = (String) options.get(sKey);
converter.getConfig().setOption(sKey,sValue);
if (batchCv!=null) {
batchCv.getConfig().setOption(sKey,sValue);
}
}
// Step 8: Perform conversion
if (bBatch) {
batchCv.convert(source,target,bRecurse, new BatchHandlerImpl());
}
else {
System.out.println("Converting "+source.getPath());
ConverterResult dataOut = null;
try {
dataOut = converter.convert(source,target.getName());
}
catch (FileNotFoundException e) {
System.out.println("--> The file "+source.getPath()+" does not exist!");
System.out.println(" "+e.getMessage());
System.exit(1);
}
catch (IOException e) {
System.out.println("--> Failed to convert the file "+source.getPath()+"!");
System.out.println(" "+e.getMessage());
System.out.println(" Please make sure the file is in OpenDocument format");
System.exit(1);
}
// TODO: Should do some further checking on the feasability of writing
// the directory and the files.
File targetDir = target.getParentFile();
if (targetDir!=null && !targetDir.exists()) { targetDir.mkdirs(); }
try {
dataOut.write(targetDir);
}
catch (IOException e) {
System.out.println("--> Error writing out file!");
System.out.println(" "+e.getMessage());
System.exit(1);
}
}
// Step 9: Say goodbye!
System.out.println("Done!");
}
/**
* Display usage.
*/
private static void showUsage(String msg) {
System.out.println();
System.out.println("This is Writer2LaTeX, Version " + ConverterFactory.getVersion()
+ " (" + ConverterFactory.getDate() + ")");
System.out.println();
if (msg != null) System.out.println(msg);
System.out.println();
System.out.println("Usage:");
System.out.println(" java -jar <path>/writer2latex.jar <options> <source file/directory> [<target file/directory>]");
System.out.println("where the available options are:");
System.out.println(" -latex");
System.out.println(" -bibtex");
System.out.println(" -xhtml");
System.out.println(" -xhtml11");
System.out.println(" -xhtml+mathml");
System.out.println(" -html5");
System.out.println(" -epub");
System.out.println(" -epub3");
System.out.println(" -recurse");
System.out.println(" -template[=]<template file>");
System.out.println(" -stylesheet[=]<style sheet file>");
System.out.println(" -resource[=]<resource file>[::<media type>]");
System.out.println(" -ultraclean");
System.out.println(" -clean");
System.out.println(" -pdfprint");
System.out.println(" -pdfscreen");
System.out.println(" -cleanxhtml");
System.out.println(" -config[=]<configuration file>");
System.out.println(" -<configuration option>[=]<value>");
System.out.println("See the documentation for the available configuration options");
}
/**
* Parse command-line arguments.
*
* @param args Array of command line arguments.
*
* @throws IllegalArgumentException If an argument is invalid.
*/
private void parseCommandLine(String sArgs[])
throws IllegalArgumentException {
int i = 0;
while (i<sArgs.length) {
String sArg = getArg(i++,sArgs);
if (sArg.startsWith("-")) { // found an option
if ("-latex".equals(sArg)) { sTargetMIME = MIMETypes.LATEX; }
else if ("-bibtex".equals(sArg)) { sTargetMIME = MIMETypes.BIBTEX; }
else if ("-html5".equals(sArg)) { sTargetMIME = MIMETypes.HTML5; }
else if ("-xhtml".equals(sArg)) { sTargetMIME = MIMETypes.XHTML; }
else if ("-xhtml11".equals(sArg)) { sTargetMIME = MIMETypes.XHTML11; }
else if ("-xhtml+mathml".equals(sArg)) { sTargetMIME = MIMETypes.XHTML_MATHML; }
else if ("-epub".equals(sArg)) { sTargetMIME = MIMETypes.EPUB; }
else if ("-epub3".equals(sArg)) { sTargetMIME = MIMETypes.EPUB3; }
else if ("-recurse".equals(sArg)) { bRecurse = true; }
else if ("-ultraclean".equals(sArg)) { configFileNames.add("*ultraclean.xml"); }
else if ("-clean".equals(sArg)) { configFileNames.add("*clean.xml"); }
else if ("-pdfprint".equals(sArg)) { configFileNames.add("*pdfprint.xml"); }
else if ("-pdfscreen".equals(sArg)) { configFileNames.add("*pdfscreen.xml"); }
else if ("-cleanxhtml".equals(sArg)) { configFileNames.add("*cleanxhtml.xml"); }
else { // option with argument
int j=sArg.indexOf("=");
String sArg2;
if (j>-1) { // argument is separated by =
sArg2 = sArg.substring(j+1);
sArg = sArg.substring(0,j);
}
else { // argument is separated by space
sArg2 = getArg(i++,sArgs);
}
if ("-config".equals(sArg)) { configFileNames.add(sArg2); }
else if ("-template".equals(sArg)) { sTemplateFileName = sArg2; }
else if ("-stylesheet".equals(sArg)) { sStyleSheetFileName = sArg2; }
else if ("-resource".equals(sArg)) { resources.add(sArg2); }
else { // configuration option
options.put(sArg.substring(1),sArg2);
}
}
}
else { // not an option, so this must be the source
sSource = sArg;
// Possibly followed by the target
if (i<sArgs.length) {
String sArgument = getArg(i++,sArgs);
if (sArgument.length()>0) { sTarget = sArgument; }
}
// Skip any trailing empty arguments and signal an error if there's more
while (i<sArgs.length) {
String sArgument = getArg(i++,sArgs);
if (sArgument.length()>0) {
throw new IllegalArgumentException("I didn't expect "+sArgument+"?");
}
}
}
}
if (sSource==null) {
throw new IllegalArgumentException("Please specify a source document/directory!");
}
// Parsing of command line ended successfully!
}
/**
* Extract the next argument from the array, while checking to see
* that the array size is not exceeded. Throw a friendly error
* message in case the arg is missing.
*
* @param i Argument index.
* @param args Array of command line arguments.
*
* @return The argument with the specified index.
*
* @throws IllegalArgumentException If an argument is invalid.
*/
private String getArg(int i, String args[])
throws IllegalArgumentException {
if (i < args.length) {
return args[i];
}
else throw new
IllegalArgumentException("I'm sorry, the commandline ended abnormally");
}
}