Merge pull request 'Eleminiere Abhängigkeit von perl und php.' (#604) from htgoebel/neo-layout:master into master
Reviewed-on: #604
This commit is contained in:
commit
2f8c93f1e4
@ -21,9 +21,7 @@ Um alle Bilder erzeugen können, benötigt man eine Vielzahl an Abhängigkeiten:
|
||||
- sed
|
||||
- ed
|
||||
- libxkbcommon (xkbcli)
|
||||
- python mit jinja2, more-itertools, numpy, pandas, matplotlib und seaborn
|
||||
- perl mit XML::Writer
|
||||
- php
|
||||
- python mit jinja2, numpy, pandas, matplotlib, seaborn und lxml
|
||||
- Linux Libertine
|
||||
- Gentium Plus Compact
|
||||
- DejaVu Sans Mono
|
||||
|
@ -1,7 +1,7 @@
|
||||
all: default
|
||||
|
||||
%-grau-1234.svg: ../../A-REFERENZ-A/%.txt
|
||||
./alle-grau-1234.pl $< > $@
|
||||
./alle-grau-1234.py $< > $@
|
||||
|
||||
EXTRASVG=\
|
||||
neo20-grau-1234.svg \
|
||||
|
@ -1,256 +0,0 @@
|
||||
#!/usr/bin/env -S perl -w
|
||||
|
||||
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 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, $ARGV[0]
|
||||
or die 'Error opening reference: '.$!;
|
||||
while (<REF>) {
|
||||
my @layer;
|
||||
last if /^== Zeichenerläuterungen/;
|
||||
|
||||
# layout blocks
|
||||
if(/Miniatur ===$/) {
|
||||
while(<REF>) {
|
||||
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
|
||||
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 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' => 'http://www.w3.org/2000/svg',
|
||||
'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 O, 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;
|
||||
}
|
||||
rect#boundary {
|
||||
fill:none;
|
||||
stroke:#eeeeee;
|
||||
stroke-width:'.in2px(0.005).';
|
||||
}
|
||||
rect#border {
|
||||
fill:#333333;
|
||||
stroke:#eeeeee;
|
||||
stroke-width:'.in2px(0.025).';
|
||||
}
|
||||
text.level1 {
|
||||
}
|
||||
text.level2 {
|
||||
}
|
||||
text.level3 {
|
||||
fill:#99dd66;
|
||||
}
|
||||
text.level4 {
|
||||
fill:#6699dd;
|
||||
font-size:13px;
|
||||
}', type => 'text/css');
|
||||
|
||||
# boundary of keys
|
||||
$writer->emptyTag('rect',
|
||||
id => 'boundary',
|
||||
width => $keywidth, height => $keyheight,
|
||||
rx => 5);
|
||||
# border for keys, actual key stickers
|
||||
$writer->emptyTag('rect',
|
||||
id => 'border',
|
||||
width => $labelwidth, height => $labelheight,
|
||||
rx => 10);
|
||||
|
||||
$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 => "level1 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 => "level2 common main$_");
|
||||
$writer->dataElement('text', $keys[3]||'',
|
||||
transform => 'translate(32,18)',
|
||||
class => "level3 common special$_");
|
||||
$writer->dataElement('text', $keys[4]||'',
|
||||
transform => 'translate(32,42)',
|
||||
class => "level4 common special$_");
|
||||
# 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));
|
||||
}
|
221
grafik/aufkleber/alle-grau-1234.py
Executable file
221
grafik/aufkleber/alle-grau-1234.py
Executable file
@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from lxml import etree as ET
|
||||
|
||||
|
||||
def in2px(inch):
|
||||
return round(inch * DPI, 2)
|
||||
|
||||
|
||||
DPI = 90
|
||||
|
||||
# a4 paper
|
||||
HEIGHT = in2px(8.268)
|
||||
WIDTH = in2px(11.69)
|
||||
|
||||
KEYWIDTH = in2px(0.75)
|
||||
KEYHEIGHT = in2px(0.75)
|
||||
LABELWIDTH = in2px(0.5)
|
||||
LABELHEIGHT = in2px(0.55)
|
||||
|
||||
KP_MAPPING = { # mapping for keypad, level 4
|
||||
'Hom': '⇱',
|
||||
'KP↑': '⇡',
|
||||
'PgU': '⇞',
|
||||
'KP←': '⇠',
|
||||
'Beg': '•',
|
||||
'KP→': '⇢',
|
||||
'End': '⇲',
|
||||
'KP↓': '⇣',
|
||||
'PgD': '⇟',
|
||||
'Ins': '⎀',
|
||||
'Del': '⌦',
|
||||
'Ent': '⏎',
|
||||
'vec': ' ⃗'
|
||||
}
|
||||
|
||||
strokewidth = in2px(0.005)
|
||||
STYLESHEET = '''
|
||||
text.common {
|
||||
font-family:Linux Biolinum O, 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;
|
||||
}
|
||||
rect#boundary {
|
||||
fill:none;
|
||||
stroke:#eeeeee;
|
||||
stroke-width:''' + str(in2px(0.005)) + '''px;
|
||||
}
|
||||
rect#border {
|
||||
fill:#333333;
|
||||
stroke:#eeeeee;
|
||||
stroke-width:''' + str(in2px(0.025)) + '''px;
|
||||
}
|
||||
text.level1 {
|
||||
}
|
||||
text.level2 {
|
||||
}
|
||||
text.level3 {
|
||||
fill:#99dd66;
|
||||
}
|
||||
text.level4 {
|
||||
fill:#6699dd;
|
||||
font-size:13px;
|
||||
}'''
|
||||
|
||||
NSMAP = {None: 'http://www.w3.org/2000/svg',
|
||||
'xlink': 'http://www.w3.org/1999/xlink'}
|
||||
XLINK = '{%s}' % NSMAP['xlink']
|
||||
DOCTYPE = ('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" '
|
||||
'"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">')
|
||||
|
||||
|
||||
def parse_ref(filename):
|
||||
'''parse reference and return multi-array'''
|
||||
with open(filename) as fh:
|
||||
lines = fh.read().splitlines()
|
||||
keymap = []
|
||||
state = 0
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if state == 0:
|
||||
if line.endswith("Miniatur ==="):
|
||||
state = 1
|
||||
layer = []
|
||||
keymap.append(layer)
|
||||
continue
|
||||
elif not line: # empty line: end of current block/layer
|
||||
state = 0
|
||||
layer = None
|
||||
continue
|
||||
elif not line.startswith("│"): # skip horizontal dividers
|
||||
continue
|
||||
else:
|
||||
line = [k.strip() for k in line.split("│")]
|
||||
layer.append(line[1:-1])
|
||||
return keymap
|
||||
|
||||
|
||||
def create_defs(parent):
|
||||
'''create the key template'''
|
||||
node = ET.SubElement(parent, 'defs')
|
||||
# style sheet
|
||||
ET.SubElement(node, 'style', type='text/css').text = STYLESHEET
|
||||
# boundary of keys
|
||||
ET.SubElement(node, 'rect', id='boundary',
|
||||
width=str(KEYWIDTH), height=str(KEYHEIGHT), rx="5")
|
||||
# border for keys, actual key stickers
|
||||
ET.SubElement(node, 'rect', id='border',
|
||||
width=str(LABELWIDTH), height=str(LABELHEIGHT), rx="10")
|
||||
|
||||
|
||||
def create_keys(parent, keymap):
|
||||
posy = 0
|
||||
|
||||
# main keyboard
|
||||
# TODO remove leading blank key
|
||||
for row in range(len(keymap[0])):
|
||||
posx = row / 2 * KEYWIDTH # not really accurate, but works
|
||||
for key in range(len(keymap[0][row])):
|
||||
key = create_key(parent, posx, posy,
|
||||
keymap[0][row][key],
|
||||
keymap[1][row][key],
|
||||
keymap[2][row][key],
|
||||
keymap[3][row][key])
|
||||
if key is not None: # advance only if sticker was output
|
||||
posx += KEYWIDTH
|
||||
posy += KEYHEIGHT
|
||||
|
||||
# numpad
|
||||
for row in range(len(keymap[7])):
|
||||
posx = 0
|
||||
for key in range(len(keymap[7][row])):
|
||||
key = create_key(parent, posx, posy,
|
||||
keymap[7][row][key],
|
||||
keymap[8][row][key],
|
||||
keymap[9][row][key],
|
||||
keymap[10][row][key])
|
||||
if key is not None: # advance only if sticker was output
|
||||
posx += KEYWIDTH
|
||||
posy += KEYHEIGHT
|
||||
|
||||
|
||||
def create_key(parent, posx, posy, *keys):
|
||||
'''create a specific key (cloned from template)'''
|
||||
|
||||
if len(keys[0]) != 1: # skip keys like Tab at the left side
|
||||
return
|
||||
|
||||
def text(level, trans, type):
|
||||
ET.SubElement(
|
||||
g1, 'text',
|
||||
{'transform': f'translate({trans})',
|
||||
'class': f"level{level} common {type}{outline}"}
|
||||
).text = keys[level-1]
|
||||
|
||||
keys = list(keys)
|
||||
|
||||
# map words to symbols for numblock
|
||||
keys[2] = KP_MAPPING.get(keys[2], keys[2])
|
||||
keys[3] = KP_MAPPING.get(keys[3], keys[3])
|
||||
|
||||
g0 = ET.SubElement(parent, 'g',
|
||||
transform=f"translate({posx},{posy})",
|
||||
id='key_' + ''.join(keys))
|
||||
ET.SubElement(g0, 'use', {XLINK + 'href': '#boundary'})
|
||||
g1 = ET.SubElement(g0, 'g',
|
||||
transform=f'translate({(KEYWIDTH-LABELWIDTH)/2.5}, 2)')
|
||||
ET.SubElement(g1, 'use', {XLINK + 'href': '#border'})
|
||||
|
||||
# do not show e1, if it's the same letter as e2
|
||||
upper_eq_lower = (keys[1].lower() == keys[0])
|
||||
|
||||
# add text+outlines to sticker
|
||||
for outline in (' outline', ''):
|
||||
if not upper_eq_lower:
|
||||
text(1, '15,41', 'main')
|
||||
text(2, '15,19', 'main')
|
||||
text(3, '32,18', 'special')
|
||||
text(4, '32,42', 'special')
|
||||
return g0
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('filename')
|
||||
args = parser.parse_args()
|
||||
|
||||
keymap = parse_ref(args.filename)
|
||||
|
||||
root = ET.Element('svg',
|
||||
height=str(HEIGHT), width=str(WIDTH),
|
||||
nsmap=NSMAP)
|
||||
create_defs(root)
|
||||
create_keys(root, keymap)
|
||||
|
||||
doc = ET.tostring(root, encoding="UTF-8", xml_declaration=True,
|
||||
doctype=DOCTYPE, pretty_print=True)
|
||||
sys.stdout.buffer.write(doc)
|
||||
|
||||
|
||||
main()
|
@ -7,13 +7,13 @@ neo-bunt-123456.png: neo-bunt-123456.ods
|
||||
libreoffice --convert-to png $<
|
||||
|
||||
neo20-grau-123456.svg:
|
||||
./all-grau-123456.php neo20
|
||||
./all-grau-123456.py neo20
|
||||
|
||||
bone-grau-123456.svg:
|
||||
./all-grau-123456.php bone
|
||||
./all-grau-123456.py bone
|
||||
|
||||
neoqwertz-grau-123456.svg:
|
||||
./all-grau-123456.php neoqwertz
|
||||
./all-grau-123456.py neoqwertz
|
||||
|
||||
EXTRASVG=\
|
||||
neo20-grau-123456.svg \
|
||||
|
File diff suppressed because it is too large
Load Diff
255
grafik/bilder-uebersicht/all-grau-123456.py
Executable file
255
grafik/bilder-uebersicht/all-grau-123456.py
Executable file
@ -0,0 +1,255 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from lxml import etree as ET
|
||||
|
||||
REFERENZ_DIR = '../../A-REFERENZ-A/'
|
||||
|
||||
KEYWIDTH = KEYHEIGHT = 72
|
||||
LABELWIDTH = KEYWIDTH
|
||||
LABELHEIGHT = KEYWIDTH
|
||||
|
||||
KP_MAPPING = { # mapping for keypad, level 4
|
||||
'Hom': '⇱',
|
||||
'KP↑': '⇡',
|
||||
'PgU': '⇞',
|
||||
'KP←': '⇠',
|
||||
'Beg': '•',
|
||||
'KP→': '⇢',
|
||||
'End': '⇲',
|
||||
'KP↓': '⇣',
|
||||
'PgD': '⇟',
|
||||
'Ins': '⎀',
|
||||
'Del': '⌦',
|
||||
'Ent': '⏎',
|
||||
'vec': ' ⃗'
|
||||
}
|
||||
|
||||
STYLESHEET = '''
|
||||
rect.grey { fill:#cccccc !important }
|
||||
rect.key { fill:white; stroke:black; stroke-width: 1 }
|
||||
|
||||
text {
|
||||
/* font-family:Linux Biolinum O, Linux Biolinum;*/
|
||||
font-family:normal;
|
||||
font-style:normal;
|
||||
font-variant:normal;
|
||||
font-stretch:normal;
|
||||
stroke:none;
|
||||
text-align:center;
|
||||
text-anchor:middle;
|
||||
dominant-baseline: middle;
|
||||
fill: black;
|
||||
}
|
||||
text.main { font-weight:bold }
|
||||
text.special { }
|
||||
text.level1 { font-size:22px }
|
||||
text.level2 { font-size:22px }
|
||||
text.level3 { font-size:14px }
|
||||
text.level4 { font-size:14px }
|
||||
text.level5 { font-size:14px }
|
||||
text.level6 { font-size:14px }
|
||||
text.deadkey { fill: red }
|
||||
text.modifier { font-size:20px }
|
||||
'''
|
||||
|
||||
NSMAP = {None: 'http://www.w3.org/2000/svg',
|
||||
'xlink': 'http://www.w3.org/1999/xlink'}
|
||||
XLINK = '{%s}' % NSMAP['xlink']
|
||||
DOCTYPE = ('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" '
|
||||
'"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">')
|
||||
|
||||
|
||||
LAYOUT = (
|
||||
[1] * 13 + [2.0],
|
||||
[1.5] + [1] * 12 + [0],
|
||||
[1.75] + [1] * 11 + [1.0, 0],
|
||||
[1.25, 1.0] + [1] * 10 + [2.75, 0],
|
||||
)
|
||||
|
||||
SPECIAL_KEYS = (
|
||||
(0, 13, 2.0, "Backspace"),
|
||||
(1, 0, 1.5, "Tab"),
|
||||
(2, 0, 1.75, "Mod 3"),
|
||||
(2, 12.75, 1, "Mod 3"),
|
||||
(3, 0, 1.25, "Umsch"),
|
||||
(3, 1.25, 1, "Mod 4"),
|
||||
(3, 12.25, 2.75, "Umschalt"),
|
||||
(4, 0, 1.5, "Strg"),
|
||||
(4, 2.5, 1.5, "Alt"),
|
||||
(4, 9.5, 1.5, "Mod4"),
|
||||
(4, 13.5, 1.5, "Strg"),
|
||||
)
|
||||
|
||||
|
||||
def parse_ref(layout):
|
||||
'''parse reference and return multi-array'''
|
||||
filename = os.path.join(REFERENZ_DIR, f'{layout}.txt')
|
||||
with open(filename) as fh:
|
||||
lines = fh.read().splitlines()
|
||||
keymap = []
|
||||
state = 0
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if state == 0:
|
||||
if line.endswith("Miniatur ==="):
|
||||
state = 1
|
||||
layer = []
|
||||
keymap.append(layer)
|
||||
continue
|
||||
elif not line: # empty line: end of current block/layer
|
||||
state = 0
|
||||
layer = None
|
||||
continue
|
||||
elif not line.startswith("│"): # skip horizontal dividers
|
||||
continue
|
||||
else:
|
||||
line = [k.strip() for k in line.split("│")]
|
||||
layer.append(line[1:-1])
|
||||
return keymap
|
||||
|
||||
|
||||
def create_defs(parent):
|
||||
'''create the key template'''
|
||||
node = ET.SubElement(parent, 'defs')
|
||||
# style sheet
|
||||
ET.SubElement(node, 'style', type='text/css').text = STYLESHEET
|
||||
# boundary of keys
|
||||
# ET.SubElement(node, 'rect', id='boundary',
|
||||
# width=str(KEYWIDTH), height=str(KEYHEIGHT), rx="0")
|
||||
# # border for keys, actual key stickers
|
||||
# ET.SubElement(node, 'rect', id='border',
|
||||
# width=str(LABELWIDTH), height=str(LABELHEIGHT), rx="0")
|
||||
|
||||
|
||||
def draw_keys(parent):
|
||||
# draw return key first to be overdrawn by others
|
||||
w = sum(LAYOUT[0]) * KEYWIDTH
|
||||
posx = sum(LAYOUT[1]) * KEYWIDTH
|
||||
ET.SubElement(parent, 'rect', {'class': 'key grey'},
|
||||
x=str(posx), y=str(KEYHEIGHT + 1),
|
||||
width=str(w - posx), height=str(2 * KEYHEIGHT))
|
||||
|
||||
def rect(x, y, kwidth, classes):
|
||||
kwidth *= KEYWIDTH
|
||||
ET.SubElement(parent, 'rect', {'class': classes},
|
||||
x=str(x), y=str(y),
|
||||
width=str(kwidth), height=str(KEYHEIGHT))
|
||||
return kwidth
|
||||
|
||||
# other keys
|
||||
posy = 1
|
||||
for row in LAYOUT:
|
||||
posx = 0
|
||||
for key in row:
|
||||
if not key:
|
||||
continue
|
||||
elif isinstance(key, float):
|
||||
kwidth = key * KEYWIDTH
|
||||
else:
|
||||
kwidth = rect(posx, posy, key, 'key')
|
||||
posx += kwidth
|
||||
posy += KEYHEIGHT
|
||||
drawing_width = posx + 1
|
||||
|
||||
# special keys
|
||||
for row, col_offset, kwidth, label in SPECIAL_KEYS:
|
||||
rect(col_offset * KEYWIDTH, row * KEYHEIGHT + 1, kwidth, 'key grey')
|
||||
rect(4 * KEYWIDTH, posy, 5.5, 'key') # Leertaste
|
||||
|
||||
posy += KEYHEIGHT
|
||||
return drawing_width, posy
|
||||
|
||||
|
||||
def create_labels(parent, keymap):
|
||||
posy = 1
|
||||
# main keyboard
|
||||
for row in range(len(keymap[0])-1):
|
||||
posx = 0
|
||||
for key in range(len(keymap[0][row])):
|
||||
create_label(parent, posx, posy,
|
||||
keymap[0][row][key],
|
||||
keymap[1][row][key],
|
||||
keymap[2][row][key],
|
||||
keymap[3][row][key],
|
||||
keymap[4][row][key],
|
||||
keymap[5][row][key])
|
||||
posx += LAYOUT[row][key] * KEYWIDTH
|
||||
posy += KEYHEIGHT
|
||||
|
||||
def text(x, y, kwidth, label):
|
||||
x = x * KEYWIDTH + kwidth * KEYWIDTH / 2 + 1
|
||||
y = y * KEYHEIGHT + KEYHEIGHT / 2 + 1
|
||||
ET.SubElement(
|
||||
parent, 'text',
|
||||
{'x': str(x), 'y': str(y),
|
||||
'class': 'modifier'}
|
||||
).text = label
|
||||
|
||||
# special keys
|
||||
for row, col_offset, kwidth, label in SPECIAL_KEYS:
|
||||
text(col_offset, row, kwidth, label)
|
||||
text(13.5, 1.25, 1.75, "Return")
|
||||
|
||||
|
||||
def create_label(parent, posx, posy, *labels):
|
||||
'''create a specific key (cloned from template)'''
|
||||
|
||||
def text(level, trans, type):
|
||||
ET.SubElement(
|
||||
g, 'text',
|
||||
{'transform': f'translate({trans})',
|
||||
'class': f"level{level} {type} {deadkey}"}
|
||||
).text = labels[level-1]
|
||||
|
||||
labels = list(labels)
|
||||
if len(labels[0]) > 1:
|
||||
# special keys are labels special above
|
||||
return
|
||||
|
||||
# map words to symbols for numblock
|
||||
labels[2] = KP_MAPPING.get(labels[2], labels[2])
|
||||
labels[3] = KP_MAPPING.get(labels[3], labels[3])
|
||||
|
||||
g = ET.SubElement(parent, 'g',
|
||||
transform=f"translate({posx},{posy})",
|
||||
id='key_' + ''.join(labels))
|
||||
upper_eq_lower = (labels[1].lower() == labels[0])
|
||||
deadkey = 'deadkey' if labels[0] in "ˆ`´" else 'live'
|
||||
|
||||
if upper_eq_lower:
|
||||
# do not show e1, if it's the same letter as e2
|
||||
text(2, '15,35', 'main')
|
||||
else:
|
||||
text(1, '15,55', 'main')
|
||||
text(2, '15,20', '')
|
||||
text(3, '42,50', 'special')
|
||||
text(4, '42,20', 'special')
|
||||
text(5, '59,50', 'special')
|
||||
text(6, '59,20', 'special')
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('layout')
|
||||
args = parser.parse_args()
|
||||
|
||||
keymap = parse_ref(args.layout)
|
||||
|
||||
root = ET.Element('svg',
|
||||
nsmap=NSMAP)
|
||||
create_defs(root)
|
||||
width, height = draw_keys(root)
|
||||
create_labels(root, keymap)
|
||||
|
||||
root.set('width', str(width))
|
||||
root.set('height', str(height))
|
||||
|
||||
doc = ET.tostring(root, encoding="utf-8", xml_declaration=True,
|
||||
doctype=DOCTYPE, pretty_print=True)
|
||||
with open(f'{args.layout}-grau-123456.svg', 'wb') as fh:
|
||||
fh.write(doc)
|
||||
|
||||
|
||||
main()
|
@ -14,9 +14,7 @@ pkgs.mkShell {
|
||||
python3Packages.seaborn
|
||||
python3Packages.more-itertools
|
||||
python3Packages.jinja2
|
||||
perl
|
||||
perlPackages.XMLWriter
|
||||
php
|
||||
python3Packages.lxml
|
||||
];
|
||||
|
||||
# You also need to install the fonts (libertine gentium dejavu ... )
|
||||
|
Loading…
Reference in New Issue
Block a user