Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions android/src/main/cpp/jni-adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ static jint nodeTypeToJavaOrdinal(NodeType type) {
return 25;
case NodeType::Spoiler:
return 26;
case NodeType::Superscript:
return 27;
case NodeType::Subscript:
return 28;
default:
return 0;
}
Expand Down Expand Up @@ -206,6 +210,14 @@ JNIEXPORT jobject JNICALL Java_com_swmansion_enriched_markdown_parser_Parser_nat
if (latexMathField) {
md4cFlags.latexMath = env->GetBooleanField(flags, latexMathField) == JNI_TRUE;
}
jfieldID superscriptField = env->GetFieldID(flagsClass, "superscript", "Z");
if (superscriptField) {
md4cFlags.superscript = env->GetBooleanField(flags, superscriptField) == JNI_TRUE;
}
jfieldID subscriptField = env->GetFieldID(flagsClass, "subscript", "Z");
if (subscriptField) {
md4cFlags.subscript = env->GetBooleanField(flags, subscriptField) == JNI_TRUE;
}
jfieldID permissiveAutolinksField = env->GetFieldID(flagsClass, "permissiveAutolinks", "Z");
if (permissiveAutolinksField) {
md4cFlags.permissiveAutolinks = env->GetBooleanField(flags, permissiveAutolinksField) == JNI_TRUE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ object MeasurementStore {
Md4cFlags(
underline = props.getMapOrNull("md4cFlags").getBooleanOrDefault("underline", false),
latexMath = FeatureFlags.IS_MATH_ENABLED && props.getMapOrNull("md4cFlags").getBooleanOrDefault("latexMath", true),
superscript = props.getMapOrNull("md4cFlags").getBooleanOrDefault("superscript", false),
subscript = props.getMapOrNull("md4cFlags").getBooleanOrDefault("subscript", false),
)

val fontSize = getInitialFontSize(styleMap, context, allowFontScaling, fontScale, maxFontSizeMultiplier)
Expand Down Expand Up @@ -344,6 +346,8 @@ object MeasurementStore {
Md4cFlags(
underline = props.getMapOrNull("md4cFlags").getBooleanOrDefault("underline", false),
latexMath = FeatureFlags.IS_MATH_ENABLED && props.getMapOrNull("md4cFlags").getBooleanOrDefault("latexMath", true),
superscript = props.getMapOrNull("md4cFlags").getBooleanOrDefault("superscript", false),
subscript = props.getMapOrNull("md4cFlags").getBooleanOrDefault("subscript", false),
)
val allowTrailingMargin = props.getBooleanOrDefault("allowTrailingMargin", false)
val fontSize = getInitialFontSize(styleMap, context, allowFontScaling, fontScale, maxFontSizeMultiplier)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ data class MarkdownASTNode(
LatexMathInline,
LatexMathDisplay,
Spoiler,
Superscript,
Subscript,
}

fun getAttribute(key: String): String? = attributes[key]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import com.swmansion.enriched.markdown.utils.common.FeatureFlags
data class Md4cFlags(
val underline: Boolean = false,
val latexMath: Boolean = FeatureFlags.IS_MATH_ENABLED,
val superscript: Boolean = false,
val subscript: Boolean = false,
val permissiveAutolinks: Boolean = true,
) {
companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.swmansion.enriched.markdown.renderer

import android.text.SpannableStringBuilder
import com.swmansion.enriched.markdown.parser.MarkdownASTNode
import com.swmansion.enriched.markdown.spans.BaselineShiftSpan
import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE

abstract class BaselineShiftRenderer(
private val fontScale: Float,
private val baselineOffsetScale: Float,
) : NodeRenderer {
override fun render(
node: MarkdownASTNode,
builder: SpannableStringBuilder,
onLinkPress: ((String) -> Unit)?,
onLinkLongPress: ((String) -> Unit)?,
factory: RendererFactory,
) {
val start = builder.length
factory.renderChildren(node, builder, onLinkPress, onLinkLongPress)
val end = builder.length

if (end > start) {
builder.setSpan(
BaselineShiftSpan(fontScale, baselineOffsetScale),
start,
end,
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class RendererFactory(
put(MarkdownASTNode.NodeType.Emphasis, EmphasisRenderer(config))
put(MarkdownASTNode.NodeType.Strikethrough, StrikethroughRenderer(config))
put(MarkdownASTNode.NodeType.Underline, UnderlineRenderer(config))
put(MarkdownASTNode.NodeType.Superscript, SuperscriptRenderer())
put(MarkdownASTNode.NodeType.Subscript, SubscriptRenderer())
put(MarkdownASTNode.NodeType.Code, CodeRenderer(config))
put(MarkdownASTNode.NodeType.Image, ImageRenderer())
put(MarkdownASTNode.NodeType.LineBreak, lineBreakRenderer)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.swmansion.enriched.markdown.renderer

private const val SUBSCRIPT_FONT_SCALE = 0.75f
private const val SUBSCRIPT_BASELINE_OFFSET_SCALE = 0.2f

class SubscriptRenderer : BaselineShiftRenderer(SUBSCRIPT_FONT_SCALE, SUBSCRIPT_BASELINE_OFFSET_SCALE)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.swmansion.enriched.markdown.renderer

private const val SUPERSCRIPT_FONT_SCALE = 0.75f
private const val SUPERSCRIPT_BASELINE_OFFSET_SCALE = -0.35f

class SuperscriptRenderer : BaselineShiftRenderer(SUPERSCRIPT_FONT_SCALE, SUPERSCRIPT_BASELINE_OFFSET_SCALE)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.swmansion.enriched.markdown.spans

import android.text.TextPaint
import android.text.style.MetricAffectingSpan
import kotlin.math.roundToInt

class BaselineShiftSpan(
private val fontScale: Float,
val baselineOffsetScale: Float,
) : MetricAffectingSpan() {
override fun updateDrawState(tp: TextPaint) {
applyShift(tp)
}

override fun updateMeasureState(tp: TextPaint) {
applyShift(tp)
}

private fun applyShift(tp: TextPaint) {
val originalTextSize = tp.textSize
tp.textSize = originalTextSize * fontScale
tp.baselineShift += (originalTextSize * baselineOffsetScale).roundToInt()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ fun parseMd4cFlags(flags: ReadableMap?): Md4cFlags =
Md4cFlags(
underline = flags?.getBoolean("underline") ?: false,
latexMath = FeatureFlags.IS_MATH_ENABLED && (flags?.getBoolean("latexMath") ?: true),
superscript = flags?.getBoolean("superscript") ?: false,
subscript = flags?.getBoolean("subscript") ?: false,
)

fun parseContextMenuItems(value: ReadableArray?): List<String> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ object MarkdownASTSerializer {
buffer.append("__")
}

NodeType.Superscript -> {
buffer.append("^")
appendChildren(node, buffer)
buffer.append("^")
}

NodeType.Subscript -> {
buffer.append("~")
appendChildren(node, buffer)
buffer.append("~")
}

NodeType.Code -> {
buffer.append("`")
appendChildren(node, buffer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.text.Spannable
import android.text.style.UnderlineSpan
import android.widget.TextView
import com.swmansion.enriched.markdown.EnrichedMarkdownText
import com.swmansion.enriched.markdown.spans.BaselineShiftSpan
import com.swmansion.enriched.markdown.spans.BlockquoteSpan
import com.swmansion.enriched.markdown.spans.CodeBlockSpan
import com.swmansion.enriched.markdown.spans.CodeSpan
Expand Down Expand Up @@ -300,6 +301,9 @@ object MarkdownExtractor {
val hasCode = spannable.getSpans(start, end, CodeSpan::class.java).isNotEmpty()
val hasStrikethrough = spannable.getSpans(start, end, StrikethroughSpan::class.java).isNotEmpty()
val hasUnderline = spannable.getSpans(start, end, UnderlineSpan::class.java).isNotEmpty()
val baselineShiftSpans = spannable.getSpans(start, end, BaselineShiftSpan::class.java)
val hasSuperscript = baselineShiftSpans.any { it.baselineOffsetScale < 0f }
val hasSubscript = baselineShiftSpans.any { it.baselineOffsetScale > 0f }
val linkSpans = spannable.getSpans(start, end, LinkSpan::class.java)

var result = text
Expand All @@ -311,6 +315,12 @@ object MarkdownExtractor {
if (hasStrikethrough) {
result = "~~$result~~"
}
if (hasSubscript) {
result = "~$result~"
}
if (hasSuperscript) {
result = "^$result^"
}
if (hasUnderline && linkSpans.isEmpty()) {
result = "<u>$result</u>"
}
Expand All @@ -321,7 +331,7 @@ object MarkdownExtractor {
result = "**$result**"
}
if (linkSpans.isNotEmpty()) {
result = "[$text](${linkSpans[0].url})"
result = "[$result](${linkSpans[0].url})"
}

return result
Expand Down
6 changes: 3 additions & 3 deletions apps/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2117,7 +2117,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
FBLazyVector: e97c19a5a442429d1988f182a1940fb08df514da
hermes-engine: b0f9c82a51be8e938eb979ada628323e1e093f1d
hermes-engine: 40811a005e96e04818cff405ec04a5b4c4411c1c
iosMath: f7a6cbadf9d836d2149c2a84c435b1effc244cba
RCTDeprecation: af44b104091a34482596cd9bd7e8d90c4e9b4bd7
RCTRequired: bb77b070f75f53398ce43c0aaaa58337cebe2bf6
Expand All @@ -2127,7 +2127,7 @@ SPEC CHECKSUMS:
React: 1ba7d364ade7d883a1ec055bfc3606f35fdee17b
React-callinvoker: bc2a26f8d84fb01f003fc6de6c9337b64715f95b
React-Core: 7840d3a80b43a95c5e80ef75146bd70925ebab0f
React-Core-prebuilt: 3dc04e91547fc0f260f4b84c12da0f672b813862
React-Core-prebuilt: 7965d06a81dcc544164f8e98b26d35ae2a4eb36e
React-CoreModules: 2eb010400b63b89e53a324ffb3c112e4c7c3ce42
React-cxxreact: a558e92199d26f145afa9e62c4233cf8e7950efe
React-debug: 755200a6e7f5e6e0a40ff8d215493d43cce285fc
Expand Down Expand Up @@ -2189,7 +2189,7 @@ SPEC CHECKSUMS:
ReactAppDependencyProvider: e96e93b493d8d86eeaee3e590ba0be53f6abe46f
ReactCodegen: 797de5178718324c6eba3327b07f9a423fbd5787
ReactCommon: 07572bf9e687c8a52fbe4a3641e9e3a1a477c78e
ReactNativeDependencies: 44f7326a697de7f6c8629036b1a4689f0e64c684
ReactNativeDependencies: 0811b43c669e637a9f3c485fdb106f187fa88398
ReactNativeEnrichedMarkdown: e6fea750b1ca4cbd853c1c78de9bd1ccb638ab77
Yoga: c0b3f2c7e8d3e327e450223a2414ca3fa296b9a2

Expand Down
Loading
Loading