@@ -21,7 +21,7 @@ struct MarkupNSAttributedStringVisitor: MarkupVisitor {
2121 }
2222
2323 func visit( _ markup: BreakLineMarkup ) -> Result {
24- return makeString ( in: markup, string: Self . breakLineSymbol, attributes: [ . breaklinePlaceholder: true ] )
24+ return makeString ( in: markup, string: Self . breakLineSymbol, attributes: [ . breaklinePlaceholder: NSAttributedString . Key . BreaklinePlaceholder . breaklineTag ] )
2525 }
2626
2727 func visit( _ markup: RawStringMarkup ) -> Result {
@@ -204,32 +204,44 @@ extension MarkupNSAttributedStringVisitor {
204204 // Find continues reduceable breakline and merge it.
205205 func reduceBreaklineInResultNSAttributedString( _ attributedString: NSAttributedString ) -> NSAttributedString {
206206 let mutableAttributedString = NSMutableAttributedString ( attributedString: attributedString)
207-
208- let breaklineLength = Self . breakLineSymbol. utf16. count
209207 let totalLength = mutableAttributedString. string. utf16. count
208+
209+ // merge tag Boundary Breakline, e.g. </p></div> -> /n/n -> /n
210+ var pre : ( NSRange , NSAttributedString . Key . BreaklinePlaceholder ) ?
210211 mutableAttributedString. enumerateAttribute ( . breaklinePlaceholder, in: NSMakeRange ( 0 , totalLength) ) { value, range, _ in
211- if let breaklinePlaceholder = value as? Bool , breaklinePlaceholder == true {
212- let thisAttributedString = mutableAttributedString. attributedSubstring ( from: range)
213- let thisAttributedStringTotalLength = thisAttributedString. string. utf16. count
214- var tagBoundaryBreaklinePlaceholderCount = 0
215- thisAttributedString. enumerateAttribute ( . tagBoundaryBreaklinePlaceholder, in: NSMakeRange ( 0 , thisAttributedStringTotalLength) ) { thisValue, thisRange, _ in
216- if let tagBoundaryBreaklinePlaceholder = thisValue as? Bool , tagBoundaryBreaklinePlaceholder == true {
217- tagBoundaryBreaklinePlaceholderCount += thisRange. length
218- }
219- }
220-
221- if tagBoundaryBreaklinePlaceholderCount > 0 {
222- if range. location == 0 {
223- mutableAttributedString. deleteCharacters ( in: range)
224- } else if range. length > breaklineLength {
225- // remove reduntant
226- var reset = range. length - tagBoundaryBreaklinePlaceholderCount
227- if reset < breaklineLength {
228- reset = breaklineLength
229- }
230- mutableAttributedString. replaceCharacters ( in: NSRange ( location: range. location, length: range. length) , with: String ( repeating: Self . breakLineSymbol, count: ( reset / breaklineLength) ) )
212+ if let breaklinePlaceholder = value as? NSAttributedString . Key . BreaklinePlaceholder {
213+ if range. location == 0 {
214+ mutableAttributedString. deleteCharacters ( in: range)
215+ } else if let pre = pre {
216+ let preRange = pre. 0
217+ let preBreaklinePlaceholder = pre. 1
218+
219+ switch ( preBreaklinePlaceholder, breaklinePlaceholder) {
220+ case ( . breaklineTag, . tagBoundarySuffix) :
221+ // <br/></div> -> /n/n -> /n
222+ mutableAttributedString. deleteCharacters ( in: preRange)
223+ case ( . breaklineTag, . tagBoundaryPrefix) :
224+ // <br/><p> -> /n/n -> /n
225+ mutableAttributedString. deleteCharacters ( in: preRange)
226+ case ( . tagBoundarySuffix, . tagBoundarySuffix) :
227+ // </div></div> -> /n/n -> /n
228+ mutableAttributedString. deleteCharacters ( in: preRange)
229+ case ( . tagBoundarySuffix, . tagBoundaryPrefix) :
230+ // </div><p> -> /n/n -> /n
231+ mutableAttributedString. deleteCharacters ( in: preRange)
232+ case ( . tagBoundaryPrefix, . tagBoundaryPrefix) :
233+ // <div><p> -> /n/n -> /n
234+ mutableAttributedString. deleteCharacters ( in: preRange)
235+ case ( . tagBoundaryPrefix, . tagBoundarySuffix) :
236+ // <p></p> -> /n/n -> /n
237+ mutableAttributedString. deleteCharacters ( in: preRange)
238+ default :
239+ break
231240 }
232241 }
242+ pre = ( range, breaklinePlaceholder)
243+ } else {
244+ pre = nil
233245 }
234246 }
235247
@@ -312,18 +324,22 @@ private extension MarkupNSAttributedStringVisitor {
312324}
313325
314326private extension NSAttributedString . Key {
315- static let reduceableBreakLine : NSAttributedString . Key = . init( " reduceableBreakLine " )
316-
317- static let tagBoundaryBreaklinePlaceholder : NSAttributedString . Key = . init( " tagBoundaryBreaklinePlaceholder " )
318327 static let breaklinePlaceholder : NSAttributedString . Key = . init( " breaklinePlaceholder " )
328+ struct BreaklinePlaceholder : OptionSet {
329+ let rawValue : Int
330+
331+ static let tagBoundaryPrefix = BreaklinePlaceholder ( rawValue: 1 )
332+ static let tagBoundarySuffix = BreaklinePlaceholder ( rawValue: 2 )
333+ static let breaklineTag = BreaklinePlaceholder ( rawValue: 3 )
334+ }
319335}
320336
321337private extension NSMutableAttributedString {
322338 func markPrefixTagBoundaryBreakline( ) {
323- self . insert ( NSAttributedString ( string: MarkupNSAttributedStringVisitor . breakLineSymbol, attributes: [ . tagBoundaryBreaklinePlaceholder : true , . breaklinePlaceholder: true ] ) , at: 0 )
339+ self . insert ( NSAttributedString ( string: MarkupNSAttributedStringVisitor . breakLineSymbol, attributes: [ . breaklinePlaceholder: NSAttributedString . Key . BreaklinePlaceholder . tagBoundaryPrefix ] ) , at: 0 )
324340 }
325341
326342 func markSuffixTagBoundaryBreakline( ) {
327- self . append ( NSAttributedString ( string: MarkupNSAttributedStringVisitor . breakLineSymbol, attributes: [ . tagBoundaryBreaklinePlaceholder : true , . breaklinePlaceholder: true ] ) )
343+ self . append ( NSAttributedString ( string: MarkupNSAttributedStringVisitor . breakLineSymbol, attributes: [ . breaklinePlaceholder: NSAttributedString . Key . BreaklinePlaceholder . tagBoundarySuffix ] ) )
328344 }
329345}
0 commit comments