Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9626ec5
clean フォルダ構成を整理しました.
rrbox Dec 22, 2022
138a792
add BuilderAttribute を追加しました.
rrbox Dec 22, 2022
f600c91
add BuilderAttribute を作成しました.
rrbox Dec 22, 2022
1321443
change BuilderAttribute を AttributeContext に変更
rrbox Dec 23, 2022
64fd3fe
change AttributeContext の mask メソッドを attribute に改名.
rrbox Dec 23, 2022
8fa7f4d
add AttributeLink, AttributeElement を AttributeContext
rrbox Dec 23, 2022
b835df1
add AttributeElement, AttributeBuilder を追加しました.
rrbox Dec 23, 2022
1665a4b
change fontColor を foregroundColor に変更しました.
rrbox Dec 23, 2022
2c3f460
add Builder のテストを作成しました.
rrbox Dec 24, 2022
5e00f8a
add AttributeBuilderTests を 追加しました.
rrbox Dec 24, 2022
fc0deba
clean 辞書のvalueの前に空白を挿入しました.
rrbox Dec 24, 2022
bbe7f8e
add AttributeContext-AttributeBuilder システム用の stack を作成しました.
rrbox Dec 24, 2022
910a623
clean switch 文の余分な break を削除しました.
rrbox Dec 24, 2022
228e9b0
fix テストの誤りを修正しました.
rrbox Dec 24, 2022
2fe87f1
add ContextStack を追加しました.
rrbox Dec 24, 2022
c499e60
change Editor と literal を context api に対応しました.
rrbox Dec 24, 2022
89d7a44
remove 過去の Attribute の API を削除しました.
rrbox Dec 24, 2022
1d2ed89
change AttributeLink を Attribute に改名しました.
rrbox Dec 24, 2022
ddf8d21
remove テストコードの余分な部分を削除しました.
rrbox Dec 24, 2022
1e16947
change AppKit 依存になるよう修正しました.
rrbox Dec 24, 2022
61a21d1
fix import を誤っていたため修正しました.
rrbox Dec 24, 2022
3615e07
clean コードを整理しました.
rrbox Dec 24, 2022
746af38
change AttributeContext を internal に変更しました.
rrbox Dec 24, 2022
0da7e61
change Attribute を構造体にし, AttributeLink を隠蔽しました.
rrbox Dec 24, 2022
7a4392c
change fontColor を foregroundColor に変更しました.
rrbox Dec 24, 2022
4ab6b99
change AttributeElement を隠蔽しました.
rrbox Dec 24, 2022
344324e
Merge pull request #27 from rrbox/feat/builder-attribute
rrbox Dec 24, 2022
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
54 changes: 54 additions & 0 deletions Sources/Tsumiji/Attribute+NSAttributedString.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// Attribute+NSAttributedString.swift
//
//
// Created by rrbox on 2022/12/22.
//

#if os(macOS)
import AppKit
#elseif os(iOS)
import UIKit
#endif

extension AttributeContext {
func attribute(_ attrString: inout AttributedString) {
attrString.foregroundColor = self.foregroundColor
attrString.font = Font(name: self.fontName, size: CGFloat(truncating: self.fontSize))
attrString.backgroundColor = self.backgroundColor

}
}

extension AttributeElement {
func modify(_ context: inout AttributeContext) {
switch self {
case let .fontName(value):
context.fontName = value
case let .fontSize(value):
context.fontSize = value
case let .foregroundColor(value):
context.foregroundColor = value
case let .backgroundColor(value):
context.backgroundColor = value
}
}
}

extension AttributeLink {
func modify(_ context: inout AttributeContext) {
switch self {
case let .single(element):
element.modify(&context)
case let .link(previous, element):
previous.modify(&context)
element.modify(&context)
}
}

func createContext() -> AttributeContext {
var result = AttributeContext()
self.modify(&result)
return result
}
}
65 changes: 0 additions & 65 deletions Sources/Tsumiji/Attribute.swift

This file was deleted.

76 changes: 76 additions & 0 deletions Sources/Tsumiji/AttributeLink.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// Tsumiji.swift
//
//
// Created by rrbox on 2022/02/09.
//

#if os(macOS)
import AppKit
#elseif os(iOS)
import UIKit
#endif

#if os(iOS)
public typealias Font = UIFont
public typealias Color = UIColor
#elseif os(macOS)
public typealias Font = NSFont
public typealias Color = NSColor
#endif

struct AttributeContext {
var fontName: String = "HelveticaNeue-UltraLight"
var fontSize: NSNumber = NSNumber(value: 32)
var foregroundColor: Color = .white
var backgroundColor: Color = .clear
}

enum AttributeElement {
case fontName(String)
case fontSize(NSNumber)
case foregroundColor(Color)
case backgroundColor(Color)
}

indirect enum AttributeLink {
case single(AttributeElement)
case link(Self, AttributeElement)
}

