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

User-defined escaping #136

Closed
lukehsiao opened this issue Oct 21, 2018 · 8 comments
Closed

User-defined escaping #136

lukehsiao opened this issue Oct 21, 2018 · 8 comments

Comments

@lukehsiao
Copy link

Feature Request:
Would it be possible to allow users the ability to define a custom escape mapping in the askama.toml, similar to how a user can define a custom syntax?

I'm not entirely sure what this would look like so this issue is just a place to discuss the idea.

@djc
Copy link
Owner

djc commented Oct 21, 2018

I think something like that could work. I think there are a few different things to be considered -- like how we make this sufficiently general to be usable for a number of different things. Can you say more about your exact use case and what it needs? Your request seems to imply that you'd be okay just triggering on the same characters that are currenly escaped in html mode, but you want to perform a different substitution?

On the other hand, the current architecture/interface is sort of built on the notion that different file types need different escaping modes, so that seems the most clean way to plug in. We might be able to rearrange the current HTML escaping code so that it's easier to plug in a different mapping, though.

@lukehsiao
Copy link
Author

I believe it should be more general that just triggering on the same characters that are currently escaped in html.

On the other hand, the current architecture/interface is sort of built on the notion that different file types need different escaping modes, so that seems the most clean way to plug in.

This is the idea I think is important. Almost all the templating engines (especially for Rust) mainly look at HTML templates. It would be great to be able to use askama for more general applications. For example, the project I'm looking at right now is templating markdown and LaTeX. In the LaTeX case, I might want to escape special latex characters (e.g. & to \& or $ to \$, but not escape these when outputting the same strings to the markdown template. It would be nice to have some way of defining this mapping, and being able to give it a specific name like we can do with the syntaxes.

@djc
Copy link
Owner

djc commented Oct 21, 2018

In that case I think there is a relatively straightforward solution. I propose that we indeed define another table structure in the configuration, which could look something like this:

[escape.latex]
filter = "latex_mod::escape"
extensions = ["tex"]

This will enable the latex escape mode automatically for extensions with the extension tex (it is an error to create escape modes with overlapping extensions or to define escape modes with names that conflict with the built-in html escape mode). Askama will call the named function when content needs to be escaped (that is, when AsRef<str>-type content is injected into the template output); it is on the template author to make sure that the escape function or module is in scope of template context types.

Does that sound right? And if so, are you willing to work on an implementation?

@djc
Copy link
Owner

djc commented Dec 12, 2018

This is probably nice-to-have for 0.8, and might not make it.

@zzau13
Copy link
Contributor

zzau13 commented Dec 17, 2018

We can use https://doc.rust-lang.org/cargo/reference/build-scripts.html#case-study-code-generation for generate fn escape and include in askama_escape/src/lib.rs. To generate this function, I have built this macros new_escape

new_escape!(
    HTMLEscape,
    "60->&lt; || 62->&gt; || 38->&amp; || 34->&quot; || 39->&#x27; || 47->&#x2f;"
);

Than through the syntax "$u8->$quote" generate the Escaped structure with any pair.

You can write from askama.toml and have the most common, (latex, html, etc,) saved.

That is to say,

  • generate from the build.rs and askama.toml the escape function in env!("OUT_DIR"), "/escape_function.rs"
  • add in askama_escape/src/lib.rs next line
include!(concat!(env!("OUT_DIR"), "/escape_function.rs"));
  • remove old escape function

How about?

@zzau13
Copy link
Contributor

zzau13 commented Dec 22, 2018

About the options that you told me, rocket included, I attached the benches report with the comparison with the current one, rocket and v_escape.

So it would, be logical, on the configuration table adding the options to create the escape function using v_escape.

Benches

v_escape

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L991

v_escape/Escaping/small time:   [395.13 ns 397.83 ns 401.16 ns]
                        thrpt:  [1.5415 GiB/s 1.5544 GiB/s 1.5651 GiB/s]

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L1052

v_escape/Escaping/ultra tiny
                        time:   [50.812 ns 51.448 ns 52.044 ns]
                        thrpt:  [128.27 MiB/s 129.76 MiB/s 131.38 MiB/s]

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L1074

v_escape/Escaping/one   time:   [37.131 ns 37.260 ns 37.394 ns]
                        thrpt:  [25.504 MiB/s 25.595 MiB/s 25.684 MiB/s]

askama_escape

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L851

askama_escape/Escaping/small
                        time:   [1.1377 us 1.1452 us 1.1520 us]
                        thrpt:  [549.67 MiB/s 552.94 MiB/s 556.60 MiB/s]

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L913

askama_escape/Escaping/ultra tiny
                        time:   [50.324 ns 50.951 ns 51.548 ns]
                        thrpt:  [129.51 MiB/s 131.02 MiB/s 132.65 MiB/s]

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L935

askama_escape/Escaping/one
                        time:   [36.697 ns 36.800 ns 36.914 ns]
                        thrpt:  [25.835 MiB/s 25.915 MiB/s 25.988 MiB/s]

rocket

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L715

rocket/Escaping/small   time:   [1.8800 us 1.9071 us 1.9288 us]
                        thrpt:  [328.31 MiB/s 332.03 MiB/s 336.84 MiB/s]

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L775

rocket/Escaping/ultra tiny
                        time:   [113.14 ns 113.56 ns 114.05 ns]
                        thrpt:  [58.534 MiB/s 58.788 MiB/s 59.005 MiB/s]

https://travis-ci.org/rust-iendo/v_htmlescape/jobs/471740072#L797

rocket/Escaping/one     time:   [134.52 ns 134.86 ns 135.24 ns]
                        thrpt:  [7.0518 MiB/s 7.0717 MiB/s 7.0893 MiB/s]

@djc Can you tell me what you think?

@zzau13
Copy link
Contributor

zzau13 commented Dec 23, 2018

On the other hand, there is a cyclical dependence between askama_shared (Config) and askama_escape (MarkupDisplay) that they forced me to do another refactor.

@djc
Copy link
Owner

djc commented Jan 11, 2019

See #197.

@zzau13 zzau13 closed this as completed Jan 12, 2019
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

No branches or pull requests

3 participants