|
|
@@ -2686,47 +2686,10 @@ class SpreadsheetGrid {
|
|
2686
|
2686
|
outputValueAt(address) {
|
|
2687
|
2687
|
return this.cellAt(address)?.outputValue;
|
|
2688
|
2688
|
}
|
|
2689
|
|
-
|
|
2690
|
|
- applyToTable() {
|
|
2691
|
|
- for (const column of this.cells) {
|
|
2692
|
|
- for (const cell of column) {
|
|
2693
|
|
- cell.applyToBlock();
|
|
2694
|
|
- }
|
|
2695
|
|
- }
|
|
2696
|
|
- }
|
|
2697
|
|
-
|
|
2698
|
|
- /**
|
|
2699
|
|
- * @param {MDTableBlock} tableBlock
|
|
2700
|
|
- * @param {MDState} state
|
|
2701
|
|
- * @returns {SpreadsheetGrid}
|
|
2702
|
|
- */
|
|
2703
|
|
- static fromTableBlock(tableBlock, state) {
|
|
2704
|
|
- var columnCount = tableBlock.headerRow.cells.length;
|
|
2705
|
|
- for (const row of tableBlock.bodyRows) {
|
|
2706
|
|
- columnCount = Math.max(columnCount, row.cells.length);
|
|
2707
|
|
- }
|
|
2708
|
|
- const rowCount = tableBlock.bodyRows.length;
|
|
2709
|
|
- const grid = new SpreadsheetGrid(columnCount, rowCount);
|
|
2710
|
|
- for (var c = 0; c < columnCount; c++) {
|
|
2711
|
|
- for (var r = 0; r < rowCount; r++) {
|
|
2712
|
|
- const cellBlock = tableBlock.bodyRows[r].cells[c];
|
|
2713
|
|
- if (cellBlock === undefined) continue;
|
|
2714
|
|
- const cell = grid.cells[c][r];
|
|
2715
|
|
- cell.block = cellBlock;
|
|
2716
|
|
- cell.originalValue = CellValue.fromCellString(cellBlock.content.toPlaintext(state));
|
|
2717
|
|
- }
|
|
2718
|
|
- }
|
|
2719
|
|
- return grid;
|
|
2720
|
|
- }
|
|
2721
|
2689
|
}
|
|
2722
|
2690
|
|
|
2723
|
2691
|
class SpreadsheetCell {
|
|
2724
|
2692
|
/**
|
|
2725
|
|
- * @type {MDTableCellBlock|null}
|
|
2726
|
|
- */
|
|
2727
|
|
- block = null;
|
|
2728
|
|
-
|
|
2729
|
|
- /**
|
|
2730
|
2693
|
* @type {CellValue}
|
|
2731
|
2694
|
*/
|
|
2732
|
2695
|
originalValue = CellValue.BLANK;
|
|
|
@@ -2746,18 +2709,6 @@ class SpreadsheetCell {
|
|
2746
|
2709
|
* @type {CellValue|null}
|
|
2747
|
2710
|
*/
|
|
2748
|
2711
|
get resolvedValue() { return this.outputValue ?? this.originalValue; }
|
|
2749
|
|
-
|
|
2750
|
|
- applyToBlock() {
|
|
2751
|
|
- if (this.block === null) return;
|
|
2752
|
|
- const resolvedValue = this.outputValue ?? this.originalValue;
|
|
2753
|
|
- const num = resolvedValue.numericValue;
|
|
2754
|
|
- if (num !== null) {
|
|
2755
|
|
- this.block.attributes['data-numeric-value'] = `${num}`;
|
|
2756
|
|
- }
|
|
2757
|
|
- if (this.outputValue === null) return;
|
|
2758
|
|
- this.block.content = new MDInlineBlock(new MDTextSpan(this.outputValue.formattedValue));
|
|
2759
|
|
- this.block.cssClasses.push('calculated', `type-${this.outputValue.type}`);
|
|
2760
|
|
- }
|
|
2761
|
2712
|
}
|
|
2762
|
2713
|
|
|
2763
|
2714
|
class SpreadsheetBlockReader extends MDBlockReader {
|
|
|
@@ -2768,7 +2719,7 @@ class SpreadsheetBlockReader extends MDBlockReader {
|
|
2768
|
2719
|
postProcess(state, blocks) {
|
|
2769
|
2720
|
for (const block of blocks) {
|
|
2770
|
2721
|
if (block instanceof MDTableBlock) {
|
|
2771
|
|
- this.#processTable(tableBlock, state);
|
|
|
2722
|
+ this.#processTable(block, state);
|
|
2772
|
2723
|
}
|
|
2773
|
2724
|
}
|
|
2774
|
2725
|
}
|
|
|
@@ -2778,7 +2729,66 @@ class SpreadsheetBlockReader extends MDBlockReader {
|
|
2778
|
2729
|
* @param {MDState} state
|
|
2779
|
2730
|
*/
|
|
2780
|
2731
|
#processTable(tableBlock, state) {
|
|
2781
|
|
- const grid = SpreadsheetGrid.fromTableBlock(tableBlock, state);
|
|
2782
|
|
- // TODO
|
|
|
2732
|
+ // Measure table
|
|
|
2733
|
+ const rowCount = tableBlock.bodyRows.length;
|
|
|
2734
|
+ var columnCount = 0;
|
|
|
2735
|
+ for (const row of tableBlock.bodyRows) {
|
|
|
2736
|
+ columnCount = Math.max(columnCount, row.cells.length);
|
|
|
2737
|
+ }
|
|
|
2738
|
+
|
|
|
2739
|
+ // Create and populate grid
|
|
|
2740
|
+ const grid = new SpreadsheetGrid(columnCount, rowCount);
|
|
|
2741
|
+ for (var c = 0; c < columnCount; c++) {
|
|
|
2742
|
+ for (var r = 0; r < rowCount; r++) {
|
|
|
2743
|
+ const cellBlock = tableBlock.bodyRows[r].cells[c];
|
|
|
2744
|
+ if (cellBlock === undefined) continue;
|
|
|
2745
|
+ const cellText = cellBlock.toPlaintext(state);
|
|
|
2746
|
+ const gridCell = grid.cells[c][r];
|
|
|
2747
|
+ gridCell.originalValue = CellValue.fromCellString(cellText);
|
|
|
2748
|
+ }
|
|
|
2749
|
+ }
|
|
|
2750
|
+
|
|
|
2751
|
+ // Calculate
|
|
|
2752
|
+ const expressions = new CellExpressionSet(grid);
|
|
|
2753
|
+ expressions.calculateCells();
|
|
|
2754
|
+
|
|
|
2755
|
+ // See if anything was calculated. If not, don't mess with table.
|
|
|
2756
|
+ var isCalculated = false;
|
|
|
2757
|
+ for (var c = 0; c < columnCount && !isCalculated; c++) {
|
|
|
2758
|
+ for (var r = 0; r < rowCount; r++) {
|
|
|
2759
|
+ if (grid.cells[c][r].isCalculated) {
|
|
|
2760
|
+ isCalculated = true;
|
|
|
2761
|
+ break;
|
|
|
2762
|
+ }
|
|
|
2763
|
+ }
|
|
|
2764
|
+ }
|
|
|
2765
|
+ if (!isCalculated) return;
|
|
|
2766
|
+
|
|
|
2767
|
+ // Copy results back to table
|
|
|
2768
|
+ for (var c = 0; c < columnCount; c++) {
|
|
|
2769
|
+ for (var r = 0; r < rowCount; r++) {
|
|
|
2770
|
+ const cellBlock = tableBlock.bodyRows[r].cells[c];
|
|
|
2771
|
+ if (cellBlock === undefined) continue;
|
|
|
2772
|
+ const gridCell = grid.cells[c][r];
|
|
|
2773
|
+ const gridValue = gridCell.outputValue;
|
|
|
2774
|
+ const cellText = gridValue.formattedValue;
|
|
|
2775
|
+ cellBlock.content = new MDInlineBlock(new MDTextSpan(cellText));
|
|
|
2776
|
+ if (gridCell.isCalculated) {
|
|
|
2777
|
+ cellBlock.cssClasses.push('calculated');
|
|
|
2778
|
+ }
|
|
|
2779
|
+ cellBlock.cssClasses.push(`spreadsheet-type-${gridValue.type}`);
|
|
|
2780
|
+ if (gridValue.type == CellValue.TYPE_ERROR) {
|
|
|
2781
|
+ cellBlock.attributes['title'] = gridValue.value;
|
|
|
2782
|
+ }
|
|
|
2783
|
+ const gridNumber = gridValue.numericValue();
|
|
|
2784
|
+ if (gridNumber !== null) {
|
|
|
2785
|
+ cellBlock.attributes['data-numeric-value'] = `${gridNumber}`;
|
|
|
2786
|
+ }
|
|
|
2787
|
+ const gridString = gridValue.stringValue(false);
|
|
|
2788
|
+ if (gridString !== null) {
|
|
|
2789
|
+ cellBlock.attributes['data-string-value'] = gridString;
|
|
|
2790
|
+ }
|
|
|
2791
|
+ }
|
|
|
2792
|
+ }
|
|
2783
|
2793
|
}
|
|
2784
|
2794
|
}
|