public struct Attribute {
let body: AttributeLink
init(body: AttributeLink) {
self.body = body
}
}

public extension Attribute {
static func fontName(_ value: String) -> Attribute {
.init(body: .single(.fontName(value)))
}
static func fontSize(_ value: NSNumber) -> Attribute {
.init(body: .single(.fontSize(value)))
}
static func foregroundColor(_ value: Color) -> Attribute {
.init(body: .single(.foregroundColor(value)))
}
static func backgroundColor(_ value: Color) -> Attribute {
.init(body: .single(.backgroundColor(value)))
}
}

public extension Attribute {
func fontName(_ value: String) -> Attribute {
.init(body: .link(self.body, .fontName(value)))
}
func fontSize(_ value: NSNumber) -> Attribute {
.init(body: .link(self.body, .fontSize(value)))
}
func foregroundColor(_ value: Color) -> Attribute {
.init(body: .link(self.body, .foregroundColor(value)))
}
func backgroundColor(_ value: Color) -> Attribute {
.init(body: .link(self.body, .backgroundColor(value)))
}
}
8 changes: 5 additions & 3 deletions Sources/Tsumiji/Editor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public struct Editor {

public var product = AttributedString()

var stack = Stack(attrributeStack: [[:]])
var stack = ContextStack()

public init() {}

Expand All @@ -21,13 +21,15 @@ public struct Editor {

@discardableResult public func text(_ value: String) -> Self {
var result = self
result.product.append(AttributedString(NSAttributedString(string: value, attributes: self.stack.getFirst().toNSAttribute())))
var attributedText = AttributedString(value)
self.stack.getFirst().attribute(&attributedText)
result.product += attributedText
return result
}

@discardableResult public func font(_ value: Attribute) -> Self {
var result = self
try! result.stack.add(attr: value)
result.stack.add(attr: value)
return result
}

Expand Down
21 changes: 7 additions & 14 deletions Sources/Tsumiji/EditorLiteral.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,20 @@ public struct EditorInterpolation: StringInterpolationProtocol {

var product: AttributedString

var stack = Stack(attrributeStack: [[:]])
var stack = ContextStack()

public init(literalCapacity: Int, interpolationCount: Int) {
self.product = AttributedString()
}

mutating public func appendLiteral(_ literal: String) {
self.product.append(AttributedString(
NSAttributedString(
string: literal,
attributes: self.stack
.getFirst()
.toNSAttribute())))
var arrtibutedText = AttributedString(literal)
self.stack.getFirst().attribute(&arrtibutedText)
self.product += arrtibutedText
}

mutating public func appendInterpolation(_ font: Attribute) {
try! self.stack.add(attr: font)
self.stack.add(attr: font)
}

mutating public func appendInterpolation(_ command: Command) {
Expand All @@ -46,12 +43,8 @@ public struct EditorLiteral: ExpressibleByStringLiteral, ExpressibleByStringInte
public var product: AttributedString

public init(stringLiteral value: String) {
self.product = AttributedString(
NSAttributedString(
string: value,
attributes: Stack(attrributeStack: [[:]])
.getFirst()
.toNSAttribute()))
self.product = AttributedString(value)
ContextStack().getFirst().attribute(&self.product)
}

public init(stringInterpolation: EditorInterpolation) {
Expand Down
37 changes: 37 additions & 0 deletions Sources/Tsumiji/Stack.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// Stack.swift
//
//
// Created by rrbox on 2022/12/22.
//

struct ContextStack {
var attrributeStack: [AttributeContext] {
didSet {
if self.attrributeStack.count == 0 {
self.attrributeStack.append(.init())
}
}
}

mutating func add(attr: Attribute) {
if var previous = self.attrributeStack.first {
attr.body.modify(&previous)
self.attrributeStack.insert(previous, at: 0)
} else {
self.attrributeStack.insert(attr.body.createContext(), at: 0)
}
}

mutating func remove() {
self.attrributeStack.remove(at: 0)
}

func getFirst() -> AttributeContext {
self.attrributeStack[0]
}

init() {
self.attrributeStack = [AttributeContext()]
}
}
13 changes: 5 additions & 8 deletions Tests/TsumijiTests/TsumijiTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,12 @@ extension Color {
}

extension Attribute {
static let red: Self = [.fontColor: Color.red]
static let big: Self = [.fontSize: 50]
static let impact: Self = [.fontName: "times"]
static let blueBack: Self = [.backgroundColor: Color.blue]
static let red: Self = .foregroundColor(.red)
static let big: Self = .fontSize(50)
static let impact: Self = .fontName("times")
static let blueBack: Self = .backgroundColor(.blue)

static let bigRed: Self = [
.fontSize: 50,
.fontColor: Color.red
]
static let bigRed: Self = .fontSize(50).foregroundColor(.red)
}

final class TsumijiTests: XCTestCase {
Expand Down