Skip to content

Conversation

@seiyab
Copy link
Collaborator

@seiyab seiyab commented Jan 11, 2024

Description

Resolves #15877 and #9503.
flattenFill() is the key.

Checklist

  • I’ve added tests to confirm my change works.
  • (If changing the API or CLI) I’ve documented the changes I’ve made (in the docs/ directory).
  • (If the change is user-facing) I’ve added my changes to changelog_unreleased/*/XXXX.md file following changelog_unreleased/TEMPLATE.md.
  • I’ve read the contributing guidelines.

Try the playground for this PR

Comment on lines -419 to +451
</Hello>123
</Hello>
123
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider this get correct.

Comment on lines +3 to +28
function fillBuilder() {
const parts = [];
let pendingDocs = [];
function flush() {
parts.push(pendingDocs);
pendingDocs = [];
}

const self = {
append(doc) {
pendingDocs.push(doc);
return self;
},
appendLine(doc) {
flush();
pendingDocs = [];
parts.push(doc);
return self;
},
build() {
flush();
return fill(parts);
},
};
return self;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible alternative API

const result = buildFill(($) => {
  $.append("a");
  $.append("b");
  $.appendLine(line);
  $.append("c");
})

instead of

const builder = fillBuilder();
builder.append("a");
builder.append("b");
builder.appendLine(line);
builder.append("c");
const result = builder.build();

@@ -0,0 +1,30 @@
import { fill } from "../builders.js";

function fillBuilder() {
Copy link
Collaborator Author

@seiyab seiyab Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to encourage using fillBuilder() instead of fill() since this should be safer.
If you agree, let's discuss on another discussion or issue.

}

/** @return {false | 'next' | 'start' | 'end'} */
function isPrettierIgnore(node) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some functions went to util.

}
let length = 1;
if (shouldPrePrintTripleHardline(path)) {
length = 3;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seiyab seiyab marked this pull request as ready for review January 12, 2024 14:11

drain(doc);

return builder.build();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will something like this work?

  const parts = []
  
  // Check last part / parts.index is ODD-EVEN
  switch (getDocType(doc)) {
      case DOC_TYPE_FILL: {
        // concat or turn the last element to array and push the first
        // push the rest
        break;
      }
      default:
        builder.append(doc);
        break;
    }

return fill(parts)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fisker
I'm sorry but I don't understand what does it mean / aim at.
Do you mean

  • it can be faster?
  • it can be more readable?
  • prefer cleaner doc? (e.g. prefer fill("a", line, "b") to fill(["a"], line, ["b"]))
  • recursion should be avoided?
  • fillBuilder looks over-engineering?

I'm not sure whether I understand the pseudo code or not but possibly following case can be a counter-example.
input: ["a", fill(["b", line, "c", line]), "b"]
expected output: fill(join(line, [["a", "b"], ["c"], ["b"]]))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's simply, so we don't need fillBuilder. Can you find other places that we want a "flat" fill?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fisker
Does 866b257 meet your request?

@seiyab seiyab requested a review from fisker January 24, 2024 14:38
@fisker
Copy link
Member

fisker commented Jan 24, 2024

@seiyab Does be4b1c6 make sense to you ?

let head = doc;
let rest = [];
if (docType === DOC_TYPE_FILL) {
[head, ...rest] = doc.parts;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this part, do we need go deeper? head and docs in rest can also be DOC_TYPE_ARRAY or DOC_TYPE_FILL.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to run some test first, prettier/prettier-regression-testing#435 (comment)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very sure it. But probably fill() isn't nested in paragraph. If we want to go deeper, we should take care that we should go deeper only even (odd for doc.parts) index element.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Searching "fill" in src/language-markdown, I confirmed fill() can't be nested in markdown. There are three use of fill():

  • printSentence() in print-sentence.js: sentence only contains word and whitespace that turns into simple docs like string or line-like. It won't have fill() as children.
  • if (shouldRemainTheSameContent(path)) { block in printer-markdown.js: same as printSentence().
  • flattenFill() in print-paragraph.js: paragraph can't be nested and the other children neither yield nested as described above.

So I think we don't need go deeper for elements of fill() as of now. But feel free to ask me to add recursive flattening for fill if you still worry about it.

@fisker
Copy link
Member

fisker commented Jan 24, 2024

Sorry that I have to rebase to reduce diff in prettier/prettier-regression-testing#435 (comment)

@fisker
Copy link
Member

fisker commented Jan 24, 2024

Wow, we are breaking (or maybe improving) a LOT... prettier/prettier-regression-testing#435 (comment)

Good opportunity to add more tests.

Better add all of them to our tests first (in other PR).

@seiyab
Copy link
Collaborator Author

seiyab commented Jan 25, 2024

Maybe this PR makes embedded code and normal code consistent. I'll check them.

Memo about regression test

content/files/en-us/learn/css/building_blocks/backgrounds_and_borders/index.md

✅ It get consistent

Details
diff --git ORI/content/files/en-us/learn/css/building_blocks/backgrounds_and_borders/index.md ALT/content/files/en-us/learn/css/building_blocks/backgrounds_and_borders/index.md
index f9114358..dd09ac79 100644
--- ORI/content/files/en-us/learn/css/building_blocks/backgrounds_and_borders/index.md
+++ ALT/content/files/en-us/learn/css/building_blocks/backgrounds_and_borders/index.md
@@ -46,7 +46,8 @@ The CSS {{cssxref("background")}} property is a shorthand for a number of backgr
         105deg,
         rgb(255 255 255 / 20%) 39%,
         rgb(51 56 57 / 100%) 96%
-      ) center center / 400px 200px no-repeat,
+      )
+      center center / 400px 200px no-repeat,
     url(big-star.png) center no-repeat,
     rebeccapurple;
 }

Stable pure CSS printer:

.box {
  background:
    linear-gradient(
        105deg,
        rgb(255 255 255 / 20%) 39%,
        rgb(51 56 57 / 100%) 96%
      )
      center center / 400px 200px no-repeat,
    url(big-star.png) center no-repeat,
    rebeccapurple;
}

Playground

/content/files/en-us/learn/javascript/client-side_web_apis/video_and_audio_apis/index.md

✅ It get consitent

Details
diff --git ORI/content/files/en-us/learn/javascript/client-side_web_apis/video_and_audio_apis/index.md ALT/content/files/en-us/learn/javascript/client-side_web_apis/video_and_audio_apis/index.md
index 30056ef5..e11799e7 100644
--- ORI/content/files/en-us/learn/javascript/client-side_web_apis/video_and_audio_apis/index.md
+++ ALT/content/files/en-us/learn/javascript/client-side_web_apis/video_and_audio_apis/index.md
@@ -144,7 +144,8 @@ Next, let's look at our button icons:
   font-family: "HeydingsControlsRegular";
   src: url("fonts/heydings_controls-webfont.eot");
   src:
-    url("fonts/heydings_controls-webfont.eot?#iefix") format("embedded-opentype"),
+    url("fonts/heydings_controls-webfont.eot?#iefix")
+      format("embedded-opentype"),
     url("fonts/heydings_controls-webfont.woff") format("woff"),
     url("fonts/heydings_controls-webfont.ttf") format("truetype");
   font-weight: normal;

Stable pure CSS printer:

@font-face {
  font-family: "HeydingsControlsRegular";
  src: url("fonts/heydings_controls-webfont.eot");
  src:
    url("fonts/heydings_controls-webfont.eot?#iefix")
      format("embedded-opentype"),
    url("fonts/heydings_controls-webfont.woff") format("woff"),
    url("fonts/heydings_controls-webfont.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
}

@seiyab
Copy link
Collaborator Author

seiyab commented Jan 25, 2024

be4b1c6 can make some sense to me but it looks technically incorrect (but it can be safe for printParagraph()). Technically saying, removing if (rest.length % 2 === 1) {{ parts.push([]); } can cause bug. I'll fix the problem and type error.

@seiyab
Copy link
Collaborator Author

seiyab commented Jan 25, 2024

Feel free to revert e85797f if you regard type safety as important.

@fisker
Copy link
Member

fisker commented Jan 25, 2024

removing if (rest.length % 2 === 1) {{ parts.push([]); } can cause bug.

fill should alway have even length, if not then there must something wrong.

@fisker
Copy link
Member

fisker commented Jan 25, 2024

Feel free to revert e85797f if you regard type safety as important.

getDocParts should not be used anymore. It's a legacy function should be removed. #15568

@fisker
Copy link
Member

fisker commented Jan 25, 2024

If you worry about edge cases,

  1. odd length should be thrown
  2. zero-length should be ignored, otherwise undefined will be pushed to doc, and it make sense to have zero-length fill, eg fill(join(line, path.map(print, "children"))

@seiyab
Copy link
Collaborator Author

seiyab commented Jan 25, 2024

@fisker
I've wrote tests #15985.

@seiyab
Copy link
Collaborator Author

seiyab commented Jan 25, 2024

I see. I'll remove the edge case consideration. I have considered fill can have even length because printer cares even length:

if (parts.length === 2) {
if (contentFits) {
cmds.push(whitespaceFlatCmd, contentFlatCmd);
} else {
cmds.push(whitespaceBreakCmd, contentBreakCmd);
}
break;
}

(I consider "fill should alway have even length" is typo of "rest should alway have even length" or "fill should alway have odd length")

@seiyab seiyab requested a review from fisker January 26, 2024 13:05
@fisker
Copy link
Member

fisker commented Jan 26, 2024

The printParagraph part looks good and fixed lots of bugs, do you think we can extract this part to seperate PR?

@seiyab

This comment was marked as outdated.

@seiyab
Copy link
Collaborator Author

seiyab commented Jan 27, 2024

@fisker
I found two smaller steps without refactoring. I pushed the steps into https://github.com/seiyab/prettier/commits/rearrange-history-of-15909/ (each step contains adding test and fixing so the branch is 4 commits ahead of main).
Should we start from a PR at the point of seiyab@064f77d as the first step?

@fisker
Copy link
Member

fisker commented Jan 27, 2024

Should we start from a PR at the point of seiyab@064f77d as the first step?

Yes, please

@seiyab
Copy link
Collaborator Author

seiyab commented Jan 28, 2024

I opened #15993 🚀

@seiyab
Copy link
Collaborator Author

seiyab commented Apr 9, 2024

Splitted into following PRs. Close this.
#15993
#16158

@seiyab seiyab closed this Apr 9, 2024
@seiyab seiyab deleted the 15877-delete-normalizeDoc branch April 9, 2024 04:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Doc of paragraph in markdown violates a rule of fill()

2 participants