Scalable Vector Graphics (afkorting: SVG) is een op XML gebaseerd bestandsformaat voor statische en dynamische vectorafbeeldingen. Het is een open standaard van het W3C. Omdat SVG-bestanden tekstbestanden zijn, kunnen ze ook makkelijk gemanipuleerd worden. Neem bijvoorbeeld het bestand amerika.svg dat een (lege) kaart van de Verenigde Staten voorstelt.

Originele SVG-afbeelding waarin de staten van de Verenigde Staten van Amerika grijs gekleurd zijn.

De persoon die deze kaart in SVG-formaat heeft omgezet, heeft ook de extra moeite genomen om alle staten aan te duiden met hun gebruikelijke 2-lettercode (bijvoorbeeld AR voor Arkansas en MT voor Montana). Als je naar de inhoud van de afbeelding kijkt, dan zal je bijvoorbeeld zien dat de eerste staatsgrens (voorgesteld door een path-element) geïdentificeerd wordt door de id HI (id="HI"), waardoor we weten dat ze Hawaï voorstelt.

Stel nu dat we beschikken over een kommagescheiden bestand (CSV-bestand, comma separated values) kleuren.csv waarvan de eerste kolom de 2-lettercode van alle Amerikaanse staten bevat en de tweede kolom de naam/code van de corresponderende HTML kleur. Hieronder staan alvast de eerste regels van het bestand. Let op het feit dat de eerste regel een hoofding is met de namen van de velden.

staat,kleur
HI,blue
AK,red
FL,red
NH,red
MI,red
…

De staten in het SVG-bestand amerika.svg kunnen dan ingekleurd worden door elk voorkomen van id="XX" (met XX de 2-lettercode van een staat) aan te vullen tot id="XX" style="fill:<kleur>;" waarbij <kleur> de kleur is die in het CSV-bestand correspondeert met de code XX. Zo moet bijvoorbeeld id="MI" omgezet worden naar id="MI" style="fill:red;".

Als resultaat krijgen we dan een SVG-bestand met ingekleurde staten, dat als volgt weergegeven wordt.

SVG-afbeelding waarin de staten van de Verenigde Staten van Amerika ingekleurd werden.

Opgave

Schrijf een bash shell script inkleuren waaraan twee gewone, leesbare tekstbestanden moeten doorgegeven worden. Het eerste bestand moet een SVG-bestand zijn, waarin bepaalde grafische elementen worden geïdentificeerd met id argumenten. Het tweede bestand moet een CSV-bestand zijn met twee kolommen, waarbij de eerste kolom identifiers bevat en de tweede kolom HTML kleuren die met de identifiers uit de eerste kolom corresponderen.

Als de argumenten die aan het script doorgegeven worden niet aan deze voorwaarden voldoen, dan moet een gepaste boodschap uitgeschreven worden naar standard error (stderr). Hierbij moet minstens gecontroleerd worden dat er twee bestanden opgegeven werden, dat de twee gegeven bestanden bestaan, gewone bestanden zijn, leesbaar zijn, en respectievelijk eindigen op de extensies .svg en .csv. Bijkomend kan je ook nagaan dat de bestanden inhoudelijk het juiste formaat hebben (denk hierbij aan het file commando). Bestudeer onderstaande voorbeeldsessie om te zien hoe het script moet reageren als bovenstaande voorwaarden niet voldaan zijn, en welke foutboodschap precies moet uitgeschreven worden.

$ inkleuren amerika.png
Syntaxis: inkleuren svg-bestand csv-bestand
$ echo $?
1
$ inkleuren xxx kleuren.csv
Fout: onbestaand, onleesbaar of ongeldig svg-bestand: xxx
Syntaxis: inkleuren svg-bestand csv-bestand
$ echo $?
2
$ inkleuren amerika.png kleuren.csv
Fout: onbestaand, onleesbaar of ongeldig svg-bestand: amerika.png
Syntaxis: inkleuren svg-bestand csv-bestand
$ echo $?
2
$ inkleuren amerika.svg xxx
Fout: onbestaand, onleesbaar of ongeldig csv-bestand: xxx
Syntaxis: inkleuren svg-bestand csv-bestand
$ echo $?
3

Als de argumenten wel aan de gestelde voorwaarden voldoen, dan moet het script voor elke identifier abcd die voorkomt in het CSV-bestand, de verwijzingen ernaar in het SVG-bestand (id="abcd") — indien aanwezig — aanvullen tot id="abcd" style="fill:<kleur>;", waarbij <kleur> de kleur is die in het CSV-bestand correspondeert met de identifier abcd. Merk dus op dat het script generieker moet werken dan enkel voor identifiers die bestaan uit twee hoofdletters. Hierbij mogen de gegeven bestanden niet gewijzigd worden, maar moet de aanvulling gebeuren in een nieuw (tijdelijk) SVG-bestand.

Nadat de hierboven omschreven aanvulling gebeurd is, moet het ingekleurde CSV-bestand omgezet worden naar een PNG-bestand (een ander afbeeldingsformaat) aan de hand van het convert commando uit de ImageMagick suite.

$ convert svg:amerika.svg png:amerika_leeg.png

Het resulterende PNG-bestand moet dezelfde naam krijgen als het gegeven SVG-bestand, maar waarbij de extensie .svg vervangen is door de extensie .png (dus amerika.png voor het gegeven bestand amerika.svg). Daarna moet het tijdelijke SVG-bestand met de ingekleurde versie van de afbeelding terug verwijderd worden.

Voorbeeld

Je moet het script inkleuren op de volgende manier kunnen gebruiken om het SVG-bestand amerika.svg met de Amerikaanse staten in te kleuren op basis van het CSV-bestand kleuren.csv.

$ inkleuren amerika.svg kleuren.csv

Dit moet een PNG-bestand amerika.png opleveren, waarbij de staten ingekleurd werden zoals aangegeven in bovenstaande figuur.