「テキスト変換」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
Ks (トーク | 投稿記録)
編集の要約なし
Ks (トーク | 投稿記録)
書式の変更他
1行目: 1行目:
== 概要 ==
= 概要 =
開いているドキュメントのテキストを変換します.
開いているドキュメントのテキストを変換します.


== 特徴 ==
= 特徴 =
* 機能追加が簡単.
* 機能追加が簡単.


== 使用方法 ==
= 更新履歴 =
* 2013/1/23 初版
* 2013/1/24 グルーピング対応.replaceS, replaceL 対応.
 
= 使用方法 =
# 基本コードを拡張子 .js で保存します.
# 基本コードを拡張子 .js で保存します.
# 必要な拡張コードを追加します.
# 必要な拡張コードを追加します.
#*「拡張機能の追加」とある場所に,コードをコピペすれば拡張が可能です.
#*「拡張機能の追加」とある場所に,コードをコピペすれば拡張が可能です.
#* 上から順にポップアップに表示されます.
#* 上から順にポップアップに表示されます.
#* <code>f[f.length] = "--";</code><br>でセパレータを挿入できます(- の数は任意).
# マクロを実行すると登録されている機能の一覧が表示されるので,選択して実行します.
# マクロを実行すると登録されている機能の一覧が表示されるので,選択して実行します.
#* テキストを選択している場合は,対象を「選択テキスト」「全体」から選べます.
#* テキストを選択している場合は,対象を「選択テキスト」「全体」から選べます.
#* テキストを選択していない場合は「全体」が対象です.
#* テキストを選択していない場合は「全体」が対象です.


== コード ==
= 便利な使い方 =
=== 拡張コード ===
# セパレータの挿入<br><code>f[f.length] = "--";</code><br>でセパレータを挿入できます(- の数は任意).
'''ご自由に追加してください!'''
# グルーピング<br>下のコードのようにコード拡張と似た書式で,グルーピングができます.
 
* 大文字に変換
<source lang="javascript">
<source lang="javascript">
f[f.length] = {
f[f.length] = {
   title:"大文字に変換",
   title:"文字変更"     // <= グルーピング名
   replace:function(text){ return text.toUpperCase() }
   group:function(f){   // <= グルーピング開始(お決まり文句)
};
    f[f.length] = {     // <= 以降はグルーピングされる機能を追加
</source>
      title:"大文字に変換",
* 小文字に変換
      replace:function(text){ return text.toUpperCase() }
<source lang="javascript">
    };
f[f.length] = {
    f[f.length] = {
  title:"小文字に変換",
      title:"小文字に変換",
  replace:function(text){ return text.toLowerCase() }
      replace:function(text){ return text.toLowerCase() }
};
     };
</source>
   }                     // <= グルーピングの終了
* カンマ前後の空白を削除
<source lang="javascript">
f[f.length] = {
  title:"カンマ前後の空白を削除",
  replace:function(text){ return text.replace(/^[ \t ]+|[ \t ]+$/mg, "").replace(/[ \t ]*,[ \t ]*/mg, ","); }
};
</source>
* BASE64エンコード(Unicode)
<source lang="javascript">
f[f.length] = {
  title:"BASE64エンコード(Unicode)",
  replace:function(text){
    var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
    var Ch = function(n){ return n<text.length ? text.charCodeAt(n) : 0 };
    var len = text.length, pad = len % 3, s = "";
    for (var i=0; i<len; i+=3) {
      var tmp = (Ch(i)<<16) | (Ch(i+1)<<8) | Ch(i+2);
      s += map[(tmp>>>18)&0x3F] + map[(tmp>>>12)&0x3F] + map[(tmp>>>6)&0x3F] + map[tmp&0x3F];
    }
     if (pad) { s = s.substring(0, s.length-(3-pad)) + "===".substring(pad) }
    return s;
   }
};
};
</source>
</source>


