From d5e26d6502fa96a2461bbf88849f669284946bef Mon Sep 17 00:00:00 2001 From: knittl Date: Sat, 3 Apr 2010 10:49:29 +0000 Subject: neo20.txt to .svg perl script this script parses the neo20.txt reference file and creates an scalable vector graphics file from it git-svn-id: https://svn.neo-layout.org@2277 b9310e46-f624-0410-8ea1-cfbb3a30dc96 --- grafik/ref2svg/ref2svg.pl | 259 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100755 grafik/ref2svg/ref2svg.pl (limited to 'grafik/ref2svg') diff --git a/grafik/ref2svg/ref2svg.pl b/grafik/ref2svg/ref2svg.pl new file mode 100755 index 0000000..f0c0790 --- /dev/null +++ b/grafik/ref2svg/ref2svg.pl @@ -0,0 +1,259 @@ +#!/usr/bin/perl -wT + +use strict; +use warnings; + +use XML::Writer; + +use open ':encoding(utf8)'; +use utf8; + +sub start_svg; +sub end_svg; +sub create_defs; +sub create_key; +sub parse_ref; +sub in2px; +sub css_builder; +sub create_keys; +sub round; + +my $dpi = 90; +# a4 paper +my $height = in2px(8.268); +my $width = in2px(11.69); + +my $keywidth = in2px(0.75); +my $keyheight = in2px(0.75); +my $labelwidth = in2px(0.5); +my $labelheight = in2px(0.55); + +my $posx = 0; +my $posy = 0; + +my $row = 0; +my %kp_mapping = ( # mapping for keypad, level 4 + 'Hom' => '⇱', + 'KP↑' => '⇡', + 'PgU' => '⇞', + 'KP←' => '⇠', + 'Beg' => '•', + 'KP→' => '⇢', + 'End' => '⇲', + 'KP↓' => '⇣', + 'PgD' => '⇟', + 'Ins' => '⎀', + 'Del' => '⌦', + 'Ent' => '↲', + 'vec' => ' ⃗' +); + +my $writer = new XML::Writer(ENCODING => 'utf-8', + DATA_MODE => 1, + DATA_INDENT => 2); + +start_svg; +create_defs; + +create_keys(parse_ref); + +end_svg; + +exit; + +# parse reference and return multi-array +sub parse_ref { + my @letters; + open REF, "../../A-REFERENZ-A/neo20.txt" + or die 'Error opening reference: '.$!; + while () { + my @layer; + last if /^== Zeichenerläuterungen/; + + # layout blocks + if(/Miniatur ===$/) { + while() { + last if(/^$/); # empty line => end of current block + next if($_ !~ /^│/); # skip horizontal dividers + + push @layer, split /│/; + } + push @letters, [ @layer ]; # push ref + } + } + close REF; + + return @letters; +} + +sub create_keys { + my @letters = @_; + + #for (0..$#{$letters[0]}) { # letters + for (0..$#{$letters[0]}) { # letters + create_key + $letters[0][$_], + $letters[0][$_], + $letters[1][$_], + $letters[2][$_], + $letters[3][$_]; + } + for (0..$#{$letters[7]}) { # numbers + create_key + $letters[7][$_], + $letters[7][$_], + $letters[8][$_], + $letters[9][$_], + $letters[10][$_]; + } +} + +sub css_builder { + my %props = @_; + my $css = ''; + + foreach (keys %props) { + $css .= "$_:${props{$_}};"; + } + return $css; +} + +sub in2px { + return ($_[0]||0) * $dpi; +} + +sub start_svg { + $writer->xmlDecl('UTF-8'); + $writer->doctype('svg', '-//W3C//DTD SVG 20001102//EN', + 'http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd'); + + $writer->startTag('svg', height => $height, width => $width, + 'xmlns:xlink' => 'http://www.w3.org/1999/xlink'); +} +sub end_svg { + $writer->endTag('svg'); + $writer->end(); +} + +# create the key template +sub create_defs { + $writer->startTag('defs'); + + # style information + $writer->dataElement('style', ' + text.common { + font-family:Linux Biolinum; + font-style:normal; + font-variant:normal; + font-stretch:normal; + text-align:center; + text-anchor:middle; + stroke:none; + } + text.main { + /*font-weight:bold;*/ + font-size:19px; + fill:#eeeeee; + stroke-width:4; + } + text.special { + font-size:16px; + stroke-width:3; + } + text.outline { + stroke:#111111; + stroke-linejoin:round; + }', type => 'text/css'); + + # boundary of keys + $writer->emptyTag('rect', + id => 'boundary', + width => $keywidth, height => $keyheight, + rx => 5, + style => css_builder( + fill => 'none', + stroke => '#eeeeee', + 'stroke-width' => in2px(0.005) + )); + # border for keys, actual key stickers + $writer->emptyTag('rect', + id => 'border', + width => $labelwidth, height => $labelheight, + rx => 10, + style => css_builder( + fill => '#333333', + stroke => '#eeeeee', + 'stroke-width' => in2px(0.025) + )); + + $writer->endTag('defs'); +} + +# create a specific key (cloned from template) +# first parameter (0) is first level, and is only used for line breaks in the graphic +# param 1..4 are actual layers +sub create_key { + my @keys = @_; + + $keys[0] = '' unless defined($keys[0]); + $keys[1] = '' unless defined($keys[1]); + s/\s//g for @keys; # remove any space + + # map words to symbols for numblock + foreach (keys %kp_mapping) { + $keys[3] =~ s/\Q$_/\Q$kp_mapping{$_}/; + $keys[4] =~ s/\Q$_/\Q$kp_mapping{$_}/; + } + + return if length($keys[0]) != 1; + + $writer->startTag('g', + transform => "translate($posx,$posy)", + id => 'key_'.(join '', @keys)); + $writer->emptyTag('use', 'xlink:href' => '#boundary'); + $writer->startTag('g', + transform => 'translate('.(($keywidth-$labelwidth)/2.5).', 2)'); + $writer->emptyTag('use', 'xlink:href' => '#border'); + + # add text+outlines to sticker + for(' outline', '') { + $writer->dataElement('text', $keys[1], + transform => 'translate(15,41)', + class => "common main$_") + # do not show e1, if it's the same letter as e2 + # only use for latin letters + unless(#$keys[1] =~ /[a-züöäß]/ && + $keys[1] =~ /\Q$keys[2]/i); + $writer->dataElement('text', $keys[2]||'', + transform => 'translate(15,19)', + class => "common main$_"); + $writer->dataElement('text', $keys[3]||'', + transform => 'translate(32,18)', + class => "common special$_", + style => css_builder(fill => '#99dd66')); + $writer->dataElement('text', $keys[4]||'', + transform => 'translate(32,42)', + class => "common special$_", + style => css_builder(fill => '#6699dd', + 'font-size' => '13px')); + # do not show e4 on keypad + #unless($row > 4 && $keys[0] =~ /\d/i); + } + $writer->endTag('g'); + $writer->endTag('g'); + + $posx += $keywidth; + if($row < 3) { + if($keys[0] =~ /[`´y]/) { # split keyboard rows, dirty way + $posx = ++$row*$keywidth/2; # not really accurate, but works + $posy += $keyheight; + } + } elsif($keys[0] =~ /[-93+j]/) { # keypad + $posx = ++$row*0; + $posy += $keyheight; + } +} + +sub round { + return int($_[0]+.5*($_[0]<=>0)); +} -- cgit v1.2.3