def absolute_to_relative_path(path):
    # TODO: add support all commands
    # TODO: optimise 'switch' logic

    # check to see if path is empty or doesn't exist
    if (path == None) or (path == ''):
        return

    # get SVG path grammar
    look_for = svg_grammar()

    # parse the input based on this grammar
    pd = look_for.parseString(path)

    p = ''

    # This variable stores the absolute coordinates as the path is converted;
    abspos = Point()

    patho = Point()

    for i in range(0, len(pd)):

        # 'move to' command
        if re.match('M', pd[i][0], re.I):

            # TODO: write this code more concisely
            
            coord = Point(pd[i][1][0], pd[i][1][1])
            p += 'm '

            # if this is the start of the path, the first M/m coordinate is
            # always absolute
            if i == 0:
                abspos.assign(coord.x, coord.y)
                p += str(abspos.x) + ',' + str(abspos.y) + ' '
                patho.assign(coord.x, coord.y)
            else:
                if pd[i][0] == 'm':
                    p += str(coord.x) + ',' + str(coord.y) + ' '
                    abspos += coord
                    patho = abspos
                    
                else:
                    p += str(coord.x - abspos.x) + ',' + str(coord.y - abspos.y) + ' '
                    abspos.assign(coord.x, coord.y)
                    patho.assign(coord.x, coord.y)
            
            # do the rest of the coordinates
            for coord_tmp in pd[i][2:]:
                coord.assign(coord_tmp[0], coord_tmp[1])
                if pd[i][0] == 'm':
                    p += str(coord.x) + ',' + str(coord.y) + ' '
                    abspos += coord 
                else:
                    p += str(coord.x - abspos.x) + ',' + str(coord.y - abspos.y) + ' '
                    abspos.assign(coord.x, coord.y)

        
        # cubic Bezier (PCCP) curve command 
        elif re.match('C', pd[i][0], re.I):
            p += pd[i][0].lower()+' '
            
            if pd[i][0] == 'c':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x) + ',' + str(coord.y) +' '
                # for keeping track of the absolute position, we need to add up every
                # *third* coordinate of the cubic Bezier curve
                for coord_tmp in pd[i][3::3]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    abspos += coord 

            if pd[i][0] == 'C':
                for n in range(1, len(pd[i])-1, 3):
                    for m in range(0, 3):
                        coord.assign(pd[i][n+m][0], pd[i][n+m][1]) 
                        p += str(coord.x - abspos.x) + ',' + str(coord.y - abspos.y)+' '
                    abspos.assign(coord.x, coord.y)


        # quadratic Bezier (PCP) curve command 
        elif re.match('Q', pd[i][0], re.I):
            p += pd[i][0].lower() + ' '
            
            if pd[i][0] == 'q':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x) + ',' + str(coord.y) +' '
                # for keeping track of the absolute position, we need to add up every
                # *third* coordinate of the cubic Bezier curve
                for coord_tmp in pd[i][2::2]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    abspos += coord 

            if pd[i][0] == 'Q':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x - abspos.x) + ',' + str(coord.y - abspos.y) + ' '
                abspos.assign(coord.x, coord.y)


        # simple cubic Bezier curve command 
        elif re.match('T', pd[i][0], re.I):
            p += pd[i][0].lower()+' '
            
            if pd[i][0] == 't':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x) + ',' + str(coord.y) + ' '
                # for keeping track of the absolute position, we need to add up every
                # *third* coordinate of the cubic Bezier curve
                #for coord in pd[i][2::2]:
                    abspos += coord 

            if pd[i][0] == 'T':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(float(coord[0]) - abspos['x']) + ',' + str(float(coord[1]) - abspos['y']) + ' '
                abspos.assign(coord.x, coord.y)

        elif re.match('S', pd[i][0], re.I):
            p += pd[i][0].lower()+' '
            
            if pd[i][0] == 's':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x)+','+str(coord.y)+' '
                    abspos += coord 

            if pd[i][0] == 'S':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x - abspos.x) + ',' + str(coord.y - abspos.y) + ' '
                abspos.assign(coord.x, coord.y)


        # 'line to'  command
        elif re.match('L', pd[i][0], re.I):
            p += pd[i][0].lower()+' '
            
            if pd[i][0] == 'l':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x) + ',' + str(coord.y) + ' '
                    abspos += coord 

            if pd[i][0] == 'L':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x - abspos.x) + ',' + str(coord.y - abspos.y) + ' '
                    abspos.assign(coord.x, coord.y)


        # 'horizontal line' command
        elif re.match('H', pd[i][0], re.I):
            p += pd[i][0].lower()+' '
            
            if pd[i][0] == 'h':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], 0)
                    p += str(coord.x) + ' '
                abspos.x += coord.x

            if pd[i][0] == 'H':
                for coord_tmp in pd[i][1:]:
                    coord.assign(coord_tmp[0], coord_tmp[1])
                    p += str(coord.x - abspos.x) + ' '
                    abspos.x = coord.x

        # 'vertical line' command
        elif re.match('V', pd[i][0], re.I):
            p += pd[i][0].lower() + ' '
            
            if pd[i][0] == 'v':
                for coord_tmp in pd[i][1:]:
                    coord.assign(0, coord_tmp[0])
                    p += str(coord.y) + ' '
                    abspos.y += coord.y

            if pd[i][0] == 'V':
                for coord_tmp in pd[i][1:]:
                    coord.assign(0, coord_tmp[0])
                    p += str(coord.y - abspos.y) + ' '
                    abspos.y = coord.y

        # 'close shape' command
        elif re.match('Z', pd[i][0], re.I):
            p += pd[i][0].lower() + ' '
            abspos = abspos + (patho - abspos)

        else:
            print("ERROR: found an unsupported SVG path command " + str(pd[i][0]))


    # return the relative path
    return p
Converts an SVG path into a path that has only relative commands.
dataset/ETHPy150Open boldport/pcbmode/pcbmode/utils/svg.py/absolute_to_relative_path