=== 基本コード ===
= コード =
 
 
== 基本コード ==
<source lang="javascript">
<source lang="javascript">
#title = "テキスト変換"
#title = "テキスト変換"
88行目: 70行目:
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑


// 実行
// 基本機能
(function(){
(function(){
   var popup = CreatePopupMenu();
   var topMenu = CreatePopupMenu();
   var selPopup = null;
   var menus = null;
   var docPopup = popup;
   var selMenu = null;
  var docMenu = topMenu;
 
  var DIFF_ID      = 0x10000;  // 適用対象を判別するための ID の最低値
  var SELECTION_ID = 0x10000;  // Selection を対象
  var DOCUMENT_ID  = 0x20000;  // Document を対象
  var EDITOR_ID    = 0x40000;  // Editor を対象(未対応)


   var SELECTION_ID = 0x1000;
   // サブメニュー登録
   var DOCUMENT_ID  = 0x2000;
  var AddSubMenu = function(menu, text) {
    var subMenu = null;
    if (menu){
      subMenu = CreatePopupMenu();
      menu.AddPopup(text, subMenu);
    }
    return subMenu;
  };
  // コマンド登録
  var commands = {}, id = 0;
  var AddCommand = function(menus, text, cmd, flag) {
    for (var i=0; i<menus.length; i++) {
      if (menus[i]) {
        menus[i].Add(text, (DIFF_ID << i) + id, flag);
        commands[id] = cmd;
        id++;
      }
    }
  };
  // 選択領域を行全体に変更してその文字列を返す
  SelectLine = function(selection, isPosView) {
    var posFlag = isPosView ? mePosView : mePosLogical;
    var ty = selection.GetTopPointY(posFlag);
    selection.SetActivePoint(posFlag, 1, selection.GetBottomPointY(posFlag));
    selection.EndOfLine(false, posFlag);
    selection.SetAnchorPoint(posFlag, 1, ty);
    return selection.Text;
  };
  // 行単位処理
   EnumLine = function(selection, isPosView, replace) {
    var lines = SelectLine(selection, isPosView).split("\n");
    var result = [];
    for (var i=0; i<lines.length; i++) {
      var text = replace(lines[i]);
      if (text != null) {
        result.push(text);
      }
    }
    return result.join("\n");
  }


   // 選択文字列があるときは選択肢追加
   // 選択文字列があるときは選択肢追加
   var sel = document.Selection;
   var sel = document.Selection;
   if (sel.Text) {
   if (sel.Text) {
     selPopup = CreatePopupMenu();
     selMenu = AddSubMenu(topMenu, "選択文字列");
    docPopup = CreatePopupMenu();
     docMenu = AddSubMenu(topMenu, "全体");
    popup.AddPopup("選択文字列", selPopup);
     popup.AddPopup("全体", docPopup);
   }
   }


   // 選択肢追加
   // 選択肢追加
   for (var i=0; i<f.length; i++) {
   // 定義リストからメニューを作成
    if (typeof f[i]["title"] == "string" && typeof f[i]["replace"] == "function") {
  var ListToMenu = function(menus, f) {
      if (selPopup) {
    for (var i=0; i<f.length; i++) {
        selPopup.Add(f[i].title, SELECTION_ID+i);
      if (typeof f[i]["title"] == "string") {
      }
        // グループ登録またはコマンド登録
      docPopup.Add(f[i].title, DOCUMENT_ID+i);
        if (typeof f[i]["group"] == "function") {
    } else if (typeof f[i] == "string" && /^-+$/.test(f[i])) {
          var group = [];
      // セパレータ処理
          f[i].group(group);
      if (selPopup) {
          var subMenus = [];
         selPopup.Add("", 0, meMenuSeparator);
          for (var j=0; j<menus.length; j++) {
            subMenus.push(AddSubMenu(menus[j], f[i].title));
          }
          ListToMenu(subMenus, group);
        } else if (typeof f[i]["replace"] == "function") {
          // 通常コマンド
          var exec = function(replace, text, isViewMode, selection){ return replace(text, selection) };
          AddCommand(menus, f[i].title, {replace:f[i].replace, exec:exec});
        } else if (typeof f[i]["replaceS"] == "function") {
          // 行全体選択
          var exec = function(replace, text, isViewMode, selection){ return replace(SelectLine(selection, isViewMode), selection) };
          AddCommand(menus, f[i].title, {replace:f[i].replaceS, isViewMode:f[i]["view"], exec:exec});
        } else if (typeof f[i]["replaceL"] == "function") {
          // 行単位処理
          var exec = function(replace, text, isViewMode, selection){ return EnumLine(selection, isViewMode, replace) };
          AddCommand(menus, f[i].title, {replace:f[i].replaceL, isViewMode:f[i]["view"], exec:exec});
        }
      } else if (typeof f[i] == "string" && /^-+$/.test(f[i])) {
        // セパレータ処理
         AddCommand(menus, "", null, meMenuSeparator);
       }
       }
      docPopup.Add("", 0, meMenuSeparator);
     
     }
     }
   }
   };
  ListToMenu([selMenu, docMenu], f);


   // ポップアップを表示して選択されたコマンドを実行
   // ポップアップを表示して選択されたコマンドを実行
   var mePosCaret = 0;
   var mePosCaret = 0;
   var select = popup.Track(mePosMouse);
   var select = topMenu.Track(mePosMouse);
   if (select > 0) {
   if (select > 0) {
    var command = commands[select&(DIFF_ID-1)];
     if (select & SELECTION_ID) {
     if (select & SELECTION_ID) {
       sel.Text = f[select-SELECTION_ID].replace(sel.Text, sel);
       sel.Text = command.exec(command.replace, sel.Text, command["isViewMode"], sel);
     } else {
     } else if (select & DOCUMENT_ID) {
       sel.SelectAll();
       sel.SelectAll();
       Document.Text = f[select-DOCUMENT_ID].replace(Document.Text, sel);
       Document.Text = command.exec(command.replace, Document.Text, command["isViewMode"], sel);
     }
     }
   }
   }
137行目: 181行目:
</source>
</source>


== ご意見・ご要望 ==
== 拡張コード ==
'''ご自由に追加してください!'''
 
=== 空白削除 ===
<source lang="javascript">
f[f.length] = {
  title:"空白削除",
  group:function(f){
    f[f.length] = {
      title:"行頭の空白文字を削除",
      replace:function(text){ return text.replace(/^[ \t ]+/mg, "") }
    };
    f[f.length] = {
      title:"行末の空白文字を削除",
      replace:function(text){ return text.replace(/[ \t ]+$/mg, "") }
    };
    f[f.length] = {
      title:"行頭・行末の空白文字を削除",
      replace:function(text){ return text.replace(/^[ \t ]+|[ \t ]+$/mg, "") }
    };
    f[f.length] = {
      title:"空白行を削除",
      replaceL:function(text){ return text=="" ? null : text }
    };
    f[f.length] = {
      title:"カンマ前後の空白文字を削除",
      replace:function(text){ return text.replace(/^[ \t ]+|[ \t ]+$/mg, "").replace(/[ \t ]*,[ \t ]*/mg, ","); }
    };
  }
};
</source>
 
=== 文字変換 ===
<source lang="javascript">
f[f.length] = {
  title:"文字変換",
  group:function(f){
    f[f.length] = {
      title:"大文字に変換",
      replace:function(text){ return text.toUpperCase() }
    };
    f[f.length] = {
      title:"小文字に変換",
      replace:function(text){ return text.toLowerCase() }
    };
    f[f.length] = {
      title:"全角⇒半角",
      group:function(f){
        f[f.length] = {
          title:"英字",
          replace:function(text){ return text.replace(/[A-Za-z]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) - 0xFEE0) }) }
        };
        f[f.length] = {
          title:"数字",
          replace:function(text){ return text.replace(/[0-9]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) - 0xFEE0) }) }
        };
        f[f.length] = {
          title:"英数字",
          replace:function(text){ return text.replace(/[A-Za-z0-9]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) - 0xFEE0) }) }
        };
      }
    };
    f[f.length] = {
      title:"半角⇒全角",
      group:function(f){
        f[f.length] = {
          title:"英字",
          replace:function(text){ return text.replace(/[A-Za-z]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) + 0xFEE0) }) }
        };
        f[f.length] = {
          title:"数字",
          replace:function(text){ return text.replace(/[0-9]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) + 0xFEE0) }) }
        };
        f[f.length] = {
          title:"英数字",
          replace:function(text){ return text.replace(/[A-Za-z0-9]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) + 0xFEE0) }) }
        };
      }
    };
  }
};
</source>
 
=== ソート ===
「[[昇順で並び替え]]」「[[降順で並び替え]]」 の移植です.
<source lang="javascript">
f[f.length] = {
  title:"ソート",
  group:function(f){
    f[f.length] = {
      title:"昇順ソート(文字列)",
      replaceS:function(text){ return text.split("\n").sort().join("\n") }
    };
    f[f.length] = {
      title:"降順ソート(文字列)",
      replaceS:function(text){ return text.split("\n").sort(function(a, b){ return ((a < b) ? 1 : ((a > b) ? -1 : 0)) }).join("\n") }
    };
  }
};
</source>
 
=== 重複行排除 ===
「[[連続する重複行を削除]]」の移植を含みます.
<source lang="javascript">
f[f.length] = {
  title:"重複削除",
  group:function(f){
    f[f.length] = {
      title:"連続する重複を削除",
      replaceS:function(text){
        text = text.split("\n");
        var result = [text[0]];
        for (var i=1; i<text.length; i++) {
          if (text[i] !== text[i-1]) {
            result.push(text[i]);
          }
        }
        return result.join("\n");
      }
    };
    f[f.length] = {
      title:"重複行を削除",
      replaceS:function(text){
        text = text.split("\n");
        var result = [], map = {};
        for (var i=0; i<text.length; i++) {
          if (!map[text[i]]) {
            map[text[i]] = true;
            result.push(text[i]);
          }
        }
        return result.join("\n");
      }
    };
  }
};
</source>
 
