/*#######################################################
*
* Maintained by Gregor Santner, 2018-
* https://gsantner.net/
*
* License: Apache 2.0 / Commercial
* https://github.com/gsantner/opoc/#licensing
* https://www.apache.org/licenses/LICENSE-2.0
*
#########################################################*/
/*
* Parses most common markdown tags. Only inline tags are supported, multiline/block syntax
* is not supported (citation, multiline code, ..). This is intended to stay as easy as possible.
*
* You can e.g. apply a accent color by replacing #000001 with your accentColor string.
*
* FILTER_ANDROID_TEXTVIEW output is intended to be used at simple Android TextViews,
* were a limited set of _html tags is supported. This allow to still display e.g. a simple
* CHANGELOG.md file without including a WebView for showing HTML, or other additional UI-libraries.
*
* FILTER_WEB is intended to be used at engines understanding most common HTML tags.
*/
package net.gsantner.opoc.format.markdown;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* Simple Markdown Parser
*/
@SuppressWarnings({"WeakerAccess", "CaughtExceptionImmediatelyRethrown", "SameParameterValue", "unused", "SpellCheckingInspection", "RepeatedSpace", "SingleCharAlternation", "Convert2Lambda"})
public class SimpleMarkdownParser {
//########################
//## Statics
//########################
public interface SmpFilter {
String filter(String text);
}
public final static SmpFilter FILTER_ANDROID_TEXTVIEW = new SmpFilter() {
@Override
public String filter(String text) {
// TextView supports a limited set of html tags, most notably
// a href, b, big, font size&color, i, li, small, u
// Don't start new line if 2 empty lines and heading
while (text.contains("\n\n#")) {
text = text.replace("\n\n#", "\n#");
}
return text
.replaceAll("(?s)", "") // HTML comments
.replace("\n\n", "\n
\n") // Start new line if 2 empty lines
.replace("~°", " ") // double space/half tab
.replaceAll("(?m)^### (.*)$", "
$1
") // h3
.replaceAll("(?m)^## (.*)$", "
$1
") // h2 (DEP: h3)
.replaceAll("(?m)^# (.*)$", "
$1
") // h1 (DEP: h2,h3)
.replaceAll("!\\[(.*?)\\]\\((.*?)\\)", "$1") // img
.replaceAll("\\[(.*?)\\]\\((.*?)\\)", "$1") // a href (DEP: img)
.replaceAll("<(http|https):\\/\\/(.*)>", "$1://$2") // a href (DEP: img)
.replaceAll("(?m)^([-*] )(.*)$", "• $2
") // unordered list + end line
.replaceAll("(?m)^ (-|\\*) ([^<]*)$", " • $2
") // unordered list2 + end line
.replaceAll("`([^<]*)`", "$1") // code
.replace("\\*", "●") // temporary replace escaped star symbol
.replaceAll("(?m)\\*\\*(.*)\\*\\*", "$1") // bold (DEP: temp star)
.replaceAll("(?m)\\*(.*)\\*", "$1") // italic (DEP: temp star code)
.replace("●", "*") // restore escaped star symbol (DEP: b,i)
.replaceAll("(?m) $", "
") // new line (DEP: ul)
;
}
};
public final static SmpFilter FILTER_WEB = new SmpFilter() {
@Override
public String filter(String text) {
// Don't start new line if 2 empty lines and heading
while (text.contains("\n\n#")) {
text = text.replace("\n\n#", "\n#");
}
text = text
.replaceAll("(?s)", "") // HTML comments
.replace("\n\n", "\n
\n") // Start new line if 2 empty lines
.replaceAll("~°", " ") // double space/half tab
.replaceAll("(?m)^### (.*)$", "
$1
") // code
.replace("\\*", "●") // temporary replace escaped star symbol
.replaceAll("(?m)\\*\\*(.*)\\*\\*", "$1") // bold (DEP: temp star)
.replaceAll("(?m)\\*(.*)\\*", "$1") // italic (DEP: temp star code)
.replace("●", "*") // restore escaped star symbol (DEP: b,i)
.replaceAll("(?m) $", "