@expensify/react-native-live-markdown 0.1.194 → 0.1.196

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,116 @@
1
+ package com.expensify.livemarkdown;
2
+
3
+ import android.content.res.AssetManager;
4
+ import android.text.SpannableStringBuilder;
5
+ import android.text.Spanned;
6
+
7
+ import androidx.annotation.NonNull;
8
+
9
+ import com.expensify.livemarkdown.spans.*;
10
+ import com.facebook.react.views.text.internal.span.CustomLineHeightSpan;
11
+
12
+ import java.util.List;
13
+ import java.util.Objects;
14
+
15
+ public class MarkdownFormatter {
16
+ private final @NonNull AssetManager mAssetManager;
17
+
18
+ public MarkdownFormatter(@NonNull AssetManager assetManager) {
19
+ mAssetManager = assetManager;
20
+ }
21
+
22
+ public void format(SpannableStringBuilder ssb, List<MarkdownRange> markdownRanges, @NonNull MarkdownStyle markdownStyle) {
23
+ Objects.requireNonNull(markdownStyle, "mMarkdownStyle is null");
24
+ removeSpans(ssb);
25
+ applyRanges(ssb, markdownRanges, markdownStyle);
26
+ }
27
+
28
+ private void removeSpans(SpannableStringBuilder ssb) {
29
+ // We shouldn't use `removeSpans()` because it also removes SpellcheckSpan, SuggestionSpan etc.
30
+ MarkdownSpan[] spans = ssb.getSpans(0, ssb.length(), MarkdownSpan.class);
31
+ for (MarkdownSpan span : spans) {
32
+ ssb.removeSpan(span);
33
+ }
34
+ }
35
+
36
+ private void applyRanges(SpannableStringBuilder ssb, List<MarkdownRange> markdownRanges, @NonNull MarkdownStyle markdownStyle) {
37
+ for (MarkdownRange markdownRange : markdownRanges) {
38
+ applyRange(ssb, markdownRange, markdownStyle);
39
+ }
40
+ }
41
+
42
+ private void applyRange(SpannableStringBuilder ssb, MarkdownRange markdownRange, MarkdownStyle markdownStyle) {
43
+ String type = markdownRange.getType();
44
+ int start = markdownRange.getStart();
45
+ int end = start + markdownRange.getLength();
46
+ switch (type) {
47
+ case "bold":
48
+ setSpan(ssb, new MarkdownBoldSpan(), start, end);
49
+ break;
50
+ case "italic":
51
+ setSpan(ssb, new MarkdownItalicSpan(), start, end);
52
+ break;
53
+ case "strikethrough":
54
+ setSpan(ssb, new MarkdownStrikethroughSpan(), start, end);
55
+ break;
56
+ case "emoji":
57
+ setSpan(ssb, new MarkdownEmojiSpan(markdownStyle.getEmojiFontSize()), start, end);
58
+ break;
59
+ case "mention-here":
60
+ setSpan(ssb, new MarkdownForegroundColorSpan(markdownStyle.getMentionHereColor()), start, end);
61
+ setSpan(ssb, new MarkdownBackgroundColorSpan(markdownStyle.getMentionHereBackgroundColor()), start, end);
62
+ break;
63
+ case "mention-user":
64
+ // TODO: change mention color when it mentions current user
65
+ setSpan(ssb, new MarkdownForegroundColorSpan(markdownStyle.getMentionUserColor()), start, end);
66
+ setSpan(ssb, new MarkdownBackgroundColorSpan(markdownStyle.getMentionUserBackgroundColor()), start, end);
67
+ break;
68
+ case "mention-report":
69
+ setSpan(ssb, new MarkdownForegroundColorSpan(markdownStyle.getMentionReportColor()), start, end);
70
+ setSpan(ssb, new MarkdownBackgroundColorSpan(markdownStyle.getMentionReportBackgroundColor()), start, end);
71
+ break;
72
+ case "syntax":
73
+ setSpan(ssb, new MarkdownForegroundColorSpan(markdownStyle.getSyntaxColor()), start, end);
74
+ break;
75
+ case "link":
76
+ setSpan(ssb, new MarkdownUnderlineSpan(), start, end);
77
+ setSpan(ssb, new MarkdownForegroundColorSpan(markdownStyle.getLinkColor()), start, end);
78
+ break;
79
+ case "code":
80
+ setSpan(ssb, new MarkdownFontFamilySpan(markdownStyle.getCodeFontFamily(), mAssetManager), start, end);
81
+ setSpan(ssb, new MarkdownFontSizeSpan(markdownStyle.getCodeFontSize()), start, end);
82
+ setSpan(ssb, new MarkdownForegroundColorSpan(markdownStyle.getCodeColor()), start, end);
83
+ setSpan(ssb, new MarkdownBackgroundColorSpan(markdownStyle.getCodeBackgroundColor()), start, end);
84
+ break;
85
+ case "pre":
86
+ setSpan(ssb, new MarkdownFontFamilySpan(markdownStyle.getPreFontFamily(), mAssetManager), start, end);
87
+ setSpan(ssb, new MarkdownFontSizeSpan(markdownStyle.getPreFontSize()), start, end);
88
+ setSpan(ssb, new MarkdownForegroundColorSpan(markdownStyle.getPreColor()), start, end);
89
+ setSpan(ssb, new MarkdownBackgroundColorSpan(markdownStyle.getPreBackgroundColor()), start, end);
90
+ break;
91
+ case "h1":
92
+ setSpan(ssb, new MarkdownBoldSpan(), start, end);
93
+ CustomLineHeightSpan[] spans = ssb.getSpans(0, ssb.length(), CustomLineHeightSpan.class);
94
+ if (spans.length >= 1) {
95
+ int lineHeight = spans[0].getLineHeight();
96
+ setSpan(ssb, new MarkdownLineHeightSpan(lineHeight * 1.5f), start, end);
97
+ }
98
+ // NOTE: size span must be set after line height span to avoid height jumps
99
+ setSpan(ssb, new MarkdownFontSizeSpan(markdownStyle.getH1FontSize()), start, end);
100
+ break;
101
+ case "blockquote":
102
+ MarkdownBlockquoteSpan span = new MarkdownBlockquoteSpan(
103
+ markdownStyle.getBlockquoteBorderColor(),
104
+ markdownStyle.getBlockquoteBorderWidth(),
105
+ markdownStyle.getBlockquoteMarginLeft(),
106
+ markdownStyle.getBlockquotePaddingLeft(),
107
+ markdownRange.getDepth());
108
+ setSpan(ssb, span, start, end);
109
+ break;
110
+ }
111
+ }
112
+
113
+ private void setSpan(SpannableStringBuilder ssb, MarkdownSpan span, int start, int end) {
114
+ ssb.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
115
+ }
116
+ }
@@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
4
4
 
