mirror of
https://github.com/gsantner/dandelion
synced 2024-11-21 20:02:07 +01:00
Update SimpleMarkdownParser
This commit is contained in:
parent
0e7ff63c9a
commit
99e369088a
10 changed files with 161 additions and 101 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,10 +1,10 @@
|
||||||
##############
|
##############
|
||||||
### Project ##
|
### Project ##
|
||||||
app/src/main/res/raw/changelog.md
|
app/src/main/res/raw/changelog.*
|
||||||
app/src/main/res/raw/contributors.md
|
app/src/main/res/raw/contributors.*
|
||||||
app/src/main/res/raw/license.md
|
app/src/main/res/raw/license.*
|
||||||
app/src/main/res/raw/readme.md
|
app/src/main/res/raw/readme.*
|
||||||
app/src/main/res/raw/contributors.txt
|
app/src/main/res/raw/contributors.*
|
||||||
#app/src/main/res/raw/podlist.json
|
#app/src/main/res/raw/podlist.json
|
||||||
|
|
||||||
##############
|
##############
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
### v1.0.1
|
||||||
|
- Update SimpleMarkdownParser
|
||||||
|
|
||||||
### v1.0.0 (2017-06-14)
|
### v1.0.0 (2017-06-14)
|
||||||
- Added AMOLED mode
|
- Added AMOLED mode
|
||||||
- Improve NavDrawer
|
- Improve NavDrawer
|
||||||
|
|
32
CONTRIBUTORS.md
Normal file
32
CONTRIBUTORS.md
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<!--
|
||||||
|
This file contains references to people who contributed to the app.
|
||||||
|
If you helped by translating the app, please send a message on Crowdin.
|
||||||
|
You can also send a mail to [gsantner AT mailbox DOT org](https://gsantner.github.io#contact) to get included.
|
||||||
|
|
||||||
|
Schema: **[Name](Reference)**<br/>~° Text
|
||||||
|
|
||||||
|
Where:
|
||||||
|
* Name: username, first/lastname
|
||||||
|
* Reference: E-Mail, Webpage
|
||||||
|
* Text: Information about / kind of contribution
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## LIST OF CONTRIBUTORS
|
||||||
|
-->
|
||||||
|
* **[Gregor Santner](https://gsantner.github.io)**<br/>~° Current developer of dandelion
|
||||||
|
* **[Paul Schaub](https://github.com/vanitasvitae)**<br/>~° Development of dandelion
|
||||||
|
* **[Abhijith Balan](abhijithb21 AT openmailbox DOT org)**<br/>~° Malayalam translation
|
||||||
|
* **[Airon90](https://diasp.eu/u/airon90)**<br/>~° Italian translation
|
||||||
|
* **[Gaukler Faun](https://github.com/scoute-dich)**<br/>~° Diaspora Native WebApp additions
|
||||||
|
* **[Martín Vukovic](martinvukovic AT protonmail DOT com)**<br/>~° Diaspora Native WebApp
|
||||||
|
* **[Nacho Fernández](nacho_f AT joindiaspora DOT com)**<br/>~° Spanish translation
|
||||||
|
* **[Naofumi Fukue](https://github.com/naofum)**<br/>~° Japanese translation
|
||||||
|
* **[pskosinski](email AT pskosinski DOT pl)**<br/>~° Polish translation
|
||||||
|
* **[SansPseudoFix](https://github.com/SansPseudoFix)**<br/>~° French translation
|
||||||
|
* **[secitem](secitem AT tuta DOT io)**<br/>~° Czech translation
|
||||||
|
* **[Zsolt Szakács](maxigaz AT diaspora DOT zone)**<br/>~° Hungarian translation
|
||||||
|
* **[Danilo Raffaelli](https://crowdin.com/profile/Daraf)**<br/>~° Italian translation
|
||||||
|
* **[O'Loubám](loubam AT diasp DOT org)**<br/>~° Galician translation
|
||||||
|
* **[transifex3](https://crowdin.com/profile/transifex3)**<br/>~° Korean translation
|
||||||
|
* **[Âng Iōngchun](https://pubpod.alqualonde.org/u/iongchun)**<br/>~° Chinese traditional translation
|
|
@ -1,24 +0,0 @@
|
||||||
00l>> This file contains references to people who contributed to the app.
|
|
||||||
01l>> If you helped by translating the app, please send a message on Crowdin.
|
|
||||||
02l>> You can also send a mail to [gdev AT live DOT de](https://gsantner.github.io/about/email/) to get included.
|
|
||||||
03l>>
|
|
||||||
04l>> Schemes:
|
|
||||||
05l>> Firstname Lastname (Link): Text
|
|
||||||
06l>> Firstname Lastname (E-Mail): Text
|
|
||||||
07l>> Username (Link): Text
|
|
||||||
08l>> Username (E-Mail): Text
|
|
||||||
## 99l CONTRIBUTORS
|
|
||||||
Abhijith Balan (abhijithb21 AT openmailbox DOT org): Malayalam translation
|
|
||||||
Airon90 (https://diasp.eu/u/airon90): Italian translation
|
|
||||||
Gaukler Faun (https://github.com/scoute-dich): Diaspora Native WebApp additions
|
|
||||||
Martín Vukovic (martinvukovic AT protonmail DOT com): Diaspora Native WebApp
|
|
||||||
Nacho Fernández (nacho_f AT joindiaspora DOT com): Spanish translation
|
|
||||||
Naofumi Fukue (https://github.com/naofum): Japanese translation
|
|
||||||
pskosinski (email AT pskosinski DOT pl): Polish translation
|
|
||||||
SansPseudoFix (https://github.com/SansPseudoFix): French translation
|
|
||||||
secitem (secitem AT tuta DOT io): Czech translation
|
|
||||||
Zsolt Szakács (maxigaz AT diaspora DOT zone): Hungarian translation
|
|
||||||
Danilo Raffaelli (https://crowdin.com/profile/Daraf): Italian translation
|
|
||||||
O'Loubám (loubam AT diasp DOT org): Galician translation
|
|
||||||
transifex3 (https://crowdin.com/profile/transifex3): Korean translation
|
|
||||||
Âng Iōngchun (https://pubpod.alqualonde.org/u/iongchun): Chinese traditional translation
|
|
|
@ -9,8 +9,8 @@ android {
|
||||||
minSdkVersion 17
|
minSdkVersion 17
|
||||||
targetSdkVersion 24
|
targetSdkVersion 24
|
||||||
|
|
||||||
versionCode 20
|
versionCode 21
|
||||||
versionName "1.0.0"
|
versionName "1.0.1-dev"
|
||||||
|
|
||||||
applicationId "com.github.dfa.diaspora_android"
|
applicationId "com.github.dfa.diaspora_android"
|
||||||
resValue 'string', 'app_name', "dandelion*"
|
resValue 'string', 'app_name', "dandelion*"
|
||||||
|
@ -86,7 +86,7 @@ dependencies {
|
||||||
// Groovy Coding Area
|
// Groovy Coding Area
|
||||||
// #####################
|
// #####################
|
||||||
final String RAW_DIR = "app/src/main/res/raw"
|
final String RAW_DIR = "app/src/main/res/raw"
|
||||||
final String[] ROOT_TO_RAW_COPYFILES = ["README.md", "LICENSE.md", "CHANGELOG.md", "CONTRIBUTORS.txt"]
|
final String[] ROOT_TO_RAW_COPYFILES = ["README.md", "LICENSE.md", "CHANGELOG.md", "CONTRIBUTORS.md"]
|
||||||
|
|
||||||
// Called before building
|
// Called before building
|
||||||
task copyRepoFiles(type: Copy) {
|
task copyRepoFiles(type: Copy) {
|
||||||
|
@ -97,16 +97,5 @@ task copyRepoFiles(type: Copy) {
|
||||||
rename { String fileName ->
|
rename { String fileName ->
|
||||||
fileName.replace(fileName, fileName.toLowerCase())
|
fileName.replace(fileName, fileName.toLowerCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter Contributors file
|
|
||||||
from(rootProject.file("CONTRIBUTORS.txt")) {
|
|
||||||
into '.' // Target already changed to 'src/main/res/raw'
|
|
||||||
rename { String fileName ->
|
|
||||||
fileName.replace(fileName, fileName.toLowerCase())
|
|
||||||
}
|
|
||||||
filter { line ->
|
|
||||||
(line.toString().matches("..l>>.*") || line.toString().startsWith("## 99l CONTRIBUTORS")) ? null : line.toString().trim().replaceAll(" \\(.*\\)", "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tasks.copyRepoFiles.execute()
|
tasks.copyRepoFiles.execute()
|
||||||
|
|
|
@ -268,7 +268,7 @@ public class AboutActivity extends ThemedActivity
|
||||||
maintainers.setTextFormatted(getString(R.string.fragment_license__maintainers_text,
|
maintainers.setTextFormatted(getString(R.string.fragment_license__maintainers_text,
|
||||||
Helpers.get().loadMarkdownForTextViewFromRaw(R.raw.maintainers, "")));
|
Helpers.get().loadMarkdownForTextViewFromRaw(R.raw.maintainers, "")));
|
||||||
contributors.setTextFormatted(getString(R.string.fragment_license__contributors_thank_you,
|
contributors.setTextFormatted(getString(R.string.fragment_license__contributors_thank_you,
|
||||||
Helpers.get().loadMarkdownForTextViewFromRaw(R.raw.contributors, "* ")));
|
Helpers.get().loadMarkdownForTextViewFromRaw(R.raw.contributors, "")));
|
||||||
thirdPartyLibs.setTextFormatted(
|
thirdPartyLibs.setTextFormatted(
|
||||||
Helpers.get().loadMarkdownForTextViewFromRaw(R.raw.license_third_party, ""));
|
Helpers.get().loadMarkdownForTextViewFromRaw(R.raw.license_third_party, ""));
|
||||||
return rootView;
|
return rootView;
|
||||||
|
|
|
@ -221,22 +221,20 @@ public class MainActivity extends ThemedActivity
|
||||||
|
|
||||||
// Show first start dialog
|
// Show first start dialog
|
||||||
try {
|
try {
|
||||||
|
SimpleMarkdownParser mdParser = SimpleMarkdownParser.get().setDefaultSmpFilter(SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW);
|
||||||
if (appSettings.isAppFirstStart()) {
|
if (appSettings.isAppFirstStart()) {
|
||||||
SimpleMarkdownParser smp = new SimpleMarkdownParser().parse(
|
mdParser.parse(
|
||||||
getResources().openRawResource(R.raw.license),
|
getResources().openRawResource(R.raw.license), "");
|
||||||
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, "");
|
String html = mdParser.getHtml()
|
||||||
String html = smp.getHtml()
|
|
||||||
+ "<br/><br/><br/>"
|
+ "<br/><br/><br/>"
|
||||||
+ "<h1>" + getString(R.string.fragment_license__thirdparty_libs) + "</h1>"
|
+ "<h1>" + getString(R.string.fragment_license__thirdparty_libs) + "</h1>"
|
||||||
+ smp.parse(getResources().openRawResource(R.raw.license_third_party),
|
+ mdParser.parse(getResources().openRawResource(R.raw.license_third_party), "");
|
||||||
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, "");
|
html = mdParser.setHtml(html).removeMultiNewlines().getHtml();
|
||||||
html = smp.setHtml(html).removeMultiNewlines().getHtml();
|
|
||||||
HelpersA.get(this).showDialogWithHtmlTextView(R.string.about_activity__title_about_license, html);
|
HelpersA.get(this).showDialogWithHtmlTextView(R.string.about_activity__title_about_license, html);
|
||||||
appSettings.isAppCurrentVersionFirstStart();
|
appSettings.isAppCurrentVersionFirstStart();
|
||||||
} else if (appSettings.isAppCurrentVersionFirstStart()) {
|
} else if (appSettings.isAppCurrentVersionFirstStart()) {
|
||||||
SimpleMarkdownParser smp = new SimpleMarkdownParser().parse(
|
SimpleMarkdownParser smp = new SimpleMarkdownParser().parse(
|
||||||
getResources().openRawResource(R.raw.changelog),
|
getResources().openRawResource(R.raw.changelog), "");
|
||||||
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, "");
|
|
||||||
HelpersA.get(this).showDialogWithHtmlTextView(R.string.changelog, smp.getHtml());
|
HelpersA.get(this).showDialogWithHtmlTextView(R.string.changelog, smp.getHtml());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* worth it, you can buy me a coke in return. Provided as is without any kind
|
* worth it, you can buy me a coke in return. Provided as is without any kind
|
||||||
* of warranty. No attribution required. - Gregor Santner
|
* of warranty. No attribution required. - Gregor Santner
|
||||||
*
|
*
|
||||||
* License: Creative Commons Zero (CC0 1.0)
|
* License of this file: Creative Commons Zero (CC0 1.0)
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -32,19 +32,25 @@ import android.support.annotation.StringRes;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.widget.AppCompatButton;
|
import android.support.v7.widget.AppCompatButton;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.text.util.Linkify;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
import android.widget.TextView;
|
||||||
import com.github.dfa.diaspora_android.App;
|
|
||||||
import com.github.dfa.diaspora_android.BuildConfig;
|
|
||||||
import com.github.dfa.diaspora_android.R;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import com.github.dfa.diaspora_android.App;
|
||||||
|
import com.github.dfa.diaspora_android.BuildConfig;
|
||||||
|
import com.github.dfa.diaspora_android.R;
|
||||||
|
|
||||||
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue"})
|
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue"})
|
||||||
public class Helpers {
|
public class Helpers {
|
||||||
protected Context context;
|
protected Context context;
|
||||||
|
@ -177,7 +183,7 @@ public class Helpers {
|
||||||
try {
|
try {
|
||||||
return new SimpleMarkdownParser()
|
return new SimpleMarkdownParser()
|
||||||
.parse(context.getResources().openRawResource(rawMdFile),
|
.parse(context.getResources().openRawResource(rawMdFile),
|
||||||
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, prepend)
|
prepend, SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW)
|
||||||
.replaceColor("#000001", color(R.color.accent))
|
.replaceColor("#000001", color(R.color.accent))
|
||||||
.removeMultiNewlines().replaceBulletCharacter("*").getHtml();
|
.removeMultiNewlines().replaceBulletCharacter("*").getHtml();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -186,6 +192,17 @@ public class Helpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHtmlToTextView(TextView textView, String html) {
|
||||||
|
Spanned spanned;
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
||||||
|
spanned = Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
|
||||||
|
} else {
|
||||||
|
spanned = Html.fromHtml(html);
|
||||||
|
}
|
||||||
|
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
textView.setText(new SpannableString(spanned));
|
||||||
|
}
|
||||||
|
|
||||||
public double getEstimatedScreenSizeInches() {
|
public double getEstimatedScreenSizeInches() {
|
||||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* worth it, you can buy me a coke in return. Provided as is without any kind
|
* worth it, you can buy me a coke in return. Provided as is without any kind
|
||||||
* of warranty. No attribution required. - Gregor Santner
|
* of warranty. No attribution required. - Gregor Santner
|
||||||
*
|
*
|
||||||
* License: Creative Commons Zero (CC0 1.0)
|
* License of this file: Creative Commons Zero (CC0 1.0)
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,7 @@ import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.widget.AppCompatTextView;
|
import android.support.v7.widget.AppCompatTextView;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.method.ScrollingMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
|
@ -91,17 +91,17 @@ public class HelpersA extends Helpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDialogWithHtmlTextView(@StringRes int resTitleId, String html) {
|
public void showDialogWithHtmlTextView(@StringRes int resTitleId, String html) {
|
||||||
showDialogWithHtmlTextView(resTitleId, html, null);
|
showDialogWithHtmlTextView(resTitleId, html, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDialogWithHtmlTextView(@StringRes int resTitleId, String html, DialogInterface.OnDismissListener dismissedListener) {
|
public void showDialogWithHtmlTextView(@StringRes int resTitleId, String text, boolean isHtml, DialogInterface.OnDismissListener dismissedListener) {
|
||||||
AppCompatTextView textView = new AppCompatTextView(context);
|
AppCompatTextView textView = new AppCompatTextView(context);
|
||||||
int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16,
|
int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16,
|
||||||
context.getResources().getDisplayMetrics());
|
context.getResources().getDisplayMetrics());
|
||||||
textView.setMovementMethod(new ScrollingMovementMethod());
|
textView.setMovementMethod(new LinkMovementMethod());
|
||||||
textView.setPadding(padding, 0, padding, 0);
|
textView.setPadding(padding, 0, padding, 0);
|
||||||
|
|
||||||
textView.setText(new SpannableString(Html.fromHtml(html)));
|
textView.setText(isHtml ? new SpannableString(Html.fromHtml(text)) : text);
|
||||||
AlertDialog.Builder dialog = new AlertDialog.Builder(context)
|
AlertDialog.Builder dialog = new AlertDialog.Builder(context)
|
||||||
.setPositiveButton(android.R.string.ok, null)
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
.setOnDismissListener(dismissedListener)
|
.setOnDismissListener(dismissedListener)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* worth it, you can buy me a coke in return. Provided as is without any kind
|
* worth it, you can buy me a coke in return. Provided as is without any kind
|
||||||
* of warranty. No attribution required. - Gregor Santner
|
* of warranty. No attribution required. - Gregor Santner
|
||||||
*
|
*
|
||||||
* License: Creative Commons Zero (CC0 1.0)
|
* License of this file: Creative Commons Zero (CC0 1.0)
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -22,9 +22,9 @@
|
||||||
*
|
*
|
||||||
* FILTER_ANDROID_TEXTVIEW output is intended to be used at simple Android TextViews,
|
* 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
|
* were a limited set of html tags is supported. This allow to still display e.g. a simple
|
||||||
* CHANGELOG.md file without inlcuding a WebView for showing HTML, or other additional UI-libraries.
|
* CHANGELOG.md file without including a WebView for showing HTML, or other additional UI-libraries.
|
||||||
*
|
*
|
||||||
* FILTER_HTMLPART is intended to be used at engines understanding most common HTML tags.
|
* FILTER_WEB is intended to be used at engines understanding most common HTML tags.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.gsantner.opoc.util;
|
package io.github.gsantner.opoc.util;
|
||||||
|
@ -38,72 +38,105 @@ import java.io.InputStreamReader;
|
||||||
/**
|
/**
|
||||||
* Simple Markdown Parser
|
* Simple Markdown Parser
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"WeakerAccess", "CaughtExceptionImmediatelyRethrown"})
|
@SuppressWarnings({"WeakerAccess", "CaughtExceptionImmediatelyRethrown", "SameParameterValue", "unused", "SpellCheckingInspection", "RepeatedSpace", "SingleCharAlternation"})
|
||||||
public class SimpleMarkdownParser {
|
public class SimpleMarkdownParser {
|
||||||
public interface SimpleLineFilter {
|
private static SimpleMarkdownParser instance;
|
||||||
String filterLine(String line);
|
|
||||||
|
public static SimpleMarkdownParser get() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new SimpleMarkdownParser();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final SimpleLineFilter FILTER_ANDROID_TEXTVIEW = new SimpleLineFilter() {
|
public interface SmpFilter {
|
||||||
|
String filter(String text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static SmpFilter FILTER_ANDROID_TEXTVIEW = new SmpFilter() {
|
||||||
@Override
|
@Override
|
||||||
public String filterLine(String line) {
|
public String filter(String text) {
|
||||||
// TextView supports a limited set of html tags, most notably
|
// TextView supports a limited set of html tags, most notably
|
||||||
// a href, b, big, font size&color, i, li, small, u
|
// a href, b, big, font size&color, i, li, small, u
|
||||||
line = line
|
|
||||||
|
// 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<br/>\n") // Start new line if 2 empty lines
|
||||||
.replace("~°", " ") // double space/half tab
|
.replace("~°", " ") // double space/half tab
|
||||||
.replaceAll("^### ([^<]*)", "<br/><big><b><font color='#000000'>$1</font></b></big> ") // h3
|
.replaceAll("(?m)^### (.*)$", "<br/><big><b><font color='#000000'>$1</font></b></big><br/>") // h3
|
||||||
.replaceAll("^## ([^<]*)", "<br/><big><big><b><font color='#000000'>$1</font></b></big></big><br/> ") // h2 (DEP: h3)
|
.replaceAll("(?m)^## (.*)$", "<br/><big><big><b><font color='#000000'>$1</font></b></big></big><br/><br/>") // h2 (DEP: h3)
|
||||||
.replaceAll("^# ([^<]*)", "<br/><big><big><big><b><font color='#000000'>$1</font></b></big></big></big><br/> ") // h1 (DEP: h2,h3)
|
.replaceAll("(?m)^# (.*)$", "<br/><big><big><big><b><font color='#000000'>$1</font></b></big></big></big><br/><br/>") // h1 (DEP: h2,h3)
|
||||||
.replaceAll("!\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // img
|
.replaceAll("!\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // img
|
||||||
.replaceAll("\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // a href (DEP: img)
|
.replaceAll("\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // a href (DEP: img)
|
||||||
.replaceAll("<(http|https):\\/\\/(.*)>", "<a href='$1://$2'>$1://$2</a>") // a href (DEP: img)
|
.replaceAll("<(http|https):\\/\\/(.*)>", "<a href='$1://$2'>$1://$2</a>") // a href (DEP: img)
|
||||||
.replaceAll("^(-|\\*) ([^<]*)", "<font color='#000001'>•</font> $2 ") // unordered list + end line
|
.replaceAll("(?m)^([-*] )(.*)$", "<font color='#000001'>•</font> $2<br/>") // unordered list + end line
|
||||||
.replaceAll("^ (-|\\*) ([^<]*)", " <font color='#000001'>•</font> $2 ") // unordered list2 + end line
|
.replaceAll("(?m)^ (-|\\*) ([^<]*)$", " <font color='#000001'>•</font> $2<br/>") // unordered list2 + end line
|
||||||
.replaceAll("`([^<]*)`", "<font face='monospace'>$1</font>") // code
|
.replaceAll("`([^<]*)`", "<font face='monospace'>$1</font>") // code
|
||||||
.replace("\\*", "●") // temporary replace escaped star symbol
|
.replace("\\*", "●") // temporary replace escaped star symbol
|
||||||
.replaceAll("\\*\\*([^<]*)\\*\\*", "<b>$1</b>") // bold (DEP: temp star)
|
.replaceAll("(?m)\\*\\*(.*)\\*\\*", "<b>$1</b>") // bold (DEP: temp star)
|
||||||
.replaceAll("\\*([^<]*)\\*", "<i>$1</i>") // italic (DEP: temp star code)
|
.replaceAll("(?m)\\*(.*)\\*", "<i>$1</i>") // italic (DEP: temp star code)
|
||||||
.replace("●", "*") // restore escaped star symbol (DEP: b,i)
|
.replace("●", "*") // restore escaped star symbol (DEP: b,i)
|
||||||
.replaceAll(" $", "<br/>") // new line (DEP: ul)
|
.replaceAll("(?m) $", "<br/>") // new line (DEP: ul)
|
||||||
;
|
;
|
||||||
return line.isEmpty() ? line + "<br/>" : line;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final SimpleLineFilter FILTER_HTMLPART = new SimpleLineFilter() {
|
public final static SmpFilter FILTER_WEB = new SmpFilter() {
|
||||||
@Override
|
@Override
|
||||||
public String filterLine(String line) {
|
public String filter(String text) {
|
||||||
line = line
|
// 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<br/>\n") // Start new line if 2 empty lines
|
||||||
.replaceAll("~°", " ") // double space/half tab
|
.replaceAll("~°", " ") // double space/half tab
|
||||||
.replaceAll("^### ([^<]*)", "<h3>$1</h3>") // h3
|
.replaceAll("(?m)^### (.*)$", "<h3>$1</h3>") // h3
|
||||||
.replaceAll("^## ([^<]*)", "<h2>$1</h2>") /// h2 (DEP: h3)
|
.replaceAll("(?m)^## (.*)$", "<h2>$1</h2>") /// h2 (DEP: h3)
|
||||||
.replaceAll("^# ([^<]*)", "<h1>$1</h1>") // h1 (DEP: h2,h3)
|
.replaceAll("(?m)^# (.*)$", "<h1>$1</h1>") // h1 (DEP: h2,h3)
|
||||||
.replaceAll("!\\[(.*?)\\]\\((.*?)\\)", "<img src=\\'$2\\' alt='$1' />") // img
|
.replaceAll("!\\[(.*?)\\]\\((.*?)\\)", "<img src=\\'$2\\' alt='$1' />") // img
|
||||||
.replaceAll("<(http|https):\\/\\/(.*)>", "<a href='$1://$2'>$1://$2</a>") // a href (DEP: img)
|
.replaceAll("<(http|https):\\/\\/(.*)>", "<a href='$1://$2'>$1://$2</a>") // a href (DEP: img)
|
||||||
.replaceAll("\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // a href (DEP: img)
|
.replaceAll("\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // a href (DEP: img)
|
||||||
.replaceAll("^(-|\\*) ([^<]*)", "<font color='#000001'>•</font> $2 ") // unordered list + end line
|
.replaceAll("(?m)^([-*] )(.*)$", "<font color='#000001'>•</font> $2 ") // unordered list + end line
|
||||||
.replaceAll("^ (-|\\*) ([^<]*)", " <font color='#000001'>•</font> $2 ") // unordered list2 + end line
|
.replaceAll("(?m)^ (-|\\*) ([^<]*)$", " <font color='#000001'>•</font> $2 ") // unordered list2 + end line
|
||||||
.replaceAll("`([^<]*)`", "<code>$1</code>") // code
|
.replaceAll("`([^<]*)`", "<code>$1</code>") // code
|
||||||
.replace("\\*", "●") // temporary replace escaped star symbol
|
.replace("\\*", "●") // temporary replace escaped star symbol
|
||||||
.replaceAll("\\*\\*([^<]*)\\*\\*", "<b>$1</b>") // bold (DEP: temp star)
|
.replaceAll("(?m)\\*\\*(.*)\\*\\*", "<b>$1</b>") // bold (DEP: temp star)
|
||||||
.replaceAll("\\*([^<]*)\\*", "<b>$1</b>") // italic (DEP: temp star)
|
.replaceAll("(?m)\\*(.*)\\*", "<i>$1</i>") // italic (DEP: temp star code)
|
||||||
.replace("●", "*") // restore escaped star symbol (DEP: b,i)
|
.replace("●", "*") // restore escaped star symbol (DEP: b,i)
|
||||||
.replaceAll(" $", "<br/>") // new line (DEP: ul)
|
.replaceAll("(?m) $", "<br/>") // new line (DEP: ul)
|
||||||
;
|
;
|
||||||
return line.isEmpty() ? line + "<br/>" : line;
|
return text;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//########################
|
//########################
|
||||||
//## Members
|
//## Members
|
||||||
//########################
|
//########################
|
||||||
|
private SmpFilter defaultSmpFilter;
|
||||||
private String html;
|
private String html;
|
||||||
|
|
||||||
public SimpleMarkdownParser parse(String filepath, SimpleLineFilter simpleLineFilter) throws IOException {
|
public SimpleMarkdownParser() {
|
||||||
return parse(new FileInputStream(filepath), simpleLineFilter, "");
|
setDefaultSmpFilter(FILTER_WEB);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleMarkdownParser parse(InputStream inputStream, SimpleLineFilter simpleLineFilter, String lineMdPrefix) throws IOException {
|
public SimpleMarkdownParser setDefaultSmpFilter(SmpFilter defaultSmpFilter) {
|
||||||
|
this.defaultSmpFilter = defaultSmpFilter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleMarkdownParser parse(String filepath, SmpFilter... smpFilters) throws IOException {
|
||||||
|
return parse(new FileInputStream(filepath), "", smpFilters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleMarkdownParser parse(InputStream inputStream, String lineMdPrefix, SmpFilter... smpFilters) throws IOException {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
BufferedReader br = null;
|
BufferedReader br = null;
|
||||||
String line;
|
String line;
|
||||||
|
@ -111,7 +144,8 @@ public class SimpleMarkdownParser {
|
||||||
try {
|
try {
|
||||||
br = new BufferedReader(new InputStreamReader(inputStream));
|
br = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
while ((line = br.readLine()) != null) {
|
while ((line = br.readLine()) != null) {
|
||||||
sb.append(simpleLineFilter.filterLine(lineMdPrefix + line));
|
sb.append(lineMdPrefix);
|
||||||
|
sb.append(line);
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
} catch (IOException rethrow) {
|
} catch (IOException rethrow) {
|
||||||
|
@ -125,7 +159,18 @@ public class SimpleMarkdownParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
html = sb.toString().trim();
|
html = parse(sb.toString(), "", smpFilters).getHtml();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleMarkdownParser parse(String markdown, String lineMdPrefix, SmpFilter... smpFilters) throws IOException {
|
||||||
|
html = markdown;
|
||||||
|
if (smpFilters.length == 0) {
|
||||||
|
smpFilters = new SmpFilter[]{defaultSmpFilter};
|
||||||
|
}
|
||||||
|
for (SmpFilter smpFilter : smpFilters) {
|
||||||
|
html = smpFilter.filter(html).trim();
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue