Skip to content

Repository files navigation

💰 RichStringKit 🔡


GitHub Workflow StatusUpdated

RichStringKit is a declarative DSL for building rich text in Swift.

Table of Contents

  1. Motivation 🧐
  2. Documentation 📖
  3. Installation 💻
  4. Usage 🔡

Motivation 🧐

NSAttributedString is a powerful tool for creating rich text, but using it can be cumbersome and error-prone. Consider the following attributed text:

Image of an attributed string that reads 'For the love of Swift' with the Swift programming language logo

Creating this text with NSAttributedString might look something like this:

letattributedString=NSMutableAttributedString(
string:"For the love of Swift ",
attributes:[.font:UIFont.systemFont(ofSize:40)])letstrongAttributes:[NSAttributedString.Key:Any]=[.foregroundColor:UIColor.swift,.font:UIFont.boldSystemFont(ofSize:40)]iflet swiftLogo =UIImage(systemName:"swift"){letswiftLogoAttachment=NSTextAttachment(image: swiftLogo)letswiftLogoString=NSAttributedString(attachment: swiftLogoAttachment)
attributedString.append(swiftLogoString)iflet swiftRange = attributedString.string.range(of:"Swift"){letstrongRange= swiftRange.lowerBound ..< attributedString.string.endIndex
attributedString.addAttributes(
strongAttributes,
range:NSRange(strongRange, in: attributedString.string))}}

Creating the same text with RichStringKit looks like this:

letrichString=NSAttributedString{"For the love of "Group{"Swift "Attachment(systemName:"swift")}.foregroundColor(.swift).font(.boldSystemFont(ofSize:40))}

Documentation 📖

Full documentation coming soon

Until then, take a look at some example usage.

Installation 💻

RichStringKit requires Swift 5.7

Swift Package Manager 📦

RichStringKit can be added as a package dependency via Xcode or in your Package.swift file.

Xcode

  • File > Swift Packages > Add Package Dependency
  • Add https://github.com/moyerr/RichStringKit.git
  • Select "Up to Next Major" with 0.0.1

Package.swift

Add the following value to the dependencies array:

.package(url:"https://github.com/moyerr/RichStringKit", from:"0.0.1")

Include it as a dependency for one or more of your targets:

.target(
name:"<your-target>", dependencies:[.product(name:"RichStringKit",package:"RichStringKit"),])

Usage 🔡

Rich String Result Builder

The mechanism that enables RichStringKit's declarative DSL is the RichStringBuilder, which is a @resultBuilder similar to SwiftUI's ViewBuilder. Closures, methods, and computed properties that return some RichString can be decorated with the @RichStringBuilder attribute to enable the DSL within them. For example:

@RichStringBuildervarrichText:someRichString{"Underlined text".underlineStyle(.single)" and ""strikethrough text".strikethroughStyle(.single)}

For more general information about Swift's result builder types, see the Result Builder section of The Swift Programming Language.

Convenience Initializers

For convenience, RichStringKit provides initializers on NSAttributedString, AttributedString, and SwiftUI's Text view, all of which can either accept a RichString or a @RichStringBuilder closure. So you can start start using rich strings with your UI framework of choice.

Use the NSAttributedString initializers when working with UIKit:

letlabel=UILabel()
label.attributedString =NSAttributedString{"UIKit".font(.boldSystemFont(ofSize:14))" is ""fun".kern(4).foregroundColor(.green)}

Use the Text or AttributedString initializers when working with SwiftUI:

structContentView:View{varbody:someView{Text{"SwiftUI".font(.boldSystemFont(ofSize:14))" is also ""fun".kern(4).foregroundColor(.green)}}}

Modifiers

Style your text using the modifiers that RichStringKit provides, or by defining your own modifiers using the RichStringModifier protocol and the modifier(_:) method.

Built-in Modifiers

RichStringKit provides many modifiers for styling text, most of which map directly to attribute keys from NSAttributedString.Key. The modifier methods that are currently available are:

  1. .backgroundColor(_:)
  2. .baselineOffset(_:)
  3. .font(_:)
  4. .foregroundColor(_:)
  5. .kern(_:)
  6. .link(_:)
  7. .strikethroughStyle(_:)
  8. .underlineColor(_:)
  9. .underlineStyle(_:)

More attributes will be added soon (#7).

Combining Modifiers

Adopt the RichStringModifier protocol when you want to create a reusable modifier that you can apply to any RichString. The example below combines modifiers to create a new modifier that you can use to create highlighted text with a yellow background and a dark foreground:

structHighlight:RichStringModifier{func body(_ content:Content)->someRichString{
content
.foregroundColor(.black).backgroundColor(.yellow)}}

You can apply modifier(_:) directly to a rich string, but a more common and idiomatic approach uses modifier(_:) to define an extension on RichString itself that incorporates the modifier:

extensionRichString{func highlighted()->someRichString{modifier(Highlight())}}

Then you can apply the highlight modifier to any rich string:

varbody:someRichText{"Draw the reader's attention to important information ""by applying a highlight".highlighted()}

Advanced Usage

Formatted Strings

The Format type is provided to apply styling to formatted strings and their arguments independently.

Format("For the love of %@"){Group{"Swift "Attachment(systemName:"swift")}.foregroundColor(.swift).font(.boldSystemFont(ofSize:40))}.font(.systemFont(ofSize:40))

Note:RichStringKit currently supports only the %@ format specifier. If your use case requires more advanced formatting, you can apply the formatting before inserting it into the final format string. For example:

letreceiptLine=AttributedString{Format("Iced latte: %@"){String(format:"%10.2f",-4.49).foregroundColor(.red)}}
// Iced latte: -4.49

About

A declarative DSL for building rich text in Swift

Resources

Stars

8 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages