AttributedString 构建器

一种使用结果构建器从各种来源构建富文本字符串的简单方法。基于 Swift Talk 的剧集。以下是可以嵌入的内容

这是一个展示纯文本字符串、Markdown 和 SwiftUI 视图的示例

@AttributedStringBuilder
var example: some AttributedStringConvertible {
    "Hello, World!"
        .bold()
        .modify { $0.backgroundColor = .yellow }
    """
    This is some markdown with **strong** `code` text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tempus, tortor eu maximus gravida, ante diam fermentum magna, in gravida ex tellus ac purus.

    - One
    - Two
    - Three

    > A blockquote.
    """.markdown()
    Embed {
        HStack {
            Image(systemName: "hand.wave")
                .font(.largeTitle)
            Text("Hello from SwiftUI")
            Color.red.frame(width: 100, height: 50)
        }
    }

然后你可以像这样将此示例转换为多页 PDF

let data = await example
    .joined(separator: "\n") // join the parts using newlines
    .run(environment: .init(attributes: sampleAttributes)) // turn into a single `NSAttributedString`
    .pdf() // render as PDF
try! data.write(to: .desktopDirectory.appending(component: "out.pdf"))

这是一个更大的示例

功能特性

属性

Attributes 结构体是一个值类型,表示 NSAttributedString 中的属性。在构建富文本字符串期间,它通过环境传递。例如,这是如何使用纯文本字符串和 .modify 构建简单富文本字符串的方法

@AttributedStringBuilder var sample1: some AttributedStringConvertible {
    "Hello"
    "World".modify { $0.textColor = .red }
}

字符串

你可以直接将任何字符串转换为富文本字符串。环境中的属性用于执行此操作。你也可以以非常类似于 SwiftUI 的方式修改环境。例如,你可以编写 "Hello".bold()" 来获取当前属性,使其变为粗体,然后使用这些修改后的属性渲染字符串 "Hello"

Markdown

你可以将任何 Markdown 字符串渲染为富文本字符串。对于大多数自定义,你可以传入自定义的样式表。在 Markdown 字符串字面量中,你可以嵌入转换为 AttributedStringConvertible 的其他值

@AttributedStringBuilder var sample2: some AttributedStringConvertible {
    Markdown("""
    This is *Markdown* syntax.

    With \("inline".modify { $0.underlineStyle = .single }) nesting.
    """)
}

图像

你可以将任何 NSImage 嵌入到富文本字符串中,它们会按原样渲染。

SwiftUI 视图

可以使用 Embed 修饰符嵌入 SwiftUI 视图。默认情况下,它向视图建议 nil⨉nil,但这可以自定义。SwiftUI 视图被渲染到 PDF 上下文中,并作为矢量图形嵌入。

表格

你可以使用 Table 支持在富文本字符串中构建表格。此接口可能仍会更改(理想情况下,我们也将为此使用结果构建器)。

环境

你可以使用类似于 SwiftUI 环境的方式,将值向下传递到树中。

状态

与环境类似,你也可以通过状态线程传递。这对于(例如)为脚注编号很有用。虽然修改后的环境始终传递给当前节点的子节点,但修改后的状态会传递给接下来渲染的节点。

Swift Talk 剧集