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 raw as a default mode #4

Open
mmstick opened this issue Jul 7, 2019 · 2 comments
Open

Support raw as a default mode #4

mmstick opened this issue Jul 7, 2019 · 2 comments

Comments

@mmstick
Copy link

mmstick commented Jul 7, 2019

Currently, the define!() macro assumes XML-like rules, and there's likely a bit of overhead in parsing every string in that manner. I have use for templating for a wide range of formats which are not XML-like in nature, such as INI, TOML, or any other custom formats. Peppering the define!() with markup::raw() seems wrong.

As an example, this is what I've come up with for generating desktop entry files. There are no escape rules, outside of \; for in keys that take multiple values.

markup::define! {
    DesktopEntry<'a>(
        name: &'a str,
        generic_name: Option<&'a str>,
        icon: &'a str,
        comment: Option<&'a str>,
        hidden: bool,
        no_display: bool,
        kind: DesktopType<'a>
    ) {
        "[Desktop Entry]\n"
        "Type=" {markup::raw(kind.type_str())} "\n"
        "Name=" {markup::raw(name)} "\n"
        
        @if let Some(generic) = (generic_name) {
            "GenericName=" {markup::raw(generic)} "\n"
            
            "X-GNOME-FullName=" {markup::raw(name)} " " {markup::raw(generic)} "\n"
        }

        "Icon=" {icon} "\n"
        
        @if let Some(comment) = (comment) {
            "Comment=" {markup::raw(comment)} "\n"
        }

        @if *(hidden) {
            "Hidden=true\n"
        }

        @if *(no_display) {
            "NoDisplay=true\n"
        }

        @if let DesktopType::Application(app) = (kind) {
            "Categories=" {markup::raw(app.categories)} "\n"
            
            @if !app.keywords.is_empty() {
                "Keywords=" { '\"' }
                @for keyword in app.keywords.iter() {
                    {markup::raw(keyword)} ";"
                }
                { markup::raw("\"\n") }
            }

            @if !app.mime_types.is_empty() {
                "MimeType=" { '\"' }
                @for mime in app.mime_types {
                    {markup::raw(mime)} ";"
                }
                { markup::raw("\"\n") }
            }

            @if app.terminal {
                "Terminal=true\n"
            }

            @if app.startup_notify {
                "StartupNotify=true\n"
            }

            "Exec=" {markup::raw(app.exec)} "\n"
            
            @if let Some(path) = (app.path) {
                "Path=" {markup::raw(path)} "\n"
            }
        } else if let DesktopType::Link { url } = (kind) {
            "Link=" {markup::raw(url)} "\n"
        }
    }
}
@utkarshkukreti
Copy link
Owner

Never thought someone would use this for generating non HTML/XML data! I added auto escaping like most HTML/XML templating languages do -- to prevent accidental XSS attacks. You could shorten markup::raw to r like this:

use markup::raw as r;

...

"Type=" {r(kind.type_str())} "\n"

Just 3 extra characters now. Maybe that is good enough?

@inferrna
Copy link

I tried to use this for code generation via build.rs and was disappoint of escaping. I'd suggest you to add new macro, called define_raw! for example, to make it usable not only for HTML/XML.

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