test_class.file: collect_app/src/test/java/org/odk/collect/android/utilities/TextUtilsTest.java
test_class.identifier: TextUtilsTest
test_case.body: @Test
      public void markDownToHtml_EscapesLessThan() {
          String[][] tests = {
                  {"<1", "&lt;1"},
                  {"<1>", "&lt;1>"},
                  {"< span>", "&lt; span>"},
                  {"< 1", "&lt; 1"},
                  {"< 1/>", "&lt; 1/>"},
                  {"test< 1/>", "test&lt; 1/>"},
                  {"test < 1/>", "test &lt; 1/>"}
          };
          for (String[] testCase: tests) {
              assertEquals(testCase[1], TextUtils.markdownToHtml(testCase[0]));
          }
      }
test_case.class_method_signature: TextUtilsTest.markDownToHtml_EscapesLessThan()
test_case.full_signature: @Test public void markDownToHtml_EscapesLessThan()
test_case.identifier: markDownToHtml_EscapesLessThan
test_case.invocations: assertEquals markdownToHtml
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void markDownToHtml_EscapesLessThan()
focal_class.declarator: createHeader = new ReplaceCallback.Callback() {
          public String matchFound(MatchResult match) {
              int level = match.group(1).length();
              return "<h" + level + ">" + match.group(2).replaceAll("#+$", "").trim() + "</h" + level
                      + ">";
          }
      }
focal_class.modifier: private static
focal_class.original_string: private static ReplaceCallback.Callback createHeader = new ReplaceCallback.Callback() {
          public String matchFound(MatchResult match) {
              int level = match.group(1).length();
              return "<h" + level + ">" + match.group(2).replaceAll("#+$", "").trim() + "</h" + level
                      + ">";
          }
      };
focal_class.type: ReplaceCallback.Callback
focal_class.var_name: createHeader
focal_class.declarator: createParagraph = new ReplaceCallback.Callback() {
          public String matchFound(MatchResult match) {
              String trimmed = match.group(1).trim();
              if (trimmed.matches("(?i)^<\\/?(h|p|bl)")) {
                  return match.group(1);
              }
              return "<p>" + trimmed + "</p>";
          }
      }
focal_class.modifier: private static
focal_class.original_string: private static ReplaceCallback.Callback createParagraph = new ReplaceCallback.Callback() {
          public String matchFound(MatchResult match) {
              String trimmed = match.group(1).trim();
              if (trimmed.matches("(?i)^<\\/?(h|p|bl)")) {
                  return match.group(1);
              }
              return "<p>" + trimmed + "</p>";
          }
      };
focal_class.type: ReplaceCallback.Callback
focal_class.var_name: createParagraph
focal_class.declarator: createSpan = new ReplaceCallback.Callback() {
          public String matchFound(MatchResult match) {
              String attributes = sanitizeAttributes(match.group(1));
              return "<font" + attributes + ">" + match.group(2).trim() + "</font>";
          }
  
          // throw away all styles except for color and font-family
          private String sanitizeAttributes(String attributes) {
  
              String stylesText = attributes.replaceAll("style=[\"'](.*?)[\"']", "$1");
              String[] styles = stylesText.trim().split(";");
              StringBuffer stylesOutput = new StringBuffer();
  
              for (String style : styles) {
                  String[] stylesAttributes = style.trim().split(":");
                  if (stylesAttributes[0].equals("color")) {
                      stylesOutput.append(" color=\"" + stylesAttributes[1] + "\"");
                  }
                  if (stylesAttributes[0].equals("font-family")) {
                      stylesOutput.append(" face=\"" + stylesAttributes[1] + "\"");
                  }
              }
  
              return stylesOutput.toString();
          }
      }
focal_class.modifier: private static
focal_class.original_string: private static ReplaceCallback.Callback createSpan = new ReplaceCallback.Callback() {
          public String matchFound(MatchResult match) {
              String attributes = sanitizeAttributes(match.group(1));
              return "<font" + attributes + ">" + match.group(2).trim() + "</font>";
          }
  
          // throw away all styles except for color and font-family
          private String sanitizeAttributes(String attributes) {
  
              String stylesText = attributes.replaceAll("style=[\"'](.*?)[\"']", "$1");
              String[] styles = stylesText.trim().split(";");
              StringBuffer stylesOutput = new StringBuffer();
  
              for (String style : styles) {
                  String[] stylesAttributes = style.trim().split(":");
                  if (stylesAttributes[0].equals("color")) {
                      stylesOutput.append(" color=\"" + stylesAttributes[1] + "\"");
                  }
                  if (stylesAttributes[0].equals("font-family")) {
                      stylesOutput.append(" face=\"" + stylesAttributes[1] + "\"");
                  }
              }
  
              return stylesOutput.toString();
          }
      };
