cell highlighting

This commit is contained in:
Ian Gulliver
2026-10-17 09:47:48 -07:00
parent e64200ac48
commit 3541abb1b1
7 changed files with 74 additions and 22 deletions
+17 -5
View File
@@ -245,7 +245,19 @@ function cells(line) {
}
function table(rows, opts) {
const [head, ...body] = rows;
return h("div", { class: "md-table" }, h("table", {}, h("thead", {}, h("tr", {}, ...head.map((c) => h("th", markClass(c), ...inline(c, opts))))), h("tbody", {}, ...body.map((r) => h("tr", {}, ...r.map((c) => h("td", markClass(c), ...inline(c, opts))))))));
return h("div", { class: "md-table" }, h("table", {}, h("thead", {}, h("tr", {}, ...head.map((c) => cell("th", c, opts)))), h("tbody", {}, ...body.map((r) => h("tr", {}, ...r.map((c) => cell("td", c, opts)))))));
}
function cell(tag, src, opts) {
const whole = markOf(src);
if (whole) {
return h(tag, { class: `md-mark-cell ${whole}` }, ...inline(src, opts));
}
const [, lead = "", rest = ""] = /^\s*(\S*)(.*)$/s.exec(src);
const mark = markOf(lead);
if (!mark) {
return h(tag, {}, ...spans(src, opts));
}
return h(tag, { class: `md-mark-cell ${mark}` }, h("span", { class: `md-mark ${mark}` }, ...spans(lead, opts)), ...spans(rest, opts));
}
const marks = {
"✓": "ok",
@@ -269,14 +281,14 @@ const marks = {
"✖": "danger",
"✖️": "danger",
"❌": "danger",
"-": "none",
"–": "none",
"—": "none",
"−": "none",
};
function markOf(src) {
return marks[src.trim().replace(/^(\*\*|__)(.*)\1$/, "$2").trim()];
}
function markClass(cell) {
const mark = markOf(cell);
return mark ? { class: `md-mark ${mark}` } : {};
}
const inlineToken = /`([^`]+)`|\*\*(.+?)\*\*|__(.+?)__|\*([^*\s][^*]*?)\*|(?<![\w])_([^_\s][^_]*?)_(?![\w])|!\[([^\]]*)\]\((?:<([^>]+)>|([^)]+))\)|\[([^\]]+)\]\(([^)\s]+)\)|(https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"])/;
function inline(src, opts) {
const mark = markOf(src);
+1 -1
View File
File diff suppressed because one or more lines are too long
+19 -7
View File
@@ -283,12 +283,25 @@ function table(rows: string[][], opts: Options): HTMLElement {
h(
"table",
{},
h("thead", {}, h("tr", {}, ...head!.map((c) => h("th", markClass(c), ...inline(c, opts))))),
h("tbody", {}, ...body.map((r) => h("tr", {}, ...r.map((c) => h("td", markClass(c), ...inline(c, opts)))))),
h("thead", {}, h("tr", {}, ...head!.map((c) => cell("th", c, opts)))),
h("tbody", {}, ...body.map((r) => h("tr", {}, ...r.map((c) => cell("td", c, opts))))),
),
);
}
function cell(tag: "th" | "td", src: string, opts: Options): HTMLElement {
const whole = markOf(src);
if (whole) {
return h(tag, { class: `md-mark-cell ${whole}` }, ...inline(src, opts));
}
const [, lead = "", rest = ""] = /^\s*(\S*)(.*)$/s.exec(src)!;
const mark = markOf(lead);
if (!mark) {
return h(tag, {}, ...spans(src, opts));
}
return h(tag, { class: `md-mark-cell ${mark}` }, h("span", { class: `md-mark ${mark}` }, ...spans(lead, opts)), ...spans(rest, opts));
}
const marks: Record<string, string> = {
"✓": "ok",
"✔": "ok",
@@ -311,17 +324,16 @@ const marks: Record<string, string> = {
"✖": "danger",
"✖️": "danger",
"❌": "danger",
"-": "none",
"–": "none",
"—": "none",
"−": "none",
};
function markOf(src: string): string | undefined {
return marks[src.trim().replace(/^(\*\*|__)(.*)\1$/, "$2").trim()];
}
function markClass(cell: string): { class?: string } {
const mark = markOf(cell);
return mark ? { class: `md-mark ${mark}` } : {};
}
const inlineToken =
/`([^`]+)`|\*\*(.+?)\*\*|__(.+?)__|\*([^*\s][^*]*?)\*|(?<![\w])_([^_\s][^_]*?)_(?![\w])|!\[([^\]]*)\]\((?:<([^>]+)>|([^)]+))\)|\[([^\]]+)\]\(([^)\s]+)\)|(https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"])/;
+11 -3
View File
@@ -862,18 +862,26 @@ button.compact.danger {
color: var(--danger);
}
.md .md-mark.ok:is(td, th) {
.md-mark.none {
color: var(--muted);
}
.md .md-mark-cell.ok {
background: var(--ok-tint);
}
.md .md-mark.warn:is(td, th) {
.md .md-mark-cell.warn {
background: var(--warn-tint);
}
.md .md-mark.danger:is(td, th) {
.md .md-mark-cell.danger {
background: var(--danger-tint);
}
.md .md-mark-cell.none {
background: var(--surface);
}
.msg.user {
align-self: flex-end;
max-width: 85%;