Creates a list of the spanned cell groups of [row, column] pairs.

    Parameters
    ----------
    html_string : str

    Returns
    -------
    list of lists of lists of int
505608
def extract_spans(html_string):
    
    try:
        from bs4 import BeautifulSoup
    except ImportError:
        print("ERROR: You must have BeautifulSoup to use html2data")
        return

    soup = BeautifulSoup(html_string, 'html.parser')
    table = soup.find('table')
    if not table:
        return []

    trs = table.findAll('tr')
    if len(trs) == 0:
        return []

    spans = []
    for tr in range(len(trs)):
        if tr == 0:
            ths = trs[tr].findAll('th')
            if len(ths) == 0:
                ths = trs[tr].findAll('td')
            tds = ths
        else:
            tds = trs[tr].findAll('td')

        column = 0
        for td in tds:
            r_span_count = 1
            c_span_count = 1
            current_column = column

            if td.has_attr('rowspan'):
                r_span_count = int(td['rowspan'])
            if td.has_attr('colspan'):
                c_span_count = int(td['colspan'])
                column += c_span_count
            else:
                column += 1

            new_span = []
            for r_index in range(tr, tr + r_span_count):
                for c_index in range(current_column, column):
                    if not get_span(spans, r_index, c_index):
                        new_span.append([r_index, c_index])

            if len(new_span) > 0:
                spans.append(new_span)

    return spans
587472
def serialize(self, serialize_cell=None):
    
    if serialize_cell is None:
      serialize_cell = self.get_cell_value
    return [[serialize_cell(cell) for cell in row] for row in self.rows]
322496
def _html_link_cells(self):
        
        new_table = self.copy()
        for row in new_table:
            for c in new_table.columns:
                link = '%s <Link>' % c
                if row.get(link, None):
                    row[c] = '<a href="%s">%s</a>' % (row[link], row[c])

        new_table.columns = [c for c in self.columns if '<Link>' not in c]
        return new_table
1070446
def tokenize_sents(string):
    
    string = six.text_type(string)

    spans = []
    for match in re.finditer('[^\s]+', string):
        spans.append(match)
    spans_count = len(spans)

    rez = []
    off = 0

    for i in range(spans_count):
        tok = string[spans[i].start():spans[i].end()]
        if i == spans_count - 1:
            rez.append(string[off:spans[i].end()])
        elif tok[-1] in ['.', '!', '?', '…', '»']:
            tok1 = tok[re.search('[.!?…»]', tok).start()-1]
            next_tok = string[spans[i + 1].start():spans[i + 1].end()]
            if (next_tok[0].isupper()
                and not tok1.isupper()
                and not (tok[-1] != '.'
                         or tok1[0] == '('
                         or tok in ABBRS)):
                rez.append(string[off:spans[i].end()])
                off = spans[i + 1].start()

    return rez
67916
def get_grouped_pairs(self, format_string):
        
        # Step 1: Split simple tokens (without a name) into
        # their whitespace parts and non-whitespace parts.
        separated = []
        pattern = re.compile(r'(\s+)')
        for token in self.get_pairs(format_string):
            if token.name:
                separated.append(token)
            else:
                separated.extend(
                    FormatStringToken(name=None, text=text)
                    for text in pattern.split(token.text) if text
                )
        # Step 2: Group tokens together based on whitespace.
        current_group = []
        grouped_pairs = []
        for token in separated:
            if token.text.isspace():
                if current_group:
                    grouped_pairs.append(current_group)
                grouped_pairs.append([token])
                current_group = []
            else:
                current_group.append(token)
        if current_group:
            grouped_pairs.append(current_group)
        return grouped_pairs