=== 文字列追加 ===
<source lang="javascript">
f[f.length] = {
  title:"文字列追加",
  group:function(f){
    f[f.length] = {
      title:"先頭",
      replaceL:(function(text){
        var add = null;
        return function(text){
          if (!add) {
            add = Prompt("追加する文字列を入力してください.", "");
            if (!add) { Quit(); }
          }
          return add + text;
        };
      })()
    };
    f[f.length] = {
      title:"末尾",
      replaceL:(function(text){
        var add = null;
        return function(text){
          if (!add) {
            add = Prompt("追加する文字列を入力してください.", "");
            if (!add) { Quit(); }
          }
          return text + add;
        };
      })()
    };
  }
};
</source>
 
=== BASE64エンコード(Unicode) ===
<source lang="javascript">
f[f.length] = {
  title:"BASE64エンコード(Unicode)",
  replace:function(text){
    var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
    var Ch = function(n){ return n<text.length ? text.charCodeAt(n) : 0 };
    var len = text.length, pad = len % 3, s = "";
    for (var i=0; i<len; i+=3) {
      var tmp = (Ch(i)<<16) | (Ch(i+1)<<8) | Ch(i+2);
      s += map[(tmp>>>18)&0x3F] + map[(tmp>>>12)&0x3F] + map[(tmp>>>6)&0x3F] + map[tmp&0x3F];
    }
    if (pad) { s = s.substring(0, s.length-(3-pad)) + "===".substring(pad) }
    return s;
  }
};
</source>
 
= 開発者向け資料 =
これは拡張コードを開発される方向けの仕様です.<br>
拡張コードは次のいずれかの関数を実装します.
# replace
# replaceS
# replaceL
 
