diff --git a/src/core/jupyter/jupyter.ts b/src/core/jupyter/jupyter.ts index 1d8349d76df..8edbc5517d3 100644 --- a/src/core/jupyter/jupyter.ts +++ b/src/core/jupyter/jupyter.ts @@ -506,7 +506,7 @@ export async function jupyterKernelspecFromMarkdown( }).`, ), ); - } else if (typeof (yamlJupyter) === "string") { + } else if (typeof yamlJupyter === "string") { const kernel = yamlJupyter; const kernelspec = await jupyterKernelspec(kernel); if (kernelspec) { @@ -521,7 +521,7 @@ export async function jupyterKernelspecFromMarkdown( ), ); } - } else if (typeof (yamlJupyter) === "object") { + } else if (typeof yamlJupyter === "object") { const jupyter = { ...yamlJupyter } as Record; if (isJupyterKernelspec(jupyter.kernelspec)) { const kernelspec = jupyter.kernelspec; @@ -1345,7 +1345,7 @@ async function mdFromCodeCell( // deno-lint-ignore no-explicit-any let value = (cellOptions as any)[key]; if (value !== undefined) { - if (typeof (value) !== "string") { + if (typeof value !== "string") { value = JSON.stringify(value); } value = value.replaceAll("'", `\\'`); @@ -1567,7 +1567,7 @@ async function mdFromCodeCell( md.push(mdOutputStream(stream)); } } else if (output.output_type === "error") { - md.push(mdOutputError(output as JupyterOutputError)); + md.push(await mdOutputError(output as JupyterOutputError, options)); } else if (isDisplayData(output)) { const fixedOutput = cleanJupyterOutputDisplayData(output); if (Object.keys(fixedOutput.data).length > 0) { @@ -1719,8 +1719,22 @@ function mdOutputStream(output: JupyterOutputStream) { return mdCodeOutput(output.text.map(colors.stripColor)); } -function mdOutputError(output: JupyterOutputError) { - return mdCodeOutput([output.ename + ": " + output.evalue]); +async function mdOutputError( + output: JupyterOutputError, + options: JupyterToMarkdownOptions, +) { + if (!options.toHtml || !hasAnsiEscapeCodes(output.evalue)) { + return mdCodeOutput([output.ename + ": " + output.evalue]); + } + const html = await convertToHtmlSpans(output.evalue); + console.log(output.evalue); + return mdMarkdownOutput( + [ + "\n::: {.ansi-escaped-output}\n```{=html}\n
",
+      html,
+      "
\n```\n:::\n", + ], + ); } async function mdOutputDisplayData( diff --git a/src/resources/formats/html/_quarto-rules.scss b/src/resources/formats/html/_quarto-rules.scss index 8dc4b921411..65d0ba3b236 100644 --- a/src/resources/formats/html/_quarto-rules.scss +++ b/src/resources/formats/html/_quarto-rules.scss @@ -443,6 +443,9 @@ div.ansi-escaped-output { * * ansi colors from IPython notebook's * +* we also add `bright-[color]-` synonyms for the `-[color]-intense` classes since +* that seems to be what ansi_up emits +* */ /* CSS font colors for translated ANSI escape sequences */ /* The color values are a mix of @@ -454,10 +457,12 @@ div.ansi-escaped-output { .ansi-black-bg { background-color: #3e424d; } -.ansi-black-intense-fg { +.ansi-black-intense-black, +.ansi-bright-black-fg { color: #282c36; } -.ansi-black-intense-bg { +.ansi-black-intense-black, +.ansi-bright-black-bg { background-color: #282c36; } .ansi-red-fg { @@ -466,10 +471,12 @@ div.ansi-escaped-output { .ansi-red-bg { background-color: #e75c58; } -.ansi-red-intense-fg { +.ansi-red-intense-red, +.ansi-bright-red-fg { color: #b22b31; } -.ansi-red-intense-bg { +.ansi-red-intense-red, +.ansi-bright-red-bg { background-color: #b22b31; } .ansi-green-fg { @@ -478,10 +485,12 @@ div.ansi-escaped-output { .ansi-green-bg { background-color: #00a250; } -.ansi-green-intense-fg { +.ansi-green-intense-green, +.ansi-bright-green-fg { color: #007427; } -.ansi-green-intense-bg { +.ansi-green-intense-green, +.ansi-bright-green-bg { background-color: #007427; } .ansi-yellow-fg { @@ -490,10 +499,12 @@ div.ansi-escaped-output { .ansi-yellow-bg { background-color: #ddb62b; } -.ansi-yellow-intense-fg { +.ansi-yellow-intense-yellow, +.ansi-bright-yellow-fg { color: #b27d12; } -.ansi-yellow-intense-bg { +.ansi-yellow-intense-yellow, +.ansi-bright-yellow-bg { background-color: #b27d12; } .ansi-blue-fg { @@ -502,10 +513,12 @@ div.ansi-escaped-output { .ansi-blue-bg { background-color: #208ffb; } -.ansi-blue-intense-fg { +.ansi-blue-intense-blue, +.ansi-bright-blue-fg { color: #0065ca; } -.ansi-blue-intense-bg { +.ansi-blue-intense-blue, +.ansi-bright-blue-bg { background-color: #0065ca; } .ansi-magenta-fg { @@ -514,10 +527,12 @@ div.ansi-escaped-output { .ansi-magenta-bg { background-color: #d160c4; } -.ansi-magenta-intense-fg { +.ansi-magenta-intense-magenta, +.ansi-bright-magenta-fg { color: #a03196; } -.ansi-magenta-intense-bg { +.ansi-magenta-intense-magenta, +.ansi-bright-magenta-bg { background-color: #a03196; } .ansi-cyan-fg { @@ -526,10 +541,12 @@ div.ansi-escaped-output { .ansi-cyan-bg { background-color: #60c6c8; } -.ansi-cyan-intense-fg { +.ansi-cyan-intense-cyan, +.ansi-bright-cyan-fg { color: #258f8f; } -.ansi-cyan-intense-bg { +.ansi-cyan-intense-cyan, +.ansi-bright-cyan-bg { background-color: #258f8f; } .ansi-white-fg { @@ -538,10 +555,12 @@ div.ansi-escaped-output { .ansi-white-bg { background-color: #c5c1b4; } -.ansi-white-intense-fg { +.ansi-white-intense-white, +.ansi-bright-white-fg { color: #a1a6b2; } -.ansi-white-intense-bg { +.ansi-white-intense-white, +.ansi-bright-white-bg { background-color: #a1a6b2; } .ansi-default-inverse-fg {