<NME> UnknownTagsHandler.java
<BEF> package cgeo.geocaching.utils;

import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.R;

import android.text.Editable;
import android.text.Html.TagHandler;
import android.text.Spanned;
import android.text.style.StrikethroughSpan;
public class UnknownTagsHandler implements TagHandler {

    private static final int UNDEFINED_POSITION = -1;
    int strikePos = UNDEFINED_POSITION;
    private boolean tableDetected = false;

    }

    private static final int UNDEFINED_POSITION = -1;

    private int countCells = 0;
    private int strikePos = UNDEFINED_POSITION;
    private boolean problematicDetected = false;
    private int listIndex = 0;
    private ListType listType = ListType.Unordered;

    @Override
    public void handleTag(final boolean opening, final String tag, final Editable output,
                          final XMLReader xmlReader) {
        if ("strike".equalsIgnoreCase(tag) || "s".equals(tag)) {
            handleStrike(opening, output);
        } else if ("table".equalsIgnoreCase(tag)) {
            handleProblematic();
        } else if ("td".equalsIgnoreCase(tag) || "th".equalsIgnoreCase(tag)) {
            handleTd(opening, output);
        } else if ("tr".equalsIgnoreCase(tag)) {
            handleTr(opening, output);
        } else if ("pre".equalsIgnoreCase(tag)) {
            handleProblematic();
        } else if ("ol".equalsIgnoreCase(tag)) {
            handleOl(opening);
        } else if ("li".equalsIgnoreCase(tag)) {
            handleLi(opening, output);
        } else if ("dt".equalsIgnoreCase(tag)) {
            handleDT(opening, output);
        } else if ("dd".equalsIgnoreCase(tag)) {
            handleDD(output);
    }

    private static void handleTd(boolean opening, Editable output) {
        // insert space for each table column
        if (opening) {
            output.insert(output.length(), " ");
        }
    }

    private static void handleTr(boolean opening, Editable output) {
        // insert new line for each table row
        if (opening) {
            output.insert(output.length(), "\n");
        }
    }

    private void handleProblematic() {
        problematicDetected = true;
    }

    private void handleTd(final boolean opening, final Editable output) {
        // insert bar for each table column, see https://en.wikipedia.org/wiki/Box-drawing_characters
        if (opening && countCells++ > 0) {
            output.append(CgeoApplication.getInstance().getString(R.string.triple_dash_vertical));
        }
    }

    private void handleTr(final boolean opening, final Editable output) {
        // insert new line for each table row
        if (opening) {
            output.append('\n');
            countCells = 0;
        }
    }

    // Ordered lists are handled in a simple manner. They are rendered as Arabic numbers starting at 1
    // with no handling for alpha or Roman numbers or arbitrary numbering.
    private void handleOl(final boolean opening) {
        if (opening) {
            listIndex = 1;
            listType = ListType.Ordered;
        } else {
            listType = ListType.Unordered;
        }
    }

    private void handleDT(final boolean opening, final Editable output) {
        output.append(opening ? "\n>> " : "");
    }

    private void handleDD(final Editable output) {
        output.append("\n");
    }

    private void handleLi(final boolean opening, final Editable output) {
        if (opening) {
            if (listType == ListType.Ordered) {
                output.append("\n  ").append(String.valueOf(listIndex++)).append(". ");
            } else {
                output.append("\n  • ");
            }
        }
    }

    private static void handleHr(final boolean opening, final Editable output) {
        if (opening) {
            // If we are in the middle of a line, add a line feed.
            if (output.length() > 0 && output.charAt(output.length() - 1) != '\n') {
                output.append('\n');
            }
            final int start = output.length();
            output.append("                              ");
            output.setSpan(new StrikethroughSpan(), start, output.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            output.append("\n");
        }
    }

}

<MSG> #965: use box drawing characters for table
<DFF> @@ -10,6 +10,7 @@ import android.text.style.StrikethroughSpan;
 public class UnknownTagsHandler implements TagHandler {
 
     private static final int UNDEFINED_POSITION = -1;
+    private static int countCells = 0;
     int strikePos = UNDEFINED_POSITION;
     private boolean tableDetected = false;
 
@@ -47,16 +48,19 @@ public class UnknownTagsHandler implements TagHandler {
     }
 
     private static void handleTd(boolean opening, Editable output) {
-        // insert space for each table column
+        // insert bar for each table column, see https://en.wikipedia.org/wiki/Box-drawing_characters
         if (opening) {
-            output.insert(output.length(), " ");
+            if (countCells++ > 0) {
+                output.append('┆');
+            }
         }
     }
 
     private static void handleTr(boolean opening, Editable output) {
         // insert new line for each table row
         if (opening) {
-            output.insert(output.length(), "\n");
+            output.append('\n');
+            countCells = 0;
         }
     }
 

#965: use box drawing characters for table