From d598004d7993dad0728a3a400304889e7ed84432 Mon Sep 17 00:00:00 2001 From: Neeldhara Misra Date: Mon, 29 Jun 2026 03:41:39 +0530 Subject: [PATCH] Sort data table resource numbers --- CONTENT_BRIDGE.md | 3 ++- docs/PARSER.md | 2 +- sites/art/src/remark/semantic-blocks.mjs | 20 ++++++++++++------- sites/poetry/src/remark/semantic-blocks.mjs | 20 ++++++++++++------- sites/puzzles/src/remark/semantic-blocks.mjs | 20 ++++++++++++------- .../src/remark/semantic-blocks.mjs | 20 ++++++++++++------- sites/research/src/remark/semantic-blocks.mjs | 20 ++++++++++++------- sites/reviews/src/remark/semantic-blocks.mjs | 20 ++++++++++++------- sites/vibes/src/remark/semantic-blocks.mjs | 20 ++++++++++++------- 9 files changed, 94 insertions(+), 51 deletions(-) diff --git a/CONTENT_BRIDGE.md b/CONTENT_BRIDGE.md index d150738..bf89930 100644 --- a/CONTENT_BRIDGE.md +++ b/CONTENT_BRIDGE.md @@ -286,7 +286,8 @@ The data file should contain either a top-level array or an object with an `items` array. The `src` path is resolved relative to the Markdown file. Use `columns` to control the visible columns, `headers` to rename table headers, `link` to choose the column that should link through the row's `link` field, -and `number` to prefix that linked column with a row number such as `slno`. +and `number` to prefix and sort that linked column by a row number such as +`slno`. In Obsidian this remains a readable code fence next to the data file. In Astro it becomes static HTML enhanced with local search and sort. In PDF it becomes a diff --git a/docs/PARSER.md b/docs/PARSER.md index b78ae17..4baef0c 100644 --- a/docs/PARSER.md +++ b/docs/PARSER.md @@ -344,7 +344,7 @@ Attributes: | `headers="key:Label,..."` | Optional | Human-readable labels for selected columns. | | `link="title"` | Optional | Column whose value links through the row's URL field. | | `url="link"` | Optional | URL field used by the linked column; defaults to `link`. | -| `number="slno"` | Optional | Prefix the linked column with a row number field. | +| `number="slno"` | Optional | Prefix and sort the linked column by a row number field. | | `caption="Resources"` | Optional | Visible toolbar title and accessible table caption. | | `search="false"` | Optional | Disable local table search; enabled by default. | | `sort="false"` | Optional | Disable sortable headers; enabled by default. | diff --git a/sites/art/src/remark/semantic-blocks.mjs b/sites/art/src/remark/semantic-blocks.mjs index a8afdbd..23809f1 100644 --- a/sites/art/src/remark/semantic-blocks.mjs +++ b/sites/art/src/remark/semantic-blocks.mjs @@ -220,19 +220,25 @@ function displayValue(value) { return VALUE_LABELS[value] || value; } +function numberLabel(row, field) { + if (!field) return ""; + const value = row[field]; + if (value === undefined || value === null || value === "") return ""; + return String(value).padStart(2, "0"); +} + function renderCell(row, column, options) { const raw = row[column] ?? ""; const display = displayValue(raw); - const sortValue = attribute(sortText(display)); + const numberPrefix = + column === options.linkColumn ? numberLabel(row, options.numberField) : ""; + const sortValue = attribute( + [numberPrefix, sortText(display)].filter(Boolean).join(" "), + ); const cellAttrs = `data-column="${attribute(column)}" data-sort-value="${sortValue}"`; if (column === options.linkColumn && row[options.urlField]) { - const numberValue = row[options.numberField]; - const numberLabel = - numberValue === undefined || numberValue === null || numberValue === "" - ? "" - : String(numberValue).padStart(2, "0"); - const prefix = options.numberField && numberLabel ? `${numberLabel}. ` : ""; + const prefix = numberPrefix ? `${numberPrefix}. ` : ""; return `${escapeHtml(prefix)}${inlineMarkup(display)}`; } diff --git a/sites/poetry/src/remark/semantic-blocks.mjs b/sites/poetry/src/remark/semantic-blocks.mjs index a8afdbd..23809f1 100644 --- a/sites/poetry/src/remark/semantic-blocks.mjs +++ b/sites/poetry/src/remark/semantic-blocks.mjs @@ -220,19 +220,25 @@ function displayValue(value) { return VALUE_LABELS[value] || value; } +function numberLabel(row, field) { + if (!field) return ""; + const value = row[field]; + if (value === undefined || value === null || value === "") return ""; + return String(value).padStart(2, "0"); +} + function renderCell(row, column, options) { const raw = row[column] ?? ""; const display = displayValue(raw); - const sortValue = attribute(sortText(display)); + const numberPrefix = + column === options.linkColumn ? numberLabel(row, options.numberField) : ""; + const sortValue = attribute( + [numberPrefix, sortText(display)].filter(Boolean).join(" "), + ); const cellAttrs = `data-column="${attribute(column)}" data-sort-value="${sortValue}"`; if (column === options.linkColumn && row[options.urlField]) { - const numberValue = row[options.numberField]; - const numberLabel = - numberValue === undefined || numberValue === null || numberValue === "" - ? "" - : String(numberValue).padStart(2, "0"); - const prefix = options.numberField && numberLabel ? `${numberLabel}. ` : ""; + const prefix = numberPrefix ? `${numberPrefix}. ` : ""; return `${escapeHtml(prefix)}${inlineMarkup(display)}`; } diff --git a/sites/puzzles/src/remark/semantic-blocks.mjs b/sites/puzzles/src/remark/semantic-blocks.mjs index a8afdbd..23809f1 100644 --- a/sites/puzzles/src/remark/semantic-blocks.mjs +++ b/sites/puzzles/src/remark/semantic-blocks.mjs @@ -220,19 +220,25 @@ function displayValue(value) { return VALUE_LABELS[value] || value; } +function numberLabel(row, field) { + if (!field) return ""; + const value = row[field]; + if (value === undefined || value === null || value === "") return ""; + return String(value).padStart(2, "0"); +} + function renderCell(row, column, options) { const raw = row[column] ?? ""; const display = displayValue(raw); - const sortValue = attribute(sortText(display)); + const numberPrefix = + column === options.linkColumn ? numberLabel(row, options.numberField) : ""; + const sortValue = attribute( + [numberPrefix, sortText(display)].filter(Boolean).join(" "), + ); const cellAttrs = `data-column="${attribute(column)}" data-sort-value="${sortValue}"`; if (column === options.linkColumn && row[options.urlField]) { - const numberValue = row[options.numberField]; - const numberLabel = - numberValue === undefined || numberValue === null || numberValue === "" - ? "" - : String(numberValue).padStart(2, "0"); - const prefix = options.numberField && numberLabel ? `${numberLabel}. ` : ""; + const prefix = numberPrefix ? `${numberPrefix}. ` : ""; return `${escapeHtml(prefix)}${inlineMarkup(display)}`; } diff --git a/sites/reflections/src/remark/semantic-blocks.mjs b/sites/reflections/src/remark/semantic-blocks.mjs index a8afdbd..23809f1 100644 --- a/sites/reflections/src/remark/semantic-blocks.mjs +++ b/sites/reflections/src/remark/semantic-blocks.mjs @@ -220,19 +220,25 @@ function displayValue(value) { return VALUE_LABELS[value] || value; } +function numberLabel(row, field) { + if (!field) return ""; + const value = row[field]; + if (value === undefined || value === null || value === "") return ""; + return String(value).padStart(2, "0"); +} + function renderCell(row, column, options) { const raw = row[column] ?? ""; const display = displayValue(raw); - const sortValue = attribute(sortText(display)); + const numberPrefix = + column === options.linkColumn ? numberLabel(row, options.numberField) : ""; + const sortValue = attribute( + [numberPrefix, sortText(display)].filter(Boolean).join(" "), + ); const cellAttrs = `data-column="${attribute(column)}" data-sort-value="${sortValue}"`; if (column === options.linkColumn && row[options.urlField]) { - const numberValue = row[options.numberField]; - const numberLabel = - numberValue === undefined || numberValue === null || numberValue === "" - ? "" - : String(numberValue).padStart(2, "0"); - const prefix = options.numberField && numberLabel ? `${numberLabel}. ` : ""; + const prefix = numberPrefix ? `${numberPrefix}. ` : ""; return `${escapeHtml(prefix)}${inlineMarkup(display)}`; } diff --git a/sites/research/src/remark/semantic-blocks.mjs b/sites/research/src/remark/semantic-blocks.mjs index a8afdbd..23809f1 100644 --- a/sites/research/src/remark/semantic-blocks.mjs +++ b/sites/research/src/remark/semantic-blocks.mjs @@ -220,19 +220,25 @@ function displayValue(value) { return VALUE_LABELS[value] || value; } +function numberLabel(row, field) { + if (!field) return ""; + const value = row[field]; + if (value === undefined || value === null || value === "") return ""; + return String(value).padStart(2, "0"); +} + function renderCell(row, column, options) { const raw = row[column] ?? ""; const display = displayValue(raw); - const sortValue = attribute(sortText(display)); + const numberPrefix = + column === options.linkColumn ? numberLabel(row, options.numberField) : ""; + const sortValue = attribute( + [numberPrefix, sortText(display)].filter(Boolean).join(" "), + ); const cellAttrs = `data-column="${attribute(column)}" data-sort-value="${sortValue}"`; if (column === options.linkColumn && row[options.urlField]) { - const numberValue = row[options.numberField]; - const numberLabel = - numberValue === undefined || numberValue === null || numberValue === "" - ? "" - : String(numberValue).padStart(2, "0"); - const prefix = options.numberField && numberLabel ? `${numberLabel}. ` : ""; + const prefix = numberPrefix ? `${numberPrefix}. ` : ""; return `${escapeHtml(prefix)}${inlineMarkup(display)}`; } diff --git a/sites/reviews/src/remark/semantic-blocks.mjs b/sites/reviews/src/remark/semantic-blocks.mjs index a8afdbd..23809f1 100644 --- a/sites/reviews/src/remark/semantic-blocks.mjs +++ b/sites/reviews/src/remark/semantic-blocks.mjs @@ -220,19 +220,25 @@ function displayValue(value) { return VALUE_LABELS[value] || value; } +function numberLabel(row, field) { + if (!field) return ""; + const value = row[field]; + if (value === undefined || value === null || value === "") return ""; + return String(value).padStart(2, "0"); +} + function renderCell(row, column, options) { const raw = row[column] ?? ""; const display = displayValue(raw); - const sortValue = attribute(sortText(display)); + const numberPrefix = + column === options.linkColumn ? numberLabel(row, options.numberField) : ""; + const sortValue = attribute( + [numberPrefix, sortText(display)].filter(Boolean).join(" "), + ); const cellAttrs = `data-column="${attribute(column)}" data-sort-value="${sortValue}"`; if (column === options.linkColumn && row[options.urlField]) { - const numberValue = row[options.numberField]; - const numberLabel = - numberValue === undefined || numberValue === null || numberValue === "" - ? "" - : String(numberValue).padStart(2, "0"); - const prefix = options.numberField && numberLabel ? `${numberLabel}. ` : ""; + const prefix = numberPrefix ? `${numberPrefix}. ` : ""; return `${escapeHtml(prefix)}${inlineMarkup(display)}`; } diff --git a/sites/vibes/src/remark/semantic-blocks.mjs b/sites/vibes/src/remark/semantic-blocks.mjs index a8afdbd..23809f1 100644 --- a/sites/vibes/src/remark/semantic-blocks.mjs +++ b/sites/vibes/src/remark/semantic-blocks.mjs @@ -220,19 +220,25 @@ function displayValue(value) { return VALUE_LABELS[value] || value; } +function numberLabel(row, field) { + if (!field) return ""; + const value = row[field]; + if (value === undefined || value === null || value === "") return ""; + return String(value).padStart(2, "0"); +} + function renderCell(row, column, options) { const raw = row[column] ?? ""; const display = displayValue(raw); - const sortValue = attribute(sortText(display)); + const numberPrefix = + column === options.linkColumn ? numberLabel(row, options.numberField) : ""; + const sortValue = attribute( + [numberPrefix, sortText(display)].filter(Boolean).join(" "), + ); const cellAttrs = `data-column="${attribute(column)}" data-sort-value="${sortValue}"`; if (column === options.linkColumn && row[options.urlField]) { - const numberValue = row[options.numberField]; - const numberLabel = - numberValue === undefined || numberValue === null || numberValue === "" - ? "" - : String(numberValue).padStart(2, "0"); - const prefix = options.numberField && numberLabel ? `${numberLabel}. ` : ""; + const prefix = numberPrefix ? `${numberPrefix}. ` : ""; return `${escapeHtml(prefix)}${inlineMarkup(display)}`; }