zesterer / ariadne

A fancy diagnostics & error reporting crate
https://crates.io/crates/ariadne
MIT License
1.74k stars 76 forks source link

Support HTML output #74

Open oovm opened 1 year ago

oovm commented 1 year ago

Is there any way to render output as html?

I want to render error report in jupyter, but if read stderr directly to it will look like this:

image

zesterer commented 1 year ago

There is currently no support for HTML output. Always happy to accept PRs though!

If you want something a little more sensible, you can run it through an ANSI escape sequence stripped like this and then just write it out as text with a monospace font.

oovm commented 1 year ago

I achieved the output html in my fork by changing the formatting here

https://github.com/zesterer/ariadne/blob/ccd465160129d2546d67f7ee78727a4098a64330/src/draw.rs#L199

write!(f, "<span style=\color: "{:x}\">{}</span>", col, Paint::new(&self.0).fg(col))

But the original stderr write can't be used, here should provide an injection mechanism.

And I feel that the Color function of yansi is not as rich as that of termcolor, maybe a generic can be added here?

oovm commented 1 year ago

I thought of a mechanism like this to support different output formats:

trait SpanFormatter {
    fn write_lhs(&self, w: impl Write) -> std::fmt::Result;
    fn write_rhs(&self, w: impl Write) -> std::fmt::Result;
}

impl SpanFormatter for Color {
    fn write_lhs(&self, w: impl Write) -> std::fmt::Result {
        // Write the ANSI escape code for this color.
        write!("\x1b[38;2;{};{};{}m", self.r, self.g, self.b)
    }

    fn write_rhs(&self, w: impl Write) -> std::fmt::Result {
        // recover the default colour
        write!(w, "\x1b[0m")
    }
}

impl SpanFormatter for HTML {
    fn write_lhs(&self, w: impl Write) -> std::fmt::Result {
        // Write the HTML span tag for this color.
        write!(w, "<span style=\"color: #{:x}\">", self.0)
    }

    fn write_rhs(&self, w: impl Write) -> std::fmt::Result {
        // recover the default colour
        write!(w, "</span>")
    }
}

One of the more complicated aspects of html is that it also needs to support escape

max-sixty commented 1 year ago

FWIW we've done this in PRQL with ansi_to_html: https://github.com/PRQL/prql/blob/ccb25f139bc7e5e990df49549a363c8f89623f59/web/book/src/lib.rs#L180