/* scan individual table and set "cellPos" data in the form { left: x-coord, top: y-coord }
493605
function scanTable($table) {
        var m = [];
        var tableWidth = 0;
        var tableHeight = 0;
        $table.children('thead,tbody,tfoot').children('tr').each(function (y, row) {
            $(row).children('td,th').each(function (x, cell) {
                var $cell = $(cell),
                    cspan = $cell.attr('colspan') | 0,
                    rspan = $cell.attr('rowspan') | 0,
                    tx, ty;
                cspan = cspan ? cspan : 1;
                rspan = rspan ? rspan : 1;
                for (; m[y] && m[y][x]; ++x);  //skip already occupied cells in current row
                for (tx = x; tx < x + cspan; ++tx) {  //mark matrix elements occupied by current cell with true
                    for (ty = y; ty < y + rspan; ++ty) {
                        if (!m[ty]) {  //fill missing rows
                            m[ty] = [];
                        }
                        m[ty][tx] = true;
                    }
                }
                var pos = {top: y, left: x, bottom: y + rspan - 1, right: x + cspan - 1};
                $cell.data('cellPos', pos);
                tableWidth = Math.max(tableWidth, pos.right);
                tableHeight = Math.max(tableHeight, pos.bottom);
                // $cell.text(x + ', ' + y + ' | ' + pos.right + ',' + pos.bottom);
            });
        });
        $table.data('tableSize', {width: tableWidth + 1, height: tableHeight + 1});
    }
300984
public void addCell(Cell aCell, Point aLocation) throws BadElementException {
        if (aCell == null) throw new NullPointerException("addCell - cell has null-value");
        if (aLocation == null) throw new NullPointerException("addCell - point has null-value");
        if (aCell.isTable()) insertTable((Table)aCell.getElements().next(), aLocation);
        
        if (aLocation.x < 0) throw new BadElementException("row coordinate of location must be >= 0");
        if ((aLocation.y <= 0) && (aLocation.y > columns)) throw new BadElementException("column coordinate of location must be >= 0 and < nr of columns");
        if (!isValidLocation(aCell, aLocation)) throw new BadElementException("Adding a cell at the location (" + aLocation.x + "," + aLocation.y + ") with a colspan of " + aCell.getColspan() + " and a rowspan of " + aCell.getRowspan() + " is illegal (beyond boundaries/overlapping).");
        
        if (aCell.getBorder() == UNDEFINED) aCell.setBorder(defaultCell.getBorder());
        aCell.fill();
        placeCell(rows, aCell, aLocation);
        setCurrentLocationToNextValidPosition(aLocation);
    }
310847
function focusToFirstTd(sq, range, $tr, tableMgr) {
  const nextFocusCell = $tr.find('td').get(0);
  range.setStart(nextFocusCell, 0);
  range.collapse(true);

  tableMgr.setLastCellNode(nextFocusCell);
  sq.setSelection(range);
}
444133
function table(node) {
  var self = this
  var rows = node.children
  var index = rows.length
  var align = node.align
  var alignLength = align.length
  var pos
  var result = []
  var row
  var out
  var alignHeading = []
  var alignRow = []

  while (index--) {
    pos = -1
    row = rows[index].children
    out = []

    while (++pos < alignLength) {
      out[pos] = self.all(row[pos]).join('')
    }

    result[index] = out.join('@')
  }

  pos = -1

  while (++pos < alignLength) {
    alignHeading.push('cb')
    alignRow.push((align[pos] || 'l').charAt(0))
  }

  result = []
    .concat(
      ['', 'tab(@) allbox;', alignHeading.join(' '), alignRow.join(' ') + ' .'],
      result,
      ['.TE']
    )
    .join('\n')

  return macro('TS', result)
}
552156
function setOffsetToLoc(loc, offset, baseline) {
            if (baseline >= loc.line) {
                return
            }
            const actualText = getActualLineIndentText(loc.line)
            if (actualText.length !== loc.column) {
                return
            }
            offsets.set(loc.line, {
                actualText,
                baseline,
                offset,
                expectedIndent: undefined,
            })
        }
837667
def setpos(self, location, text):
        """"""
        self.location = location
        self.text = text
654518
function _offsetPos(pos, offset) {
        return {line: pos.line, ch: pos.ch + offset};
    }
1071652
private void placeCell(ArrayList<Row> someRows, Cell aCell, Point aPosition) {
        int i;
        Row row = null;
        int rowCount = aPosition.x + aCell.getRowspan() - someRows.size();
        assumeTableDefaults(aCell);
        if ( (aPosition.x + aCell.getRowspan()) > someRows.size() ) {
            for (i = 0; i < rowCount; i++) {
                row = new Row(columns);
                someRows.add(row);
            }
        }
        
        // reserve cell in rows below
        for (i = aPosition.x + 1; i < (aPosition.x  + aCell.getRowspan()); i++) {
            if ( !someRows.get(i).reserve(aPosition.y, aCell.getColspan())) {
                
                // should be impossible to come here :-)
                throw new RuntimeException("addCell - error in reserve");
            }
        }
        row = someRows.get(aPosition.x);
        row.addElement(aCell, aPosition.y);
        
    }
870463
function (keyboardProxy, pos) {
    var el = keyboardProxy[0];
    if (el.setSelectionRange) {
      el.focus();
      el.setSelectionRange(pos, pos);
    }
    else if (el.createTextRange) {
      var range = el.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
960655
function _updateColspan(tableData, startColIndex, endColIndex) {
  tableData.forEach(rowData => {
    util.range(startColIndex, endColIndex + 1).forEach(colIndex => {
      const cellData = rowData [colIndex];

      if (util.isExisty(cellData.colMergeWith)) {
        const merger = rowData [cellData.colMergeWith];

        if (merger.colspan) {
          merger.colspan -= 1;
        }
      } else if (cellData.colspan > 1) {
        const lastMergedCellIndex = colIndex + cellData.colspan - 1;

        cellData.colspan -= (endColIndex - colIndex + 1);

        if (lastMergedCellIndex > endColIndex) {
          rowData [endColIndex + 1] = util.extend({}, cellData);
        }
      }
    });
  });
}
581633
function setCell(map, key, columnCount, columnIndex, value) {
  if (!map.has(key)) map.set(key, new Array(columnCount));
  map.get(key)[columnIndex] = value;
}
143399
function _reverseTableDir(&$table)
	{
		$cells = &$table['cells'];
		$numcols = $table['nc'];
		$numrows = $table['nr'];
		for ($i = 0; $i < $numrows; $i++) { // Rows
			$row = [];
			for ($j = ($numcols - 1); $j >= 0; $j--) { // Columns
				if (isset($cells[$i][$j]) && $cells[$i][$j]) {
					$cell = &$cells[$i][$j];
					$col = $numcols - $j - 1;
					if (isset($cell['colspan']) && $cell['colspan'] > 1) {
						$col -= ($cell['colspan'] - 1);
					}
					// Nested content
					if (isset($cell['textbuffer'])) {
						for ($n = 0; $n < count($cell['textbuffer']); $n++) {
							$t = $cell['textbuffer'][$n][0];
							if (substr($t, 0, 19) == "\xbb\xa4\xactype=nestedtable") {
								$objattr = $this->_getObjAttr($t);
								$objattr['col'] = $col;
								$cell['textbuffer'][$n][0] = "\xbb\xa4\xactype=nestedtable,objattr=" . serialize($objattr) . "\xbb\xa4\xac";
								$this->table[($this->tableLevel + 1)][$objattr['nestedcontent']]['nestedpos'][1] = $col;
							}
						}
					}
					$row[$col] = $cells[$i][$j];
					unset($cell);
				}
			}
			for ($f = 0; $f < $numcols; $f++) {
				if (!isset($row[$f])) {
					$row[$f] = 0;
				}
			}
			$table['cells'][$i] = $row;
		}
	}
1063879
function insertColumn(
    opts: Options,
    change: Change,
    at?: number, // Column index
    getCell?: (column: number, row: number) => Block
): Change {
    const { value } = change;
    const { startKey } = value;

    const pos = TablePosition.create(opts, value.document, startKey);
    const { table } = pos;

    const columnIndex =
        typeof at === 'undefined' ? pos.getColumnIndex() + 1 : at;

    // Insert the new cell
    table.nodes.forEach((row, rowIndex) => {
        const newCell = getCell
            ? getCell(columnIndex, rowIndex)
            : createCell(opts);
        change.insertNodeByKey(row.key, columnIndex, newCell, {
            normalize: false
        });
    });

    // Update the selection (not doing can break the undo)
    return moveSelection(
        opts,
        change,
        pos.getColumnIndex() + 1,
        pos.getRowIndex()
    );
}
1293223
function(ch, w, coord, prop) {
   var child = ch[0];
   child.getPos(prop).setc(coord.left, coord.top);
   child.setData('width', coord.width, prop);
   child.setData('height', coord.height, prop);
 }
1297302
function moveSelection(
    opts: Options,
    change: Change,
    x: number,
    y: number
): Change {
    const { value } = change;
    const { startKey } = value;
    const pos = TablePosition.create(opts, value.document, startKey);

    if (!pos.isInCell()) {
        throw new Error('moveSelection can only be applied from within a cell');
    }

    const { table } = pos;
    const row = table.nodes.get(y);
    const cell = row.nodes.get(x);

    return change.collapseToStartOf(cell);
}
605937
private void updateValue(Point location) {
        CellPosition oldValue = value;
        if (location == null) {
            value = null;
        } else {
            int row = table.rowAtPoint(location);
            int column = table.columnAtPoint(location);
            value = new CellPosition(row, column);
        }
        maybeNotifyListeners(oldValue, value);
    }
1076147
function focusToCell(sq, $cell, tableMgr) {
  const nextFocusCell = $cell.get(0);

  if ($cell.length && $.contains(document, $cell)) {
    const range = sq.getSelection();
    range.selectNodeContents($cell[0]);
    range.collapse(true);
    sq.setSelection(range);

    tableMgr.setLastCellNode(nextFocusCell);
  }
}