216 lines
8.5 KiB
JavaScript
216 lines
8.5 KiB
JavaScript
"use strict";
|
|
|
|
exports.__esModule = true;
|
|
exports.columnAddressFromString = exports.cellAddressFromString = void 0;
|
|
exports.columnIndexToLabel = columnIndexToLabel;
|
|
exports.rowAddressFromString = void 0;
|
|
exports.sheetIndexToString = sheetIndexToString;
|
|
exports.simpleCellRangeToString = exports.simpleCellRangeFromString = exports.simpleCellAddressToString = exports.simpleCellAddressFromString = void 0;
|
|
var _AbsoluteCellRange = require("../AbsoluteCellRange");
|
|
var _Cell = require("../Cell");
|
|
var _CellAddress = require("./CellAddress");
|
|
var _ColumnAddress = require("./ColumnAddress");
|
|
var _parserConsts = require("./parser-consts");
|
|
var _RowAddress = require("./RowAddress");
|
|
/**
|
|
* @license
|
|
* Copyright (c) 2024 Handsoncode. All rights reserved.
|
|
*/
|
|
|
|
const addressRegex = new RegExp(`^(${_parserConsts.SHEET_NAME_PATTERN})?(\\${_parserConsts.ABSOLUTE_OPERATOR}?)([A-Za-z]+)(\\${_parserConsts.ABSOLUTE_OPERATOR}?)([0-9]+)$`);
|
|
const columnRegex = new RegExp(`^(${_parserConsts.SHEET_NAME_PATTERN})?(\\${_parserConsts.ABSOLUTE_OPERATOR}?)([A-Za-z]+)$`);
|
|
const rowRegex = new RegExp(`^(${_parserConsts.SHEET_NAME_PATTERN})?(\\${_parserConsts.ABSOLUTE_OPERATOR}?)([0-9]+)$`);
|
|
const simpleSheetNameRegex = new RegExp(`^${_parserConsts.UNQUOTED_SHEET_NAME_PATTERN}$`);
|
|
/**
|
|
* Computes R0C0 representation of cell address based on it's string representation and base address.
|
|
*
|
|
* @param sheetMapping - mapping function needed to change name of a sheet to index
|
|
* @param stringAddress - string representation of cell address, e.g., 'C64'
|
|
* @param baseAddress - base address for R0C0 conversion
|
|
* @returns object representation of address
|
|
*/
|
|
const cellAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
|
|
const result = addressRegex.exec(stringAddress);
|
|
const col = columnLabelToIndex(result[6]);
|
|
let sheet = extractSheetNumber(result, sheetMapping);
|
|
if (sheet === undefined) {
|
|
return undefined;
|
|
}
|
|
if (sheet === null) {
|
|
sheet = undefined;
|
|
}
|
|
const row = Number(result[8]) - 1;
|
|
if (result[5] === _parserConsts.ABSOLUTE_OPERATOR && result[7] === _parserConsts.ABSOLUTE_OPERATOR) {
|
|
return _CellAddress.CellAddress.absolute(col, row, sheet);
|
|
} else if (result[5] === _parserConsts.ABSOLUTE_OPERATOR) {
|
|
return _CellAddress.CellAddress.absoluteCol(col, row - baseAddress.row, sheet);
|
|
} else if (result[7] === _parserConsts.ABSOLUTE_OPERATOR) {
|
|
return _CellAddress.CellAddress.absoluteRow(col - baseAddress.col, row, sheet);
|
|
} else {
|
|
return _CellAddress.CellAddress.relative(col - baseAddress.col, row - baseAddress.row, sheet);
|
|
}
|
|
};
|
|
exports.cellAddressFromString = cellAddressFromString;
|
|
const columnAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
|
|
const result = columnRegex.exec(stringAddress);
|
|
let sheet = extractSheetNumber(result, sheetMapping);
|
|
if (sheet === undefined) {
|
|
return undefined;
|
|
}
|
|
if (sheet === null) {
|
|
sheet = undefined;
|
|
}
|
|
const col = columnLabelToIndex(result[6]);
|
|
if (result[5] === _parserConsts.ABSOLUTE_OPERATOR) {
|
|
return _ColumnAddress.ColumnAddress.absolute(col, sheet);
|
|
} else {
|
|
return _ColumnAddress.ColumnAddress.relative(col - baseAddress.col, sheet);
|
|
}
|
|
};
|
|
exports.columnAddressFromString = columnAddressFromString;
|
|
const rowAddressFromString = (sheetMapping, stringAddress, baseAddress) => {
|
|
const result = rowRegex.exec(stringAddress);
|
|
let sheet = extractSheetNumber(result, sheetMapping);
|
|
if (sheet === undefined) {
|
|
return undefined;
|
|
}
|
|
if (sheet === null) {
|
|
sheet = undefined;
|
|
}
|
|
const row = Number(result[6]) - 1;
|
|
if (result[5] === _parserConsts.ABSOLUTE_OPERATOR) {
|
|
return _RowAddress.RowAddress.absolute(row, sheet);
|
|
} else {
|
|
return _RowAddress.RowAddress.relative(row - baseAddress.row, sheet);
|
|
}
|
|
};
|
|
/**
|
|
* Computes simple (absolute) address of a cell address based on its string representation.
|
|
* - If sheet name is present in the string representation but is not present in sheet mapping, returns `undefined`.
|
|
* - If sheet name is not present in the string representation, returns {@param contextSheetId} as sheet number.
|
|
*
|
|
* @param sheetMapping - mapping function needed to change name of a sheet to index
|
|
* @param stringAddress - string representation of cell address, e.g., 'C64'
|
|
* @param contextSheetId - sheet in context of which we should parse the address
|
|
* @returns absolute representation of address, e.g., { sheet: 0, col: 1, row: 1 }
|
|
*/
|
|
exports.rowAddressFromString = rowAddressFromString;
|
|
const simpleCellAddressFromString = (sheetMapping, stringAddress, contextSheetId) => {
|
|
const regExpExecArray = addressRegex.exec(stringAddress);
|
|
if (!regExpExecArray) {
|
|
return undefined;
|
|
}
|
|
const col = columnLabelToIndex(regExpExecArray[6]);
|
|
let sheet = extractSheetNumber(regExpExecArray, sheetMapping);
|
|
if (sheet === undefined) {
|
|
return undefined;
|
|
}
|
|
if (sheet === null) {
|
|
sheet = contextSheetId;
|
|
}
|
|
const row = Number(regExpExecArray[8]) - 1;
|
|
return (0, _Cell.simpleCellAddress)(sheet, col, row);
|
|
};
|
|
exports.simpleCellAddressFromString = simpleCellAddressFromString;
|
|
const simpleCellRangeFromString = (sheetMapping, stringAddress, contextSheetId) => {
|
|
const split = stringAddress.split(_parserConsts.RANGE_OPERATOR);
|
|
if (split.length !== 2) {
|
|
return undefined;
|
|
}
|
|
const [startString, endString] = split;
|
|
const start = simpleCellAddressFromString(sheetMapping, startString, contextSheetId);
|
|
if (start === undefined) {
|
|
return undefined;
|
|
}
|
|
const end = simpleCellAddressFromString(sheetMapping, endString, start.sheet);
|
|
if (end === undefined) {
|
|
return undefined;
|
|
}
|
|
if (start.sheet !== end.sheet) {
|
|
return undefined;
|
|
}
|
|
return (0, _AbsoluteCellRange.simpleCellRange)(start, end);
|
|
};
|
|
/**
|
|
* Returns string representation of absolute address
|
|
* If sheet index is not present in sheet mapping, returns undefined
|
|
*
|
|
* @param sheetIndexMapping - mapping function needed to change sheet index to sheet name
|
|
* @param address - object representation of absolute address
|
|
* @param sheetIndex - if is not equal with address sheet index, string representation will contain sheet name
|
|
*/
|
|
exports.simpleCellRangeFromString = simpleCellRangeFromString;
|
|
const simpleCellAddressToString = (sheetIndexMapping, address, sheetIndex) => {
|
|
const column = columnIndexToLabel(address.col);
|
|
const sheetName = sheetIndexToString(address.sheet, sheetIndexMapping);
|
|
if (sheetName === undefined) {
|
|
return undefined;
|
|
}
|
|
if (sheetIndex !== address.sheet) {
|
|
return `${sheetName}!${column}${address.row + 1}`;
|
|
} else {
|
|
return `${column}${address.row + 1}`;
|
|
}
|
|
};
|
|
exports.simpleCellAddressToString = simpleCellAddressToString;
|
|
const simpleCellRangeToString = (sheetIndexMapping, address, sheetIndex) => {
|
|
const startString = simpleCellAddressToString(sheetIndexMapping, address.start, sheetIndex);
|
|
const endString = simpleCellAddressToString(sheetIndexMapping, address.end, address.start.sheet);
|
|
if (startString === undefined || endString === undefined) {
|
|
return undefined;
|
|
} else {
|
|
return `${startString}${_parserConsts.RANGE_OPERATOR}${endString}`;
|
|
}
|
|
};
|
|
/**
|
|
* Convert column label to index
|
|
*
|
|
* @param columnStringRepresentation - column label (e.g., 'AAB')
|
|
* @returns column index
|
|
*/
|
|
exports.simpleCellRangeToString = simpleCellRangeToString;
|
|
function columnLabelToIndex(columnStringRepresentation) {
|
|
if (columnStringRepresentation.length === 1) {
|
|
return columnStringRepresentation.toUpperCase().charCodeAt(0) - 65;
|
|
} else {
|
|
return columnStringRepresentation.split('').reduce((currentColumn, nextLetter) => {
|
|
return currentColumn * 26 + (nextLetter.toUpperCase().charCodeAt(0) - 64);
|
|
}, 0) - 1;
|
|
}
|
|
}
|
|
/**
|
|
* Converts column index to label
|
|
*
|
|
* @param column - address to convert
|
|
* @returns string representation, e.g., 'AAB'
|
|
*/
|
|
function columnIndexToLabel(column) {
|
|
let result = '';
|
|
while (column >= 0) {
|
|
result = String.fromCharCode(column % 26 + 97) + result;
|
|
column = Math.floor(column / 26) - 1;
|
|
}
|
|
return result.toUpperCase();
|
|
}
|
|
function sheetIndexToString(sheetId, sheetMappingFn) {
|
|
let sheetName = sheetMappingFn(sheetId);
|
|
if (sheetName === undefined) {
|
|
return undefined;
|
|
}
|
|
if (simpleSheetNameRegex.test(sheetName)) {
|
|
return sheetName;
|
|
} else {
|
|
sheetName = sheetName.replace(/'/g, "''");
|
|
return `'${sheetName}'`;
|
|
}
|
|
}
|
|
function extractSheetNumber(regexResult, sheetMapping) {
|
|
var _a;
|
|
let maybeSheetName = (_a = regexResult[3]) !== null && _a !== void 0 ? _a : regexResult[2];
|
|
if (maybeSheetName) {
|
|
maybeSheetName = maybeSheetName.replace(/''/g, "'");
|
|
return sheetMapping(maybeSheetName);
|
|
} else {
|
|
return null;
|
|
}
|
|
} |