1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 or later
5    * as published by the Free Software Foundation. This program is distributed
6    * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7    * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *      http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * © CrossWire Bible Society, 2005 - 2016
18   *
19   */
20  package org.crosswire.common.xml;
21  
22  import java.io.Writer;
23  
24  /**
25   * This class provides for the formatted and syntax highlighted serialization of
26   * a SAX stream to a <code>Writer</code>.
27   * 
28   * @see gnu.lgpl.License The GNU Lesser General Public License for details.
29   * @author DM Smith
30   */
31  public class HTMLSerializingContentHandler extends PrettySerializingContentHandler {
32      /**
33       * A formatting serializer that does not add whitespace to the document.
34       * This uses a StringWriter and the toString method will return its content.
35       */
36      public HTMLSerializingContentHandler() {
37          super();
38      }
39  
40      /**
41       * A formatting serializer that adds whitespace to the document according to
42       * the specified <code>FormatType</code>. This uses a StringWriter and the
43       * toString method will return its content.
44       * 
45       * @param theFormat
46       *            the formatting to use
47       */
48      public HTMLSerializingContentHandler(FormatType theFormat) {
49          super(theFormat);
50      }
51  
52      /**
53       * A formatting serializer that adds whitespace to the document according to
54       * the specified <code>FormatType</code>. As the document is serialized it
55       * is written to the provided <code>Writer</code>.
56       * 
57       * @param theFormat
58       *            the formatting to use
59       * @param theWriter
60       *            the writer to use
61       */
62      public HTMLSerializingContentHandler(FormatType theFormat, Writer theWriter) {
63          super(theFormat, theWriter);
64      }
65  
66      @Override
67      protected String decorateTagName(String tagName) {
68          StringBuilder buf = new StringBuilder(50);
69          buf.append("<font class='tag'>");
70          buf.append(super.decorateTagName(tagName));
71          buf.append("</font>");
72          return buf.toString();
73      }
74  
75      /*
76       * (non-Javadoc)
77       * 
78       * @seeorg.crosswire.common.xml.PrettySerializingContentHandler#
79       * decorateAttributeName(java.lang.String)
80       */
81      @Override
82      protected String decorateAttributeName(String attrName) {
83          StringBuilder buf = new StringBuilder(50);
84          buf.append("<font class='attr'>");
85          buf.append(super.decorateAttributeName(attrName));
86          buf.append("</font>");
87          return buf.toString();
88      }
89  
90      /*
91       * (non-Javadoc)
92       * 
93       * @seeorg.crosswire.common.xml.PrettySerializingContentHandler#
94       * decorateAttributeValue(java.lang.String)
95       */
96      @Override
97      protected String decorateAttributeValue(String attrValue) {
98          StringBuilder buf = new StringBuilder(50);
99          buf.append("<font class='value'>");
100         buf.append(super.decorateAttributeValue(attrValue));
101         buf.append("</font>");
102         return buf.toString();
103     }
104 
105     /*
106      * (non-Javadoc)
107      * 
108      * @see
109      * org.crosswire.common.xml.PrettySerializingContentHandler#decorateCharacters
110      * (java.lang.String)
111      */
112     @Override
113     protected String decorateCharacters(String characters) {
114         StringBuilder buf = new StringBuilder(50);
115         buf.append("<font class='text'>");
116         buf.append(XMLUtil.escape(super.decorateCharacters(characters)).replaceAll("\n", "<br>"));
117         buf.append("</font>");
118         return buf.toString();
119     }
120 
121     /*
122      * (non-Javadoc)
123      * 
124      * @see
125      * org.crosswire.common.xml.PrettySerializingContentHandler#decorateIndent
126      * (int)
127      */
128     @Override
129     protected String decorateIndent(int indentLevel) {
130         StringBuilder buf = new StringBuilder(100);
131         buf.append("<font class='indent'>");
132         buf.append(super.decorateIndent(indentLevel).replaceAll("\t", "&nbsp;&nbsp;&nbsp;&nbsp;"));
133         buf.append("</font>");
134         return buf.toString();
135     }
136 
137     /*
138      * (non-Javadoc)
139      * 
140      * @see org.xml.sax.ContentHandler#startDocument()
141      */
142     @Override
143     public void startDocument() {
144         // Note: we should be using SPAN here but Sun's Java does not support
145         // styling it.
146         // Also, it introduces whitespace between the span and the text.
147         write("<html><head><style type='text/css'>\nFONT.tag    { font-family:courier new, monospaced; color:#666699; font-weight:bold; }\nFONT.attr   { font-family:courier new, monospaced; color:#669966; font-weight:bold; }\nFONT.value  { font-family:courier new, monospaced; color:#669966; font-style:italic; }\nFONT.indent { }\nFONT.text   { font-family:courier new, monospaced; background:#FFFF99; }\n</style></head><body>\n");
148     }
149 
150     /*
151      * (non-Javadoc)
152      * 
153      * @see org.xml.sax.ContentHandler#endDocument()
154      */
155     @Override
156     public void endDocument() {
157         write("</body></head>");
158     }
159 
160     /*
161      * (non-Javadoc)
162      * 
163      * @see
164      * org.crosswire.common.xml.PrettySerializingContentHandler#getEmptyTagEnd()
165      */
166     @Override
167     protected String getEmptyTagEnd() {
168         return XMLUtil.escape(super.getEmptyTagEnd());
169     }
170 
171     /*
172      * (non-Javadoc)
173      * 
174      * @see
175      * org.crosswire.common.xml.PrettySerializingContentHandler#getEndTagStart()
176      */
177     @Override
178     protected String getEndTagStart() {
179         return XMLUtil.escape(super.getEndTagStart());
180     }
181 
182     /*
183      * (non-Javadoc)
184      * 
185      * @see org.crosswire.common.xml.PrettySerializingContentHandler#getPIEnd()
186      */
187     @Override
188     protected String getPIEnd() {
189         return XMLUtil.escape(super.getPIEnd());
190     }
191 
192     /*
193      * (non-Javadoc)
194      * 
195      * @see
196      * org.crosswire.common.xml.PrettySerializingContentHandler#getPIStart()
197      */
198     @Override
199     protected String getPIStart() {
200         return XMLUtil.escape(super.getPIStart());
201     }
202 
203     /*
204      * (non-Javadoc)
205      * 
206      * @see org.crosswire.common.xml.PrettySerializingContentHandler#getTagEnd()
207      */
208     @Override
209     protected String getTagEnd() {
210         return XMLUtil.escape(super.getTagEnd());
211     }
212 
213     /*
214      * (non-Javadoc)
215      * 
216      * @see
217      * org.crosswire.common.xml.PrettySerializingContentHandler#getTagStart()
218      */
219     @Override
220     protected String getTagStart() {
221         return XMLUtil.escape(super.getTagStart());
222     }
223 
224     /*
225      * (non-Javadoc)
226      * 
227      * @see
228      * org.crosswire.common.xml.PrettySerializingContentHandler#getNewline()
229      */
230     @Override
231     protected String getNewline() {
232         return "<br>";
233     }
234 }
235