bbhack.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # usage:
  2. # bbhack.py -i [breadboard input file] -o [breadboard output file]
  3. # loads the breadboard input file, simplifies the connectors, and saves it to the breadboard output file
  4. import getopt, sys, os, os.path, re, xml.dom.minidom, xml.dom
  5. def usage():
  6. print """
  7. usage:
  8. bbhack.py -i [breadboard input file] -o [breadboard output file]
  9. loads the breadboard input file, simplifies the connectors, and saves it to the breadboard output file.
  10. """
  11. def main():
  12. try:
  13. opts, args = getopt.getopt(sys.argv[1:], "hi:o:", ["help", "input", "output"])
  14. except getopt.GetoptError, err:
  15. # print help information and exit:
  16. print str(err) # will print something like "option -a not recognized"
  17. usage()
  18. sys.exit(2)
  19. input = None
  20. output = None
  21. for o, a in opts:
  22. #print o
  23. #print a
  24. if o in ("-i", "--input"):
  25. input = a
  26. elif o in ("-o", "--output"):
  27. output = a
  28. elif o in ("-h", "--help"):
  29. usage()
  30. sys.exit(2)
  31. else:
  32. assert False, "unhandled option"
  33. if(not(input)):
  34. usage()
  35. sys.exit(2)
  36. if(not(output)):
  37. usage()
  38. sys.exit(2)
  39. dom = xml.dom.minidom.parse(input)
  40. root = dom.documentElement
  41. gNodes = root.getElementsByTagName("g")
  42. socketsNode = None
  43. for g in gNodes:
  44. if g.getAttribute("id") == "sockets":
  45. socketsNode = g
  46. break
  47. if not socketsNode:
  48. print "no sockets node found"
  49. sys.exit(0)
  50. rects = []
  51. for r in root.childNodes:
  52. if r.nodeType != g.ELEMENT_NODE:
  53. continue
  54. if r.tagName != "rect":
  55. continue
  56. id = r.getAttribute("id")
  57. if not id:
  58. continue
  59. if id.find("pin") >= 0:
  60. rects.append(r)
  61. for r in rects:
  62. root.removeChild(r)
  63. r.unlink()
  64. for g in socketsNode.childNodes:
  65. if g.nodeType != g.ELEMENT_NODE:
  66. continue
  67. if g.tagName != "g":
  68. continue
  69. p1 = None
  70. p2 = None
  71. c1 = None
  72. for c in g.childNodes:
  73. if c.nodeType != c.ELEMENT_NODE:
  74. continue
  75. if c.tagName == "circle":
  76. c1 = c
  77. elif c.tagName == "path":
  78. if not p1:
  79. p1 = c
  80. else:
  81. p2 = c
  82. if not c1:
  83. continue
  84. if not p1:
  85. q = g.nextSibling
  86. while q:
  87. if q.nodeType == c.ELEMENT_NODE:
  88. if q.tagName == "path":
  89. if not p1:
  90. p1 = q
  91. else:
  92. p2 = q
  93. break
  94. elif q.tagName == "g":
  95. break
  96. q = q.nextSibling
  97. if not p1:
  98. continue
  99. if not p2:
  100. continue
  101. id = g.getAttribute("id")
  102. if id:
  103. if id.find("xpin") >= 0:
  104. g.setAttribute("id", id.replace("xpin", "pin"))
  105. elif id.find("pinx") >= 0:
  106. g.setAttribute("id", id.replace("pinx", "pin"))
  107. print g.getAttribute("id")
  108. p1.parentNode.removeChild(p1)
  109. p2.parentNode.removeChild(p2)
  110. c1.parentNode.removeChild(c1)
  111. np1 = dom.createElement("path")
  112. g.appendChild(np1)
  113. np1.setAttribute("fill", p1.getAttribute("fill"))
  114. r = float(c1.getAttribute("r"))
  115. cx = float(c1.getAttribute("cx"))
  116. cy = float(c1.getAttribute("cy"))
  117. np1.setAttribute("d", ''.join(["M", `cx - r - r`, ",", `cy`, " a",`r * 2`, ",", `r * 2`, " ", `0`, " ", `0`, " ", `1`, " ", `r * 4`, ",", `0`]))
  118. np2 = dom.createElement("path")
  119. g.appendChild(np2)
  120. np2.setAttribute("fill", p2.getAttribute("fill"))
  121. np2.setAttribute("d", ''.join(["M", `cx + r + r`, ",", `cy`, " a",`r * 2`, ",", `r * 2`, " ", `0`, " ", `1`, " ", `1`, " ", `-r * 4`, ",", `0`]))
  122. g.appendChild(c1)
  123. p1.unlink()
  124. p2.unlink()
  125. outfile = open(output, 'wb')
  126. s = dom.toxml("UTF-8")
  127. s = re.sub('\s*\n\s*\n', '', s) # ghosts of removed (and unlinked) nodes seem to generate newlines, so tighten up the xml
  128. outfile.write(s)
  129. outfile.flush()
  130. outfile.close()
  131. if __name__ == "__main__":
  132. main()