1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.jeuclid.app;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.Locale;
27
28 import net.sourceforge.jeuclid.LayoutContext;
29 import net.sourceforge.jeuclid.MutableLayoutContext;
30 import net.sourceforge.jeuclid.context.LayoutContextImpl;
31 import net.sourceforge.jeuclid.context.Parameter;
32 import net.sourceforge.jeuclid.context.typewrapper.EnumTypeWrapper;
33 import net.sourceforge.jeuclid.context.typewrapper.TypeWrapper;
34 import net.sourceforge.jeuclid.converter.Converter;
35 import net.sourceforge.jeuclid.converter.ConverterRegistry;
36
37 import org.apache.commons.cli.CommandLine;
38 import org.apache.commons.cli.GnuParser;
39 import org.apache.commons.cli.HelpFormatter;
40 import org.apache.commons.cli.Option;
41 import org.apache.commons.cli.Options;
42 import org.apache.commons.cli.ParseException;
43 import org.apache.commons.lang.StringUtils;
44
45
46
47
48
49
50
51
52
53 public final class Mml2xxx {
54
55
56 private static final String OUT_FILE_TYPE = "outFileType";
57
58 private static final String DEFAULT_TYPE = "image/png";
59
60 private Mml2xxx() {
61
62 }
63
64 private static Options createOptions() {
65 final Options options = new Options();
66 final Option oft = new Option(Mml2xxx.OUT_FILE_TYPE, true,
67 "output file mime type [default: derived from the target file's extention]"
68 + "; available values are: "
69 + StringUtils.join(ConverterRegistry.getInstance()
70 .getAvailableOutfileTypes().iterator(), ' '));
71 options.addOption(oft);
72 final LayoutContext defaultCtx = LayoutContextImpl
73 .getDefaultLayoutContext();
74 for (final Parameter param : Parameter.values()) {
75 final TypeWrapper typeWrapper = param.getTypeWrapper();
76 final StringBuilder desc = new StringBuilder(param
77 .getOptionDesc());
78 final String defValue = param.toString(defaultCtx
79 .getParameter(param));
80 if (defValue != null) {
81 desc.append(" [default: ").append(defValue).append("]");
82 }
83 final Option o = new Option(param.getOptionName(), true, desc
84 .toString());
85 String argName = param.getTypeWrapper().getValueType()
86 .getSimpleName().toLowerCase(Locale.ENGLISH);
87 if (typeWrapper instanceof EnumTypeWrapper) {
88 argName = StringUtils.join(((EnumTypeWrapper) typeWrapper)
89 .values(), '|');
90 }
91 o.setArgName(argName);
92 options.addOption(o);
93 }
94 return options;
95 }
96
97
98
99
100
101
102
103 public static void main(final String[] args) {
104 final Options options = Mml2xxx.createOptions();
105 CommandLine cmdLine = null;
106 try {
107 cmdLine = new GnuParser().parse(options, args);
108
109 final List<String> files = Arrays.asList(cmdLine.getArgs());
110 if (files.size() < 2) {
111 throw new ParseException("Not enough arguments!");
112 }
113 final int sourceCount = files.size() - 1;
114 final File lastFile = new File(files.get(sourceCount));
115 final boolean multi = lastFile.isDirectory();
116 final List<File> sources = Mml2xxx.createListOfSourceFiles(files,
117 sourceCount);
118
119 final MutableLayoutContext ctx = Mml2xxx
120 .createLayoutContext(cmdLine);
121 if (multi) {
122 Mml2xxx.convertMultipleFiles(cmdLine, lastFile, sources, ctx);
123 } else {
124 if (sources.size() != 1) {
125 throw new ParseException(
126 "Too many file arguments. Did you want to add a target directory?");
127 }
128 final String outFileType = Mml2xxx.findOutfileType(cmdLine,
129 lastFile.getName());
130 Converter.getInstance().convert(sources.get(0), lastFile,
131 outFileType, ctx);
132 }
133 } catch (final ParseException pe) {
134 System.err.println(pe);
135 Mml2xxx.showUsage(options);
136 System.exit(1);
137 } catch (final IOException ioe) {
138 System.err.println("Error encountered during converion process");
139 ioe.printStackTrace(System.err);
140 System.exit(2);
141 } catch (final IllegalArgumentException iae) {
142 System.err.println(iae);
143 Mml2xxx.showUsage(options);
144 System.exit(1);
145 }
146 }
147
148 private static void convertMultipleFiles(final CommandLine cmdLine,
149 final File lastFile, final List<File> sources,
150 final MutableLayoutContext layoutContext) throws ParseException,
151 IOException {
152 final String outFileType = Mml2xxx.findOutfileType(cmdLine, null);
153 for (final File source : sources) {
154 final String fileName = source.getName();
155 final int dotpos = fileName.lastIndexOf('.');
156 final String baseName;
157 if (dotpos >= 0) {
158 baseName = fileName.substring(0, dotpos);
159 } else {
160 baseName = fileName;
161 }
162 final File target = new File(lastFile, baseName
163 + '.'
164 + ConverterRegistry.getInstance().getSuffixForMimeType(
165 outFileType));
166 Converter.getInstance().convert(source, target, outFileType,
167 layoutContext);
168 }
169 }
170
171 private static List<File> createListOfSourceFiles(
172 final List<String> files, final int count) throws ParseException {
173 final List<File> sources = new ArrayList<File>(count);
174 for (int i = 0; i < count; i++) {
175 final String current = files.get(i);
176 final File source = new File(current);
177 if (!source.isFile() || !source.canRead()) {
178 throw new ParseException(current
179 + " is not a file or not readable");
180 }
181 sources.add(source);
182 }
183 return sources;
184 }
185
186 private static String findOutfileType(final CommandLine cmdLine,
187 final String fileName) throws ParseException {
188 String outFileType = cmdLine.getOptionValue(Mml2xxx.OUT_FILE_TYPE);
189 final String isNotSupported = " is not supported";
190 if ((outFileType == null) && (fileName != null)) {
191 final int dot = fileName.lastIndexOf('.');
192 if (dot != -1 && dot != fileName.length() - 1) {
193 final String extension = fileName.substring(dot + 1);
194 outFileType = ConverterRegistry.getInstance()
195 .getMimeTypeForSuffix(extension);
196 }
197 }
198 if (outFileType == null) {
199 System.out.println("No ouput type could be detected, assuming "
200 + Mml2xxx.DEFAULT_TYPE);
201 outFileType = Mml2xxx.DEFAULT_TYPE;
202 } else {
203 if (!ConverterRegistry.getInstance().getAvailableOutfileTypes()
204 .contains(outFileType)) {
205 throw new IllegalArgumentException("Output type "
206 + outFileType + isNotSupported);
207 }
208 }
209 return outFileType;
210 }
211
212 private static MutableLayoutContext createLayoutContext(
213 final CommandLine cmdLine) {
214 final MutableLayoutContext ctx = new LayoutContextImpl(
215 LayoutContextImpl.getDefaultLayoutContext());
216 for (final Parameter param : Parameter.values()) {
217 final String value = cmdLine
218 .getOptionValue(param.getOptionName());
219 if (value != null) {
220 ctx.setParameter(param, param.fromString(value));
221 }
222 }
223 return ctx;
224 }
225
226 private static void showUsage(final Options options) {
227 final HelpFormatter hf = new HelpFormatter();
228 final String lineSep = hf.getNewLine();
229 hf
230 .printHelp(
231 "mml2xxx <source file(s)> <target file/directory> [options]",
232 "source is the path to the source file (MathML or ODF format)"
233 + lineSep
234 + "target is the path to the target file / directory"
235 + lineSep
236 + "If multiple source files are given, target must be a directory",
237 options,
238 "Example: mml2xxx a.mml a.png -backgroundColor white");
239 }
240
241 }