5
5
  import com.facebook.react.bridge.ReactContext;
6
6
  import com.facebook.react.util.RNLog;
7
+ import com.facebook.soloader.SoLoader;
7
8
 
8
9
  import org.json.JSONArray;
9
10
  import org.json.JSONException;
@@ -14,6 +15,10 @@ import java.util.LinkedList;
14
15
  import java.util.List;
15
16
 
16
17
  public class MarkdownParser {
18
+ static {
19
+ SoLoader.loadLibrary("livemarkdown");
20
+ }
21
+
17
22
  private final @NonNull ReactContext mReactContext;
18
23
  private String mPrevText;
19
24
  private int mPrevParserId;
@@ -1,31 +1,21 @@
1
1
  package com.expensify.livemarkdown;
2
2
 
3
- import android.content.res.AssetManager;
4
3
  import android.text.SpannableStringBuilder;
5
- import android.text.Spanned;
6
4
 
7
5
  import androidx.annotation.NonNull;
8
6
 
9
- import com.expensify.livemarkdown.spans.*;
10
7
  import com.facebook.react.bridge.ReactContext;
11
- import com.facebook.react.views.text.internal.span.CustomLineHeightSpan;
12
- import com.facebook.soloader.SoLoader;
13
8
 
14
9
  import java.util.List;
15
- import java.util.Objects;
16
10
 
17
11
  public class MarkdownUtils {
18
- static {
19
- SoLoader.loadLibrary("livemarkdown");
20
- }
21
-
22
12
  public MarkdownUtils(@NonNull ReactContext reactContext) {
23
- mAssetManager = reactContext.getAssets();
24
13
  mMarkdownParser = new MarkdownParser(reactContext);
14
+ mMarkdownFormatter = new MarkdownFormatter(reactContext.getAssets());
25
15
  }
26
16
 
27
- private final @NonNull AssetManager mAssetManager;
28
17
  private final @NonNull MarkdownParser mMarkdownParser;
18
+ private final @NonNull MarkdownFormatter mMarkdownFormatter;
29
19
 
30
20
  private MarkdownStyle mMarkdownStyle;
31
21
  private int mParserId;
@@ -39,98 +29,8 @@ public class MarkdownUtils {
39
29
  }
40
30
 
41
31
  public void applyMarkdownFormatting(SpannableStringBuilder ssb) {
42
- Objects.requireNonNull(mMarkdownStyle, "mMarkdownStyle is null");
43
-
44
- removeSpans(ssb);
45
-
46
32
  String text = ssb.toString();
47
33
  List<MarkdownRange> markdownRanges = mMarkdownParser.parse(text, mParserId);
48
-
49
- for (MarkdownRange markdownRange : markdownRanges) {
50
- applyRange(ssb, markdownRange);
51
- }
52
- }
53
-
54
- private void applyRange(SpannableStringBuilder ssb, MarkdownRange markdownRange) {
55
- String type = markdownRange.getType();
56
- int start = markdownRange.getStart();
57
- int end = start + markdownRange.getLength();
58
- switch (type) {
59
- case "bold":
60
- setSpan(ssb, new MarkdownBoldSpan(), start, end);
61
- break;
62
- case "italic":
63
- setSpan(ssb, new MarkdownItalicSpan(), start, end);
64
- break;
65
- case "strikethrough":
66
- setSpan(ssb, new MarkdownStrikethroughSpan(), start, end);
67
- break;
68
- case "emoji":
69
- setSpan(ssb, new MarkdownEmojiSpan(mMarkdownStyle.getEmojiFontSize()), start, end);
70
- break;
71
- case "mention-here":
72
- setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getMentionHereColor()), start, end);
73
- setSpan(ssb, new MarkdownBackgroundColorSpan(mMarkdownStyle.getMentionHereBackgroundColor()), start, end);
74
- break;
75
- case "mention-user":
76
- // TODO: change mention color when it mentions current user
77
- setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getMentionUserColor()), start, end);
78
- setSpan(ssb, new MarkdownBackgroundColorSpan(mMarkdownStyle.getMentionUserBackgroundColor()), start, end);
79
- break;
80
- case "mention-report":
81
- setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getMentionReportColor()), start, end);
82
- setSpan(ssb, new MarkdownBackgroundColorSpan(mMarkdownStyle.getMentionReportBackgroundColor()), start, end);
83
- break;
84
- case "syntax":
85
- setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getSyntaxColor()), start, end);
86
- break;
87
- case "link":
88
- setSpan(ssb, new MarkdownUnderlineSpan(), start, end);
89
- setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getLinkColor()), start, end);
90
- break;
91
- case "code":
92
- setSpan(ssb, new MarkdownFontFamilySpan(mMarkdownStyle.getCodeFontFamily(), mAssetManager), start, end);
93
- setSpan(ssb, new MarkdownFontSizeSpan(mMarkdownStyle.getCodeFontSize()), start, end);
94
- setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getCodeColor()), start, end);
95
- setSpan(ssb, new MarkdownBackgroundColorSpan(mMarkdownStyle.getCodeBackgroundColor()), start, end);
96
- break;
97
- case "pre":
98
- setSpan(ssb, new MarkdownFontFamilySpan(mMarkdownStyle.getPreFontFamily(), mAssetManager), start, end);
99
- setSpan(ssb, new MarkdownFontSizeSpan(mMarkdownStyle.getPreFontSize()), start, end);
100
- setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getPreColor()), start, end);
101
- setSpan(ssb, new MarkdownBackgroundColorSpan(mMarkdownStyle.getPreBackgroundColor()), start, end);
102
- break;
103
- case "h1":
104
- setSpan(ssb, new MarkdownBoldSpan(), start, end);
105
- CustomLineHeightSpan[] spans = ssb.getSpans(0, ssb.length(), CustomLineHeightSpan.class);
106
- if (spans.length >= 1) {
107
- int lineHeight = spans[0].getLineHeight();
108
- setSpan(ssb, new MarkdownLineHeightSpan(lineHeight * 1.5f), start, end);
109
- }
110
- // NOTE: size span must be set after line height span to avoid height jumps
111
- setSpan(ssb, new MarkdownFontSizeSpan(mMarkdownStyle.getH1FontSize()), start, end);
112
- break;
113
- case "blockquote":
114
- MarkdownBlockquoteSpan span = new MarkdownBlockquoteSpan(
115
- mMarkdownStyle.getBlockquoteBorderColor(),
116
- mMarkdownStyle.getBlockquoteBorderWidth(),
117
- mMarkdownStyle.getBlockquoteMarginLeft(),
118
- mMarkdownStyle.getBlockquotePaddingLeft(),
119
- markdownRange.getDepth());
120
- setSpan(ssb, span, start, end);
121
- break;
122
- }
123
- }
124
-
125
- private void setSpan(SpannableStringBuilder ssb, MarkdownSpan span, int start, int end) {
126
- ssb.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
127
- }
128
-
129
- private void removeSpans(SpannableStringBuilder ssb) {
130
- // We shouldn't use `removeSpans()` because it also removes SpellcheckSpan, SuggestionSpan etc.
131
- MarkdownSpan[] spans = ssb.getSpans(0, ssb.length(), MarkdownSpan.class);
132
- for (MarkdownSpan span : spans) {
133
- ssb.removeSpan(span);
134
- }
34
+ mMarkdownFormatter.format(ssb, markdownRanges, mMarkdownStyle);
135
35
  }
136
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expensify/react-native-live-markdown",
3
- "version": "0.1.194",
3
+ "version": "0.1.196",
4
4
  "description": "Drop-in replacement for React Native's TextInput component with Markdown formatting.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",