-
Notifications
You must be signed in to change notification settings - Fork 5
/
generateSFSymbolEnum.swift
116 lines (95 loc) · 3.72 KB
/
generateSFSymbolEnum.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import Foundation
typealias ReleaseDate = String
typealias Symbol = String
typealias Symbols = [Symbol:ReleaseDate]
typealias Release = [String:String]
typealias Releases = [ReleaseDate:Release]
typealias SymbolTuple = (symbol:Symbol,released:ReleaseDate)
extension Release {
var availabilty:String {
"available(" +
self.map{ (os,version) in os + " " + version }.sorted().joined(separator: ",") +
",*)"
}
}
extension Symbol {
var replacementName:String {
guard !Set(["return","case","repeat"]).contains(self) else { return "`"+self+"`" }
let parts = components(separatedBy:".")
let firstElement = parts.first!
let camelCase = firstElement + parts.dropFirst().map{ $0.prefix(1).uppercased() + $0.dropFirst()}.joined(separator: "")
return camelCase.first?.isNumber == true ? "number" + camelCase : camelCase
}
}
let plistURL: URL = {
let betaURL = URL(fileURLWithPath: "/Applications/SF Symbols beta.app/Contents/Resources/Metadata/name_availability.plist")
let oldURL = URL(fileURLWithPath:"/Applications/SF Symbols.app/Contents/Resources/Metadata-Public/name_availability.plist")
let newURL = URL(fileURLWithPath:"/Applications/SF Symbols.app/Contents/Resources/Metadata/name_availability.plist")
if FileManager.default.fileExists(atPath: betaURL.path) {
return betaURL
} else if FileManager.default.fileExists(atPath: oldURL.path) {
return oldURL
} else {
return newURL
}
}()
let (sortedSymbolTuple,releaseYears) = readSymbolsAndYears(from:plistURL)
print("""
// this file has been generated
// you can recreate it using generateSFSymbolEnum.swift script
import Foundation
public enum SFSymbol:String
{
""")
for symbolTuple in sortedSymbolTuple
{
print(" @" + releaseYears[symbolTuple.released]!.availabilty + " case " + symbolTuple.symbol.replacementName + " = \"" + symbolTuple.symbol + "\"" )
}
print("""
}
extension SFSymbol:CaseIterable
{
public static let allCases:[SFSymbol] = {
var allCases:[SFSymbol] = []
""")
var lastavailablity = ""
for symbolTuple in sortedSymbolTuple
{
if symbolTuple.released != lastavailablity
{
if lastavailablity != ""
{
print("\n ])\n }\n")
}
lastavailablity = symbolTuple.released
print(" if #" + releaseYears[symbolTuple.released]!.availabilty + "{")
print(" allCases.append(contentsOf: [")
print(" SFSymbol." + symbolTuple.symbol.replacementName , terminator:"")
}
else
{
print(",\n SFSymbol." + symbolTuple.symbol.replacementName, terminator:"")
}
}
print("""
])
}
return allCases
}()
}
""")
exit(1)
func readSymbolsAndYears(from fileURL:URL) -> ( [SymbolTuple],Releases)
{
let data = try! Data.init(contentsOf: fileURL, options: .mappedIfSafe)
let propertyList = try! PropertyListSerialization.propertyList(from:data,options:[],format:nil) as! Dictionary<String,Any>
let symbols = propertyList["symbols"] as! Symbols
let releases = propertyList["year_to_release"] as! Releases
let releaseDatesFromSymbols = Set<ReleaseDate>(symbols.values)
let releaseDatesFromReleases = Set<ReleaseDate>(releases.keys)
assert(releaseDatesFromReleases.isSubset(of:releaseDatesFromSymbols),"There are symbols with relasedates that have no release versions \(releaseDatesFromReleases) < \(releaseDatesFromSymbols)")
let sortedSymbolTuple = symbols
.sorted{ $0.value == $1.value ? $0.key < $1.key : $0.value < $1.value}
.map{ SymbolTuple(symbol:$0.key,released:$0.value) }
return (sortedSymbolTuple,releases)
}