936386
def structure_from_string(data):
        

        data = data.splitlines()
        data = [x.split() for x in data if x]  # remove empty lines

        # following specification/terminology given in manual
        if len(data[0]) == 6:  # lattice parameters
            a, b, c, alpha, beta, gamma = map(float, data[0])
            coord_system = Lattice.from_parameters(a, b, c,
                                                   alpha, beta, gamma).matrix
            lattice_vecs = np.array([
                [data[1][0], data[1][1], data[1][2]],
                [data[2][0], data[2][1], data[2][2]],
                [data[3][0], data[3][1], data[3][2]]
            ], dtype=float)
            first_species_line = 4
        else:
            coord_system = np.array([
                [data[0][0], data[0][1], data[0][2]],
                [data[1][0], data[1][1], data[1][2]],
                [data[2][0], data[2][1], data[2][2]]
            ], dtype=float)
            lattice_vecs = np.array([
                [data[3][0], data[3][1], data[3][2]],
                [data[4][0], data[4][1], data[4][2]],
                [data[5][0], data[5][1], data[5][2]]
            ], dtype=float)
            first_species_line = 6

        scaled_matrix = np.matmul(coord_system, lattice_vecs)
        lattice = Lattice(scaled_matrix)

        all_coords = []
        all_species = []
        for l in data[first_species_line:]:

            all_coords.append(np.array([l[0], l[1], l[2]], dtype=float))

            species_strs = "".join(l[3:])  # join multiple strings back together
            species_strs = species_strs.replace(" ", "")  # trim any white space
            species_strs = species_strs.split(",")  # comma-delimited

            species = {}

            for species_str in species_strs:
                species_str = species_str.split('=')
                if len(species_str) == 1:
                    # assume occupancy is 1.0
                    species_str = [species_str[0], 1.0]
                try:
                    species[Specie(species_str[0])] = float(species_str[1])
                except:
                    species[DummySpecie(species_str[0])] = float(species_str[1])

            all_species.append(species)

        return Structure(lattice, all_species, all_coords)
872666
function _createCellHtml(cell) {
  let attrs = cell.colspan > 1 ? ` colspan="${cell.colspan}"` : '';
  attrs += cell.rowspan > 1 ? ` rowspan="${cell.rowspan}"` : '';
  attrs += cell.align ? ` align="${cell.align}"` : '';

  return `<${cell.nodeName}${attrs}>${cell.content}</${cell.nodeName}>`;
}
163881
def _init_groups(self, string):
        

        taf_group_pattern = """
            (?:FM|(?:PROB(?:\d{1,2})\s*(?:TEMPO)?)|TEMPO|BECMG|[\S\s])[A-Z0-9\+\-/\s$]+?(?=FM|PROB|TEMPO|BECMG|$)
        """

        group_list = []

        groups = re.findall(taf_group_pattern, string, re.VERBOSE)
        if not groups:
            raise MalformedTAF("No valid groups found")

        for group in groups:
            group_list.append(group)

        return(group_list)
445887
def html(string)
      ptr = Libcgraph.agstrdup_html(graph.ptr, string)
      string = ptr.read_string
      Libcgraph.agstrfree graph.ptr, ptr

      string
    end
1241379
def from_string(string):
        
        lines = string.split("\n")
        toks = lines[0].split()
        lengths = [float(i) for i in toks]
        toks = lines[1].split()
        angles = [float(i) for i in toks[0:3]]
        latt = Lattice.from_lengths_and_angles(lengths, angles)
        sp = []
        coords = []
        for l in lines[4:]:
            m = re.match(
                r"\d+\s+(\w+)\s+([0-9\-\.]+)\s+([0-9\-\.]+)\s+([0-9\-\.]+)",
                l.strip())
            if m:
                sp.append(m.group(1))
                coords.append([float(m.group(i)) for i in range(2, 5)])
        return Cssr(Structure(latt, sp, coords))
1267356
def toList(self):
        
        if self.getNumCols() > 1:
            return [
                tuple(self.getRowByIndex(i))
                for i in range(self.getNumRows())
            ]
        else:
            return [
                self.getRowByIndex(i)[0]
                for i in range(self.getNumRows())
            ]
