Confusingly using the LESS replace () function

I am trying to write a LESS mixin that uses part of a string to form a class name. I expected that I could use replace() to provide the value of a variable, and then use the variable in the rule. Here is the test I wrote to verify that it will work:

 .foo(@xyz) { @pfx: replace(@xyz, "(.).*", "$1"); .@ {pfx}-foo { margin: 0; } } .foo(abcdefghijklmnop); 

When I run this with lessc (1.7.4) (edit is also 2.1.0), it kind of works, generating this:

 .aaa-foo { margin: 0; } 

So, replace() correctly resets the first character ("a") from the line I pass to, but instead

 .a-foo 

it gives me

 .aaa-foo 

I looked at the source for the replace() function, and it was very simple, so I'm just completely confused about what is going on. (I tried the regex as "^(.).*$" With the same result.)

I extended the test a bit:

 .foo(@xyz) { @pfx: replace(@xyz, "(.).*", "$1"); .@ {pfx}-foo { margin: 0; content: "@{pfx}"; } } .foo(abcdefghijklmnop); 

which gives me:

 .aaa-foo { margin: 0; content: "a"; } 

which means the regex is working fine.

+5
source share
3 answers

try it

 .foo(@xyz) { @props: ~`"@{arguments}"`; @pfx: replace(@props, "^(.).*$", "$1"); .@ {pfx}-foo { margin: 0; } } .foo(abcdefghijklmnop); 

EDIT

Also, in response to the comment, you want to pass a replacement string, in fact, a simpler version is to use .foo(~"abcdefghijklmnop") , which makes it less likely to consider the parameter as a string without quotation marks.

+2
source

Try the following:

 @pfx: e(replace(@xyz, "^(.).*$", "$1")); 

Or that:

 @pfx: replace(~"@{xyz}", "^(.).*$", "$1"); 

See documentation for function e .

+2
source

Apparently, several workarounds are provided, but how that still remains a myth.

AST after the assessment was absolutely correct, which is as follows:

 Element { combinator: { value: '', emptyOrWhitespace: true }, value: '.', index: 54, currentFileInfo: { filename: 'input', relativeUrls: undefined, rootpath: '', currentDirectory: '', entryPath: '', rootFilename: 'input' } }, Element { combinator: { value: '', emptyOrWhitespace: true }, value: Quoted { escaped: undefined, value: 'a', quote: 'a', index: undefined, currentFileInfo: undefined }, index: 55, currentFileInfo: { filename: 'input', relativeUrls: undefined, rootpath: '', currentDirectory: '', entryPath: '', rootFilename: 'input' } }, Element { combinator: { value: '', emptyOrWhitespace: true }, value: '-foo', index: 61, currentFileInfo: { filename: 'input', relativeUrls: undefined, rootpath: '', currentDirectory: '', entryPath: '', rootFilename: 'input' } } 

But when you create CSS code, things quickly go south.

 Quoted.prototype.genCSS = function (context, output) { if (!this.escaped) { output.add(this.quote, this.currentFileInfo, this.index); } output.add(this.value); if (!this.escaped) { output.add(this.quote); } }; 

Quoted node will output a value with a quote around it when it is not escaped. Then somehow the quote is the first char value, for example 'a' in this case.

And when applying e() around replace , it will put Anonymous node in AST instead of Quoted node less, so no quote will be output.

+2
source

Source: https://habr.com/ru/post/1207606/


All Articles