ZMarkupParser 是一个纯 Swift 库,可帮助您使用自定义样式和标签将 HTML 字符串转换为 NSAttributedString。
<a>Link<b>LinkBold</a>Bold</b><br>
-> <a>Link<b>LinkBold</b></a><b>Bold</b><br/>
)。<ul>
列表视图、<table>
表格视图、<img>
图像,以及 <hr>
水平线等等。NSAttributedString.DocumentType.html
相比,性能更好。要运行 ZMarkupParser 演示,请下载存储库并打开 ZMarkupParser.xcworkspace。然后,选择 ZMarkupParser-Demo 目标并运行它以开始探索该库。尽情享用!
(2022/M2/24GB 内存/macOS 13.2/XCode 14.1)
请注意,当 HTML 字符串的长度超过 54,600+ 个字符时,使用 DocumentType.html 选项渲染 NSAttributedString 可能会导致崩溃。 为避免此问题,请考虑改用 ZMarkupParser。
上图显示了渲染不同 HTML 字符串长度 (x) 所用的时间(以秒为单位)。 可以看出,ZMarkupParser 的性能优于 NSAttributedString.DocumentType.html,尤其是对于较大的 HTML 字符串。
https://github.com/ZhgChgLi/ZMarkupParser.git
或者
...
dependencies: [
.package(url: "https://github.com/ZhgChgLi/ZMarkupParser.git", from: "1.12.0"),
]
...
.target(
...
dependencies: [
"ZMarkupParser",
],
...
)
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
use_frameworks!
target 'MyApp' do
pod 'ZMarkupParser', '~> 1.12.0'
end
<a>Link<b>LinkBold</a>Bold</b>
[
{tagStart: "a"},
{string: "Link"},
{tagStart: "b"},
{string: "LinkBold"},
{tagClose: "a"},
{string: "Bold"},
{tagClose: "b"}
]
[
{tagStart: "a"},
{string: "Link"},
{tagStart: "b"},
{string: "LinkBold"},
{tagClose: "b"},
{tagClose: "a"},
{tagStart: "b"},
{string: "Bold"},
{tagClose: "b"}
]
RootMarkup
|--A
| |--String("Link")
| |--B
| |--String("LinkBold")
|
|--B
|--String("Bold")
RootMarkup
|--A(underline=true)
| |--String("Link")(color=blue, font=13pt)
| |--B
| |--String("LinkBold")(color=blue, font=18pt, bold=true)
|
|--B(font=18pt, bold=true)
结果
Link{
NSColor = "UIExtendedSRGBColorSpace 0 0.478431 1 1";
NSFont = "<UICTFont: 0x145d17600> font-family: \".SFUI-Regular\"; font-weight: normal; font-style: normal; font-size: 13.00pt";
NSUnderline = 1;
}LinkBold{
NSColor = "UIExtendedSRGBColorSpace 0 0.478431 1 1";
NSFont = "<UICTFont: 0x145d18710> font-family: \".SFUI-Semibold\"; font-weight: bold; font-style: normal; font-size: 18.00pt";
NSUnderline = 1;
}Bold{
NSFont = "<UICTFont: 0x145d18710> font-family: \".SFUI-Semibold\"; font-weight: bold; font-style: normal; font-size: 18.00pt";
}
ZMarkupParser 提供了一组预定义的标签名称,这些标签名称映射到抽象的 markup 类,例如 A_HTMLTagName() 用于 ,B_HTMLTagName() 用于 ,等等。 此映射用于在解析过程中创建相应的 markup 类的实例。
此外,如果存在未定义的标签或者您想自定义自己的标签,可以使用 ExtendTagName(tagName: String)
方法创建自定义标签名称,并将其映射到您自己设计的抽象 markup 类。
A_HTMLTagName(), // <a></a>
B_HTMLTagName(), // <b></b>
BR_HTMLTagName(), // <br></br> and also <br/>
DIV_HTMLTagName(), // <div></div>
HR_HTMLTagName(), // <hr></hr>
I_HTMLTagName(), // <i></i>
LI_HTMLTagName(), // <li></li>
OL_HTMLTagName(), // <ol></ol>
P_HTMLTagName(), // <p></p>
SPAN_HTMLTagName(), // <span></span>
STRONG_HTMLTagName(), // <strong></strong>
U_HTMLTagName(), // <u></u>
UL_HTMLTagName(), // <ul></ul>
DEL_HTMLTagName(), // <del></del>
IMG_HTMLTagName(handler: ZNSTextAttachmentHandler), // <img> and image downloader
TR_HTMLTagName(), // <tr>
TD_HTMLTagName(), // <td>
TH_HTMLTagName(), // <th>
...and more
MarkupStyle 包装器包含用于定义 NSAttributedString 属性的各种属性。 这些属性包括
var font:MarkupStyleFont
var paragraphStyle:MarkupStyleParagraphStyle
var foregroundColor:MarkupStyleColor? = nil
var backgroundColor:MarkupStyleColor? = nil
var ligature:NSNumber? = nil
var kern:NSNumber? = nil
var tracking:NSNumber? = nil
var strikethroughStyle:NSUnderlineStyle? = nil
var underlineStyle:NSUnderlineStyle? = nil
var strokeColor:MarkupStyleColor? = nil
var strokeWidth:NSNumber? = nil
var shadow:NSShadow? = nil
var textEffect:String? = nil
var attachment:NSTextAttachment? = nil
var link:URL? = nil
var baselineOffset:NSNumber? = nil
var underlineColor:MarkupStyleColor? = nil
var strikethroughColor:MarkupStyleColor? = nil
var obliqueness:NSNumber? = nil
var expansion:NSNumber? = nil
var writingDirection:NSNumber? = nil
var verticalGlyphForm:NSNumber? = nil
...
例如,您可以初始化或定义一个 MarkupStyle 对象,并设置所需的属性,例如将字体大小设置为 13,将背景颜色设置为海蓝色
MarkupStyle(font: MarkupStyleFont(size: 13), backgroundColor: MarkupStyleColor(name: .aquamarine))
这些是预定义的样式属性,可用于将 HTML 标签转换为 NSAttributedString 属性。 每个样式属性都有一个相应的类,用于定义其行为以及应如何将其应用于 NSAttributedString。
ColorHTMLTagStyleAttribute(), // color
BackgroundColorHTMLTagStyleAttribute(), // background-color
FontSizeHTMLTagStyleAttribute(), // font-size
FontWeightHTMLTagStyleAttribute(), // font-weight
LineHeightHTMLTagStyleAttribute(), // line-height
WordSpacingHTMLTagStyleAttribute(), // word-spacing
如果存在未定义的样式属性,则可以使用 ExtendHTMLTagStyleAttribute 类来定义它。 该类接受样式名称和一个闭包,该闭包接受现有样式和新样式属性的值,并返回应用了新属性的新样式。
例如:style="text-decoration"
ExtendHTMLTagStyleAttribute(styleName: "text-decoration", render: { fromStyle, value in
var newStyle = fromStyle
if value == "underline" {
newStyle.underline = NSUnderlineStyle.single
} else {
// ...
}
return newStyle
})
import ZMarkupParser
let parser = ZHTMLParserBuilder.initWithDefault().set(rootStyle: MarkupStyle(font: MarkupStyleFont(size: 13)).build()
该代码使用 initWithDefault()
方法,以默认设置初始化一个新的 ZHTMLParserBuilder 对象。 此方法添加所有预定义的 HTML 标签名称和样式属性,并将标签的默认 MarkupStyle 设置为渲染。
然后,调用 set(rootStyle: MarkupStyle)
方法来指定要渲染的默认根样式。 此根样式将应用于解析器生成的整个属性字符串。
最后,在末尾调用 build()
方法以生成解析器对象。
let parser = ZHTMLParserBuilder.initWithDefault().add(OL_HTMLTagName(), withCustomStyle: MarkupStyle(paragraphStyle: MarkupStyleParagraphStyle(textListStyleType: .circle, textListHeadIndent: 4, textListIndent: 8))).build()
这些代码片段演示了如何自定义标签的样式或扩展标签名称
要自定义标签的样式,可以使用 ZHTMLParserBuilder 类的 add 方法,并提供 HTMLTagName 的实例和 MarkupStyle 对象作为参数。 例如,以下代码片段将使用自定义 markup 样式来渲染 标签
let parser = ZHTMLParserBuilder.initWithDefault().add(B_HTMLTagName(), withCustomStyle: MarkupStyle(font: MarkupStyleFont(size: 18, weight: .style(.semibold)))).build()
要扩展标签名称并自定义其样式,可以使用 ExtendTagName 类和 ZHTMLParserBuilder 类的 add 方法。 例如,以下代码片段会将标签名称扩展为 并使用自定义 markup 样式来渲染它
let parser = ZHTMLParserBuilder.initWithDefault().add(ExtendTagName("zhgchgli"), withCustomStyle: MarkupStyle(backgroundColor: MarkupStyleColor(name: .aquamarine))).build()
class HTML 属性可以使用 HTMLTagClassAttribute 来定义具有预定义样式的 classNames。
HTML 允许指定多个以空格分隔的 class
属性,但是 id
属性每个 HTML 标签只能分配一个值。
例如
<span id="header">hey</span>hey <span id="text-red text-small">Teste de texto text small</span> hey<span class="text-red">hey</span>heyhey
let parser = ZHTMLParserBuilder.initWithDefault().add(HTMLTagClassAttribute(className: "text-red", render: {
return MarkupStyle(foregroundColor: MarkupStyleColor(color: .red))
})).add(HTMLTagClassAttribute(className: "text-small", render: {
return MarkupStyle(font: MarkupStyleFont(.systemFont(ofSize: 6)))
})).add(HTMLTagIdAttribute(idName: "header", render: {
return MarkupStyle(font: MarkupStyleFont(.systemFont(ofSize: 36)))
})).build()
parser.render(htmlString) // NSAttributedString
By default, ZMarkupParser will decode HTML entities using the [HTMLString](https://github.com/alexisakers/HTMLString) library.
If you wish to keep the raw data clean, you can disable this feature by using the following syntax: `parser.render(htmlString, forceDecodeHTMLEntities: false)` or `setHtmlString(attributedString, with: parser, forceDecodeHTMLEntities: false)`.
// work with UITextView
textView.setHtmlString(htmlString)
// work with UILabel
label.setHtmlString(htmlString)
parser.stripper(htmlString) // NSAttributedString
let selector = parser.selector(htmlString) // HTMLSelector e.g. input: <a><b>Test</b>Link</a>
selector.first("a")?.first("b").attributedString // will return Test
selector.filter("a").get() // will return dict struct
selector.filter("a") // will return json string of dict
let selector = parser.selector(htmlString) // HTMLSelector e.g. input: <a><b>Test</b>Link</a>
parser.render(selector.first("a")?.first("b"))
parser.render(String) { _ in }...
parser.stripper(String) { _ in }...
parser.selector(String) { _ in }...
如果要渲染巨大的 html 字符串,请改用异步。
MarkupStyleColor(sponsor: .pinkoi(.navy))
直接初始化颜色。Pinkoi.com 是亚洲领先的原创设计商品、数字创作和工作坊体验在线市场。
MarkupStyleVendorColor(vendor: .pinkoi(.navy))
直接初始化颜色。如果您觉得此库有帮助,请考虑为该 repo 点赞或将其推荐给您的朋友。
欢迎提出 issue 或通过拉取请求提交修复/贡献。:)