The filters `|linebreaks`, `|linebreaksbr` and `|paragraphbreaks`
generate HTML code to be embedded in a page. Having to specify that the
output of these filters is `|safe` is cumbersome. Also, these filters
need to operate on already escaped HTML data. This could be done by
writing `{{ s|escape|linebreaks|safe }}`.
This PR does the input and output formatting escaping for the user. The
input gets escaped for HTML (invariant of the selected escaper), and the
output gets marked as HTML safe.
This PR reimplements the code generation for `{% filter %}` blocks, so
that the data is written directly into its destination writer, without
using a buffer. This way it behaves like a specialized
`{{ expr|filter1|filter2 }}` would, if the `expr` was a `Template` that
contained the body of the filter block.
`quick_cache` is the wrong tool for this job. It want to evict items
after a time, which must not happen. It has too many options and
features we don't need.
Less searching for an explanation.
I also restructured the text to use sections instead of bullet points.
And lastly I made `rinja_derive_standalone` export `derive_template`,
too, instead of `derive_template2`. This way we have less macro-magic.
This PR adds an `HtmlSafeMarker` trait. Types that implement this marker
are know to never generate strings containing the characters `< > & " '`,
so they don't have to be escaped.
All glory goes to \@dtolnay's ["Autoref-based stable specialization"][1]
case study / blog entry.
[1]: <0a9f083f33/autoref-specialization/README.md>
This PR configures the formatting with a few defaults that aid
readability, in my opinion. One drawback of adding this file is that
rustfmt uses unstable features, now, and you have to use nightly to run
it:
```sh
cargo +nightly fmt --all
```
This PR adds an optional argument to the `|tojson` filter, which
controls if the serialized JSON data gets prettified or not. The
arguments works the same as flask's [`|tojson`][flask] filter, which
passes the argument to python's [`json.dumps()`][python]:
* Omitting the argument, providing a negative integer, or `None`, then
compact JSON data is generated.
* Providing a non-negative integer, then this amount of ASCII spaces is
used to indent the data. (Capped to 16 characters.)
* Providing a string, then this string is used as prefix. I attempts are
made to ensure that the prefix actually consists of whitespaces,
because chances are, that if you provide e.g. `&nsbp;`, then you are
doing it intentionally.
This is a breaking change, because it changes the default behavior to
not prettify the data. This is done intentionally, because this is how
it works in flask.
[flask]: https://jinja.palletsprojects.com/en/3.1.x/templates/#jinja-filters.tojson
[python]: https://docs.python.org/3/library/json.html#json.dump
This PR adds the crate "rinja_derive_standalone", which is just like
"rinja_derive", though not a "proc_macro". This way we can easily expose
it's internals for testing and benchmarking.
Right now, the PR is more or less a prove of concept, and it probably
needs a handful more useful benchmark use cases to be worth the hassle.
`std::fmt::Error` does not know why it failed, only that it failed, as
it has a single value. This PR removes the captured value, to make the
code a bit more dense.