In 2009 bedacht Kim Godgul een visuele code om woorden voor te stellen. Hij noemde ze ColorHoney omdat elke letter van een woord voorgesteld wordt als een diamant die samengesteld is uit twee gekleurde driehoeken. De twee kanten van de diamant worden respectievelijk de lichte kleur en de donkere kleur genoemd.

diamant
In de ColorHoney code wordt elke letter van een woord voorgesteld als een diamant die samengesteld is uit twee gekleurde driehoeken. De twee kanten van de diamant worden respectievelijk de lichte kleur en de donkere kleur genoemd.

Standaard worden er zes kleuren gebruikt om de driehoeken in te kleuren: rood, groen, blauw, cyaan, magenta en geel. Daarmee kan dus een alfabet van maximaal 36 symbolen (letters, cijfers, leestekens, spaties) voorgesteld worden, waarbij elk symbool correspondeert met een combinatie van twee kleuren.

alfabet
In de ColorHoney code wordt elke letter van het alfabet geassocieerd met een diamant die een unieke combinatie van twee kleuren heeft. Standaard worden er zes kleuren gebruikt om de driehoeken in te kleuren: rood, groen, blauw, cyaan, magenta en geel.

ColorHoney gebruikt een vaste layout om de diamanten voor de opeenvolgende symbolen van een woord te plaatsen: de vier diamanten voor elke groep van vier opeenvolgende symbolen vormen een patroon dat zich steeds blijft herhalen.

layout
ColorHoney gebruikt een vaste layout om de diamanten voor de opeenvolgende symbolen te plaatsen: de vier diamanten voor elke groep van vier opeenvolgende symbolen vormen een patroon dat zich steeds blijft herhalen.

Daardoor heeft de weergave van de code wat weg van een veelkleurige honingraat. Hier zijn negen voorbeelden van woorden die voorgesteld worden met hun ColorHoney-code:

Gandalf (ColorHoney)
ColorHoney code voor het woord Gandalf.

Gandalf
Aragorn (ColorHoney)
ColorHoney code voor het woord Aragorn.

Aragorn
Boromir (ColorHoney)
ColorHoney code voor het woord Boromir.

Boromir
Samwise (ColorHoney)
ColorHoney code voor het woord Samwise.

Samwise
Frodo (ColorHoney)
ColorHoney code voor het woord Frodo.

Frodo
Meriadoc (ColorHoney)
ColorHoney code voor het woord Meriadoc.

Meriadoc
Legolas (ColorHoney)
ColorHoney code voor het woord Legolas.

Legolas
Gimli (ColorHoney)
ColorHoney code voor het woord Gimli.

Gimli
Peregrin (ColorHoney)
ColorHoney code voor het woord Peregrin.

Peregrin

Opgave

Schrijf een bash shell script colorhoney waaraan twee argumenten moeten doorgegeven worden: i) een woord $$w$$ dat enkel bestaat uit letters (hoofdletters en kleine letters) en ii) de padnaam van een tekstbestand dat twee kleuren associeert met elke letter van het alfabet. Het script mag ervan uitgaan dat beide argumenten geldig zijn, zonder dat dit expliciet moet gecontroleerd worden. Het tekstbestand bestaat uit 26 regels die elk een unieke letter van het alfabet bevatten en twee HTML-kleuren1: de corresponderende lichte en donkere kleur. Deze drie informatievelden worden telkens van elkaar gescheiden door één tab. De eerste paar regels van zo'n bestand zouden er bijvoorbeeld als volgt kunnen uitzien (alphabet.txt2):

G	red	blue
A	magenta	magenta
N	green	red
D	magenta	green
L	green	magenta
F	red	green
R	yellow	blue
K	green	cyan
…

Het script moet de ColorHoney-code van woord $$w$$ in SVG-formaat uitschrijven naar standaard uitvoer (stdout). Daarbij moet gebruikgemaakt worden van de kleurencombinaties die vastgelegd zijn in het tekstbestand dat als tweede argument aan het script wordt doorgegeven. Verderop3 bespreken we stap voor stap hoe de SVG-afbeelding opgebouwd wordt. Het script moet bijvoorbeeld kunnen gebruikt worden om de afbeeldingen uit de inleiding van deze opgave te genereren. Dit is bijvoorbeeld de SVG-afbeelding met de ColorHoney-code van het woord Gandalf die het script moet uitschrijven, op basis van de kleurencombinaties die we hierboven als voorbeeld gebruikt hebben (alphabet.txt4):

