Emmetを利用して連番テキストを作る


## はじめに

[atomで置換を使って連番テキストを作る](http://qiita.com/Luecy1/items/f8894c2e26677d664672)という記事を見つけた。
私も以前は似たような方法を利用していたが、最近はEmmetを利用して連番テキストを生成しているので共有したい。

## 前提: Emmetとは

HTMLを書く方の多くはご存知だろうが、Emmetとは簡潔に言ってしまえばHTML/CSSの短縮構文と、それをHTML/CSSに変換するプログラムのことだ。
Emmetは多数のエディタでプラグインとして提供されており、[Atom用も提供されている](https://atom.io/packages/emmet)。
例えば元記事で行っている`input`タグを10個生成したければ下記のように書く。

```emmet:変換前
input[type=text name=hoge$ id=hoge$]*10
```

このあと行末で`Tab`キーを押せばHTMLに変換される。

```html:変換後
<input type="text" name="hoge1" id="hoge1">
<input type="text" name="hoge2" id="hoge2">
<input type="text" name="hoge3" id="hoge3">
<input type="text" name="hoge4" id="hoge4">
<input type="text" name="hoge5" id="hoge5">
<input type="text" name="hoge6" id="hoge6">
<input type="text" name="hoge7" id="hoge7">
<input type="text" name="hoge8" id="hoge8">
<input type="text" name="hoge9" id="hoge9">
<input type="text" name="hoge10" id="hoge10">
```

これだけであればわざわざEmmetを使わずとも置換機能で事足りると思うが、Emmetを使えば置換機能でやるのが面倒くさそうな構造であってもすんなりと書ける。

```emmet:変換前
table#list>thead>th.no{No.}+th.content^+tbody>tr.line$$$*3>th.no{$}+td.content
```

```html:変換後
<table id="list">
  <thead>
    <th class="no">No.</th>
    <th class="content"></th>
  </thead>
  <tbody>
    <tr class="line001">
      <th class="no">1</th>
      <td class="content"></td>
    </tr>
    <tr class="line002">
      <th class="no">2</th>
      <td class="content"></td>
    </tr>
    <tr class="line003">
      <th class="no">3</th>
      <td class="content"></td>
    </tr>
  </tbody>
</table>
```

このようにゼロパディングもお手の物だ。

## 本題: 連番テキストを作る

さて、本題は連番を含むHTMLを作るのではなく、連番テキストを作るのである。
結論から書くとこのように書けばよい。

```
{第$$$行目${newline}}*100
```

この状態で`Tab`キーを押すと

```
第001行目
第002行目
第003行目
(中略)
第098行目
第099行目
第100行目
```

と生成される。

### 理屈

1. 文字を入力する場合は`{文字}`と書く
2. 改行を入れる場合は`${newline}`と書く

Emmetは記法にさえ則っていればちゃんと変換してくれる。
そのため、別にタグを含む必要はないのである。
ただし、AtomのEmmetプラグインの場合ファイルタイプは`HTML`にしておく必要がある。

## おまけ: Vimの場合

Vimであれば`文字`と入力して`yy`(行をコピー)して`99p`(99回貼り付け)とすれば`文字`を100行入力できる。
また、インクリメントする`<Ctrl-a>`やデクリメントする`<Ctrl-x>`というキーバインドがあるが、ビジュアルモードで対象数字を選択した上で`g<Ctrl-a>`または`g<Ctrl-x>`とすると連番になるようにインクリメント、デクリメントしてくれる。

そのため

```
第001行
```

と書いて`yy`、`99p`とし、ビジュアルモードで`001`を2行目から100行目まで選択してから`g<Ctrl-a>`と入力すると

```
第001行目
第002行目
第003行目
(中略)
第098行目
第099行目
第100行目
```

となる。

**追記**

ビジュアルモードで指定して一括インクリメント、デクリメントはパッチ7.4.754で取り込まれた機能のようである（参考: [Visual モード時の CTRL-A/CTRL-X について](http://vim-jp.org/blog/2015/06/30/visual-ctrl-a-ctrl-x.html)。
比較的新しい機能であり、Linuxディストリビューション公式で配布しているパッケージだと対応していない場合もあるため注意が必要となる。

**以上追記**

**2016/04/19 追記**

コメントにて@YamasakiKenta氏に補足をいただいたのだが、上記の手順は設定によってはこちらの動作と異なる。

    'nrformats' 'nf'        string  (default "bin,octal,hex")
                        バッファについてローカル
                        {Vi にはない}
        テキスト内の数をコマンド CTRL-A や CTRL-X で増減させるとき、 Vimに何を
        数として認識させるかを設定する。これらのコマンドの詳しい情報については
        |CTRL-A| を参照。
        alpha   これが含まれると、単一のアルファベットも増減操作を受ける。これ
                は a), b) 等の、文字を使ったリストに対して便利である。
                                                        *octal-nrformats*
        octal   これが含まれると、0 で始まる数は8進数として認識される。例:
                "007" の上で CTRL-A を使うと "010" となる。
        hex     これが含まれると、"0x" や "0X" で始まる数は16進数として認識さ
                れる。例: "0x100" の上で CTRL-X を使うと "0x0ff" となる。
        bin     If included, numbers starting with "0b" or "0B" will be
                considered to be binary.  Example: Using CTRL-X on
                "0b1000" subtracts one, resulting in "0b0111".
        1 から 9 の数字で始まる数は、常に10進数として認識される。8進数または16
        進数として認識されない数も10進数として認識される。
 
(引用元: [options - Vim日本語ドキュメント](http://vim-jp.org/vimdoc-ja/options.html#'nrformats'))

[私のvimrc](https://github.com/fkfk/vim-dotfiles/blob/master/.vimrc#L178)では`alpha,hex`を指定しているが、デフォルト値は`bin,octal,hex`となっている（`bin`は最近追加されたもののようで、ローカルに保存しているマニュアルでは`octal,hex`となっている)。
この設定を書いた当時恐らく学生だったと思うが、8進数を扱う機会などなかったので`alpha,hex`としていたのだと思う。
デフォルト設定のまま当手順で操作すると8進数扱いとなり、想定通りにはならないのでご注意いただきたい。

**以上2016/04/16追記**

なお、Atomでも[vim-mode-plus](https://atom.io/packages/vim-mode-plus)で似たような操作が出来ることを確認したが([vim-mode](https://atom.io/packages/vim-mode)では未確認)、

```
第001行目
第1行目
第2行目
(中略)
第97行目
第98行目
第99行目
```

とゼロパディングを削除してしまった上に、ビジュアルモードで選択した1行目はインクリメントしないようである。
この辺りVimとは使用感が異なり未だに戸惑うため、Atomを利用するときは上記Emmetを利用した連番テキスト生成を用いている。