Move syntax highligting to codeview components

This commit is contained in:
qwerty287 2022-08-28 10:31:53 +02:00
parent 848e7ef8fa
commit 18c1222e04
No known key found for this signature in database
GPG Key ID: E0464C650D9D25B2
23 changed files with 757 additions and 881 deletions

View File

@ -29,6 +29,9 @@ android {
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix '.debug'
}
}
compileOptions {
coreLibraryDesugaringEnabled true

View File

@ -9,8 +9,10 @@ import android.widget.ArrayAdapter;
import com.amrdeveloper.codeview.Code;
import org.apache.commons.lang3.EnumUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.databinding.ActivityCodeEditorBinding;
import org.mian.gitnex.helpers.codeeditor.*;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -22,9 +24,8 @@ import java.util.Map;
public class CodeEditorActivity extends BaseActivity {
private final ThemeName currentTheme = ThemeName.FIVE_COLOR;
private Theme currentTheme;
private ActivityCodeEditorBinding binding;
private LanguageManager languageManager;
private LanguageName currentLanguage = LanguageName.UNKNOWN;
@Override
@ -40,9 +41,10 @@ public class CodeEditorActivity extends BaseActivity {
String fileContent = getIntent().getStringExtra("fileContent");
String fileExtension;
currentTheme = Theme.getDefaultTheme(this);
if(getIntent().getStringExtra("fileExtension") != null) {
fileExtension = getIntent().getStringExtra("fileExtension").toUpperCase();
fileExtension = MainGrammarLocator.fromExtension(getIntent().getStringExtra("fileExtension")).toUpperCase();
if(EnumUtils.isValidEnum(LanguageName.class, fileExtension)) {
currentLanguage = LanguageName.valueOf(fileExtension);
@ -75,9 +77,8 @@ public class CodeEditorActivity extends BaseActivity {
binding.codeView.setTabLength(4);
binding.codeView.setEnableAutoIndentation(true);
// Setup the language and theme with SyntaxManager helper class
languageManager = new LanguageManager(this, binding.codeView);
languageManager.applyTheme(currentLanguage, currentTheme);
// Set up the language and theme with SyntaxManager helper class
currentLanguage.getLanguage().applyTheme(this, binding.codeView, currentTheme);
// Setup auto pair complete
final Map<Character, Character> pairCompleteMap = new HashMap<>();
@ -93,7 +94,7 @@ public class CodeEditorActivity extends BaseActivity {
binding.codeView.enablePairCompleteCenterCursor(true);
binding.codeView.setText(fileContent);
// Setup the auto complete and auto indenting for the current language
// Set up the auto complete and auto indenting for the current language
configLanguageAutoComplete();
configLanguageAutoIndentation();
}
@ -102,14 +103,14 @@ public class CodeEditorActivity extends BaseActivity {
boolean useModernAutoCompleteAdapter = true;
if(useModernAutoCompleteAdapter) {
List<Code> codeList = languageManager.getLanguageCodeList(currentLanguage);
List<Code> codeList = currentLanguage.getLanguage().getCodeList();
CustomCodeViewAdapter adapter = new CustomCodeViewAdapter(this, codeList);
binding.codeView.setAdapter(adapter);
}
else {
String[] languageKeywords = languageManager.getLanguageKeywords(currentLanguage);
String[] languageKeywords = currentLanguage.getLanguage().getKeywords();
final int layoutId = R.layout.list_item_suggestion;
@ -121,8 +122,8 @@ public class CodeEditorActivity extends BaseActivity {
}
private void configLanguageAutoIndentation() {
binding.codeView.setIndentationStarts(languageManager.getLanguageIndentationStarts(currentLanguage));
binding.codeView.setIndentationEnds(languageManager.getLanguageIndentationEnds(currentLanguage));
binding.codeView.setIndentationStarts(currentLanguage.getLanguage().getIndentationStarts());
binding.codeView.setIndentationEnds(currentLanguage.getLanguage().getIndentationEnds());
}
private void configCodeViewPlugins() {

View File

@ -1,41 +1,14 @@
package org.mian.gitnex.core;
import androidx.annotation.NonNull;
import java.util.Set;
import io.noties.prism4j.DefaultGrammarLocator;
import io.noties.prism4j.Grammar;
import io.noties.prism4j.GrammarLocator;
import io.noties.prism4j.Prism4j;
/**
* @author opyale
*/
public class MainGrammarLocator implements GrammarLocator {
public class MainGrammarLocator {
public static final String DEFAULT_FALLBACK_LANGUAGE = "clike";
public static final String DEFAULT_FALLBACK_LANGUAGE = null;//"clike";
private static final DefaultGrammarLocator defaultGrammarLocator = new DefaultGrammarLocator();
private static volatile MainGrammarLocator instance;
private MainGrammarLocator() {
}
public static MainGrammarLocator getInstance() {
if(instance == null) {
synchronized(MainGrammarLocator.class) {
if(instance == null) {
instance = new MainGrammarLocator();
}
}
}
return instance;
}
public String fromExtension(String extension) {
public static String fromExtension(String extension) {
switch(extension.toLowerCase()) {
@ -88,9 +61,9 @@ public class MainGrammarLocator implements GrammarLocator {
case "md":
return "markdown";
case "xml":
case "html":
case "htm":
//case "xml":
//case "html":
//case "htm":
case "mathml":
case "svg":
return "markup";
@ -119,17 +92,4 @@ public class MainGrammarLocator implements GrammarLocator {
}
@Override
public Grammar grammar(@NonNull Prism4j prism4j, @NonNull String language) {
return defaultGrammarLocator.grammar(prism4j, language);
}
@NonNull
@Override
public Set<String> languages() {
return defaultGrammarLocator.languages();
}
}

View File

@ -21,6 +21,8 @@ import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.helpers.codeeditor.markwon.MarkwonHighlighter;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
import java.util.Objects;
@ -30,10 +32,6 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.qwerty287.markwonprism4j.Prism4jTheme;
import de.qwerty287.markwonprism4j.Prism4jThemeDarkula;
import de.qwerty287.markwonprism4j.Prism4jThemeDefault;
import de.qwerty287.markwonprism4j.SyntaxHighlightPlugin;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
@ -54,7 +52,6 @@ import io.noties.markwon.recycler.MarkwonAdapter;
import io.noties.markwon.recycler.SimpleEntry;
import io.noties.markwon.recycler.table.TableEntry;
import io.noties.markwon.recycler.table.TableEntryPlugin;
import io.noties.prism4j.Prism4j;
import stormpot.*;
/**
@ -164,12 +161,10 @@ public class Markdown {
private void setup() {
Prism4jTheme prism4jTheme = AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1 ? Prism4jThemeDarkula.create() : Prism4jThemeDefault.create();
Markwon.Builder builder = Markwon.builder(context).usePlugin(CorePlugin.create()).usePlugin(HtmlPlugin.create()).usePlugin(LinkifyPlugin.create(true)).usePlugin(SoftBreakAddsNewLinePlugin.create())
.usePlugin(TablePlugin.create(context)).usePlugin(MovementMethodPlugin.create(TableAwareMovementMethod.create())).usePlugin(TaskListPlugin.create(context)).usePlugin(StrikethroughPlugin.create())
.usePlugin(PicassoImagesPlugin.create(PicassoService.getInstance(context).get()))
.usePlugin(SyntaxHighlightPlugin.create(new Prism4j(MainGrammarLocator.getInstance()), prism4jTheme, MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE)).usePlugin(new AbstractMarkwonPlugin() {
.usePlugin(MarkwonHighlighter.create(context, Theme.getDefaultTheme(context), MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE)).usePlugin(new AbstractMarkwonPlugin() {
private Typeface tf;
@ -272,14 +267,12 @@ public class Markdown {
linkPostProcessor.repository = repository;
}
Prism4jTheme prism4jTheme = AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1 ? Prism4jThemeDarkula.create() : Prism4jThemeDefault.create();
final InlineParserFactory inlineParserFactory = MarkwonInlineParser.factoryBuilder().addInlineProcessor(new IssueInlineProcessor()).addInlineProcessor(new UserInlineProcessor()).build();
Markwon.Builder builder = Markwon.builder(context).usePlugin(CorePlugin.create()).usePlugin(HtmlPlugin.create()).usePlugin(LinkifyPlugin.create(true)) // TODO not working
.usePlugin(SoftBreakAddsNewLinePlugin.create()).usePlugin(TableEntryPlugin.create(context)).usePlugin(MovementMethodPlugin.create(TableAwareMovementMethod.create()))
.usePlugin(TaskListPlugin.create(context)).usePlugin(StrikethroughPlugin.create()).usePlugin(PicassoImagesPlugin.create(PicassoService.getInstance(context).get()))
.usePlugin(SyntaxHighlightPlugin.create(new Prism4j(MainGrammarLocator.getInstance()), prism4jTheme, MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE)).usePlugin(new AbstractMarkwonPlugin() {
.usePlugin(MarkwonHighlighter.create(context, Theme.getDefaultTheme(context), MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE)).usePlugin(new AbstractMarkwonPlugin() {
private final Context context = RecyclerViewRenderer.this.context;
private Typeface tf;

View File

@ -1,138 +0,0 @@
package org.mian.gitnex.helpers.codeeditor;
import android.content.Context;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import org.mian.gitnex.helpers.codeeditor.languages.GoLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.HtmlLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.JavaLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.PhpLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.PythonLanguage;
import org.mian.gitnex.helpers.codeeditor.languages.XmlLanguage;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public class LanguageManager {
private final Context context;
private final CodeView codeView;
public LanguageManager(Context context, CodeView codeView) {
this.context = context;
this.codeView = codeView;
}
public void applyTheme(LanguageName language, ThemeName theme) {
if(theme == ThemeName.FIVE_COLOR) {
applyFiveColorsDarkTheme(language);
}
}
public String[] getLanguageKeywords(LanguageName language) {
switch(language) {
case JAVA:
return JavaLanguage.getKeywords(context);
case PY:
return PythonLanguage.getKeywords(context);
case GO:
return GoLanguage.getKeywords(context);
case PHP:
return PhpLanguage.getKeywords(context);
case XML:
return XmlLanguage.getKeywords(context);
case HTML:
return HtmlLanguage.getKeywords(context);
default:
return new String[]{};
}
}
public List<Code> getLanguageCodeList(LanguageName language) {
switch(language) {
case JAVA:
return JavaLanguage.getCodeList(context);
case PY:
return PythonLanguage.getCodeList(context);
case GO:
return GoLanguage.getCodeList(context);
case PHP:
return PhpLanguage.getCodeList(context);
case XML:
return XmlLanguage.getCodeList(context);
case HTML:
return HtmlLanguage.getCodeList(context);
default:
return new ArrayList<>();
}
}
public Set<Character> getLanguageIndentationStarts(LanguageName language) {
switch(language) {
case JAVA:
return JavaLanguage.getIndentationStarts();
case PY:
return PythonLanguage.getIndentationStarts();
case GO:
return GoLanguage.getIndentationStarts();
case PHP:
return PhpLanguage.getIndentationStarts();
case XML:
return XmlLanguage.getIndentationStarts();
case HTML:
return HtmlLanguage.getIndentationStarts();
default:
return new HashSet<>();
}
}
public Set<Character> getLanguageIndentationEnds(LanguageName language) {
switch(language) {
case JAVA:
return JavaLanguage.getIndentationEnds();
case PY:
return PythonLanguage.getIndentationEnds();
case GO:
return GoLanguage.getIndentationEnds();
case PHP:
return PhpLanguage.getIndentationEnds();
case XML:
return XmlLanguage.getIndentationEnds();
case HTML:
return HtmlLanguage.getIndentationEnds();
default:
return new HashSet<>();
}
}
private void applyFiveColorsDarkTheme(LanguageName language) {
switch(language) {
case JAVA:
JavaLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case PY:
PythonLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case GO:
GoLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case PHP:
PhpLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case XML:
XmlLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
case HTML:
HtmlLanguage.applyFiveColorsDarkTheme(context, codeView);
break;
}
}
}

View File

@ -1,5 +1,8 @@
package org.mian.gitnex.helpers.codeeditor;
import org.mian.gitnex.helpers.codeeditor.languages.*;
import java.util.HashMap;
/**
* @author AmrDeveloper
* @author M M Arif
@ -8,9 +11,23 @@ package org.mian.gitnex.helpers.codeeditor;
public enum LanguageName {
UNKNOWN, // no language is specified or app currently does not support the mentioned language
JAVA, // java
PY, // python with py extension
PYTHON,
GO, // go lang
PHP, // php
XML, // xml
HTML // html
HTML; // html
private static final HashMap<LanguageName, Language> languages = new HashMap<>();
static {
languages.put(JAVA, new JavaLanguage());
languages.put(PYTHON, new PythonLanguage());
languages.put(GO, new GoLanguage());
languages.put(PHP, new PhpLanguage());
languages.put(XML, new XmlLanguage());
languages.put(HTML, new HtmlLanguage());
}
public Language getLanguage() {
return languages.get(this);
}
}

View File

@ -1,10 +0,0 @@
package org.mian.gitnex.helpers.codeeditor;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public enum ThemeName {
FIVE_COLOR
}

View File

@ -1,11 +1,7 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import org.mian.gitnex.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -17,11 +13,7 @@ import java.util.regex.Pattern;
* @author M M Arif
*/
public class GoLanguage {
//Language Keywords
private static final Pattern PATTERN_KEYWORDS = Pattern.compile(
"\\b(break|default|func|interface|case|defer|" + "go|map|struct|chan|else|goto|package|switch|const" + "|fallthrough|if|range|type|continue|for|import|return|var|" + "string|true|false|new|nil|byte|bool|int|int8|int16|int32|int64)\\b");
public class GoLanguage extends Language {
//Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -32,68 +24,75 @@ public class GoLanguage {
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT = Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION = Pattern.compile(":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
//View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
//Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
//Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.reHighlightSyntax();
@Override
public String[] getKeywords() {
return new String[]{"break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", "chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "bool", "byte", "cap",
"close", "complex", "complex64", "complex128", "uint16", "copy", "false", "float32", "float64", "imag", "int", "int8", "int16", "uint32", "int32", "int64", "len", "make", "new", "nil", "uint64", "range",
"type", "continue", "for", "import", "return", "var"};
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.go_keywords);
}
public static List<Code> getCodeList(Context context) {
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
String[] keywords = getKeywords();
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch(element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
public static String getCommentEnd() {
return "";
case GENERIC:
// TODO supported by Go 1.18
case ANNOTATION:
default:
return null;
}
}
}

View File

@ -1,11 +1,7 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import org.mian.gitnex.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -16,11 +12,7 @@ import java.util.regex.Pattern;
* @author M M Arif
*/
public class HtmlLanguage {
//Language Keywords
private static final Pattern PATTERN_KEYWORDS = Pattern.compile(
"\\b(<html|<DOCTYPE|<head|<title|<body|<style|<script|src|href" + "<h1|<h2|<h3|<h4|<h5|<h6|<br|<hr|<section|<header|<footer|<select|<img|<embed|<iframe|<div|<p|code|strong|small|template|" + "input|form|textarea|button|option|label|fieldset|legend|datalist|frame|map|area|canvas|picture|svg|audio|source|track|video|" + "link|nav|ul|ol|li|table|caption|th|tr|td|thead|tbody|tfooter|col|span|main|article|aside|meta|base|noscript|object|param|)\\b");
public class HtmlLanguage extends Language {
//Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -30,63 +22,10 @@ public class HtmlLanguage {
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT = Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("<!--.*-->");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION = Pattern.compile(":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
//View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
//Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
//Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.reHighlightSyntax();
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.html_keywords);
}
public static List<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
@ -95,4 +34,66 @@ public class HtmlLanguage {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch(element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
case MULTI_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case GENERIC:
case TODO_COMMENT:
case ANNOTATION:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[]{"<html", "<DOCTYPE", "<head", "<title", "<body", "<h1", "<h2", "<h3", "<h4", "<h5", "<h6", "<br", "<hr", "<section", "<header", "<footer", "<select", "<img", "<embed", "<iframe", "<style",
"<script", "<div", "<p", "code", "strong", "small", "template", "form", "input", "textarea", "button", "option", "label", "fieldset", "legend", "datalist", "frame", "map", "area", "canvas", "picture", "svg",
"audio", "source", "track", "video", "link", "nav", "ul", "ol", "li", "table", "caption", "th", "tr", "td", "thead", "tbody", "tfooter", "col", "span", "main", "article", "aside", "meta", "base", "noscript",
"object", "param", "src", "href"};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -1,11 +1,7 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import org.mian.gitnex.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -17,11 +13,7 @@ import java.util.regex.Pattern;
* @author M M Arif
*/
public class JavaLanguage {
//Language Keywords
private static final Pattern PATTERN_KEYWORDS = Pattern.compile(
"\\b(abstract|boolean|break|byte|case|catch" + "|char|class|continue|default|do|double|else" + "|enum|extends|final|finally|float|for|if" + "|implements|import|instanceof|int|interface" + "|long|native|new|null|package|private|protected" + "|public|return|short|static|strictfp|super|switch" + "|synchronized|this|throw|transient|try|void|volatile|while)\\b");
public class JavaLanguage extends Language {
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
@ -30,68 +22,12 @@ public class JavaLanguage {
private static final Pattern PATTERN_OPERATION = Pattern.compile(":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
private static final Pattern PATTERN_GENERIC = Pattern.compile("<[a-zA-Z0-9,<>]+>");
private static final Pattern PATTERN_ANNOTATION = Pattern.compile("@.[a-zA-Z0-9]+");
private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("//TODO[^\n]*");
private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b");
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
//View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
//Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_ANNOTATION, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(PATTERN_GENERIC, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
//Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_TODO_COMMENT, resources.getColor(R.color.gold, null));
codeView.reHighlightSyntax();
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.java_keywords);
}
public static List<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
@ -100,4 +36,69 @@ public class JavaLanguage {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch(element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case GENERIC:
return PATTERN_GENERIC;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case ANNOTATION:
return PATTERN_ANNOTATION;
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[]{"public", "private", "protected", "package", "abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "continue", "default", "do", "double", "else", "enum", "extends",
"final", "finally", "float", "for", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this",
"throw", "transient", "try", "void", "volatile", "while"};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -0,0 +1,46 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
/**
* @author qwerty287
*/
public abstract class Language {
public abstract Pattern getPattern(LanguageElement element);
public abstract Set<Character> getIndentationStarts();
public abstract Set<Character> getIndentationEnds();
public abstract String[] getKeywords();
public abstract List<Code> getCodeList();
public void applyTheme(Context context, CodeView codeView, Theme theme) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
//View Background
codeView.setBackgroundColor(resources.getColor(theme.getBackgroundColor(), null));
//Syntax Colors
for(LanguageElement e : Objects.requireNonNull(LanguageElement.class.getEnumConstants())) {
Pattern p = getPattern(e);
if(p != null) {
codeView.addSyntaxPattern(p, resources.getColor(theme.getColor(e), null));
}
}
//Default Color
codeView.setTextColor(resources.getColor(theme.getDefaultColor(), null));
codeView.reHighlightSyntax();
}
}

View File

@ -0,0 +1,22 @@
package org.mian.gitnex.helpers.codeeditor.languages;
/**
* @author qwerty287
*/
public enum LanguageElement {
KEYWORD,
ATTRIBUTE,
BUILTIN,
NUMBER,
HEX,
OPERATION,
GENERIC,
ANNOTATION,
CHAR,
STRING,
SINGLE_LINE_COMMENT,
TODO_COMMENT,
MULTI_LINE_COMMENT
}

View File

@ -1,11 +1,7 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import org.mian.gitnex.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -16,11 +12,7 @@ import java.util.regex.Pattern;
* @author M M Arif
*/
public class PhpLanguage {
//Language Keywords
private static final Pattern PATTERN_KEYWORDS = Pattern.compile(
"\\b(<?php|__construct|var_dump|define|echo|var|float|" + "int|bool|false|true|function|private|public|protected|interface|return|copy|struct|abstract|extends|" + "trait|static|namespace|implements|__set|__get|unlink|this|try|catch|Throwable|Exception|pdo|" + "str_replace|form|date|abs|min|max|strtotime|mktime|" + "foreach|require_once|include_once|hash|array|range|break|continue|preg_match|preg_match_all|preg_replace|" + "throw|new|and|or|if|else|elseif|switch|case|default|match|require|include|goto|do|while|for|map|)\\b");
public class PhpLanguage extends Language {
//Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -32,61 +24,10 @@ public class PhpLanguage {
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT = Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("//\\s?(TODO|todo)\\s[^\\n]*");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("(?<=->)[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION = Pattern.compile(":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
//View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
//Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
//Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.reHighlightSyntax();
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.php_keywords);
}
public static List<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
@ -95,4 +36,69 @@ public class PhpLanguage {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch(element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case MULTI_LINE_COMMENT:
return PATTERN_MULTI_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case ANNOTATION:
// TODO supported by PHP
case GENERIC:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[]{"<?php", "__construct", "var_dump", "define", "echo", "var", "float", "int", "bool", "false", "true", "function", "private", "public", "protected", "interface", "return", "copy", "struct",
"abstract", "extends", "trait", "static", "namespace", "implements", "__set", "__get", "unlink", "this", "try", "catch", "Throwable", "Exception", "pdo", "throw", "new", "and", "or", "if", "else", "elseif",
"switch", "case", "default", "match", "require", "include", "require_once", "include_once", "goto", "do", "while", "for", "foreach", "map", "hash", "array", "range", "break", "continue", "preg_match",
"preg_match_all", "preg_replace", "str_replace", "form", "date", "abs", "min", "max", "strtotime", "mktime"};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View File

@ -1,11 +1,7 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import org.mian.gitnex.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -17,11 +13,7 @@ import java.util.regex.Pattern;
* @author M M Arif
*/
public class PythonLanguage {
//Language Keywords
private static final Pattern PATTERN_KEYWORDS = Pattern.compile(
"\\b(False|await|else|import|pass|None|break|except|in|raise" + "|True|class|finally|is|return|and|continue|for|lambda" + "|try|as|def|from|nonlocal|while|assert|del|global|not" + "|with|async|elif|if|or|yield)\\b");
public class PythonLanguage extends Language {
//Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -31,62 +23,11 @@ public class PythonLanguage {
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("#TODO[^\n]*");
private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("#\\s?(TODO|todo)\\s[^\n]*");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION = Pattern.compile(":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
private static final Pattern PATTERN_HASH_COMMENT = Pattern.compile("#(?!TODO )[^\\n]*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
//View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
//Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_HASH_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
//Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_TODO_COMMENT, resources.getColor(R.color.gold, null));
codeView.reHighlightSyntax();
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.python_keywords);
}
public static List<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add(':');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
return new HashSet<>();
}
public static String getCommentStart() {
return "#";
}
@ -95,4 +36,65 @@ public class PythonLanguage {
return "";
}
@Override
public Pattern getPattern(LanguageElement element) {
switch(element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
return PATTERN_HASH_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case TODO_COMMENT:
return PATTERN_TODO_COMMENT;
case ANNOTATION:
// TODO supported by Python
case GENERIC:
case MULTI_LINE_COMMENT:
default:
return null;
}
}
@Override
public String[] getKeywords() {
return new String[]{"False", "await", "else", "import", "pass", "None", "break", "except", "in", "raise", "True", "class", "finally", "is", "return", "and", "continue", "for", "lambda", "try", "as", "def",
"from", "nonlocal", "while", "assert", "del", "global", "not", "with", "async", "elif", "if", "or", "yield",};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords();
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add(':');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
return new HashSet<>();
}
}

View File

@ -1,11 +1,7 @@
package org.mian.gitnex.helpers.codeeditor.languages;
import android.content.Context;
import android.content.res.Resources;
import com.amrdeveloper.codeview.Code;
import com.amrdeveloper.codeview.CodeView;
import com.amrdeveloper.codeview.Keyword;
import org.mian.gitnex.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -16,10 +12,7 @@ import java.util.regex.Pattern;
* @author M M Arif
*/
public class XmlLanguage {
//Language Keywords
private static final Pattern PATTERN_KEYWORDS = Pattern.compile("\\b(<xml|version|encoding)\\b");
public class XmlLanguage extends Language {
//Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -29,69 +22,79 @@ public class XmlLanguage {
private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']");
private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]");
private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*");
private static final Pattern PATTERN_MULTI_LINE_COMMENT = Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/");
private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("<!--.*-->");
private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+");
private static final Pattern PATTERN_OPERATION = Pattern.compile(":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*");
public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) {
codeView.resetSyntaxPatternList();
codeView.resetHighlighter();
Resources resources = context.getResources();
//View Background
codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null));
//Syntax Colors
codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null));
codeView.addSyntaxPattern(PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null));
codeView.addSyntaxPattern(PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null));
codeView.addSyntaxPattern(PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null));
codeView.addSyntaxPattern(PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null));
codeView.addSyntaxPattern(PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null));
//Default Color
codeView.setTextColor(resources.getColor(R.color.five_dark_white, null));
codeView.reHighlightSyntax();
@Override
public Pattern getPattern(LanguageElement element) {
switch(element) {
case KEYWORD:
return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b");
case BUILTIN:
return PATTERN_BUILTINS;
case NUMBER:
return PATTERN_NUMBERS;
case CHAR:
return PATTERN_CHAR;
case STRING:
return PATTERN_STRING;
case HEX:
return PATTERN_HEX;
case SINGLE_LINE_COMMENT:
case MULTI_LINE_COMMENT:
return PATTERN_SINGLE_LINE_COMMENT;
case ATTRIBUTE:
return PATTERN_ATTRIBUTE;
case OPERATION:
return PATTERN_OPERATION;
case GENERIC:
case TODO_COMMENT:
case ANNOTATION:
default:
return null;
}
}
public static String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.xml_keywords);
@Override
public String[] getKeywords() {
return new String[]{
"<xml",
"encoding",
"version",
};
}
public static List<Code> getCodeList(Context context) {
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
String[] keywords = getKeywords();
for(String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
return "<!--";
}
public static String getCommentEnd() {
return "";
return "-->";
}
}

View File

@ -0,0 +1,51 @@
package org.mian.gitnex.helpers.codeeditor.markwon;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.core.MarkwonTheme;
public class MarkwonHighlighter extends AbstractMarkwonPlugin {
@NonNull
public static MarkwonHighlighter create(
Context context,
@NonNull Theme theme) {
return create(context, theme, null);
}
@NonNull
public static MarkwonHighlighter create(
Context context,
@NonNull Theme theme,
@Nullable String fallbackLanguage) {
return new MarkwonHighlighter(context, theme, fallbackLanguage);
}
private final Theme theme;
private final Context context;
private final String fallbackLanguage;
public MarkwonHighlighter(
Context context,
@NonNull Theme theme,
@Nullable String fallbackLanguage) {
this.theme = theme;
this.context = context;
this.fallbackLanguage = fallbackLanguage;
}
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(context.getResources().getColor(theme.getDefaultColor(), null))
.codeBackgroundColor(context.getResources().getColor(theme.getBackgroundColor(), null));
}
@Override
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
builder.syntaxHighlight(SyntaxHighlighter.create(context, theme, fallbackLanguage));
}
}

View File

@ -0,0 +1,94 @@
package org.mian.gitnex.helpers.codeeditor.markwon;
import android.content.Context;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.EnumUtils;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.helpers.codeeditor.LanguageName;
import org.mian.gitnex.helpers.codeeditor.languages.Language;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.noties.markwon.syntax.SyntaxHighlight;
/**
* @author qwerty287
*/
public class SyntaxHighlighter implements SyntaxHighlight {
@NonNull
public static SyntaxHighlighter create(
Context context,
@NonNull Theme theme) {
return new SyntaxHighlighter(context, theme, null);
}
@NonNull
public static SyntaxHighlighter create(
Context context,
@NonNull Theme theme,
@Nullable String fallback) {
return new SyntaxHighlighter(context, theme, fallback);
}
private final Theme theme;
private final Context context;
private final String fallback;
protected SyntaxHighlighter(
Context context,
@NonNull Theme theme,
@Nullable String fallback) {
this.context = context;
this.theme = theme;
this.fallback = fallback;
}
@NonNull
@Override
public CharSequence highlight(@Nullable String info, @NonNull String code) {
if(code.isEmpty()) {
return code;
}
if (info == null) {
info = fallback;
}
if(info != null) {
info = MainGrammarLocator.fromExtension(info).toUpperCase();
}
Editable highlightedCode = new SpannableStringBuilder(code);
Language l;
if(EnumUtils.isValidEnum(LanguageName.class, info)) {
l = LanguageName.valueOf(info).getLanguage();
}
else {
return code;
}
for(LanguageElement e : Objects.requireNonNull(LanguageElement.class.getEnumConstants())) {
Pattern p = l.getPattern(e);
if(p != null) {
Matcher matcher = p.matcher(highlightedCode);
while (matcher.find()) {
highlightedCode.setSpan(new ForegroundColorSpan(context.getResources().getColor(theme.getColor(e), null)),
matcher.start(), matcher.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
return highlightedCode;
}
}

View File

@ -0,0 +1,52 @@
package org.mian.gitnex.helpers.codeeditor.theme;
import androidx.annotation.ColorRes;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
/**
* @author qwerty287
* @author M M Arif
*/
public class FiveColorsDarkTheme implements Theme {
@Override
@ColorRes
public int getColor(LanguageElement element) {
switch(element) {
case HEX:
case NUMBER:
case KEYWORD:
case OPERATION:
case GENERIC:
return R.color.five_dark_purple;
case CHAR:
case STRING:
return R.color.five_dark_yellow;
case BUILTIN:
return R.color.five_dark_white;
case SINGLE_LINE_COMMENT:
case MULTI_LINE_COMMENT:
return R.color.five_dark_grey;
case ATTRIBUTE:
case TODO_COMMENT:
case ANNOTATION:
return R.color.five_dark_blue;
default:
return R.color.five_dark_white;
}
}
@Override
@ColorRes
public int getDefaultColor() {
return R.color.five_dark_white;
}
@Override
@ColorRes
public int getBackgroundColor() {
return R.color.five_dark_black;
}
}

View File

@ -0,0 +1,52 @@
package org.mian.gitnex.helpers.codeeditor.theme;
import androidx.annotation.ColorRes;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
/**
* @author qwerty287
* @author M M Arif
*/
public class FiveColorsTheme implements Theme {
@Override
@ColorRes
public int getColor(LanguageElement element) {
switch(element) {
case HEX:
case NUMBER:
case KEYWORD:
case OPERATION:
case GENERIC:
return R.color.five_dark_purple;
case CHAR:
case STRING:
return R.color.five_yellow;
case BUILTIN:
return R.color.five_dark_black;
case SINGLE_LINE_COMMENT:
case MULTI_LINE_COMMENT:
return R.color.five_dark_grey;
case ATTRIBUTE:
case TODO_COMMENT:
case ANNOTATION:
return R.color.five_dark_blue;
default:
return R.color.five_dark_black;
}
}
@Override
@ColorRes
public int getDefaultColor() {
return R.color.five_dark_black;
}
@Override
@ColorRes
public int getBackgroundColor() {
return R.color.five_background_grey;
}
}

View File

@ -0,0 +1,29 @@
package org.mian.gitnex.helpers.codeeditor.theme;
import android.content.Context;
import androidx.annotation.ColorRes;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement;
/**
* @author qwerty287
*/
public interface Theme {
FiveColorsTheme FIVE_COLORS = new FiveColorsTheme();
FiveColorsDarkTheme FIVE_COLORS_DARK = new FiveColorsDarkTheme();
@ColorRes
int getColor(LanguageElement element);
@ColorRes
int getDefaultColor();
@ColorRes
int getBackgroundColor();
static Theme getDefaultTheme(Context context) {
return AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1 ? FIVE_COLORS_DARK : FIVE_COLORS;
}
}

View File

@ -16,14 +16,10 @@ import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.mian.gitnex.R;
import org.mian.gitnex.core.MainGrammarLocator;
import org.mian.gitnex.helpers.AppUtil;
import de.qwerty287.markwonprism4j.Prism4jSyntaxHighlight;
import de.qwerty287.markwonprism4j.Prism4jTheme;
import de.qwerty287.markwonprism4j.Prism4jThemeDarkula;
import de.qwerty287.markwonprism4j.Prism4jThemeDefault;
import io.noties.prism4j.Prism4j;
import org.mian.gitnex.helpers.codeeditor.markwon.SyntaxHighlighter;
import org.mian.gitnex.helpers.codeeditor.theme.Theme;
/**
* @author opyale
@ -31,7 +27,7 @@ import io.noties.prism4j.Prism4j;
public class SyntaxHighlightedArea extends LinearLayout {
private Prism4jTheme prism4jTheme;
private Theme theme;
private TextView sourceView;
private LinesView linesView;
@ -53,14 +49,14 @@ public class SyntaxHighlightedArea extends LinearLayout {
public void setup() {
prism4jTheme = AppUtil.getColorFromAttribute(getContext(), R.attr.isDark) == 1 ? Prism4jThemeDarkula.create() : Prism4jThemeDefault.create();
theme = Theme.getDefaultTheme(getContext());
sourceView = new TextView(getContext());
sourceView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
sourceView.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/sourcecodeproregular.ttf"));
sourceView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
sourceView.setTextColor(prism4jTheme.textColor());
sourceView.setTextColor(getContext().getResources().getColor(theme.getDefaultColor(), null));
sourceView.setTextIsSelectable(true);
int padding = AppUtil.getPixelsFromDensity(getContext(), 5);
@ -78,12 +74,12 @@ public class SyntaxHighlightedArea extends LinearLayout {
linesView.getPaint().setTypeface(sourceView.getTypeface());
linesView.getPaint().setTextSize(sourceView.getTextSize());
linesView.setBackgroundColor(prism4jTheme.background());
linesView.setTextColor(prism4jTheme.textColor());
linesView.setLineColor(prism4jTheme.textColor());
linesView.setBackgroundColor(getContext().getResources().getColor(theme.getBackgroundColor(), null));
linesView.setTextColor(getContext().getResources().getColor(theme.getDefaultColor(), null));
linesView.setLineColor(getContext().getResources().getColor(theme.getDefaultColor(), null));
setOrientation(HORIZONTAL);
setBackgroundColor(prism4jTheme.background());
setBackgroundColor(getContext().getResources().getColor(theme.getBackgroundColor(), null));
addView(linesView);
addView(horizontalScrollView);
@ -97,10 +93,8 @@ public class SyntaxHighlightedArea extends LinearLayout {
try {
MainGrammarLocator mainGrammarLocator = MainGrammarLocator.getInstance();
CharSequence highlightedSource = Prism4jSyntaxHighlight.create(new Prism4j(mainGrammarLocator), prism4jTheme, MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE)
.highlight(mainGrammarLocator.fromExtension(extension), source);
CharSequence highlightedSource = SyntaxHighlighter.create(getContext(), theme, MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE)
.highlight(MainGrammarLocator.fromExtension(extension).toUpperCase(), source);
getActivity().runOnUiThread(() -> sourceView.setText(highlightedSource));

View File

@ -74,4 +74,6 @@
<color name="five_dark_grey">#a9b1ae</color>
<color name="five_dark_white">#ffffff</color>
<color name="gold">#e6b121</color>
<color name="five_yellow">#fdc92f</color>
<color name="five_background_grey">#f5f2f0</color>
</resources>

View File

@ -1,304 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--HTML Keywords List-->
<string-array name="html_keywords">
<item><![CDATA[<html]]></item>
<item><![CDATA[<DOCTYPE]]></item>
<item><![CDATA[<head]]></item>
<item><![CDATA[<title]]></item>
<item><![CDATA[<body]]></item>
<item><![CDATA[<h1]]></item>
<item><![CDATA[<h2]]></item>
<item><![CDATA[<h3]]></item>
<item><![CDATA[<h4]]></item>
<item><![CDATA[<h5]]></item>
<item><![CDATA[<h6]]></item>
<item><![CDATA[<br]]></item>
<item><![CDATA[<hr]]></item>
<item><![CDATA[<section]]></item>
<item><![CDATA[<header]]></item>
<item><![CDATA[<footer]]></item>
<item><![CDATA[<select]]></item>
<item><![CDATA[<img]]></item>
<item><![CDATA[<embed]]></item>
<item><![CDATA[<iframe]]></item>
<item><![CDATA[<style]]></item>
<item><![CDATA[<script]]></item>
<item><![CDATA[<div]]></item>
<item><![CDATA[<p]]></item>
<item>code</item>
<item>strong</item>
<item>small</item>
<item>template</item>
<item>form</item>
<item>input</item>
<item>textarea</item>
<item>button</item>
<item>option</item>
<item>label</item>
<item>fieldset</item>
<item>legend</item>
<item>datalist</item>
<item>frame</item>
<item>map</item>
<item>area</item>
<item>canvas</item>
<item>picture</item>
<item>svg</item>
<item>audio</item>
<item>source</item>
<item>track</item>
<item>video</item>
<item>link</item>
<item>nav</item>
<item>ul</item>
<item>ol</item>
<item>li</item>
<item>table</item>
<item>caption</item>
<item>th</item>
<item>tr</item>
<item>td</item>
<item>thead</item>
<item>tbody</item>
<item>tfooter</item>
<item>col</item>
<item>span</item>
<item>main</item>
<item>article</item>
<item>aside</item>
<item>meta</item>
<item>base</item>
<item>noscript</item>
<item>object</item>
<item>param</item>
<item>src</item>
<item>href</item>
</string-array>
<!--XML Keywords List-->
<string-array name="xml_keywords">
<item><![CDATA[<xml]]></item>
<item>encoding</item>
<item>version</item>
</string-array>
<!--PHP Keywords List-->
<string-array name="php_keywords">
<item><![CDATA[<?php]]></item>
<item>__construct</item>
<item>var_dump</item>
<item>define</item>
<item>echo</item>
<item>var</item>
<item>float</item>
<item>int</item>
<item>bool</item>
<item>false</item>
<item>true</item>
<item>function</item>
<item>private</item>
<item>public</item>
<item>protected</item>
<item>interface</item>
<item>return</item>
<item>copy</item>
<item>struct</item>
<item>abstract</item>
<item>extends</item>
<item>trait</item>
<item>static</item>
<item>namespace</item>
<item>implements</item>
<item>__set</item>
<item>__get</item>
<item>unlink</item>
<item>this</item>
<item>try</item>
<item>catch</item>
<item>Throwable</item>
<item>Exception</item>
<item>pdo</item>
<item>throw</item>
<item>new</item>
<item>and</item>
<item>or</item>
<item>if</item>
<item>else</item>
<item>elseif</item>
<item>switch</item>
<item>case</item>
<item>default</item>
<item>match</item>
<item>require</item>
<item>include</item>
<item>require_once</item>
<item>include_once</item>
<item>goto</item>
<item>do</item>
<item>while</item>
<item>for</item>
<item>foreach</item>
<item>map</item>
<item>hash</item>
<item>array</item>
<item>range</item>
<item>break</item>
<item>continue</item>
<item>preg_match</item>
<item>preg_match_all</item>
<item>preg_replace</item>
<item>str_replace</item>
<item>form</item>
<item>date</item>
<item>abs</item>
<item>min</item>
<item>max</item>
<item>strtotime</item>
<item>mktime</item>
</string-array>
<!--Java Keywords List-->
<string-array name="java_keywords">
<item>public</item>
<item>private</item>
<item>protected</item>
<item>package</item>
<item>abstract</item>
<item>boolean</item>
<item>break</item>
<item>byte</item>
<item>case</item>
<item>catch</item>
<item>char</item>
<item>class</item>
<item>continue</item>
<item>default</item>
<item>do</item>
<item>double</item>
<item>else</item>
<item>enum</item>
<item>extends</item>
<item>final</item>
<item>finally</item>
<item>float</item>
<item>for</item>
<item>if</item>
<item>implements</item>
<item>import</item>
<item>instanceof</item>
<item>int</item>
<item>interface</item>
<item>long</item>
<item>native</item>
<item>new</item>
<item>return</item>
<item>short</item>
<item>static</item>
<item>strictfp</item>
<item>super</item>
<item>switch</item>
<item>synchronized</item>
<item>this</item>
<item>throw</item>
<item>transient</item>
<item>try</item>
<item>void</item>
<item>volatile</item>
<item>while</item>
</string-array>
<!--GoLang Keywords List-->
<string-array name="go_keywords">
<item>break</item>
<item>default</item>
<item>func</item>
<item>interface</item>
<item>select</item>
<item>case</item>
<item>defer</item>
<item>go</item>
<item>map</item>
<item>struct</item>
<item>chan</item>
<item>else</item>
<item>goto</item>
<item>package</item>
<item>switch</item>
<item>const</item>
<item>fallthrough</item>
<item>if</item>
<item>bool</item>
<item>byte</item>
<item>cap</item>
<item>close</item>
<item>complex</item>
<item>complex64</item>
<item>complex128</item>
<item>uint16</item>
<item>copy</item>
<item>false</item>
<item>float32</item>
<item>float64</item>
<item>imag</item>
<item>int</item>
<item>int8</item>
<item>int16</item>
<item>uint32</item>
<item>int32</item>
<item>int64</item>
<item>len</item>
<item>make</item>
<item>new</item>
<item>nil</item>
<item>uint64</item>
<item>range</item>
<item>type</item>
<item>continue</item>
<item>for</item>
<item>import</item>
<item>return</item>
<item>var</item>
</string-array>
<!--Python Keywords List-->
<string-array name="python_keywords">
<item>False</item>
<item>await</item>
<item>else</item>
<item>import</item>
<item>pass</item>
<item>None</item>
<item>break</item>
<item>except</item>
<item>in</item>
<item>raise</item>
<item>True</item>
<item>class</item>
<item>finally</item>
<item>is</item>
<item>return</item>
<item>and</item>
<item>continue</item>
<item>for</item>
<item>lambda</item>
<item>try</item>
<item>as</item>
<item>def</item>
<item>from</item>
<item>nonlocal</item>
<item>while</item>
<item>assert</item>
<item>del</item>
<item>global</item>
<item>not</item>
<item>with</item>
<item>async</item>
<item>elif</item>
<item>if</item>
<item>or</item>
<item>yield</item>
</string-array>
</resources>