Typ
Mac-app
Länk
github.com/WheresMarco/Copista
Nyckeltekniker
  • Swift
  • SwiftUI
  • PDFKit
  • Vision
  • Foundation Models
  • Sparkle
Välkomstguiden vid första starten.
Välkomstguiden vid första starten.

Copista är en Mac-app jag byggde för notbiblioteket i en svensk blåsorkester. En låt kan komma som en PDF per stämma, som en enda inskannad bunt med alla stämmor eller som något däremellan. Copista hittar var varje stämma börjar och vilket instrument den är till, låter en rätta det som blev fel och skriver sedan ut varje låt sorterad per stämma med rätt antal exemplar.

Appen är skriven i Swift med SwiftUI och Observation, och PDF:erna läses och ritas med PDFKit och Core Graphics. Allt körs lokalt och originalfilerna ändras aldrig.

Kärnan är detekteringen. För varje PDF provas den mest pålitliga signalen först. Sparade rättelser kommer först, och filer känns igen på en SHA-256 av innehållet via CryptoKit, inte på filnamnet. Sedan bokmärken i PDF:en, filnamnet, textlagret i sidans övre hörn och till sist OCR med Vision, där överkanten av sidan läses av RecognizeTextRequest på svenska, engelska, tyska och norska. Roterade skanningar provas i varje riktning. En sida utan eget namn hör till stämman före, och en ny stämma börjar där ett instrumentnamn dyker upp i ett övre hörn eller på en egen rad.

Namnmatchningen hanterar svenska och engelska stämnamn, vanliga tyska namn, förkortningar, kombinationer som Horn 1/3 och fuzzy matchning för förvanskad gammal handtextning. Gamla handskrivna skanningar med två stämmor på samma sida delas genom att leta efter ett brett vitt band mitt på sidan, och säkerheten höjs om ett instrumentnamn också hittas i nedre halvan. På macOS 26 med Apple Intelligence frågas dessutom den lokala modellen via Foundation Models om etiketter som den egna matchningen inte kan placera. Modellen ser bara texten på etikettens position.

Utskriften planeras per låt, så att varje låt blir ett eget utskriftsjobb och en egen PDF. Vid dubbelsidig utskrift läggs tomma baksidor in där det behövs, så att varje exemplar börjar på ett nytt ark. Inställningar och rättelser sparas som JSON, och uppdateringar distribueras via Sparkle med signerade releaser från GitHub. Testerna är skrivna med Swift Testing och genererar sina PDF:er direkt i koden.