Eliminate the need for php.
Replace the only php script in "grafik" by a python script. Unfortunately this requires the Python package "lxml" (which is commonly used, though), since the "xml" package from the Python standard library is not quite capable. Since the original php script created a quite ugly and redundant svg file, I took the one from "grafik/bilder-einzeln/flat" as a basis. The new image is a bit different from the original, as it takes some ideas from "grafik/aufkleber/alle-grau-1234.py". Anyhow, almost all design parameters can be adjusted in the the stylesheet.
This commit is contained in:
parent
4db350cb29
commit
0982d8234a
@ -22,7 +22,6 @@ Um alle Bilder erzeugen können, benötigt man eine Vielzahl an Abhängigkeiten:
|
||||
- ed
|
||||
- libxkbcommon (xkbcli)
|
||||
- python mit jinja2, numpy, pandas, matplotlib, seaborn und lxml
|
||||
- php
|
||||
- Linux Libertine
|
||||
- Gentium Plus Compact
|
||||
- DejaVu Sans Mono
|
||||
|
@ -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()
|
@ -15,7 +15,6 @@ pkgs.mkShell {
|
||||
python3Packages.more-itertools
|
||||
python3Packages.jinja2
|
||||
python3Packages.lxml
|
||||
php
|
||||
];
|
||||
|
||||
# You also need to install the fonts (libertine gentium dejavu ... )
|
||||
|
Loading…
Reference in New Issue
Block a user