Skip to content

Instantly share code, notes, and snippets.

@frboulais
Created April 5, 2021 09:36
Show Gist options
  • Save frboulais/54e021dde4dafe1edd9d10a6e79ff632 to your computer and use it in GitHub Desktop.
Save frboulais/54e021dde4dafe1edd9d10a6e79ff632 to your computer and use it in GitHub Desktop.
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
struct Constants {
static let digraphes = ["ou", "ai", "oi", "on", "en", "an", "ch", "ei", "em", "am"]
}
extension String {
var digraphs: [String] {
guard let regex = try? NSRegularExpression(pattern: "\\((.+)\\)") else {
return []
}
return regex.matches(in: self, range: .init(startIndex..., in: self)).reduce([]) { digraphs, match in
if let range = Range(match.range, in: self) {
return digraphs + Constants.digraphes.filter { self[range].contains($0) }
} else {
return digraphs
}
}
}
}
extension Array where Element == String {
var commonDigraphs: [String] {
map { $0.digraphs }
.reduce([], +)
.reduce(into: [:]) { counts, digraph in counts[digraph, default: 0] += 1 }
.sorted(by: { $0.value > $1.value })
.map { $0.key }
}
}
class MyViewController : UIViewController {
private let emphasisColor: UIColor = .systemRed
private let CHWords = ["(ch)u(ch)", "(ch)aton", "(cha)ton", "tor(chon)", "polo(chon)", "mou(choir)"]
private let ANENWords = ["(chen)(ten)", "(chan)ton", "(ban)(den)", "(pan)(chan)", "(nen)(ran)", "(chen)(dan)", "p(em)b(an)", "(mem)bo", "pi(den)", "re(chan)", "lou(ren)", "(ban)(sen)", "(ram)bé", "(men)tir", "mar(chan?d)", "mé(chan?t)", "début(an?t)", "pim(en?t)"]
private let AIEIWords = ["(ai)(sei)", "(chai)che", "(chai)gon", "(chei)(chei)", "(bei)choi", "(cai)(bei)"]
private lazy var stackView: UIStackView = {
let view = UIStackView()
view.translatesAutoresizingMaskIntoConstraints = false
view.axis = .horizontal
view.alignment = .top
view.spacing = UIStackView.spacingUseSystem
return view
}()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
stackView.center = view.center
}
override func loadView() {
let view = UIView()
view.backgroundColor = .white
for words in [CHWords, AIEIWords, ANENWords] {
appendList(for: words)
}
view.addSubview(stackView)
self.view = view
}
private func appendList(for words: [String]) {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .center
stackView.spacing = UIStackView.spacingUseSystem
let digraphs = words.commonDigraphs
for word in words {
if word.filter({ $0 == "?"}).count % 2 != 0 {
appendLabel(for: word.appending("?"), withDigraphs: digraphs, in: stackView)
} else {
appendLabel(for: word, withDigraphs: digraphs, in: stackView)
}
}
self.stackView.addArrangedSubview(stackView)
}
private func appendLabel(for word: String, withDigraphs digraphs: [String], in stackView: UIStackView) {
var attributes = [NSAttributedString.Key : Any]()
attributes[.font] = UIFont(name: "HelveticaNeue", size: 18)
attributes[.foregroundColor] = UIColor.black
attributes[.strikethroughColor] = UIColor.black
let attributedString = NSMutableAttributedString(string: word, attributes: attributes)
let range = NSRange(word.startIndex..., in: word)
// Highlighting emphasis part
if let regex = try? NSRegularExpression(pattern: "\\((.+)\\)") {
for match in regex.matches(in: word, range: range) {
var attrs = attributes
attrs[.font] = UIFont(name: "HelveticaNeue-Bold", size: 18)
attrs[.foregroundColor] = emphasisColor.withAlphaComponent(0.5)
attributedString.addAttributes(attrs, range: match.range)
if let matchRange = Range(match.range, in: word),
let digraph = digraphs.first(where: { word[matchRange].contains($0) }),
let digraphRange = word.range(of: digraph) {
attrs[.foregroundColor] = emphasisColor
attributedString.addAttributes(attrs, range: NSRange(digraphRange, in: word))
}
}
}
// Marking silent letters
if let regex = try? NSRegularExpression(pattern: "\\?(.+)\\?") {
for match in regex.matches(in: word, range: range) {
var attrs = attributes
attrs[.strikethroughStyle] = NSUnderlineStyle.single.rawValue
attrs[.strikethroughColor] = attributedString.attribute(.foregroundColor, at: <#T##Int#>, effectiveRange: <#T##NSRangePointer?#>)
attributedString.setAttributes(attributes, range: match.range)
}
}
// Deleting separator characters
if let regex = try? NSRegularExpression(pattern: "[(,),?]") {
for match in regex.matches(in: word, range: range).reversed() {
attributedString.deleteCharacters(in: match.range)
}
}
let label = UILabel()
label.backgroundColor = .secondarySystemBackground
label.layer.cornerRadius = 8
label.clipsToBounds = true
label.attributedText = attributedString
stackView.addArrangedSubview(label)
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment