diff --git a/.github/ISSUE_TEMPLATE/formatting.md b/.github/ISSUE_TEMPLATE/formatting.md index 5d6d3a27f..fa46e7a0d 100644 --- a/.github/ISSUE_TEMPLATE/formatting.md +++ b/.github/ISSUE_TEMPLATE/formatting.md @@ -26,7 +26,7 @@ Don't fill the form below manually! Let a program create a report for you: --> -**Prettier 3.9.1** +**Prettier 3.9.3** [Playground link](https://prettier.io/playground/#.....) ```sh diff --git a/.github/ISSUE_TEMPLATE/integration.md b/.github/ISSUE_TEMPLATE/integration.md index 0cdaaa6ec..a917eafcf 100644 --- a/.github/ISSUE_TEMPLATE/integration.md +++ b/.github/ISSUE_TEMPLATE/integration.md @@ -20,7 +20,7 @@ BEFORE SUBMITTING AN ISSUE: **Environments:** -- Prettier Version: 3.9.1 +- Prettier Version: 3.9.3 - Running Prettier via: - Runtime: - Operating System: diff --git a/CHANGELOG.md b/CHANGELOG.md index 889a1f80d..794b314db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,49 @@ +# 3.9.3 + +[diff](https://github.com/prettier/prettier/compare/3.9.1...3.9.3) + +#### Markdown: Fix unexpected removal of characters in liquid syntax ([#19489](https://github.com/prettier/prettier/pull/19489) by [@seiyab](https://github.com/seiyab)) + + +```md +// Input + +{{ page.title +}} text + + +{{ page.title + text + + +{{ page.title +}} text +``` + +#### TypeScript: Allow decorators to be used with declare on class fields ([#19492](https://github.com/prettier/prettier/pull/19492) by [@evoactivity](https://github.com/evoactivity)) + +Extensively used within the Ember ecosystem, decorators with `declare` on class fields will ignore the babel parser error and allow Prettier to format the code without breaking it. + + +```ts +// Input +export default class ProjectStatusComponent extends Component { + @service declare server: ServerService; +} + +// Prettier 3.9.1 +// SyntaxError: Decorators can't be used with a declare field. (2:3) +// 1 | export default class ProjectStatusComponent extends Component { +//> 2 | @service declare server: ServerService; +// | ^ +// 3 | } + +// Prettier 3.9.3 +export default class ProjectStatusComponent extends Component { + @service declare server: ServerService; +} +``` + # 3.9.1 [diff](https://github.com/prettier/prettier/compare/3.9.0...3.9.1) diff --git a/package.json b/package.json index a948f8c01..fce87d835 100644 --- a/package.json +++ b/package.json @@ -181,7 +181,7 @@ "node-style-text": "2.1.2", "npm-run-all2": "9.0.2", "open-editor": "6.0.0", - "prettier": "3.9.1", + "prettier": "3.9.3", "pretty-bytes": "7.1.0", "pretty-ms": "9.3.0", "puppeteer": "25.2.1", diff --git a/src/language-markdown/parse/micromark/micromark-extension-liquid.js b/src/language-markdown/parse/micromark/micromark-extension-liquid.js index 808879086..cac4a27a4 100644 --- a/src/language-markdown/parse/micromark/micromark-extension-liquid.js +++ b/src/language-markdown/parse/micromark/micromark-extension-liquid.js @@ -33,10 +33,10 @@ function liquidFromMarkdown() { /** @type {Handle} */ function exit(token) { - const d = this.resume(); + this.resume(); /** @type {any} */ const node = this.stack.at(-1); - node.value = d; + node.value = this.sliceSerialize(token); this.exit(token); } } @@ -55,6 +55,9 @@ function liquidSyntax() { }; function tokenize(effects, ok, nok) { + /** @type {typeof codes.rightCurlyBrace | typeof codes.percentSign} */ + let closingCode; + return start; /** @type {State} */ @@ -66,6 +69,10 @@ function liquidSyntax() { switch (code) { case codes.percentSign: case codes.leftCurlyBrace: + closingCode = + code === codes.percentSign + ? codes.percentSign + : codes.rightCurlyBrace; effects.consume(code); return inside; default: @@ -77,9 +84,9 @@ function liquidSyntax() { /** @type {State} */ function inside(code) { switch (code) { - case codes.percentSign: - case codes.rightCurlyBrace: - return effects.check({ tokenize: tokenizeClose }, close, data)(code); + case closingCode: + effects.consume(code); + return mayClose; case codes.eof: return nok(code); default: @@ -91,53 +98,21 @@ function liquidSyntax() { effects.enter(types.data); return inside; } - return data(code); + effects.consume(code); + return inside; } } /** @type {State} */ - function data(code) { - effects.consume(code); - return inside; - } - - function tokenizeClose(effects, ok, nok) { - return startClose; - - /** @type {State} */ - function startClose(code) { - switch (code) { - case codes.percentSign: - case codes.rightCurlyBrace: - effects.consume(code); - return endClose; - default: - return nok(code); - } - } - - /** @type {State} */ - function endClose(code) { - if (code !== codes.rightCurlyBrace) { - return nok(code); - } + function mayClose(code) { + if (code === codes.rightCurlyBrace) { effects.consume(code); + effects.exit(types.data); + effects.exit(nodeType); return ok; } - } - /** @type {State} */ - function close(code) { - effects.consume(code); - return closeEnd; - } - - /** @type {State} */ - function closeEnd(code) { - effects.consume(code); - effects.exit(types.data); - effects.exit(nodeType); - return ok; + return inside; } } } diff --git a/tests/format/markdown/liquid/__snapshots__/format.test.js.snap b/tests/format/markdown/liquid/__snapshots__/format.test.js.snap index d79547f8f..f7220d61a 100644 --- a/tests/format/markdown/liquid/__snapshots__/format.test.js.snap +++ b/tests/format/markdown/liquid/__snapshots__/format.test.js.snap @@ -1,5 +1,63 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing +exports[`character-after-closing-tokens.md - {"proseWrap":"always"} format 1`] = ` +====================================options===================================== +parsers: ["markdown"] +proseWrap: "always" + printWidth: 80 (default) | +=====================================input====================================== +{{ page.title +}} a + +--- + +{% + if user +%} Hello, {{ user }}! +{% endif %} + +=====================================output===================================== +{{ page.title +}} a + +--- + +{% + if user +%} Hello, {{ user }}! {% endif %} + +================================================================================ +`; + +exports[`character-after-closing-tokens.md format 1`] = ` +====================================options===================================== +parsers: ["markdown"] + printWidth: 80 (default) | +=====================================input====================================== +{{ page.title +}} a + +--- + +{% + if user +%} Hello, {{ user }}! +{% endif %} + +=====================================output===================================== +{{ page.title +}} a + +--- + +{% + if user +%} Hello, {{ user }}! +{% endif %} + +================================================================================ +`; + exports[`example-1.md - {"proseWrap":"always"} format 1`] = ` ====================================options===================================== parsers: ["markdown"] @@ -216,6 +274,138 @@ parsers: ["markdown"] ================================================================================ `; +exports[`issue-19488.md - {"proseWrap":"always"} format 1`] = ` +====================================options===================================== +parsers: ["markdown"] +proseWrap: "always" + printWidth: 80 (default) | +=====================================input====================================== +{{% blocks/cover +title="Welcome" +%}} + +This input uses Hugo shortcode. Prettier doesn't support this explicitly but it shouldn't break it either. + +{{% /blocks/cover %}} + +--- + +{{% blocks/cover +%}} + +{{% blocks/cover +%%}} + +{{% blocks/cover +}}} + +{{{% blocks/cover +%}} + +{% blocks/cover +%}} + +{{ blocks/cover +%}} + +=====================================output===================================== +{{% blocks/cover +title="Welcome" +%}} + +This input uses Hugo shortcode. Prettier doesn't support this explicitly but it +shouldn't break it either. + +{{% /blocks/cover %}} + +--- + +{{% blocks/cover +%}} + +{{% blocks/cover +%%}} + +{{% blocks/cover +}}} + +{{{% blocks/cover +%}} + +{% blocks/cover +%}} + +{{ blocks/cover +%}} + +================================================================================ +`; + +exports[`issue-19488.md format 1`] = ` +====================================options===================================== +parsers: ["markdown"] + printWidth: 80 (default) | +=====================================input====================================== +{{% blocks/cover +title="Welcome" +%}} + +This input uses Hugo shortcode. Prettier doesn't support this explicitly but it shouldn't break it either. + +{{% /blocks/cover %}} + +--- + +{{% blocks/cover +%}} + +{{% blocks/cover +%%}} + +{{% blocks/cover +}}} + +{{{% blocks/cover +%}} + +{% blocks/cover +%}} + +{{ blocks/cover +%}} + +=====================================output===================================== +{{% blocks/cover +title="Welcome" +%}} + +This input uses Hugo shortcode. Prettier doesn't support this explicitly but it shouldn't break it either. + +{{% /blocks/cover %}} + +--- + +{{% blocks/cover +%}} + +{{% blocks/cover +%%}} + +{{% blocks/cover +}}} + +{{{% blocks/cover +%}} + +{% blocks/cover +%}} + +{{ blocks/cover +%}} + +================================================================================ +`; + exports[`unbalanced-mismatched-braces.md - {"proseWrap":"always"} format 1`] = ` ====================================options===================================== parsers: ["markdown"] @@ -226,8 +416,8 @@ proseWrap: "always" Braces {% doesn't match so these words should not be considered as *liquid node* }} =====================================output===================================== -Braces -{% doesn't match so these words should not be considered as *liquid node* }} +Braces {% doesn't match so these words should not be considered as _liquid node_ +}} ================================================================================ `; @@ -241,7 +431,7 @@ parsers: ["markdown"] Braces {% doesn't match so these words should not be considered as *liquid node* }} =====================================output===================================== -Braces {% doesn't match so these words should not be considered as *liquid node* }} +Braces {% doesn't match so these words should not be considered as _liquid node_ }} ================================================================================ `; diff --git a/tests/format/markdown/liquid/character-after-closing-tokens.md b/tests/format/markdown/liquid/character-after-closing-tokens.md new file mode 100644 index 000000000..b3c601f9b --- /dev/null +++ b/tests/format/markdown/liquid/character-after-closing-tokens.md @@ -0,0 +1,9 @@ +{{ page.title +}} a + +--- + +{% + if user +%} Hello, {{ user }}! +{% endif %} diff --git a/tests/format/markdown/liquid/issue-19488.md b/tests/format/markdown/liquid/issue-19488.md new file mode 100644 index 000000000..71d14d01b --- /dev/null +++ b/tests/format/markdown/liquid/issue-19488.md @@ -0,0 +1,27 @@ +{{% blocks/cover +title="Welcome" +%}} + +This input uses Hugo shortcode. Prettier doesn't support this explicitly but it shouldn't break it either. + +{{% /blocks/cover %}} + +--- + +{{% blocks/cover +%}} + +{{% blocks/cover +%%}} + +{{% blocks/cover +}}} + +{{{% blocks/cover +%}} + +{% blocks/cover +%}} + +{{ blocks/cover +%}} diff --git a/website/versioned_docs/version-stable/browser.md b/website/versioned_docs/version-stable/browser.md index aeb13c183..c98038389 100644 --- a/website/versioned_docs/version-stable/browser.md +++ b/website/versioned_docs/version-stable/browser.md @@ -21,7 +21,7 @@ Required options: - **[`parser`](options.md#parser) (or [`filepath`](options.md#file-path))**: One of these options has to be specified for Prettier to know which parser to use. -- **`plugins`**: Unlike the `format` function from the [Node.js-based API](api.md#prettierformatsource-options), this function doesn’t load plugins automatically. The `plugins` option is required because all the parsers included in the Prettier package come as plugins (for reasons of file size). These plugins are files in [https://unpkg.com/browse/prettier@3.9.1/plugins](https://unpkg.com/browse/prettier@3.9.1/plugins). Note that `estree` plugin should be loaded when printing JavaScript, TypeScript, Flow, or JSON. +- **`plugins`**: Unlike the `format` function from the [Node.js-based API](api.md#prettierformatsource-options), this function doesn’t load plugins automatically. The `plugins` option is required because all the parsers included in the Prettier package come as plugins (for reasons of file size). These plugins are files in [https://unpkg.com/browse/prettier@3.9.3/plugins](https://unpkg.com/browse/prettier@3.9.3/plugins). Note that `estree` plugin should be loaded when printing JavaScript, TypeScript, Flow, or JSON. You need to load the ones that you’re going to use and pass them to `prettier.format` using the `plugins` option. @@ -32,8 +32,8 @@ See below for examples. ### Global ```html - - + +