|     25         return parse_ldraw_contour(line) | 
    26         return parse_ldraw_contour(line) | 
|     26     else: | 
    27     else: | 
|     27         raise BadLdrawLine('unknown line type') | 
    28         raise BadLdrawLine('unknown line type') | 
|     28  | 
    29  | 
|     29 def parse_ldraw_subfile_reference(line): | 
    30 def parse_ldraw_subfile_reference(line): | 
|     30     pattern = r'^1\s+(\d+)' + r'\s+([^ ]+)' * (3 + 9 + 1) + r'\s*$' | 
    31     pattern = r'^1\s+([^ ]+)' + r'\s+([^ ]+)' * (3 + 9 + 1) + r'\s*$' | 
|     31     match = re.search(pattern, line) | 
    32     match = re.search(pattern, line) | 
|     32     if not match: | 
    33     if not match: | 
|     33         raise BadLdrawLine('unable to parse') | 
    34         raise BadLdrawLine('unable to parse') | 
|     34     groups = list(match.groups()) | 
    35     groups = list(match.groups()) | 
|     35     indices = { | 
    36     indices = { | 
|     36         'color': 0, | 
    37         'color_index': 0, | 
|     37         'anchor': slice(1, 4), | 
    38         'anchor': slice(1, 4), | 
|     38         'matrix': slice(4, 13), | 
    39         'matrix': slice(4, 13), | 
|     39         'subfile_path': 13 | 
    40         'subfile_path': 13 | 
|     40     } | 
    41     } | 
|     41     try: | 
    42     try: | 
|     42         color = int(groups[indices['color']]) | 
    43         color = Color(groups[indices['color_index']]) | 
|     43         vertex_values = [float(x) for x in groups[indices['anchor']]] | 
    44         vertex_values = [float(x) for x in groups[indices['anchor']]] | 
|     44         matrix_values = [float(x) for x in groups[indices['matrix']]] | 
    45         matrix_values = [float(x) for x in groups[indices['matrix']]] | 
|     45     except ValueError: | 
    46     except ValueError: | 
|     46         raise BadLdrawLine('bad numeric values') | 
    47         raise BadLdrawLine('bad numeric values') | 
|     47     return linetypes.SubfileReference( | 
    48     return linetypes.SubfileReference( | 
|     52     ) | 
    53     ) | 
|     53  | 
    54  | 
|     54 def generic_parse_polygon(line, *, type_code, vertex_count): | 
    55 def generic_parse_polygon(line, *, type_code, vertex_count): | 
|     55     pattern = r'^' \ | 
    56     pattern = r'^' \ | 
|     56         + str(type_code) \ | 
    57         + str(type_code) \ | 
|     57         + '\s+(\d+)' \ | 
    58         + '\s+([^ ]+)' \ | 
|     58         + r'\s+([^ ]+)' * (vertex_count * 3) \ | 
    59         + r'\s+([^ ]+)' * (vertex_count * 3) \ | 
|     59         + r'\s*$' | 
    60         + r'\s*$' | 
|     60     match = re.search(pattern, line) | 
    61     match = re.search(pattern, line) | 
|     61     if not match: | 
    62     if not match: | 
|     62         raise BadLdrawLine(str.format('cannot parse type-{} line', type_code)) | 
    63         raise BadLdrawLine(str.format('cannot parse type-{} line', type_code)) | 
|     70             coordinates = [float(x) for x in coordinates] | 
    71             coordinates = [float(x) for x in coordinates] | 
|     71         except ValueError: | 
    72         except ValueError: | 
|     72             raise BadLdrawLine('bad numeric values') | 
    73             raise BadLdrawLine('bad numeric values') | 
|     73         vertices.append(Vertex(*coordinates)) | 
    74         vertices.append(Vertex(*coordinates)) | 
|     74     return { | 
    75     return { | 
|     75         'color': int(match.group(1)), | 
    76         'color': Color(match.group(1)), | 
|     76         'vertices': vertices, | 
    77         'vertices': vertices, | 
|     77     } | 
    78     } | 
|     78  | 
    79  | 
|     79 def parse_ldraw_line(line): | 
    80 def parse_ldraw_line(line): | 
|     80     parse_result = generic_parse_polygon(line, type_code = 2, vertex_count = 2) | 
    81     parse_result = generic_parse_polygon(line, type_code = 2, vertex_count = 2) |