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: inconsistencies when using pugSingleQuote: false with singleQuote: true in vue SFCs templates #339

Closed
qnp opened this issue Feb 24, 2022 · 9 comments · Fixed by #354
Labels
type: bug Functionality that does not work as intended/expected

Comments

@qnp
Copy link
Contributor

qnp commented Feb 24, 2022

Info

Tool Version
Plugin v1.19.2
Prettier v2.5.1
Framework vue
Node v16.13.2
OS mac

Prettier config

{
  "singleQuote": true,
  "pugSingleQuote": false
}
<template lang="pug">
  my-component(:my-prop="someJavascript('here')")
  div {{ someJavascript('here') }}
</template>

Output

After formatting, we obtain:

my-component(:my-prop="someJavascript('here')")
div {{ someJavascript("here") }}

Code between "mustaches" {{ ... }} is not pug markup but Javascript code, however it does not respect the singleQuote: true prettier option.

Expected Output

Everything between "mustaches" {{ ... }} must be treated as Javascript code, so that the singleQuote: true prettier option is respected, as follows:

- div {{ someJavascript("here") }}
+ div {{ someJavascript('here') }}

Additional Context

May be related to #66 ?

Minimal repro playground

issue-prettier-plugin-pug-quotes.zip

@qnp qnp changed the title Bug: inconsistencies when using pugSingleQuote: false with singleQuote: true Bug: inconsistencies when using pugSingleQuote: false with singleQuote: true in vue SFCs templates Feb 24, 2022
@Shinigami92 Shinigami92 added framework: Vue Related to the framework Vue type: bug Functionality that does not work as intended/expected labels Feb 24, 2022
@qnp
Copy link
Contributor Author

qnp commented Feb 24, 2022

To clarify : this is not a vue SFC related issue only, I mean, it also appears in plain pug using mustache patterns – as you can see in my minimal repro example. The point is we encounter it while using vue SFC because we always need these mustache patterns in vue templates.

@Shinigami92
Copy link
Member

Have not touched the code base for a while, so I currently don't know the exact location where to start.
It would be very welcome if you jump into it and open a PR, I can then try to help you if you have some questions.

I have a https://github.com/prettier/plugin-pug/blob/main/CONTRIBUTING.md and it is very helpful to just copy one of the tests and create a tests/issues/issue-339/issue-339.test.ts

@Shinigami92 Shinigami92 removed the framework: Vue Related to the framework Vue label Feb 24, 2022
@qnp
Copy link
Contributor Author

qnp commented Feb 24, 2022

RIght, @Shinigami92 I'll try to dive in soon and make the fixes.

@Shinigami92
Copy link
Member

RIght, @Shinigami92 I'll try to dive in soon and make the fixes.

Any progress?

@qnp
Copy link
Contributor Author

qnp commented Mar 15, 2022

Cound’t manage to start, but it's in my pipe. I can propose you something during this week.

@qnp
Copy link
Contributor Author

qnp commented Mar 17, 2022

@Shinigami92, I have found the origin of the issue, but I need your insight.

The problem lies here :

plugin-pug/src/printer.ts

Lines 267 to 277 in 40bd270

this.codeInterpolationOptions = {
singleQuote: options.pugSingleQuote ?? options.singleQuote,
bracketSpacing: options.pugBracketSpacing ?? options.bracketSpacing,
arrowParens: options.pugArrowParens ?? options.arrowParens,
printWidth: 9000,
endOfLine: 'lf',
useTabs: options.pugUseTabs ?? options.useTabs,
tabWidth: options.pugTabWidth ?? options.tabWidth,
bracketSameLine: options.pugBracketSameLine ?? options.bracketSameLine,
};
}

where pug<X> options have been introduced to override <X> prettier options, useful in the case of Vue SFCs.

this.codeInterpolationOptions are passed where the code between {{ }} is formatted, hence this is the pug override which is taken, if provided, whereas the matched code should be considered as pure javascript and treated with non-prefixed singleQuote options.

I have perfomed other tests with all the possible pug<X> options different from the <X> ones. I could not see any problems with the other ones. Indeed, the problem with singleQuote & pugSingleQuote options is very specific of Vue usage (sorry about this wrong comment ) where attributes in quotes wrap javascript code.

So in order to have consistency in template interpolation using javascript code, we should not be doing

singleQuote: options.pugSingleQuote ?? options.singleQuote

However, as expected, removing the override breaks others tests:

  • tests/options/singleQuote/single-false-pug-true/single-false-pug-true.test.ts
  • tests/options/singleQuote/single-true-pug-false/single-true-pug-false.test.ts

So the solution would be the use a vue-specific options object (without pugSingleQuote override) in frameworkFormat function ?

@Shinigami92
Copy link
Member

@qnp I would assume that we can specifically can override the option if text token was called 🤔

Could you try to add an over-override here?

plugin-pug/src/printer.ts

Lines 453 to 463 in 40bd270

const options: Options = { ...this.codeInterpolationOptions };
switch (this.framework) {
case 'angular':
options.parser = '__ng_interpolation';
break;
case 'svelte':
case 'vue':
default:
options.parser = 'babel';
options.semi = false;
}

Maybe like const options: Options = { ...this.codeInterpolationOptions, singleQuote: options.singleQuote }; or so?!

@qnp
Copy link
Contributor Author

qnp commented Mar 17, 2022

It's exactly what I thought doing, I think this is the best solution. Keep in touch

@qnp
Copy link
Contributor Author

qnp commented Mar 17, 2022

#354

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.

2 participants