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

[Feature] Custom list prefixes for AttributedStringVisitor #255

Merged
merged 2 commits into from Apr 28, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions .travis.yml
Expand Up @@ -4,9 +4,9 @@ before_install:
- set -o pipefail
- xcrun simctl boot "iPhone 12" || echo "(Pre)Launched the simulator."
script:
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk iphonesimulator -destination "platform=iOS Simulator,OS=14.2,name=iPhone 12" -enableCodeCoverage YES ONLY_ACTIVE_ARCH=YES test
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk iphonesimulator -destination "platform=iOS Simulator,OS=14.2,name=iPhone 12" -enableCodeCoverage YES ONLY_ACTIVE_ARCH=YES -quiet test
- bash <(curl -s https://codecov.io/bash)
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk macosx -destination 'platform=OS X,arch=x86_64' -enableCodeCoverage YES test
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk macosx -destination 'platform=OS X,arch=x86_64' -enableCodeCoverage YES -quiet test
- bash <(curl -s https://codecov.io/bash)
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV' -enableCodeCoverage YES test
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV' -enableCodeCoverage YES -quiet test
- bash <(curl -s https://codecov.io/bash)
14 changes: 12 additions & 2 deletions Sources/Down/AST/Visitors/AttributedStringVisitor.swift
Expand Up @@ -14,23 +14,32 @@ import Foundation
/// represented at each node and uses an instance of `Styler` to apply the visual attributes.
/// These substrings are joined together to produce the final result.

public typealias ListPrefixGeneratorBuilder = (List) -> ListItemPrefixGenerator

public class AttributedStringVisitor {

// MARK: - Properties

private let styler: Styler
private let options: DownOptions
private let listPrefixGeneratorBuilder: ListPrefixGeneratorBuilder
private var listPrefixGenerators = [ListItemPrefixGenerator]()

/// Creates a new instance with the given styler and options.
///
/// - parameters:
/// - styler: used to style the markdown elements.
/// - options: may be used to modify rendering.
/// - listPrefixGeneratorBuilder: may be used to modify list prefixes.

public init(styler: Styler, options: DownOptions = .default) {
public init(
styler: Styler,
options: DownOptions = .default,
listPrefixGeneratorBuilder: @escaping ListPrefixGeneratorBuilder = { StaticListItemPrefixGenerator(list: $0) }
) {
self.styler = styler
self.options = options
self.listPrefixGeneratorBuilder = listPrefixGeneratorBuilder
}

}
Expand All @@ -53,7 +62,8 @@ extension AttributedStringVisitor: Visitor {
}

public func visit(list node: List) -> NSMutableAttributedString {
listPrefixGenerators.append(ListItemPrefixGenerator(list: node))

listPrefixGenerators.append(listPrefixGeneratorBuilder(node))
defer { listPrefixGenerators.removeLast() }

let items = visitChildren(of: node)
Expand Down
46 changes: 29 additions & 17 deletions Sources/Down/AST/Visitors/ListItemPrefixGenerator.swift
Expand Up @@ -8,34 +8,46 @@

import Foundation

class ListItemPrefixGenerator {
/// A ListItemPrefixGenerator is an object used to generate list item prefix.
public protocol ListItemPrefixGenerator {
init(listType: List.ListType, numberOfItems: Int, nestDepth: Int)
func next() -> String?
}
dloic marked this conversation as resolved.
Show resolved Hide resolved

public extension ListItemPrefixGenerator {
init(list: List) {
self.init(listType: list.listType, numberOfItems: list.numberOfItems, nestDepth: list.nestDepth)
}
}

/// Default implementation of `ListItemPrefixGenerator`.
/// Generating the following symbol based on `List.ListType`:
/// - List.ListType is bullet => "•"
/// - List.ListType is ordered => "X." (where is the item number)
public class StaticListItemPrefixGenerator: ListItemPrefixGenerator {

// MARK: - Properties

private var prefixes: IndexingIterator<[String]>

// MARK: - Life cycle

convenience init(list: List) {
self.init(listType: list.listType, numberOfItems: list.numberOfItems)
}

init(listType: List.ListType, numberOfItems: Int) {
switch listType {
case .bullet:
prefixes = [String](repeating: "•", count: numberOfItems)
.makeIterator()

case .ordered(let start):
prefixes = (start..<(start + numberOfItems))
.map { "\($0)." }
.makeIterator()
required public init(listType: List.ListType, numberOfItems: Int, nestDepth: Int) {
switch listType {
case .bullet:
prefixes = [String](repeating: "•", count: numberOfItems)
.makeIterator()

case .ordered(let start):
prefixes = (start..<(start + numberOfItems))
.map { "\($0)." }
.makeIterator()
}
}
}

// MARK: - Methods

func next() -> String? {
public func next() -> String? {
prefixes.next()
}

Expand Down
8 changes: 4 additions & 4 deletions Tests/DownTests/AST/ListItemPrefixGeneratorTests.swift
Expand Up @@ -11,9 +11,9 @@ import XCTest

class ListItemPrefixGeneratorTests: XCTestCase {

func testNumberPrefixGeneration() {
func testNumberStaticPrefixGeneration() {
// Given
let sut = ListItemPrefixGenerator(listType: .ordered(start: 3), numberOfItems: 3)
let sut = StaticListItemPrefixGenerator(listType: .ordered(start: 3), numberOfItems: 3, nestDepth: 1)

// Then
XCTAssertEqual("3.", sut.next())
Expand All @@ -22,9 +22,9 @@ class ListItemPrefixGeneratorTests: XCTestCase {
XCTAssertNil(sut.next())
}

func testBulletPrefixGeneration() {
func testBulletStaticPrefixGeneration() {
// Given
let sut = ListItemPrefixGenerator(listType: .bullet, numberOfItems: 3)
let sut = StaticListItemPrefixGenerator(listType: .bullet, numberOfItems: 3, nestDepth: 1)

// Then
XCTAssertEqual("•", sut.next())
Expand Down