== replace ==
<source lang="javascript">
function replace(
    text : string,
    selection : Selection
) : string
</source>
最も基本的な変換関数です.<br>
選択されている文字列,またはドキュメント全体の文字列を引数として,
変換結果を返します.<br>
selection 引数は通常必要有りません.
Selection の持つ関数を利用したい場合などに利用します.
 
== replaceS ==
<source lang="javascript">
function replaceS(
    text : string,
    selection : Selection
) : string
</source>
行途中の選択がされている場合に,行全体を選択し直してから実行される変換関数です.<br>
行は論理行で処理しますが,下記のように <code>view:true</code> を定義時に登録することで,
表示行で処理することもできます.
<source lang="javascript">
f[f.length] = {
  title:"replaceL",
  view:true,
  replaceS:function(text){ return text }
};
</source>
 
== replaceL ==
<source lang="javascript">
function replaceL(
    text : string,
    selection : Selection
) : string
</source>
行単位で処理する場合に利用する変換関数です.<br>
渡される text は,他の関数と違い'''「1 行分の文字列」'''です.<br>
<code>String.replace</code> や <code>String.split("\n").join("\n")</code> を利用することで同様の処理が行えますが,より簡易的に処理するために用意されています.<br>
 
次の 2 つの定義は同じ処理(空白行削除)をします.
<source lang="javascript">
replaceS:function(text){ return text.replace(/^\n/mg, "") }
replaceL:function(text){ if (text != "") { return text } }
</source>
<code>replaceL</code> 関数の場合,null を返すかあるいは return しない場合に行を削除します.<br>
 
<code>replaceL</code> 関数は行毎に呼ばれるため,全体で 1 回のみの処理を記述するのが面倒です.<br>
もし必要な場合は,拡張コードの「文字列追加」のようにクロージャを利用する必要があります.
 
= ご意見・ご要望 =
何かありましたら,右の [編集] から追記してください.対応するもかしれません.
何かありましたら,右の [編集] から追記してください.対応するもかしれません.

2013年1月25日 (金) 00:09時点における版

概要

開いているドキュメントのテキストを変換します.

特徴

  • 機能追加が簡単.

更新履歴

  • 2013/1/23 初版
  • 2013/1/24 グルーピング対応.replaceS, replaceL 対応.

使用方法

  1. 基本コードを拡張子 .js で保存します.
  2. 必要な拡張コードを追加します.
    • 「拡張機能の追加」とある場所に,コードをコピペすれば拡張が可能です.
    • 上から順にポップアップに表示されます.
  3. マクロを実行すると登録されている機能の一覧が表示されるので,選択して実行します.
    • テキストを選択している場合は,対象を「選択テキスト」「全体」から選べます.
    • テキストを選択していない場合は「全体」が対象です.

便利な使い方

  1. セパレータの挿入
    f[f.length] = "--";
    でセパレータを挿入できます(- の数は任意).
  2. グルーピング
    下のコードのようにコード拡張と似た書式で,グルーピングができます.
f[f.length] = {
  title:"文字変更"      // <= グルーピング名
  group:function(f){    // <= グルーピング開始(お決まり文句)
    f[f.length] = {     // <= 以降はグルーピングされる機能を追加
      title:"大文字に変換",
      replace:function(text){ return text.toUpperCase() }
    };
    f[f.length] = {
      title:"小文字に変換",
      replace:function(text){ return text.toLowerCase() }
    };
  }                     // <= グルーピングの終了
};

コード

基本コード

#title = "テキスト変換"
// -----------------------------------------------------------------------------
// 手軽にテキスト変換を行うためのマクロ
// -----------------------------------------------------------------------------
var f = [];

// 拡張機能の追加
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

