style: improve markdown rendering output formatting
- Use terminal-link for clickable hyperlinks - Reduce heading color brightness - Remove extra trailing newlines from code blocks - Fix horizontal rule spacing - Wrap codespan content in backticks - Suppress language error warnings from highlighter
This commit is contained in:
parent
c0ab652135
commit
0727c5ebec
4 changed files with 32 additions and 14 deletions
15
bun.lock
15
bun.lock
|
|
@ -11,6 +11,7 @@
|
|||
"chalk": "^5.6.2",
|
||||
"cli-highlight": "^2.1.11",
|
||||
"cli-table3": "^0.6.5",
|
||||
"terminal-link": "^5.0.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.4.12",
|
||||
|
|
@ -62,6 +63,8 @@
|
|||
|
||||
"ai": ["ai@6.0.161", "", { "dependencies": { "@ai-sdk/gateway": "3.0.98", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ufhmijmx2YyWTPAicGgtpLOB/xD7mG8zKs1pT1Trj+JL/3r1rS8fkMi/cHZoChSAQSGB4pgmcWVxDrVTUvK2IQ=="],
|
||||
|
||||
"ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="],
|
||||
|
||||
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||
|
|
@ -84,13 +87,15 @@
|
|||
|
||||
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
"environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
|
||||
|
||||
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
||||
|
||||
"eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="],
|
||||
|
||||
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
||||
|
||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
"has-flag": ["has-flag@5.0.1", "", {}, "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA=="],
|
||||
|
||||
"highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="],
|
||||
|
||||
|
|
@ -114,6 +119,10 @@
|
|||
|
||||
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
||||
"supports-hyperlinks": ["supports-hyperlinks@4.4.0", "", { "dependencies": { "has-flag": "^5.0.1", "supports-color": "^10.2.2" } }, "sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg=="],
|
||||
|
||||
"terminal-link": ["terminal-link@5.0.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "supports-hyperlinks": "^4.1.0" } }, "sha512-qFAy10MTMwjzjU8U16YS4YoZD+NQLHzLssFMNqgravjbvIPNiqkGFR4yjhJfmY9R5OFU7+yHxc6y+uGHkKwLRA=="],
|
||||
|
||||
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
|
||||
|
||||
"thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
|
||||
|
|
@ -136,6 +145,10 @@
|
|||
|
||||
"parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="],
|
||||
|
||||
"supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"supports-hyperlinks/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="],
|
||||
|
||||
"wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"cli-highlight/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
"ansi-styles": "^6.2.3",
|
||||
"chalk": "^5.6.2",
|
||||
"cli-highlight": "^2.1.11",
|
||||
"cli-table3": "^0.6.5"
|
||||
"cli-table3": "^0.6.5",
|
||||
"terminal-link": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ export default class Renderer {
|
|||
|
||||
const [columns] = pipe.getWindowSize();
|
||||
const rendered = await renderMarkdown(str, columns);
|
||||
pipe.write(rendered);
|
||||
pipe.write(rendered.replace(/\n\n$/, "\n"));
|
||||
}
|
||||
|
||||
async renderStream(stream: AsyncIterableStream<TextStreamPart<ToolSet>>) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
import chalk from "chalk";
|
||||
import { highlight } from "cli-highlight";
|
||||
import CliTable3 from "cli-table3";
|
||||
import terminalLink from "terminal-link";
|
||||
|
||||
const originalErr = console.error;
|
||||
console.error = (...data: unknown[]) => {
|
||||
if (data.join("").includes("Could not find the language")) return;
|
||||
originalErr(...data);
|
||||
};
|
||||
|
||||
export async function renderMarkdown(
|
||||
text: PromiseLike<string> | string,
|
||||
|
|
@ -13,12 +20,12 @@ export async function renderMarkdown(
|
|||
return Bun.markdown.render(md, {
|
||||
heading: (children, { level }) => {
|
||||
const colors = [
|
||||
chalk.cyanBright.underline,
|
||||
chalk.blueBright,
|
||||
chalk.greenBright,
|
||||
chalk.cyan,
|
||||
chalk.cyan.underline,
|
||||
chalk.blue,
|
||||
chalk.green,
|
||||
chalk.cyanBright,
|
||||
chalk.blueBright,
|
||||
chalk.greenBright,
|
||||
];
|
||||
const color = colors[level - 1] ?? chalk.white;
|
||||
return color.bold(`${"#".repeat(level)} ${children}\n\n`);
|
||||
|
|
@ -44,7 +51,7 @@ export async function renderMarkdown(
|
|||
} catch {}
|
||||
}
|
||||
|
||||
return `\`\`\`${chalk.green(meta?.language)}\n${toRender}\n\`\`\`\n`;
|
||||
return `\`\`\`${chalk.green(meta?.language)}\n${toRender}\n\`\`\``;
|
||||
},
|
||||
list: (children, { depth }) =>
|
||||
`${depth > 0 ? "\n" : ""}${children}${depth === 0 ? "\n" : ""}`,
|
||||
|
|
@ -61,15 +68,12 @@ export async function renderMarkdown(
|
|||
}
|
||||
return `${indent}${marker} ${children}\n`;
|
||||
},
|
||||
hr: () => `\n${chalk.dim("─".repeat(columns))}\n`,
|
||||
hr: () => `${chalk.dim("─".repeat(columns))}\n\n`,
|
||||
table: (_children) => {
|
||||
const toRender = currentTable.toString();
|
||||
currentTable = new CliTable3();
|
||||
return `${toRender}\n\n`;
|
||||
},
|
||||
thead: () => {
|
||||
return "";
|
||||
},
|
||||
tr: (children) => {
|
||||
if (children) currentTable.push(children.split("|").slice(1));
|
||||
return "";
|
||||
|
|
@ -82,9 +86,9 @@ export async function renderMarkdown(
|
|||
strong: (children) => chalk.bold(children),
|
||||
emphasis: (children) => chalk.italic(children),
|
||||
strikethrough: (children) => chalk.grey.strikethrough(children),
|
||||
codespan: (children) => chalk.bgWhite.black(children),
|
||||
codespan: (children) => chalk.bgWhite.black(`\`${children}\``),
|
||||
link: (children, { href }) =>
|
||||
chalk.blueBright(`${children}: ${chalk.underline(href)}`),
|
||||
chalk.blueBright.underline(terminalLink(children, href)),
|
||||
image: () => "",
|
||||
text: (children) => children,
|
||||
html: () => "",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue