@@ -52,9 +52,30 @@ public class HtmlTagHandler implements Html.TagHandler {
5252 /**
5353 * List indentation in pixels. Nested lists use multiple of this.
5454 */
55+ /**
56+ * Running HTML table string based off of the root table tag. Root table tag being the tag which
57+ * isn't embedded within any other table tag. Example:
58+ * <!-- This is the root level opening table tag. This is where we keep track of tables. -->
59+ * <table>
60+ * ...
61+ * <table> <!-- Non-root table tags -->
62+ * ...
63+ * </table>
64+ * ...
65+ * </table>
66+ * <!-- This is the root level closing table tag and the end of the string we track. -->
67+ */
68+ StringBuilder tableHtmlBuilder = new StringBuilder ();
69+ /**
70+ * Tells us which level of table tag we're on; ultimately used to find the root table tag.
71+ */
72+ int tableTagLevel = 0 ;
73+
5574 private static final int indent = 10 ;
5675 private static final int listItemIndent = indent * 2 ;
5776 private static final BulletSpan bullet = new BulletSpan (indent );
77+ private ClickableTableSpan mClickableTableSpan ;
78+ private DrawTableLinkSpan mDrawTableLinkSpan ;
5879
5980 private static class Ul {
6081 }
@@ -71,6 +92,18 @@ private static class Center {
7192 private static class Strike {
7293 }
7394
95+ private static class Table {
96+ }
97+
98+ private static class Tr {
99+ }
100+
101+ private static class Th {
102+ }
103+
104+ private static class Td {
105+ }
106+
74107 @ Override
75108 public void handleTag (final boolean opening , final String tag , Editable output , final XMLReader xmlReader ) {
76109 if (opening ) {
@@ -102,6 +135,23 @@ public void handleTag(final boolean opening, final String tag, Editable output,
102135 start (output , new Center ());
103136 } else if (tag .equalsIgnoreCase ("s" ) || tag .equalsIgnoreCase ("strike" )) {
104137 start (output , new Strike ());
138+ } else if (tag .equalsIgnoreCase ("table" )) {
139+ start (output , new Table ());
140+ if (tableTagLevel == 0 ) {
141+ tableHtmlBuilder = new StringBuilder ();
142+ // We need some text for the table to be replaced by the span because
143+ // the other tags will remove their text when their text is extracted
144+ output .append ("table placeholder" );
145+ }
146+
147+ tableTagLevel ++;
148+ }
149+ else if (tag .equalsIgnoreCase ("tr" )) {
150+ start (output , new Tr ());
151+ } else if (tag .equalsIgnoreCase ("th" )) {
152+ start (output , new Th ());
153+ } else if (tag .equalsIgnoreCase ("td" )) {
154+ start (output , new Td ());
105155 }
106156 } else {
107157 // closing tag
@@ -150,8 +200,55 @@ public void handleTag(final boolean opening, final String tag, Editable output,
150200 end (output , Center .class , true , new AlignmentSpan .Standard (Layout .Alignment .ALIGN_CENTER ));
151201 } else if (tag .equalsIgnoreCase ("s" ) || tag .equalsIgnoreCase ("strike" )) {
152202 end (output , Strike .class , false , new StrikethroughSpan ());
203+ } else if (tag .equalsIgnoreCase ("table" )) {
204+ tableTagLevel --;
205+
206+ // When we're back at the root-level table
207+ if (tableTagLevel == 0 ) {
208+ final String tableHtml = tableHtmlBuilder .toString ();
209+
210+ ClickableTableSpan clickableTableSpan = null ;
211+ if (mClickableTableSpan != null ) {
212+ clickableTableSpan = mClickableTableSpan .newInstance ();
213+ clickableTableSpan .setTableHtml (tableHtml );
214+ }
215+
216+ DrawTableLinkSpan drawTableLinkSpan = null ;
217+ if (mDrawTableLinkSpan != null ) {
218+ drawTableLinkSpan = mDrawTableLinkSpan .newInstance ();
219+ }
220+
221+ end (output , Table .class , false , drawTableLinkSpan , clickableTableSpan );
222+ } else {
223+ end (output , Table .class , false );
224+ }
225+ }
226+ else if (tag .equalsIgnoreCase ("tr" )) {
227+ end (output , Tr .class , false );
228+ } else if (tag .equalsIgnoreCase ("th" )) {
229+ end (output , Th .class , false );
230+ } else if (tag .equalsIgnoreCase ("td" )) {
231+ end (output , Td .class , false );
153232 }
154233 }
234+
235+ storeTableTags (opening , tag );
236+ }
237+
238+ /**
239+ * If we're arriving at a table tag or are already within a table tag, then we should store it
240+ * the raw HTML for our ClickableTableSpan
241+ */
242+ private void storeTableTags (boolean opening , String tag ) {
243+ if (tableTagLevel > 0 || tag .equalsIgnoreCase ("table" )) {
244+ tableHtmlBuilder .append ("<" );
245+ if (!opening ) {
246+ tableHtmlBuilder .append ("/" );
247+ }
248+ tableHtmlBuilder
249+ .append (tag .toLowerCase ())
250+ .append (">" );
251+ }
155252 }
156253
157254 /**
@@ -176,6 +273,12 @@ private void end(Editable output, Class kind, boolean paragraphStyle, Object...
176273 // end of the tag
177274 int len = output .length ();
178275
276+ // If we're in a table, then we need to store the raw HTML for later
277+ if (tableTagLevel > 0 ) {
278+ final CharSequence extractedSpanText = extractSpanText (output , kind );
279+ tableHtmlBuilder .append (extractedSpanText );
280+ }
281+
179282 output .removeSpan (obj );
180283
181284 if (where != len ) {
@@ -196,6 +299,21 @@ private void end(Editable output, Class kind, boolean paragraphStyle, Object...
196299 }
197300 }
198301
302+ /**
303+ * Returns the text contained within a span and deletes it from the output string
304+ */
305+ private CharSequence extractSpanText (Editable output , Class kind ) {
306+ final Object obj = getLast (output , kind );
307+ // start of the tag
308+ final int where = output .getSpanStart (obj );
309+ // end of the tag
310+ final int len = output .length ();
311+
312+ final CharSequence extractedSpanText = output .subSequence (where , len );
313+ output .delete (where , len );
314+ return extractedSpanText ;
315+ }
316+
199317 /**
200318 * Get last marked position of a specific tag kind (private class)
201319 */
@@ -213,4 +331,11 @@ private static Object getLast(Editable text, Class kind) {
213331 }
214332 }
215333
334+ public void setClickableTableSpan (ClickableTableSpan clickableTableSpan ) {
335+ this .mClickableTableSpan = clickableTableSpan ;
336+ }
337+
338+ public void setDrawTableLinkSpan (DrawTableLinkSpan drawTableLinkSpan ) {
339+ this .mDrawTableLinkSpan = drawTableLinkSpan ;
340+ }
216341}
0 commit comments