From b327eaaa104ee38ff9ada270d0839a86027734a9 Mon Sep 17 00:00:00 2001 From: Joe Bezdek Date: Fri, 5 Jan 2024 00:05:12 -0600 Subject: [PATCH 1/3] Add minimum word length parameter to constrain hyphenation --- Sources/HyphenableText/HyphenableText.swift | 27 +++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/Sources/HyphenableText/HyphenableText.swift b/Sources/HyphenableText/HyphenableText.swift index 4be5200..a4dc51d 100644 --- a/Sources/HyphenableText/HyphenableText.swift +++ b/Sources/HyphenableText/HyphenableText.swift @@ -13,6 +13,26 @@ public extension String { /// /// - see: [Wikipedia](https://en.wikipedia.org/wiki/Soft_hyphen). static let softHyphen = "\u{00AD}" + + /// Split the string using space as a separator and, for those substrings + /// whose lengths are greater than or equal to minimumWordLength, + /// replace them with a softHyphenated version.. + /// + /// - note: This assumes that words are delineated by + /// space characters, which may not be correct for all locales where + /// CFStringIsHyphenationAvailableForLocale(_:) returns true. Consider + /// using CFStringTokenizer to eliminate this assumption. + func softHyphenateByWord(minimumWordLength: Int = 0, withLocale locale: Locale = .autoupdatingCurrent) -> Self { + var substringArray: [String] = self.split(separator: " ", omittingEmptySubsequences: false).map({ String($0) }) + + for (i, substring) in substringArray.enumerated() { + if substring.count >= minimumWordLength { + substringArray[i] = substring.softHyphenated(withLocale: locale) + } + } + + return substringArray.joined(separator: " ") + } /// Insert a soft-hyphen character at every possible location in the string. /// @@ -65,15 +85,18 @@ public struct HyphenableText: View { @Environment(\.locale) private var locale public let text: String + public let minimumWordLength: Int - public init(_ text: String) { + public init(_ text: String, ignoreWordsShorterThan minimumWordLength: Int = 0) { self.text = text + self.minimumWordLength = minimumWordLength } public var body: some View { Text( text - .softHyphenated( + .softHyphenateByWord( + minimumWordLength: minimumWordLength, withLocale: locale ) ) From e055ebac290d6cde838bebc84b0b051f821ae9e8 Mon Sep 17 00:00:00 2001 From: Joe Bezdek Date: Fri, 5 Jan 2024 00:15:40 -0600 Subject: [PATCH 2/3] Fix typo --- Sources/HyphenableText/HyphenableText.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/HyphenableText/HyphenableText.swift b/Sources/HyphenableText/HyphenableText.swift index a4dc51d..ef0a478 100644 --- a/Sources/HyphenableText/HyphenableText.swift +++ b/Sources/HyphenableText/HyphenableText.swift @@ -16,7 +16,7 @@ public extension String { /// Split the string using space as a separator and, for those substrings /// whose lengths are greater than or equal to minimumWordLength, - /// replace them with a softHyphenated version.. + /// replace them with a softHyphenated version. /// /// - note: This assumes that words are delineated by /// space characters, which may not be correct for all locales where From f6410685effb8a2c2b84ac21f1393ae002475ad0 Mon Sep 17 00:00:00 2001 From: Joe Bezdek Date: Fri, 5 Jan 2024 12:35:31 -0600 Subject: [PATCH 3/3] Remove unnecessary self reference --- Sources/HyphenableText/HyphenableText.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/HyphenableText/HyphenableText.swift b/Sources/HyphenableText/HyphenableText.swift index ef0a478..7bd1ce1 100644 --- a/Sources/HyphenableText/HyphenableText.swift +++ b/Sources/HyphenableText/HyphenableText.swift @@ -23,7 +23,7 @@ public extension String { /// CFStringIsHyphenationAvailableForLocale(_:) returns true. Consider /// using CFStringTokenizer to eliminate this assumption. func softHyphenateByWord(minimumWordLength: Int = 0, withLocale locale: Locale = .autoupdatingCurrent) -> Self { - var substringArray: [String] = self.split(separator: " ", omittingEmptySubsequences: false).map({ String($0) }) + var substringArray: [String] = split(separator: " ", omittingEmptySubsequences: false).map({ String($0) }) for (i, substring) in substringArray.enumerated() { if substring.count >= minimumWordLength {