319014
function createRows(items, columns, columnNames, paddingChr) {
  return items.map(item => {
    let row = []
    let numLines = 0
    columnNames.forEach(columnName => {
      numLines = Math.max(numLines, item[columnName].length)
    })
    // combine matching lines of each rows
    for (let i = 0; i < numLines; i++) {
      row[i] = row[i] || []
      columnNames.forEach(columnName => {
        let column = columns[columnName]
        let val = item[columnName][i] || '' // || '' ensures empty columns get padded
        if (column.align === 'right') row[i].push(padLeft(val, column.width, paddingChr))
        else if (column.align === 'center' || column.align === 'centre') row[i].push(padCenter(val, column.width, paddingChr))
        else row[i].push(padRight(val, column.width, paddingChr))
      })
    }
    return row
  })
}
478996
def multi_cell(self, w, h, txt='', border=0, align='J', fill=0, split_only=False):
        ""
        txt = self.normalize_text(txt)
        ret = [] # if split_only = True, returns splited text cells
        cw=self.current_font['cw']
        if(w==0):
            w=self.w-self.r_margin-self.x
        wmax=(w-2*self.c_margin)*1000.0/self.font_size
        s=txt.replace("\r",'')
        nb=len(s)
        if(nb>0 and s[nb-1]=="\n"):
            nb-=1
        b=0
        if(border):
            if(border==1):
                border='LTRB'
                b='LRT'
                b2='LR'
            else:
                b2=''
                if('L' in border):
                    b2+='L'
                if('R' in border):
                    b2+='R'
                if ('T' in border):
                    b=b2+'T'
                else:
                    b=b2
        sep=-1
        i=0
        j=0
        l=0
        ns=0
        nl=1
        while(i<nb):
            #Get next character
            c=s[i]
            if(c=="\n"):
                #Explicit line break
                if(self.ws>0):
                    self.ws=0
                    if not split_only:
                        self._out('0 Tw')
                if not split_only:
                    self.cell(w,h,substr(s,j,i-j),b,2,align,fill)
                else:
                    ret.append(substr(s,j,i-j))
                i+=1
                sep=-1
                j=i
                l=0
                ns=0
                nl+=1
                if(border and nl==2):
                    b=b2
                continue
            if(c==' '):
                sep=i
                ls=l
                ns+=1
            if self.unifontsubset:
                l += self.get_string_width(c) / self.font_size*1000.0
            else:
                l += cw.get(c,0)
            if(l>wmax):
                #Automatic line break
                if(sep==-1):
                    if(i==j):
                        i+=1
                    if(self.ws>0):
                        self.ws=0
                        if not split_only:
                            self._out('0 Tw')
                    if not split_only:
                        self.cell(w,h,substr(s,j,i-j),b,2,align,fill)
                    else:
                        ret.append(substr(s,j,i-j))
                else:
                    if(align=='J'):
                        if ns>1:
                            self.ws=(wmax-ls)/1000.0*self.font_size/(ns-1)
                        else:
                            self.ws=0
                        if not split_only:
                            self._out(sprintf('%.3f Tw',self.ws*self.k))
                    if not split_only:
                        self.cell(w,h,substr(s,j,sep-j),b,2,align,fill)
                    else:
                        ret.append(substr(s,j,sep-j))
                    i=sep+1
                sep=-1
                j=i
                l=0
                ns=0
                nl+=1
                if(border and nl==2):
                    b=b2
            else:
                i+=1
        #Last chunk
        if(self.ws>0):
            self.ws=0
            if not split_only:
                self._out('0 Tw')
        if(border and 'B' in border):
            b+='B'
        if not split_only:
            self.cell(w,h,substr(s,j,i-j),b,2,align,fill)
            self.x=self.l_margin
        else:
            ret.append(substr(s,j,i-j))
        return ret
