summaryrefslogtreecommitdiff
path: root/gerber/excellon_tool.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerber/excellon_tool.py')
-rw-r--r--gerber/excellon_tool.py70
1 files changed, 37 insertions, 33 deletions
diff --git a/gerber/excellon_tool.py b/gerber/excellon_tool.py
index bd76e54..a9ac450 100644
--- a/gerber/excellon_tool.py
+++ b/gerber/excellon_tool.py
@@ -28,9 +28,9 @@ try:
from cStringIO import StringIO
except(ImportError):
from io import StringIO
-
+
from .excellon_statements import ExcellonTool
-
+
def loads(data, settings=None):
""" Read tool file information and return a map of tools
Parameters
@@ -52,13 +52,13 @@ class ExcellonToolDefinitionParser(object):
----------
None
"""
-
+
allegro_tool = re.compile(r'(?P<size>[0-9/.]+)\s+(?P<plated>P|N)\s+T(?P<toolid>[0-9]{2})\s+(?P<xtol>[0-9/.]+)\s+(?P<ytol>[0-9/.]+)')
allegro_comment_mils = re.compile('Holesize (?P<toolid>[0-9]{1,2})\. = (?P<size>[0-9/.]+) Tolerance = \+(?P<xtol>[0-9/.]+)/-(?P<ytol>[0-9/.]+) (?P<plated>(PLATED)|(NON_PLATED)|(OPTIONAL)) MILS Quantity = [0-9]+')
allegro2_comment_mils = re.compile('T(?P<toolid>[0-9]{1,2}) Holesize (?P<toolid2>[0-9]{1,2})\. = (?P<size>[0-9/.]+) Tolerance = \+(?P<xtol>[0-9/.]+)/-(?P<ytol>[0-9/.]+) (?P<plated>(PLATED)|(NON_PLATED)|(OPTIONAL)) MILS Quantity = [0-9]+')
allegro_comment_mm = re.compile('Holesize (?P<toolid>[0-9]{1,2})\. = (?P<size>[0-9/.]+) Tolerance = \+(?P<xtol>[0-9/.]+)/-(?P<ytol>[0-9/.]+) (?P<plated>(PLATED)|(NON_PLATED)|(OPTIONAL)) MM Quantity = [0-9]+')
allegro2_comment_mm = re.compile('T(?P<toolid>[0-9]{1,2}) Holesize (?P<toolid2>[0-9]{1,2})\. = (?P<size>[0-9/.]+) Tolerance = \+(?P<xtol>[0-9/.]+)/-(?P<ytol>[0-9/.]+) (?P<plated>(PLATED)|(NON_PLATED)|(OPTIONAL)) MM Quantity = [0-9]+')
-
+
matchers = [
(allegro_tool, 'mils'),
(allegro_comment_mils, 'mils'),
@@ -66,34 +66,34 @@ class ExcellonToolDefinitionParser(object):
(allegro_comment_mm, 'mm'),
(allegro2_comment_mm, 'mm'),
]
-
+
def __init__(self, settings=None):
self.tools = {}
self.settings = settings
-
+
def parse_raw(self, data):
for line in StringIO(data):
self._parse(line.strip())
-
+
return self.tools
-
+
def _parse(self, line):
-
+
for matcher in ExcellonToolDefinitionParser.matchers:
m = matcher[0].match(line)
if m:
unit = matcher[1]
-
+
size = float(m.group('size'))
platedstr = m.group('plated')
toolid = int(m.group('toolid'))
xtol = float(m.group('xtol'))
ytol = float(m.group('ytol'))
-
+
size = self._convert_length(size, unit)
xtol = self._convert_length(xtol, unit)
ytol = self._convert_length(ytol, unit)
-
+
if platedstr == 'PLATED':
plated = ExcellonTool.PLATED_YES
elif platedstr == 'NON_PLATED':
@@ -102,19 +102,20 @@ class ExcellonToolDefinitionParser(object):
plated = ExcellonTool.PLATED_OPTIONAL
else:
plated = ExcellonTool.PLATED_UNKNOWN
-
- tool = ExcellonTool(None, number=toolid, diameter=size, plated=plated)
-
+
+ tool = ExcellonTool(None, number=toolid, diameter=size,
+ plated=plated)
+
self.tools[tool.number] = tool
-
+
break
-
+
def _convert_length(self, value, unit):
-
+
# Convert the value to mm
if unit == 'mils':
value /= 39.3700787402
-
+
# Now convert to the settings unit
if self.settings.units == 'inch':
return value / 25.4
@@ -137,34 +138,35 @@ def loads_rep(data, settings=None):
return ExcellonReportParser(settings).parse_raw(data)
class ExcellonReportParser(object):
-
+
# We sometimes get files with different encoding, so we can't actually
# match the text - the best we can do it detect the table header
header = re.compile(r'====\s+====\s+====\s+====\s+=====\s+===')
-
+
def __init__(self, settings=None):
self.tools = {}
self.settings = settings
-
+
self.found_header = False
-
+
def parse_raw(self, data):
for line in StringIO(data):
self._parse(line.strip())
-
+
return self.tools
-
+
def _parse(self, line):
-
+
# skip empty lines and "comments"
if not line.strip():
return
-
+
if not self.found_header:
- # Try to find the heaader, since we need that to be sure we understand the contents correctly.
+ # Try to find the heaader, since we need that to be sure we
+ # understand the contents correctly.
if ExcellonReportParser.header.match(line):
self.found_header = True
-
+
elif line[0] != '=':
# Already found the header, so we know to to map the contents
parts = line.split()
@@ -180,7 +182,9 @@ class ExcellonReportParser(object):
feedrate = int(parts[3])
speed = int(parts[4])
qty = int(parts[5])
-
- tool = ExcellonTool(None, number=toolid, diameter=size, plated=plated, feed_rate=feedrate, rpm=speed)
-
- self.tools[tool.number] = tool \ No newline at end of file
+
+ tool = ExcellonTool(None, number=toolid, diameter=size,
+ plated=plated, feed_rate=feedrate,
+ rpm=speed)
+
+ self.tools[tool.number] = tool