46 lines
1.3 KiB
JavaScript
46 lines
1.3 KiB
JavaScript
import { tabs_to_spaces } from '@efforting.tech/text/text-utilities';
|
|
|
|
const raster_table_pattern = /^((?:[^\S\n]|[\w-])+)\n((?:[^\S\n]|-)+)\n(.+)/ms;
|
|
const column_pattern = /\s*(.+?)(?=\s{2,}|$)/gd;
|
|
const row_pattern = /^(.+)$/mg
|
|
|
|
// If loader is null we return a raw representation
|
|
export function load_raster_table(raster, loader=null, tab_width=4, null_padding=true) {
|
|
if (raster.match(/\t/g)) {
|
|
raster = tabs_to_spaces(raster, tab_width);
|
|
}
|
|
|
|
if (null_padding) { //TODO - this is just experimental proof of concept
|
|
raster = raster.replace(/〃/g, '\0〃');
|
|
}
|
|
|
|
|
|
const m = raster.match(raster_table_pattern);
|
|
const column_matches = [...m[1].matchAll(column_pattern)];
|
|
const column_positions = [...column_matches.map(cm => cm.indices[1][0])]
|
|
const column_names = [...column_matches.map(cm => cm[1])]
|
|
const rows = [];
|
|
|
|
for (const row of m[3].matchAll(row_pattern)) {
|
|
|
|
const pending_row = [];
|
|
for (let ci=0; ci<column_positions.length; ci++) {
|
|
const cell = row[1].slice(column_positions[ci], column_positions[ci+1]);
|
|
if (null_padding) {
|
|
pending_row.push(cell.replace(/\0/, ''));
|
|
} else {
|
|
pending_row.push(cell);
|
|
}
|
|
}
|
|
rows.push(pending_row);
|
|
}
|
|
|
|
if (loader) {
|
|
return new loader({ rows, column_names });
|
|
} else {
|
|
return {column_names, column_positions, rows};
|
|
}
|
|
}
|
|
|
|
|
|
//TODO: load_ditto_raster_table
|