f[f.length] = {
  title:"行頭の空白文字を削除",
  replace:function(text){ return text.replace(/^[ \t ]+/mg, "") }
};
f[f.length] = {
  title:"行末の空白文字を削除",
  replace:function(text){ return text.replace(/[ \t ]+$/mg, "") }
};
f[f.length] = {
  title:"行頭・行末の空白文字を削除",
  replace:function(text){ return text.replace(/^[ \t ]+|[ \t ]+$/mg, "") }
};
f[f.length] = {
  title:"空白行を削除",
  replace:function(text){ return text.replace(/^\n/mg, "") }
};

// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

// 基本機能
(function(){
  var topMenu = CreatePopupMenu();
  var menus = null;
  var selMenu = null;
  var docMenu = topMenu;

  var DIFF_ID      = 0x10000;   // 適用対象を判別するための ID の最低値
  var SELECTION_ID = 0x10000;   // Selection を対象
  var DOCUMENT_ID  = 0x20000;   // Document を対象
  var EDITOR_ID    = 0x40000;   // Editor を対象(未対応)

  // サブメニュー登録
  var AddSubMenu = function(menu, text) {
    var subMenu = null;
    if (menu){
      subMenu = CreatePopupMenu();
      menu.AddPopup(text, subMenu);
    }
    return subMenu;
  };
  // コマンド登録
  var commands = {}, id = 0;
  var AddCommand = function(menus, text, cmd, flag) {
    for (var i=0; i<menus.length; i++) {
      if (menus[i]) {
        menus[i].Add(text, (DIFF_ID << i) + id, flag);
        commands[id] = cmd;
        id++;
      }
    }
  };
  // 選択領域を行全体に変更してその文字列を返す
  SelectLine = function(selection, isPosView) {
    var posFlag = isPosView ? mePosView : mePosLogical;
    var ty = selection.GetTopPointY(posFlag);
    selection.SetActivePoint(posFlag, 1, selection.GetBottomPointY(posFlag));
    selection.EndOfLine(false, posFlag);
    selection.SetAnchorPoint(posFlag, 1, ty);
    return selection.Text;
  };
  // 行単位処理
  EnumLine = function(selection, isPosView, replace) {
    var lines = SelectLine(selection, isPosView).split("\n");
    var result = [];
    for (var i=0; i<lines.length; i++) {
      var text = replace(lines[i]);
      if (text != null) {
        result.push(text);
      }
    }
    return result.join("\n");
  }

  // 選択文字列があるときは選択肢追加
  var sel = document.Selection;
  if (sel.Text) {
    selMenu = AddSubMenu(topMenu, "選択文字列");
    docMenu = AddSubMenu(topMenu, "全体");
  }

  // 選択肢追加
  // 定義リストからメニューを作成
  var ListToMenu = function(menus, f) {
    for (var i=0; i<f.length; i++) {
      if (typeof f[i]["title"] == "string") {
        // グループ登録またはコマンド登録
        if (typeof f[i]["group"] == "function") {
          var group = [];
          f[i].group(group);
          var subMenus = [];
          for (var j=0; j<menus.length; j++) {
            subMenus.push(AddSubMenu(menus[j], f[i].title));
          }
          ListToMenu(subMenus, group);
        } else if (typeof f[i]["replace"] == "function") {
          // 通常コマンド
          var exec = function(replace, text, isViewMode, selection){ return replace(text, selection) };
          AddCommand(menus, f[i].title, {replace:f[i].replace, exec:exec});
        } else if (typeof f[i]["replaceS"] == "function") {
          // 行全体選択
          var exec = function(replace, text, isViewMode, selection){ return replace(SelectLine(selection, isViewMode), selection) };
          AddCommand(menus, f[i].title, {replace:f[i].replaceS, isViewMode:f[i]["view"], exec:exec});
        } else if (typeof f[i]["replaceL"] == "function") {
          // 行単位処理
          var exec = function(replace, text, isViewMode, selection){ return EnumLine(selection, isViewMode, replace) };
          AddCommand(menus, f[i].title, {replace:f[i].replaceL, isViewMode:f[i]["view"], exec:exec});
        }
      } else if (typeof f[i] == "string" && /^-+$/.test(f[i])) {
        // セパレータ処理
        AddCommand(menus, "", null, meMenuSeparator);
      }
    }
  };
  ListToMenu([selMenu, docMenu], f);

  // ポップアップを表示して選択されたコマンドを実行
  var mePosCaret = 0;
  var select = topMenu.Track(mePosMouse);
  if (select > 0) {
    var command = commands[select&(DIFF_ID-1)];
    if (select & SELECTION_ID) {
      sel.Text = command.exec(command.replace, sel.Text, command["isViewMode"], sel);
    } else if (select & DOCUMENT_ID) {
      sel.SelectAll();
      Document.Text = command.exec(command.replace, Document.Text, command["isViewMode"], sel);
    }
  }
})();

