

SurfaceFormatter — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

SurfaceFormatter

================

[![Build Status](https://github.com/surface-ui/surface_formatter/workflows/CI/badge.svg)](https://github.com/surface-ui/surface_formatter/actions?query=workflow%3A%22CI%22)

[![hex.pm](https://img.shields.io/hexpm/v/surface_formatter.svg)](https://hex.pm/packages/surface_formatter)

[![hex.pm](https://img.shields.io/hexpm/l/surface_formatter.svg)](https://hex.pm/packages/surface_formatter)

A code formatter for <https://hex.pm/packages/surface>.

The complete documentation for SurfaceFormatter is located [here](https://hexdocs.pm/surface_formatter/).

 Installation

---------------

Add `:surface_formatter` as a dependency in `mix.exs`:

```

defp deps do

 [

 {:surface\_formatter, "~> 0.7.5"}

 ]

end

```

 Formatter Plugin Usage (Elixir 1.13 and later)

-------------------------------------------------

### 

 Configuration

Modify the following in `.formatter.exs`:

* `inputs` - add patterns for all Surface files

* `plugins` - add [`Surface.Formatter.Plugin`](Surface.Formatter.Plugin.html)

```

# .formatter.exs

[

 ...,

 # match all .sface files and all .ex files with ~F sigils

 inputs: ["lib/\*\*/\*.{ex,sface}", ...],

 plugins: [Surface.Formatter.Plugin]

]

```

For documentation of other `.formatter.exs` options, see [`Surface.Formatter.Plugin`](Surface.Formatter.Plugin.html).

### 

 Usage

```

$ mix format

```

(Formats both Elixir and Surface code.)

 Mix Task Usage (Elixir 1.12 and earlier)

-------------------------------------------

### 

 Configuration

Add `surface_inputs` to `.formatter.exs` with patterns for all Surface files:

```

# .formatter.exs

[

 ...,

 # match all .sface files and all .ex files with ~F sigils

 surface\_inputs: ["lib/\*\*/\*.{ex,sface}", ...]

]

```

If your project does not use `sface` files, you can omit `:surface_inputs` and

specify file patterns in the standard `:inputs` field instead. ([`mix surface.format`](Mix.Tasks.Surface.Format.html) will fall back to `:inputs`.) But be warned that including

`.sface` files in `:inputs` causes [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) to crash in Elixir 1.12 and

earlier.

For documentation of other `.formatter.exs` options, see [`mix surface.format`](Mix.Tasks.Surface.Format.html).

### 

 Usage

```

$ mix surface.format

```

 Formatting rules

-------------------

The formatter mostly follows these rules:

* Only formats code inside of `~F"""` blocks and `.sface` files.

* Child nodes are typically indented 2 spaces in from their parent.

* Interpolated Elixir code (inside `{ }` brackets) is formatted by the

[official Elixir formatter](https://hexdocs.pm/elixir/Code.html#format_string!/2).

* HTML attributes are put on separate lines if the line is too long.

* Retains "lack of whitespace" such as `<p>No whitespace between text and tags</p>`.

* Collapses extra newlines down to at most one blank line.

See [`Surface.Formatter.format_string!/2`](Surface.Formatter.html#format_string!/2) for further documentation.

 Example at a glance

----------------------

Out of the box, Surface code that looks like this:

```

 <RootComponent with_many_attributes={ true } causing_this_line_to_wrap={ true} because_it_is_too_long={ "yes, this line is long enough to wrap" }>

   <!--   HTML public comment (hits the browser)   -->

   {!--   Surface private comment (does not hit the browser)   --}

   <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}]}>

  Default slot 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"

>

  <!-- HTML public comment (hits the browser) -->

  {!-- Surface private comment (does not hit the browser) --}

  <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}

  ]}>

    Default slot contents

  </Child>

</RootComponent>

```





Surface.Formatter — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L1 "View Source")

=================================================================================================================================================================

Functions for formatting Surface code snippets.

[Link to this section](#summary)

 Summary

==========================================

[Types](#types)

----------------

[attribute()](#t:attribute/0)

A parsed HTML/Component attribute name and value.

[attribute\_value()](#t:attribute_value/0)

The value of a parsed HTML/Component attribute.

[formatter\_node()](#t:formatter_node/0)

A node that will ultimately be sent to `Surface.Formatter.Render.node/2` for rendering.

[option()](#t:option/0)

Options that can be passed to [`Surface.Formatter.format_string!/2`](#format_string!/2).

[surface\_node()](#t:surface_node/0)

A node output by `Surface.Compiler.Parser.parse`.

[tag()](#t:tag/0)

The name of an HTML/Surface tag, such as `div`, `ListItem`, or `#Markdown`.

[whitespace()](#t:whitespace/0)

Whitespace nodes that can be rendered by `Surface.Formatter.Render.node/2`.

[Functions](#functions)

------------------------

[format\_string!(string, opts \\ [])](#format_string!/2)

Formats the given Surface code string. (Typically the contents of an `~F`

sigil or `.sface` file.)

[is\_element?(arg1)](#is_element?/1)

Returns true if the argument is an element (HTML element or surface

component), false otherwise.

[render\_contents\_verbatim?(tag)](#render_contents_verbatim?/1)

Given a tag, return whether to render the contens verbatim instead of formatting them.

Specifically, don't modify contents of macro components or <pre> and <code> tags.

[Link to this section](#types)

Types

=====================================

[Link to this type](#t:attribute/0 "Link to this type")

attribute()

===========

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L28 "View Source")

Specs

-----

```

attribute() :: {name :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)(), [attribute\_value](#t:attribute_value/0)(), [term](https://hexdocs.pm/elixir/typespecs.html#built-in-types)()}

```

A parsed HTML/Component attribute name and value.

[Link to this type](#t:attribute_value/0 "Link to this type")

attribute\_value()

==================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L20 "View Source")

Specs

-----

```

attribute_value() ::

  [integer](https://hexdocs.pm/elixir/typespecs.html#basic-types)()

  | [boolean](https://hexdocs.pm/elixir/typespecs.html#built-in-types)()

  | [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()

  | {:attribute_expr, interpolated_expression :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)(), [term](https://hexdocs.pm/elixir/typespecs.html#built-in-types)()}

  | [[String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()]

```

The value of a parsed HTML/Component attribute.

[Link to this type](#t:formatter_node/0 "Link to this type")

formatter\_node()

=================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L59 "View Source")

Specs

-----

```

formatter_node() :: [surface\_node](#t:surface_node/0)() | [whitespace](#t:whitespace/0)()

```

A node that will ultimately be sent to `Surface.Formatter.Render.node/2` for rendering.

The output of `Surface.Compiler.Parser.parse` is ran through the various formatting

phases, which ultimately output a tree of this type.

[Link to this type](#t:option/0 "Link to this type")

option()

========

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L12 "View Source")

Specs

-----

```

option() :: {:line_length, [integer](https://hexdocs.pm/elixir/typespecs.html#basic-types)()} | {:indent, [integer](https://hexdocs.pm/elixir/typespecs.html#basic-types)()}

```

Options that can be passed to [`Surface.Formatter.format_string!/2`](#format_string!/2).

* `:line_length` - Maximum line length before wrapping opening tags

* `:indent` - Starting indentation depth depending on the context of the ~F sigil

[Link to this type](#t:surface_node/0 "Link to this type")

surface\_node()

===============

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L31 "View Source")

Specs

-----

```

surface_node() ::

  [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()

  | {:interpolation, [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)(), [map](https://hexdocs.pm/elixir/typespecs.html#basic-types)()}

  | {[tag](#t:tag/0)(), [[attribute](#t:attribute/0)()], [[surface\_node](#t:surface_node/0)()], [map](https://hexdocs.pm/elixir/typespecs.html#basic-types)()}

```

A node output by `Surface.Compiler.Parser.parse`.

[Link to this type](#t:tag/0 "Link to this type")

tag()

=====

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L17 "View Source")

Specs

-----

```

tag() :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()

```

The name of an HTML/Surface tag, such as `div`, `ListItem`, or `#Markdown`.

[Link to this type](#t:whitespace/0 "Link to this type")

whitespace()

============

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L47 "View Source")

Specs

-----

```

whitespace() :: :newline | :space | :indent | :indent_one_less

```

Whitespace nodes that can be rendered by `Surface.Formatter.Render.node/2`.

The Surface parser does not return these, but formatter phases introduce these nodes

in preparation for rendering.

* `:newline` adds a newline (`\n`) character

* `:space` adds a space () character

* `:indent` adds spaces at the appropriate indentation amount

* `:indent_one_less` adds spaces at 1 indentation level removed (used for closing tags)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#format_string!/2 "Link to this function")

format\_string!(string, opts \\ [])

===================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L378 "View Source")

Specs

-----

```

format_string!([String.t](https://hexdocs.pm/elixir/String.html#t:t/0)(), [[option](#t:option/0)()]) :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()

```

Formats the given Surface code string. (Typically the contents of an `~F`

sigil or `.sface` file.)

In short:

* HTML/Surface elements are indented to the right of their parents.

* Attributes are split on multiple lines if the line is too long; otherwise on the same line.

* Elixir code snippets (inside `{ }`) are ran through the Elixir code formatter.

* Lack of whitespace is preserved, so that intended behaviors are not removed.

(For example, `<span>Foo bar baz</span>` will not have newlines or spaces added.)

Below the **Options** section is a non-exhaustive list of behaviors of the formatter.

Options

=======

* `:line_length` - the line length to aim for when formatting

the document. Defaults to 98. As with the Elixir formatter,

this value is used as reference but is not always enforced

depending on the context.

Indentation

===========

The formatter ensures that children are indented one tab (two spaces) in from

their parent.

Whitespace

==========

 Whitespace that exists

-------------------------

As in regular HTML, any string of continuous whitespace is considered

equivalent to any other string of continuous whitespace. There are four

exceptions:

1. Macro components (with names starting with `#`, such as `<#Markdown>`)

2. `<pre>` tags

3. `<code>` tags

4. `<script>` tags

The contents of those tags are considered whitespace-sensitive, and developers

should sanity check after running the formatter.

 Whitespace that doesn't exist (Lack of whitespace)

-----------------------------------------------------

As is sometimes the case in HTML, *lack* of whitespace is considered

significant. Instead of attempting to determine which contexts matter, the

formatter consistently retains lack of whitespace. This means that the

following

```

<div><p>Hello</p></div>

```

will not be changed. However, the following

```

<div> <p> Hello </p> </div>

```

will be formatted as

```

<div>

  <p>

    Hello

  </p>

</div>

```

because of the whitespace on either side of each tag.

To be clear, this example

```

<div> <p>Hello</p> </div>

```

will be formatted as

```

<div>

  <p>Hello</p>

</div>

```

because of the lack of whitespace in between the opening and closing `<p>` tags

and their child content.

 Splitting children onto separate lines

-----------------------------------------

In certain scenarios, the formatter will move nodes to their own line:

(Below, "element" means an HTML element or a Surface component.)

1. If an element contains other elements as children, it will be surrounded by newlines.

2. If there is a space after an opening tag or before a closing tag, it is converted to a newline.

3. If a closing tag is put on its own line, the formatter ensures there's a newline before the next sibling node.

Since SurfaceFormatter doesn't know if a component represents an inline or block element,

it does not currently make distinctions between elements that should or should not be

moved onto their own lines, other than the above rules.

This allows inline elements to be placed among text without splitting them onto their own lines:

```

The <b>Dialog</b> is a stateless component. All event handlers

had to be defined in the parent <b>LiveView</b>.

```

 Newline characters

---------------------

The formatter will not add extra newlines unprompted beyond moving nodes onto

their own line. However, if the input code has extra newlines, the formatter

will retain them but will collapse more than one extra newline into a single

one.

This means that

```

<p>Hello</p>

<p>Goodbye</p>

```

will be formatted as

```

<p>Hello</p>

<p>Goodbye</p>

```

HTML attributes and component props

===================================

HTML attributes such as `class` in `<p class="container">` and component

props such as `name` in `<Person name="Samantha">` are formatted to make use

of Surface features.

 Inline literals

------------------

String literals are placed after the `=` without any interpolation brackets (`{ }`). This means that

```

<Component foo={"hello"} />

```

will be formatted as

```

<Component foo="hello" />

```

Also, `true` boolean literals are formatted using the Surface shorthand

whereby you can simply write the name of the attribute and it is passed in as

`true`. For example,

```

<Component secure={true} />

```

and

```

<Component secure=true />

```

will both be formatted as

```

<Component secure />

```

 Interpolation (`{ }` brackets)

---------------------------------

Attributes that interpolate Elixir code with `{ }` brackets are ran through

the Elixir code formatter.

This means that:

* `<Foo num={123456} />` becomes `<Foo num={123_456} />`

* `list={[1,2,3]}` becomes `list={[1, 2, 3]}`

* `things={%{ one: "1", two: "2"}}` becomes `things={%{one: "1", two: "2"}}`

Sometimes the Elixir code formatter will add line breaks in the formatted

expression. In that case, SurfaceFormatter will ensure indentation lines up. If

there is a single attribute, it will keep the attribute on the same line as the

tag name, for example:

```

<Component list={[

  {"foo", foo},

  {"bar", bar}

]} />

```

However, if there are multiple attributes it will put them on separate lines:

```

<Child

  list={[

    {"foo", foo},

    {"bar", bar}

  ]}

  int={123}

/>

```

 Whitespace in string attributes

----------------------------------

### 

 Code semantics must be maintained

It's critical that a code formatter never change the semantics of the code

it modifies. In other words, the behavior of a program should never change

due to a code formatter.

The **Whitespace** section above outlines how `SurfaceFormatter` preserves

code semantics by refusing to modify contents of `<script>`, `<code>` and

`<pre>` tags as well as macro components. And for the same reason, the

formatter does not introduce whitespace between HTML tags when there is none.

### 

 Code semantics in string attributes

This principle is also relevant to string attributes, such as:

```

<MyComponent string_prop="  string  with  whitespace  " />

```

`SurfaceFormatter` cannot reliably guess whether application behavior will be

changed by formatting the contents of a string. For example, consider a

component with the following interface:

```

<List items="

apples (fuji)

oranges (navel)

bell peppers (green)

" />

```

The component internally splits on newline characters and outputs the following HTML:

```

<ul>

  <li>apples (fuji)</li>

  <li>oranges (navel)</li>

  <li>bell peppers (green)</li>

</ul>

```

If `SurfaceFormatter` assumes it is safe to modify whitespace in string

attributes, then the Surface code would likely change to this:

```

<List items="apples (fuji) oranges (navel) bell peppers (green)" />

```

Which would output the following HTML:

```

<ul>

  <li>apples (fuji) oranges (navel) bell peppers (green)</li>

</ul>

```

Notice that the behavior of the application would have changed simply by

running the formatter. It is for this reason that `SurfaceFormatter`

always retains precisely the same whitespace in attribute strings,

including both space and newline characters.

 Wrapping attributes on separate lines

----------------------------------------

In the **Interpolation (`{ }` brackets)** section we noted that attributes

will each be put on their own line if there is more than one attribute and at

least one contains a newline after being formatted by the Elixir code

formatter.

There is another scenario where attributes will each be given their own line:

**any time the opening tag would exceed `line_length` if put on one line**.

This value is provided in `.formatter.exs` and defaults to 98.

The formatter indents attributes one tab in from the start of the opening tag

for readability:

```

<div

  class="very long class value that causes this to exceed the established line length"

  aria-role="button"

>

```

If you desire to have a separate line length for [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) and [`mix surface.format`](Mix.Tasks.Surface.Format.html),

provide `surface_line_length` in `.formatter.exs` and it will be given precedence

when running [`mix surface.format`](Mix.Tasks.Surface.Format.html). For example:

```

# .formatter.exs

[

 surface\_line\_length: 120,

 import\_deps: [...],

 # ...

]

```

Developer Responsibility

========================

As with all changes (for both [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) and [`mix surface.format`](Mix.Tasks.Surface.Format.html)) it's

recommended that developers don't blindly run the formatter on an entire

codebase and commit, but instead sanity check each file to ensure the results

are desired.

[Link to this function](#is_element?/1 "Link to this function")

is\_element?(arg1)

==================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L415 "View Source")

Specs

-----

```

is_element?([surface\_node](#t:surface_node/0)()) :: [boolean](https://hexdocs.pm/elixir/typespecs.html#built-in-types)()

```

Returns true if the argument is an element (HTML element or surface

component), false otherwise.

[Link to this function](#render_contents_verbatim?/1 "Link to this function")

render\_contents\_verbatim?(tag)

================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter.ex#L423 "View Source")

Specs

-----

```

render_contents_verbatim?([tag](#t:tag/0)()) :: [boolean](https://hexdocs.pm/elixir/typespecs.html#built-in-types)()

```

Given a tag, return whether to render the contens verbatim instead of formatting them.

Specifically, don't modify contents of macro components or <pre> and <code> tags.





Surface.Formatter.NodeTranslator — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.NodeTranslator (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L1 "View Source")

================================================================================================================================================================================================

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[context\_for\_block(name, meta, state)](#context_for_block/3)

Callback implementation for `c:Surface.Compiler.NodeTranslator.context_for_block/3`.

[context\_for\_node(name, meta, state)](#context_for_node/3)

Callback implementation for `c:Surface.Compiler.NodeTranslator.context_for_node/3`.

[context\_for\_subblock(name, meta, state, parent\_context)](#context_for_subblock/4)

Callback implementation for `c:Surface.Compiler.NodeTranslator.context_for_subblock/4`.

[handle\_attribute(name, value, attr\_meta, state, context)](#handle_attribute/5)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_attribute/5`.

[handle\_block(name, expr, body, meta, state, context)](#handle_block/6)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_block/6`.

[handle\_block\_expression(block\_name, arg2, state, context)](#handle_block_expression/4)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_block_expression/4`.

[handle\_comment(comment, meta, state)](#handle_comment/3)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_comment/3`.

[handle\_expression(expression, meta, state)](#handle_expression/3)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_expression/3`.

[handle\_init(state)](#handle_init/1)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_init/1`.

[handle\_node(name, attributes, body, meta, state, context)](#handle_node/6)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_node/6`.

[handle\_subblock(name, expr, children, meta, state, arg6)](#handle_subblock/6)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_subblock/6`.

[handle\_tagged\_expression(binary, expression, meta, state)](#handle_tagged_expression/4)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_tagged_expression/4`.

[handle\_text(text, state)](#handle_text/2)

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_text/2`.

[to\_meta(meta)](#to_meta/1)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#context_for_block/3 "Link to this function")

context\_for\_block(name, meta, state)

======================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L126 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.context_for_block/3`.

[Link to this function](#context_for_node/3 "Link to this function")

context\_for\_node(name, meta, state)

=====================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L118 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.context_for_node/3`.

[Link to this function](#context_for_subblock/4 "Link to this function")

context\_for\_subblock(name, meta, state, parent\_context)

==========================================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L122 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.context_for_subblock/4`.

[Link to this function](#handle_attribute/5 "Link to this function")

handle\_attribute(name, value, attr\_meta, state, context)

==========================================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L52 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_attribute/5`.

[Link to this function](#handle_block/6 "Link to this function")

handle\_block(name, expr, body, meta, state, context)

=====================================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L22 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_block/6`.

[Link to this function](#handle_block_expression/4 "Link to this function")

handle\_block\_expression(block\_name, arg2, state, context)

============================================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L43 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_block_expression/4`.

[Link to this function](#handle_comment/3 "Link to this function")

handle\_comment(comment, meta, state)

=====================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L14 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_comment/3`.

[Link to this function](#handle_expression/3 "Link to this function")

handle\_expression(expression, meta, state)

===========================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L6 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_expression/3`.

[Link to this function](#handle_init/1 "Link to this function")

handle\_init(state)

===================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L4 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_init/1`.

[Link to this function](#handle_node/6 "Link to this function")

handle\_node(name, attributes, body, meta, state, context)

==========================================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L18 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_node/6`.

[Link to this function](#handle_subblock/6 "Link to this function")

handle\_subblock(name, expr, children, meta, state, arg6)

=========================================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L26 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_subblock/6`.

[Link to this function](#handle_tagged_expression/4 "Link to this function")

handle\_tagged\_expression(binary, expression, meta, state)

===========================================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L10 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_tagged_expression/4`.

[Link to this function](#handle_text/2 "Link to this function")

handle\_text(text, state)

=========================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L38 "View Source")

Callback implementation for `c:Surface.Compiler.NodeTranslator.handle_text/2`.

[Link to this function](#to_meta/1 "Link to this function")

to\_meta(meta)

==============

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/node_translator.ex#L130 "View Source")





Surface.Formatter.Phase — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Phase behaviour (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phase.ex#L1 "View Source")

=======================================================================================================================================================================================

A phase implementing a single "rule" for formatting code. These work as middleware

between `Surface.Compiler.Parser.parse` and `Surface.Formatter.Render.node/2`

to modify node lists before they are rendered.

Some phases rely on other phases; `@moduledoc`s should make this explicit.

For reference, the formatter operates by running these phases in the following order:

* [`Surface.Formatter.Phases.TagWhitespace`](Surface.Formatter.Phases.TagWhitespace.html)

* [`Surface.Formatter.Phases.Newlines`](Surface.Formatter.Phases.Newlines.html)

* [`Surface.Formatter.Phases.SpacesToNewlines`](Surface.Formatter.Phases.SpacesToNewlines.html)

* [`Surface.Formatter.Phases.Indent`](Surface.Formatter.Phases.Indent.html)

* [`Surface.Formatter.Phases.FinalNewline`](Surface.Formatter.Phases.FinalNewline.html)

* [`Surface.Formatter.Phases.BlockExceptions`](Surface.Formatter.Phases.BlockExceptions.html)

* [`Surface.Formatter.Phases.Render`](Surface.Formatter.Phases.Render.html)

[Link to this section](#summary)

 Summary

==========================================

[Types](#types)

----------------

[node\_transformer()](#t:node_transformer/0)

A node that takes a list of nodes and returns them back after applying a transformation

[nodes()](#t:nodes/0)

A list of nodes

[Functions](#functions)

------------------------

[transform\_element\_children(nodes, transform)](#transform_element_children/2)

Given a list of nodes, find all "element" nodes (HTML elements or Surface components)

and transform children of those nodes using the given function.

[transform\_elements\_and\_descendants(nodes, transform)](#transform_elements_and_descendants/2)

Given a list of nodes, find all "element" nodes (HTML elements or Surface components)

and transform children of those nodes using the given function.

[Callbacks](#callbacks)

------------------------

[run(nodes, opts)](#c:run/2)

The function implementing the phase. Returns the given nodes with the transformation applied.

[Link to this section](#types)

Types

=====================================

[Link to this type](#t:node_transformer/0 "Link to this type")

node\_transformer()

===================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phase.ex#L28 "View Source")

Specs

-----

```

node_transformer() :: ([nodes](#t:nodes/0)() -> [nodes](#t:nodes/0)())

```

A node that takes a list of nodes and returns them back after applying a transformation

[Link to this type](#t:nodes/0 "Link to this type")

nodes()

=======

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phase.ex#L31 "View Source")

Specs

-----

```

nodes() :: [[Surface.Formatter.formatter\_node](Surface.Formatter.html#t:formatter_node/0)()]

```

A list of nodes

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#transform_element_children/2 "Link to this function")

transform\_element\_children(nodes, transform)

==============================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phase.ex#L40 "View Source")

Specs

-----

```

transform_element_children([nodes](#t:nodes/0)(), [node\_transformer](#t:node_transformer/0)()) :: [nodes](#t:nodes/0)()

```

Given a list of nodes, find all "element" nodes (HTML elements or Surface components)

and transform children of those nodes using the given function.

Useful for recursing deeply through the entire tree of nodes.

[Link to this function](#transform_elements_and_descendants/2 "Link to this function")

transform\_elements\_and\_descendants(nodes, transform)

=======================================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phase.ex#L60 "View Source")

Given a list of nodes, find all "element" nodes (HTML elements or Surface components)

and transform children of those nodes using the given function.

Recurses deeply through the tree, unlike `transform_element_children`, which only affects

a single layer.

[Link to this section](#callbacks)

Callbacks

=============================================

[Link to this callback](#c:run/2 "Link to this callback")

run(nodes, opts)

================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phase.ex#L23 "View Source")

Specs

-----

```

run(

  nodes :: [[Surface.Formatter.formatter\_node](Surface.Formatter.html#t:formatter_node/0)()],

  opts :: [[Surface.Formatter.option](Surface.Formatter.html#t:option/0)()]

) :: [[Surface.Formatter.formatter\_node](Surface.Formatter.html#t:formatter_node/0)()]

```

The function implementing the phase. Returns the given nodes with the transformation applied.





Surface.Formatter.Phases.BlockExceptions — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Phases.BlockExceptions (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/block_exceptions.ex#L1 "View Source")

================================================================================================================================================================================================================

Handle exceptional case for blocks.

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[run(nodes, opts)](#run/2)

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[transform\_block(node)](#transform_block/1)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#run/2 "Link to this function")

run(nodes, opts)

================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/block_exceptions.ex#L9 "View Source")

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[Link to this function](#transform_block/1 "Link to this function")

transform\_block(node)

======================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/block_exceptions.ex#L13 "View Source")





Surface.Formatter.Phases.FinalNewline — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Phases.FinalNewline (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/final_newline.ex#L1 "View Source")

==========================================================================================================================================================================================================

Add a newline after all of the nodes if one was present on the original input

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[run(nodes, opts)](#run/2)

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#run/2 "Link to this function")

run(nodes, opts)

================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/final_newline.ex#L7 "View Source")

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).





Surface.Formatter.Phases.Indent — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Phases.Indent (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/indent.ex#L1 "View Source")

=============================================================================================================================================================================================

Adds indentation nodes (`:indent` and `:indent_one_less`) where appropriate.

`Surface.Formatter.Render.node/2` is responsible for adding the appropriate

level of indentation. It keeps track of the indentation level based on how

"nested" a node is. While running Formatter Phases, it's not necessary to

keep track of that detail.

`:indent_one_less` exists to notate the indentation that should occur before

a closing tag, which is one less than its children.

Relies on `Newlines` phase, which collapses :newline nodes to at most 2 in a row.

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[add\_indentation(nodes, accumulated \\ [])](#add_indentation/2)

[run(nodes, opts)](#run/2)

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#add_indentation/2 "Link to this function")

add\_indentation(nodes, accumulated \\ [])

==========================================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/indent.ex#L31 "View Source")

[Link to this function](#run/2 "Link to this function")

run(nodes, opts)

================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/indent.ex#L19 "View Source")

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).





Surface.Formatter.Phases.Newlines — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Phases.Newlines (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/newlines.ex#L1 "View Source")

=================================================================================================================================================================================================

Standardizes usage of newlines.

* Prevents more than 1 empty line in a row.

* Prevents an empty line separating an opening/closing tag from the contents inside.

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[run(nodes, opts)](#run/2)

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#run/2 "Link to this function")

run(nodes, opts)

================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/newlines.ex#L12 "View Source")

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).





Surface.Formatter.Phases.Render — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Phases.Render (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/render.ex#L1 "View Source")

=============================================================================================================================================================================================

Render the formatted Surface code after it has run through the other

transforming phases.

[Link to this section](#summary)

 Summary

==========================================

[Types](#types)

----------------

[render\_attribute\_option()](#t:render_attribute_option/0)

[Functions](#functions)

------------------------

[render\_node(segment, opts)](#render_node/2)

Given a [`Surface.Formatter.formatter_node/0`](Surface.Formatter.html#t:formatter_node/0) node, render it to a string

for writing back into a file.

[run(nodes, opts)](#run/2)

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[Link to this section](#types)

Types

=====================================

[Link to this type](#t:render_attribute_option/0 "Link to this type")

render\_attribute\_option()

===========================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/render.ex#L309 "View Source")

Specs

-----

```

render_attribute_option() :: {:attributes, [[Surface.Formatter.attribute](Surface.Formatter.html#t:attribute/0)()]}

```

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#render_node/2 "Link to this function")

render\_node(segment, opts)

===========================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/render.ex#L30 "View Source")

Specs

-----

```

render_node([Surface.Formatter.formatter\_node](Surface.Formatter.html#t:formatter_node/0)(), [[Surface.Formatter.option](Surface.Formatter.html#t:option/0)()]) ::

  [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)() | nil

```

Given a [`Surface.Formatter.formatter_node/0`](Surface.Formatter.html#t:formatter_node/0) node, render it to a string

for writing back into a file.

[Link to this function](#run/2 "Link to this function")

run(nodes, opts)

================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/render.ex#L10 "View Source")

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).





Surface.Formatter.Phases.SpacesToNewlines — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Phases.SpacesToNewlines (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/spaces_to_newlines.ex#L1 "View Source")

===================================================================================================================================================================================================================

In a variety of scenarios, converts :space nodes to :newline nodes.

(Below, "element" means an HTML element or a Surface component.)

1. If an element contains other elements as children, surround it with newlines.

2. If there is a space after an opening tag or before a closing tag, convert it to a newline.

3. If there is a closing tag on its own line, ensure there's a newline before the next sibling node.

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[run(nodes, opts)](#run/2)

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#run/2 "Link to this function")

run(nodes, opts)

================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/spaces_to_newlines.ex#L15 "View Source")

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).





Surface.Formatter.Phases.TagWhitespace — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Phases.TagWhitespace (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/tag_whitespace.ex#L1 "View Source")

============================================================================================================================================================================================================

Inspects all text nodes and "tags" leading and trailing whitespace

by converting it into a `:space` atom or a list of `:newline` atoms.

This is the first phase of formatting, and all other phases depend on it.

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[run(nodes, opts)](#run/2)

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[tag\_whitespace(text)](#tag_whitespace/1)

This function takes a node provided by `Surface.Compiler.Parser.parse`

and converts the leading/trailing whitespace into [`Surface.Formatter.whitespace/0`](Surface.Formatter.html#t:whitespace/0) nodes.

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#run/2 "Link to this function")

run(nodes, opts)

================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/tag_whitespace.ex#L12 "View Source")

Callback implementation for [`Surface.Formatter.Phase.run/2`](Surface.Formatter.Phase.html#c:run/2).

[Link to this function](#tag_whitespace/1 "Link to this function")

tag\_whitespace(text)

=====================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/phases/tag_whitespace.ex#L23 "View Source")

Specs

-----

```

tag_whitespace([Surface.Formatter.surface\_node](Surface.Formatter.html#t:surface_node/0)()) :: [

  [Surface.Formatter.surface\_node](Surface.Formatter.html#t:surface_node/0)() | :newline | :space

]

```

This function takes a node provided by `Surface.Compiler.Parser.parse`

and converts the leading/trailing whitespace into [`Surface.Formatter.whitespace/0`](Surface.Formatter.html#t:whitespace/0) nodes.





Surface.Formatter.Plugin — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

Surface.Formatter.Plugin (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/plugin.ex#L1 "View Source")

===============================================================================================================================================================================

An [Elixir formatter

plugin](https://hexdocs.pm/mix/1.13.0-rc.1/Mix.Tasks.Format.html#module-plugins)

for Surface code.

Elixir 1.13 introduced formatter plugins, allowing the Surface formatter to

run during [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) instead of requiring developers to run [`mix surface.format`](Mix.Tasks.Surface.Format.html) separately.

To format Surface code using Elixir 1.12 or earlier, use [`mix surface.format`](Mix.Tasks.Surface.Format.html).

### 

`.formatter.exs` setup

Add to `:plugins` in `.formatter.exs` in order to format `~F` sigils and

`.sface` files when running [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html).

Only works on files matching patterns in `:inputs`, so add patterns for

all Surface files to ensure they're formatted.

```

# in .formatter.exs

[

 ...,

 plugins: [Surface.Formatter.Plugin]

 # add patterns matching all .sface files and all .ex files with ~F sigils

 inputs: ["\*.{ex,exs}", "{config,lib,test}/\*\*/\*.{ex,exs,sface}"],

 # THE FOLLOWING ARE OPTIONAL:

 # set desired line length for both Elixir's code formatter and this one

 # (only affects opening tags in Surface)

 line\_length: 80,

 # or, set line length only for Surface code (overrides `line\_length`)

 surface\_line\_length: 84

]

```

### 

 Options

In `.formatter.exs`, the following options can be provided:

* `:line_length` - Maximum line length of an opening tag before

SurfaceFormatter attempts to wrap it onto multiple lines. This option is

used by [`Code.format_string!/2`](https://hexdocs.pm/elixir/Code.html#format_string!/2) and [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) and defaults to 98.

* `:surface_line_length` - Overrides `:line_length`; useful for setting

separate desired line length for Surface code and non-Surface Elixir code.

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[features(opts)](#features/1)

Callback implementation for [`Mix.Tasks.Format.features/1`](https://hexdocs.pm/mix/Mix.Tasks.Format.html#c:features/1).

[format(contents, opts)](#format/2)

Callback implementation for [`Mix.Tasks.Format.format/2`](https://hexdocs.pm/mix/Mix.Tasks.Format.html#c:format/2).

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#features/1 "Link to this function")

features(opts)

==============

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/plugin.ex#L54 "View Source")

Callback implementation for [`Mix.Tasks.Format.features/1`](https://hexdocs.pm/mix/Mix.Tasks.Format.html#c:features/1).

[Link to this function](#format/2 "Link to this function")

format(contents, opts)

======================

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/surface/formatter/plugin.ex#L58 "View Source")

Callback implementation for [`Mix.Tasks.Format.format/2`](https://hexdocs.pm/mix/Mix.Tasks.Format.html#c:format/2).





mix surface.format — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

mix surface.format (SurfaceFormatter v0.7.5)

[View Source](https://github.com/surface-ui/surface_formatter/blob/v0.7.5/lib/mix/tasks/surface/format.ex#L1 "View Source")

=========================================================================================================================================================================

**To format Surface code using Elixir 1.13 or later, use

[`Surface.Formatter.Plugin`](Surface.Formatter.Plugin.html).**

Formats Surface `~F` sigils and `.sface` files in the given files and patterns.

```

$ mix surface.format "lib/**/*.{ex,exs}" "test/**/*.{ex,exs}"

$ cat path/to/file.ex | mix surface.format -

```

Takes the same options as [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) except for `--check-equivalent`.

 Formatting options

---------------------

Like [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html), the Surface formatter reads a `.formatter.exs` file in the

current directory for formatter configuration. The Surface formatter accepts

the same options as [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html). Read more about the expected format of

`.formatter.exs` and the shared configuration options

[documented here](https://hexdocs.pm/mix/master/Mix.Tasks.Format.html#module-formatting-options).

The Surface formatter also takes the following two additional options

specified in `.formatter.exs`:

* `:surface_line_length` overrides `:line_length` only for [`mix surface.format`](#content)

(`:line_length` is used otherwise, or defaults to 98)

* `:surface_inputs` overrides `:inputs` only for [`mix surface.format`](#content)

(`:inputs` is used otherwise)

 Task-specific options

------------------------

The Surface formatter accepts the same task-specific options as [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html).

[Read documentation for the options documented here.](https://hexdocs.pm/mix/master/Mix.Tasks.Format.html#module-task-specific-options).

For quick reference, here are some examples of using these options:

```

$ mix surface.format --check-formatted

** (Mix) mix surface.format failed due to --check-formatted.

The following files are not formatted:

  * path/to/component.ex

  * path/to/file.sface

```

```

$ mix surface.format --dry-run

```

```

$ mix surface.format --dot-formatter path/to/.formatter.exs

```

You can also use the same syntax as [`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) for specifying which files to

format:

```

$ mix surface.format path/to/file.ex "lib/**/*.{ex,exs}" "test/**/*.{ex,exs}"

```





API Reference — SurfaceFormatter v0.7.5

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

 API Reference SurfaceFormatter v0.7.5

=======================================

 Modules

----------

[Surface.Formatter](Surface.Formatter.html)

Functions for formatting Surface code snippets.

[Surface.Formatter.NodeTranslator](Surface.Formatter.NodeTranslator.html)

[Surface.Formatter.Phase](Surface.Formatter.Phase.html)

A phase implementing a single "rule" for formatting code. These work as middleware

between `Surface.Compiler.Parser.parse` and `Surface.Formatter.Render.node/2`

to modify node lists before they are rendered.

[Surface.Formatter.Phases.BlockExceptions](Surface.Formatter.Phases.BlockExceptions.html)

Handle exceptional case for blocks.

[Surface.Formatter.Phases.FinalNewline](Surface.Formatter.Phases.FinalNewline.html)

Add a newline after all of the nodes if one was present on the original input

[Surface.Formatter.Phases.Indent](Surface.Formatter.Phases.Indent.html)

Adds indentation nodes (`:indent` and `:indent_one_less`) where appropriate.

[Surface.Formatter.Phases.Newlines](Surface.Formatter.Phases.Newlines.html)

Standardizes usage of newlines.

[Surface.Formatter.Phases.Render](Surface.Formatter.Phases.Render.html)

Render the formatted Surface code after it has run through the other

transforming phases.

[Surface.Formatter.Phases.SpacesToNewlines](Surface.Formatter.Phases.SpacesToNewlines.html)

In a variety of scenarios, converts :space nodes to :newline nodes.

[Surface.Formatter.Phases.TagWhitespace](Surface.Formatter.Phases.TagWhitespace.html)

Inspects all text nodes and "tags" leading and trailing whitespace

by converting it into a `:space` atom or a list of `:newline` atoms.

[Surface.Formatter.Plugin](Surface.Formatter.Plugin.html)

An [Elixir formatter

plugin](https://hexdocs.pm/mix/1.13.0-rc.1/Mix.Tasks.Format.html#module-plugins)

for Surface code.

 Mix Tasks

------------

[mix surface.format](Mix.Tasks.Surface.Format.html)

**To format Surface code using Elixir 1.13 or later, use

[`Surface.Formatter.Plugin`](Surface.Formatter.Plugin.html).**

