Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem :: Markdown processing NOT working for example :: {<bold-300|blue-500|text>}
Analysis MARKDOWN : Old View System vs New Compose System
OLD VIEW SYSTEM (MarkdownParser.java)
Architecture: TWO-PHASE Processing
Phase 1: Stack-Based Delimiter Matching (
getPreProcessedSpannableBuilder)**bold**,_italic_,~~strikethrough~~Phase 2: Regex-Based Transformation (
parseRegexTransformation)<weight-size|text>← Runs FIRST{color|text}← Runs SECOND{bg:color|text}Why
{<bold-300|blue-500|text>}WORKS in old system:NEW COMPOSE SYSTEM (MarkdownParser.kt)
Architecture: SINGLE-PHASE Sequential Processing
All processors run in a fixed chain (lines 38-47):
**text**_text_~~text~~{color|text}← Runs FIRST (among complex)<weight-size|text>← Runs SECOND[text](url)<u>text<u>Why
{<bold-300|blue-500|text>}FAILS in new system:Key Architectural Differences
.+?(non-greedy)((.|\\n)+?)(multiline support){<font|color|text>}works<font|{color|text}>workskotlin.runCatchingSolution Options
Since you cannot change backend response, here are 3 approaches:
Option 1: Swap Processor Order (Recommended)
Change MarkdownParser.kt to match old system's order:
Pros: Maintains backward compatibility with existing markdown
Cons: May break any new code expecting current order
Option 2: Syntax Preprocessing Layer
Add a preprocessor that converts old syntax to new:
Pros: No processor order changes, isolated fix
Cons: Extra processing overhead, may miss edge cases
Option 3: Smart Nested Pattern Detection
Enhance ColorProcessor to detect and skip nested patterns:
Pros: Surgical fix, no global changes
Cons: Complex logic, may affect performance
Recommended Approach
Option 1 (Swap Processor Order) is the best solution because:
The Problem in Detail
Your backend sends:
"{<bold-300|blue-500|You saved ₹220, including ₹41 with>} {<bold-300|cider-500|Gold>}"This has nested syntax: outer curly braces
{}wrapping inner angle brackets<>Current (Broken) Processing Flow
Processor Order:
**text**)_text_)~~text~~){color|text}) ← Problem starts here<weight-size|text>)Execution Step-by-Step:
Input Text:
Step 1-3: BoldProcessor, ItalicProcessor, StrikethroughProcessor
**,_,~~patterns"{<bold-300|blue-500|You saved>}"Step 4: ColorProcessor runs
ColorProcessor regex:
(\{)(.+?)(\|)((.|\\n)+?)(\})This matches:
{<bold-300|blue-500← PROBLEM!|You saved}The regex captures
<bold-300|blue-500as the "color" parameter because it greedily takes everything between{and the first|.ColorProcessor calls
parseColor("<bold-300|blue-500"):Since parsing fails, the transformation is skipped. Text remains:
"{<bold-300|blue-500|You saved>}"Step 5: FontWeightProcessor runs
FontWeightProcessor regex:
(\<)(.+?)(\|)((.|\\n)+?)(\>)This looks for pattern:
<...>In
"{<bold-300|blue-500|You saved>}", the angle brackets are trapped inside the curly braces. The regex cannot match because:<<at position after{><and>{}interfere with proper matchingText remains:
"{<bold-300|blue-500|You saved>}"← STILL UNSTYLEDStep 6-7: LinkProcessor, UnderlineAnnotaterProcessor
"{<bold-300|blue-500|You saved>}"← Raw text, no stylingFixed (Working) Processing Flow
New Processor Order (after swap):
**text**)_text_)~~text~~)<weight-size|text>) ← Now runs FIRST{color|text}) ← Now runs SECONDExecution Step-by-Step:
Input Text:
Step 1-3: BoldProcessor, ItalicProcessor, StrikethroughProcessor
"{<bold-300|blue-500|You saved>}"Step 4: FontWeightProcessor runs FIRST
FontWeightProcessor regex:
(\<)(.+?)(\|)((.|\\n)+?)(\>)This matches:
<bold-300|blue-500|You saved← Takes EVERYTHING after first|until>>Key insight: The regex captures
blue-500|You savedas the TEXT_GROUP because it uses(.+?)which matches everything (including the second|) until it hits>.Now FontWeightProcessor processes this:
After FontWeightProcessor, the text becomes:
The outer
{}remain, but the inner<>pattern has been consumed and replaced with styled text.Step 5: ColorProcessor runs SECOND
ColorProcessor regex:
(\{)(.+?)(\|)((.|\\n)+?)(\})This matches:
{blue-500← NOW VALID!|You saved}ColorProcessor calls
parseColor("blue-500"):Parsing succeeds! ColorProcessor transforms:
After ColorProcessor, the text becomes:
Step 6-7: LinkProcessor, UnderlineAnnotaterProcessor
"You saved"with bold-300 font styling + blue-500 color ← FULLY STYLED!Why Order Matters: The Critical Difference
Current Order (Color → Font): FAILS
Fixed Order (Font → Color): WORKS
The Regex Behavior Explained
Both processors use non-greedy matching
(.+?)but capture different amounts:FontWeightProcessor:
(\<)(.+?)(\|)((.|\\n)+?)(\>)|for FONT_GROUP>for TEXT_GROUP<bold-300|blue-500|text>extracts:bold-300blue-500|text← Includes the second|and everything afterColorProcessor:
(\{)(.+?)(\|)((.|\\n)+?)(\})|for COLOR_GROUP}for TEXT_GROUP{blue-500|text}extracts:blue-500textWhen FontWeightProcessor runs first, it "unwraps" the inner
<>layer, leaving a clean{color|text}pattern for ColorProcessor to handle correctly.Summary
Swapping the processor order fixes the issue because:
<bold-300|...>, consuming the angle brackets{color|text}syntax - no more nested brackets confusing the ColorProcessorThis matches the proven behavior of the old View system, ensuring backward compatibility with all existing backend markdown.
Before ::
After :::