拡張コード

ご自由に追加してください!

空白削除

f[f.length] = {
  title:"空白削除",
  group:function(f){
    f[f.length] = {
      title:"行頭の空白文字を削除",
      replace:function(text){ return text.replace(/^[ \t ]+/mg, "") }
    };
    f[f.length] = {
      title:"行末の空白文字を削除",
      replace:function(text){ return text.replace(/[ \t ]+$/mg, "") }
    };
    f[f.length] = {
      title:"行頭・行末の空白文字を削除",
      replace:function(text){ return text.replace(/^[ \t ]+|[ \t ]+$/mg, "") }
    };
    f[f.length] = {
      title:"空白行を削除",
      replaceL:function(text){ return text=="" ? null : text }
    };
    f[f.length] = {
      title:"カンマ前後の空白文字を削除",
      replace:function(text){ return text.replace(/^[ \t ]+|[ \t ]+$/mg, "").replace(/[ \t ]*,[ \t ]*/mg, ","); }
    };
  }
};

文字変換

f[f.length] = {
  title:"文字変換",
  group:function(f){
    f[f.length] = {
      title:"大文字に変換",
      replace:function(text){ return text.toUpperCase() }
    };
    f[f.length] = {
      title:"小文字に変換",
      replace:function(text){ return text.toLowerCase() }
    };
    f[f.length] = {
      title:"全角⇒半角",
      group:function(f){
        f[f.length] = {
          title:"英字",
          replace:function(text){ return text.replace(/[A-Za-z]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) - 0xFEE0) }) }
        };
        f[f.length] = {
          title:"数字",
          replace:function(text){ return text.replace(/[0-9]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) - 0xFEE0) }) }
        };
        f[f.length] = {
          title:"英数字",
          replace:function(text){ return text.replace(/[A-Za-z0-9]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) - 0xFEE0) }) }
        };
      }
    };
    f[f.length] = {
      title:"半角⇒全角",
      group:function(f){
        f[f.length] = {
          title:"英字",
          replace:function(text){ return text.replace(/[A-Za-z]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) + 0xFEE0) }) }
        };
        f[f.length] = {
          title:"数字",
          replace:function(text){ return text.replace(/[0-9]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) + 0xFEE0) }) }
        };
        f[f.length] = {
          title:"英数字",
          replace:function(text){ return text.replace(/[A-Za-z0-9]/mg, function(s){ return String.fromCharCode(s.charCodeAt(0) + 0xFEE0) }) }
        };
      }
    };
  }
};

ソート

昇順で並び替え」「降順で並び替え」 の移植です.

f[f.length] = {
  title:"ソート",
  group:function(f){
    f[f.length] = {
      title:"昇順ソート(文字列)",
      replaceS:function(text){ return text.split("\n").sort().join("\n") }
    };
    f[f.length] = {
      title:"降順ソート(文字列)",
      replaceS:function(text){ return text.split("\n").sort(function(a, b){ return ((a < b) ? 1 : ((a > b) ? -1 : 0)) }).join("\n") }
    };
  }
};

重複行排除

