lambda-fairy / maud

:pencil: Compile-time HTML templates for Rust
https://maud.lambda.xyz
Apache License 2.0
2.14k stars 143 forks source link

FR: Indentation #434

Open abhillman opened 3 months ago

abhillman commented 3 months ago

I am using maude to generate specific HTML for a collection of structs. Thus, when writing tests, it is handy to be able to assert that some HTML has been emitted. Without indentation, the output can be difficult to read. Moreover, html-tidy (see below for an example of using it) can significantly modify HTML in an opinionated manner.

FWIW, here is an example of how to shell-out to html-tidy (tidy-sys is also a good option):

struct Tidy;

impl Tidy {
    fn tidy(html: String) -> String {
        let mut result = std::process::Command::new("tidy")
            .arg("--indent")
            .arg("auto")
            .arg("--quiet")
            .arg("yes")
            .arg("--show-body-only")
            .arg("auto")
            .arg("--show-errors")
            .arg("0")
            .arg("--wrap")
            .arg("0")
            .stderr(Stdio::piped())
            .stdin(Stdio::piped())
            .stdout(Stdio::piped())
            .spawn()
            .unwrap();

        let stdin = result.stdin.as_mut().unwrap();
        stdin.write_all(html.as_ref()).unwrap();

        let output = result.wait_with_output().unwrap();
        let err = String::from_utf8(output.stderr).unwrap();
        if !err.is_empty() {
            panic!("{}", err);
        }

        String::from_utf8(output.stdout).unwrap()
    }
}

The problem is that with maude, I get the following (which I like, despite readability issues):

<pre><style>
                        table, th, td {
                          border: 1px solid;
                        }
                    </style><table><tbody><tr><td><p>1</p></td></tr><tr><td><p>2</p></td></tr><tr><td><p>3</p></td></tr></tbody></table></pre>

With html-tidy, I get the following, which drops my pre tag (it will do a lot of other stuff with other HTML snippets, too).

<table>
  <tbody>
    <tr>
      <td>
        <p>1</p>
      </td>
    </tr>
    <tr>
      <td>
        <p>2</p>
      </td>
    </tr>
    <tr>
      <td>
        <p>3</p>
      </td>
    </tr>
  </tbody>
</table>

In this case, is html-tidy technically correct? Almost certainly yes -- it is probably standards-compliant to use CSS as opposed to wrapping a table in a pre to get it to look the way I like it. Reading tidy's man page, I don't think I see any additional options to disable various modifications of HTML. That said for the purposes of rapid iteration (let alone testing), it is nice to be able to just use maude.

If out of scope, no huge deal, I can write a quick couple lines of code to do quick-and-dirty indentation. But doing it in maude itself would be more robust (i.e. just adding spaces when iterating over declared tags as opposed to parsing).

Related issues: