webページの情報をリッチテキストでコピーする

# はじめに
ネットで情報を集めてまとめる作業は趣味/業務で頻繁に発生しますが、規模が大きくなるとまとめる作業が面倒になってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110548/3142f3ef-dd20-4b8e-7bc8-3039833d1b93.png)


テキストコピーを使う箇所をリッチテキストコピーに替えることで効率化できないか検討します。
※ここではリッチテキストフォーマットを厳密に指すのではなく、テキスト以上の構造を持たせた情報くらいの粒度で指します。

# ベースとなる機能
まず必要な機能とそれを実現する方法について紹介しておきます。
実現方法は複数検討できますが、ここではナイーブに実装できる方法を選びます。

## webページの情報を取得する
javascriptで記述できます。例えば[このページ](https://qiita.com/kagasan/items/cf8dfd6b10448c356795)で次のスクリプトを実行するとページタイトルとurlを出力できます。（画像右側がコンソール画面）
```javascript
console.log(document.title, location.href);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110548/62782096-c7a7-32d8-7515-c6718e0fa12c.png)

## クリップボードに貼り付ける
こちらもjavascriptで記述できます。以下をコンソールから実行することでクリップボードに'hello world'が貼り付けられます。
`execCommand('copy')`は非推奨ですが、ナイーブに実装できるということで利用しています。
```javascript
{
    const input = document.createElement('input');
    input.setAttribute('value', 'hello world');
    document.body.appendChild(input);
    input.select();
    document.execCommand('copy');
    document.body.removeChild(input);
}
```

## webページ上で実行する
javascriptで記述できるブックマークレットを使います。
次のスクリプトをブックマークに登録しておき、任意のページでブックマークを実行すると「ページタイトルとurlをクリップボードにコピー」ができます。
```javascript
javascript:(function(){
    const input = document.createElement('input');
    input.setAttribute('value', `${document.title}, ${location.href}`);
    document.body.appendChild(input);
    input.select();
    document.execCommand('copy');
    document.body.removeChild(input);
})();
```
[このページ](https://qiita.com/kagasan/items/cf8dfd6b10448c356795)
で実行すると次が得られます。
```
N番目の素数を表す式をPythonで #Python - Qiita, https://qiita.com/kagasan/items/cf8dfd6b10448c356795
```
多少加工するとmarkdown形式でコピーできます。
```javascript
javascript:(function(){
    const input = document.createElement('input');
    input.setAttribute('value', `[${document.title}](${location.href})`);
    document.body.appendChild(input);
    input.select();
    document.execCommand('copy');
    document.body.removeChild(input);
})();
```
これはこれで便利そうです。
```
[N番目の素数を表す式をPythonで #Python - Qiita](https://qiita.com/kagasan/items/cf8dfd6b10448c356795)
```

# リッチなテキストでコピーする
テキスト形式でコピーできることは分かりましたが、テキスト以上の形式でコピーしたくなります。
## リンク形式でコピーする
コピー対象をhtmlの構造にしておくことでリンク要素を作ってコピーできます。
```javascript
javascript:(function(){
    const divElement = document.createElement('div');
    divElement.innerHTML = `<a href="${location.href}">${document.title}</a>`;
    document.body.appendChild(divElement);
    const range = document.createRange();
    range.selectNode(divElement);
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
    document.body.removeChild(divElement);
})();
```
パワポにリンク付きでページ情報を添えられるようになりますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110548/dcfaf7ec-b85a-bf93-c8df-fdf842e04378.png)


## 表形式でコピーする
コピー対象をあらかじめ表形式にしておくと情報整理が楽になりそうです。
```javascript
javascript:(function(){
    const table = document.createElement('table');
    table.innerHTML = `
        <tr>
            <td>${document.title}</td>
            <td><a href='${location.href}'>${location.href}</a></td>
        </tr>
    `;
    document.body.appendChild(table);
    const range = document.createRange();
    range.selectNode(table);
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
    document.body.removeChild(table);
})();
```
表の行単位でクリップボードにコピーされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110548/1d73db5a-194d-33a3-9ed6-7906976103b9.png)

# おわりに
ページタイトルとurlをクリップボードにコピーする方法を検討しました。
実際の作業ではもっと複雑なロジックで情報整理するシーンもありますが、この拡張でどうにかなりそうな気配がします。
※実現には複数の方法があり、別の選択をしたほうがよくなる場合もありそうです。


# おまけ
コピーではないけれど、こういうこともできるねという処理。
## urlを開く
今のページタイトルで検索する。
```javascript
javascript:(function(){
    location.href = `https://www.google.com/search?q=${document.title}`;
})();
```
新しいタブで開く場合はこう。
```javascript
javascript:(function(){
    window.open(`https://www.google.com/search?q=${document.title}`);
})();
```

## テキストを新しいタブで開く
csvなどでフォーマットしたい場合に？
```javascript
javascript:(function(){
    const text = 'こんにちは\nworld';
    const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    window.open(url);
})();
```
## リッチなテキストを新しいタブで開く
決まったルールでページ内の情報をまとめたい場合に？
```javascript
javascript:(function(){
    const html = `<table border="1"><tr>
        <td>${document.title}</td>
        <td><a href='${location.href}'>${location.href}</a></td>
    </tr></table>`;
    const blob = new Blob([html], { type: 'text/html;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    window.open(url);
})();
```

## テキストを保存する
csvでローカルに保存したくなる場合などに。
```javascript
javascript:(function(){
    const text = `${document.title},${location.href}`;
    const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'data.csv';
    a.click();
})();
```