/* * Copyright (C) 2015. Jared Rummler <me@jaredrummler.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.jaredrummler.android.processes.sample.utils; import android.text.Html; import android.text.Spanned; import android.widget.TextView; import java.util.Iterator; import java.util.LinkedList; /** * <p>Build a valid HTML string for a {@link TextView}.</p> * * <p>Example usage:</p> * * <pre> * <code> * HtmlBuilder html = new HtmlBuilder() * .p() * .b() * .font().color("red").face("sans-serif-condensed").text("Hello").close() * .close() * .close(); * * // html.toString(): * // <p><b><font color="red" face="sans-serif-condensed">Hello</font></b></p> * * yourEditText.setText(html.toSpan()); * </code> * </pre> * * <p>HTML Tags Supported by {@link TextView}:</p> * * <ul> * <li><code><a href="..."></code></li> * <li><code><b></code></li> * <li><code><big></code></li> * <li><code><blockquote></code></li> * <li><code><br></code></li> * <li><code><cite></code></li> * <li><code><dfn></code></li> * <li><code><div align="..."></code></li> * <li><code><em></code></li> * <li><code><font color="..." face="..."></code></li> * <li><code><h1></code></li> * <li><code><h2></code></li> * <li><code><h3></code></li> * <li><code><h4></code></li> * <li><code><h5></code></li> * <li><code><h6></code></li> * <li><code><i></code></li> * <li><code><img src="..."></code></li> * <li><code><p></code></li> * <li><code><small></code></li> * <li><code><strike></code></li> * <li><code><strong></code></li> * <li><code><sub></code></li> * <li><code><sup></code></li> * <li><code><tt></code></li> * <li><code><u></code></li> * </ul> */ public class HtmlBuilder { private final StringBuilder html = new StringBuilder(); private final LinkedList<String> tags = new LinkedList<>(); public HtmlBuilder open(String element, String data) { tags.add(element); html.append('<'); html.append(element); if (data != null) { html.append(' ').append(data); } html.append('>'); return this; } public HtmlBuilder open(String element) { return open(element, null); } public HtmlBuilder open(char element) { return open(String.valueOf(element)); } public HtmlBuilder close(String element) { html.append("</").append(element).append('>'); for (Iterator<String> iterator = tags.iterator(); iterator.hasNext(); ) { if (iterator.next().equals(element)) { iterator.remove(); break; } } return this; } public HtmlBuilder close() { if (tags.isEmpty()) { return this; } html.append("</").append(tags.removeFirst()).append('>'); return this; } public HtmlBuilder close(char element) { return close(String.valueOf(element)); } public HtmlBuilder append(boolean b) { html.append(b); return this; } public HtmlBuilder append(char c) { html.append(c); return this; } public HtmlBuilder append(int i) { html.append(i); return this; } public HtmlBuilder append(long l) { html.append(l); return this; } public HtmlBuilder append(float f) { html.append(f); return this; } public HtmlBuilder append(double d) { html.append(d); return this; } public HtmlBuilder append(Object obj) { html.append(obj); return this; } public HtmlBuilder append(String str) { html.append(str); return this; } public HtmlBuilder append(StringBuffer sb) { html.append(sb); return this; } public HtmlBuilder append(char[] chars) { html.append(chars); return this; } public HtmlBuilder append(char[] str, int offset, int len) { html.append(str, offset, len); return this; } public HtmlBuilder append(CharSequence csq) { html.append(csq); return this; } public HtmlBuilder append(CharSequence csq, int start, int end) { html.append(csq, start, end); return this; } public HtmlBuilder append(Tag tag) { html.append(tag.toString()); return this; } public HtmlBuilder a(String href, String text) { return append(String.format("<a href=\"%s\">%s</a>", href, text)); } public HtmlBuilder b() { return open('b'); } public HtmlBuilder b(String text) { html.append("<b>").append(text).append("</b>"); return this; } public HtmlBuilder big() { return open("big"); } public HtmlBuilder big(String text) { html.append("<big>").append(text).append("</big>"); return this; } public HtmlBuilder blockquote() { return open("blockquote"); } public HtmlBuilder blockquote(String text) { html.append("<blockquote>").append(text).append("</blockquote>"); return this; } public HtmlBuilder br() { html.append("<br>"); return this; } public HtmlBuilder cite() { return open("cite"); } public HtmlBuilder cite(String text) { html.append("<cite>").append(text).append("</cite>"); return this; } public HtmlBuilder dfn() { return open("dfn"); } public HtmlBuilder dfn(String text) { html.append("<dfn>").append(text).append("</dfn>"); return this; } public HtmlBuilder div() { return open("div"); } public HtmlBuilder div(String align) { html.append(String.format("<div align=\"%s\">", align)); tags.add("div"); return this; } public HtmlBuilder em() { return open("em"); } public HtmlBuilder em(String text) { html.append("<em>").append(text).append("</em>"); return this; } public Font font() { return new Font(this); } public HtmlBuilder font(int color, String text) { return font().color(color).text(text).close(); } public HtmlBuilder font(String face, String text) { return font().face(face).text(text).close(); } public HtmlBuilder h1() { return open("h1"); } public HtmlBuilder h1(String text) { html.append("<h1>").append(text).append("</h1>"); return this; } public HtmlBuilder h2() { return open("h2"); } public HtmlBuilder h2(String text) { html.append("<h2>").append(text).append("</h2>"); return this; } public HtmlBuilder h3() { return open("h3"); } public HtmlBuilder h3(String text) { html.append("<h3>").append(text).append("</h3>"); return this; } public HtmlBuilder h4() { return open("h4"); } public HtmlBuilder h4(String text) { html.append("<h4>").append(text).append("</h4>"); return this; } public HtmlBuilder h5() { return open("h5"); } public HtmlBuilder h5(String text) { html.append("<h5>").append(text).append("</h5>"); return this; } public HtmlBuilder h6() { return open("h6"); } public HtmlBuilder h6(String text) { html.append("<h6>").append(text).append("</h6>"); return this; } public HtmlBuilder i() { return open('i'); } public HtmlBuilder i(String text) { html.append("<i>").append(text).append("</i>"); return this; } public Img img() { return new Img(this); } public HtmlBuilder img(String src) { return img().src(src).close(); } public HtmlBuilder p() { return open('p'); } public HtmlBuilder p(String text) { html.append("<p>").append(text).append("</p>"); return this; } public HtmlBuilder small() { return open("small"); } public HtmlBuilder small(String text) { html.append("<small>").append(text).append("</small>"); return this; } public HtmlBuilder strike() { return open("strike"); } public HtmlBuilder strike(String text) { html.append("<strike>").append(text).append("</strike>"); return this; } public HtmlBuilder strong() { return open("strong"); } public HtmlBuilder strong(String text) { html.append("<strong>").append(text).append("</strong>"); return this; } public HtmlBuilder sub() { return open("sub"); } public HtmlBuilder sub(String text) { html.append("<sub>").append(text).append("</sub>"); return this; } public HtmlBuilder sup() { return open("sup"); } public HtmlBuilder sup(String text) { html.append("<sup>").append(text).append("</sup>"); return this; } public HtmlBuilder tt() { return open("tt"); } public HtmlBuilder tt(String text) { html.append("<tt>").append(text).append("</tt>"); return this; } public HtmlBuilder u() { return open('u'); } public HtmlBuilder u(String text) { html.append("<u>").append(text).append("</u>"); return this; } public Spanned toSpan() { return Html.fromHtml(html.toString()); } @Override public String toString() { return html.toString(); } public static class Tag { protected final HtmlBuilder builder; protected final String element; protected String separator = ""; public Tag(HtmlBuilder builder, String element) { this.builder = builder; this.element = element; open(); } protected void open() { builder.append('<').append(element).append(' '); } public HtmlBuilder close() { return builder.append("</").append(element).append('>'); } @Override public String toString() { return builder.toString(); } } public static class Font extends Tag { public Font() { this(new HtmlBuilder()); } public Font(HtmlBuilder builder) { super(builder, "font"); } public Font size(int size) { builder.append(separator).append("size=\"").append(size).append('\"'); separator = " "; return this; } public Font size(String size) { builder.append(separator).append("size=\"").append(size).append('\"'); separator = " "; return this; } public Font color(int color) { return color(String.format("#%06X", (0xFFFFFF & color))); } public Font color(String color) { builder.append(separator).append("color=\"").append(color).append('\"'); separator = " "; return this; } public Font face(String face) { builder.append(separator).append("face=\"").append(face).append('\"'); separator = " "; return this; } public Font text(String text) { builder.append('>').append(text); return this; } } public static class Img extends Tag { public Img() { this(new HtmlBuilder()); } public Img(HtmlBuilder builder) { super(builder, "img"); } public Img src(String src) { builder.append(separator).append("src=\"").append(src).append('\"'); separator = " "; return this; } public Img alt(String alt) { builder.append(separator).append("alt=\"").append(alt).append('\"'); separator = " "; return this; } public Img height(String height) { builder.append(separator).append("height=\"").append(height).append('\"'); separator = " "; return this; } public Img height(int height) { builder.append(separator).append("height=\"").append(height).append('\"'); separator = " "; return this; } public Img width(String width) { builder.append(separator).append("width=\"").append(width).append('\"'); separator = " "; return this; } public Img width(int width) { builder.append(separator).append("width=\"").append(width).append('\"'); separator = " "; return this; } @Override public HtmlBuilder close() { return builder.append('>'); } } }