<svg xmlns="http://www.w3.org/2000/svg" height="300" viewBox="-0.6 -1.5433 4.2 3.086">
<style>.border{stroke:#F5F1EB;stroke-width:0.05;stroke-linejoin:round}</style>
<defs><g id="diamond">
<polygon points="0,-1 -0.5773,0 0.5773,0 0,-1"/>
<polygon points="0,1 -0.5773,0 0.5773,0 0,1" fill="currentColor"/>
<polygon class="border" points="0,1 -0.5773,0 0,-1 0.5773,0 0,1" fill="none"/>
</g></defs>
<rect x="-0.6" y="-1.5433" rx="0.1" width="4.2" height="3.086" fill="#F5F1EB"/>
<use href="#diamond" x="0" y="0" fill="red" color="blue" transform="rotate(30,0,0)"/>
<use href="#diamond" x="0.5" y="0.866" fill="magenta" color="magenta" transform="rotate(90,0.5,0.866)"/>
<use href="#diamond" x="1" y="0" fill="green" color="red" transform="rotate(-30,1,0)"/>
<use href="#diamond" x="1.5" y="-0.866" fill="magenta" color="green" transform="rotate(90,1.5,-0.866)"/>
<use href="#diamond" x="2" y="0" fill="magenta" color="magenta" transform="rotate(30,2,0)"/>
<use href="#diamond" x="2.5" y="0.866" fill="green" color="magenta" transform="rotate(90,2.5,0.866)"/>
<use href="#diamond" x="3" y="0" fill="red" color="green" transform="rotate(-30,3,0)"/>
</svg>

Opbouw van de SVG-afbeelding

Scalable Vector Graphics (SVG5) is een op XML6 gebaseerd bestandsformaat dat vectorafbeeldingen7 tekstueel beschrijft aan de hand van eenvoudige meetkundige bouwstenen zoals punten, lijnen, cirkels en veelhoeken.

Je moet geen SVG of XML kennen om deze opgave op te lossen. We bespreken stap voor stap hoe de ColorHoney-code van een woord opgebouwd wordt in SVG-formaat aan de hand van drie sjablonen: hoofding8, diamant9 en voettekst10. Daarbij zullen we de variabele onderdelen van elk sjabloon in het groen weergeven. Daar moet het script de juiste waarden invullen. Het is belangrijk dat elk sjabloon exact overgenomen wordt, zodat het resultaat dat het script uitschrijft precies overeenkomt met de beschreven specificatie.

Hoofding
<svg xmlns="http://www.w3.org/2000/svg" height="300" viewBox="-0.6 -1.5433 4.2 3.086">
<style>.border{stroke:#F5F1EB;stroke-width:0.05;stroke-linejoin:round}</style>
<defs><g id="diamond">
<polygon points="0,-1 -0.5773,0 0.5773,0 0,-1"/>
<polygon points="0,1 -0.5773,0 0.5773,0 0,1" fill="currentColor"/>
<polygon class="border" points="0,1 -0.5773,0 0,-1 0.5773,0 0,1" fill="none"/>
</g></defs>
<rect x="-0.6" y="-1.5433" rx="0.1" width="4.2" height="3.086" fill="#F5F1EB"/>

Dit sjabloon bevat enkele vaste ingrediënten voor alle SVG-bestanden die de ColorHoney-code van een woord $$w$$ voorstellen: de SVG start-tag (svg), algemene opmaak van de afbeelding (style), een definitie van de manier waarop diamanten weergegeven worden (defs), en een gekleurde rechthoek die dienst doet als achtergrond voor de afbeelding (rect).

Alle afbeeldingen hebben een vaste hoogte, maar hun breedte hangt af van de lengte $$|w|$$ van woord $$w$$. Die breedte moet op twee plaatsen in het sjabloon ingevuld worden. Ze wordt berekend als \[ 1.2 + \left\lfloor \frac{|w|}{2} \right\rfloor  \] waarbij $$\left\lfloor x \right\rfloor$$ staat voor het grootste geheel getal dat kleiner is dan of gelijk aan $$x \in \mathbb{R}$$. Die breedte moet altijd voorgesteld worden met één cijfer na de komma.

Diamant
<use href="#diamond" x="0" y="0" fill="red" color="blue" transform="rotate(30,0,0)"/>

Deze regel tekent de diamant voor de $$i$$-de letter $$w_i$$ van woord $$w$$. Daarbij worden de letters van woord $$w$$ van links naar rechts genummerd vanaf 0. Hierbij moet de volgende informatie in het sjabloon ingevuld worden:

Voor elke letter van woord $$w$$ (van links naar rechts) moet een regel volgens dit sjabloon toegevoegd worden aan de SVG-afbeelding.

Voettekst
</svg>

Dit laatste sjabloon sluit de SVG-afbeelding af met een SVG stop-tag.

Voorbeeld

Deze interactieve sessie toont hoe het script colorhoney moet kunnen gebruikt worden. Daarbij gaan we ervan uit dat het tekstbestand alphabet.txt11 zich in de huidige directory bevindt.

$ colorhoney "Gandalf" alphabet.txt12
<svg xmlns="http://www.w3.org/2000/svg" height="300" viewBox="-0.6 -1.5433 4.2 3.086">
<style>.border{stroke:#F5F1EB;stroke-width:0.05;stroke-linejoin:round}</style>
<defs><g id="diamond">
<polygon points="0,-1 -0.5773,0 0.5773,0 0,-1"/>
<polygon points="0,1 -0.5773,0 0.5773,0 0,1" fill="currentColor"/>
<polygon class="border" points="0,1 -0.5773,0 0,-1 0.5773,0 0,1" fill="none"/>
</g></defs>
<rect x="-0.6" y="-1.5433" rx="0.1" width="4.2" height="3.086" fill="#F5F1EB"/>
<use href="#diamond" x="0" y="0" fill="red" color="blue" transform="rotate(30,0,0)"/>
<use href="#diamond" x="0.5" y="0.866" fill="magenta" color="magenta" transform="rotate(90,0.5,0.866)"/>
<use href="#diamond" x="1" y="0" fill="green" color="red" transform="rotate(-30,1,0)"/>
<use href="#diamond" x="1.5" y="-0.866" fill="magenta" color="green" transform="rotate(90,1.5,-0.866)"/>
<use href="#diamond" x="2" y="0" fill="magenta" color="magenta" transform="rotate(30,2,0)"/>
<use href="#diamond" x="2.5" y="0.866" fill="green" color="magenta" transform="rotate(90,2.5,0.866)"/>
<use href="#diamond" x="3" y="0" fill="red" color="green" transform="rotate(-30,3,0)"/>
</svg>