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

Bug: Can't preserve backticks #261

Closed
jd-solanki opened this issue Jul 28, 2021 · 6 comments · Fixed by #266
Closed

Bug: Can't preserve backticks #261

jd-solanki opened this issue Jul 28, 2021 · 6 comments · Fixed by #266
Labels
type: bug Functionality that does not work as intended/expected

Comments

@jd-solanki
Copy link

jd-solanki commented Jul 28, 2021

Info

Tool Version
Plugin v1.16.0
Prettier v2.3.2
Framework none
Node v14.16.1
OS linux

Prettier config

{
    "arrowParens": "avoid",
    "bracketSpacing": true,
    "htmlWhitespaceSensitivity": "css",
    "insertPragma": false,
    "jsxBracketSameLine": false,
    "jsxSingleQuote": true,
    "printWidth": 120,
    "proseWrap": "preserve",
    "quoteProps": "as-needed",
    "requirePragma": false,
    "semi": true,
    "singleQuote": true,
    "tabWidth": 2,
    "trailingComma": "all",
    "useTabs": false,
    "vueIndentScriptAndStyle": false,
    "endOfLine": "lf",
    "pugSingleQuote": false,
    "pugTabWidth": 4,
    "pugEmptyAttributes": "none"
}

Input

Below backtick usage is converted to double quotes

img(src=post.img, class=`${roundness}`)

Output or Error

backtick converted to double quotes so generated HTML have below incorrect class

<img class="${roundness}" src="https://picsum.photos/400/225">

Expected Output

<img class="rounded-lg" src="https://picsum.photos/400/225">

Additional Context

roundness is a global variable:

pug -O "{roundness: 'rounded-lg'}" -w ./index.pug -o . -P

So, How can I make this plugin preserve backtick when I save in vs code?

@jd-solanki jd-solanki changed the title Bug: Bug: Can't preserve backticks Jul 28, 2021
@Shinigami92
Copy link
Member

Will check if this is a bug

Could you check that your input is really valid?

image

Seems there is a missing backtick?

Could you check if it's a regression of ff0715c#diff-4ade25325a6cd7d1cca619364c84d19bfa47e6939a2c1b38d065767255b8f86eR168

So could you try roll back a version (to 1.15.x) and see if it's "fixed" then?

If so, I think I will have time next weekend to fix that

@jd-solanki
Copy link
Author

Sorry, I had full code and removed the unwanted class so I missed the ending backtick but my input is correct.

Will try your suggestion of rolling back and will let you know.

@Shinigami92
Copy link
Member

I found out that it is a specific bug for class attribute (maybe also for id)
So other attributes will work fine

And yes, it was introduced by the mentioned change

@Yann-prak
Copy link

Will check if this is a bug

Could you check that your input is really valid?

image

Seems there is a missing backtick?

Could you check if it's a regression of ff0715c#diff-4ade25325a6cd7d1cca619364c84d19bfa47e6939a2c1b38d065767255b8f86eR168

So could you try roll back a version (to 1.15.x) and see if it's "fixed" then?

If so, I think I will have time next weekend to fix that

Hi,

I've roll back to 1.15.x and the bug doesn't exist anymore. Maybe your changes affected the way prettier interpret backticks.

@Yann-prak
Copy link

I found out that it is a specific bug for class attribute (maybe also for id)
So other attributes will work fine

And yes, it was introduced by the mentioned change

Yes ! The only way I can reproduce the bug is on the id attr.

@Shinigami92
Copy link
Member

The fix need to be applied here

plugin-pug/src/printer.ts

Lines 790 to 848 in 39c50ce

if (isQuoted(token.val)) {
if (token.name === 'class' && this.options.pugClassNotation === 'literal') {
// Handle class attribute
const val: string = token.val.slice(1, -1).trim();
const classes: string[] = val.split(/\s+/);
const specialClasses: string[] = [];
const normalClasses: string[] = [];
const validClassNameRegex: RegExp = /^-?[_a-zA-Z]+[_a-zA-Z0-9-]*$/;
for (const className of classes) {
if (!validClassNameRegex.test(className)) {
specialClasses.push(className);
} else {
normalClasses.push(className);
}
}
if (normalClasses.length > 0) {
// Write css-class in front of attributes
const position: number = this.possibleClassPosition;
this.result = [
this.result.slice(0, position),
'.',
normalClasses.join('.'),
this.result.slice(position)
].join('');
this.possibleClassPosition += 1 + normalClasses.join('.').length;
this.replaceTagWithLiteralIfPossible(/div\./, '.');
}
if (specialClasses.length > 0) {
token.val = makeString(specialClasses.join(' '), this.quotes);
this.previousAttributeRemapped = false;
} else {
this.previousAttributeRemapped = true;
return;
}
} else if (token.name === 'id' && this.options.pugIdNotation !== 'as-is') {
// Handle id attribute
let val: string = token.val;
val = val.slice(1, -1);
val = val.trim();
const validIdNameRegex: RegExp = /^-?[_a-zA-Z]+[_a-zA-Z0-9-]*$/;
if (!validIdNameRegex.test(val)) {
val = makeString(val, this.quotes);
this.result += 'id';
if (token.mustEscape === false) {
this.result += '!';
}
this.result += `=${val}`;
return;
}
// Write css-id in front of css-classes
const position: number = this.possibleIdPosition;
const literal: string = `#${val}`;
this.result = [this.result.slice(0, position), literal, this.result.slice(position)].join('');
this.possibleClassPosition += literal.length;
this.replaceTagWithLiteralIfPossible(/div#/, '#');
this.previousAttributeRemapped = true;
return;
}
}

@Shinigami92 Shinigami92 added the type: bug Functionality that does not work as intended/expected label Jul 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Functionality that does not work as intended/expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants