Visual Studio Codeのhtmlフォーマッターのメモ

# 概要

Visual Studio Code(以降VSCodeと記述)のデフォルトのhtmlフォーマッターをカスタマイズしたときのメモです。
VSCodeのhtmlフォーマッターは[js-beautify] (https://www.npmjs.com/package/js-beautify)というパッケージをベースにしており、拡張機能を追加することなくhtmlファイルのフォーマットを行うことができます。
（なお、[Beautify] (https://marketplace.visualstudio.com/items?itemName=HookyQR.beautify)という拡張機能がありますが、これがインストールされている訳ではないようです。）

htmlファイルをフォーマットするには、フォーマットしたい範囲を選択状態にして<kbd>Ctrl + K</kbd> <kbd>Ctrl + F</kbd>を押します。

**環境**

* Windows 10 Professional
* VSCode 1.24.1

**参考**

* [HTML programming in VS Code] (https://code.visualstudio.com/docs/languages/html)

# 設定のデフォルト値

<kbd>Ctrl + ,</kbd>を押して設定画面を開きます。検索フィールドで"html.format"と入力してフォーマッターの設定に関する項目を絞り込みます。
下記は、VSCode 1.24.1での設定のデフォルト値です。

```js
{
  // コンテンツを再フォーマットしてはならないタグをコンマで区切ってリストにします。'null' は、既定値の'pre' タグを表します。
  "html.format.contentUnformatted": "pre,code,textarea",

  // 既定のHTMLフォーマッタを有効/無効にします
  "html.format.enable": true,

  // 末尾に改行を入れます。
  "html.format.endWithNewline": false,

  // 直前に改行を1つ入れるタグの、コンマで区切られたリストです。'null'は、既定値の"head, body, /html" を表します。
  "html.format.extraLiners": "head, body, /html",

  // 書式設定とインデント{{#foo}}および{{/foo}}。
  "html.format.indentHandlebars": false,

  // <head>セクションと<body>セクションをインデントします。
  "html.format.indentInnerHtml": false,

  // 1つのチャンク内に保持できる改行の最大数。無制限にするには、'null'を使います。
  "html.format.maxPreserveNewLines": null,

  // 要素の前にある既存の改行を保持するかどうか。要素の前でのみ機能し、タグの内側やテキストに対しては機能しません。
  "html.format.preserveNewLines": true,

  // 再フォーマットしてはならないタグの、コンマ区切りの一覧。'null'の場合、既定で https://www.w3.org/TR/html5/dom.html#phrasing-content にリストされているすべてのタグになります。
  "html.format.unformatted": "wbr",

  // 属性を折り返します。
  "html.format.wrapAttributes": "auto",

  // 1行あたりの最大文字数 (0=無効にする)。
  "html.format.wrapLineLength": 120
}
```

# 設定値とフォーマット結果

以降は、設定値を変えてhtmlファイルがどのようにフォーマットされるか確認した結果です。

## html.format.enable

> 既定のHTMLフォーマッタを有効/無効にします

設定値は `true`(default) または `false`。
この設定はフォーマッターを有効にするかどうかなのでフォーマット結果は省略します。
デフォルトでは有効なので、他の拡張機能でフォーマットしたい場合などは無効にします。


## html.format.indentInnerHtml

> <head>セクションと<body>セクションをインデントします。

設定値は `true` または `false`(default)。
`true`にすると、headタグとbodyタグをインデントします。

### format前

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
<div id="app">
<!--省略-->
</div>
</body>
</html>
```

### format後

**true**

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
  </head>
  <body>
    <div id="app">
      <!--省略-->
    </div>
  </body>
</html>
```

**false(default)**

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
  <div id="app">
    <!--省略-->
  </div>
</body>
</html>
```


## html.format.indentHandlebars

> 書式設定とインデント{{#foo}}および{{/foo}}。

設定値は `true` または `false`(default)。
`true`にすると、Handlebarsの式(`{{expression}}`)の内側がHandlebarsの式を基準にインデントされます。
なお、設定値に関わらずHandlebarsの式自体もインデントされます。

* [Handlebars] (http://handlebarsjs.com/)は、JavaScriptで使えるテンプレートエンジンです。

### format前

```html
<div class="container">
{{#if authenticated}}
<div class="primary">
<p>認証済み</p>
</div>
{{else}}
<div class="warning">
<p>未認証</p>
</div>
{{/if}}
</div>
```

### format後

**true**

Handlebarsの式の内側が式を基準にインデントされます。

```html
<div class="container">
  {{#if authenticated}}
    <div class="primary">
      <p>認証済み</p>
    </div>
  {{else}}
    <div class="warning">
      <p>未認証</p>
    </div>
  {{/if}}
</div>
```

**false(default)**

Handlebarsの式のインデントとは関係なく内側のタグがインデントされます。

```html
<div class="container">
  {{#if authenticated}}
  <div class="primary">
    <p>認証済み</p>
  </div>
  {{else}}
  <div class="warning">
    <p>未認証</p>
  </div>
  {{/if}}
</div>
```


## html.format.extraLiners

> 直前に改行を1つ入れるタグの、コンマで区切られたリストです。'null'は、既定値の"head, body, /html" を表します。

設定値はタグ（複数ある場合はカンマ区切りで指定）または'null'。デフォルトは"head, body, /html"。

### format前

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
<div id="app">
<!--省略-->
</div>
</body>
</html>
```

### format後

**既定値(head, body, /html)**

```html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>

<body>
  <div id="app">
    <!--省略-->
  </div>
</body>

</html>
```

**空行をいれない("")**

どのタグの前にも空行を入れたくない場合は設定値に""を指定します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
  <div id="app">
    <!--省略-->
  </div>
</body>
</html>
```

<!--
html.format.wrapLineLength

> 1行あたりの最大文字数 (0=無効にする)。

設定値は0以上の整数値でデフォルトは120。0を指定した場合は無制限。

format前

```html
todo
```

format後

```html
todo
```
-->

## html.format.wrapAttributes

> 属性を折り返します。

設定値は以下の通り。デフォルトは`auto`。

* `auto` : Wrap when the line length is exceeded
    * 行の長さが最大文字数を超えたときに折り返す
* `force` : Wrap all attributes, except first
    * 2つ目の属性から折り返す
* `force-aligned` : Wrap all attributes, except first, and align attributes
    * 2つ目の属性から折り返し、属性の並びを揃える
* `force-expand-multiline` : Wrap all attributes
    * 全ての属性を折り返す、ただし属性が1つだけの場合は折り返さない

### format前

```html
<p class="desc">description</p>
<p class="desc" data-index-1="aaa" data-index-2="bbb" data-index-3="ccc">description</p>
```

### format後

**auto**

暫定的に`"html.format.wrapLineLength": 30`に設定した状態でフォーマットしました。

```html
<p class="desc">description</p>
<p class="desc" data-index-1="aaa"
  data-index-2="bbb" data-index-3="ccc">description</p>
```

**force**

```html
<p class="desc">description</p>
<p class="desc"
  data-index-1="aaa"
  data-index-2="bbb"
  data-index-3="ccc">description</p>
```

**force-aligned**

```html
<p class="desc">description</p>
<p class="desc"
   data-index-1="aaa"
   data-index-2="bbb"
   data-index-3="ccc">description</p>
```

**force-expand-multiline**

```html
<p class="desc">description</p>
<p
  class="desc"
  data-index-1="aaa"
  data-index-2="bbb"
  data-index-3="ccc"
>description</p>
```


## html.format.endWithNewline

> 末尾に改行を入れます。

設定値は `true` または `false`(default)。
`true`にするとファイルの一番最後の行に改行が入ります。

### format前

```html
<!--省略-->
</div>
</body>
</html>
```

### format後

**true**

```html
      <!--省略-->
    </div>
  </body>
</html>

```

**false(default)**

```html
      <!--省略-->
    </div>
  </body>
</html>
```

 
## html.format.preserveNewLines

> 要素の前にある既存の改行を保持するかどうか。要素の前でのみ機能し、タグの内側やテキストに対しては機能しません。

設定値は `true`(default) または `false`。
`true`にすると既存の空行を保持します。

### format前

```html
<div>

<h1>title</h1>


<p>description</p>

</div>
```

### format後

**true(default)**

空行はそのまま保持されます。

```html
<div>

  <h1>title</h1>


  <p>description</p>

</div>
```

**false**

空行は削除されます。

```html
<div>
  <h1>title</h1>
  <p>description</p>
</div>
```


## html.format.maxPreserveNewLines

> 1つのチャンク内に保持できる改行の最大数。無制限にするには、'null'を使います。

設定値は `null`(default)か、1以上の整数値。
連続する空行の最大行数を指定します。デフォルトは'null'なので無制限です。

### format前

```html
<div>
<h1>title</h1>



<p>description</p>


</div>
```

### format後

**既定値(null)**

空行はそのまま保持されます。

```html
<div>
  <h1>title</h1>



  <p>description</p>


</div>
```

**1を指定**

1を指定すると、空行は最大1行までになります。

```html
<div>
  <h1>title</h1>

  <p>description</p>

</div>
```


## html.format.unformatted

>  再フォーマットしてはならないタグの、コンマ区切りの一覧。
> 'null'の場合、既定で https://www.w3.org/TR/html5/dom.html#phrasing-content にリストされているすべてのタグになります。

設定値はタグ（複数ある場合はカンマ区切りで指定）または'null'。デフォルトは"wbr"。
インライン要素などフォーマットしたくないタグを指定します。

### format前

```html
<p>The following span is an <span class="highlight">inline element</span>;
its background has been colored to display both the beginning and end of
the inline element's influence.</p>
```

### format後

**既定値(wbr)**

デフォルトではspanタグで改行されてしまいます。

```html
<p>The following span is an
  <span class="highlight">inline element</span>; its background has been colored to display both the beginning and end of the inline element's
  influence.</p>
```

**spanを指定**

フォーマットしないタグにspanを指定すると、spanタグでは改行は行われません。

```html
<p>The following span is an <span class="highlight">inline element</span>; its background has been colored to display both
  the beginning and end of the inline element's influence.</p>
```


## html.format.contentUnformatted

> コンテンツを再フォーマットしてはならないタグをコンマで区切ってリストにします。'null'は、既定値の'pre'タグを表します。

設定値はタグ（複数ある場合はカンマ区切りで指定）または'null'。デフォルトは"pre,code,textarea"。
デフォルトではscriptタグは含まれていないので、scriptタグでJavaScriptコードを埋め込んでいる場合はフォーマットするとコードが整形されてしまうので注意が必要です。

### format前

```html
<div>
<textarea>aaaaaa
bbbbbb
cccccc

dddddd</textarea>
</div>
```

### format後

**既定値(pre,code,textarea)**

```html
<div>
  <textarea>aaaaaa
bbbbbb
cccccc

dddddd</textarea>
</div>
```

**null(pre)**

textareaが対象から外れたのでコンテンツまでフォーマットされています。

```html
<div>
  <textarea>aaaaaa bbbbbb cccccc dddddd

  </textarea>
</div>
```