1342490
def colformat(strings, num_sep_spaces=1, terminal_width=None):
    """"""
    if terminal_width is None:
        terminal_width = get_terminal_size().columns

    if not strings:
        return

    num_items = len(strings)
    max_len = max([len(strip_ansi_escapes(s)) for s in strings])

    num_columns = min(
        int((terminal_width + num_sep_spaces) / (max_len + num_sep_spaces)),
        num_items)
    num_columns = max(1, num_columns)

    num_lines = int(math.ceil(float(num_items) / num_columns))
    num_columns = int(math.ceil(float(num_items) / num_lines))

    num_elements_last_column = num_items % num_lines
    if num_elements_last_column == 0:
        num_elements_last_column = num_lines

    lines = []
    for i in range(num_lines):
        line_size = num_columns
        if i >= num_elements_last_column:
            line_size -= 1
        lines.append([None] * line_size)

    for i, line in enumerate(lines):
        line_size = len(line)
        for j in range(line_size):
            k = i + num_lines * j
            item = strings[k]
            if j % line_size != line_size - 1:
                item_len = len(strip_ansi_escapes(item))
                item = item + ' ' * (max_len - item_len)
            line[j] = item

    sep = ' ' * num_sep_spaces
    for line in lines:
        yield sep.join(line)
50625
def n_list(self, node):
        
        p = self.prec
        self.prec = 100
        n = node.pop()
        lastnode = n.kind
        start = len(self.f.getvalue())
        if lastnode.startswith('BUILD_LIST'):
            self.write('['); endchar = ']'
        elif lastnode.startswith('BUILD_TUPLE'):
            self.write('('); endchar = ')'
        elif lastnode.startswith('BUILD_SET'):
            self.write('{'); endchar = '}'
        elif lastnode.startswith('ROT_TWO'):
            self.write('('); endchar = ')'
        else:
            raise RuntimeError('Internal Error: n_list expects list or tuple')

        flat_elems = []
        for elem in node:
            if elem == 'expr1024':
                for subelem in elem:
                        for subsubelem in subelem:
                            flat_elems.append(subsubelem)
            elif elem == 'expr32':
                for subelem in elem:
                    flat_elems.append(subelem)
            else:
                flat_elems.append(elem)

        self.indent_more(INDENT_PER_LEVEL)
        if len(node) > 3:
            line_separator = ',\n' + self.indent
        else:
            line_separator = ', '
        sep = INDENT_PER_LEVEL[:-1]

        # FIXME:
        # if flat_elems > some_number, then group
        # do automatic wrapping
        for elem in flat_elems:
            if (elem == 'ROT_THREE'):
                continue

            assert elem == 'expr'
            value = self.traverse(elem)
            self.node_append(sep, value, elem)
            sep = line_separator
        if len(node) == 1 and lastnode.startswith('BUILD_TUPLE'):
            self.write(',')
        self.write(endchar)
        finish = len(self.f.getvalue())
        n.parent = node.parent
        self.set_pos_info(n, start, finish)
        self.set_pos_info(node, start, finish)
        self.indent_less(INDENT_PER_LEVEL)
        self.prec = p
        self.prune()
        return
1258249
function createBasicCell(rowIndex, colIndex, nodeName) {
  return {
    nodeName: nodeName || 'TD',
    colspan: 1,
    rowspan: 1,
    content: BASIC_CELL_CONTENT,
    elementIndex: {
      rowIndex,
      colIndex
    }
  };
}
1281238
def split_table_cells(self, row):
        

        row = iter(row)
        col = 0
        start_col = col + 1
        cell = ''
        first_cell = True
        while True:
            char = next(row, None)
            col += 1
            if char == '|':
                if first_cell:
                    # First cell (content before the first |) is skipped
                    first_cell = False
                else:
                    yield (cell, start_col)
                cell = ''
                start_col = col + 1
            elif char == '\\':
                char = next(row)
                col += 1
                if char == 'n':
                    cell += '\n'
                else:
                    if char not in ['|', '\\']:
                        cell += '\\'
                    cell += char
            elif char:
                cell += char
            else:
                break