/ CPX_DAC_Guide / python / svgtopy.py
svgtopy.py
  1  # SPDX-FileCopyrightText: 2019 Kevin J. Walters for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  #!/usr/bin/python3
  6  
  7  ### svgtopy v1.0
  8  """Print vectors from an SVG input file in python list format
  9  for easy pasting into a program.
 10  
 11  This is Python code not intended for running on a microcontroller board.
 12  """
 13  
 14  ### MIT License
 15  
 16  ### Copyright (c) 2019 Kevin J. Walters
 17  
 18  ### Permission is hereby granted, free of charge, to any person obtaining a copy
 19  ### of this software and associated documentation files (the "Software"), to deal
 20  ### in the Software without restriction, including without limitation the rights
 21  ### to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 22  ### copies of the Software, and to permit persons to whom the Software is
 23  ### furnished to do so, subject to the following conditions:
 24  
 25  ### The above copyright notice and this permission notice shall be included in all
 26  ### copies or substantial portions of the Software.
 27  
 28  ### THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 29  ### IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 30  ### FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 31  ### AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 32  ### LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 33  ### OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 34  ### SOFTWARE.
 35  
 36  
 37  ### it only understands M and L in SVG
 38  
 39  ### Worth looking at SVG libraries to see if they
 40  ### can parse/transform SVG data
 41  
 42  import getopt
 43  import sys
 44  import re
 45  ##import fileinput
 46  import xml.etree.ElementTree as ET
 47  
 48  ### globals
 49  ### pylint: disable=invalid-name
 50  debug = 0
 51  verbose = False
 52  
 53  
 54  def usage(exit_code):  ### pylint: disable=missing-docstring
 55      print("""Usage: svgtopy [-d] [-h] [-v] [--help]
 56  Convert an svg file from from standard input to comma-separated tuples
 57  on standard output for inclusion as a list in a python program.""",
 58            file=sys.stderr)
 59      if exit_code is not None:
 60          sys.exit(exit_code)
 61  
 62  
 63  def search_path_d(svgdata, point_groups):
 64      """Look for M and L in the SVG d attribute of a path node"""
 65  
 66      points = []
 67      for match in re.finditer(r"([A-Za-z])([\d\.]+)\s+([\d\.]+)\s*", svgdata):
 68          if match:
 69              cmd = match.group(1)
 70              if cmd == "M":  ### Start of a new part
 71                  mx, my = match.group(2, 3)
 72                  if points:
 73                      point_groups.append(points)
 74                      points = []
 75                  points.append((float(mx), float(my)))
 76                  if debug:
 77                      print("M pos", mx, my)
 78  
 79              elif cmd == "L":  ### Continuation of current part
 80                  lx, ly = match.group(2, 3)
 81                  points.append((float(lx), float(ly)))
 82                  if debug:
 83                      print("L pos", lx, ly)
 84  
 85              else:
 86                  print("SVG cmd not implemented:", cmd,
 87                        file=sys.stderr)
 88          else:
 89              print("some parsing issue",
 90                    file=sys.stderr)
 91  
 92      # Add the last part to point_groups
 93      if points:
 94          point_groups.append(points)
 95          points = []
 96  
 97  
 98  def main(cmdlineargs):
 99      """main(args)"""
100      global debug, verbose  ### pylint: disable=global-statement
101  
102      try:
103          opts, _ = getopt.getopt(cmdlineargs,
104                                  "dhv", ["help"])
105      except getopt.GetoptError as err:
106          print(err,
107                file=sys.stderr)
108          usage(2)
109      for opt, _ in opts:
110          if opt == "-d":
111              debug = True
112          elif opt == "-v":
113              verbose = True
114          elif opt in ("-h", "--help"):
115              usage(0)
116          else:
117              print("Internal error: unhandled option",
118                    file=sys.stderr)
119              sys.exit(3)
120  
121      xml_ns = {"svg": "http://www.w3.org/2000/svg"}
122      tree = ET.parse(sys.stdin)
123      point_groups = []
124      for path in tree.findall("svg:path", xml_ns):
125          svgdata = path.attrib["d"]
126          if verbose:
127              print("Processing path with {0:d} length".format(len(svgdata)))
128          search_path_d(svgdata, point_groups)
129  
130  
131  
132      for idx, points in enumerate(point_groups):
133          print("# Group", idx + 1)
134          for point in points:
135              print("     ", point, ",", sep="")
136  
137  if __name__ == "__main__":
138      main(sys.argv[1:])