文章中の全角文字と半角文字の間にスペースを挿入するサクラエディタのマクロ

作ってみた。

autospace.js

コードは以下。JavaScriptによるWSHマクロ。

if(Editor.GetSelectedString(0).length == 0) Editor.SelectAll();
var source = Editor.GetSelectedString(0);

var except_left = '\r\n-、。,.,.、。  」)}』】〕]〉》>≫“‘';
var except_right = '\r\n-、。,.,.、。  「({『【〔[〈《<≪”’';
var strong_left = '([{<「';
var strong_right = ')]}>」,';
var strong_tpo = '"\'';
var strong_both1 = '/:&';
var strong_both2 = '0123456789';

var n = String.fromCharCode(0x0);

String.prototype.isNarrow = function(){
    for(var i = 0; i < this.length; i++){
        var c = this.charCodeAt(i);
        if(0x0 <= c && c <= 0x7f){
            // narrow
        }else{
            return false;
        }
    }
    return true;
};
String.prototype.contains = function(s){
    return (0 <= this.indexOf(s));
};

// ignore url
source = source.replace(/(https?:\/\/[a-zA-Z0-9_\.\!\~\*\(\);\/\?\:\@\&\=\+\$,%#-]+)/g, n + '$1' + n);
// ignore mail
source = source.replace(/([a-zA-Z0-9_\.-]+\@[a-zA-Z0-9_\.-]+)/g, n + '$1' + n);

var ignore = false;
var tpo = {};
var result = [];
for(var i = 0; i < source.length; i++){
    var current = source.charAt(i)
    var forward = source.charAt(i + 1);
    
    var cel = except_left.contains(current);
    var cer = except_right.contains(current);
    var csl = strong_left.contains(current);
    var csr = strong_right.contains(current);
    var cst = strong_tpo.contains(current);
    var cs1 = strong_both1.contains(current);
    var cs2 = strong_both2.contains(current);
    var fel = except_left.contains(forward);
    var fer = except_right.contains(forward);
    var fsl = strong_left.contains(forward);
    var fsr = strong_right.contains(forward);
    var fst = strong_tpo.contains(forward);
    var fs1 = strong_both1.contains(forward);
    var fs2 = strong_both2.contains(forward);
    
    if(current == n){
        ignore = !ignore;
        if(!ignore && !fel && !fsr) result.push(' ');
        continue;
    }
    
    result.push(current);
    
    if(ignore) continue;
    
    var is_space = false;
    if(fs1 && !cs1){
        is_space = true;
    }else if(cs1 && !fs1){
        is_space = true;
    }else if(fs2 && !cs2){
        is_space = true;
    }else if(cs2 && !fs2){
        is_space = true;
    }else if(csl && fsl){
        continue;
    }else if(csr && fsr){
        continue;
    }else if(!csl && (fsl || fst)){
        is_space = true;
    }else if((csr || cst) && !fsr){
        is_space = true;
    }else if(current.isNarrow() != forward.isNarrow()){
        is_space = true;
    }
    if(is_space){
        if(fel || cer) continue;
        if(fsr || csl) continue;
        
        if(!cst && fst && !tpo[forward]){
            //
        }else if(cst && !fst && !tpo[current]){
            tpo[current] = true;
            continue;
        }else if(!cst && fst && tpo[forward]){
            continue;
        }else if(cst && !fst && tpo[current]){
            tpo[current] = false;
        }
        result.push(' ');
    }
}
Editor.InsText(result.join(''));

汚いコードで申し訳ない。

これは何か

文中の全角文字と半角文字の間にスペースが挿入されるというサクラエディタ用のマクロ。

単純にスペースを挿入するだけじゃなく、いくつかのルールがある。

  • 半角のカッコの外側方向の隣には、常にスペースを挿入する。
  • いくつかの半角記号の左右には、常にスペースを挿入する。
  • 半角数字の左右には、常にスペースを挿入する。
  • 行頭や行末にはスペースを挿入しない。
  • 隣が"、"や"。"のときはスペースを挿入しない。
  • カッコの内側方向の隣にはスペースを挿入しない。
  • 連続したカッコの間にはスペースを挿入しない。
  • URLやメールアドレスの文字列に対してはスペースを挿入しない。

こんな感じ。まあわかりやすく言うと、

  • 全角文字と半角文字の間にスペースを挿入する。
  • 半角文字と半角文字の間でも、スペースを挿入した方が読みやすそうな場合は、挿入する。
  • 本来はスペースを挿入する場面でも、挿入しない方が読みやすい場合は、挿入しない。

ということ。

全角文字、半角文字の定義は、文字コード7Fまで(ASCII文字)を半角として、それ以外を全角とした。だから半角カナは全角扱いになる。スペース挿入のルール上もその方が良さそうなので。

使い方

サクラエディタの[設定]→[共通設定]→[マクロ]で、上記jsファイルを登録する。さらにキーを割り当てたり、カスタムメニューに登録したりして使う。[ツール]→[登録済みマクロ]のメニューから選んでも良いね。

文字列を選択して、マクロを呼び出して使う。文字列を選択しないでマクロを呼び出すと、すべての文字列が対象になる。

あいうえお、abc(DEFかきくけこ)さしす123GHせそ。
たちつてと「なにぬIJK-456」ねの"7890LMN"。はひふへほ。OPQ。
RS(『まみむ「めも」』)TUvwx、やゆよ。
らりるhttp://example.com/れろ。
わをmail@example.comん。

これを変換すると、

あいうえお、abc (DEF かきくけこ) さしす 123 GH せそ。
たちつてと「なにぬ IJK-456」ねの "7890 LMN"。はひふへほ。OPQ。
RS (『まみむ「めも」』) TUvwx、やゆよ。
らりる http://example.com/ れろ。
わを mail@example.com ん。

こうなる。

注意事項

いろいろ問題が含まれているので、注意事項がある。

  • ソースコードには使わない。
  • 顔文字、アスキーアートが含まれる部分には使わない。
  • その他、怪しいときは使わない。
  • 変換後、必ず読み返してみて確認する。

というか、単純な日本語と英語が程よく混ざった文章だけに使うようにすればたぶん大丈夫。