連続する重複行を削除」の移植を含みます.

f[f.length] = {
  title:"重複削除",
  group:function(f){
    f[f.length] = {
      title:"連続する重複を削除",
      replaceS:function(text){
        text = text.split("\n");
        var result = [text[0]];
        for (var i=1; i<text.length; i++) {
          if (text[i] !== text[i-1]) {
            result.push(text[i]);
          }
        }
        return result.join("\n");
      }
    };
    f[f.length] = {
      title:"重複行を削除",
      replaceS:function(text){
        text = text.split("\n");
        var result = [], map = {};
        for (var i=0; i<text.length; i++) {
          if (!map[text[i]]) {
            map[text[i]] = true;
            result.push(text[i]);
          }
        }
        return result.join("\n");
      }
    };
  }
};

文字列追加

f[f.length] = {
  title:"文字列追加",
  group:function(f){
    f[f.length] = {
      title:"先頭",
      replaceL:(function(text){
        var add = null;
        return function(text){
          if (!add) {
            add = Prompt("追加する文字列を入力してください.", "");
            if (!add) { Quit(); }
          }
          return add + text;
        };
      })()
    };
    f[f.length] = {
      title:"末尾",
      replaceL:(function(text){
        var add = null;
        return function(text){
          if (!add) {
            add = Prompt("追加する文字列を入力してください.", "");
            if (!add) { Quit(); }
          }
          return text + add;
        };
      })()
    };
  }
};

BASE64エンコード(Unicode)

f[f.length] = {
  title:"BASE64エンコード(Unicode)",
  replace:function(text){
    var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
    var Ch = function(n){ return n<text.length ? text.charCodeAt(n) : 0 };
    var len = text.length, pad = len % 3, s = "";
    for (var i=0; i<len; i+=3) {
      var tmp = (Ch(i)<<16) | (Ch(i+1)<<8) | Ch(i+2);
      s += map[(tmp>>>18)&0x3F] + map[(tmp>>>12)&0x3F] + map[(tmp>>>6)&0x3F] + map[tmp&0x3F];
    }
    if (pad) { s = s.substring(0, s.length-(3-pad)) + "===".substring(pad) }
    return s;
  }
};

開発者向け資料

これは拡張コードを開発される方向けの仕様です.
拡張コードは次のいずれかの関数を実装します.

  1. replace
  2. replaceS
  3. replaceL

replace

function replace(
    text : string,
    selection : Selection
) : string

最も基本的な変換関数です.
選択されている文字列,またはドキュメント全体の文字列を引数として, 変換結果を返します.
selection 引数は通常必要有りません. Selection の持つ関数を利用したい場合などに利用します.

replaceS

function replaceS(
    text : string,
    selection : Selection
) : string

行途中の選択がされている場合に,行全体を選択し直してから実行される変換関数です.
行は論理行で処理しますが,下記のように view:true を定義時に登録することで, 表示行で処理することもできます.

f[f.length] = {
  title:"replaceL",
  view:true,
  replaceS:function(text){ return text }
};

replaceL

function replaceL(
    text : string,
    selection : Selection
) : string

行単位で処理する場合に利用する変換関数です.
渡される text は,他の関数と違い「1 行分の文字列」です.
String.replaceString.split("\n").join("\n") を利用することで同様の処理が行えますが,より簡易的に処理するために用意されています.

次の 2 つの定義は同じ処理(空白行削除)をします.

replaceS:function(text){ return text.replace(/^\n/mg, "") }
replaceL:function(text){ if (text != "") { return text } }

replaceL 関数の場合,null を返すかあるいは return しない場合に行を削除します.

replaceL 関数は行毎に呼ばれるため,全体で 1 回のみの処理を記述するのが面倒です.
もし必要な場合は,拡張コードの「文字列追加」のようにクロージャを利用する必要があります.

ご意見・ご要望

何かありましたら,右の [編集] から追記してください.対応するもかしれません.

スポンサーリンク