Yahoo!知恵袋でインデント(字下げ)入りの回答をする

私は基本的にteratailで回答していて、たまに知恵袋でも回答するのですが、
知恵袋だとタブやスペースによるインデント(字下げ)が消えてしまうという問題によく頭を悩まされます。

他の回答者がやっているように`__`(2つ以上のアンダーバー)を使えばいいのでしょうけど、

基本的に(私含めて)プログラミング初心者が多い知恵袋で、いちいち質問者に「エディタで置換してください」と言うのは手間ですし、上手くいかないことが多いです。

それにpythonとかだとアンダーバーにも意味があったりしますから、なおさらアンダーバーはよくないです。

それでも諦めてアンダーバーを使っていたのですが、ある日インデント入りの回答をしている人を見たので、自分でもインデント入り回答ができないか挑戦することにしてみました。

今回はPCのみを想定しています。
実験は

- mac OS High Sierra (ver 10.13.1)
- Google Chrome ver 62.0.3202.89（Official Build）

で行いましたが、おそらくPCからならどのOS、ブラウザからもできる方法だと思います。

方法としては、とりあえず別な記号でインデントを表現しておき、それを後から半角スペースに置換するというものです。
言語によってインデント幅はバラバラでしょうから、そこは各自で確認してください。
(例えばjavascriptは2、pythonは4、など)

初投稿なのでお手柔らかに願います。(^ ^;

# デベロッパーツールで確認

回答直前の状態からchromeのデベロッパーツールを使用して送信される値をまず確認してみました。

内容はpythonとjavascriptで回答する場合を想定しています。
アンダーバーは使用したくなかったので、とりあえず`` ` ``(バッククォート)を使用することにしました。

言語(例えばLISPとか)によってはバッククォートを使いたくない人もいるかもしれませんので、そこは適宜別な記号で読み替えていってください。(他に良い記号があればコメントしていただけると幸いです。)

![知恵袋スクショ2.png](https://qiita-image-store.s3.amazonaws.com/0/205472/f95a43c4-ee1e-e101-751c-4025bd15214b.png)

`この内容で回答する`を右クリック -> 検証をクリック

![知恵袋スクショ3.png](https://qiita-image-store.s3.amazonaws.com/0/205472/3af2824e-5796-393b-0a70-925268e92361.png)

するとこの要素の上に目当ての項目が見当たります。

```html:html
<input type="hidden" name="content" value="def func():
````return False

function hoge(){
``console.log('hoge');
``return false;
}">
```
この部分ですね。この`input`要素の`value`を書き換えてやれば良さそうです。

# javascriptで書き換え

まずは実験ということで、コンソールを使用してみます。
開いたデベロッパーツールからそのままコンソールに直行。

```javascript:javascript
console.log(document.getElementsByName("content")[0].value);
```
上記コードを入力して実行。

```
def func():
````return False

function hoge(){
``console.log("hoge");
``return false;
}
```
どうやら`document.getElementsByName("content")[0]`で目的の要素を取得できるみたいです。

これを利用して書き換えられます。

# `.replace()`を使って、削除されない空白文字に置換

通常の半角スペースでは上手くいかなかったので、
[nicowiki](http://nicowiki.com/%E7%A9%BA%E7%99%BD%E3%83%BB%E7%89%B9%E6%AE%8A%E8%A8%98%E5%8F%B7.html)を参考にしたところ、

ユニコード`\u00A0`[^1]だと削除されないみたいだったので、
これで置換することにしました。

```javascript:javascript
var content = document.getElementsByName("content")[0];
content.value = content.value.replace(/``/g,"\u00A0\u00A0");
```

このコードを実行することで``` `` ```が半角スペース2つに置換されます。

これをコンソールから確認[^2]

![置換後.png](https://qiita-image-store.s3.amazonaws.com/0/205472/68a37eda-6d84-e462-bf72-44d4c963c60c.png)

ちゃんと置換されているようですが、実はここまでは`\u0020`(普通の半角スペース)でもちゃんと表示されます。

投稿後はどうだ?!

![回答.png](https://qiita-image-store.s3.amazonaws.com/0/205472/afc3079e-5623-e074-a542-9c48e24bb9e4.png)

`\u00A0`で無事に意図通りのインデント表示がされました!

またこのコードを使用した回答をコピペしてエディタに貼り付けると、上手く半角スペースととらえられる模様。

成功です!

# ブックマークレット化して回答時にすぐに利用できるようにする

いちいちデベロッパーツールを利用して上記のように書き込むのは面倒なので、ブックマークレットを作成しました
。

```javascript:javascript
javascript:(function(){
  var c = document.getElementsByName("content")[0];
  c.value = c.value.replace(/``/g,"\u00A0\u00A0");
  console.log(c.value); // <= デバッグ用
})();
```
`console.log()`は動作確認用に入れています。いらないと思う方は削除なりコメントアウトなりして使ってください。

これを[packer](http://dean.edwards.name/packer/)で圧縮して、

```javascript:bookmarklet
javascript:(function(){var c=document.getElementsByName("content")[0];c.value=c.value.replace(/``/g,"\u00A0\u00A0");console.log(c.value)})();
```
完成です!

# 一応使い方&まとめ的な何か

`答える`をクリックしたのちに出てくるプレビュー画面(1枚目の画像のところ)で、`この内容で回答する`をクリックする前に使用すると、表示は変化しません[^3]が送信内容をちゃんと空白に置換されたものに変えられます。
<br />

これで質問者に気兼ねなく、綺麗なコードをそのまま載せることができますね。
この記事が皆様のお役に立てれば光栄です。

最後まで読んでいただき、ありがとうございました!m(_ _)m

# Appendix
### ブックマークレットの登録方法
    1. テキトーなページ(なんならこの記事)をブックマーク
    2. ブックマークのurlを`javascript:`から始まるjsのコードに置き換える
    3. ブックマークの名前をテキトーなものに変更(例えば「知恵袋インデント」など)
    4. ブックマークをクリックすることで使用

### 実験したければ↓
:pencil: [投稿実験用の質問](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12182028782)を載せておきます。実験投稿したくなった方はご自由にお使いください。(回答できない状態になっていた場合はコメント願います。)

### スマホについて
[iOS版アプリ](https://itunes.apple.com/jp/app/yahoo!-zhi-hui-dai-ri-changno/id354626165?mt=8)において、コピペすると`\u00A0`そのものとして扱われるらしく、コンパイルエラーに繋がってしまいました。必ずしも完璧な方法ではない、ということです。ご注意ください。
ブラウザで見るぶんにはiPhoneでも通常の半角スペース(`\u0020`)として認識されましたので、その点はご安心ください。

[^1]: 追記 : 後から調べ直したところ[`&nbsp;`](https://ja.wikipedia.org/wiki/%E3%83%8E%E3%83%BC%E3%83%96%E3%83%AC%E3%83%BC%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9)と同じですが、こちらでブックマークレットを作成すると`&nbsp;`がそのまま出て来てしまうので、ユニコードで指定してください。他に方法があればコメントくださると幸いです。
[^2]: 下の`undefined`で気づいた方もいらっしゃるかもしれませんが、これは後からブックマークレットの関数を打ち込んで撮影したものです。ご了承ください。(^ ^;
[^3]: ブックマークレットが長くなってしまいますが、

    ```javascript
    var q = document.querySelectorAll(".queTxt")[1];
    q.innerHTML = q.innerHTML.replace(/``/g,"\u00A0\u00A0");
    ```
    を付け加えることでプレビュー画面においても表示を変えることができます。