def _parse_rectangles(self, cellchar, tablechar, form, **kwargs):
        """
        Parse a form for rectangular formfields identified by formchar
        enclosing an identifier.

        """

        # update options given at creation with new input - this
        # allows e.g. self.map() to add custom settings for individual
        # cells/tables
        custom_options = copy.copy(self.options)
        custom_options.update(kwargs)

        nform = len(form)

        mapping = {}
        cell_coords = {}
        table_coords = {}

        # Locate the identifier tags and the horizontal end coords for all forms
        re_cellchar =  re.compile(r"%s+([^%s%s])%s+" % (cellchar, INVALID_FORMCHARS, cellchar, cellchar))
        re_tablechar = re.compile(r"%s+([^%s%s|])%s+" % (tablechar, INVALID_FORMCHARS, tablechar, tablechar))
        for iy, line in enumerate(_to_ansi(form, regexable=True)):
            # find cells
            ix0 = 0
            while True:
                match = re_cellchar.search(line, ix0)
                if match:
                    # get the width of the rectangle directly from the match
                    cell_coords[match.group(1)] = [iy, match.start(), match.end()]
                    ix0 = match.end()
                else:
                    break
            # find tables
            ix0 = 0
            while True:
                match = re_tablechar.search(line, ix0)
                if match:
                    # get the width of the rectangle directly from the match
                    table_coords[match.group(1)] = [iy, match.start(), match.end()]
                    ix0 = match.end()
                else:
                    break

        # get rectangles and assign EvCells
        for key, (iy, leftix, rightix) in cell_coords.items():

            # scan up to find top of rectangle
            dy_up = 0
            if iy > 0:
                for i in range(1,iy):
                    if all(form[iy-i][ix] == cellchar for ix in range(leftix, rightix)):
                        dy_up += 1
                    else:
                        break
            # find bottom edge of rectangle
            dy_down = 0
            if iy < nform-1:
                for i in range(1,nform-iy-1):
                    if all(form[iy+i][ix] == cellchar for ix in range(leftix, rightix)):
                        dy_down += 1
                    else:
                        break

            #  we have our rectangle. Calculate size of EvCell.
            iyup = iy - dy_up
            iydown = iy + dy_down
            width = rightix - leftix
            height = abs(iyup - iydown) + 1

            # we have all the coordinates we need. Create EvCell.
            data = self.cells_mapping.get(key, "")
            #if key == "1":

            options = { "pad_left":0, "pad_right":0, "pad_top":0, "pad_bottom":0, "align":"l", "valign":"t", "enforce_size":True}
            options.update(custom_options)
            #if key=="4":

            mapping[key] = (iyup, leftix, width, height, EvCell(data, width=width, height=height,**options))

        # get rectangles and assign Tables
        for key, (iy, leftix, rightix) in table_coords.items():

            # scan up to find top of rectangle
            dy_up = 0
            if iy > 0:
                for i in range(1,iy):
                    if all(form[iy-i][ix] == tablechar for ix in range(leftix, rightix)):
                        dy_up += 1
                    else:
                        break
            # find bottom edge of rectangle
            dy_down = 0
            if iy < nform-1:
                for i in range(1,nform-iy-1):
                    if all(form[iy+i][ix] == tablechar for ix in range(leftix, rightix)):
                        dy_down += 1
                    else:
                        break

            #  we have our rectangle. Calculate size of Table.
            iyup = iy - dy_up
            iydown = iy + dy_down
            width = rightix - leftix
            height = abs(iyup - iydown) + 1

            # we have all the coordinates we need. Create Table.
            table = self.tables_mapping.get(key, None)

            options = { "pad_left":0, "pad_right":0, "pad_top":0, "pad_bottom":0,
                        "align":"l", "valign":"t", "enforce_size":True}
            options.update(custom_options)

            if table:
                table.reformat(width=width, height=height, **options)
            else:
                table = EvTable(width=width, height=height, **options)
            mapping[key] = (iyup, leftix, width, height, table)

        return mapping
dataset/ETHPy150Open evennia/evennia/evennia/utils/evform.py/EvForm._parse_rectangles/original