JLatexMathPlugin add error handling
This commit is contained in:
		
							parent
							
								
									c98f456744
								
							
						
					
					
						commit
						a1f12641c3
					
				| @ -13,8 +13,12 @@ | |||||||
|   ``` |   ``` | ||||||
| * `JLatexMathPlugin`: add `theme` (to customize both inlines and blocks) | * `JLatexMathPlugin`: add `theme` (to customize both inlines and blocks) | ||||||
| * `JLatexMathPlugin`: add `renderMode` to use previous (pre `4.3.0`) LaTeX rendering | * `JLatexMathPlugin`: add `renderMode` to use previous (pre `4.3.0`) LaTeX rendering | ||||||
|  | * add `JLatexMathPlugin.ErrorHandler` to catch latex rendering errors and (optionally) display error drawable ([#204]) | ||||||
| * add `SoftBreakAddsNewLinePlugin` plugin (`core` module) | * add `SoftBreakAddsNewLinePlugin` plugin (`core` module) | ||||||
| * `LinkResolverDef` defaults to `https` when a link does not have scheme information | * `LinkResolverDef` defaults to `https` when a link does not have scheme information ([#75]) | ||||||
|  | 
 | ||||||
|  | [#75]: https://github.com/noties/Markwon/issues/75 | ||||||
|  | [#204]: https://github.com/noties/Markwon/issues/204  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # 4.2.2 | # 4.2.2 | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ import io.noties.markwon.image.AsyncDrawable; | |||||||
| import io.noties.markwon.image.AsyncDrawableLoader; | import io.noties.markwon.image.AsyncDrawableLoader; | ||||||
| import io.noties.markwon.image.AsyncDrawableScheduler; | import io.noties.markwon.image.AsyncDrawableScheduler; | ||||||
| import io.noties.markwon.image.AsyncDrawableSpan; | import io.noties.markwon.image.AsyncDrawableSpan; | ||||||
|  | import io.noties.markwon.image.DrawableUtils; | ||||||
| import io.noties.markwon.image.ImageSizeResolver; | import io.noties.markwon.image.ImageSizeResolver; | ||||||
| import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; | import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; | ||||||
| import ru.noties.jlatexmath.JLatexMathDrawable; | import ru.noties.jlatexmath.JLatexMathDrawable; | ||||||
| @ -62,6 +63,22 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin { | |||||||
|         BLOCKS_AND_INLINES |         BLOCKS_AND_INLINES | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * @since 4.3.0-SNAPSHOT | ||||||
|  |      */ | ||||||
|  |     public interface ErrorHandler { | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * @param latex that caused the error or null if operated `AsyncDrawable` | ||||||
|  |          *              is not an instance of `JLatexAsyncDrawable` | ||||||
|  |          * @param error occurred | ||||||
|  |          * @return (optional) error drawable that will be used instead (if drawable will have bounds | ||||||
|  |          * it will be used, if not intrinsic bounds will be set) | ||||||
|  |          */ | ||||||
|  |         @Nullable | ||||||
|  |         Drawable handleError(@Nullable String latex, @NonNull Throwable error); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public interface BuilderConfigure { |     public interface BuilderConfigure { | ||||||
|         void configureBuilder(@NonNull Builder builder); |         void configureBuilder(@NonNull Builder builder); | ||||||
|     } |     } | ||||||
| @ -125,11 +142,15 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin { | |||||||
|         // @since 4.3.0-SNAPSHOT |         // @since 4.3.0-SNAPSHOT | ||||||
|         private final RenderMode renderMode; |         private final RenderMode renderMode; | ||||||
| 
 | 
 | ||||||
|  |         // @since 4.3.0-SNAPSHOT | ||||||
|  |         private final ErrorHandler errorHandler; | ||||||
|  | 
 | ||||||
|         private final ExecutorService executorService; |         private final ExecutorService executorService; | ||||||
| 
 | 
 | ||||||
|         Config(@NonNull Builder builder) { |         Config(@NonNull Builder builder) { | ||||||
|             this.theme = builder.theme.build(); |             this.theme = builder.theme.build(); | ||||||
|             this.renderMode = builder.renderMode; |             this.renderMode = builder.renderMode; | ||||||
|  |             this.errorHandler = builder.errorHandler; | ||||||
|             // @since 4.0.0 |             // @since 4.0.0 | ||||||
|             ExecutorService executorService = builder.executorService; |             ExecutorService executorService = builder.executorService; | ||||||
|             if (executorService == null) { |             if (executorService == null) { | ||||||
| @ -284,6 +305,9 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin { | |||||||
|         // @since 4.3.0-SNAPSHOT |         // @since 4.3.0-SNAPSHOT | ||||||
|         private RenderMode renderMode = RenderMode.BLOCKS_AND_INLINES; |         private RenderMode renderMode = RenderMode.BLOCKS_AND_INLINES; | ||||||
| 
 | 
 | ||||||
|  |         // @since 4.3.0-SNAPSHOT | ||||||
|  |         private ErrorHandler errorHandler; | ||||||
|  | 
 | ||||||
|         // @since 4.0.0 |         // @since 4.0.0 | ||||||
|         private ExecutorService executorService; |         private ExecutorService executorService; | ||||||
| 
 | 
 | ||||||
| @ -305,6 +329,12 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin { | |||||||
|             return this; |             return this; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         @NonNull | ||||||
|  |         public Builder errorHandler(@Nullable ErrorHandler errorHandler) { | ||||||
|  |             this.errorHandler = errorHandler; | ||||||
|  |             return this; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         /** |         /** | ||||||
|          * @since 4.0.0 |          * @since 4.0.0 | ||||||
|          */ |          */ | ||||||
| @ -351,10 +381,24 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin { | |||||||
|                         try { |                         try { | ||||||
|                             execute(); |                             execute(); | ||||||
|                         } catch (Throwable t) { |                         } catch (Throwable t) { | ||||||
|                             Log.e( |                             // @since 4.3.0-SNAPSHOT add error handling | ||||||
|                                     "JLatexMathPlugin", |                             final ErrorHandler errorHandler = config.errorHandler; | ||||||
|                                     "Error displaying latex: `" + drawable.getDestination() + "`", |                             if (errorHandler == null) { | ||||||
|                                     t); |                                 // as before | ||||||
|  |                                 Log.e( | ||||||
|  |                                         "JLatexMathPlugin", | ||||||
|  |                                         "Error displaying latex: `" + drawable.getDestination() + "`", | ||||||
|  |                                         t); | ||||||
|  |                             } else { | ||||||
|  |                                 final Drawable errorDrawable = errorHandler.handleError( | ||||||
|  |                                         drawable.getDestination(), | ||||||
|  |                                         t | ||||||
|  |                                 ); | ||||||
|  |                                 if (errorDrawable != null) { | ||||||
|  |                                     DrawableUtils.applyIntrinsicBoundsIfEmpty(errorDrawable); | ||||||
|  |                                     setResult(drawable, errorDrawable); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
| @ -370,19 +414,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin { | |||||||
|                             jLatexMathDrawable = createInlineDrawable(jLatextAsyncDrawable.getDestination()); |                             jLatexMathDrawable = createInlineDrawable(jLatextAsyncDrawable.getDestination()); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|                         // we must post to handler, but also have a way to identify the drawable |                         setResult(drawable, jLatexMathDrawable); | ||||||
|                         // for which we are posting (in case of cancellation) |  | ||||||
|                         handler.postAtTime(new Runnable() { |  | ||||||
|                             @Override |  | ||||||
|                             public void run() { |  | ||||||
|                                 // remove entry from cache (it will be present if task is not cancelled) |  | ||||||
|                                 if (cache.remove(drawable) != null |  | ||||||
|                                         && drawable.isAttached()) { |  | ||||||
|                                     drawable.setResult(jLatexMathDrawable); |  | ||||||
|                                 } |  | ||||||
| 
 |  | ||||||
|                             } |  | ||||||
|                         }, drawable, SystemClock.uptimeMillis()); |  | ||||||
|                     } |                     } | ||||||
|                 })); |                 })); | ||||||
|             } |             } | ||||||
| @ -456,6 +488,23 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin { | |||||||
| 
 | 
 | ||||||
|             return builder.build(); |             return builder.build(); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         // @since 4.3.0-SNAPSHOT | ||||||
|  |         private void setResult(@NonNull final AsyncDrawable drawable, @NonNull final Drawable result) { | ||||||
|  |             // we must post to handler, but also have a way to identify the drawable | ||||||
|  |             // for which we are posting (in case of cancellation) | ||||||
|  |             handler.postAtTime(new Runnable() { | ||||||
|  |                 @Override | ||||||
|  |                 public void run() { | ||||||
|  |                     // remove entry from cache (it will be present if task is not cancelled) | ||||||
|  |                     if (cache.remove(drawable) != null | ||||||
|  |                             && drawable.isAttached()) { | ||||||
|  |                         drawable.setResult(result); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                 } | ||||||
|  |             }, drawable, SystemClock.uptimeMillis()); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static class InlineImageSizeResolver extends ImageSizeResolver { |     private static class InlineImageSizeResolver extends ImageSizeResolver { | ||||||
|  | |||||||
| @ -2,12 +2,15 @@ package io.noties.markwon.sample.latex; | |||||||
| 
 | 
 | ||||||
| import android.content.res.Resources; | import android.content.res.Resources; | ||||||
| import android.graphics.drawable.ColorDrawable; | import android.graphics.drawable.ColorDrawable; | ||||||
|  | import android.graphics.drawable.Drawable; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.widget.TextView; | import android.widget.TextView; | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||||
|  | import androidx.core.content.ContextCompat; | ||||||
| 
 | 
 | ||||||
|  | import io.noties.debug.Debug; | ||||||
| import io.noties.markwon.Markwon; | import io.noties.markwon.Markwon; | ||||||
| import io.noties.markwon.ext.latex.JLatexMathPlugin; | import io.noties.markwon.ext.latex.JLatexMathPlugin; | ||||||
| import io.noties.markwon.ext.latex.JLatexMathTheme; | import io.noties.markwon.ext.latex.JLatexMathTheme; | ||||||
| @ -57,6 +60,7 @@ public class LatexActivity extends ActivityWithMenuOptions { | |||||||
|                 .add("bangle", this::bangle) |                 .add("bangle", this::bangle) | ||||||
|                 .add("boxes", this::boxes) |                 .add("boxes", this::boxes) | ||||||
|                 .add("insideBlockQuote", this::insideBlockQuote) |                 .add("insideBlockQuote", this::insideBlockQuote) | ||||||
|  |                 .add("error", this::error) | ||||||
|                 .add("legacy", this::legacy); |                 .add("legacy", this::legacy); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -95,6 +99,27 @@ public class LatexActivity extends ActivityWithMenuOptions { | |||||||
|         render(md); |         render(md); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private void error() { | ||||||
|  |         final String md = wrapLatexInSampleMarkdown("\\sum_{i=0}^\\infty x \\cdot 0 \\rightarrow \\iMightNotExist{0}"); | ||||||
|  | 
 | ||||||
|  |         final Markwon markwon = Markwon.builder(this) | ||||||
|  |                 .usePlugin(MarkwonInlineParserPlugin.create()) | ||||||
|  |                 .usePlugin(JLatexMathPlugin.create(textView.getTextSize(), builder -> { | ||||||
|  |                     //noinspection Convert2Lambda | ||||||
|  |                     builder.errorHandler(new JLatexMathPlugin.ErrorHandler() { | ||||||
|  |                         @Nullable | ||||||
|  |                         @Override | ||||||
|  |                         public Drawable handleError(@Nullable String latex, @NonNull Throwable error) { | ||||||
|  |                             Debug.e(error, latex); | ||||||
|  |                             return ContextCompat.getDrawable(LatexActivity.this, R.drawable.ic_android_black_24dp); | ||||||
|  |                         } | ||||||
|  |                     }); | ||||||
|  |                 })) | ||||||
|  |                 .build(); | ||||||
|  | 
 | ||||||
|  |         markwon.setMarkdown(textView, md); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private void legacy() { |     private void legacy() { | ||||||
|         final String md = wrapLatexInSampleMarkdown(LATEX_BANGLE); |         final String md = wrapLatexInSampleMarkdown(LATEX_BANGLE); | ||||||
| 
 | 
 | ||||||
| @ -127,22 +152,22 @@ public class LatexActivity extends ActivityWithMenuOptions { | |||||||
|         final float textSize = textView.getTextSize(); |         final float textSize = textView.getTextSize(); | ||||||
|         final Resources r = getResources(); |         final Resources r = getResources(); | ||||||
| 
 | 
 | ||||||
| final Markwon markwon = Markwon.builder(this) |         final Markwon markwon = Markwon.builder(this) | ||||||
|         // NB! `MarkwonInlineParserPlugin` is required in order to parse inlines |                 // NB! `MarkwonInlineParserPlugin` is required in order to parse inlines | ||||||
|         .usePlugin(MarkwonInlineParserPlugin.create()) |                 .usePlugin(MarkwonInlineParserPlugin.create()) | ||||||
|         .usePlugin(JLatexMathPlugin.create(textSize, textSize * 1.25F, builder -> { |                 .usePlugin(JLatexMathPlugin.create(textSize, textSize * 1.25F, builder -> { | ||||||
|             builder.theme() |                     builder.theme() | ||||||
|                     .inlineBackgroundProvider(() -> new ColorDrawable(0x1000ff00)) |                             .inlineBackgroundProvider(() -> new ColorDrawable(0x1000ff00)) | ||||||
|                     .blockBackgroundProvider(() -> new ColorDrawable(0x10ff0000)) |                             .blockBackgroundProvider(() -> new ColorDrawable(0x10ff0000)) | ||||||
|                     .blockPadding(JLatexMathTheme.Padding.symmetric( |                             .blockPadding(JLatexMathTheme.Padding.symmetric( | ||||||
|                             r.getDimensionPixelSize(R.dimen.latex_block_padding_vertical), |                                     r.getDimensionPixelSize(R.dimen.latex_block_padding_vertical), | ||||||
|                             r.getDimensionPixelSize(R.dimen.latex_block_padding_horizontal) |                                     r.getDimensionPixelSize(R.dimen.latex_block_padding_horizontal) | ||||||
|                     )); |                             )); | ||||||
| 
 | 
 | ||||||
|             // explicitly request LEGACY rendering mode |                     // explicitly request LEGACY rendering mode | ||||||
| //                    builder.renderMode(JLatexMathPlugin.RenderMode.LEGACY); | //                    builder.renderMode(JLatexMathPlugin.RenderMode.LEGACY); | ||||||
|         })) |                 })) | ||||||
|         .build(); |                 .build(); | ||||||
| 
 | 
 | ||||||
|         markwon.setMarkdown(textView, markdown); |         markwon.setMarkdown(textView, markdown); | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dimitry Ivanov
						Dimitry Ivanov