javascriptのおかげで卒論でちょっと楽できた話

大学生時代に卒論書いてるとき「英単語とか半角数字の両端には半角スペースを入れてください」と教授に言われた。

例えば「数字の1は英語でoneといいます」は 「数字の 1 は英語で one といいます」と書かないといけない。
（※"1"と"one"の両端に半角スペースが入っています。）

手作業で半角スペースをいちいち入れるのはとても面倒で、なんとか自動化できないかと思っていろいろ試したらjavascriptでできた。
できたのでツール化した。

卒論書きながら作ったからクオリティ低いけど（言い訳）許してください。

# 対象読者
理系大学生(とくに4回生or院2回生)
冬に向けて卒論を執筆する予定の学生
教授の指示に従うのがめんどくさいと感じる学生

# 全体像
ここにおいてます。
https://github.com/sirloinSE/ProofreadingTool

# ソース
メインの処理はjavascript側に書いているので、これだけ載せます。
HTMLとCSSも少し書きましたがここではあんまり関係ないので詳しくは上記のGithubで御覧ください。

```javascript:main.js
(function () {
  'use strict';

  function isZenkaku(obj){
    var len=escape(obj).length;
    if(len>=4){
      // 全角の場合
      return true;
    }else{
      // 半角の場合
      return false;
    }
  }

  // str の idx 文字目の次に半角スペースを挿入
    function insertSpace(str, idx){
      return str.slice(0, idx) + ' ' + str.slice(idx);
    };

   document.getElementById('btn').addEventListener('click', function(){
    // 入力されたテキスト
    var text = document.getElementById('text1').value;
    // 半角スペースを入れるインデックスを保持
    var spacenum = [];
    var j = 0;

    for (var i = 0; i < text.length; i++) {
     if ((isZenkaku(text[i]) == true && isZenkaku(text[i + 1]) == false )
      || (isZenkaku(text[i]) == false && isZenkaku(text[i + 1]) == true )) {
        // ”全角＋半角” or ”半角＋全角”のとき
        spacenum[j] = i+1;
        j++;
      }
    }

    var k = 0;
    for (var i = 0; i < spacenum.length; i++) {
      // 半角スペース挿入
      text = insertSpace(text, spacenum[i] + k);
      // 半角スペースを入れた分インデックスがずれる
      k++;
    }
    document.getElementById('text2').value = text; //text2に出力
  });
})();
```

クソコードすんません

# 解説
かるーく解説
## 半角・全角チェック
```javascript
function isZenkaku(obj){
    var len=escape(obj).length;
    if(len>=4){
      // 全角の場合
      return true;
    }else{
      // 半角の場合
      return false;
    }
  }
```

文字を1文字ずつ取ってきてescape関数でエンコードし、サイズが4以上なら全角文字、それ以外は半角文字と判定しています。

## 半角スペースを挿入する関数
```javascript
  // str の idx 文字目の次に半角スペースを挿入
    function insertSpace(str, idx){
      return str.slice(0, idx) + ' ' + str.slice(idx);
    };
```

文章の任意の場所に半角スペースを挿入する関数です。

## 文中の何文字目に半角スペースを挿入するかを判定
```javascript
// 入力されたテキスト
    var text = document.getElementById('text1').value;
    // 半角スペースを入れるインデックスを保持
    var spacenum = [];
    var j = 0;

    for (var i = 0; i < text.length; i++) {
     if ((isZenkaku(text[i]) == true && isZenkaku(text[i + 1]) == false )
      || (isZenkaku(text[i]) == false && isZenkaku(text[i + 1]) == true )) {
        // ”全角＋半角” or ”半角＋全角”のとき
        spacenum[j] = i+1;
        j++;
      }
    }
```

`text`には半角文字と全角文字の混ざった文章が入ります。

for文の中ではi文字目とi+1文字目にisZenkaku関数を使って半角・全角をジャッジします。

コメントにある「"全角＋半角"」とは冒頭の”数字の1は英語でoneといいます”の例で言うところの3文字目と4文字目の「<font color="gray">数字</font><font color="red">の1</font><font color="gray">は英語でoneといいます</font>」のような部分を指します。
同様に、以下のように4〜5文字目、8〜9文字目、11〜12文字目もです。

「<font color="gray">数字</font><font color="red">の1は</font><font color="gray">英語</font><font color="red">でo</font><font color="gray">n</font><font color="red">eと</font><font color="gray">いいます</font>」

これらの部分は<font color="blue">半角文字と全角文字の境目</font>なので半角スペースを入れるべきところです。
その場所を`spacenum[]`に記憶させています。

## 半角スペースを挿入する
```javascript
var k = 0;
    for (var i = 0; i < spacenum.length; i++) {
      // 半角スペース挿入
      text = insertSpace(text, spacenum[i] + k);
      // 半角スペースを入れた分インデックスがずれる
      k++;
    }
```

`spacenum[]`を頼りに半角スペースを入れていきます。
insertSpace()関数で半角スペースを入れるたびにその分文字数が増えてしまい、spacenumが保持する値とずれてしまいます。
ズレを修正するために`k`で調整してます。