1 /*
2  * This file is part of ELKI:
3  * Environment for Developing KDD-Applications Supported by Index-Structures
4  *
5  * Copyright (C) 2018
6  * ELKI Development Team
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Affero General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Affero General Public License for more details.
17  *
18  * You should have received a copy of the GNU Affero General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 package de.lmu.ifi.dbs.elki.utilities.xml;
22 
23 import java.io.IOException;
24 import java.io.OutputStream;
25 
26 import javax.xml.transform.OutputKeys;
27 import javax.xml.transform.Transformer;
28 import javax.xml.transform.TransformerException;
29 import javax.xml.transform.TransformerFactory;
30 import javax.xml.transform.dom.DOMSource;
31 import javax.xml.transform.stream.StreamResult;
32 
33 import org.w3c.dom.Document;
34 import org.w3c.dom.Element;
35 
36 /**
37  * Class with HTML related utility functions, in particular HTML generation.
38  *
39  * @author Erich Schubert
40  * @since 0.2
41  */
42 public final class HTMLUtil {
43   /**
44    * Private constructor. Static methods only.
45    */
HTMLUtil()46   private HTMLUtil() {
47     // Do not use.
48   }
49 
50   /**
51    * HTML namespace
52    */
53   public static final String HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
54 
55   /**
56    * XHTML PUBLIC doctype
57    */
58   public static final String HTML_XHTML_TRANSITIONAL_DOCTYPE_PUBLIC = "-//W3C//DTD XHTML 1.0 Transitional//EN";
59 
60   /**
61    * XHTML SYSTEM doctype
62    */
63   public static final String HTML_XHTML_TRANSITIONAL_DOCTYPE_SYSTEM = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";
64 
65   /**
66    * HTML root element
67    */
68   public static final String HTML_HTML_TAG = "html";
69 
70   /**
71    * HTML head element
72    */
73   public static final String HTML_HEAD_TAG = "head";
74 
75   /**
76    * HTML title element
77    */
78   public static final String HTML_TITLE_TAG = "title";
79 
80   /**
81    * HTML body element
82    */
83   public static final String HTML_BODY_TAG = "body";
84 
85   /**
86    * HTML dl element
87    */
88   public static final String HTML_DL_TAG = "dl";
89 
90   /**
91    * HTML dt element
92    */
93   public static final String HTML_DT_TAG = "dt";
94 
95   /**
96    * HTML dd element
97    */
98   public static final String HTML_DD_TAG = "dd";
99 
100   /**
101    * HTML unordered list tag
102    */
103   public static final String HTML_UL_TAG = "ul";
104 
105   /**
106    * HTML ordered list tag
107    */
108   public static final String HTML_OL_TAG = "ol";
109 
110   /**
111    * HTML list item tag
112    */
113   public static final String HTML_LI_TAG = "li";
114 
115   /**
116    * HTML em element
117    */
118   public static final String HTML_EM_TAG = "em";
119 
120   /**
121    * HTML i element
122    */
123   public static final String HTML_I_TAG = "i";
124 
125   /**
126    * HTML strong element
127    */
128   public static final String HTML_STRONG_TAG = "strong";
129 
130   /**
131    * HTML b element
132    */
133   public static final String HTML_B_TAG = "b";
134 
135   /**
136    * HTML tt element
137    */
138   public static final String HTML_TT_TAG = "tt";
139 
140   /**
141    * HTML br element
142    */
143   public static final String HTML_BR_TAG = "br";
144 
145   /**
146    * HTML h1 element
147    */
148   public static final String HTML_H1_TAG = "h1";
149 
150   /**
151    * HTML a element
152    */
153   public static final String HTML_A_TAG = "a";
154 
155   /**
156    * HTML p element
157    */
158   public static final String HTML_P_TAG = "p";
159 
160   /**
161    * HTML div element
162    */
163   public static final String HTML_DIV_TAG = "div";
164 
165   /**
166    * HTML span element
167    */
168   public static final String HTML_SPAN_TAG = "span";
169 
170   /**
171    * HTML img element
172    */
173   public static final String HTML_IMG_TAG = "img";
174 
175   /**
176    * HTML meta element
177    */
178   public static final String HTML_META_TAG = "meta";
179 
180   /**
181    * HTML link element
182    */
183   public static final String HTML_LINK_TAG = "link";
184 
185   /**
186    * HTML href attribute (a, link tags)
187    */
188   public static final String HTML_HREF_ATTRIBUTE = "href";
189 
190   /**
191    * HTML src attribute (img tag)
192    */
193   public static final String HTML_SRC_ATTRIBUTE = "src";
194 
195   /**
196    * HTML style attribute
197    */
198   public static final String HTML_STYLE_ATTRIBUTE = "style";
199 
200   /**
201    * HTML class attribute
202    */
203   public static final String HTML_CLASS_ATTRIBUTE = "class";
204 
205   /**
206    * HTML element id attribute
207    */
208   public static final String HTML_ID_ATTRIBUTE = "id";
209 
210   /**
211    * HTML name attribute (e.g. A tag)
212    */
213   public static final String HTML_NAME_ATTRIBUTE = "name";
214 
215   /**
216    * HTML type attribute (link tag)
217    */
218   public static final String HTML_TYPE_ATTRIBUTE = "type";
219 
220   /**
221    * HTML rel attribute (link tag)
222    */
223   public static final String HTML_REL_ATTRIBUTE = "rel";
224 
225   /**
226    * HTML rel value for stylesheets
227    */
228   public static final String HTML_REL_STYLESHEET = "stylesheet";
229 
230   /**
231    * HTML http-equiv attribute (meta tag)
232    */
233   public static final String HTML_HTTP_EQUIV_ATTRIBUTE = "http-equiv";
234 
235   /**
236    * HTML content attribute (meta tag)
237    */
238   public static final String HTML_CONTENT_ATTRIBUTE = "content";
239 
240   /**
241    * HTML http-equiv value Content-type
242    */
243   public static final String HTML_HTTP_EQUIV_CONTENT_TYPE = "Content-Type";
244 
245   /**
246    * HTML content type
247    */
248   public static final String CONTENT_TYPE_HTML = "text/html";
249 
250   /**
251    * CSS content type
252    */
253   public static final String CONTENT_TYPE_CSS = "text/css";
254 
255   /**
256    * HTML content type with UTF-8 indication
257    */
258   public static final String CONTENT_TYPE_HTML_UTF8 = CONTENT_TYPE_HTML + "; charset=UTF-8";
259 
260   /**
261    * Write an HTML document to an output stream.
262    *
263    * @param htmldoc Document to output
264    * @param out Stream to write to
265    * @throws IOException thrown on IO errors
266    */
writeXHTML(Document htmldoc, OutputStream out)267   public static void writeXHTML(Document htmldoc, OutputStream out) throws IOException {
268     javax.xml.transform.Result result = new StreamResult(out);
269     // Use a transformer for pretty printing
270     Transformer xformer;
271     try {
272       xformer = TransformerFactory.newInstance().newTransformer();
273       xformer.setOutputProperty(OutputKeys.INDENT, "yes");
274       // TODO: ensure the "meta" tag doesn't claim a different encoding!
275       xformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
276       xformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, HTML_XHTML_TRANSITIONAL_DOCTYPE_PUBLIC);
277       xformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, HTML_XHTML_TRANSITIONAL_DOCTYPE_SYSTEM);
278       xformer.transform(new DOMSource(htmldoc), result);
279     }
280     catch(TransformerException e1) {
281       throw new IOException(e1);
282     }
283     out.flush();
284   }
285 
286   /**
287    * Append a multiline text to a node, transforming linewraps into BR tags.
288    *
289    * @param htmldoc Document
290    * @param parent Parent node
291    * @param text Text to add.
292    * @return parent node
293    */
appendMultilineText(Document htmldoc, Element parent, String text)294   public static Element appendMultilineText(Document htmldoc, Element parent, String text) {
295     String[] parts = text != null ? text.split("\n") : null;
296     if(parts == null || parts.length == 0) {
297       return parent;
298     }
299     parent.appendChild(htmldoc.createTextNode(parts[0]));
300     for(int i = 1; i < parts.length; i++) {
301       parent.appendChild(htmldoc.createElement(HTML_BR_TAG));
302       parent.appendChild(htmldoc.createTextNode(parts[i]));
303     }
304     return parent;
305   }
306 }
307