Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add control of ParagraphSpacingPolicy to remove additional line breaks #37

Merged
merged 3 commits into from
Nov 24, 2023
Merged
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
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,29 @@ To extend the tag name and customize its style, you can use the ExtendTagName cl
let parser = ZHTMLParserBuilder.initWithDefault().add(ExtendTagName("zhgchgli"), withCustomStyle: MarkupStyle(backgroundColor: MarkupStyleColor(name: .aquamarine))).build()
```

#### Paragraph Spacing Policy

Often, you will want to create some type of spacing between various paragraphs or elements to increase legibility. There are two strategies to handle this:

1. Create additional line breaks in between paragraphs and sections. This means that there will be the size of 1 empty paragraph between each other paragraph. This is the default behaviour. In this mode you will likely want to ensure you are ***Not*** using paragraph spacing in in your markup styles.
2. Make use of `paragraphSpacing` through `MarkupStyleParagraphStyle` or `NSParagraphStyle`. If you are using these you will likely want to disable the additional line breaks.

This can be configured on your your `ZHTMLParserBuilder` as follows:

```swift
let parser = ZHTMLParserBuilder
.initWithDefault()
// Indicate that we should use paragraph spacing for spacing.
.set(spacingPolicy: .paragraphSpacing)
// Create our spacing using paragraphSpacing.
.set(rootStyle: .init(
paragraphStyle: .init(
paragraphSpacing: 12
)
))
.build()
```

### Render HTML String
```swift
parser.render(htmlString) // NSAttributedString
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct MarkupNSAttributedStringVisitor: MarkupVisitor {

let components: [MarkupStyleComponent]
let rootStyle: MarkupStyle?
var paragraphSpacingPolicy: ParagraphSpacingPolicy = .lineBreaks

func visit(_ markup: RootMarkup) -> Result {
return reduceBreaklineInResultNSAttributedString(collectAttributedString(markup))
Expand Down Expand Up @@ -82,14 +83,18 @@ struct MarkupNSAttributedStringVisitor: MarkupVisitor {

func visit(_ markup: ListMarkup) -> Result {
let attributedString = collectAttributedString(markup)
attributedString.append(makeBreakLine(in: markup))
if paragraphSpacingPolicy == .lineBreaks {
attributedString.append(makeBreakLine(in: markup))
}
attributedString.insert(makeBreakLine(in: markup), at: 0)
return attributedString
}

func visit(_ markup: ParagraphMarkup) -> Result {
let attributedString = collectAttributedString(markup)
attributedString.append(makeBreakLine(in: markup, reduceable: false))
if paragraphSpacingPolicy == .lineBreaks {
attributedString.append(makeBreakLine(in: markup, reduceable: false))
}
attributedString.insert(makeBreakLine(in: markup, reduceable: false), at: 0)
return attributedString
}
Expand Down Expand Up @@ -143,14 +148,18 @@ struct MarkupNSAttributedStringVisitor: MarkupVisitor {

func visit(_ markup: TableMarkup) -> Result {
let attributedString = collectAttributedString(markup)
attributedString.append(makeBreakLine(in: markup))
if paragraphSpacingPolicy == .lineBreaks {
attributedString.append(makeBreakLine(in: markup))
}
attributedString.insert(makeBreakLine(in: markup), at: 0)
return attributedString
}

func visit(_ markup: HeadMarkup) -> NSAttributedString {
let attributedString = collectAttributedString(markup)
attributedString.append(makeBreakLine(in: markup))
if paragraphSpacingPolicy == .lineBreaks {
attributedString.append(makeBreakLine(in: markup))
}
attributedString.insert(makeBreakLine(in: markup), at: 0)
return attributedString
}
Expand All @@ -163,7 +172,9 @@ struct MarkupNSAttributedStringVisitor: MarkupVisitor {

func visit(_ markup: BlockQuoteMarkup) -> NSAttributedString {
let attributedString = collectAttributedString(markup)
attributedString.append(makeBreakLine(in: markup))
if paragraphSpacingPolicy == .lineBreaks {
attributedString.append(makeBreakLine(in: markup))
}
attributedString.insert(makeBreakLine(in: markup), at: 0)
return attributedString
}
Expand Down
33 changes: 31 additions & 2 deletions Sources/ZMarkupParser/Core/Processor/MarkupRenderProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,46 @@

import Foundation

public enum ParagraphSpacingPolicy {
///
/// In this mode, line break will be used to create spacing between paragraphs
///
/// For example
/// Line 1
///
/// Line 2
case lineBreaks
///
/// In this mode new additional line breaks are added.
///
/// Instead the MarkupStyleParagraphStyle.paragraphSpacing will create spacing between paragraphs.
///
/// For example
/// Line 1
/// Line 2
///
case paragraphSpacing
}


final class MarkupRenderProcessor: ParserProcessor {
typealias From = (Markup, [MarkupStyleComponent])
typealias To = NSAttributedString

let rootStyle: MarkupStyle?
init(rootStyle: MarkupStyle?) {
let paragraphSpacingPolicy: ParagraphSpacingPolicy

init(rootStyle: MarkupStyle?, paragraphSpacingPolicy: ParagraphSpacingPolicy = .lineBreaks) {
self.rootStyle = rootStyle
self.paragraphSpacingPolicy = paragraphSpacingPolicy
}

func process(from: From) -> To {
let visitor = MarkupNSAttributedStringVisitor(components: from.1, rootStyle: rootStyle)
let visitor = MarkupNSAttributedStringVisitor(
components: from.1,
rootStyle: rootStyle,
paragraphSpacingPolicy: paragraphSpacingPolicy
)
return visitor.visit(markup: from.0)
}
}
10 changes: 8 additions & 2 deletions Sources/ZMarkupParser/HTML/ZHTMLParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ public final class ZHTMLParser {
lazy var htmlStringToParsedResult: HTMLStringToParsedResultProcessor = HTMLStringToParsedResultProcessor()
lazy var markupStripperProcessor: MarkupStripperProcessor = MarkupStripperProcessor()

init(htmlTags: [HTMLTag], styleAttributes: [HTMLTagStyleAttribute], policy: MarkupStylePolicy, rootStyle: MarkupStyle?) {
init(
htmlTags: [HTMLTag],
styleAttributes: [HTMLTagStyleAttribute],
policy: MarkupStylePolicy,
rootStyle: MarkupStyle?,
paragraphSpacingPolicy: ParagraphSpacingPolicy = .lineBreaks
) {
self.htmlTags = htmlTags
self.styleAttributes = styleAttributes
self.rootStyle = rootStyle

self.markupRenderProcessor = MarkupRenderProcessor(rootStyle: rootStyle)
self.markupRenderProcessor = MarkupRenderProcessor(rootStyle: rootStyle, paragraphSpacingPolicy: paragraphSpacingPolicy)

self.htmlParsedResultToHTMLElementWithRootMarkupProcessor = HTMLParsedResultToHTMLElementWithRootMarkupProcessor(htmlTags: htmlTags)
self.htmlElementWithMarkupToMarkupStyleProcessor = HTMLElementWithMarkupToMarkupStyleProcessor(styleAttributes: styleAttributes, policy: policy)
Expand Down
14 changes: 13 additions & 1 deletion Sources/ZMarkupParser/HTML/ZHTMLParserBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public final class ZHTMLParserBuilder {
private(set) var styleAttributes: [HTMLTagStyleAttribute] = []
private(set) var rootStyle: MarkupStyle? = .default
private(set) var policy: MarkupStylePolicy = .respectMarkupStyleFromHTMLStyleAttribute
private(set) var paragraphSpacingPolicy: ParagraphSpacingPolicy = .lineBreaks

public init() {

Expand Down Expand Up @@ -63,7 +64,18 @@ public final class ZHTMLParserBuilder {
return self
}

public func set(spacingPolicy: ParagraphSpacingPolicy) -> Self {
self.paragraphSpacingPolicy = spacingPolicy
return self
}

public func build() -> ZHTMLParser {
return ZHTMLParser(htmlTags: htmlTags, styleAttributes: styleAttributes, policy: policy, rootStyle: rootStyle)
return ZHTMLParser(
htmlTags: htmlTags,
styleAttributes: styleAttributes,
policy: policy,
rootStyle: rootStyle,
paragraphSpacingPolicy: paragraphSpacingPolicy
)
}
}