paulstatezny

paulstatezny

SurfaceFormatter - A code formatter for Surface, the component-based library for Phoenix LiveView

Hello everyone, I’ve just released a new library called SurfaceFormatter.

A special thanks to @msaraiva for his help and collaboration!

What is it?

SurfaceFormatter is a code formatter (like mix format) for Surface code.

If you’re not familiar with Surface, you can find it on Hex, GitHub, or the original ElixirForum post.

Why did I create it?

So that Surface developers can focus on building things without sacrificing valuable time and attention to make the code nicely formatted.

How does it work?

Add it to a Surface project, and run mix surface.format. That’s it!

Where can I find it?

https://github.com/surface-ui/surface_formatter

A short example

Surface code that looks like this:

 <RootComponent with_many_attributes={{ true }} causing_this_line_to_wrap={{ true}} because_it_is_too_long={{ "yes" }}>
   <!-- An HTML comment -->
   {{#An Elixir comment}}



   <div :if={{@show_div}}
   class="container">
       <p> Text inside paragraph    </p>
    <span>Text touching parent tags</span>
   </div>

<Child  items={{[%{name: "Option 1", key: 1}, %{name: "Option 2", key:  2},    %{name: "Option 3", key: 3}, %{name: "Option 4", key: 4}]}}>
  Contents
</Child>
</RootComponent>

will be formatted like this:

<RootComponent
  with_many_attributes
  causing_this_line_to_wrap
  because_it_is_too_long="yes, this line is long enough to wrap"
>
  {{ # An Elixir comment }}

  <div :if={{ @show_div }} class="container">
    <p>
      Text inside paragraph
    </p>
    <span>Text touching parent tags</span>
  </div>

  <Child items={{[
    %{name: "Option 1", key: 1},
    %{name: "Option 2", key: 2},
    %{name: "Option 3", key: 3},
    %{name: "Option 4", key: 4}
  ]}}>
    Contents
  </Child>
</RootComponent>

Most Liked

paulstatezny

paulstatezny

SurfaceFormatter v0.2.1 has been released.

Previous versions didn’t allow inline elements to stay on the same line among text nodes, for example:

<p>
  I want <strong>this text</strong> to all stay on <em>one line</em>.
</p>

The previous rules were that each node (HTML element, text, or interpolation) would always be moved to a separate line. Therefore, this represents a pretty generous “relaxing” of the formatter. If anyone finds that it has become “too relaxed” in any scenarios, please post here and let me know!

paulstatezny

paulstatezny

SurfaceFormatter v0.7.0 was released. It comes packaged with a Formatter Plugin (available in Elixir 1.13) so that you can now run

$ mix format

to format both Elixir and Surface code in one command.

Special thanks to José Valim for adding Formatter Plugins to mix format! And to Marlus Saraiva for his part in it as well!

The next steps for SurfaceFormatter are:

  1. To merge it into Surface so that formatting works with even less setup out of the box.

  2. To attempt porting it into a HEEx formatter. As I understand it, formatting HEEx comes with some unique/extra technical challenges compared with Surface. We’ll see what happens. :slightly_smiling_face:

paulstatezny

paulstatezny

@Eiji Great observation :slight_smile:

Yes, the parsing library from Surface itself (which SurfaceFormatter uses under the hood) does not expose those comments, so we lose them. However, you can replace them with interpolated Elixir comments instead.

{{ # Some comment }}

I think it would be great to be able to keep HTML comments. If there is enough interest, perhaps the Surface parser can be modified to expose them.

In the meantime, I have added a more thorough explanation in that section of the docs to hopefully make the “why” more clear: https://hexdocs.pm/surface_formatter/Surface.Code.html#format_string!/2-html-comments

Where Next?

Popular in Announcing Top

wmnnd
Hi there, for my project DBLSQD, I needed a file storage solution that is a bit more flexible than Arc. Because I thought others might f...
New
OvermindDL1
I created a new library (rather I pulled out a couple files from my big project), it manages an operating system PID file for the BEAM. ...
New
tmbb
PhoenixWS - Websockets over Phoenix Channels Source code on Github here: GitHub - tmbb/phoenix_ws: Websockets implemented over Phoenix Ch...
New
seancribbs
Today I released a new dialyzer Mix task as the dialyzex package! At the time we started writing this task, the existing dialyzer integra...
New
Crowdhailer
I have been updating a library that allows you to pipe between functions that use the erlang result tuple convention. Assuming you have ...
New
kip
ex_cldr provides localisation and internationalisation support based upon the data from the Unicode CLDR project. Unicode released CLDR ...
407 12840 120
New
zachdaniel
Ash Framework What is Ash? Ash Framework is a declarative, resource-oriented application development framework for Elixir. A resource can...
New
markmark206
simple_feature_flags is a tiny package that lets you turn features on or off based on which environment (e.g. localhost, staging, product...
New
OvermindDL1
Been making an MLElixir thing (not released yet…) for fun in spare time in the past day. I’m just trying to see how much I can get an ML...
132 13966 106
New
marcuslankenau
I feel kind of stuck with the absence of a proper xml library for Elixir. Currently I use SweetXML which was ok for me more or less to pa...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement