Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Add support for {% # prettier-ignore %} #85

Merged
merged 2 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions src/printer/print/children.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,43 @@ function printChild(
const child = childPath.getValue();

if (hasPrettierIgnore(child)) {
const isPrevBorrowingOpeningMarker =
child.prev && needsToBorrowNextOpeningTagStartMarker(child.prev);
const bodyStartOffset = isPrevBorrowingOpeningMarker
? printOpeningTagStartMarker(child).length
: 0;
const bodyStart = locStart(child) + bodyStartOffset;

const isNextBorrowingClosingMarker =
child.next && needsToBorrowPrevClosingTagEndMarker(child.next);

// This could be "minus the `>` because the next tag borrows it"
const bodyEndOffset = isNextBorrowingClosingMarker
? printClosingTagEndMarker(child, options).length
: 0;
const bodyEnd = locEnd(child) - bodyEndOffset;

let rawContent = options.originalText.slice(bodyStart, bodyEnd);

// This is an idempotence edge case that I don't know how to solve
// "cleanly." I feel like there's a more elegant solution, but I can't
// find one right now.
//
// The gist: We might pretty-print something like this:
// <!-- prettier-ignore -->
// <b>{%cycle a,b,c%}</b
// >hi
// Which would mean the closing tag is '</b\n >'
//
// For idempotence to be maintained, we need to strip the '\n '
// from the raw source.
if (child.type === NodeTypes.HtmlElement && isNextBorrowingClosingMarker) {
rawContent = rawContent.trimEnd();
}

return [
printOpeningTagPrefix(child, options),
...replaceTextEndOfLine(
options.originalText.slice(
locStart(child) +
(child.prev && needsToBorrowNextOpeningTagStartMarker(child.prev)
? printOpeningTagStartMarker(child).length
: 0),
locEnd(child) -
(child.next && needsToBorrowPrevClosingTagEndMarker(child.next)
? printClosingTagEndMarker(child, options).length
: 0),
),
),
...replaceTextEndOfLine(rawContent),
printClosingTagSuffix(child, options),
];
}
Expand Down
23 changes: 21 additions & 2 deletions src/printer/utils/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,33 @@ export function shouldPreserveContent(
return false;
}

export function isPrettierIgnoreNode(node: LiquidHtmlNode | undefined) {
export function isPrettierIgnoreHtmlNode(
node: LiquidHtmlNode | undefined,
): node is HtmlComment {
return (
node &&
!!node &&
node.type === NodeTypes.HtmlComment &&
/^\s*prettier-ignore/m.test(node.body)
);
}

export function isPrettierIgnoreLiquidNode(
node: LiquidHtmlNode | undefined,
): node is LiquidTag {
return (
!!node &&
node.type === NodeTypes.LiquidTag &&
node.name === '#' &&
/^\s*prettier-ignore/m.test(node.markup)
);
}

export function isPrettierIgnoreNode(
node: LiquidHtmlNode | undefined,
): node is HtmlComment | LiquidTag {
return isPrettierIgnoreLiquidNode(node) || isPrettierIgnoreHtmlNode(node);
}

export function hasPrettierIgnore(node: LiquidHtmlNode) {
return isPrettierIgnoreNode(node) || isPrettierIgnoreNode(node.prev);
}
Expand Down
47 changes: 47 additions & 0 deletions test/liquid-prettier-ignore/fixed.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
It should respect the html prettier-ignore comment
printWidth: 1
<!-- prettier-ignore -->
{% cycle a,b,c %}

It should respect the html prettier-ignore comment on tags
printWidth: 1
<a>
<!-- prettier-ignore -->
<b>{% cycle a,b,c %}</b
>hi
</a>

It should respect the html prettier-ignore comment on liquid tags
printWidth: 1
<a>
<!-- prettier-ignore -->
{%capture foo%}{% for x in (0 .. 1) %}{% cycle a,b,c %}{% endfor %}{%endcapture%}
</a>

It should respect the liquid prettier-ignore comment
printWidth: 1
{% # prettier-ignore %}
{% cycle a,b,c %}

It should respect the liquid prettier-ignore comment on tags
printWidth: 1
<a>
{% # prettier-ignore %}
<b>{% cycle a,b,c %}</b
>hi
</a>

It should respect the liquid prettier-ignore comment on liquid tags
printWidth: 1
<a>
{% # prettier-ignore %}
{%capture foo%}{% for x in (0 .. 1) %}{% cycle a,b,c %}{% endfor %}{%endcapture%}
</a>

It should respect the liquid prettier-ignore comment on tags (and maintain whitespace semantic meaning)
printWidth: 1
<a>
{% # prettier-ignore %}
{%capture foo%}{% for x in (0 .. 1) %}{% cycle a,b,c %}{% endfor %}{%endcapture%}
{{- 'hi' }}
</a>
44 changes: 44 additions & 0 deletions test/liquid-prettier-ignore/index.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
It should respect the html prettier-ignore comment
printWidth: 1
<!-- prettier-ignore -->
{% cycle a,b,c %}

It should respect the html prettier-ignore comment on tags
printWidth: 1
<a>
<!-- prettier-ignore -->
<b>{% cycle a,b,c %}</b>hi
</a>

It should respect the html prettier-ignore comment on liquid tags
printWidth: 1
<a>
<!-- prettier-ignore -->
{%capture foo%}{% for x in (0 .. 1) %}{% cycle a,b,c %}{% endfor %}{%endcapture%}
</a>

It should respect the liquid prettier-ignore comment
printWidth: 1
{% # prettier-ignore %}
{% cycle a,b,c %}

It should respect the liquid prettier-ignore comment on tags
printWidth: 1
<a>
{% # prettier-ignore %}
<b>{% cycle a,b,c %}</b>hi
</a>

It should respect the liquid prettier-ignore comment on liquid tags
printWidth: 1
<a>
{% # prettier-ignore %}
{%capture foo%}{% for x in (0 .. 1) %}{% cycle a,b,c %}{% endfor %}{%endcapture%}
</a>

It should respect the liquid prettier-ignore comment on tags (and maintain whitespace semantic meaning)
printWidth: 1
<a>
{% # prettier-ignore %}
{%capture foo%}{% for x in (0 .. 1) %}{% cycle a,b,c %}{% endfor %}{%endcapture%}{{ 'hi' }}
</a>
6 changes: 6 additions & 0 deletions test/liquid-prettier-ignore/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { assertFormattedEqualsFixed } from '../test-helpers';
import * as path from 'path';

describe(`Unit: ${path.basename(__dirname)}`, () => {
assertFormattedEqualsFixed(__dirname);
});
1 change: 1 addition & 0 deletions test/test-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export function assertFormattedEqualsFixed(
let expected = expectedChunks[i].replace(TEST_MESSAGE, '').trimStart();

if (TEST_IDEMPOTENCE) {
if (testConfig.debug) debug(actual, testOptions);
actual = format(actual, testOptions).trimEnd();
}

Expand Down