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

let less parser support heredoc to convenient multi line string input #2580

Closed
keven-wang opened this issue May 4, 2015 · 13 comments
Closed

Comments

@keven-wang
Copy link

i want to add a function for less to genererate svg string , the function will be used as follows:

background-image: svg-cont('width:80', 'height:100', <<EOF
        <path d="m100,100"/>
        <path d="m100,50"/> 
       ...
EOF);

but the parser of the less didn't support heredoc, so it's diffcult to input multi line string. i edit parser.js implements heredoc. so i want my edit can be merged. the following is my edit.

----------------parser.js

                quoted: function () {following
                    /* the orginal implements
                   var str, j = i, e, index = i;

                    if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings
                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") { return; }

                    if (e) { $char('~'); }

                    str = $re(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/);
                    if (str) {
                        return new(tree.Quoted)(str[0], str[1] || str[2], e, index, env.currentFileInfo);
                    }*/

                    var str_reg  = /^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/;
                    var here_reg = /<{2,}(\w+)([\S\s]+?)\1/;
                    var str, j = i, e, isStr, isHereDoc, index = i;

                    if (input.charAt(j) === '<') { isHereDoc = true; }
                    if (input.charAt(j) === '~') { j++; e = true; $char('~'); } // Escaped strings
                    if (input.charAt(j) === '"' || input.charAt(j) === "'") { isStr = true; }

                    if(isHereDoc && (str = $re(here_reg)) ){
                        return new(tree.Quoted)('"', str[2].trim(), false, index, env.currentFileInfo);
                    }else if( isStr && (str = $re(str_reg)) ){
                        return new(tree.Quoted)(str[0].charAt(0), str[1] || str[2], e, index, env.currentFileInfo);
                    }
                },
@seven-phases-max
Copy link
Member

Multiline strings were discussed at #1648, but the context and use-case there were quite different so I'm not closing this as a duplicate.

Regardless of above, please learn how to work with GitHub forks and pull-requests (https://help.github.com/categories/collaborating/). Additionally see Contributing Notes.

@seven-phases-max
Copy link
Member

Technically this can be achieved with something like:

div {
    background-image: 
        svg-cont(
            'width:80', 'height:100', `' \
            <path d="m100,100"/> \
            <path d="m100,50"/> \
                   ... \
        '`);
}

But this is quite hackish.

@keven-wang
Copy link
Author

sorry, i am a newer of git, i will learn how to use forks and pull-requests。 i will not use \ to generate muli line string. it is ugly and diffcult to read, you can not figure out whether some space exists behind \。if not support heredoc i'd better to use following style:

background-image: svg-cont('width:80', 'height:100',
        '<path d="m100,100"/>'
        '<path d="m100,50"/>' 
);

it's not convenient, but it's easy to read. a lot of language support heredoc like ruby(my favorite)、php、C#...。i can not think out why we not support it, it's so easy to support it.

@battlesnake
Copy link

Backslash continuation is explicit and readable - I can tell that a line is continued by the trailing backslash, and tell that it continues from the previous one if that has a trailing backslash. Bash-style <<EOF is less readable by that same reasoning. Regarding trailing whitespace after the backslash - any decent editor can be configured to either highlight or remove trailing whitespace.

Wouldn't it be cleaner to have the SVG in separate SVG files instead, and to use the build system to inline them into the LESS or the generated CSS during build? There's probably already Gulp/Grunt plugins to do this, and I've used a simple Perl script for it in the past on a project that used Make.

@seven-phases-max
Copy link
Member

@battlesnake

and to use the build system to inline them into the LESS or the generated CSS during build?

You don't even need any external tool for this since data-uri can do it for you.

But I can imagine reasons you don't want it in a separate file:
Beside obvious but not so important idea of "keeping tiny/depended snippets of code consolidated", currently there's a major show-stopper for the CSS-inlined SVGs. Unlike with any other svg code insertion methods, the CSS-inlined SVG cannot be styled by the CSS itself (what an irony! :).
So by explicitly inlining svg as a string you get an option/workaround to style/parametrize it at least via variables, e.g.:

@width: 80;
background-image: svg-cont('width:@{width}', 'height:100',
        '<path d="m100,100"/>'
        '<path d="m100,50"/>' 
);

Otherwise you have to put the SVG into the HTML (or invent even more dirty tricks like this)


Either way, sure <<EOF is bloody nonsense, so if Less has to have something like that it could be some other syntax.

@battlesnake
Copy link

Interesting, I didn't know that CSS doesn't get applied to inline SVG [[edit: inline in CSS, not HTML]]

Regarding syntax, I think a good golden rule is "look at how Bash does it, and do the opposite".

Out of curiosity, can a string span several lines in less?

font-family: "this stupid font has
a line-break in its name";

Also a bad idea, I'm just curious as to whether it works. I'll try it now actually. -- result: doesn't work, thankfully

@matthew-dean
Copy link
Member

I didn't know that CSS doesn't get applied to inline SVG

It only does if the SVG is inline in the HTML document. You can also reference a CSS file from within the SVG file, so there's no reason that CSS file couldn't be the same LESS-generated one. That might be a cleaner approach. See: https://css-tricks.com/using-svg/

@battlesnake
Copy link

I built an interactive SVG-based project a few months ago, I think some browsers/devices had issues with referencing stylesheets from in SVG documents (I recall that IE and mobile Safari were the worst offenders for SVG bugs).

An archive of the actual project (ERR online coverage of Estonia's 2015 election) is at: http://hackology.co.uk/elections/
The map is SVG, charts are SVG+d3.js (feel free to play with the pie/bar buttons :D )

Anyway I'm going off topic here, I'll stop talking about SVG now!

@matthew-dean
Copy link
Member

See the link. Apparently it may work if you embed using <object>.

@battlesnake
Copy link

I tried object / embed / iframe / img. For some methods, the interactivity broke on certain browsers/platforms. With other methods, other stuff broke. Whatever implementation I used in that finished version is based on compromises over browser bugs. iPad Safari was very disappointing during the development of that...

@matthew-dean
Copy link
Member

@battlesnake You're probably right. Browsers still suck at cross-platform SVG, and they'll fail at different times. I did an SVG-based mobile app once. Mobile Safari would grind to a halt because it allocated memory for the total calculated size of SVG, regardless of how much was actually drawn in the document. Mobile IE would crash at random times depending on the number of SVGs and their interactivity.

@keven-wang
Copy link
Author

first, thanks focus and reply for this issue. i explain why i wanted add this features for less.
@seven-phases-max guessed righit. i didn't like write code in a separate file, beacuse you can not change some set through less variable, and it can not "keeping tiny/depended snippets of code consolidated".

in the project , i use svg as background image for some icon instead of png image or gif image. because must input some long attriubte such as xmlns when writing svg code, i changed less code and add a function for less to generate svg code, then i can only write svg content and some key attibutes. but in less it is diffcult to input a mulitline string and passed to a javascript function to handle.

@seven-phases-max's idea is not convenient enough, because has a lot of svg tag and atttriubtes , i canot write a lot of mixins to map them.

@stale
Copy link

stale bot commented Nov 14, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Nov 14, 2017
@stale stale bot closed this as completed Nov 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants