@@ -94,8 +94,9 @@ public static String toHtml(Spanned text) {
9494 String normalizedBlockQuote =
9595 normalizedCodeBlock .replaceAll ("</blockquote>\\ n<br>" , "</blockquote>" );
9696
97- // Replace empty <p> tags (with or without style attributes) with <br>
98- String normalizedHtml = normalizedBlockQuote .replaceAll ("<p[^>]*></p>" , "<br>" );
97+ // Replace empty <p> tags with <br>, except when they carry text-align
98+ String normalizedHtml =
99+ normalizedBlockQuote .replaceAll ("<p(?![^>]*text-align\\ s*:)[^>]*></p>" , "<br>" );
99100
100101 return "<html>\n " + normalizedHtml + "</html>" ;
101102 }
@@ -593,7 +594,14 @@ private void handleEndTag(String tag) {
593594 if (tag .equalsIgnoreCase ("br" )) {
594595 handleBr (mSpannableStringBuilder );
595596 } else if (tag .equalsIgnoreCase ("p" )) {
597+ boolean empty = isEmptyTag ;
598+ Alignment pendingAlignment = empty ? getLast (mSpannableStringBuilder , Alignment .class ) : null ;
596599 endBlockElement (mSpannableStringBuilder , mSpanFactory );
600+ // Plain empty paragraphs never reach setParagraphSpanFromMark (no ZWS).
601+ // Represent them as a blank line so they round-trip as <br>.
602+ if (empty && pendingAlignment == null ) {
603+ handleBr (mSpannableStringBuilder );
604+ }
597605 } else if (tag .equalsIgnoreCase ("ul" )) {
598606 currentListAlignmentCssValue = null ;
599607 endBlockElement (mSpannableStringBuilder , mSpanFactory );
0 commit comments