Sublime Text 2 + Emmet でRetina用に半分の画像サイズでimgタグを挿入する方法

## 概要
Sublime Text2 には Emmetをインストールした状態でhtmlを編集時に<code>cmd + shift + p -> "Emmet : Update Image Size"</code>で指定したパスの画像を<code>width</code>と<code>height</code>込みでimageタグを挿入してくれるという便利機能がある。

```html:sample.html
<img src="/img/sample.jpg" height="136" width="300" alt="">
```

Retinaを考慮したスマートフォン用にマークアップしている際はこの自動挿入される<code>width</code>と<code>height</code>のサイズを半分にする必要があるがそれができない。

既存の<code>"Emmet : Update Image Size"</code>を編集してRetina用に半分のサイズを自動挿入する方法を説明する。

## 1. スクリプトファイルを開く
1. メニューの<code>Preferences -> Browse Packages…</code>でFinder開く
2. 開いたFinderの<code>Emmet -> emmet -> emmet-app.js</code>を開く

## 2. 編集

### updateImageSizeHTMLを下記で上書き

```javascript:emmet-app.js
function updateImageSizeHTML(editor, isRetina) {
  var offset = editor.getCaretPos(),
      rate = isRetina ? 0.5 : 1;

  // find tag from current caret position
  var info = require('editorUtils').outputInfo(editor);
  var xmlElem = require('xmlEditTree').parseFromPosition(info.content, offset, true);
  if (xmlElem && (xmlElem.name() || '').toLowerCase() == 'img') {
    getImageSizeForSource(editor, xmlElem.value('src'), function(size) {
      if (size) {
        var compoundData = xmlElem.range(true);
        xmlElem.value('width', Math.floor(size.width * rate));
        xmlElem.value('height', Math.floor(size.height * rate), xmlElem.indexOf('width') + 1);

        require('actionUtils').compoundUpdate(editor, _.extend(compoundData, {
          data: xmlElem.toString(),
          caret: offset
        }));
      }
    });
  }
}
```

### updateImageSizeCSSを下記で上書き

```javascript:emmet-app.js
function updateImageSizeCSS(editor, isRetina) {
  var offset = editor.getCaretPos(),
      rate = isRetina ? 0.5 : 1;

  // find tag from current caret position
  var info = require('editorUtils').outputInfo(editor);
  var cssRule = require('cssEditTree').parseFromPosition(info.content, offset, true);
  if (cssRule) {
    // check if there is property with image under caret
    var prop = cssRule.itemFromPosition(offset, true), m;
    if (prop && (m = /url\((["']?)(.+?)\1\)/i.exec(prop.value() || ''))) {
      getImageSizeForSource(editor, m[2], function(size) {
        if (size) {
          var compoundData = cssRule.range(true);
          cssRule.value('width', Math.floor(size.width * rate) + 'px');
          cssRule.value('height', Math.floor(size.height * rate) + 'px', cssRule.indexOf('width') + 1);

          require('actionUtils').compoundUpdate(editor, _.extend(compoundData, {
            data: cssRule.toString(),
            caret: offset
          }));
        }
      });
    }
  }
}
```

### <code>update_image_size</code>の登録部分に<code> update_image_size_for_retina </code>を追記

```javascript:emmet-app.js
require('actions').add('update_image_size', function(editor) {
  // this action will definitely won’t work in SASS dialect,
  // but may work in SCSS or LESS
  if (_.include(['css', 'less', 'scss'], String(editor.getSyntax()))) {
    updateImageSizeCSS(editor, false);
  } else {
    updateImageSizeHTML(editor, false);
  }

  return true;
});
// for Retina ★下記追記
require('actions').add('update_image_size_for_retina', function(editor) {
  // this action will definitely won’t work in SASS dialect,
  // but may work in SCSS or LESS
  if (_.include(['css', 'less', 'scss'], String(editor.getSyntax()))) {
    updateImageSizeCSS(editor, true);
  } else {
    updateImageSizeHTML(editor, true);
  }

  return true;
});
```

## 3. 設定ファイルを開く
1. メニューの<code>Preferences -> Browse Packages…</code>でFinder開く
2. Finderの<code>Emmet -> Default.sublime-commands</code>を開く

## 4. 修正

```javascript:Default.sublime-commands

	{
		"caption": "Emmet: Update Image Size for Retina",
		"command": "run_emmet_action",
		"args": {
			"action": "update_image_size_for_retina"
		}
	},
```

## 5. 実行

1. htmlファイルを開く
2. imgタグのsrcに存在する画像へのパスを記述
3. <code>cmd + shift + p -> "Emmet : Update Image Size for Retina"</code>を選択して、エンターキー押下