Qiita記事上のソースコードを手っ取り早くファイルに保存するブックマークレットを作った

# 目的

Qiita上の下記のようなソースコードを試したいときに、わざわざテキスト選択して画面スクロールしてコピーするのが面倒臭すぎると感じたので、１クリックでファイルに保存できるようにブックマークレットをつくってみた。

- すぐ使いたい方は[こちら](https://qiita.com/kob58im/items/d0ec515d066d310dd493#%E6%94%B9%E8%A1%8C%E5%89%8A%E9%99%A4%E7%89%88%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88%E8%B2%BC%E3%82%8A%E4%BB%98%E3%81%91%E7%94%A8)から
- [ブックマークレットの作り方](https://qiita.com/kob58im/items/d0ec515d066d310dd493#%E5%8F%82%E8%80%83%E3%82%B5%E3%82%A4%E3%83%88---%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9)

```

hogehoge
：
数百行くらいの長いコード
：
```

# 注意事項と動作環境

ブックマークレットとしてつかうときは改行は削除してください。
[ブックマークレット変換（成形） - Website Tools](http://websitetools.biz-box.jp/js_bookmarklet.php)が便利でした。

動作確認はWindows10 + Chromeで行っています。
追記：Edgeでも動作しました。

# ソースコードを保存するブックマークレット

+ 保存ファイルの改行コードについて：<br>
`\n`(LF)になるっぽいので`\r\n`(CRLF)に置換してます。[^1]
+ 保存ファイルの拡張子について：<br>
C#er向けにカスタマイズしちゃってますが、適宜修正してください。`.txt`を付加しているのは、`.bat`とかで保存してしまうと開くとき面倒くさいのとセキュリティ的によろしくない気がしたためです。

```javascript

javascript:(function(){
  var elm=document.getElementsByClassName('code-frame');
  if(elm.length===0){return;}

  var s='';
  var fns=new Array(elm.length);
  for(var i=0;i<elm.length;i++){
    s+=i+1+' ';
    fns[i]='src';
    var elm2=elm[i].getElementsByClassName('code-lang');
    var tlang=elm[i].getAttribute('data-lang');
    if(elm2.length===1){
      fns[i]=elm2[0].innerText;
      s+=fns[i];
    }
    if(!fns[i].endsWith('.cs')){
      if(tlang==='cs'||tlang==='csharp'){
        fns[i]+='.cs';
      }else{
        fns[i]+='.txt';
      }
    }
    if(tlang){s+='('+tlang+')';}
    s+='\n';
  }
  var idx=0;
  if(elm.length>1){
    idx=prompt(s+'\nSelect 1-'+elm.length)-1;
    if(!(idx>=0&&idx<elm.length)){return;}
  }
  var fn=fns[idx];

  var t=elm[idx].getElementsByClassName('highlight')[0].innerText.replace(/\r?\n/g,'\r\n');
  var b=new Blob([t],{"type":"text/plain"});
  if(window.navigator.msSaveBlob){
    window.navigator.msSaveBlob(b,fn);
  }else{
    if(window.URL&&window.URL.createObjectURL){
      uri=URL.createObjectURL(b);
    }else{
      uri='data:application/octet-stream;base64,'
         +encodeURIComponent(btoa(unescape(encodeURIComponent(t))));
    }
    a=document.createElement('A');
    a.href=uri;
    a.download=fn;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  }
})();
```

## 改行削除版（ブックマークレット貼り付け用）：

```javascript

javascript:(function(){var elm=document.getElementsByClassName('code-frame');if(elm.length===0){return;}var s='';var fns=new Array(elm.length);for(var i=0;i<elm.length;i++){s+=i+1+' ';fns[i]='src';var elm2=elm[i].getElementsByClassName('code-lang');var tlang=elm[i].getAttribute('data-lang');if(elm2.length===1){fns[i]=elm2[0].innerText;s+=fns[i];}if(!fns[i].endsWith('.cs')){if(tlang==='cs'||tlang==='csharp'){fns[i]+='.cs';}else{fns[i]+='.txt';}}if(tlang){s+='('+tlang+')';}s+='\n';}var idx=0;if(elm.length>1){idx=prompt(s+'\nSelect 1-'+elm.length)-1;if(!(idx>=0&&idx<elm.length)){return;}}var fn=fns[idx];var t=elm[idx].getElementsByClassName('highlight')[0].innerText.replace(/\r?\n/g,'\r\n');var b=new Blob([t],{"type":"text/plain"});if(window.navigator.msSaveBlob){window.navigator.msSaveBlob(b,fn);}else{if(window.URL&&window.URL.createObjectURL){uri=URL.createObjectURL(b);}else{uri='data:application/octet-stream;base64,'+encodeURIComponent(btoa(unescape(encodeURIComponent(t))));}a=document.createElement('A');a.href=uri;a.download=fn;document.body.appendChild(a);a.click();document.body.removeChild(a);}})();

```

# 実行時のキャプチャ - 複数コードがある場合

コードの数だけ選択子を表示します。数字を入力してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/117c63a1-1669-2852-031e-a9e39ad1f179.png)


# 事前調査：Qiita上のソースコードのHTMLタグ

言語指定：指定あり(csharp)　かつ　ファイル名：指定なし　の場合

```html

<div class="code-frame" data-lang="csharp">
  <div class="highlight">
    <pre>...</pre>
  </div>
</div>
```

言語指定：指定あり(text)　かつ　ファイル名：指定あり(compile.bat)　の場合

```html

<div class="code-frame" data-lang="text">
  <div class="code-lang">
    <span class="bold">compile.bat</span>
  </div>
  <div class="highlight">
    <pre>...</pre>
  </div>
</div>
```

となった

# 参考サイト

[msSaveBlob,Data URI SchemeおよびURL.createObjectURLによるデータ保存 - Qiita](https://qiita.com/weal/items/bcee74b3633ae658b56c)

# 参考サイト - ブックマークレットの作り方

- [ブックマークレットの登録方法](https://qiita.com/aqril_1132/items/b5f9040ccb8cbc705d04)
- [[Windows 10]Microsoft Edgeでブックマークレットを使う。](https://www.ka-net.org/blog/?p=6000)
- [現在開いているwebページのURLを変換して別窓で表示するブックマークレット](https://teratail.com/questions/11472)
- [ブックマークレット変換（成形） - Website Tools](http://websitetools.biz-box.jp/js_bookmarklet.php)

[^1]: Windowsじゃないかたは、適宜`replace(/\r?\n/g,'\r\n')`のとこ削除するか`replace(/\r?\n/g,'\r')`に変更してください。