Advertisement
creamygoat

RenderKeys

Aug 11th, 2013
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 18.36 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #-------------------------------------------------------------------------------
  4. # renderkeys.py
  5. # http://pastebin.com/jBLu3EFT
  6. #-------------------------------------------------------------------------------
  7.  
  8.  
  9. u'''RenderKeys outputs an SVG of a keyboard template for Thurly Wop.
  10.  
  11. Description:
  12.  It does what it says on the tin.
  13.  
  14. Author:
  15.  Daniel Neville (Blancmange), creamygoat@gmail.com
  16.  
  17. Copyright:
  18.  None
  19.  
  20. Licence:
  21.  Public domain
  22.  
  23.  
  24. INDEX
  25.  
  26.  
  27. Imports
  28.  
  29. Exceptions:
  30.  
  31.  Error
  32.  
  33. Helpter functions:
  34.  
  35.  Save(Data, FileName)
  36.  HTMLEscaped(Text): string
  37.  AttrMarkup(Attributes, PrependSpace): string
  38.  
  39. Implementation:
  40.  
  41.  KeyboardSVG(): string
  42.  
  43. Main:
  44.  
  45.  Main()
  46.  
  47.  
  48. '''
  49.  
  50.  
  51. #-------------------------------------------------------------------------------
  52. # Imports
  53. #-------------------------------------------------------------------------------
  54.  
  55.  
  56. from __future__ import division
  57.  
  58. import sys
  59. import traceback
  60.  
  61. import math
  62.  
  63. from math import (
  64.   pi, sqrt, hypot, sin, cos, tan, asin, acos, atan, atan2, radians, degrees,
  65.   floor, ceil
  66. )
  67.  
  68.  
  69. #-------------------------------------------------------------------------------
  70.  
  71.  
  72. def Save(Data, FileName):
  73.  
  74.   u'''Save data to a new file.
  75.  
  76.  Data is usually a string. If a file with the given name already exists,
  77.  it is overwritten.
  78.  
  79.  If the string is a Unicode string, it should be encoded:
  80.  
  81.    Save(Data.encode('utf_8'), FileName)
  82.  
  83.  Encoding will fail if Data is a non-Unicode string which contains a
  84.  character outside of the 7-bit ASCII range. This can easily occur
  85.  when an ordinary byte string contains a Latin-1 character such as
  86.  the times symbol (“×”, code 215). Take care to prefix non-ASCII
  87.  string constants with “u”.
  88.  
  89.  '''
  90.  
  91.   f = open(FileName, 'wb')
  92.  
  93.   try:
  94.     f.write(Data)
  95.   finally:
  96.     f.close()
  97.  
  98.  
  99. #-------------------------------------------------------------------------------
  100.  
  101.  
  102. def HTMLEscaped(Text):
  103.  
  104.   u'''Return text safe to use in HTML text and in quoted attributes values.
  105.  
  106.  Using unquoted values in attribute assignments where the values can be
  107.  chosen by an untrusted agent can lead to a script injection attack unless
  108.  the values are very heavily sanitised. It is good practice to always wrap
  109.  attribute values in single or double quotes.
  110.  
  111.  '''
  112.  
  113.   EntityMap = {
  114.     '&': '&',
  115.     '<': '&lt;',
  116.     '>': '&gt;',
  117.     '"': '&quot;',
  118.     "'": '&apos;',
  119.     '`': '&#96;'
  120.   }
  121.  
  122.   Result = ""
  123.  
  124.   for RawC in Text:
  125.     SafeC = EntityMap[RawC] if RawC in EntityMap else RawC
  126.     Result += SafeC
  127.  
  128.   return Result
  129.  
  130.  
  131. #-------------------------------------------------------------------------------
  132.  
  133.  
  134. def AttrMarkup(Attributes, PrependSpace):
  135.  
  136.   u'''Return HTML-style attribute markup from a dictionary.
  137.  
  138.  if PrependSpace is True and there is at least one attribute assignment
  139.  generated, a space is added to the beginning of the result.
  140.  
  141.  Both an empty dictionary and None are valid values for Attributes.
  142.  
  143.  '''
  144.  
  145.   Result = ''
  146.  
  147.   if Attributes is not None:
  148.     for Attr, Value in Attributes.items():
  149.       if PrependSpace or (Result != ''):
  150.         Result += ' '
  151.       Result += HTMLEscaped(Attr) + '="' + HTMLEscaped(Value) + '"'
  152.  
  153.   return Result
  154.  
  155.  
  156. #-------------------------------------------------------------------------------
  157.  
  158.  
  159. def KeyboardSVG():
  160.  
  161.   u'''Render the key template as a string of SVG markup.'''
  162.  
  163.   LegendLayouts = [
  164.     (
  165.       # 0: Letter keys
  166.       [
  167.         [
  168.           'font-family="Ariel, sans-serif"',
  169.           'font-size="36" font-weight="normal" text-anchor="middle"'
  170.         ]
  171.       ],
  172.       [[(28, 47)]]
  173.     ),
  174.     (
  175.       # 1: Number and symbol keys
  176.       [
  177.         [
  178.           'font-family="Ariel, sans-serif"',
  179.           'font-size="28" font-weight="normal" text-anchor="start"'
  180.         ]
  181.       ],
  182.       [[(22, 60)], [(22, 41), (22, 79)]]
  183.     ),
  184.     (
  185.       # 2: Left-aligned special keys
  186.       [
  187.         [
  188.           'font-family="Ariel, sans-serif"',
  189.           'font-size="20" font-weight="normal" text-anchor="start"'
  190.         ]
  191.       ],
  192.       [[(18, 56)], [(18, 44), (18, 68)], [(18, 56), (75, 44), (75, 65)]]
  193.     ),
  194.     (
  195.       # 1: Numerc cluster
  196.       [
  197.         [
  198.           'font-family="Ariel, sans-serif"',
  199.           'font-size="28" font-weight="normal" text-anchor="start"'
  200.         ],
  201.         [
  202.           'font-family="Ariel, sans-serif"',
  203.           'font-size="20" font-weight="normal" text-anchor="start"'
  204.         ]
  205.       ],
  206.       [[(22, 56)], [(22, 41), (22, 77)]]
  207.     )
  208.   ]
  209.  
  210.   Minus = u'\u2212'
  211.   AsteriskOp = u'\u2217'
  212.   UpArrow = u'\u2191'
  213.   DownArrow = u'\u2193'
  214.   LeftArrow = u'\u2190'
  215.   RightArrow = u'\u2192'
  216.  
  217.   KeyGroups = [
  218.     (
  219.       'Escape and function keys',
  220.       (
  221.         'Esc',
  222.         'F1', 'F2', 'F3', 'F4',
  223.         'F5', 'F6', 'F7', 'F8',
  224.         'F9', 'F10','F11','F12'
  225.       )
  226.     ),
  227.     (
  228.       'Numbers and symbols row',
  229.       (
  230.         'Grave',
  231.         '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
  232.         'Hyphen', 'Equals', 'Backspace'
  233.       )
  234.     ),
  235.     (
  236.       'Top row of letters',
  237.       (
  238.         'Tab',
  239.         'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P',
  240.         'LBracket', 'RBracket', 'Backslash'
  241.       )
  242.     ),
  243.     (
  244.       'Middle row of letters',
  245.       (
  246.         'CapsLock',
  247.         'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L',
  248.         'Semicolon', 'SingleQuote', 'Return'
  249.       )
  250.     ),
  251.     (
  252.       'Bottom row of letters',
  253.       (
  254.         'LShift',
  255.         'Z', 'X', 'C', 'V', 'B', 'N', 'M',
  256.         'Comma', 'Period', 'Slash', 'RShift'
  257.       )
  258.     ),
  259.     (
  260.       'Space bar and qualifier keys',
  261.       (
  262.         'LCtrl', 'LSys', 'LAlt',
  263.         'Space',
  264.         'RAlt', 'RSys', 'RCmd', 'RCtrl'
  265.       )
  266.     ),
  267.     (
  268.       'Terminal keys',
  269.       (
  270.         'PrintScreen', 'ScrollLock', 'Pause'
  271.       )
  272.     ),
  273.     (
  274.       'Editing and navigation keys',
  275.       (
  276.         'Insert', 'Home', 'PageUp',
  277.         'Delete', 'End', 'PageDown',
  278.         'Up',
  279.         'Left', 'Down', 'Right'
  280.       )
  281.     ),
  282.     (
  283.       'Numeric cluster',
  284.       (
  285.         'NumLock', 'Divide', 'Multiply', 'Subtract',
  286.         'N7', 'N8', 'N9', 'Add',
  287.         'N4', 'N5', 'N6',
  288.         'N1', 'N2', 'N3', 'Enter',
  289.         'N0', 'DecimalPoint'
  290.       )
  291.     )
  292.   ]
  293.  
  294.   KeyCapData = {
  295.     'Esc': ((0, 0), (100, 100), (2, [u'Esc'])),
  296.     'F1': ((200, 0), (100, 100), (2, [u'F1'])),
  297.     'F2': ((300, 0), (100, 100), (2, [u'F2'])),
  298.     'F3': ((400, 0), (100, 100), (2, [u'F3'])),
  299.     'F4': ((500, 0), (100, 100), (2, [u'F4'])),
  300.     'F5': ((650, 0), (100, 100), (2, [u'F5'])),
  301.     'F6': ((750, 0), (100, 100), (2, [u'F6'])),
  302.     'F7': ((850, 0), (100, 100), (2, [u'F7'])),
  303.     'F8': ((950, 0), (100, 100), (2, [u'F8'])),
  304.     'F9': ((1100, 0), (100, 100), (2, [u'F9'])),
  305.     'F10': ((1200, 0), (100, 100), (2, [u'F10'])),
  306.     'F11': ((1300, 0), (100, 100), (2, [u'F11'])),
  307.     'F12': ((1400, 0), (100, 100), (2, [u'F12'])),
  308.     'Grave': ((0, 150), (100, 100), (1, [u'~', u'`'])),
  309.     '1': ((100, 150), (100, 100), (1, [u'!', u'1'])),
  310.     '2': ((200, 150), (100, 100), (1, [u'@', u'2'])),
  311.     '3': ((300, 150), (100, 100), (1, [u'#', u'3'])),
  312.     '4': ((400, 150), (100, 100), (1, [u'$', u'4'])),
  313.     '5': ((500, 150), (100, 100), (1, [u'%', u'5'])),
  314.     '6': ((600, 150), (100, 100), (1, [u'^', u'6'])),
  315.     '7': ((700, 150), (100, 100), (1, [u'&', u'7'])),
  316.     '8': ((800, 150), (100, 100), (1, [AsteriskOp, u'8'])),
  317.     '9': ((900, 150), (100, 100), (1, [u'(', u'9'])),
  318.     '0': ((1000, 150), (100, 100), (1, [u')', u'0'])),
  319.     'Hyphen': ((1100, 150), (100, 100), (1, [u'—', Minus])),
  320.     'Equals': ((1200, 150), (100, 100), (1, [u'+', u'='])),
  321.     'Backspace': ((1300, 150), (200, 100), (2, [u'\u2190 Backspace'])),
  322.     'Tab': ((0, 250), (150, 100), (2, [u'Tab', u'\u21e4', u'\u21e5'])),
  323.     'Q': ((150, 250), (100, 100), (0, [u'Q'])),
  324.     'W': ((250, 250), (100, 100), (0, [u'W'])),
  325.     'E': ((350, 250), (100, 100), (0, [u'E'])),
  326.     'R': ((450, 250), (100, 100), (0, [u'R'])),
  327.     'T': ((550, 250), (100, 100), (0, [u'T'])),
  328.     'Y': ((650, 250), (100, 100), (0, [u'Y'])),
  329.     'U': ((750, 250), (100, 100), (0, [u'U'])),
  330.     'I': ((850, 250), (100, 100), (0, [u'I'])),
  331.     'O': ((950, 250), (100, 100), (0, [u'O'])),
  332.     'P': ((1050, 250), (100, 100), (0, [u'P'])),
  333.     'LBracket': ((1150, 250), (100, 100), (1, [u'{', u'['])),
  334.     'RBracket': ((1250, 250), (100, 100), (1, [u'}', u']'])),
  335.     'Backslash': ((1350, 250), (150, 100), (1, [u'|', u'\\'])),
  336.     'CapsLock': ((0, 350), (175, 100), (2, [u'Caps Lock'])),
  337.     'A': ((175, 350), (100, 100), (0, [u'A'])),
  338.     'S': ((275, 350), (100, 100), (0, [u'S'])),
  339.     'D': ((375, 350), (100, 100), (0, [u'D'])),
  340.     'F': ((475, 350), (100, 100), (0, [u'F'])),
  341.     'G': ((575, 350), (100, 100), (0, [u'G'])),
  342.     'H': ((675, 350), (100, 100), (0, [u'H'])),
  343.     'J': ((775, 350), (100, 100), (0, [u'J'])),
  344.     'K': ((875, 350), (100, 100), (0, [u'K'])),
  345.     'L': ((975, 350), (100, 100), (0, [u'L'])),
  346.     'Semicolon': ((1075, 350), (100, 100), (1, [u':', u';'])),
  347.     'SingleQuote': ((1175, 350), (100, 100), (1, [u'"', u'\''])),
  348.     'Return': ((1275, 350), (225, 100), (2, [u'Enter \u21b5'])),
  349.     'LShift': ((0, 450), (225, 100), (2,[ u'\u21e7 Shift'])),
  350.     'Z': ((225, 450), (100, 100), (0, [u'Z'])),
  351.     'X': ((325, 450), (100, 100), (0, [u'X'])),
  352.     'C': ((425, 450), (100, 100), (0, [u'C'])),
  353.     'V': ((525, 450), (100, 100), (0, [u'V'])),
  354.     'B': ((625, 450), (100, 100), (0, [u'B'])),
  355.     'N': ((725, 450), (100, 100), (0, [u'N'])),
  356.     'M': ((825, 450), (100, 100), (0, [u'M'])),
  357.     'Comma': ((925, 450), (100, 100), (1, [u'<', u','])),
  358.     'Period': ((1025, 450), (100, 100), (1, [u'>', u'.'])),
  359.     'Slash': ((1125, 450), (100, 100), (1, [u'?', u'/'])),
  360.     'RShift': ((1225, 450), (275, 100), (2, [u'\u21e7 Shift'])),
  361.     'LCtrl': ((0, 550), (150, 100), (2, [u'Ctrl'])),
  362.     'LSys': ((150, 550), (100, 100), (2, [u'Sys'])),
  363.     'LAlt': ((250, 550), (150, 100), (2, [u'Alt'])),
  364.     'Space': ((400, 550), (600, 100), (0, [])),
  365.     'RAlt': ((1000, 550), (125, 100), (2, [u'Alt'])),
  366.     'RSys': ((1125, 550), (125, 100), (2, [u'Sys'])),
  367.     'RCmd': ((1250, 550), (125, 100), (2, [u'Cmd'])),
  368.     'RCtrl': ((1375, 550), (125, 100), (2, [u'Ctrl'])),
  369.     'PrintScreen': ((1550, 0), (100, 100), (2, [u'PrtSc', u'SysRq'])),
  370.     'ScrollLock': ((1650, 0), (100, 100), (2, [u'Scroll', u'Lock'])),
  371.     'Pause': ((1750, 0), (100, 100), (2, [u'Pause', u'Break'])),
  372.     'Insert': ((1550, 150), (100, 100), (2, [u'Insert'])),
  373.     'Delete': ((1550, 250), (100, 100), (2, [u'Delete'])),
  374.     'Home': ((1650, 150), (100, 100), (2, [u'Home'])),
  375.     'End': ((1650, 250), (100, 100), (2, [u'End'])),
  376.     'PageUp': ((1750, 150), (100, 100), (2, [u'Page', u'Up'])),
  377.     'PageDown': ((1750, 250), (100, 100), (2, [u'Page', u'Down'])),
  378.     'Up': ((1650, 450), (100, 100), (0, [UpArrow])),
  379.     'Left': ((1550, 550), (100, 100), (0, [LeftArrow])),
  380.     'Down': ((1650, 550), (100, 100), (0, [DownArrow])),
  381.     'Right': ((1750, 550), (100, 100), (0, [RightArrow])),
  382.     'NumLock': ((1900, 150), (100, 100), (2, [u'Num', u'Lock'])),
  383.     'Divide': ((2000, 150), (100, 100), (3, [u'/'])),
  384.     'Multiply': ((2100, 150), (100, 100), (3, [AsteriskOp])),
  385.     'Subtract': ((2200, 150), (100, 100), (3, [Minus])),
  386.     'Add': ((2200, 250), (100, 200), (3, [u'+'])),
  387.     'Enter': ((2200, 450), (100, 200), (2, [u'Enter'])),
  388.     'DecimalPoint': ((2100, 550), (100, 100), (3, [u'.', u'Del'])),
  389.     'N0': ((1900, 550), (200, 100), (3, [u'0', u'Ins'])),
  390.     'N1': ((1900, 450), (100, 100), (3, [u'1', u'End'])),
  391.     'N2': ((2000, 450), (100, 100), (3, [u'2', DownArrow])),
  392.     'N3': ((2100, 450), (100, 100), (3, [u'3', u'PgDn'])),
  393.     'N4': ((1900, 350), (100, 100), (3, [u'4', LeftArrow])),
  394.     'N5': ((2000, 350), (100, 100), (3, [u'5', u''])),
  395.     'N6': ((2100, 350), (100, 100), (3, [u'6', RightArrow])),
  396.     'N7': ((1900, 250), (100, 100), (3, [u'7', u'Home'])),
  397.     'N8': ((2000, 250), (100, 100), (3, [u'8', UpArrow])),
  398.     'N9': ((2100, 250), (100, 100), (3, [u'9', u'PgUp']))
  399.   }
  400.  
  401.   KeySpriteNamesByDimensions = {
  402.     (100, 100): 'key',
  403.     (125, 100): 'keyW125',
  404.     (150, 100): 'keyW150',
  405.     (175, 100): 'keyW175',
  406.     (200, 100): 'keyW200',
  407.     (225, 100): 'keyW225',
  408.     (275, 100): 'keyW275',
  409.     (600, 100): 'keyW600',
  410.     (100, 200): 'keyH200'
  411.   }
  412.  
  413.   #-----------------------------------------------------------------------------
  414.  
  415.   def PrologueLines():
  416.  
  417.     Lines = [
  418.       u'<?xml version="1.0" standalone="no"?>',
  419.       u'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"',
  420.       u'  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
  421.       u'<svg width="28cm" height="7.913043478cm" viewBox="0 0 2300 650"',
  422.       u'    preserveAspectRatio="xMidYMid meet"',
  423.       u'    xmlns="http://www.w3.org/2000/svg" version="1.1"',
  424.       u'    xmlns:xlink="http://www.w3.org/1999/xlink">',
  425.       u'<title>Keyboard Layout</title>',
  426.       u'<defs>',
  427.       u'  <symbol id="key" viewBox="0 0 100 100">',
  428.       u'    <rect x="5" y="5" width="90" height="90" rx="10" ry="10"/>',
  429.       u'  </symbol>',
  430.       u'  <symbol id="keyW125" viewBox="0 0 125 100">',
  431.       u'    <rect x="5" y="5" width="115" height="90" rx="10" ry="10"/>',
  432.       u'  </symbol>',
  433.       u'  <symbol id="keyW150" viewBox="0 0 150 100">',
  434.       u'    <rect x="5" y="5" width="140" height="90" rx="10" ry="10"/>',
  435.       u'  </symbol>',
  436.       u'  <symbol id="keyW175" viewBox="0 0 175 100">',
  437.       u'    <rect x="5" y="5" width="165" height="90" rx="10" ry="10"/>',
  438.       u'  </symbol>',
  439.       u'  <symbol id="keyW200" viewBox="0 0 200 100">',
  440.       u'    <rect x="5" y="5" width="190" height="90" rx="10" ry="10"/>',
  441.       u'  </symbol>',
  442.       u'  <symbol id="keyW225" viewBox="0 0 225 100">',
  443.       u'    <rect x="5" y="5" width="215" height="90" rx="10" ry="10"/>',
  444.       u'  </symbol>',
  445.       u'  <symbol id="keyW275" viewBox="0 0 275 100">',
  446.       u'    <rect x="5" y="5" width="265" height="90" rx="10" ry="10"/>',
  447.       u'  </symbol>',
  448.       u'  <symbol id="keyW600" viewBox="0 0 600 100">',
  449.       u'    <rect x="5" y="5" width="590" height="90" rx="10" ry="10"/>',
  450.       u'  </symbol>',
  451.       u'  <symbol id="keyH200" viewBox="0 0 100 200">',
  452.       u'    <rect x="5" y="5" width="90" height="190" rx="10" ry="10"/>',
  453.       u'  </symbol>',
  454.       u'</defs>',
  455.       u'',
  456.       u'<!-- Background -->',
  457.       u'<rect x="0" y="0" width="2300" height="650" ' +
  458.           u'stroke="none" fill="silver"/>',
  459.       u'',
  460.     ]
  461.  
  462.     return Lines
  463.  
  464.   #-----------------------------------------------------------------------------
  465.  
  466.   def EpilogueLines():
  467.  
  468.     Lines = [
  469.       u'',
  470.       u'</svg>'
  471.     ]
  472.  
  473.     return Lines
  474.  
  475.   #-----------------------------------------------------------------------------
  476.  
  477.   def BodyLines():
  478.  
  479.     Lines = []
  480.  
  481.     DefaultLL = LegendLayouts[0]
  482.  
  483.     Lines.append(u'<g stroke-width="5" stroke="black" fill="white"')
  484.     for Str in DefaultLL[0][0]:
  485.       Lines.append(u'    ' + Str)
  486.     Lines[-1] += '>'
  487.     Lines.append(u'')
  488.  
  489.     for GIx, GroupData in enumerate(KeyGroups):
  490.  
  491.       GroupDesc, Keys = GroupData
  492.       Lines.append(u'<!-- ' + GroupDesc + '-->')
  493.       Lines.append(u'')
  494.  
  495.       for KIx, Key in enumerate(Keys):
  496.  
  497.         if Key in KeyCapData:
  498.  
  499.           KCData = KeyCapData[Key]
  500.           Pos, Size, LegendData = KCData
  501.           LegendStyleIx, LegendStrs = LegendData
  502.           LL = LegendLayouts[LegendStyleIx]
  503.  
  504.           PosStr = u'%g, %g' % (Pos[0], Pos[1])
  505.           WHStr = u'width="%g" height="%g"' % (Size[0], Size[1])
  506.  
  507.           SpriteName = KeySpriteNamesByDimensions[Size]
  508.  
  509.           Lines.append(u'  <!-- ' + Key + ' -->')
  510.  
  511.           Lines.append(u'  <g transform="translate(' + PosStr + u')"')
  512.           if LegendStyleIx != 0:
  513.             for Str in LL[0][0]:
  514.               Lines.append(u'      ' + Str)
  515.           Lines[-1] += '>'
  516.  
  517.           Lines.append(u'    <use x="0" y="0" ' + WHStr +
  518.               ' xlink:href="#' + SpriteName + '"/>')
  519.  
  520.           if LegendStrs != []:
  521.  
  522.             LegendPositions = LL[1][len(LegendStrs) - 1]
  523.  
  524.             for LIx, Legend in enumerate(LegendStrs):
  525.  
  526.               AttrsIx = min(LIx, len(LL[0]) - 1)
  527.               Attrs = LL[0][AttrsIx]
  528.  
  529.               LegendPos = LegendPositions[LIx]
  530.  
  531.               if Size[1] > 100:
  532.                 LegendPos = (LegendPos[0], LegendPos[1] + 50)
  533.  
  534.               LegendPosStr = u'x="%g" y="%g"' % (LegendPos[0], LegendPos[1])
  535.               TextCmdStr = (u'    <text ' + LegendPosStr +
  536.                   ' fill="black" stroke="none">' +
  537.                   HTMLEscaped(Legend) +
  538.                   u'</text>')
  539.  
  540.               if AttrsIx > 0:
  541.                 Lines.append(u'    <g')
  542.                 if len(Attrs) > 0:
  543.                   Lines[-1] += u' ' + Attrs[0]
  544.                   for Str in Attrs[1:]:
  545.                     Lines.append(u'        ' + Str)
  546.                 Lines[-1] += '>'
  547.                 Lines.append(u'  ' + TextCmdStr)
  548.                 Lines.append(u'    </g>')
  549.               else:
  550.                 Lines.append(TextCmdStr)
  551.  
  552.           Lines.append(u'  </g>')
  553.  
  554.       Lines.append(u'')
  555.  
  556.     Lines.append(u'</g>')
  557.     Lines.append(u'')
  558.  
  559.     return Lines
  560.  
  561.   #-----------------------------------------------------------------------------
  562.  
  563.   Lines = []
  564.  
  565.   Lines += PrologueLines();
  566.   Lines += BodyLines();
  567.   Lines += EpilogueLines();
  568.   Lines.append('')
  569.  
  570.   return '\n'.join(Lines)
  571.  
  572.  
  573. #-------------------------------------------------------------------------------
  574. # Main
  575. #-------------------------------------------------------------------------------
  576.  
  577.  
  578. def Main():
  579.  
  580.   Result = 0
  581.   ErrMsg = ''
  582.  
  583.   OutputFileName = 'Keys.svg'
  584.  
  585.   S = ''
  586.  
  587.   try:
  588.  
  589.     S = KeyboardSVG()
  590.     Save(S.encode('utf_8'), OutputFileName)
  591.  
  592.   except (Exception), E:
  593.  
  594.     exc_type, exc_value, exc_traceback = sys.exc_info()
  595.     ErrLines = traceback.format_exc().splitlines()
  596.     ErrMsg = 'Unhandled exception:\n' + '\n'.join(ErrLines)
  597.     Result = 3
  598.  
  599.   if ErrMsg != '':
  600.     print >> sys.stderr, sys.argv[0] + ': ' + ErrMsg
  601.  
  602.   return Result
  603.  
  604.  
  605. #-------------------------------------------------------------------------------
  606. # Command line trigger
  607. #-------------------------------------------------------------------------------
  608.  
  609.  
  610. if __name__ == '__main__':
  611.   sys.exit(Main())
  612.  
  613.  
  614. #-------------------------------------------------------------------------------
  615. # End
  616. #-------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement