Bug 12808 fixed: Add missing </td> in doc generation (note, warning, ...)
[scilab.git] / scilab / modules / helptools / src / java / org / scilab / modules / helptools / HTMLDocbookTagConverter.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.helptools;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.lang.Character.UnicodeBlock;
18 import java.net.URI;
19 import java.net.URISyntaxException;
20 import java.util.Date;
21 import java.util.Map;
22 import java.util.Stack;
23 import java.util.regex.Pattern;
24
25 import org.xml.sax.InputSource;
26 import org.xml.sax.SAXException;
27
28 import org.scilab.modules.commons.ScilabConstants;
29 import org.scilab.modules.helptools.image.ImageConverter;
30 import org.scilab.modules.helptools.image.LaTeXImageConverter;
31 import org.scilab.modules.helptools.image.MathMLImageConverter;
32 import org.scilab.modules.helptools.image.ScilabImageConverter;
33 import org.scilab.modules.helptools.image.SVGImageConverter;
34 import org.scilab.modules.helptools.image.XcosImageConverter;
35 import org.scilab.modules.helptools.scilab.ScilabLexer;
36 import org.scilab.modules.helptools.scilab.HTMLScilabCodeHandler;
37 import org.scilab.modules.helptools.scilab.AbstractScilabCodeHandler;
38 import org.scilab.modules.helptools.XML.XMLLexer;
39 import org.scilab.modules.helptools.XML.HTMLXMLCodeHandler;
40 import org.scilab.modules.helptools.c.CLexer;
41 import org.scilab.modules.helptools.c.HTMLCCodeHandler;
42 import org.scilab.modules.helptools.java.JavaLexer;
43 import org.scilab.modules.localization.Messages;
44
45 /**
46  * Class to convert DocBook to HTML
47  * @author Calixte DENIZET
48  */
49 public class HTMLDocbookTagConverter extends DocbookTagConverter implements TemplateFiller {
50
51     public static enum GenerationType { WEB, JAVAHELP, CHM, HTML };
52
53     private static final String SCILAB_URI = "http://www.scilab.org";
54     private static final String LATEXBASENAME = "_LaTeX_";
55     private static final String VERSION = Messages.gettext("Version");
56     private static final String DESCRIPTION = Messages.gettext("Description");
57
58     private StringBuilder buffer = new StringBuilder(8192);
59     private int latexCompt = 1;
60     private String imageDir;
61     private String urlBase;
62     private boolean linkToTheWeb;
63     private boolean hasExamples;
64     private int warnings;
65     private int nbFiles;
66     protected String outName;
67     protected String outImages;
68
69     protected Map<String, String> mapId;
70     protected Map<String, String> tocitem;
71     protected HTMLDocbookLinkResolver.TreeId tree;
72     protected Map<String, HTMLDocbookLinkResolver.TreeId> mapTreeId;
73     protected Map<String, String> mapIdPurpose;
74     protected Map<String, String> mapIdRefname;
75
76     protected TemplateHandler templateHandler;
77
78     protected ScilabLexer scilabLexer;
79     protected XMLLexer xmlLexer;
80     protected CLexer cLexer;
81     protected JavaLexer javaLexer;
82
83     protected String bookTitle = "";
84     protected String partTitle = "";
85     protected String chapterTitle = "";
86     protected String sectionTitle = "";
87     protected String fileSubtitle = "";
88
89     protected String refpurpose = "";
90     protected String refname = "";
91     protected String version;
92     protected String appendToProgramListing;
93     protected String appendForExecToProgramListing;
94     protected String prependToProgramListing;
95     protected String currentId;
96     protected String indexFilename = "index" /*UUID.randomUUID().toString()*/ + ".html";
97     protected String language;
98
99     protected boolean isToolbox;
100     protected final GenerationType type;
101
102     /**
103      * Constructor
104      * @param inName the name of the input stream
105      * @param outName the output directory
106      * @param primConf the file containing the primitives of Scilab
107      * @param macroConf the file containing the macros of Scilab
108      * @param template the template to use
109      * @param version the version
110      * @param imageDir the image directory (relative to outName)
111      * @param isToolbox is true when compile a toolbox' help
112      * @param urlBase the base url for external link
113      */
114     public HTMLDocbookTagConverter(String inName, String outName, String[] primConf, String[] macroConf, String template, String version, String imageDir, boolean isToolbox, String urlBase, String language, GenerationType type) throws IOException, SAXException {
115         super(inName);
116
117         this.version = version;
118         this.imageDir = imageDir;
119         this.outName = outName + File.separator;
120         this.outImages = this.outName;
121         HTMLDocbookLinkResolver resolver = new HTMLDocbookLinkResolver(inName);
122         mapId = resolver.getMapId();
123         tocitem = resolver.getToc();
124         tree = resolver.getTree();
125         mapTreeId = resolver.getMapTreeId();
126         mapIdPurpose = resolver.getMapIdPurpose();
127         mapIdRefname = resolver.getMapIdRefname();
128
129         scilabLexer = new ScilabLexer(primConf, macroConf);
130         this.urlBase = urlBase;
131         this.linkToTheWeb = urlBase != null && !urlBase.equals("scilab://");
132         this.isToolbox = isToolbox;
133         this.language = language;
134         this.type = type;
135         if (isToolbox) {// we generate a toolbox's help
136             HTMLScilabCodeHandler.setLinkWriter(new AbstractScilabCodeHandler.LinkWriter() {
137                 public String getLink(String id) {
138                     if (id.length() > 0 && id.charAt(0) == '%') {
139                         id = id.replace("%", "percent");
140                     }
141                     String link = mapId.get(id);
142                     if (link == null) {
143                         return HTMLDocbookTagConverter.this.urlBase + id;
144                     } else {
145                         return link;
146                     }
147                 }
148             });
149         } else {// we generate Scilab's help
150             HTMLScilabCodeHandler.setLinkWriter(new AbstractScilabCodeHandler.LinkWriter() {
151                 public String getLink(String id) {
152                     if (id.length() > 0 && id.charAt(0) == '%') {
153                         id = id.replace("%", "percent");
154                     }
155                     return mapId.get(id);
156                 }
157             });
158         }
159
160         xmlLexer = new XMLLexer();
161         cLexer = new CLexer();
162         javaLexer = new JavaLexer();
163         File tpl = new File(template);
164         templateHandler = new TemplateHandler(this, tpl, language);
165         ImageConverter.registerExternalImageConverter(LaTeXImageConverter.getInstance(this));
166         ImageConverter.registerExternalImageConverter(MathMLImageConverter.getInstance(this));
167         ImageConverter.registerExternalImageConverter(SVGImageConverter.getInstance(this));
168         ImageConverter.registerExternalImageConverter(ScilabImageConverter.getInstance(this));
169         ImageConverter.registerExternalImageConverter(XcosImageConverter.getInstance(this));
170     }
171
172     public static boolean containsCJK(CharSequence seq) {
173         if (seq == null) {
174             return false;
175         }
176
177         for (int i = 0; i < seq.length(); i++) {
178             Character.UnicodeBlock block = Character.UnicodeBlock.of(seq.charAt(i));
179             if (block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
180                     || block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
181                     || block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
182                     || block == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS
183                     || block == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
184                     || block == Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT
185                     || block == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
186                     || block == Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS) {
187                 return true;
188             }
189         }
190
191         return false;
192     }
193
194     public static boolean containsCyrillic(CharSequence seq) {
195         if (seq == null) {
196             return false;
197         }
198
199         for (int i = 0; i < seq.length(); i++) {
200             Character.UnicodeBlock block = Character.UnicodeBlock.of(seq.charAt(i));
201             if (block == Character.UnicodeBlock.CYRILLIC || block == Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY) {
202                 return true;
203             }
204         }
205
206         return false;
207     }
208
209     /**
210      * Replace special chars
211      */
212     public static final String replaceEntity(final String str) {
213         return str.replaceAll("&", "&amp;").replaceAll("<", "&#0060;").replaceAll(">", "&#0062;").replaceAll("\"", "&#0034;").replaceAll("\'", "&#0039;");
214     }
215
216     /**
217      * Get the type of the generation
218      * @return the generation type
219      */
220     public final GenerationType getGenerationType() {
221         return type;
222     }
223
224     public String getBaseImagePath() {
225         return "";
226     }
227
228     public String getLanguage() {
229         return language;
230     }
231
232     /**
233      * @return the buffer used
234      */
235     public StringBuilder getBuffer() {
236         return buffer;
237     }
238
239     /**
240      * @param tag the tag name
241      * @param contents the contents to enclose between opening and closing tags
242      */
243     public String encloseContents(final String tag, final String contents) {
244         buffer.setLength(0);
245         buffer.append("<");
246         buffer.append(tag);
247         buffer.append(">");
248         if (contents != null) {
249             buffer.append(contents);
250         }
251         buffer.append("</");
252         buffer.append(tag);
253         buffer.append(">");
254
255         return buffer.toString();
256     }
257
258     /**
259      * @param tag the tag name
260      * @param attrs the attributes {attr1, value1, attr2, value2, ...}
261      * @param contents the contents to enclose between opening and closing tags
262      */
263     public String encloseContents(final String tag, final String[] attrs, final String contents) {
264         buffer.setLength(0);
265         buffer.append("<");
266         buffer.append(tag);
267         if (attrs != null) {
268             for (int i = 0; i < attrs.length; i += 2) {
269                 if (attrs[i + 1] != null && !attrs[i + 1].isEmpty()) {
270                     buffer.append(" ");
271                     buffer.append(attrs[i]);
272                     buffer.append("=\"");
273                     buffer.append(attrs[i + 1]);
274                     buffer.append("\"");
275                 }
276             }
277         }
278
279         buffer.append(">");
280         if (contents != null) {
281             buffer.append(contents);
282         }
283         buffer.append("</");
284         buffer.append(tag);
285         buffer.append(">");
286
287         return buffer.toString();
288     }
289
290     /**
291      * @param tag the tag name
292      * @param clazz the css class name
293      * @param contents the contents to enclose between opening and closing tags
294      */
295     public String encloseContents(final String tag, final String clazz, final String contents) {
296         buffer.setLength(0);
297         buffer.append("<");
298         buffer.append(tag);
299         buffer.append(" class=\"");
300         buffer.append(clazz);
301         buffer.append("\">");
302         if (contents != null) {
303             buffer.append(contents);
304         }
305         buffer.append("</");
306         buffer.append(tag);
307         buffer.append(">");
308
309         return buffer.toString();
310     }
311
312     /**
313      * {@inheritDoc}
314      */
315     public boolean isEscapable(final String tagName, final String uri) {
316         return !"latex".equals(tagName) && !"screen".equals(tagName) && !"programlisting".equals(tagName) && !"code".equals(tagName) && !"synopsis".equals(tagName) && !(uri.equals(SCILAB_URI) && tagName.equals("image"));
317     }
318
319     /**
320      * {@inheritDoc}
321      */
322     public boolean isTrimable(final String tagName) {
323         return !"screen".equals(tagName) && !"programlisting".equals(tagName) && !"code".equals(tagName) && !"synopsis".equals(tagName);
324     }
325
326     /**
327      * @param fileName the file to create
328      * @param subtitle the subtitle of the file
329      * @param contents the contents of the file
330      */
331     public void createHTMLFile(final String id, final String fileName, final String subtitle, final String contents) {
332         if (!hasError) {
333             fileSubtitle = subtitle;
334             nbFiles++;
335             templateHandler.generateFileFromTemplate(outName + fileName, id, contents);
336         }
337     }
338
339     /**
340      * {@inheritDoc}
341      */
342     public String makeTitle(final String id) {
343         if (refname.length() > 0) {
344             return tocitem.get(id);
345         }
346
347         return "";
348     }
349
350     /**
351      * {@inheritDoc}
352      */
353     public String makeSubtitle(final String id) {
354         return fileSubtitle;
355     }
356
357     /**
358      * {@inheritDoc}
359      */
360     public String makePrevious(final String id) {
361         buffer.setLength(0);
362         buffer.append("<span class=\"previous\">");
363         HTMLDocbookLinkResolver.TreeId leaf = mapTreeId.get(id);
364         if (leaf == null) {
365             return "";
366         }
367         HTMLDocbookLinkResolver.TreeId prev = leaf.getPrevious();
368         if (prev.parent != null) {
369             buffer.append("<a href=\"");
370             buffer.append(mapId.get(prev.id));
371             buffer.append("\">&lt;&lt; ");
372             buffer.append(tocitem.get(prev.id));
373             buffer.append("</a></span>\n");
374
375             return buffer.toString();
376         }
377
378         return "";
379     }
380
381     /**
382      * {@inheritDoc}
383      */
384     public String makePath(final String id) {
385         buffer.setLength(0);
386         buffer.append("<span class=\"path\">");
387         HTMLDocbookLinkResolver.TreeId leaf = mapTreeId.get(id);
388         if (leaf == null) {
389             return "";
390         }
391         String str = tocitem.get(id);
392         leaf = leaf.parent;
393         while (leaf != null && !leaf.isRoot()) {
394             str = "<a href=\"" + mapId.get(leaf.id) + "\">" + tocitem.get(leaf.id) + "</a> &gt; " + str;
395             leaf = leaf.parent;
396         }
397
398         str = "<a href=\"" + indexFilename  + "\">" + bookTitle + "</a> &gt;&gt; " + str;
399         buffer.append(str);
400         buffer.append("</span>\n");
401
402         return buffer.toString();
403     }
404
405     /**
406      * {@inheritDoc}
407      */
408     public String makeTop(final String id) {
409         buffer.setLength(0);
410         buffer.append("<span class=\"top\">");
411         HTMLDocbookLinkResolver.TreeId leaf = mapTreeId.get(id);
412         if (leaf == null) {
413             return "";
414         }
415
416         leaf = leaf.parent;
417         if (leaf != null) {
418             buffer.append("<a href=\"");
419             if (!leaf.isRoot()) {
420                 buffer.append(mapId.get(leaf.id));
421                 buffer.append("\">");
422                 buffer.append(tocitem.get(leaf.id));
423             } else {
424                 buffer.append(indexFilename);
425                 buffer.append("\">");
426                 buffer.append(bookTitle);
427             }
428             buffer.append("</a></span>\n");
429         } else {
430             return "";
431         }
432
433         return buffer.toString();
434     }
435
436     /**
437      * {@inheritDoc}
438      */
439     public String makeNext(final String id) {
440         buffer.setLength(0);
441         buffer.append("<span class=\"next\">");
442         HTMLDocbookLinkResolver.TreeId leaf = mapTreeId.get(id);
443         if (leaf == null) {
444             return "";
445         }
446         HTMLDocbookLinkResolver.TreeId next = leaf.getNext();
447         if (next != null) {
448             buffer.append("<a href=\"");
449             buffer.append(mapId.get(next.id));
450             buffer.append("\">");
451             buffer.append(tocitem.get(next.id));
452             buffer.append(" &gt;&gt;</a></span>\n");
453
454             return buffer.toString();
455         }
456
457         return "";
458     }
459
460     /**
461      * {@inheritDoc}
462      */
463     public String makeStart(final String id) {
464         buffer.setLength(0);
465         buffer.append("<span class=\"start\">");
466         buffer.append("<a href=\"");
467         buffer.append(indexFilename);
468         buffer.append("\">");
469         buffer.append(bookTitle);
470         buffer.append("</a></span>\n");
471
472         return buffer.toString();
473     }
474
475     /**
476      * {@inheritDoc}
477      */
478     public String makeTocList(final String id) {
479         buffer.setLength(0);
480         HTMLDocbookLinkResolver.TreeId leaf = mapTreeId.get(id);
481         if (leaf == null) {
482             return "";
483         }
484
485         HTMLDocbookLinkResolver.TreeId parent = leaf.parent;
486         buffer.append("<ul class=\"toc\">\n");
487         String str = "";
488         while (parent != null && !parent.isRoot()) {
489             str = "<li class=\"parent\"><a href=\"" + mapId.get(parent.id) + "\">" + tocitem.get(parent.id) + "</a></li>\n" + str;
490             parent = parent.parent;
491         }
492         buffer.append("<li class=\"root\"><a href=\"");
493         buffer.append(indexFilename);
494         buffer.append("\">");
495         buffer.append(bookTitle);
496         buffer.append("</a></li>\n");
497         buffer.append(str);
498
499         parent = leaf.parent;
500
501         for (HTMLDocbookLinkResolver.TreeId c : parent.children) {
502             if (c == leaf) {
503                 buffer.append("<li class=\"list-active\"><a href=\"");
504             } else {
505                 buffer.append("<li><a href=\"");
506             }
507             buffer.append(mapId.get(c.id));
508             buffer.append("\">");
509             buffer.append(tocitem.get(c.id));
510             buffer.append("</a></li>\n");
511         }
512         buffer.append("</ul>\n");
513
514         return buffer.toString();
515     }
516
517     /**
518      * {@inheritDoc}
519      */
520     public String makeLastModified(final String id) {
521         buffer.setLength(0);
522         try {
523             buffer.append("<span class=\"lastmodified\">");
524             buffer.append(new Date(new File(new URI(currentFileName)).lastModified()).toString());
525             buffer.append("</span>\n");
526         } catch (URISyntaxException e) {
527             e.printStackTrace();
528         }
529         return buffer.toString();
530     }
531
532     /**
533      * {@inheritDoc}
534      */
535     public String makeGenerationDate(final String id) {
536         buffer.setLength(0);
537         buffer.append("<span class=\"generationdate\">");
538         buffer.append(new Date(System.currentTimeMillis()).toString());
539         buffer.append("</span>\n");
540
541         return buffer.toString();
542     }
543
544     /**
545      * {@inheritDoc}
546      */
547     public String makeVersion(final String id) {
548         buffer.setLength(0);
549         buffer.append("<span class=\"version\">");
550         buffer.append(version);
551         buffer.append("</span>\n");
552
553         return buffer.toString();
554     }
555
556     public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
557         latexCompt = 1;
558         return super.resolveEntity(publicId, systemId);
559     }
560
561     /**
562      * Handle a refentry
563      * @param attributes the tag attributes
564      * @param contents the tag contents
565      * @return the HTML code
566      * @throws SAXEception if an error is encountered
567      */
568     public String handleRefentry(final Map<String, String> attributes, final String contents) throws SAXException {
569         String id = attributes.get("id");
570         if (id != null) {
571             currentId = id;
572         }
573         String fileName = mapId.get(currentId);
574         String needsExampleAttr = attributes.get("needs-examples");
575         createHTMLFile(currentId, fileName, refpurpose, contents);
576         if (!hasExamples && (needsExampleAttr == null || !needsExampleAttr.equals("no"))) {
577             warnings++;
578             //System.err.println("Warning (should be fixed): no example in " + currentFileName);
579         } else {
580             hasExamples = false;
581         }
582         String rp = encloseContents("span", "refentry-description", refpurpose);
583         String str = encloseContents("li", encloseContents("a", new String[] {"href", fileName, "class", "refentry"}, refname) + " &#8212; " + rp);
584         refpurpose = "";
585         refname = "";
586         currentId = null;
587
588         return str;
589     }
590
591     /**
592      * Handle a section
593      * @param attributes the tag attributes
594      * @param contents the tag contents
595      * @return the HTML code
596      * @throws SAXEception if an error is encountered
597      */
598     public String handleSection(final Map<String, String> attributes, final String contents) throws SAXException {
599         String fileName = attributes.get("id") + ".html";
600         String str = encloseContents("ul", "list-refentry", contents);
601         String title = encloseContents("h3", "title-section", sectionTitle);
602         createHTMLFile(attributes.get("id"), fileName, sectionTitle, title + "\n" + str);
603
604         str = encloseContents("li", encloseContents("a", new String[] {"href", fileName, "class", "section"}, sectionTitle) + "\n" + str);
605         sectionTitle = "";
606
607         return str;
608     }
609
610     /**
611      * Handle a book
612      * @param attributes the tag attributes
613      * @param contents the tag contents
614      * @return the HTML code
615      * @throws SAXEception if an error is encountered
616      */
617     public String handleBook(final Map<String, String> attributes, final String contents) throws SAXException {
618         String str = encloseContents("ul", "list-part", contents);
619         String btitle;
620         if (bookTitle.trim().equalsIgnoreCase("Scilab")) {
621             btitle = version;
622         } else {
623             btitle = bookTitle;
624         }
625         String title = encloseContents("h3", "book-title", btitle);
626         createHTMLFile("index", indexFilename, btitle, title + "\n" + str);
627
628         if (warnings != 0) {
629             System.err.println("Total files without example: " + warnings);
630             System.err.println("Total generated html files: " + nbFiles);
631         }
632
633         return encloseContents("li", encloseContents("a", new String[] {"href", indexFilename, "class", "part"}, bookTitle) + "\n" + str);
634     }
635
636     /**
637      * Handle a part
638      * @param attributes the tag attributes
639      * @param contents the tag contents
640      * @return the HTML code
641      * @throws SAXEception if an error is encountered
642      */
643     public String handlePart(final Map<String, String> attributes, final String contents) throws SAXException {
644         String fileName = attributes.get("id") + ".html";
645         String str = encloseContents("ul", "list-chapter", contents);
646         String title = encloseContents("h3", "title-part", partTitle);
647         createHTMLFile(attributes.get("id"), fileName, partTitle, title + "\n" + str);
648         str = encloseContents("li", encloseContents("a", new String[] {"href", fileName, "class", "part"}, partTitle) + "\n" + str);
649         partTitle = "";
650
651         return str;
652     }
653
654     /**
655      * Handle a chapter
656      * @param attributes the tag attributes
657      * @param contents the tag contents
658      * @return the HTML code
659      * @throws SAXEception if an error is encountered
660      */
661     public String handleChapter(final Map<String, String> attributes, final String contents) throws SAXException {
662         String fileName = attributes.get("id") + ".html";
663         String str = encloseContents("ul", "list-refentry", contents);
664         String title = encloseContents("h3", "title-chapter", chapterTitle);
665         createHTMLFile(attributes.get("id"), fileName, chapterTitle, title + "\n" + str);
666
667         str = encloseContents("li", encloseContents("a", new String[] {"href", fileName, "class", "chapter"}, chapterTitle) + "\n" + str);
668         chapterTitle = "";
669
670         return str;
671     }
672
673     // partiellement merdique car le style de title depend du noeud pere.
674     /**
675      * Handle a title
676      * @param attributes the tag attributes
677      * @param contents the tag contents
678      * @return the HTML code
679      * @throws SAXEception if an error is encountered
680      */
681     public String handleTitle(final Map<String, String> attributes, final String contents) throws SAXException {
682         String clazz = "title";
683         String parent = getParentTagName();
684         if (parent.equals("chapter")) {
685             chapterTitle = contents;
686         } else if (parent.equals("part")) {
687             partTitle = contents;
688         } else if (parent.equals("info")) {
689             bookTitle = contents;
690         } else if (parent.equals("section")) {
691             sectionTitle = contents;
692         } else if (parent.equals("refsection") && Pattern.matches("^[ \\t]*ex[ea]mpl[eo].*", contents.toLowerCase())) {
693             hasExamples = true;
694             return encloseContents("h3", clazz, contents);
695         } else {
696             return encloseContents("h3", clazz, contents);
697         }
698
699         return null;
700     }
701
702     /**
703      * Handle a para
704      * @param attributes the tag attributes
705      * @param contents the tag contents
706      * @return the HTML code
707      * @throws SAXEception if an error is encountered
708      */
709     public String handlePara(final Map<String, String> attributes, final String contents) throws SAXException {
710         return encloseContents("p", "para", contents);
711     }
712
713     /**
714      * Handle a literal
715      * @param attributes the tag attributes
716      * @param contents the tag contents
717      * @return the HTML code
718      * @throws SAXEception if an error is encountered
719      */
720     public String handleLiteral(final Map<String, String> attributes, final String contents) throws SAXException {
721         return encloseContents("code", "literal", contents);
722     }
723
724     /**
725      * Handle a varname
726      * @param attributes the tag attributes
727      * @param contents the tag contents
728      * @return the HTML code
729      * @throws SAXEception if an error is encountered
730      */
731     public String handleVarname(final Map<String, String> attributes, final String contents) throws SAXException {
732         return encloseContents("code", "varname", contents);
733     }
734
735     /**
736      * Handle a command
737      * @param attributes the tag attributes
738      * @param contents the tag contents
739      * @return the HTML code
740      * @throws SAXEception if an error is encountered
741      */
742     public String handleCommand(final Map<String, String> attributes, final String contents) throws SAXException {
743         return encloseContents("code", "command", contents);
744     }
745
746     /**
747      * Handle a code
748      * @param attributes the tag attributes
749      * @param contents the tag contents
750      * @return the HTML code
751      * @throws SAXEception if an error is encountered
752      */
753     public String handleCode(final Map<String, String> attributes, final String contents) throws SAXException {
754         return encloseContents("code", "scilabcode", scilabLexer.convert(HTMLScilabCodeHandler.getInstance(refname, currentFileName), contents));//encloseContents("code", "code", contents);
755     }
756
757     /**
758      * Handle a function
759      * @param attributes the tag attributes
760      * @param contents the tag contents
761      * @return the HTML code
762      * @throws SAXEception if an error is encountered
763      */
764     public String handleFunction(final Map<String, String> attributes, final String contents) throws SAXException {
765         return encloseContents("code", "function", contents);
766     }
767
768     /**
769      * Handle a constant
770      * @param attributes the tag attributes
771      * @param contents the tag contents
772      * @return the HTML code
773      * @throws SAXEception if an error is encountered
774      */
775     public String handleConstant(final Map<String, String> attributes, final String contents) throws SAXException {
776         return encloseContents("code", "constant", contents);
777     }
778
779     /**
780      * Handle an option
781      * @param attributes the tag attributes
782      * @param contents the tag contents
783      * @return the HTML code
784      * @throws SAXEception if an error is encountered
785      */
786     public String handleOption(final Map<String, String> attributes, final String contents) throws SAXException {
787         return encloseContents("code", "option", contents);
788     }
789
790     /**
791      * Handle a refnamediv
792      * @param attributes the tag attributes
793      * @param contents the tag contents
794      * @return the HTML code
795      * @throws SAXEception if an error is encountered
796      */
797     public String handleRefnamediv(final Map<String, String> attributes, final String contents) throws SAXException {
798         String id = attributes.get("id");
799         if (id != null) {
800             currentId = id;
801         }
802
803         return encloseContents("div", "refnamediv", contents);
804     }
805
806     /**
807      * Handle a refname
808      * @param attributes the tag attributes
809      * @param contents the tag contents
810      * @return the HTML code
811      * @throws SAXEception if an error is encountered
812      */
813     public String handleRefname(final Map<String, String> attributes, final String contents) throws SAXException {
814         refname = contents;
815         return encloseContents("h1", "refname", contents);
816     }
817
818     /**
819      * Handle a refpurpose
820      * @param attributes the tag attributes
821      * @param contents the tag contents
822      * @return the HTML code
823      * @throws SAXEception if an error is encountered
824      */
825     public String handleRefpurpose(final Map<String, String> attributes, final String contents) throws SAXException {
826         refpurpose = contents;
827         return encloseContents("p", "refpurpose", contents);
828     }
829
830     /**
831      * Handle a refsynopsisdiv
832      * @param attributes the tag attributes
833      * @param contents the tag contents
834      * @return the HTML code
835      * @throws SAXEception if an error is encountered
836      */
837     public String handleRefsynopsisdiv(final Map<String, String> attributes, final String contents) throws SAXException {
838         String id = attributes.get("id");
839         if (id != null) {
840             return "<a name=\"" + id + "\"></a>" + encloseContents("div", "refsynopsisdiv", contents);
841         } else {
842             return encloseContents("div", "refsynopsisdiv", contents);
843         }
844     }
845
846     /**
847      * Handle a synopsis
848      * @param attributes the tag attributes
849      * @param contents the tag contents
850      * @return the HTML code
851      * @throws SAXEception if an error is encountered
852      */
853     public String handleSynopsis(final Map<String, String> attributes, final String contents) throws SAXException {
854         String id = attributes.get("id");
855         String str = encloseContents("div", "synopsis", encloseContents("pre", SynopsisLexer.convert(refname, contents)));
856         if (id != null) {
857             return "<a name=\"" + id + "\"></a>" + str;
858         } else {
859             return str;
860         }
861     }
862
863     /**
864      * Handle a info
865      * @param attributes the tag attributes
866      * @param contents the tag contents
867      * @return the HTML code
868      * @throws SAXEception if an error is encountered
869      */
870     public String handleInfo(final Map<String, String> attributes, final String contents) throws SAXException {
871         String id = attributes.get("id");
872         if (id != null) {
873             return "<a name=\"" + id + "\"></a>" + encloseContents("div", "info", contents);
874         } else {
875             return encloseContents("div", "info", contents);
876         }
877     }
878
879     /**
880      * Handle a refsection
881      * @param attributes the tag attributes
882      * @param contents the tag contents
883      * @return the HTML code
884      * @throws SAXEception if an error is encountered
885      */
886     public String handleRefsection(final Map<String, String> attributes, final String contents) throws SAXException {
887         String id = attributes.get("id");
888         if (id != null) {
889             return "<a name=\"" + id + "\"></a>" + encloseContents("div", "refsection", contents);
890         } else {
891             return encloseContents("div", "refsection", contents);
892         }
893     }
894
895     /**
896      * Handle a progamlisting
897      * @param attributes the tag attributes
898      * @param contents the tag contents
899      * @return the HTML code
900      * @throws SAXEception if an error is encountered
901      */
902     public String handleProgramlisting(final Map<String, String> attributes, final String contents) throws SAXException {
903         String id = attributes.get("id");
904         String role = attributes.get("role");
905         String str;
906         if (role == null) {
907             String code = encloseContents("pre", "scilabcode", scilabLexer.convert(HTMLScilabCodeHandler.getInstance(refname, currentFileName), contents));
908             if (prependToProgramListing != null) {
909                 code = prependToProgramListing + code;
910             }
911             if (appendToProgramListing != null) {
912                 code += appendToProgramListing;
913             }
914             str = encloseContents("div", "programlisting", code);
915         } else {
916             if (role.equals("xml")) {
917                 str = encloseContents("div", "programlisting", encloseContents("pre", "xmlcode", xmlLexer.convert(HTMLXMLCodeHandler.getInstance(), contents)));
918             } else if (role.equals("c") || role.equals("cpp") || role.equals("code_gateway")) {
919                 hasExamples = true;
920                 str = encloseContents("div", "programlisting", encloseContents("pre", "ccode", cLexer.convert(HTMLCCodeHandler.getInstance(), contents)));
921             } else if (role.equals("java")) {
922                 hasExamples = true;
923                 str = encloseContents("div", "programlisting", encloseContents("pre", "ccode", javaLexer.convert(HTMLCCodeHandler.getInstance(), contents)));
924             } else if (role.equals("exec")) {
925                 String code = encloseContents("pre", "scilabcode", scilabLexer.convert(HTMLScilabCodeHandler.getInstance(refname, currentFileName), contents));
926                 if (prependToProgramListing != null) {
927                     code = prependToProgramListing + code;
928                 }
929                 if (appendForExecToProgramListing != null) {
930                     code += appendForExecToProgramListing;
931                 }
932                 str = encloseContents("div", "programlisting", code);
933             } else if (role.equals("no-scilab-exec")) {
934                 hasExamples = true;
935                 String code = encloseContents("pre", "scilabcode", scilabLexer.convert(HTMLScilabCodeHandler.getInstance(refname, currentFileName), contents));
936                 str = encloseContents("div", "programlisting", code);
937             } else {
938                 String code = encloseContents("pre", "scilabcode", scilabLexer.convert(HTMLScilabCodeHandler.getInstance(refname, currentFileName), contents));
939                 if (prependToProgramListing != null) {
940                     code = prependToProgramListing + code;
941                 }
942                 if (appendToProgramListing != null) {
943                     code += appendToProgramListing;
944                 }
945                 str = encloseContents("div", "programlisting", code);
946             }
947         }
948         if (id != null) {
949             return "<a name=\"" + id + "\"></a>" + str;
950         } else {
951             return str;
952         }
953     }
954
955     /**
956      * Handle a screen
957      * @param attributes the tag attributes
958      * @param contents the tag contents
959      * @return the HTML code
960      * @throws SAXEception if an error is encountered
961      */
962     public String handleScreen(final Map<String, String> attributes, final String contents) throws SAXException {
963         String id = attributes.get("id");
964         String str = encloseContents("div", "screen", encloseContents("pre", contents));
965         if (id != null) {
966             return "<a name=\"" + id + "\"></a>" + str;
967         } else {
968             return str;
969         }
970     }
971
972     /**
973      * Handle a pubdate
974      * @param attributes the tag attributes
975      * @param contents the tag contents
976      * @return the HTML code
977      * @throws SAXEception if an error is encountered
978      */
979     public String handlePubdate(final Map<String, String> attributes, final String contents) throws SAXException {
980         return null;
981     }
982
983     /**
984      * Handle a simplelist
985      * @param attributes the tag attributes
986      * @param contents the tag contents
987      * @return the HTML code
988      * @throws SAXEception if an error is encountered
989      */
990     public String handleSimplelist(final Map<String, String> attributes, final String contents) throws SAXException {
991         String style = "itemizedlist";
992
993         return encloseContents("ul", style, contents);
994     }
995
996     /**
997      * Handle a member
998      * @param attributes the tag attributes
999      * @param contents the tag contents
1000      * @return the HTML code
1001      * @throws SAXEception if an error is encountered
1002      */
1003     public String handleMember(final Map<String, String> attributes, final String contents) throws SAXException {
1004         return encloseContents("li", "member", contents);
1005     }
1006
1007     /**
1008      * Handle a link
1009      * @param attributes the tag attributes
1010      * @param contents the tag contents
1011      * @return the HTML code
1012      * @throws SAXEception if an error is encountered
1013      */
1014     public String handleLink(final Map<String, String> attributes, final String contents) throws SAXException {
1015         String link = attributes.get("linkend");
1016         if (link == null) {
1017             throw new SAXException("No linkend attribute in tag link");
1018         }
1019
1020         String type = attributes.get("type");
1021         String id;
1022         if (type != null && type.equals("scilab")) {
1023             if (this.type == GenerationType.JAVAHELP) {
1024                 id = resolvScilabLink(link);
1025             } else {
1026                 return contents;
1027             }
1028         } else if (type != null && type.equals("remote")) {
1029             id = makeRemoteLink(link);
1030         } else {
1031             id = mapId.get(link);
1032         }
1033
1034         if (id == null) {
1035             warnings++;
1036             System.err.println("Warning (should be fixed): invalid internal link to " + link + " in " + currentFileName + "\nat line " + locator.getLineNumber());
1037             return null;
1038         }
1039
1040         Stack<DocbookElement> stack = getStack();
1041         String refnameTarget = mapIdRefname.get(link);
1042         String str;
1043         if (contents != null && !contents.isEmpty()) {
1044             str = contents;
1045         } else {
1046             str = refnameTarget;
1047         }
1048
1049         if (str == null) {
1050             warnings++;
1051             System.err.println("Warning (should be fixed): empty link (no text will be printed) to " + link + " in " + currentFileName + "\nat line " + locator.getLineNumber());
1052         }
1053
1054         String href = encloseContents("a", new String[] {"href", id, "class", "link"}, str);
1055
1056         int s = stack.size();
1057         if (s >= 3) {
1058             DocbookElement elem = stack.get(s - 3);
1059             if (elem.getName().equals("refsection")) {
1060                 String role = elem.getAttributes().get("role");
1061                 if (role != null && role.equals("see also")) {
1062                     String purpose = mapIdPurpose.get(link);
1063                     if (purpose != null) {
1064                         return href + " &#8212; " + purpose;
1065                     } else {
1066                         return href;
1067                     }
1068                 }
1069             }
1070         }
1071
1072         return href;
1073     }
1074
1075     /**
1076      * Rewrite a link when its type is "scilab"
1077      * @param link the link
1078      * @return the modified link with protocol scilab:// for example
1079      */
1080     protected String resolvScilabLink(String link) {
1081         int pos = link.indexOf("/");
1082         if (pos == -1) {
1083             return null;
1084         }
1085         String first = link.substring(0, pos);
1086         String second = link.substring(pos + 1);
1087         String[] toks = first.split("\\.");
1088         if (toks == null || toks.length != 2) {
1089             return null;
1090         }
1091
1092         if (!linkToTheWeb) {
1093             return urlBase + link;
1094         } else {
1095             if (toks[0].equals("scilab") && toks[1].equals("help")) {
1096                 return urlBase + second + ".html";
1097             } else {
1098                 return "#";
1099             }
1100         }
1101     }
1102
1103     /**
1104      * Make a remote link
1105      * @param link the link
1106      * @return the good link
1107      */
1108     protected String makeRemoteLink(String link) {
1109         return link;
1110     }
1111
1112     /**
1113      * Handle an ulink
1114      * @param attributes the tag attributes
1115      * @param contents the tag contents
1116      * @return the HTML code
1117      * @throws SAXEception if an error is encountered
1118      */
1119     public String handleUlink(final Map<String, String> attributes, final String contents) throws SAXException {
1120         String link = attributes.get("url");
1121         if (link == null) {
1122             throw new SAXException("No url attribute in tag ulink");
1123         }
1124
1125         return encloseContents("a", new String[] {"href", link, "class", "ulink"}, contents);
1126     }
1127
1128     /**
1129      * Handle a xref
1130      * @param attributes the tag attributes
1131      * @param contents the tag contents
1132      * @return the HTML code
1133      * @throws SAXEception if an error is encountered
1134      */
1135     public String handleXref(final Map<String, String> attributes, final String contents) throws SAXException {
1136         String link = attributes.get("linkend");
1137         if (link == null) {
1138             throw new SAXException("No linkend attribute in tag link");
1139         }
1140
1141         String id = mapId.get(link);
1142         if (id == null) {
1143             warnings++;
1144             System.err.println("Warning (should be fixed): invalid internal link to " + link + " in " + currentFileName + "\nat line " + locator.getLineNumber());
1145             return null;
1146         }
1147
1148         return encloseContents("a", new String[] {"href", id, "class", "xref"}, contents);
1149     }
1150
1151     /**
1152      * Handle a latex (not really a docbook tag...)
1153      * @param attributes the tag attributes
1154      * @param contents the tag contents
1155      * @return the HTML code
1156      * @throws SAXEception if an error is encountered
1157      */
1158     public String handleLatex(final Map<String, String> attributes, final String contents) throws SAXException {
1159         boolean isLocalized = "true".equals(attributes.get("localized"));
1160         File f;
1161         if (isLocalized) {
1162             f = new File(outImages + "/" + imageDir, LATEXBASENAME + currentBaseName + "_" + language + "_" + (latexCompt++) + ".png");
1163         } else {
1164             if ("ru_RU".equals(language) && HTMLDocbookTagConverter.containsCyrillic(contents)) {
1165                 System.err.println("Warning: LaTeX code in " + getCurrentFileName() + " contains cyrillic character. The tag <latex> should contain the attribute scilab:localized=\"true\"");
1166             } else if ("ja_JP".equals(language) && HTMLDocbookTagConverter.containsCJK(contents)) {
1167                 System.err.println("Warning: LaTeX code in " + getCurrentFileName() + " contains CJK character. The tag <latex> should contain the attribute scilab:localized=\"true\"");
1168             }
1169             f = new File(outImages + "/" + imageDir, LATEXBASENAME + currentBaseName + "_" + (latexCompt++) + ".png");
1170         }
1171
1172         String parent = getParentTagName();
1173         if (parent.equals("para") && !attributes.containsKey("style")) {
1174             attributes.put("style", "text");
1175         }
1176         String fs = attributes.get("fontsize");
1177         if (fs == null) {
1178             attributes.put("fontsize", "16");
1179         }
1180         return ImageConverter.getImageByCode(currentFileName, contents, attributes, "image/latex", f, imageDir + "/" + f.getName(), getBaseImagePath(), locator.getLineNumber(), language, isLocalized);
1181     }
1182
1183     /**
1184      * Handle a term
1185      * @param attributes the tag attributes
1186      * @param contents the tag contents
1187      * @return the HTML code
1188      * @throws SAXEception if an error is encountered
1189      */
1190     public String handleTerm(final Map<String, String> attributes, final String contents) throws SAXException {
1191         String id = attributes.get("id");
1192         if (id != null) {
1193             return "<a name=\"" + id + "\"></a>" + encloseContents("span", "term", contents);
1194         } else {
1195             return encloseContents("span", "term", contents);
1196         }
1197     }
1198
1199     /**
1200      * Handle a listitem
1201      * @param attributes the tag attributes
1202      * @param contents the tag contents
1203      * @return the HTML code
1204      * @throws SAXEception if an error is encountered
1205      */
1206     public String handleListitem(final Map<String, String> attributes, final String contents) throws SAXException {
1207         String parent = getParentTagName();
1208         if (parent.equals("varlistentry")) {
1209             return encloseContents("dd", contents);
1210         }
1211         return encloseContents("li", contents);
1212     }
1213
1214     /**
1215      * Handle a varlistentry
1216      * @param attributes the tag attributes
1217      * @param contents the tag contents
1218      * @return the HTML code
1219      * @throws SAXEception if an error is encountered
1220      */
1221     public String handleVarlistentry(final Map<String, String> attributes, final String contents) throws SAXException {
1222         return encloseContents("dt", contents);
1223     }
1224
1225     /**
1226      * Handle a variablelist
1227      * @param attributes the tag attributes
1228      * @param contents the tag contents
1229      * @return the HTML code
1230      * @throws SAXEception if an error is encountered
1231      */
1232     public String handleVariablelist(final Map<String, String> attributes, final String contents) throws SAXException {
1233         return encloseContents("dl", contents);
1234     }
1235
1236     /**
1237      * Handle an itemizedlist
1238      * @param attributes the tag attributes
1239      * @param contents the tag contents
1240      * @return the HTML code
1241      * @throws SAXEception if an error is encountered
1242      */
1243     public String handleItemizedlist(final Map<String, String> attributes, final String contents) throws SAXException {
1244         String id = attributes.get("id");
1245         if (id != null) {
1246             return "<a name=\"" + id + "\"></a>" + encloseContents("ul", "itemizedlist", contents);
1247         } else {
1248             return encloseContents("ul", "itemizedlist", contents);
1249         }
1250     }
1251
1252     /**
1253      * Handle an emphasis
1254      * @param attributes the tag attributes
1255      * @param contents the tag contents
1256      * @return the HTML code
1257      * @throws SAXEception if an error is encountered
1258      */
1259     public String handleEmphasis(final Map<String, String> attributes, final String contents) throws SAXException {
1260         String role = attributes.get("role");
1261         if (role != null) {
1262             if (role.equals("bold")) {
1263                 return encloseContents("b", contents);
1264             }
1265             if (role.equals("italic")) {
1266                 return encloseContents("i", contents);
1267             }
1268         }
1269
1270         return encloseContents("em", contents);
1271     }
1272
1273     /**
1274      * Handle a tr
1275      * @param attributes the tag attributes
1276      * @param contents the tag contents
1277      * @return the HTML code
1278      * @throws SAXEception if an error is encountered
1279      */
1280     public String handleTr(final Map<String, String> attributes, final String contents) throws SAXException {
1281         String bgcolor = attributes.get("bgcolor");
1282         return encloseContents("tr", new String[] {"bgcolor", bgcolor}, contents);
1283     }
1284
1285     /**
1286      * Handle a td
1287      * @param attributes the tag attributes
1288      * @param contents the tag contents
1289      * @return the HTML code
1290      * @throws SAXEception if an error is encountered
1291      */
1292     public String handleTd(final Map<String, String> attributes, final String contents) throws SAXException {
1293         String align = attributes.get("align");
1294         String bgcolor = attributes.get("bgcolor");
1295         return encloseContents("td", new String[] {"align", align, "bgcolor", bgcolor}, contents);
1296     }
1297
1298     /**
1299      * Handle an informaltable
1300      * @param attributes the tag attributes
1301      * @param contents the tag contents
1302      * @return the HTML code
1303      * @throws SAXEception if an error is encountered
1304      */
1305     public String handleInformaltable(final Map<String, String> attributes, final String contents) throws SAXException {
1306         String id = attributes.get("id");
1307         String bgcolor = attributes.get("bgcolor");
1308         String border = attributes.get("border");
1309         String cellpadding = attributes.get("cellpadding");
1310         String width = attributes.get("width");
1311         if (id != null) {
1312             return "<a name=\"" + id + "\"></a>" + encloseContents("table", new String[] {"class", "informaltable", "border", border, "cellpadding", cellpadding, "width", width}, contents);
1313         } else {
1314             return encloseContents("table", new String[] {"class", "informaltable", "border", border, "cellpadding", cellpadding, "width", width}, contents);
1315         }
1316     }
1317
1318     /**
1319      * Handle an imagedata
1320      * @param attributes the tag attributes
1321      * @param contents the tag contents
1322      * @return the HTML code
1323      * @throws SAXEception if an error is encountered
1324      */
1325     public String handleImagedata(final Map<String, String> attributes, final String contents) throws SAXException {
1326         String fileref = attributes.get("fileref");
1327         if (fileref == null) {
1328             if (contents == null || contents.length() == 0) {
1329                 throw new SAXException("No fileref attribute or no data in tag imagedata");
1330             }
1331
1332             return contents;
1333         }
1334
1335         try {
1336             String path = new File(new URI(currentFileName)).getParent();
1337             File file = ImageConverter.imageExists(path, fileref);
1338             if (file != null) {
1339                 throw new SAXException("The given fileref is not on an existing image file:\n" + fileref + " [" + file + "]");
1340             }
1341
1342             return ImageConverter.getImageByFile(attributes, path, fileref, outImages, imageDir, getBaseImagePath());
1343         }  catch (URISyntaxException e) {
1344             System.err.println(e);
1345         }
1346
1347         return null;
1348     }
1349
1350     /**
1351      * Handle an imageobject
1352      * @param attributes the tag attributes
1353      * @param contents the tag contents
1354      * @return the HTML code
1355      * @throws SAXEception if an error is encountered
1356      */
1357     public String handleImageobject(final Map<String, String> attributes, final String contents) throws SAXException {
1358         return contents;
1359     }
1360
1361     /**
1362      * Handle an inlinemediaobject
1363      * @param attributes the tag attributes
1364      * @param contents the tag contents
1365      * @return the HTML code
1366      * @throws SAXEception if an error is encountered
1367      */
1368     public String handleInlinemediaobject(final Map<String, String> attributes, final String contents) throws SAXException {
1369         return encloseContents("span", contents);
1370     }
1371
1372     /**
1373      * Handle a screenshot
1374      * @param attributes the tag attributes
1375      * @param contents the tag contents
1376      * @return the HTML code
1377      * @throws SAXEception if an error is encountered
1378      */
1379     public String handleScreenshot(final Map<String, String> attributes, final String contents) throws SAXException {
1380         String id = attributes.get("id");
1381         if (id != null) {
1382             return "<a name=\"" + id + "\"></a>" + encloseContents("div", "screenshot", contents);
1383         } else {
1384             return encloseContents("div", "screenshot", contents);
1385         }
1386     }
1387
1388     /**
1389      * Handle a mediaobject
1390      * @param attributes the tag attributes
1391      * @param contents the tag contents
1392      * @return the HTML code
1393      * @throws SAXEception if an error is encountered
1394      */
1395     public String handleMediaobject(final Map<String, String> attributes, final String contents) throws SAXException {
1396         String id = attributes.get("id");
1397         String c = contents.replaceFirst("top:([0-9]+)px;", "");
1398         if (id != null) {
1399             return "<a name=\"" + id + "\"></a>" + encloseContents("div", "mediaobject", c);
1400         } else {
1401             return encloseContents("div", "mediaobject", c);
1402         }
1403     }
1404
1405     /**
1406      * Handle an informalequation
1407      * @param attributes the tag attributes
1408      * @param contents the tag contents
1409      * @return the HTML code
1410      * @throws SAXEception if an error is encountered
1411      */
1412     public String handleInformalequation(final Map<String, String> attributes, final String contents) throws SAXException {
1413         String id = attributes.get("id");
1414         if (id != null) {
1415             return "<a name=\"" + id + "\"></a>" + encloseContents("div", "informalequation", contents);
1416         } else {
1417             return encloseContents("div", "informalequation", contents);
1418         }
1419     }
1420
1421     /**
1422      * Handle an orderedlist
1423      * @param attributes the tag attributes
1424      * @param contents the tag contents
1425      * @return the HTML code
1426      * @throws SAXEception if an error is encountered
1427      */
1428     public String handleOrderedlist(final Map<String, String> attributes, final String contents) throws SAXException {
1429         String numeration = "1";
1430         String numAttr = attributes.get("numeration");
1431         if (numAttr != null) {
1432             if (numAttr.equals("loweralpha")) {
1433                 numeration = "a";
1434             } else if (numAttr.equals("upperalpha")) {
1435                 numeration = "A";
1436             } else if (numAttr.equals("lowerroman")) {
1437                 numeration = "i";
1438             } else if (numAttr.equals("upperroman")) {
1439                 numeration = "I";
1440             }
1441         }
1442
1443         String id = attributes.get("id");
1444         if (id != null) {
1445             return "<a name=\"" + id + "\"></a>" + encloseContents("ol", new String[] {"type", numeration}, contents);
1446         } else {
1447             return encloseContents("ol", new String[] {"type", numeration}, contents);
1448         }
1449     }
1450
1451     /**
1452      * Handle a subscript
1453      * @param attributes the tag attributes
1454      * @param contents the tag contents
1455      * @return the HTML code
1456      * @throws SAXEception if an error is encountered
1457      */
1458     public String handleSubscript(final Map<String, String> attributes, final String contents) throws SAXException {
1459         return encloseContents("sub", contents);
1460     }
1461
1462     /**
1463      * Handle a superscript
1464      * @param attributes the tag attributes
1465      * @param contents the tag contents
1466      * @return the HTML code
1467      * @throws SAXEception if an error is encountered
1468      */
1469     public String handleSuperscript(final Map<String, String> attributes, final String contents) throws SAXException {
1470         return encloseContents("sup", contents);
1471     }
1472
1473     /**
1474      * Handle a replaceable
1475      * @param attributes the tag attributes
1476      * @param contents the tag contents
1477      * @return the HTML code
1478      * @throws SAXEception if an error is encountered
1479      */
1480     public String handleReplaceable(final Map<String, String> attributes, final String contents) throws SAXException {
1481         return encloseContents("span", "replaceable", contents);
1482     }
1483
1484     /**
1485      * Handle a question
1486      * @param attributes the tag attributes
1487      * @param contents the tag contents
1488      * @return the HTML code
1489      * @throws SAXEception if an error is encountered
1490      */
1491     public String handleQuestion(final Map<String, String> attributes, final String contents) throws SAXException {
1492         return encloseContents("dt", encloseContents("strong", contents));
1493     }
1494
1495     /**
1496      * Handle an answer
1497      * @param attributes the tag attributes
1498      * @param contents the tag contents
1499      * @return the HTML code
1500      * @throws SAXEception if an error is encountered
1501      */
1502     public String handleAnswer(final Map<String, String> attributes, final String contents) throws SAXException {
1503         return encloseContents("dd", contents);
1504     }
1505
1506     /**
1507      * Handle a qandaentry
1508      * @param attributes the tag attributes
1509      * @param contents the tag contents
1510      * @return the HTML code
1511      * @throws SAXEception if an error is encountered
1512      */
1513     public String handleQandaentry(final Map<String, String> attributes, final String contents) throws SAXException {
1514         return encloseContents("dl", contents);
1515     }
1516
1517     /**
1518      * Handle a qandaset
1519      * @param attributes the tag attributes
1520      * @param contents the tag contents
1521      * @return the HTML code
1522      * @throws SAXEception if an error is encountered
1523      */
1524     public String handleQandaset(final Map<String, String> attributes, final String contents) throws SAXException {
1525         return encloseContents("div", "qandaset", contents);
1526     }
1527
1528     /**
1529      * Handle a caption
1530      * @param attributes the tag attributes
1531      * @param contents the tag contents
1532      * @return the HTML code
1533      * @throws SAXEception if an error is encountered
1534      */
1535     public String handleCaption(final Map<String, String> attributes, final String contents) throws SAXException {
1536         return encloseContents("caption", encloseContents("b", contents));
1537     }
1538
1539     /**
1540      * Handle a tbody
1541      * @param attributes the tag attributes
1542      * @param contents the tag contents
1543      * @return the HTML code
1544      * @throws SAXEception if an error is encountered
1545      */
1546     public String handleTbody(final Map<String, String> attributes, final String contents) throws SAXException {
1547         return encloseContents("tbody", "tbody", contents);
1548     }
1549
1550     /**
1551      * Handle a table
1552      * @param attributes the tag attributes
1553      * @param contents the tag contents
1554      * @return the HTML code
1555      * @throws SAXEception if an error is encountered
1556      */
1557     public String handleTable(final Map<String, String> attributes, final String contents) throws SAXException {
1558         String id = attributes.get("id");
1559         String bgcolor = attributes.get("bgcolor");
1560         String border = attributes.get("border");
1561         String cellpadding = attributes.get("cellpadding");
1562
1563         if (id != null) {
1564             return "<a name=\"" + id + "\"></a>" + encloseContents("table", new String[] {"class", "doctable", "bgcolor", bgcolor, "border", border, "cellpadding", cellpadding}, contents);
1565         } else {
1566             return encloseContents("table", new String[] {"class", "doctable", "bgcolor", bgcolor, "border", border, "cellpadding", cellpadding}, contents);
1567         }
1568     }
1569
1570     /**
1571      * Handle a surname
1572      * @param attributes the tag attributes
1573      * @param contents the tag contents
1574      * @return the HTML code
1575      * @throws SAXEception if an error is encountered
1576      */
1577     public String handleSurname(final Map<String, String> attributes, final String contents) throws SAXException {
1578         return encloseContents("span", "surname", contents);
1579     }
1580
1581     /**
1582      * Handle a firstname
1583      * @param attributes the tag attributes
1584      * @param contents the tag contents
1585      * @return the HTML code
1586      * @throws SAXEception if an error is encountered
1587      */
1588     public String handleFirstname(final Map<String, String> attributes, final String contents) throws SAXException {
1589         return encloseContents("span", "firstname", contents);
1590     }
1591
1592     /**
1593      * Handle a bibliomset
1594      * @param attributes the tag attributes
1595      * @param contents the tag contents
1596      * @return the HTML code
1597      * @throws SAXEception if an error is encountered
1598      */
1599     public String handleBibliomset(final Map<String, String> attributes, final String contents) throws SAXException {
1600         String id = attributes.get("id");
1601         if (id != null) {
1602             return "<a name=\"" + id + "\"></a>" + encloseContents("div", "bibliomset", contents);
1603         } else {
1604             return encloseContents("div", "bibliomset", contents);
1605         }
1606     }
1607
1608     /**
1609      * Handle a bibliomixed
1610      * @param attributes the tag attributes
1611      * @param contents the tag contents
1612      * @return the HTML code
1613      * @throws SAXEception if an error is encountered
1614      */
1615     public String handleBibliomixed(final Map<String, String> attributes, final String contents) throws SAXException {
1616         String id = attributes.get("id");
1617         if (id != null) {
1618             return "<a name=\"" + id + "\"></a>" + encloseContents("div", "bibliomixed", contents);
1619         } else {
1620             return encloseContents("div", "bibliomixed", contents);
1621         }
1622     }
1623
1624     /**
1625      * Handle a th
1626      * @param attributes the tag attributes
1627      * @param contents the tag contents
1628      * @return the HTML code
1629      * @throws SAXEception if an error is encountered
1630      */
1631     public String handleTh(final Map<String, String> attributes, final String contents) throws SAXException {
1632         return encloseContents("th", contents);
1633     }
1634
1635     /**
1636      * Handle a revhistory
1637      * @param attributes the tag attributes
1638      * @param contents the tag contents
1639      * @return the HTML code
1640      * @throws SAXEception if an error is encountered
1641      */
1642     public String handleRevhistory(final Map<String, String> attributes, final String contents) throws SAXException {
1643         String id = attributes.get("id");
1644         String str = "<table class=\"revhistory\"><tr class=\"title\"><td>" + VERSION + "</td><td>" + DESCRIPTION + "</td></tr>" + contents + "</table>";
1645         if (id != null) {
1646             return "<a name=\"" + id + "\"></a>" + str;
1647         } else {
1648             return str;
1649         }
1650     }
1651
1652     /**
1653      * Handle a revision
1654      * @param attributes the tag attributes
1655      * @param contents the tag contents
1656      * @return the HTML code
1657      * @throws SAXEception if an error is encountered
1658      */
1659     public String handleRevision(final Map<String, String> attributes, final String contents) throws SAXException {
1660         return encloseContents("tr", contents);
1661     }
1662
1663     /**
1664      * Handle a revnumber
1665      * @param attributes the tag attributes
1666      * @param contents the tag contents
1667      * @return the HTML code
1668      * @throws SAXEception if an error is encountered
1669      */
1670     public String handleRevnumber(final Map<String, String> attributes, final String contents) throws SAXException {
1671         return encloseContents("td", "revnumber", contents);
1672     }
1673
1674     /**
1675      * Handle a revremark
1676      * @param attributes the tag attributes
1677      * @param contents the tag contents
1678      * @return the HTML code
1679      * @throws SAXEception if an error is encountered
1680      */
1681     public String handleRevremark(final Map<String, String> attributes, final String contents) throws SAXException {
1682         return encloseContents("td", "revremark", contents);
1683     }
1684
1685     /**
1686      * Handle a revdescription
1687      * @param attributes the tag attributes
1688      * @param contents the tag contents
1689      * @return the HTML code
1690      * @throws SAXEception if an error is encountered
1691      */
1692     public String handleRevdescription(final Map<String, String> attributes, final String contents) throws SAXException {
1693         return encloseContents("td", "revdescription", contents);
1694     }
1695
1696     /**
1697      * Handle a note
1698      * @param attributes the tag attributes
1699      * @param contents the tag contents
1700      * @return the HTML code
1701      * @throws SAXEception if an error is encountered
1702      */
1703     public String handleNote(final Map<String, String> attributes, final String contents) throws SAXException {
1704         String id = attributes.get("id");
1705         String code = "<table><tr><td valign=\"top\"><img src=\"" + getBaseImagePath() + "ScilabNote.png\"/></td><td valign=\"top\">" + encloseContents("div", "note", contents) + "</td></tr></table>";
1706         if (id != null) {
1707             return "<a name=\"" + id + "\"></a>" + code;
1708         } else {
1709             return code;
1710         }
1711     }
1712
1713     /**
1714      * Handle a warning
1715      * @param attributes the tag attributes
1716      * @param contents the tag contents
1717      * @return the HTML code
1718      * @throws SAXEception if an error is encountered
1719      */
1720     public String handleWarning(final Map<String, String> attributes, final String contents) throws SAXException {
1721         String id = attributes.get("id");
1722         String code = "<table><tr><td valign=\"top\"><img src=\"" + getBaseImagePath() + "ScilabWarning.png\"/></td><td valign=\"top\">" + encloseContents("div", "warning", contents) + "</td></tr></table>";
1723         if (id != null) {
1724             return "<a name=\"" + id + "\"></a>" + code;
1725         } else {
1726             return code;
1727         }
1728     }
1729
1730     /**
1731      * Handle a caution
1732      * @param attributes the tag attributes
1733      * @param contents the tag contents
1734      * @return the HTML code
1735      * @throws SAXEception if an error is encountered
1736      */
1737     public String handleCaution(final Map<String, String> attributes, final String contents) throws SAXException {
1738         String id = attributes.get("id");
1739         String code = "<table><tr><td valign=\"top\"><img src=\"" + getBaseImagePath() + "ScilabCaution.png\"/></td><td valign=\"top\">" + encloseContents("div", "caution", contents) + "</td></tr></table>";
1740         if (id != null) {
1741             return "<a name=\"" + id + "\"></a>" + code;
1742         } else {
1743             return code;
1744         }
1745     }
1746
1747     /**
1748      * Handle a tip
1749      * @param attributes the tag attributes
1750      * @param contents the tag contents
1751      * @return the HTML code
1752      * @throws SAXEception if an error is encountered
1753      */
1754     public String handleTip(final Map<String, String> attributes, final String contents) throws SAXException {
1755         String id = attributes.get("id");
1756         String code = "<table><tr><td valign=\"top\"><img src=\"" + getBaseImagePath() + "ScilabTip.png\"/></td><td valign=\"top\">" + encloseContents("div", "tip", contents) + "</td></tr></table>";
1757         if (id != null) {
1758             return "<a name=\"" + id + "\"></a>" + code;
1759         } else {
1760             return code;
1761         }
1762     }
1763
1764     /**
1765      * Handle a important
1766      * @param attributes the tag attributes
1767      * @param contents the tag contents
1768      * @return the HTML code
1769      * @throws SAXEception if an error is encountered
1770      */
1771     public String handleImportant(final Map<String, String> attributes, final String contents) throws SAXException {
1772         String id = attributes.get("id");
1773         String code = "<table><tr><td valign=\"top\"><img src=\"" + getBaseImagePath() + "ScilabImportant.png\"/></td><td valign=\"top\">" + encloseContents("div", "important", contents) + "</td></tr></table>";
1774         if (id != null) {
1775             return "<a name=\"" + id + "\"></a>" + code;
1776         } else {
1777             return code;
1778         }
1779     }
1780 }