001/**
002 *
003 * Copyright 2003-2007 Jive Software.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.jivesoftware.smackx.xhtmlim;
019
020import org.jivesoftware.smack.packet.Message;
021import org.jivesoftware.smack.util.XmlStringBuilder;
022
023/**
024 * An XHTMLText represents formatted text. This class also helps to build valid 
025 * XHTML tags.
026 *
027 * @author Gaston Dombiak
028 */
029public class XHTMLText {
030
031    public static final String NAMESPACE = "http://www.w3.org/1999/xhtml";
032
033    private final XmlStringBuilder text = new XmlStringBuilder();
034
035    /**
036     * Creates a new XHTMLText with body tag params.
037     * 
038     * @param style the XHTML style of the body
039     * @param lang the language of the body
040     */
041    public XHTMLText(String style, String lang) {
042        appendOpenBodyTag(style, lang);
043    }
044
045    public static final String A = "a";
046    public static final String HREF = "href";
047    public static final String STYLE = "style";
048
049    /**
050     * Appends a tag that indicates that an anchor section begins.
051     * 
052     * @param href indicates the URL being linked to
053     * @param style the XHTML style of the anchor
054     */
055    public XHTMLText appendOpenAnchorTag(String href, String style) {
056        text.halfOpenElement(A);
057        text.optAttribute(HREF, href);
058        text.optAttribute(STYLE, style);
059        text.rightAngleBracket();
060        return this;
061    }
062
063    /**
064     * Appends a tag that indicates that an anchor section ends.
065     * 
066     */
067    public XHTMLText appendCloseAnchorTag() {
068        text.closeElement(A);
069        return this;
070    }
071
072    public static final String BLOCKQUOTE = "blockquote";
073    /**
074     * Appends a tag that indicates that a blockquote section begins.
075     * 
076     * @param style the XHTML style of the blockquote
077     */
078    public XHTMLText appendOpenBlockQuoteTag(String style) {
079        text.halfOpenElement(BLOCKQUOTE);
080        text.optAttribute(STYLE, style);
081        text.rightAngleBracket();
082        return this;
083    }
084
085    /**
086     * Appends a tag that indicates that a blockquote section ends.
087     * 
088     */
089    public XHTMLText appendCloseBlockQuoteTag() {
090        text.closeElement(BLOCKQUOTE);
091        return this;
092    }
093
094    /**
095     * Appends a tag that indicates that a body section begins.
096     * 
097     * @param style the XHTML style of the body
098     * @param lang the language of the body
099     */
100    private XHTMLText appendOpenBodyTag(String style, String lang) {
101        text.halfOpenElement(Message.BODY);
102        text.xmlnsAttribute(NAMESPACE);
103        text.optElement(STYLE, style);
104        text.xmllangAttribute(lang);
105        text.rightAngleBracket();
106        return this;
107    }
108
109    public XHTMLText appendCloseBodyTag() {
110        text.closeElement(Message.BODY);
111        return this;
112    }
113
114    public static final String BR = "br";
115    public static final String CITE = "cite";
116    public static final String CODE = "code";
117
118    /**
119     * Appends a tag that inserts a single carriage return.
120     * 
121     */
122    public XHTMLText appendBrTag() {
123        text.emptyElement(BR);
124        return this;
125    }
126
127    /**
128     * Appends a tag that indicates a reference to work, such as a book, report or web site.
129     * 
130     */
131    public XHTMLText appendOpenCiteTag() {
132        text.openElement(CITE);
133        return this;
134    }
135
136    /**
137     * Appends a tag that indicates text that is the code for a program.
138     * 
139     */
140    public XHTMLText appendOpenCodeTag() {
141        text.openElement(CODE);
142        return this;
143    }
144
145    /**
146     * Appends a tag that indicates end of text that is the code for a program.
147     * 
148     */
149    public XHTMLText appendCloseCodeTag() {
150        text.closeElement(CODE);
151        return this;
152    }
153
154    public static final String EM = "em";
155
156    /**
157     * Appends a tag that indicates emphasis.
158     * 
159     */
160    public XHTMLText appendOpenEmTag() {
161        text.openElement(EM);
162        return this;
163    }
164
165    /**
166     * Appends a tag that indicates end of emphasis.
167     * 
168     */
169    public XHTMLText appendCloseEmTag() {
170        text.closeElement(EM);
171        return this;
172    }
173
174    public static final String H = "h";
175
176    /**
177     * Appends a tag that indicates a header, a title of a section of the message.
178     * 
179     * @param level the level of the Header. It must be a value between 1 and 3
180     * @param style the XHTML style of the blockquote
181     */
182    public XHTMLText appendOpenHeaderTag(int level, String style) {
183        if (level > 3 || level < 1) {
184            throw new IllegalArgumentException("Level must be between 1 and 3");
185        }
186        text.halfOpenElement(H + Integer.toString(level));
187        text.optAttribute(STYLE, style);
188        text.rightAngleBracket();
189        return this;
190    }
191
192    /**
193     * Appends a tag that indicates that a header section ends.
194     * 
195     * @param level the level of the Header. It must be a value between 1 and 3
196     */
197    public XHTMLText appendCloseHeaderTag(int level) {
198        if (level > 3 || level < 1) {
199            throw new IllegalArgumentException("Level must be between 1 and 3");
200        }
201        text.closeElement(H + Integer.toBinaryString(level));
202        return this;
203    }
204
205    public static final String IMG = "img";
206
207    /**
208     * Appends a tag that indicates an image.
209     * 
210     * @param align how text should flow around the picture
211     * @param alt the text to show if you don't show the picture
212     * @param height how tall is the picture
213     * @param src where to get the picture
214     * @param width how wide is the picture
215     */
216    public XHTMLText appendImageTag(String align, String alt, String height, String src, String width) {
217        text.halfOpenElement(IMG);
218        text.optAttribute("align", align);
219        text.optAttribute("alt", alt);
220        text.optAttribute("height", height);
221        text.optAttribute("src", src);
222        text.optAttribute("width", width);
223        text.rightAngleBracket();
224        return this;
225    }
226
227    public static final String LI = "li";
228    public static final String OL = "ol";
229
230    /**
231     * Appends a tag that indicates the start of a new line item within a list.
232     * 
233     * @param style the style of the line item
234     */
235    public XHTMLText appendLineItemTag(String style) {
236        text.halfOpenElement(LI);
237        text.optAttribute(STYLE, style);
238        text.rightAngleBracket();
239        return this;
240    }
241
242    /**
243     * Appends a tag that indicates that a line item section ends.
244     *
245     */
246    public XHTMLText appendCloseLineItemTag() {
247        text.closeElement(LI);
248        return this;
249    }
250
251    /**
252     * Appends a tag that creates an ordered list. "Ordered" means that the order of the items 
253     * in the list is important. To show this, browsers automatically number the list. 
254     * 
255     * @param style the style of the ordered list
256     */
257    public XHTMLText appendOpenOrderedListTag(String style) {
258        text.halfOpenElement(OL);
259        text.optAttribute(STYLE, style);
260        text.rightAngleBracket();
261        return this;
262    }
263
264    /**
265     * Appends a tag that indicates that an ordered list section ends.
266     * 
267     */
268    public XHTMLText appendCloseOrderedListTag() {
269        text.closeElement(OL);
270        return this;
271    }
272
273    public static final String UL = "ul";
274
275    /**
276     * Appends a tag that creates an unordered list. The unordered part means that the items 
277     * in the list are not in any particular order.
278     * 
279     * @param style the style of the unordered list
280     */
281    public XHTMLText appendOpenUnorderedListTag(String style) {
282        text.halfOpenElement(UL);
283        text.optAttribute(STYLE, style);
284        text.rightAngleBracket();
285        return this;
286    }
287
288    /**
289     * Appends a tag that indicates that an unordered list section ends.
290     * 
291     */
292    public XHTMLText appendCloseUnorderedListTag() {
293        text.closeElement(UL);
294        return this;
295    }
296
297    public static final String P = "p";
298
299    /**
300     * Appends a tag that indicates the start of a new paragraph. This is usually rendered 
301     * with two carriage returns, producing a single blank line in between the two paragraphs.
302     * 
303     * @param style the style of the paragraph
304     */
305    public XHTMLText appendOpenParagraphTag(String style) {
306        text.halfOpenElement(P);
307        text.optAttribute(STYLE, style);
308        text.rightAngleBracket();
309        return this;
310    }
311
312    /**
313     * Appends a tag that indicates the end of a new paragraph. This is usually rendered 
314     * with two carriage returns, producing a single blank line in between the two paragraphs.
315     * 
316     */
317    public XHTMLText appendCloseParagraphTag() {
318        text.closeElement(P);
319        return this;
320    }
321
322    public static final String Q = "q";
323
324    /**
325     * Appends a tag that indicates that an inlined quote section begins.
326     * 
327     * @param style the style of the inlined quote
328     */
329    public XHTMLText appendOpenInlinedQuoteTag(String style) {
330        text.halfOpenElement(Q);
331        text.optAttribute(STYLE, style);
332        text.rightAngleBracket();
333        return this;
334    }
335
336    /**
337     * Appends a tag that indicates that an inlined quote section ends.
338     * 
339     */
340    public XHTMLText appendCloseInlinedQuoteTag() {
341        text.closeElement(Q);
342        return this;
343    }
344
345    public static final String SPAN = "span";
346
347    /**
348     * Appends a tag that allows to set the fonts for a span of text.
349     * 
350     * @param style the style for a span of text
351     */
352    public XHTMLText appendOpenSpanTag(String style) {
353        text.halfOpenElement(SPAN);
354        text.optAttribute(STYLE, style);
355        text.rightAngleBracket();
356        return this;
357    }
358
359    /**
360     * Appends a tag that indicates that a span section ends.
361     * 
362     */
363    public XHTMLText appendCloseSpanTag() {
364        text.closeElement(SPAN);
365        return this;
366    }
367
368    public static final String STRONG = "strong";
369
370    /**
371     * Appends a tag that indicates text which should be more forceful than surrounding text.
372     * 
373     */
374    public XHTMLText appendOpenStrongTag() {
375        text.openElement(STRONG);
376        return this;
377    }
378
379    /**
380     * Appends a tag that indicates that a strong section ends.
381     * 
382     */
383    public XHTMLText appendCloseStrongTag() {
384        text.closeElement(STRONG);
385        return this;
386    }
387
388    /**
389     * Appends a given text to the XHTMLText.
390     * 
391     * @param textToAppend the text to append   
392     */
393    public XHTMLText append(String textToAppend) {
394        text.escape(textToAppend);
395        return this;
396    }
397
398    /**
399     * Returns the text of the XHTMLText.
400     * 
401     * @return the text of the XHTMLText   
402     */
403    public String toString() {
404        return text.toString();
405    }
406
407    public XmlStringBuilder toXML() {
408        return text;
409    }
410}