V1.1.1 (#60)
* Fix OrderedListItemSpan text position (baseline) (#55) * Add softBreakAddsNewLine option for SpannableConfiguration (#54) * Paragraph text can now explicitly be spanned (#58) Thanks to @c-b-h! * Fix table border color if odd background is specified (#56) * Add table customizations (even and header rows)
This commit is contained in:
		
							parent
							
								
									7c7b1f59a8
								
							
						
					
					
						commit
						20159bef7f
					
				| @ -37,7 +37,7 @@ allprojects { | ||||
| and then in your module `build.gradle`: | ||||
| 
 | ||||
| ```groovy | ||||
| implementation 'ru.noties:markwon:1.1.0-SNAPSHOT' | ||||
| implementation 'ru.noties:markwon:1.1.1-SNAPSHOT' | ||||
| ``` | ||||
| 
 | ||||
| Please note that `markwon-image-loader`, `markwon-syntax` and `markwon-view` are also present in `SNAPSHOT` repository and share the same version as main `markwon` artifact. | ||||
|  | ||||
| @ -29,6 +29,14 @@ task wrapper(type: Wrapper) { | ||||
|     distributionType 'all' | ||||
| } | ||||
| 
 | ||||
| if (hasProperty('local')) { | ||||
|     if (!hasProperty('LOCAL_MAVEN_URL')) { | ||||
|         throw new RuntimeException('Cannot publish to local maven as no such property exists: LOCAL_MAVEN_URL') | ||||
|     } | ||||
|     ext.RELEASE_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|     ext.SNAPSHOT_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
| } | ||||
| 
 | ||||
| ext { | ||||
| 
 | ||||
|     // Config | ||||
|  | ||||
| @ -6,7 +6,7 @@ org.gradle.configureondemand=true | ||||
| android.enableBuildCache=true | ||||
| android.buildCacheDir=build/pre-dex-cache | ||||
| 
 | ||||
| VERSION_NAME=1.1.0 | ||||
| VERSION_NAME=1.1.1-SNAPSHOT | ||||
| 
 | ||||
| GROUP=ru.noties | ||||
| POM_DESCRIPTION=Markwon | ||||
|  | ||||
| @ -30,9 +30,5 @@ afterEvaluate { | ||||
| } | ||||
| 
 | ||||
| if (hasProperty('release')) { | ||||
|     if (hasProperty('local')) { | ||||
|         ext.RELEASE_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|         ext.SNAPSHOT_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|     } | ||||
|     apply from: 'https://raw.githubusercontent.com/noties/gradle-mvn-push/master/gradle-mvn-push-aar.gradle' | ||||
| } | ||||
|  | ||||
| @ -24,9 +24,5 @@ afterEvaluate { | ||||
| } | ||||
| 
 | ||||
| if (hasProperty('release')) { | ||||
|     if (hasProperty('local')) { | ||||
|         ext.RELEASE_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|         ext.SNAPSHOT_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|     } | ||||
|     apply from: 'https://raw.githubusercontent.com/noties/gradle-mvn-push/master/gradle-mvn-push-aar.gradle' | ||||
| } | ||||
|  | ||||
| @ -23,9 +23,5 @@ afterEvaluate { | ||||
| } | ||||
| 
 | ||||
| if (hasProperty('release')) { | ||||
|     if (hasProperty('local')) { | ||||
|         ext.RELEASE_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|         ext.SNAPSHOT_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|     } | ||||
|     apply from: 'https://raw.githubusercontent.com/noties/gradle-mvn-push/master/gradle-mvn-push-aar.gradle' | ||||
| } | ||||
|  | ||||
| @ -25,9 +25,5 @@ afterEvaluate { | ||||
| } | ||||
| 
 | ||||
| if (hasProperty('release')) { | ||||
|     if (hasProperty('local')) { | ||||
|         ext.RELEASE_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|         ext.SNAPSHOT_REPOSITORY_URL = LOCAL_MAVEN_URL | ||||
|     } | ||||
|     apply from: 'https://raw.githubusercontent.com/noties/gradle-mvn-push/master/gradle-mvn-push-aar.gradle' | ||||
| } | ||||
|  | ||||
| @ -32,6 +32,7 @@ public class SpannableConfiguration { | ||||
|     private final SpannableHtmlParser htmlParser; | ||||
|     private final ImageSizeResolver imageSizeResolver; | ||||
|     private final SpannableFactory factory; // @since 1.1.0 | ||||
|     private final boolean softBreakAddsNewLine; // @since 1.1.1 | ||||
| 
 | ||||
|     private SpannableConfiguration(@NonNull Builder builder) { | ||||
|         this.theme = builder.theme; | ||||
| @ -42,6 +43,7 @@ public class SpannableConfiguration { | ||||
|         this.htmlParser = builder.htmlParser; | ||||
|         this.imageSizeResolver = builder.imageSizeResolver; | ||||
|         this.factory = builder.factory; | ||||
|         this.softBreakAddsNewLine = builder.softBreakAddsNewLine; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
| @ -84,6 +86,15 @@ public class SpannableConfiguration { | ||||
|         return factory; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return a flag indicating if soft break should be treated as a hard | ||||
|      * break and thus adding a new line instead of adding a white space | ||||
|      * @since 1.1.1 | ||||
|      */ | ||||
|     public boolean softBreakAddsNewLine() { | ||||
|         return softBreakAddsNewLine; | ||||
|     } | ||||
| 
 | ||||
|     @SuppressWarnings("unused") | ||||
|     public static class Builder { | ||||
| 
 | ||||
| @ -95,7 +106,8 @@ public class SpannableConfiguration { | ||||
|         private UrlProcessor urlProcessor; | ||||
|         private SpannableHtmlParser htmlParser; | ||||
|         private ImageSizeResolver imageSizeResolver; | ||||
|         private SpannableFactory factory; | ||||
|         private SpannableFactory factory; // @since 1.1.0 | ||||
|         private boolean softBreakAddsNewLine; // @since 1.1.1 | ||||
| 
 | ||||
|         Builder(@NonNull Context context) { | ||||
|             this.context = context; | ||||
| @ -155,6 +167,19 @@ public class SpannableConfiguration { | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * @param softBreakAddsNewLine a flag indicating if soft break should be treated as a hard | ||||
|          *                             break and thus adding a new line instead of adding a white space | ||||
|          * @return self | ||||
|          * @see <a href="https://spec.commonmark.org/0.28/#soft-line-breaks">spec</a> | ||||
|          * @since 1.1.1 | ||||
|          */ | ||||
|         @NonNull | ||||
|         public Builder softBreakAddsNewLine(boolean softBreakAddsNewLine) { | ||||
|             this.softBreakAddsNewLine = softBreakAddsNewLine; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         @NonNull | ||||
|         public SpannableConfiguration build() { | ||||
| 
 | ||||
|  | ||||
| @ -56,6 +56,12 @@ public interface SpannableFactory { | ||||
|             boolean isHeader, | ||||
|             boolean isOdd); | ||||
| 
 | ||||
|     /** | ||||
|      * @since 1.1.1 | ||||
|      */ | ||||
|     @Nullable | ||||
|     Object paragraph(boolean inTightList); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object image( | ||||
|             @NonNull SpannableTheme theme, | ||||
|  | ||||
| @ -103,6 +103,15 @@ public class SpannableFactoryDef implements SpannableFactory { | ||||
|         return new TableRowSpan(theme, cells, isHeader, isOdd); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @since 1.1.1 | ||||
|      */ | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object paragraph(boolean inTightList) { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object image(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull AsyncDrawable.Loader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) { | ||||
|  | ||||
| @ -256,9 +256,13 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(SoftLineBreak softLineBreak) { | ||||
|         // at first here was a new line, but here should be a space char | ||||
|         // @since 1.1.1 there is an option to treat soft break as a hard break (thus adding new line) | ||||
|         if (configuration.softBreakAddsNewLine()) { | ||||
|             newLine(); | ||||
|         } else { | ||||
|             builder.append(' '); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(HardLineBreak hardLineBreak) { | ||||
| @ -376,15 +380,18 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Paragraph paragraph) { | ||||
| 
 | ||||
|         final boolean inTightList = isInTightList(paragraph); | ||||
| 
 | ||||
|         if (!inTightList) { | ||||
|             newLine(); | ||||
|         } | ||||
| 
 | ||||
|         final int length = builder.length(); | ||||
|         visitChildren(paragraph); | ||||
| 
 | ||||
|         // @since 1.1.1 apply paragraph span | ||||
|         setSpan(length, factory.paragraph(inTightList)); | ||||
| 
 | ||||
|         if (!inTightList) { | ||||
|             newLine(); | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,8 @@ import android.support.annotation.NonNull; | ||||
| abstract class CanvasUtils { | ||||
| 
 | ||||
|     static float textCenterY(int top, int bottom, @NonNull Paint paint) { | ||||
|         return (int) (bottom - ((bottom - top) / 2) - ((paint.descent() + paint.ascent()) / 2.F + .5F)); | ||||
|         // @since 1.1.1 it's `top +` and not `bottom -` | ||||
|         return (int) (top + ((bottom - top) / 2) - ((paint.descent() + paint.ascent()) / 2.F + .5F)); | ||||
|     } | ||||
| 
 | ||||
|     private CanvasUtils() { | ||||
|  | ||||
| @ -59,8 +59,7 @@ public class OrderedListItemSpan implements LeadingMarginSpan { | ||||
|             left = x + (width * dir) + (width - numberWidth); | ||||
|         } | ||||
| 
 | ||||
|         final float numberY = CanvasUtils.textCenterY(top, bottom, p); | ||||
| 
 | ||||
|         c.drawText(number, left, numberY, p); | ||||
|         // @since 1.1.1 we are using `baseline` argument to position text | ||||
|         c.drawText(number, left, baseline, p); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -206,6 +206,14 @@ public class SpannableTheme { | ||||
|     // by default paint.color * TABLE_ODD_ROW_DEF_ALPHA | ||||
|     protected final int tableOddRowBackgroundColor; | ||||
| 
 | ||||
|     // @since 1.1.1 | ||||
|     // by default no background | ||||
|     protected final int tableEventRowBackgroundColor; | ||||
| 
 | ||||
|     // @since 1.1.1 | ||||
|     // by default no background | ||||
|     protected final int tableHeaderRowBackgroundColor; | ||||
| 
 | ||||
|     // drawable that will be used to render checkbox (should be stateful) | ||||
|     // TaskListDrawable can be used | ||||
|     protected final Drawable taskListDrawable; | ||||
| @ -236,6 +244,8 @@ public class SpannableTheme { | ||||
|         this.tableBorderColor = builder.tableBorderColor; | ||||
|         this.tableBorderWidth = builder.tableBorderWidth; | ||||
|         this.tableOddRowBackgroundColor = builder.tableOddRowBackgroundColor; | ||||
|         this.tableEventRowBackgroundColor = builder.tableEvenRowBackgroundColor; | ||||
|         this.tableHeaderRowBackgroundColor = builder.tableHeaderRowBackgroundColor; | ||||
|         this.taskListDrawable = builder.taskListDrawable; | ||||
|     } | ||||
| 
 | ||||
| @ -493,6 +503,23 @@ public class SpannableTheme { | ||||
|         paint.setStyle(Paint.Style.FILL); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @since 1.1.1 | ||||
|      */ | ||||
|     public void applyTableEvenRowStyle(@NonNull Paint paint) { | ||||
|         // by default to background to even row | ||||
|         paint.setColor(tableEventRowBackgroundColor); | ||||
|         paint.setStyle(Paint.Style.FILL); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @since 1.1.1 | ||||
|      */ | ||||
|     public void applyTableHeaderRowStyle(@NonNull Paint paint) { | ||||
|         paint.setColor(tableHeaderRowBackgroundColor); | ||||
|         paint.setStyle(Paint.Style.FILL); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return a Drawable to be used as a checkbox indication in task lists | ||||
|      * @since 1.0.1 | ||||
| @ -530,6 +557,8 @@ public class SpannableTheme { | ||||
|         private int tableBorderColor; | ||||
|         private int tableBorderWidth = -1; | ||||
|         private int tableOddRowBackgroundColor; | ||||
|         private int tableEvenRowBackgroundColor; // @since 1.1.1 | ||||
|         private int tableHeaderRowBackgroundColor; // @since 1.1.1 | ||||
|         private Drawable taskListDrawable; | ||||
| 
 | ||||
|         Builder() { | ||||
| @ -733,6 +762,24 @@ public class SpannableTheme { | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * @since 1.1.1 | ||||
|          */ | ||||
|         @NonNull | ||||
|         public Builder tableEvenRowBackgroundColor(@ColorInt int tableEvenRowBackgroundColor) { | ||||
|             this.tableEvenRowBackgroundColor = tableEvenRowBackgroundColor; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * @since 1.1.1 | ||||
|          */ | ||||
|         @NonNull | ||||
|         public Builder tableHeaderRowBackgroundColor(int tableHeaderRowBackgroundColor) { | ||||
|             this.tableHeaderRowBackgroundColor = tableHeaderRowBackgroundColor; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Supplied Drawable must be stateful ({@link Drawable#isStateful()} returns true). If a task | ||||
|          * is marked as done, then this drawable will be updated with an {@code int[] { android.R.attr.state_checked }} | ||||
|  | ||||
| @ -157,18 +157,35 @@ public class TableRowSpan extends ReplacementSpan { | ||||
|         // feels like magic... | ||||
|         final int heightDiff = (bottom - top - height) / 4; | ||||
| 
 | ||||
|         if (odd) { | ||||
|         // @since 1.1.1 | ||||
|         // draw backgrounds | ||||
|         { | ||||
|             if (header) { | ||||
|                 theme.applyTableHeaderRowStyle(this.paint); | ||||
|             } else if (odd) { | ||||
|                 theme.applyTableOddRowStyle(this.paint); | ||||
|             } else { | ||||
|                 // even | ||||
|                 theme.applyTableEvenRowStyle(this.paint); | ||||
|             } | ||||
| 
 | ||||
|             // if present (0 is transparent) | ||||
|             if (this.paint.getColor() != 0) { | ||||
|                 final int save = canvas.save(); | ||||
|                 try { | ||||
|                     rect.set(0, 0, width, bottom - top); | ||||
|                 theme.applyTableOddRowStyle(this.paint); | ||||
|                     canvas.translate(x, top - heightDiff); | ||||
|                     canvas.drawRect(rect, this.paint); | ||||
|                 } finally { | ||||
|                     canvas.restoreToCount(save); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // @since 1.1.1 reset after applying background color | ||||
|         // as background changes color attribute and if not specific tableBorderColor | ||||
|         // is specified then after this row all borders will have color of this row (plus alpha) | ||||
|         this.paint.set(paint); | ||||
|         theme.applyTableBorderStyle(this.paint); | ||||
| 
 | ||||
|         final int borderWidth = theme.tableBorderWidth(paint); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dimitry
						Dimitry