Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support colour output in stdout for jupyter and julia engines #12132

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

MichaelHatherly
Copy link
Contributor

@MichaelHatherly MichaelHatherly commented Feb 21, 2025

Description

This adds support for printing colour output from stdout and stderr in the jupyter and julia backends. Only applies to HTML output.

Fixes #12117.

Checklist

I have (if applicable):

  • filed a contributor agreement.
  • referenced the GitHub issue this PR closes
  • updated the appropriate changelog in the PR
  • ensured the present test suite passes
  • added new tests
  • created a separate documentation PR in Quarto's website repo and linked it to this PR

@MichaelHatherly
Copy link
Contributor Author

Still to add some tests and update the changelog. I'll do that once I've familiarised myself with https://github.com/quarto-dev/quarto-cli/blob/main/tests/README.md

@cscheid
Copy link
Collaborator

cscheid commented Feb 21, 2025

@MichaelHatherly The easiest way to add tests is, by far, to use the _quarto: tests: key. Here's an example:

---
format: html
_quarto:
  tests:
    html:
      ensureFileRegexMatches:
        - ["Nunc ac dignissim magna. Vestibulum vitae egestas elit."]
---

{{< lipsum 2 >}}

In our test suite, every document inside tests/docs/smoke-all is rendered and tested using the _quarto: tests: functionality.

For the example above, the behavior is very simple: it's asking for the HTML format output to respect a given regex.

Checking in a document with this syntax is enough for our test suite to run it, but during development there is a more convenient option. If you're running a dev build of quarto, you should have a ./tests/run-fast-tests.sh script. This script takes .qmd files as parameters and runs them in the test suite infrastructure. As a minimal test, you could do something like the following:

$ cd tests/docs/smoke-all
$ cat > this-test-will-fail.qmd
---
format: html
_quarto:
  tests:
    html:
      ensureFileRegexMatches:
        - []
        - ["Forbidden"]
---

Forbidden
^D
$ cd ../..
$ ./run-fast-tests.sh ./docs/smoke-all/this-test-will-fail.qmd
docs/smoke-all/this-test-will-fail.qmd
running 1 test from ./smoke/smoke-all.test.ts
[smoke] > quarto render docs/smoke-all/this-test-will-fail.qmd --to html ...
------- output -------
[verify] > Inspecting docs/smoke-all/this-test-will-fail.html for Regex matches
----- output end -----
[smoke] > quarto render docs/smoke-all/this-test-will-fail.qmd --to html ... FAILED (3s)

 ERRORS

[smoke] > quarto render docs/smoke-all/this-test-will-fail.qmd --to html => ./test.ts:329:8
error: AssertionError: Failed assertion:

--------------------------------------------------------------------------------
[smoke] > quarto render docs/smoke-all/this-test-will-fail.qmd --to html
          ./run-tests.sh smoke/smoke-all.test.ts

[verify] > Inspecting docs/smoke-all/this-test-will-fail.html for Regex matches

Illegal match /Forbidden/m was found in file docs/smoke-all/this-test-will-fail.html.
AssertionError: Illegal match /Forbidden/m was found in file docs/smoke-all/this-test-will-fail.html.
    at Module.assert (https://jsr.io/@std/assert/0.224.0/assert.ts:18:11)
    at assert (https://jsr.io/@std/testing/0.224.0/asserts.ts:608:11)
    at file:///Users/cscheid/repos/github/quarto-dev/quarto-cli/tests/verify.ts:389:7
    at Array.forEach (<anonymous>)
    at regexChecker (file:///Users/cscheid/repos/github/quarto-dev/quarto-cli/tests/verify.ts:388:15)
    at eventLoopTick (ext:core/01_core.js:175:7)
    at async Object.verify (file:///Users/cscheid/repos/github/quarto-dev/quarto-cli/tests/verify.ts:416:9)
    at async fn (file:///Users/cscheid/repos/github/quarto-dev/quarto-cli/tests/test.ts:240:15)
    at async innerWrapped (ext:cli/40_test.js:191:5)
    at async outerWrapped (ext:cli/40_test.js:134:14)

OUTPUT:
    pandoc
    to: html
    output-file: this-test-will-fail.html
    standalone: true
    section-divs: true
    html-math-method: mathjax
    wrap: none
    default-image-extension: png
    variables: {}

    metadata
    document-css: false
    link-citations: true
    date-format: long
    lang: en

    Output created: this-test-will-fail.html

    throw new AssertionError(msg);
          ^
    at assert (https://jsr.io/@std/assert/0.224.0/assert.ts:18:11)
    at Module.fail (https://jsr.io/@std/assert/0.224.0/fail.ts:17:3)
    at fail (https://jsr.io/@std/testing/0.224.0/asserts.ts:663:11)
    at fn (file:///Users/cscheid/repos/github/quarto-dev/quarto-cli/tests/test.ts:303:11)

 FAILURES

[smoke] > quarto render docs/smoke-all/this-test-will-fail.qmd --to html => ./test.ts:329:8

FAILED | 0 passed | 1 failed (3s)

error: Test failed

In this test, we're asking the test suite to fail if the Forbidden regex is matched.

Some example checkers:

  • ensureFileRegexMatches: works in every format (but is tricky for binary formats, see below)
  • html has ensureHtmlElements which takes CSS selector lists
  • docx:
    • ensureDocxRegexMatches: extracts the content XML from the binary output and then runs a regex check
    • ensureDocxXPath: extracts the XML from the docx format and then checks for the XPath selector

The full suite isn't document but is at tests/verify.ts.

@MichaelHatherly
Copy link
Contributor Author

Thank you for those details @cscheid, very helpful!

@MichaelHatherly MichaelHatherly marked this pull request as ready for review February 21, 2025 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Colour console output stripped from both Julia backends
2 participants