Add simple-ext module
This commit is contained in:
parent
fdb0f76e13
commit
a082e9ed44
27
markwon-simple-ext/build.gradle
Normal file
27
markwon-simple-ext/build.gradle
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
android {
|
||||||
|
|
||||||
|
compileSdkVersion config['compile-sdk']
|
||||||
|
buildToolsVersion config['build-tools']
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion config['min-sdk']
|
||||||
|
targetSdkVersion config['target-sdk']
|
||||||
|
versionCode 1
|
||||||
|
versionName version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
api project(':markwon-core')
|
||||||
|
|
||||||
|
deps['test'].with {
|
||||||
|
testImplementation it['junit']
|
||||||
|
testImplementation it['robolectric']
|
||||||
|
testImplementation it['mockito']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerArtifact(this)
|
4
markwon-simple-ext/gradle.properties
Normal file
4
markwon-simple-ext/gradle.properties
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
POM_NAME=Simple Extension
|
||||||
|
POM_ARTIFACT_ID=simple-ext
|
||||||
|
POM_DESCRIPTION=Custom extension based on simple delimiter usage
|
||||||
|
POM_PACKAGING=aar
|
1
markwon-simple-ext/src/main/AndroidManifest.xml
Normal file
1
markwon-simple-ext/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<manifest package="io.noties.markwon.simple.ext" />
|
@ -0,0 +1,64 @@
|
|||||||
|
package io.noties.markwon.simple.ext;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.commonmark.parser.delimiter.DelimiterProcessor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.noties.markwon.SpanFactory;
|
||||||
|
|
||||||
|
// @since 4.0.0-SNAPSHOT
|
||||||
|
class SimpleExtBuilder {
|
||||||
|
|
||||||
|
private final List<DelimiterProcessor> extensions = new ArrayList<>(2);
|
||||||
|
|
||||||
|
private boolean isBuilt;
|
||||||
|
|
||||||
|
void addExtension(
|
||||||
|
int length,
|
||||||
|
char character,
|
||||||
|
@NonNull SpanFactory spanFactory) {
|
||||||
|
|
||||||
|
checkState();
|
||||||
|
|
||||||
|
extensions.add(new SimpleExtDelimiterProcessor(
|
||||||
|
character,
|
||||||
|
character,
|
||||||
|
length,
|
||||||
|
spanFactory));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addExtension(
|
||||||
|
int length,
|
||||||
|
char openingCharacter,
|
||||||
|
char closingCharacter,
|
||||||
|
@NonNull SpanFactory spanFactory) {
|
||||||
|
|
||||||
|
checkState();
|
||||||
|
|
||||||
|
extensions.add(new SimpleExtDelimiterProcessor(
|
||||||
|
openingCharacter,
|
||||||
|
closingCharacter,
|
||||||
|
length,
|
||||||
|
spanFactory));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
List<DelimiterProcessor> build() {
|
||||||
|
|
||||||
|
checkState();
|
||||||
|
|
||||||
|
isBuilt = true;
|
||||||
|
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkState() {
|
||||||
|
if (isBuilt) {
|
||||||
|
throw new IllegalStateException("SimpleExtBuilder is already built, " +
|
||||||
|
"do not mutate SimpleExtPlugin after configuration is finished");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package io.noties.markwon.simple.ext;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.commonmark.node.Node;
|
||||||
|
import org.commonmark.node.Text;
|
||||||
|
import org.commonmark.parser.delimiter.DelimiterProcessor;
|
||||||
|
import org.commonmark.parser.delimiter.DelimiterRun;
|
||||||
|
|
||||||
|
import io.noties.markwon.SpanFactory;
|
||||||
|
|
||||||
|
// @since 4.0.0-SNAPSHOT
|
||||||
|
class SimpleExtDelimiterProcessor implements DelimiterProcessor {
|
||||||
|
|
||||||
|
private final char open;
|
||||||
|
private final char close;
|
||||||
|
private final int length;
|
||||||
|
private final SpanFactory spanFactory;
|
||||||
|
|
||||||
|
SimpleExtDelimiterProcessor(
|
||||||
|
char open,
|
||||||
|
char close,
|
||||||
|
int length,
|
||||||
|
@NonNull SpanFactory spanFactory) {
|
||||||
|
this.open = open;
|
||||||
|
this.close = close;
|
||||||
|
this.length = length;
|
||||||
|
this.spanFactory = spanFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char getOpeningCharacter() {
|
||||||
|
return open;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char getClosingCharacter() {
|
||||||
|
return close;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDelimiterUse(DelimiterRun opener, DelimiterRun closer) {
|
||||||
|
if (opener.length() >= length && closer.length() >= length) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(Text opener, Text closer, int delimiterUse) {
|
||||||
|
|
||||||
|
final Node node = new SimpleExtNode(spanFactory);
|
||||||
|
|
||||||
|
Node tmp = opener.getNext();
|
||||||
|
Node next;
|
||||||
|
|
||||||
|
while (tmp != null && tmp != closer) {
|
||||||
|
next = tmp.getNext();
|
||||||
|
node.appendChild(tmp);
|
||||||
|
tmp = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
opener.insertAfter(node);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package io.noties.markwon.simple.ext;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.commonmark.node.CustomNode;
|
||||||
|
import org.commonmark.node.Visitor;
|
||||||
|
|
||||||
|
import io.noties.markwon.SpanFactory;
|
||||||
|
|
||||||
|
// @since 4.0.0-SNAPSHOT
|
||||||
|
class SimpleExtNode extends CustomNode {
|
||||||
|
|
||||||
|
private final SpanFactory spanFactory;
|
||||||
|
|
||||||
|
SimpleExtNode(@NonNull SpanFactory spanFactory) {
|
||||||
|
this.spanFactory = spanFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
SpanFactory spanFactory() {
|
||||||
|
return spanFactory;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package io.noties.markwon.simple.ext;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.commonmark.parser.Parser;
|
||||||
|
import org.commonmark.parser.delimiter.DelimiterProcessor;
|
||||||
|
|
||||||
|
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||||
|
import io.noties.markwon.MarkwonVisitor;
|
||||||
|
import io.noties.markwon.SpanFactory;
|
||||||
|
import io.noties.markwon.SpannableBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.0.0-SNAPSHOT
|
||||||
|
*/
|
||||||
|
public class SimpleExtPlugin extends AbstractMarkwonPlugin {
|
||||||
|
|
||||||
|
public interface SimpleExtConfigure {
|
||||||
|
void configure(@NonNull SimpleExtPlugin plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static SimpleExtPlugin create() {
|
||||||
|
return new SimpleExtPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static SimpleExtPlugin create(@NonNull SimpleExtConfigure configure) {
|
||||||
|
final SimpleExtPlugin plugin = new SimpleExtPlugin();
|
||||||
|
configure.configure(plugin);
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final SimpleExtBuilder builder = new SimpleExtBuilder();
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
SimpleExtPlugin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public SimpleExtPlugin addExtension(
|
||||||
|
int length,
|
||||||
|
char character,
|
||||||
|
@NonNull SpanFactory spanFactory) {
|
||||||
|
builder.addExtension(length, character, spanFactory);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public SimpleExtPlugin addExtension(
|
||||||
|
int length,
|
||||||
|
char openingCharacter,
|
||||||
|
char closingCharacter,
|
||||||
|
@NonNull SpanFactory spanFactory) {
|
||||||
|
builder.addExtension(length, openingCharacter, closingCharacter, spanFactory);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureParser(@NonNull Parser.Builder builder) {
|
||||||
|
for (DelimiterProcessor processor : this.builder.build()) {
|
||||||
|
builder.customDelimiterProcessor(processor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
||||||
|
builder.on(SimpleExtNode.class, new MarkwonVisitor.NodeVisitor<SimpleExtNode>() {
|
||||||
|
@Override
|
||||||
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull SimpleExtNode simpleExtNode) {
|
||||||
|
|
||||||
|
final int length = visitor.length();
|
||||||
|
|
||||||
|
visitor.visitChildren(simpleExtNode);
|
||||||
|
|
||||||
|
SpannableBuilder.setSpans(
|
||||||
|
visitor.builder(),
|
||||||
|
simpleExtNode.spanFactory().getSpans(visitor.configuration(), visitor.renderProps()),
|
||||||
|
length,
|
||||||
|
visitor.length()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -43,6 +43,7 @@ dependencies {
|
|||||||
implementation project(':markwon-syntax-highlight')
|
implementation project(':markwon-syntax-highlight')
|
||||||
implementation project(':markwon-recycler')
|
implementation project(':markwon-recycler')
|
||||||
implementation project(':markwon-recycler-table')
|
implementation project(':markwon-recycler-table')
|
||||||
|
implementation project(':markwon-simple-ext')
|
||||||
|
|
||||||
implementation project(':markwon-image-picasso')
|
implementation project(':markwon-image-picasso')
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
<activity android:name="io.noties.markwon.sample.recycler.RecyclerActivity" />
|
<activity android:name="io.noties.markwon.sample.recycler.RecyclerActivity" />
|
||||||
<activity android:name="io.noties.markwon.sample.theme.ThemeActivity" />
|
<activity android:name="io.noties.markwon.sample.theme.ThemeActivity" />
|
||||||
<activity android:name=".html.HtmlActivity" />
|
<activity android:name=".html.HtmlActivity" />
|
||||||
|
<activity android:name=".simpleext.SimpleExtActivity" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import io.noties.markwon.sample.customextension.CustomExtensionActivity;
|
|||||||
import io.noties.markwon.sample.html.HtmlActivity;
|
import io.noties.markwon.sample.html.HtmlActivity;
|
||||||
import io.noties.markwon.sample.latex.LatexActivity;
|
import io.noties.markwon.sample.latex.LatexActivity;
|
||||||
import io.noties.markwon.sample.recycler.RecyclerActivity;
|
import io.noties.markwon.sample.recycler.RecyclerActivity;
|
||||||
|
import io.noties.markwon.sample.simpleext.SimpleExtActivity;
|
||||||
|
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends Activity {
|
||||||
|
|
||||||
@ -102,6 +103,10 @@ public class MainActivity extends Activity {
|
|||||||
activity = HtmlActivity.class;
|
activity = HtmlActivity.class;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SIMPLE_EXT:
|
||||||
|
activity = SimpleExtActivity.class;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("No Activity is associated with sample-item: " + item);
|
throw new IllegalStateException("No Activity is associated with sample-item: " + item);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,9 @@ public enum Sample {
|
|||||||
|
|
||||||
RECYCLER(R.string.sample_recycler),
|
RECYCLER(R.string.sample_recycler),
|
||||||
|
|
||||||
HTML(R.string.sample_html);
|
HTML(R.string.sample_html),
|
||||||
|
|
||||||
|
SIMPLE_EXT(R.string.sample_simple_ext);
|
||||||
|
|
||||||
private final int textResId;
|
private final int textResId;
|
||||||
|
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package io.noties.markwon.sample.simpleext;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import io.noties.markwon.Markwon;
|
||||||
|
import io.noties.markwon.core.spans.EmphasisSpan;
|
||||||
|
import io.noties.markwon.core.spans.StrongEmphasisSpan;
|
||||||
|
import io.noties.markwon.sample.R;
|
||||||
|
import io.noties.markwon.simple.ext.SimpleExtPlugin;
|
||||||
|
|
||||||
|
public class SimpleExtActivity extends Activity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_text_view);
|
||||||
|
|
||||||
|
final TextView textView = findViewById(R.id.text_view);
|
||||||
|
|
||||||
|
final Markwon markwon = Markwon.builder(this)
|
||||||
|
.usePlugin(SimpleExtPlugin.create(plugin -> plugin
|
||||||
|
// +sometext+
|
||||||
|
.addExtension(1, '+', (_1, _2) -> new EmphasisSpan())
|
||||||
|
// ??sometext??
|
||||||
|
.addExtension(2, '?', (_1, _2) -> new StrongEmphasisSpan())
|
||||||
|
// @@sometext$$
|
||||||
|
.addExtension(2, '@', '$', (_1, _2) -> new ForegroundColorSpan(Color.RED))))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final String markdown = "# SimpleExt\n" +
|
||||||
|
"\n" +
|
||||||
|
"+let's start with `+`, ??then we can use this, and finally @@this$$??+";
|
||||||
|
|
||||||
|
markwon.setMarkdown(textView, markdown);
|
||||||
|
}
|
||||||
|
}
|
@ -17,4 +17,7 @@
|
|||||||
|
|
||||||
<string name="sample_html"># \# Html\n\nShows how to define own tag handlers</string>
|
<string name="sample_html"># \# Html\n\nShows how to define own tag handlers</string>
|
||||||
|
|
||||||
|
<string name="sample_simple_ext"># \# SimpleExt\n\nShows how to use SimpleExtPlugin module
|
||||||
|
to create own delimited parser extensions</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -12,5 +12,6 @@ include ':app', ':sample',
|
|||||||
':markwon-linkify',
|
':markwon-linkify',
|
||||||
':markwon-recycler',
|
':markwon-recycler',
|
||||||
':markwon-recycler-table',
|
':markwon-recycler-table',
|
||||||
|
':markwon-simple-ext',
|
||||||
':markwon-syntax-highlight',
|
':markwon-syntax-highlight',
|
||||||
':markwon-test-span'
|
':markwon-test-span'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user