1 /*
2 * Copyright (C) Stephan Dlugosz, 2007. All Rights Reserved.
3 *
4 * LaTeXTaglet is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * LaTeXTaglet is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser Public License
15 * along with LaTeXTaglet; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 package net.sf.latextaglet.internal;
20 import java.io.File;
21 import java.io.FileWriter;
22 import java.io.IOException;
23 import java.io.Writer;
24 import java.util.Date;
25 import java.util.StringTokenizer;
26
27 import com.sun.javadoc.Tag;
28 import com.sun.tools.doclets.internal.toolkit.Configuration;
29 import com.sun.tools.doclets.internal.toolkit.taglets.Taglet;
30
31 /**
32 * Abstract: Taglet class frr writing formulas
33 *
34 * The LaTeX code can use commands of the (La)TeX math mode with the additional packages
35 *
36 * <p>amsfonts,latexsym,amsmath,amsthm,amscd,amssymb,eucal,exscale,dsfont,icomma,bm</p>
37 *
38 * Requirements: (La)TeX Installation, ImageMagick, ghostscript<br>
39 *
40 * @author Stephan Dlugosz
41 */
42 public abstract class LaTeXTaglet implements Taglet {
43 /**
44 * Will return true since <code>@latex</code>
45 * can be used in field documentation.
46 * @return true since <code>@latex</code>
47 * can be used in field documentation and false
48 * otherwise.
49 */
50 public boolean inField() {
51 return true;
52 }
53
54 /**
55 * Will return true since <code>@latex</code>
56 * can be used in constructor documentation.
57 * @return true since <code>@latex</code>
58 * can be used in constructor documentation and false
59 * otherwise.
60 */
61 public boolean inConstructor() {
62 return true;
63 }
64
65 /**
66 * Will return true since <code>@latex</code>
67 * can be used in method documentation.
68 * @return true since <code>@latex</code>
69 * can be used in method documentation and false
70 * otherwise.
71 */
72 public boolean inMethod() {
73 return true;
74 }
75
76 /**
77 * Will return true since <code>@latex</code>
78 * can be used in method documentation.
79 * @return true since <code>@latex</code>
80 * can be used in overview documentation and false
81 * otherwise.
82 */
83 public boolean inOverview() {
84 return true;
85 }
86
87 /**
88 * Will return true since <code>@latex</code>
89 * can be used in package documentation.
90 * @return true since <code>@latex</code>
91 * can be used in package documentation and false
92 * otherwise.
93 */
94 public boolean inPackage() {
95 return true;
96 }
97
98 /**
99 * Will return true since <code>@latex</code>
100 * can be used in type documentation (classes or interfaces).
101 * @return true since <code>@latex</code>
102 * can be used in type documentation and false
103 * otherwise.
104 */
105 public boolean inType() {
106 return true;
107 }
108
109 public abstract boolean isInlineTag();
110
111
112 /**
113 * @param tag
114 * @param conf
115 * @return String that is printed in the corresponding html file
116 */
117 public abstract String toString(Tag tag, Configuration conf);
118
119 /**
120 * @param tags
121 * @param conf
122 * @return String that is printed in the corresponding html file
123 */
124 public abstract String toString(Tag[] tags, Configuration conf);
125
126
127
128
129 private File getCanonicalFile(final String str) throws IOException {
130 File file;
131 if (str==null) {
132 file = new File("").getCanonicalFile();
133 } else {
134 file = new File(str).getCanonicalFile();
135 }
136 return file;
137 }
138
139 private File getCanonicalFile(final String paths, final File file) {
140 StringTokenizer st = new StringTokenizer(paths, File.pathSeparator);
141 for (; st.hasMoreTokens(); ) {
142 File path;
143 try {
144 path = getCanonicalFile(st.nextToken());
145 } catch (IOException e) {
146 continue;
147 }
148 if (file.toString().indexOf(path.toString())==0) {
149 return path;
150 }
151 }
152 throw new IllegalStateException();
153 }
154
155
156 static private long sequence = 0;
157
158
159
160 /**
161 * @param LaTeXCode
162 * @param conf
163 * @param ownLine true if Equation is set into its own line
164 * @return String name of png file of the formula
165 */
166 protected String createPicture(Tag LaTeXCode, Configuration conf, boolean ownLine) {
167 String path = null;
168 String name = null;
169
170 try {
171 File destDir = getCanonicalFile(conf.destDirName);
172 // XXX System.out.println("destDir="+destDir);
173
174 File javaFile = new File(LaTeXCode.position().file().toString());
175 name = javaFile.getName();
176 // XXX System.out.println("java="+javaFile);
177 // XXX System.out.println("name="+name);
178
179 File srcDir = getCanonicalFile(conf.sourcepath, javaFile);
180 // XXX System.out.println("srcDir="+srcDir);
181
182 String relative = javaFile.toString().substring(srcDir.toString().length());
183 // XXX System.out.println("relative="+relative);
184 String paket=relative.substring(0, relative.length()-name.length());
185 // XXX System.out.println("package="+paket);
186
187 long msec = new Date().getTime();
188
189 path = destDir+paket;
190 name = javaFile.getName()+"-"+msec+"."+sequence;
191 sequence += 1;
192 // XXX System.out.println("path:"+path);
193 // XXX System.out.println("name:"+name);
194 // XXX System.out.println("tex:"+path+name+".tex");
195
196 Writer fw= new FileWriter(path+name+".tex"); //$NON-NLS-1$
197 fw.write("\\documentclass{article}\n"); //$NON-NLS-1$
198 fw.write("\\usepackage{amsfonts,latexsym,amsmath,amsthm,amscd,amssymb,eucal,exscale,dsfont,icomma,bm}\n"); //$NON-NLS-1$
199 fw.write("\\newcommand{\\mx}[1]{\\mathbf{\\bm{#1}}} % Matrix command\n");
200 fw.write("\\newcommand{\\vc}[1]{\\mathbf{\\bm{#1}}} % Vector command\n");
201 fw.write("\\newcommand{\\T}{\\text{T}} % Transpose\n");
202 fw.write("\\pagestyle{empty}\n");
203 fw.write("\\begin{document}\n");
204 if (ownLine) {
205 fw.write("\\["); // fw.write("\\begin{equation}\n");
206 } else {
207 fw.write("$");
208 }
209 fw.write(LaTeXCode.text());
210 if (ownLine) {
211 fw.write("\\]"); // fw.write("\n\\end{equation}");
212 } else {
213 fw.write("$");
214 }
215 fw.write("\\end{document}\n");
216 fw.close();
217 } catch(IOException ex) {
218 ex.printStackTrace();
219 }
220
221 // System.out.println("***"+LaTeXCode.text()+"***");
222
223 StringBuilder cmd = new StringBuilder();
224 cmd.append("tagtex ").append(path).append(' ').append(name);
225 // XXX System.out.println("call: " + cmd.toString());
226
227 Runtime rt = Runtime.getRuntime();
228 Process p=null;
229 StreamHandler errorHandler=null;
230 StreamHandler outputHandler=null;
231 try {
232 p=rt.exec(cmd.toString());
233 errorHandler = new StreamHandler(p.getErrorStream(), System.err);
234 outputHandler = new StreamHandler(p.getInputStream(), System.out);
235 } catch (IOException ex) {
236 ex.printStackTrace();
237 }
238 errorHandler.start();
239 outputHandler.start();
240
241 try {
242 int exitVal = p.waitFor();
243 if (exitVal!=0) throw new IllegalStateException(cmd.toString());
244 } catch(InterruptedException ex) {
245 ex.printStackTrace(System.err);
246 }
247
248 // XXX System.out.println("png:"+name+".png");
249 return name+".png"; //$NON-NLS-1$
250 }
251 }