Fix parsing for OrCAD.
* Modify the way we parse parameters to allow more than one parameter in a single line as in the following example: %FSLAX55Y55*MOIN*% %IR0*IPPOS*OFA0.00000B0.00000*MIA0B0*SFA1.00000B1.00000*% (this is from OrCAD 16 default output) * Add missing deprecated parameters. * Change API to use given FileSettings on output. This allows us to use pcb-tools to convert between FS formats.
This commit is contained in:
parent
4bb2e5f8a0
commit
be5b94b8c0
2 changed files with 327 additions and 154 deletions
|
|
@ -23,13 +23,6 @@ Gerber (RS-274X) Statements
|
|||
from .utils import parse_gerber_value, write_gerber_value, decimal_string
|
||||
|
||||
|
||||
__all__ = ['FSParamStmt', 'MOParamStmt', 'IPParamStmt', 'OFParamStmt',
|
||||
'LPParamStmt', 'ADParamStmt', 'AMParamStmt', 'INParamStmt',
|
||||
'LNParamStmt', 'CoordStmt', 'ApertureStmt', 'CommentStmt',
|
||||
'EofStmt', 'QuadrantModeStmt', 'RegionModeStmt', 'UnknownStmt',
|
||||
'ParamStmt']
|
||||
|
||||
|
||||
class Statement(object):
|
||||
""" Gerber statement Base class
|
||||
|
||||
|
|
@ -128,17 +121,21 @@ class FSParamStmt(ParamStmt):
|
|||
self.notation = notation
|
||||
self.format = format
|
||||
|
||||
def to_gerber(self):
|
||||
zero_suppression = 'L' if self.zero_suppression == 'leading' else 'T'
|
||||
notation = 'A' if self.notation == 'absolute' else 'I'
|
||||
fmt = ''.join(map(str, self.format))
|
||||
return '%FS{0}{1}X{2}Y{3}*%'.format(zero_suppression, notation,
|
||||
fmt, fmt)
|
||||
def to_gerber(self, settings=None):
|
||||
if settings:
|
||||
zero_suppression = 'L' if settings.zero_suppression == 'leading' else 'T'
|
||||
notation = 'A' if settings.notation == 'absolute' else 'I'
|
||||
fmt = ''.join(map(str, settings.format))
|
||||
else:
|
||||
zero_suppression = 'L' if self.zero_suppression == 'leading' else 'T'
|
||||
notation = 'A' if self.notation == 'absolute' else 'I'
|
||||
fmt = ''.join(map(str, self.format))
|
||||
|
||||
return '%FS{0}{1}X{2}Y{3}*%'.format(zero_suppression, notation, fmt, fmt)
|
||||
|
||||
def __str__(self):
|
||||
return ('<Format Spec: %d:%d %s zero suppression %s notation>' %
|
||||
(self.format[0], self.format[1], self.zero_suppression,
|
||||
self.notation))
|
||||
(self.format[0], self.format[1], self.zero_suppression, self.notation))
|
||||
|
||||
|
||||
class MOParamStmt(ParamStmt):
|
||||
|
|
@ -176,7 +173,7 @@ class MOParamStmt(ParamStmt):
|
|||
ParamStmt.__init__(self, param)
|
||||
self.mode = mo
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
mode = 'MM' if self.mode == 'metric' else 'IN'
|
||||
return '%MO{0}*%'.format(mode)
|
||||
|
||||
|
|
@ -185,95 +182,6 @@ class MOParamStmt(ParamStmt):
|
|||
return ('<Mode: %s>' % mode_str)
|
||||
|
||||
|
||||
class IPParamStmt(ParamStmt):
|
||||
""" IP - Gerber Image Polarity Statement. (Deprecated)
|
||||
"""
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
param = stmt_dict.get('param')
|
||||
ip = 'positive' if stmt_dict.get('ip') == 'POS' else 'negative'
|
||||
return cls(param, ip)
|
||||
|
||||
def __init__(self, param, ip):
|
||||
""" Initialize IPParamStmt class
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param : string
|
||||
Parameter string.
|
||||
|
||||
ip : string
|
||||
Image polarity. May be either'positive' or 'negative'
|
||||
|
||||
Returns
|
||||
-------
|
||||
ParamStmt : IPParamStmt
|
||||
Initialized IPParamStmt class.
|
||||
|
||||
"""
|
||||
ParamStmt.__init__(self, param)
|
||||
self.ip = ip
|
||||
|
||||
def to_gerber(self):
|
||||
ip = 'POS' if self.ip == 'positive' else 'NEG'
|
||||
return '%IP{0}*%'.format(ip)
|
||||
|
||||
def __str__(self):
|
||||
return ('<Image Polarity: %s>' % self.ip)
|
||||
|
||||
|
||||
class OFParamStmt(ParamStmt):
|
||||
""" OF - Gerber Offset statement (Deprecated)
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
param = stmt_dict.get('param')
|
||||
a = float(stmt_dict.get('a', 0))
|
||||
b = float(stmt_dict.get('b', 0))
|
||||
return cls(param, a, b)
|
||||
|
||||
def __init__(self, param, a, b):
|
||||
""" Initialize OFParamStmt class
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param : string
|
||||
Parameter
|
||||
|
||||
a : float
|
||||
Offset along the output device A axis
|
||||
|
||||
b : float
|
||||
Offset along the output device B axis
|
||||
|
||||
Returns
|
||||
-------
|
||||
ParamStmt : OFParamStmt
|
||||
Initialized OFParamStmt class.
|
||||
|
||||
"""
|
||||
ParamStmt.__init__(self, param)
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
def to_gerber(self):
|
||||
ret = '%OF'
|
||||
if self.a is not None:
|
||||
ret += 'A' + decimal_string(self.a, precision=5)
|
||||
if self.b is not None:
|
||||
ret += 'B' + decimal_string(self.b, precision=5)
|
||||
return ret + '*%'
|
||||
|
||||
def __str__(self):
|
||||
offset_str = ''
|
||||
if self.a is not None:
|
||||
offset_str += ('X: %f' % self.a)
|
||||
if self.b is not None:
|
||||
offset_str += ('Y: %f' % self.b)
|
||||
return ('<Offset: %s>' % offset_str)
|
||||
|
||||
|
||||
class LPParamStmt(ParamStmt):
|
||||
""" LP - Gerber Level Polarity statement
|
||||
"""
|
||||
|
|
@ -304,7 +212,7 @@ class LPParamStmt(ParamStmt):
|
|||
ParamStmt.__init__(self, param)
|
||||
self.lp = lp
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
lp = 'C' if self.lp == 'clear' else 'D'
|
||||
return '%LP{0}*%'.format(lp)
|
||||
|
||||
|
|
@ -351,13 +259,15 @@ class ADParamStmt(ParamStmt):
|
|||
self.d = d
|
||||
self.shape = shape
|
||||
if modifiers is not None:
|
||||
self.modifiers = [[x for x in m.split("X")] for m in modifiers.split(",")]
|
||||
self.modifiers = [[x for x in m.split("X")] for m in modifiers.split(",") if len(m)]
|
||||
else:
|
||||
self.modifiers = []
|
||||
|
||||
def to_gerber(self):
|
||||
return '%ADD{0}{1},{2}*%'.format(self.d, self.shape,
|
||||
','.join(['X'.join(e) for e in self.modifiers]))
|
||||
def to_gerber(self, settings=None):
|
||||
if len(self.modifiers):
|
||||
return '%ADD{0}{1},{2}*%'.format(self.d, self.shape, ','.join(['X'.join(e) for e in self.modifiers]))
|
||||
else:
|
||||
return '%ADD{0}{1}*%'.format(self.d, self.shape)
|
||||
|
||||
def __str__(self):
|
||||
if self.shape == 'C':
|
||||
|
|
@ -404,15 +314,51 @@ class AMParamStmt(ParamStmt):
|
|||
self.name = name
|
||||
self.macro = macro
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
return '%AM{0}*{1}*%'.format(self.name, self.macro)
|
||||
|
||||
def __str__(self):
|
||||
return '<Aperture Macro %s: %s>' % (self.name, self.macro)
|
||||
|
||||
|
||||
class ASParamStmt(ParamStmt):
|
||||
""" AS - Axis Select. (Deprecated)
|
||||
"""
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
param = stmt_dict.get('param')
|
||||
mode = stmt_dict.get('mode')
|
||||
return cls(param, mode)
|
||||
|
||||
def __init__(self, param, ip):
|
||||
""" Initialize ASParamStmt class
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param : string
|
||||
Parameter string.
|
||||
|
||||
mode : string
|
||||
Axis select. May be either 'AXBY' or 'AYBX'
|
||||
|
||||
Returns
|
||||
-------
|
||||
ParamStmt : ASParamStmt
|
||||
Initialized ASParamStmt class.
|
||||
|
||||
"""
|
||||
ParamStmt.__init__(self, param)
|
||||
self.mode = mode
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
return '%AS{0}*%'.format(self.mode)
|
||||
|
||||
def __str__(self):
|
||||
return ('<Axis Select: %s>' % self.mode)
|
||||
|
||||
|
||||
class INParamStmt(ParamStmt):
|
||||
""" IN - Image Name Statement
|
||||
""" IN - Image Name Statement (Deprecated)
|
||||
"""
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
|
|
@ -438,13 +384,235 @@ class INParamStmt(ParamStmt):
|
|||
ParamStmt.__init__(self, param)
|
||||
self.name = name
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
return '%IN{0}*%'.format(self.name)
|
||||
|
||||
def __str__(self):
|
||||
return '<Image Name: %s>' % self.name
|
||||
|
||||
|
||||
class IPParamStmt(ParamStmt):
|
||||
""" IP - Gerber Image Polarity Statement. (Deprecated)
|
||||
"""
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
param = stmt_dict.get('param')
|
||||
ip = 'positive' if stmt_dict.get('ip') == 'POS' else 'negative'
|
||||
return cls(param, ip)
|
||||
|
||||
def __init__(self, param, ip):
|
||||
""" Initialize IPParamStmt class
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param : string
|
||||
Parameter string.
|
||||
|
||||
ip : string
|
||||
Image polarity. May be either'positive' or 'negative'
|
||||
|
||||
Returns
|
||||
-------
|
||||
ParamStmt : IPParamStmt
|
||||
Initialized IPParamStmt class.
|
||||
|
||||
"""
|
||||
ParamStmt.__init__(self, param)
|
||||
self.ip = ip
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
ip = 'POS' if self.ip == 'positive' else 'NEG'
|
||||
return '%IP{0}*%'.format(ip)
|
||||
|
||||
def __str__(self):
|
||||
return ('<Image Polarity: %s>' % self.ip)
|
||||
|
||||
|
||||
class IRParamStmt(ParamStmt):
|
||||
""" IR - Image Rotation Param (Deprecated)
|
||||
"""
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
return cls(**stmt_dict)
|
||||
|
||||
def __init__(self, param, angle):
|
||||
""" Initialize IRParamStmt class
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param : string
|
||||
Parameter code
|
||||
|
||||
angle : int
|
||||
Image angle
|
||||
|
||||
Returns
|
||||
-------
|
||||
ParamStmt : IRParamStmt
|
||||
Initialized IRParamStmt class.
|
||||
|
||||
"""
|
||||
ParamStmt.__init__(self, param)
|
||||
self.angle = angle
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
return '%IR{0}*%'.format(self.angle)
|
||||
|
||||
def __str__(self):
|
||||
return '<Image Angle: %s>' % self.angle
|
||||
|
||||
|
||||
class MIParamStmt(ParamStmt):
|
||||
""" MI - Image Mirror Param (Deprecated)
|
||||
"""
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
param = stmt_dict.get('param')
|
||||
a = int(stmt_dict.get('a', 0))
|
||||
b = int(stmt_dict.get('b', 0))
|
||||
return cls(param, a, b)
|
||||
|
||||
def __init__(self, param, a, b):
|
||||
""" Initialize MIParamStmt class
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param : string
|
||||
Parameter code
|
||||
|
||||
a : int
|
||||
Mirror for A output devices axis (0=disabled, 1=mirrored)
|
||||
|
||||
b : int
|
||||
Mirror for B output devices axis (0=disabled, 1=mirrored)
|
||||
|
||||
Returns
|
||||
-------
|
||||
ParamStmt : MIParamStmt
|
||||
Initialized MIParamStmt class.
|
||||
|
||||
"""
|
||||
ParamStmt.__init__(self, param)
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
ret = "%MI"
|
||||
if self.a is not None:
|
||||
ret += "A{0}".format(self.a)
|
||||
if self.b is not None:
|
||||
ret += "B{0}".format(self.b)
|
||||
|
||||
return ret
|
||||
|
||||
def __str__(self):
|
||||
return '<Image Mirror: A=%d B=%d>' % (self.a, self.b)
|
||||
|
||||
|
||||
class OFParamStmt(ParamStmt):
|
||||
""" OF - Gerber Offset statement (Deprecated)
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
param = stmt_dict.get('param')
|
||||
a = float(stmt_dict.get('a', 0))
|
||||
b = float(stmt_dict.get('b', 0))
|
||||
return cls(param, a, b)
|
||||
|
||||
def __init__(self, param, a, b):
|
||||
""" Initialize OFParamStmt class
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param : string
|
||||
Parameter
|
||||
|
||||
a : float
|
||||
Offset along the output device A axis
|
||||
|
||||
b : float
|
||||
Offset along the output device B axis
|
||||
|
||||
Returns
|
||||
-------
|
||||
ParamStmt : OFParamStmt
|
||||
Initialized OFParamStmt class.
|
||||
|
||||
"""
|
||||
ParamStmt.__init__(self, param)
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
ret = '%OF'
|
||||
if self.a is not None:
|
||||
ret += 'A' + decimal_string(self.a, precision=5)
|
||||
if self.b is not None:
|
||||
ret += 'B' + decimal_string(self.b, precision=5)
|
||||
return ret + '*%'
|
||||
|
||||
def __str__(self):
|
||||
offset_str = ''
|
||||
if self.a is not None:
|
||||
offset_str += ('X: %f' % self.a)
|
||||
if self.b is not None:
|
||||
offset_str += ('Y: %f' % self.b)
|
||||
return ('<Offset: %s>' % offset_str)
|
||||
|
||||
|
||||
class SFParamStmt(ParamStmt):
|
||||
""" SF - Scale Factor Param (Deprecated)
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict):
|
||||
param = stmt_dict.get('param')
|
||||
a = float(stmt_dict.get('a', 1))
|
||||
b = float(stmt_dict.get('b', 1))
|
||||
return cls(param, a, b)
|
||||
|
||||
def __init__(self, param, a, b):
|
||||
""" Initialize OFParamStmt class
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param : string
|
||||
Parameter
|
||||
|
||||
a : float
|
||||
Scale factor for the output device A axis
|
||||
|
||||
b : float
|
||||
Scale factor for the output device B axis
|
||||
|
||||
Returns
|
||||
-------
|
||||
ParamStmt : SFParamStmt
|
||||
Initialized SFParamStmt class.
|
||||
|
||||
"""
|
||||
ParamStmt.__init__(self, param)
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
ret = '%SF'
|
||||
if self.a is not None:
|
||||
ret += 'A' + decimal_string(self.a, precision=5)
|
||||
if self.b is not None:
|
||||
ret += 'B' + decimal_string(self.b, precision=5)
|
||||
return ret + '*%'
|
||||
|
||||
def __str__(self):
|
||||
scale_factor = ''
|
||||
if self.a is not None:
|
||||
scale_factor += ('X: %f' % self.a)
|
||||
if self.b is not None:
|
||||
scale_factor += ('Y: %f' % self.b)
|
||||
return ('<Scale Factor: %s>' % scale_factor)
|
||||
|
||||
|
||||
class LNParamStmt(ParamStmt):
|
||||
""" LN - Level Name Statement (Deprecated)
|
||||
"""
|
||||
|
|
@ -472,7 +640,7 @@ class LNParamStmt(ParamStmt):
|
|||
ParamStmt.__init__(self, param)
|
||||
self.name = name
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
return '%LN{0}*%'.format(self.name)
|
||||
|
||||
def __str__(self):
|
||||
|
|
@ -485,8 +653,6 @@ class CoordStmt(Statement):
|
|||
|
||||
@classmethod
|
||||
def from_dict(cls, stmt_dict, settings):
|
||||
zeros = settings.zero_suppression
|
||||
format = settings.format
|
||||
function = stmt_dict['function']
|
||||
x = stmt_dict.get('x')
|
||||
y = stmt_dict.get('y')
|
||||
|
|
@ -495,17 +661,13 @@ class CoordStmt(Statement):
|
|||
op = stmt_dict.get('op')
|
||||
|
||||
if x is not None:
|
||||
x = parse_gerber_value(stmt_dict.get('x'),
|
||||
format, zeros)
|
||||
x = parse_gerber_value(stmt_dict.get('x'), settings.format, settings.zero_suppression)
|
||||
if y is not None:
|
||||
y = parse_gerber_value(stmt_dict.get('y'),
|
||||
format, zeros)
|
||||
y = parse_gerber_value(stmt_dict.get('y'), settings.format, settings.zero_suppression)
|
||||
if i is not None:
|
||||
i = parse_gerber_value(stmt_dict.get('i'),
|
||||
format, zeros)
|
||||
i = parse_gerber_value(stmt_dict.get('i'), settings.format, settings.zero_suppression)
|
||||
if j is not None:
|
||||
j = parse_gerber_value(stmt_dict.get('j'),
|
||||
format, zeros)
|
||||
j = parse_gerber_value(stmt_dict.get('j'), settings.format, settings.zero_suppression)
|
||||
return cls(function, x, y, i, j, op, settings)
|
||||
|
||||
def __init__(self, function, x, y, i, j, op, settings):
|
||||
|
|
@ -541,8 +703,6 @@ class CoordStmt(Statement):
|
|||
|
||||
"""
|
||||
Statement.__init__(self, "COORD")
|
||||
self.zero_suppression = settings.zero_suppression
|
||||
self.format = settings.format
|
||||
self.function = function
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
|
@ -550,18 +710,18 @@ class CoordStmt(Statement):
|
|||
self.j = j
|
||||
self.op = op
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
ret = ''
|
||||
if self.function:
|
||||
ret += self.function
|
||||
if self.x is not None:
|
||||
ret += 'X{0}'.format(write_gerber_value(self.x, self.format, self.zero_suppression))
|
||||
ret += 'X{0}'.format(write_gerber_value(self.x, settings.format, settings.zero_suppression))
|
||||
if self.y is not None:
|
||||
ret += 'Y{0}'.format(write_gerber_value(self.y, self.format, self.zero_suppression))
|
||||
ret += 'Y{0}'.format(write_gerber_value(self.y, settings.format, settings.zero_suppression))
|
||||
if self.i is not None:
|
||||
ret += 'I{0}'.format(write_gerber_value(self.i, self.format, self.zero_suppression))
|
||||
ret += 'I{0}'.format(write_gerber_value(self.i, settings.format, settings.zero_suppression))
|
||||
if self.j is not None:
|
||||
ret += 'J{0}'.format(write_gerber_value(self.j, self.format, self.zero_suppression))
|
||||
ret += 'J{0}'.format(write_gerber_value(self.j, settings.format, settings.zero_suppression))
|
||||
if self.op:
|
||||
ret += self.op
|
||||
return ret + '*'
|
||||
|
|
@ -600,7 +760,7 @@ class ApertureStmt(Statement):
|
|||
self.d = int(d)
|
||||
self.deprecated = True if deprecated is not None else False
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
if self.deprecated:
|
||||
return 'G54D{0}*'.format(self.d)
|
||||
else:
|
||||
|
|
@ -618,7 +778,7 @@ class CommentStmt(Statement):
|
|||
Statement.__init__(self, "COMMENT")
|
||||
self.comment = comment
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
return 'G04{0}*'.format(self.comment)
|
||||
|
||||
def __str__(self):
|
||||
|
|
@ -631,7 +791,7 @@ class EofStmt(Statement):
|
|||
def __init__(self):
|
||||
Statement.__init__(self, "EOF")
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
return 'M02*'
|
||||
|
||||
def __str__(self):
|
||||
|
|
@ -656,7 +816,7 @@ class QuadrantModeStmt(Statement):
|
|||
or "multi-quadrant"')
|
||||
self.mode = mode
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
return 'G74*' if self.mode == 'single-quadrant' else 'G75*'
|
||||
|
||||
|
||||
|
|
@ -675,7 +835,7 @@ class RegionModeStmt(Statement):
|
|||
raise ValueError('Valid modes are "on" or "off"')
|
||||
self.mode = mode
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
return 'G36*' if self.mode == 'on' else 'G37*'
|
||||
|
||||
|
||||
|
|
@ -686,5 +846,5 @@ class UnknownStmt(Statement):
|
|||
Statement.__init__(self, "UNKNOWN")
|
||||
self.line = line
|
||||
|
||||
def to_gerber(self):
|
||||
def to_gerber(self, settings=None):
|
||||
return self.line
|
||||
|
|
|
|||
|
|
@ -104,12 +104,13 @@ class GerberFile(CamFile):
|
|||
return (xbounds, ybounds)
|
||||
|
||||
|
||||
def write(self, filename):
|
||||
def write(self, filename, settings=None):
|
||||
""" Write data out to a gerber file
|
||||
"""
|
||||
with open(filename, 'w') as f:
|
||||
for statement in self.statements:
|
||||
f.write(statement.to_gerber() + "\n")
|
||||
f.write(statement.to_gerber(settings or self.settings))
|
||||
f.write("\n")
|
||||
|
||||
|
||||
class GerberParser(object):
|
||||
|
|
@ -125,7 +126,6 @@ class GerberParser(object):
|
|||
|
||||
FS = r"(?P<param>FS)(?P<zero>(L|T))?(?P<notation>(A|I))X(?P<x>[0-7][0-7])Y(?P<y>[0-7][0-7])"
|
||||
MO = r"(?P<param>MO)(?P<mo>(MM|IN))"
|
||||
IP = r"(?P<param>IP)(?P<ip>(POS|NEG))"
|
||||
LP = r"(?P<param>LP)(?P<lp>(D|C))"
|
||||
AD_CIRCLE = r"(?P<param>AD)D(?P<d>\d+)(?P<shape>C)[,]?(?P<modifiers>[^,]*)?"
|
||||
AD_RECT = r"(?P<param>AD)D(?P<d>\d+)(?P<shape>R)[,](?P<modifiers>[^,]*)"
|
||||
|
|
@ -135,13 +135,18 @@ class GerberParser(object):
|
|||
AM = r"(?P<param>AM)(?P<name>{name})\*(?P<macro>.*)".format(name=NAME)
|
||||
|
||||
# begin deprecated
|
||||
OF = r"(?P<param>OF)(A(?P<a>{decimal}))?(B(?P<b>{decimal}))?".format(decimal=DECIMAL)
|
||||
AS = r"(?P<param>AS)(?P<mode>(AXBY)|(AYBX))"
|
||||
IN = r"(?P<param>IN)(?P<name>.*)"
|
||||
IP = r"(?P<param>IP)(?P<ip>(POS|NEG))"
|
||||
IR = r"(?P<param>IR)(?P<angle>{number})".format(number=NUMBER)
|
||||
MI = r"(?P<param>MI)(A(?P<a>0|1))?(B(?P<b>0|1))?"
|
||||
OF = r"(?P<param>OF)(A(?P<a>{decimal}))?(B(?P<b>{decimal}))?".format(decimal=DECIMAL)
|
||||
SF = r"(?P<param>SF)(?P<discarded>.*)"
|
||||
LN = r"(?P<param>LN)(?P<name>.*)"
|
||||
# end deprecated
|
||||
|
||||
PARAMS = (FS, MO, IP, LP, AD_CIRCLE, AD_RECT, AD_OBROUND, AD_POLY, AD_MACRO, AM, OF, IN, LN)
|
||||
PARAM_STMT = [re.compile(r"%{0}\*%".format(p)) for p in PARAMS]
|
||||
PARAMS = (FS, MO, LP, AD_CIRCLE, AD_RECT, AD_OBROUND, AD_POLY, AD_MACRO, AM, AS, IN, IP, IR, MI, OF, SF, LN)
|
||||
PARAM_STMT = [re.compile(r"%?{0}\*%?".format(p)) for p in PARAMS]
|
||||
|
||||
COORD_STMT = re.compile((
|
||||
r"(?P<function>{function})?"
|
||||
|
|
@ -149,7 +154,7 @@ class GerberParser(object):
|
|||
r"(I(?P<i>{number}))?(J(?P<j>{number}))?"
|
||||
r"(?P<op>{op})?\*".format(number=NUMBER, function=FUNCTION, op=COORD_OP)))
|
||||
|
||||
APERTURE_STMT = re.compile(r"(?P<deprecated>G54)?D(?P<d>\d+)\*")
|
||||
APERTURE_STMT = re.compile(r"(?P<deprecated>(G54)|G55)?D(?P<d>\d+)\*")
|
||||
|
||||
COMMENT_STMT = re.compile(r"G04(?P<comment>[^*]*)(\*)?")
|
||||
|
||||
|
|
@ -270,8 +275,6 @@ class GerberParser(object):
|
|||
stmt = MOParamStmt.from_dict(param)
|
||||
self.settings.units = stmt.mode
|
||||
yield stmt
|
||||
elif param["param"] == "IP":
|
||||
yield IPParamStmt.from_dict(param)
|
||||
elif param["param"] == "LP":
|
||||
yield LPParamStmt.from_dict(param)
|
||||
elif param["param"] == "AD":
|
||||
|
|
@ -284,8 +287,26 @@ class GerberParser(object):
|
|||
yield INParamStmt.from_dict(param)
|
||||
elif param["param"] == "LN":
|
||||
yield LNParamStmt.from_dict(param)
|
||||
# deprecated commands AS, IN, IP, IR, MI, OF, SF, LN
|
||||
elif param["param"] == "AS":
|
||||
yield ASParamStmt.from_dict(param)
|
||||
elif param["param"] == "IN":
|
||||
yield INParamStmt.from_dict(param)
|
||||
elif param["param"] == "IP":
|
||||
yield IPParamStmt.from_dict(param)
|
||||
elif param["param"] == "IR":
|
||||
yield IRParamStmt.from_dict(param)
|
||||
elif param["param"] == "MI":
|
||||
yield MIParamStmt.from_dict(param)
|
||||
elif param["param"] == "OF":
|
||||
yield OFParamStmt.from_dict(param)
|
||||
elif param["param"] == "SF":
|
||||
yield SFParamStmt.from_dict(param)
|
||||
elif param["param"] == "LN":
|
||||
yield LNParamStmt.from_dict(param)
|
||||
else:
|
||||
yield UnknownStmt(line)
|
||||
|
||||
did_something = True
|
||||
line = r
|
||||
continue
|
||||
|
|
@ -298,14 +319,6 @@ class GerberParser(object):
|
|||
line = r
|
||||
continue
|
||||
|
||||
if False:
|
||||
print self.COORD_STMT.pattern
|
||||
print self.APERTURE_STMT.pattern
|
||||
print self.COMMENT_STMT.pattern
|
||||
print self.EOF_STMT.pattern
|
||||
for i in self.PARAM_STMT:
|
||||
print i.pattern
|
||||
|
||||
if line.find('*') > 0:
|
||||
yield UnknownStmt(line)
|
||||
did_something = True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue