New html formatter
lbogdan opened this issue ยท 25 comments
Hey guys!
Because js-beautify-html
was driving me nuts ๐ฌ, I started working on a html formatter based on reshape parser. I just wanted to let you know, so that we don't duplicate our efforts.
I currently have a proof of concept, I'll setup a page shortly in which we can test it by live formatting entered html.
Sounds good -- I was thinking about starting to work on it too but haven't got time.
Let's join efforts and make #491 happen ๐ป
Ok, I have a version up & running here (it's on a PR build of CodeSandbox where I fixed a bug).
Let me know what you think.
Initial impressions:
-
You seem to be having a
printWidth
-- nice work! -
I'm hoping that we use this format for long attributes
<div attr="foo" attr="foo" attr="foo" attr="foo" >bar</div>
-
I hope we are more strict about formatting multiline comments. Currently only first line of the comment is formatted / indented. We can follow the same logic of formatting html tags.
- If it can be put in the same line without exceeding
printWidth
, make it a one line comment - If it can't, format it in this way:
<!-- comment here all the way until `printWidth` next line for comment -->
- If it can be put in the same line without exceeding
-
We should embed a mini formatter for multi-line interpolations, such as the value of
:class
. We can look into using some bits from prettier (can't take it as is since vue interpolation is JS values, not JS statements)
Hey, @octref, thank you for your feedback!
As I said, this is just a proof of concept, to see how reshape
works (fortunately, it turns out it's very simple). Before I start writing something more involved, we first need to decide on some specifications, even if very crude. I'll try to make a draft tomorrow.
Now answers to your remarks:
You seem to be having a printWidth -- nice work!
It's not really printWidth
- how it works is that if an element has more than two attributes, they're arranged on subsequent lines, so it's
<div id="app"></div>
but
<div id="app"
style="width: 100%;"
></div>
I'm hoping that we use this format for long attributes
I guess you're referring to the indentation of attributes. Right now the first one is on the same line with the element, they're all aligned, and the subsequent ones are each on a new line, and aligned with that first one. There are many variations here - first attribute on a new line, indented by one unit (like in your example) etc. Specifications should help with that.
I hope we are more strict about formatting multiline comments.
That's a bit more complicated. What if the commented text is html? We can't really reformat the lines, as we'll end up with something like
<!--
<div><select><option value="foo">foo</option></select></div>
-->
instead of
<!--
<div>
<select>
<option value="foo">foo</option>
</select>
</div>
-->
(and reformatting whitespace also doesn't work well)
<!--
<div>
<select>
<option value="foo">foo</option>
</select>
</div>
-->
We should embed a mini formatter for multi-line interpolations, such as the value of :class.
We can probably use prettier, adjusting it's printWidth
accordingly. The first <div :class="...
in my example is a good start to explore this - notice that right now the indentation is wrong by one unit, in my opinion, it should be
<div :class="[
type === 'textarea' ? 'el-textarea' : 'el-input',
inputSize ? 'el-input--' + inputSize : '',
{
'is-disabled': disabled,
...
}
]">
instead of
<div :class="[
type === 'textarea' ? 'el-textarea' : 'el-input',
inputSize ? 'el-input--' + inputSize : '',
{
'is-disabled': disabled,
...
}
]">
I'll come back with the specifications draft and a lot more good / bad examples.
I'd want to use prettier for each part of Vue, so I think a printWidth
makes sense. This way it also aligns with existing prettier config.
I'd say for multi-line comments, all I care is
<!--
and-->
have same indentation- The body of the comment starts at one more indentation than the
<!--
.
We should not try to do any formatting for the content. It can be html or any other thing.
Forget about the multi-line comment -> single-line comment idea.
I created a new repo and started drafting some specifications (more like a brain dump, really, so don't expect much). You can find them here:
I'd suggest not to bogged down by with spec. If you want to put the code somewhere I can help. Otherwise I'll jus take a look at Reshape and do it myself as I originally planned.
My thought is simple -- making it work for this single use-case (template in Vue), and making it good, opinionated and embeddable.
Agreed, I'll update the CodeSandbox shortly with what I have so far, and let you know.
New version: https://codesandbox.io/s/qzvxvmk6v6?view=preview . Play around with it and let me know what you think.
Instead of putting it on codesandbox, I'd prefer if we can have a repo with unit tests set up so we can keep working together on it.
Yes, of course, that was only a proof-of-concept to be able to test different inputs. It needs a major refactor and unit tests, of course. I'll try to set this up in a day or two.
Was playing around with it -- it's pretty good! There are a few edge cases that should be handled, but once you have the unit-tests setup we can go from there.
And once we have the repo we can host it on codesandbox, so people can try it and report bugs.
Any report on the progress with this? Html formatting will be awesome!
I can't wait. When will it be released?
Just for the record - I was able to get a decent html formatting in .vue SFC with the current ( to be retired js-beautify-html ?) and to avoid the conflict with prettier extension I've disabled it for .vue files and enabled js-beautify-html for vetur:
"prettier.disableLanguages": ["vue"], "vetur.format.defaultFormatter.html": "js-beautify-html", // Options for all default formatters "vetur.format.defaultFormatterOptions": { "js-beautify-html": { "wrap_attributes": "force-aligned" } }
However, I wanted to report that the formatter breaks as soon as a Diff is opened in vscode - forcing me to restart the app to get the formatting to work. I don't know if it is vetur or js-beautify at fault here but just wanted to bring it to your attention.
@onelifenyc Can you use https://www.cockos.com/licecap/ to record a gif and open a new issue? Thanks.
How is it going? you need help? I got fed up with js-beautify, which I'm still forced to use just to have a least of coherency in my html. It's about time.
Bumping this thread. What is the current state of the issue. Would love to help if possible.
I think everyone is waiting for prettier to support HTML formatting.
If you want to help you might check this out:
prettier/prettier#1882
any update for this?
everyone needs this.
@adi518 @mmusket @StefanFeederle @qiming-kooboo there is progress in #491. I proposed my project https://github.com/Prettyhtml/prettyhtml which works really great and @octref has plans to integrate it into vetur. @StefanFeederle prettier is far ahead e.g they only support strict HTML5 (without custom self-closing elements, browser attribute encoding which breaks most template languages etc..)
It would be great if you could test https://github.com/Prettyhtml/prettyhtml and provide some feedback. Please consider prettyhtml at first as a general formatter. We will deal with framework specific things later. Thanks.