diff --git a/docs/docs/theme.md b/docs/docs/theme.md
index 4612a63d..4baf954c 100644
--- a/docs/docs/theme.md
+++ b/docs/docs/theme.md
@@ -116,7 +116,7 @@ The color of background of code block text
Leading margin for the block code content
-
+
### Code typeface
diff --git a/docs/docs/v3/core/theme.md b/docs/docs/v3/core/theme.md
index 93c31e85..bfb2b71d 100644
--- a/docs/docs/v3/core/theme.md
+++ b/docs/docs/v3/core/theme.md
@@ -120,7 +120,7 @@ The color of background of code block text
Leading margin for the block code content
-
+
### Code typeface
diff --git a/markwon-core/src/main/java/ru/noties/markwon/core/MarkwonTheme.java b/markwon-core/src/main/java/ru/noties/markwon/core/MarkwonTheme.java
index fc97875a..43848d75 100644
--- a/markwon-core/src/main/java/ru/noties/markwon/core/MarkwonTheme.java
+++ b/markwon-core/src/main/java/ru/noties/markwon/core/MarkwonTheme.java
@@ -108,7 +108,7 @@ public class MarkwonTheme {
final Dip dip = Dip.create(context);
return new Builder()
- .codeMultilineMargin(dip.toPx(8))
+ .codeBlockMargin(dip.toPx(8))
.blockMargin(dip.toPx(24))
.blockQuoteWidth(dip.toPx(4))
.bulletListItemStrokeWidth(dip.toPx(1))
@@ -165,15 +165,19 @@ public class MarkwonTheme {
// by default `width` of a space char... it's fun and games, but span doesn't have access to paint in `getLeadingMargin`
// so, we need to set this value explicitly (think of an utility method, that takes TextView/TextPaint and measures space char)
- protected final int codeMultilineMargin;
+ protected final int codeBlockMargin;
// by default Typeface.MONOSPACE
protected final Typeface codeTypeface;
+ protected final Typeface codeBlockTypeface;
+
// by default a bit (how much?!) smaller than normal text
// applied ONLY if default typeface was used, otherwise, not applied
protected final int codeTextSize;
+ protected final int codeBlockTextSize;
+
// by default paint.getStrokeWidth
protected final int headingBreakHeight;
@@ -207,9 +211,11 @@ public class MarkwonTheme {
this.codeBlockTextColor = builder.codeBlockTextColor;
this.codeBackgroundColor = builder.codeBackgroundColor;
this.codeBlockBackgroundColor = builder.codeBlockBackgroundColor;
- this.codeMultilineMargin = builder.codeMultilineMargin;
+ this.codeBlockMargin = builder.codeBlockMargin;
this.codeTypeface = builder.codeTypeface;
+ this.codeBlockTypeface = builder.codeBlockTypeface;
this.codeTextSize = builder.codeTextSize;
+ this.codeBlockTextSize = builder.codeBlockTextSize;
this.headingBreakHeight = builder.headingBreakHeight;
this.headingBreakColor = builder.headingBreakColor;
this.headingTypeface = builder.headingTypeface;
@@ -301,66 +307,117 @@ public class MarkwonTheme {
}
/**
- * Modified in 1.0.5 to accept `multiline` argument
+ * @since 3.0.0
*/
- public void applyCodeTextStyle(@NonNull Paint paint, boolean multiline) {
+ public void applyCodeTextStyle(@NonNull Paint paint) {
- // @since 1.0.5 added handling of multiline code blocks
- if (multiline
- && codeBlockTextColor != 0) {
- paint.setColor(codeBlockTextColor);
- } else if (codeTextColor != 0) {
+ if (codeTextColor != 0) {
paint.setColor(codeTextColor);
}
- // custom typeface was set
if (codeTypeface != null) {
paint.setTypeface(codeTypeface);
- // please note that we won't be calculating textSize
- // (like we do when no Typeface is provided), if it's some specific typeface
- // we would confuse users about textSize
- if (codeTextSize != 0) {
+ if (codeTextSize > 0) {
paint.setTextSize(codeTextSize);
}
} else {
+
paint.setTypeface(Typeface.MONOSPACE);
- final float textSize;
- if (codeTextSize != 0) {
- textSize = codeTextSize;
+
+ if (codeTextSize > 0) {
+ paint.setTextSize(codeTextSize);
} else {
- textSize = paint.getTextSize() * CODE_DEF_TEXT_SIZE_RATIO;
+ paint.setTextSize(paint.getTextSize() * CODE_DEF_TEXT_SIZE_RATIO);
}
- paint.setTextSize(textSize);
}
}
- public int getCodeMultilineMargin() {
- return codeMultilineMargin;
+ /**
+ * @since 3.0.0
+ */
+ public void applyCodeBlockTextStyle(@NonNull Paint paint) {
+
+ // apply text color, first check for block specific value,
+ // then check for code (inline), else do nothing (keep original color of text)
+ final int textColor = codeBlockTextColor != 0
+ ? codeBlockTextColor
+ : codeTextColor;
+
+ if (textColor != 0) {
+ paint.setColor(textColor);
+ }
+
+ final Typeface typeface = codeBlockTypeface != null
+ ? codeBlockTypeface
+ : codeTypeface;
+
+ if (typeface != null) {
+
+ paint.setTypeface(typeface);
+
+ // please note that we won't be calculating textSize
+ // (like we do when no Typeface is provided), if it's some specific typeface
+ // we would confuse users about textSize
+ final int textSize = codeBlockTextSize > 0
+ ? codeBlockTextSize
+ : codeTextSize;
+
+ if (textSize > 0) {
+ paint.setTextSize(textSize);
+ }
+ } else {
+
+ // by default use monospace
+ paint.setTypeface(Typeface.MONOSPACE);
+
+ final int textSize = codeBlockTextSize > 0
+ ? codeBlockTextSize
+ : codeTextSize;
+
+ if (textSize > 0) {
+ paint.setTextSize(textSize);
+ } else {
+ // calculate default value
+ paint.setTextSize(paint.getTextSize() * CODE_DEF_TEXT_SIZE_RATIO);
+ }
+ }
+ }
+
+
+ public int getCodeBlockMargin() {
+ return codeBlockMargin;
}
/**
- * Modified in 1.0.5 to accept `multiline` argument
+ * @since 3.0.0
*/
- public int getCodeBackgroundColor(@NonNull Paint paint, boolean multiline) {
-
+ public int getCodeBackgroundColor(@NonNull Paint paint) {
final int color;
-
- // @since 1.0.5 added handling of multiline code blocks
- if (multiline
- && codeBlockBackgroundColor != 0) {
- color = codeBlockBackgroundColor;
- } else if (codeBackgroundColor != 0) {
+ if (codeBackgroundColor != 0) {
color = codeBackgroundColor;
} else {
color = ColorUtils.applyAlpha(paint.getColor(), CODE_DEF_BACKGROUND_COLOR_ALPHA);
}
-
return color;
}
+ /**
+ * @since 3.0.0
+ */
+ public int getCodeBlockBackgroundColor(@NonNull Paint paint) {
+
+ final int color = codeBlockBackgroundColor != 0
+ ? codeBlockBackgroundColor
+ : codeBackgroundColor;
+
+ return color != 0
+ ? color
+ : ColorUtils.applyAlpha(paint.getColor(), CODE_DEF_BACKGROUND_COLOR_ALPHA);
+ }
+
public void applyHeadingTextStyle(@NonNull Paint paint, @IntRange(from = 1, to = 6) int level) {
if (headingTypeface == null) {
paint.setFakeBoldText(true);
@@ -426,9 +483,11 @@ public class MarkwonTheme {
private int codeBlockTextColor; // @since 1.0.5
private int codeBackgroundColor;
private int codeBlockBackgroundColor; // @since 1.0.5
- private int codeMultilineMargin;
+ private int codeBlockMargin;
private Typeface codeTypeface;
+ private Typeface codeBlockTypeface; // @since 3.0.0
private int codeTextSize;
+ private int codeBlockTextSize; // @since 3.0.0
private int headingBreakHeight = -1;
private int headingBreakColor;
private Typeface headingTypeface;
@@ -451,7 +510,7 @@ public class MarkwonTheme {
this.codeBlockTextColor = theme.codeBlockTextColor;
this.codeBackgroundColor = theme.codeBackgroundColor;
this.codeBlockBackgroundColor = theme.codeBlockBackgroundColor;
- this.codeMultilineMargin = theme.codeMultilineMargin;
+ this.codeBlockMargin = theme.codeBlockMargin;
this.codeTypeface = theme.codeTypeface;
this.codeTextSize = theme.codeTextSize;
this.headingBreakHeight = theme.headingBreakHeight;
@@ -537,8 +596,8 @@ public class MarkwonTheme {
}
@NonNull
- public Builder codeMultilineMargin(@Px int codeMultilineMargin) {
- this.codeMultilineMargin = codeMultilineMargin;
+ public Builder codeBlockMargin(@Px int codeBlockMargin) {
+ this.codeBlockMargin = codeBlockMargin;
return this;
}
@@ -548,12 +607,30 @@ public class MarkwonTheme {
return this;
}
+ /**
+ * @since 3.0.0
+ */
+ @NonNull
+ public Builder codeBlockTypeface(@NonNull Typeface typeface) {
+ this.codeBlockTypeface = typeface;
+ return this;
+ }
+
@NonNull
public Builder codeTextSize(@Px int codeTextSize) {
this.codeTextSize = codeTextSize;
return this;
}
+ /**
+ * @since 3.0.0
+ */
+ @NonNull
+ public Builder codeBlockTextSize(@Px int codeTextSize) {
+ this.codeBlockTextSize = codeTextSize;
+ return this;
+ }
+
@NonNull
public Builder headingBreakHeight(@Px int headingBreakHeight) {
this.headingBreakHeight = headingBreakHeight;
diff --git a/markwon-core/src/main/java/ru/noties/markwon/core/factory/CodeBlockSpanFactory.java b/markwon-core/src/main/java/ru/noties/markwon/core/factory/CodeBlockSpanFactory.java
index 4fd07685..2bf9383e 100644
--- a/markwon-core/src/main/java/ru/noties/markwon/core/factory/CodeBlockSpanFactory.java
+++ b/markwon-core/src/main/java/ru/noties/markwon/core/factory/CodeBlockSpanFactory.java
@@ -6,12 +6,12 @@ import android.support.annotation.Nullable;
import ru.noties.markwon.MarkwonConfiguration;
import ru.noties.markwon.RenderProps;
import ru.noties.markwon.SpanFactory;
-import ru.noties.markwon.core.spans.CodeSpan;
+import ru.noties.markwon.core.spans.CodeBlockSpan;
public class CodeBlockSpanFactory implements SpanFactory {
@Nullable
@Override
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {
- return new CodeSpan(configuration.theme(), true);
+ return new CodeBlockSpan(configuration.theme());
}
}
diff --git a/markwon-core/src/main/java/ru/noties/markwon/core/factory/CodeSpanFactory.java b/markwon-core/src/main/java/ru/noties/markwon/core/factory/CodeSpanFactory.java
index 7726bc02..944556fb 100644
--- a/markwon-core/src/main/java/ru/noties/markwon/core/factory/CodeSpanFactory.java
+++ b/markwon-core/src/main/java/ru/noties/markwon/core/factory/CodeSpanFactory.java
@@ -12,6 +12,6 @@ public class CodeSpanFactory implements SpanFactory {
@Nullable
@Override
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {
- return new CodeSpan(configuration.theme(), false);
+ return new CodeSpan(configuration.theme());
}
}
diff --git a/markwon-core/src/main/java/ru/noties/markwon/core/spans/CodeBlockSpan.java b/markwon-core/src/main/java/ru/noties/markwon/core/spans/CodeBlockSpan.java
new file mode 100644
index 00000000..00109766
--- /dev/null
+++ b/markwon-core/src/main/java/ru/noties/markwon/core/spans/CodeBlockSpan.java
@@ -0,0 +1,66 @@
+package ru.noties.markwon.core.spans;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.support.annotation.NonNull;
+import android.text.Layout;
+import android.text.TextPaint;
+import android.text.style.LeadingMarginSpan;
+import android.text.style.MetricAffectingSpan;
+
+import ru.noties.markwon.core.MarkwonTheme;
+
+/**
+ * @since 3.0.0 split inline and block spans
+ */
+public class CodeBlockSpan extends MetricAffectingSpan implements LeadingMarginSpan {
+
+ private final MarkwonTheme theme;
+ private final Rect rect = ObjectsPool.rect();
+ private final Paint paint = ObjectsPool.paint();
+
+ public CodeBlockSpan(@NonNull MarkwonTheme theme) {
+ this.theme = theme;
+ }
+
+ @Override
+ public void updateMeasureState(TextPaint p) {
+ apply(p);
+ }
+
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ apply(ds);
+ }
+
+ private void apply(TextPaint p) {
+ theme.applyCodeBlockTextStyle(p);
+ }
+
+ @Override
+ public int getLeadingMargin(boolean first) {
+ return theme.getCodeBlockMargin();
+ }
+
+ @Override
+ public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {
+
+ paint.setStyle(Paint.Style.FILL);
+ paint.setColor(theme.getCodeBlockBackgroundColor(p));
+
+ final int left;
+ final int right;
+ if (dir > 0) {
+ left = x;
+ right = c.getWidth();
+ } else {
+ left = x - c.getWidth();
+ right = x;
+ }
+
+ rect.set(left, top, right, bottom);
+
+ c.drawRect(rect, paint);
+ }
+}
diff --git a/markwon-core/src/main/java/ru/noties/markwon/core/spans/CodeSpan.java b/markwon-core/src/main/java/ru/noties/markwon/core/spans/CodeSpan.java
index dc233538..856d5807 100644
--- a/markwon-core/src/main/java/ru/noties/markwon/core/spans/CodeSpan.java
+++ b/markwon-core/src/main/java/ru/noties/markwon/core/spans/CodeSpan.java
@@ -1,27 +1,20 @@
package ru.noties.markwon.core.spans;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
import android.support.annotation.NonNull;
-import android.text.Layout;
import android.text.TextPaint;
-import android.text.style.LeadingMarginSpan;
import android.text.style.MetricAffectingSpan;
import ru.noties.markwon.core.MarkwonTheme;
-public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan {
+/**
+ * @since 3.0.0 split inline and block spans
+ */
+public class CodeSpan extends MetricAffectingSpan {
private final MarkwonTheme theme;
- private final Rect rect = ObjectsPool.rect();
- private final Paint paint = ObjectsPool.paint();
- private final boolean multiline;
-
- public CodeSpan(@NonNull MarkwonTheme theme, boolean multiline) {
+ public CodeSpan(@NonNull MarkwonTheme theme) {
this.theme = theme;
- this.multiline = multiline;
}
@Override
@@ -32,41 +25,10 @@ public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan {
@Override
public void updateDrawState(TextPaint ds) {
apply(ds);
- if (!multiline) {
- ds.bgColor = theme.getCodeBackgroundColor(ds, false);
- }
+ ds.bgColor = theme.getCodeBackgroundColor(ds);
}
private void apply(TextPaint p) {
- theme.applyCodeTextStyle(p, multiline);
- }
-
- @Override
- public int getLeadingMargin(boolean first) {
- return multiline ? theme.getCodeMultilineMargin() : 0;
- }
-
- @Override
- public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {
-
- if (multiline) {
-
- paint.setStyle(Paint.Style.FILL);
- paint.setColor(theme.getCodeBackgroundColor(p, true));
-
- final int left;
- final int right;
- if (dir > 0) {
- left = x;
- right = c.getWidth();
- } else {
- left = x - c.getWidth();
- right = x;
- }
-
- rect.set(left, top, right, bottom);
-
- c.drawRect(rect, paint);
- }
+ theme.applyCodeTextStyle(p);
}
}
diff --git a/sample/src/main/java/ru/noties/markwon/sample/recycler/RecyclerActivity.java b/sample/src/main/java/ru/noties/markwon/sample/recycler/RecyclerActivity.java
index d366a64e..c230aa6c 100644
--- a/sample/src/main/java/ru/noties/markwon/sample/recycler/RecyclerActivity.java
+++ b/sample/src/main/java/ru/noties/markwon/sample/recycler/RecyclerActivity.java
@@ -13,8 +13,6 @@ import android.text.TextUtils;
import org.commonmark.ext.gfm.tables.TableBlock;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.node.FencedCodeBlock;
-import org.commonmark.node.Heading;
-import org.commonmark.node.SoftLineBreak;
import org.commonmark.parser.Parser;
import java.io.BufferedReader;
@@ -29,9 +27,7 @@ import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.MarkwonConfiguration;
import ru.noties.markwon.MarkwonVisitor;
-import ru.noties.markwon.SpanFactory;
import ru.noties.markwon.core.CorePlugin;
-import ru.noties.markwon.core.CoreProps;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.svg.SvgPlugin;
@@ -52,36 +48,6 @@ public class RecyclerActivity extends Activity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler);
- {
-final Markwon markwon = Markwon.builder(contex)
- .usePlugin(new AbstractMarkwonPlugin() {
-@Override
-public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
- builder.on(Heading.class, new MarkwonVisitor.NodeVisitor() {
- @Override
- public void visit(@NonNull MarkwonVisitor visitor, @NonNull Heading heading) {
-
- // or just `visitor.length()`
- final int start = visitor.builder().length();
-
- visitor.visitChildren(heading);
-
- // or just `visitor.setSpansForNodeOptional(heading, start)`
- final SpanFactory factory = visitor.configuration().spansFactory().get(heading.getClass());
- if (factory != null) {
- visitor.setSpans(start, factory.getSpans(visitor.configuration(), visitor.renderProps()));
- }
-
- if (visitor.hasNext(heading)) {
- visitor.ensureNewLine();
- visitor.forceNewLine();
- }
- }
- });
-}
- });
- }
-
// create MarkwonAdapter and register two blocks that will be rendered differently
// * fenced code block (can also specify the same Entry for indended code block)
// * table block