← poker-tutor
"""Second pass of the Android recipe: bundled symbols + sounds. Run once, after android_port.py."""
import sys, os, re, glob, shutil
repo = sys.argv[1]; os.chdir(repo)
src = os.path.expanduser("~/poker-tutor/Sources/PokerUI")
# 1. the asset catalog with the hand-drawn glyphs
dst = "Sources/PokerUI/Resources/Module.xcassets"
if not os.path.isdir(dst): shutil.copytree(f"{src}/Resources/Module.xcassets", dst)
# 2. the Symbol helper (copied verbatim from poker-tutor's Theme.swift)
t = open("Sources/PokerUI/Theme.swift").read()
if "struct Symbol: View" not in t:
p = open(f"{src}/Theme.swift").read()
block = p[p.index("// MARK: - Symbols"):]
open("Sources/PokerUI/Theme.swift", "w").write(t.rstrip("\n") + "\n\n" + block)
# 3. every symbol call site
pat = re.compile(r'Image\(systemName:\s*((?:[^()]|\n)*?)\)(\s*\.font\(\.system\(size:\s*((?:[^()]|\([^()]*\))*?)(?:,\s*weight:\s*\.\w+)?\)\))?', re.S)
n = 0
for f in glob.glob("Sources/PokerUI/*.swift"):
if f.endswith("Theme.swift"): continue
s = open(f).read()
def rep(m):
expr = " ".join(m.group(1).split())
return f"Symbol({expr}, size: {m.group(3).strip()})" if m.group(3) else f"Symbol({expr})"
s2, k = pat.subn(rep, s)
if k: open(f, "w").write(s2); n += k
print("symbol call sites rewritten:", n)
# 4. sounds through Skip's audio library
p = "Sources/PokerUI/Sound.swift"; s = open(p).read()
if "SkipAV" not in s:
s = s.replace("import Foundation\n#if canImport(AVFoundation)\nimport AVFoundation\n#endif\n",
"import Foundation\n#if canImport(AVFoundation)\nimport AVFoundation\n#elseif os(Android)\nimport SkipAV // Skip's AVAudioPlayer, over Android's MediaPlayer\n#endif\n", 1)
s = s.replace("#if canImport(AVFoundation)\n/// The table sounds.\n", "#if canImport(AVFoundation) || os(Android)\n/// The table sounds.\n", 1)
s = s.replace("#else\n/// No sound on Android yet: the table plays silently. Wiring Skip's audio library is a later step,\n/// and until then the setting still exists so the screens and the suite do not have to know.\n",
"#else\n/// No sound here: the table plays silently, and the setting still exists so the screens and the\n/// suite do not have to know.\n", 1)
open(p, "w").write(s)
p = "Package.swift"; s = open(p).read()
if "skip-av" not in s:
s = s.replace(' .package(url: "https://github.com/skiptools/skip.git", from: "1.9.8"),\n ] : [],',
' .package(url: "https://github.com/skiptools/skip.git", from: "1.9.8"),\n .package(url: "https://github.com/skiptools/skip-av.git", from: "0.5.0"),\n ] : [],')
s = s.replace(' + (android ? [.product(name: "SkipFuseUI", package: "skip-fuse-ui")] : []),\n resources: [.process("Resources")],',
' + (android ? [.product(name: "SkipFuseUI", package: "skip-fuse-ui"),\n .product(name: "SkipAV", package: "skip-av")] : []),\n resources: [.process("Resources")],')
open(p, "w").write(s)
print("polish applied to", repo)
# report any symbol names this repo uses that the helper does not know
theme = open("Sources/PokerUI/Theme.swift").read()
known = set(re.findall(r'"([a-z0-9.]+)":', theme[theme.index("static let bundled"):]))
skipmap = set("house house.fill gearshape gearshape.fill xmark chevron.left chevron.right chevron.up chevron.down magnifyingglass hand.thumbsup.fill hand.thumbsup checkmark checkmark.circle pencil ellipsis person.fill star.fill list.bullet arrow.clockwise.circle plus trash".split())
used = set()
for f in glob.glob("Sources/PokerUI/*.swift") + ["Sources/PokerUI/Copy.swift"]:
used |= set(re.findall(r'"([a-z0-9]+(?:\.[a-z0-9]+)+)"', open(f).read()))
used = {u for u in used if not u.startswith("com.") and not u[0].isdigit() and "tutor" not in u}
print("possibly unmapped symbols:", sorted(u for u in used if u not in known and u not in skipmap and u.count(".") <= 3 and len(u) < 36)[:30])