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