focal_class.type: ReplaceCallback.Callback
focal_class.var_name: createSpan
focal_class.file: collect_app/src/main/java/org/odk/collect/android/utilities/TextUtils.java
focal_class.identifier: TextUtils
focal_class.class_method_signature: TextUtils.TextUtils()
focal_class.full_signature: private  TextUtils()
focal_class.identifier: TextUtils
focal_class.modifiers: private
focal_class.parameters: ()
focal_class.signature:  TextUtils()
focal_class.class_method_signature: TextUtils.markdownToHtml(String text)
focal_class.full_signature: protected static String markdownToHtml(String text)
focal_class.identifier: markdownToHtml
focal_class.modifiers: protected static
focal_class.parameters: (String text)
focal_class.return: String
focal_class.signature: String markdownToHtml(String text)
focal_class.class_method_signature: TextUtils.textToHtml(String text)
focal_class.full_signature: public static CharSequence textToHtml(String text)
focal_class.identifier: textToHtml
focal_class.modifiers: public static
focal_class.parameters: (String text)
focal_class.return: CharSequence
focal_class.signature: CharSequence textToHtml(String text)
focal_class.class_method_signature: TextUtils.ellipsizeBeginning(String text)
focal_class.full_signature: public static String ellipsizeBeginning(String text)
focal_class.identifier: ellipsizeBeginning
focal_class.modifiers: public static
focal_class.parameters: (String text)
focal_class.return: String
focal_class.signature: String ellipsizeBeginning(String text)
focal_class.class_method_signature: TextUtils.join(@NonNull CharSequence delimiter, @NonNull Iterable tokens)
focal_class.full_signature: public static String join(@NonNull CharSequence delimiter, @NonNull Iterable tokens)
focal_class.identifier: join
focal_class.modifiers: public static
focal_class.parameters: (@NonNull CharSequence delimiter, @NonNull Iterable tokens)
focal_class.return: String
focal_class.signature: String join(@NonNull CharSequence delimiter, @NonNull Iterable tokens)
focal_method.body: protected static String markdownToHtml(String text) {
  
          text = text.replaceAll("<([^a-zA-Z/])", "&lt;$1");
          // https://github.com/enketo/enketo-transformer/blob/master/src/markdown.js
  
          // span - replaced &lt; and &gt; with <>
          text = ReplaceCallback.replace("(?s)<\\s?span([^\\/\n]*)>((?:(?!<\\/).)+)<\\/\\s?span\\s?>",
                  text, createSpan);
  
          //intermediary replacements keys for special characters, N/B: These symbols are not meant to be interpreted as markdown
          text = text.replaceAll("(?s)\\\\#", "&#35;");
          text = text.replaceAll("(?s)\\\\\\\\", "&#92;");
          text = text.replaceAll("(?s)\\\\_", "&#95;");
          text = text.replaceAll("(?s)\\\\\\*", "&#42;");
  
          // strong
          text = text.replaceAll("(?s)__(.*?)__", "<strong>$1</strong>");
          text = text.replaceAll("(?s)\\*\\*(.*?)\\*\\*", "<strong>$1</strong>");
  
          // emphasis
          text = text.replaceAll("(?s)_([^\\s][^_\n]*)_", "<em>$1</em>");
          text = text.replaceAll("(?s)\\*([^\\s][^\\*\n]*)\\*", "<em>$1</em>");
  
          // links
          text = text.replaceAll("(?s)\\[([^\\]]*)\\]\\(([^\\)]+)\\)",
                  "<a href=\"$2\" target=\"_blank\">$1</a>");
          // headers - requires ^ or breaks <font color="#f58a1f">color</font>
          text = ReplaceCallback.replace("(?s)^(#+)([^\n]*)$", text, createHeader);
          // paragraphs
          text = ReplaceCallback.replace("(?s)([^\n]+)\n", text, createParagraph);
  
          // replacing intermediary keys with the proper markdown symbols
          text = text.replaceAll("(?s)&#35;", "#");
          text = text.replaceAll("(?s)&#42;", "*");
          text = text.replaceAll("(?s)&#95;", "_");
          text = text.replaceAll("(?s)&#92;", "\\\\");
          return text;
      }
focal_method.class_method_signature: TextUtils.markdownToHtml(String text)
focal_method.full_signature: protected static String markdownToHtml(String text)
focal_method.identifier: markdownToHtml
focal_method.invocations: replaceAll replace replaceAll replaceAll replaceAll replaceAll replaceAll replaceAll replaceAll replaceAll replaceAll replace replace replaceAll replaceAll replaceAll replaceAll
focal_method.modifiers: protected static
focal_method.parameters: (String text)
focal_method.return: String
focal_method.signature: String markdownToHtml(String text)