refactor: use CSV path instead of markdown file for spark tables
Switch the spark table resolution logic to use the direct path to the backing CSV file rather than attempting to parse the containing markdown file. This simplifies the lookup process and improves reliability. Also refactor `SparkTableMeta` to store rows as objects keyed by header instead of raw string arrays.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
import Slugger from "github-slugger";
|
||||
import { parseCSVString } from "../utils/csv-loader";
|
||||
import { rollFormula } from "../md-commander/hooks";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -41,8 +42,8 @@ export interface SparkTableMeta {
|
||||
slug: string;
|
||||
/** Data column headers (excluding dice column) */
|
||||
dataHeaders: string[];
|
||||
/** Full list of rows */
|
||||
rows: string[][];
|
||||
/** Full list of rows as objects keyed by header */
|
||||
rows: Record<string, string>[];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -141,7 +142,7 @@ export function findSparkTable(
|
||||
notation: table.headers[0],
|
||||
slug,
|
||||
dataHeaders: table.headers.slice(1),
|
||||
rows: table.rows,
|
||||
rows: rowsToObjects(table),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -169,13 +170,50 @@ export function findSparkTableByCombinedSlug(
|
||||
notation: table.headers[0],
|
||||
slug: colSlug,
|
||||
dataHeaders: table.headers.slice(1),
|
||||
rows: table.rows,
|
||||
rows: rowsToObjects(table),
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Convert a MarkdownTable's string[][] rows to Record<string, string>[] */
|
||||
function rowsToObjects(table: MarkdownTable): Record<string, string>[] {
|
||||
return table.rows.map((row) => {
|
||||
const obj: Record<string, string> = {};
|
||||
for (let i = 0; i < table.headers.length; i++) {
|
||||
obj[table.headers[i]] = row[i] ?? "";
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a CSV string into a SparkTableMeta.
|
||||
* The CSV must have a dice formula as its first column header.
|
||||
* Returns null if the CSV is not a valid spark table.
|
||||
*/
|
||||
export function parseSparkTableCsv(csv: string): SparkTableMeta | null {
|
||||
const parsed = parseCSVString(csv);
|
||||
const headers = Object.keys(parsed[0] ?? {});
|
||||
|
||||
if (headers.length < 2) return null;
|
||||
if (!DICE_HEADER_RE.test(headers[0])) return null;
|
||||
|
||||
const slugger = new Slugger();
|
||||
const dataHeaders = headers.slice(1);
|
||||
const slug = dataHeaders
|
||||
.map((h) => slugger.slug(h.toLowerCase()))
|
||||
.join("-");
|
||||
|
||||
return {
|
||||
notation: headers[0],
|
||||
slug,
|
||||
dataHeaders,
|
||||
rows: parsed as Record<string, string>[],
|
||||
};
|
||||
}
|
||||
|
||||
/** Scan all spark tables in a markdown file and return their metadata */
|
||||
export function scanSparkTables(
|
||||
markdown: string,
|
||||
@@ -237,8 +275,9 @@ export function rollSparkTable(meta: SparkTableMeta): SparkTableResult {
|
||||
const slugger = new Slugger();
|
||||
const columns: SparkTableColumn[] = [];
|
||||
|
||||
for (let colIdx = 0; colIdx < meta.dataHeaders.length; colIdx++) {
|
||||
const header = meta.dataHeaders[colIdx];
|
||||
const diceHeader = Object.keys(meta.rows[0] ?? {})[0] ?? "";
|
||||
|
||||
for (const header of meta.dataHeaders) {
|
||||
const slug = slugger.slug(header.toLowerCase());
|
||||
|
||||
const roll = rollFormula(meta.notation);
|
||||
@@ -247,9 +286,9 @@ export function rollSparkTable(meta: SparkTableMeta): SparkTableResult {
|
||||
// Find the row matching the rolled value
|
||||
let value = `(no row for ${rolledValue})`;
|
||||
for (const row of meta.rows) {
|
||||
const diceCell = row[0] ?? "";
|
||||
const diceCell = row[diceHeader] ?? "";
|
||||
if (matchesCell(diceCell, rolledValue)) {
|
||||
value = row[colIdx + 1] ?? "";
|
||||
value = row[header] ?? "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user