/**
* 1行選択ボックスで、テキストを一括処理するためのライブラリ集
*
* // 選択範囲のテキストを後方参照付き置換で一括変換。Unixのsedコマンドのパクり
* sed( '
(.*?) | ', '$1 | ' );
* // 選択範囲の各行に行番号を付加する
* $.each( function(s,i){ return i+'\t'+s; } ).send();
* // 選択範囲の的タグを消去する
* $.deltag().send();
*
*/
/**
* 指定されたパスのテキストを読みだします。
* @param {String} filename ファイル名
* @return {String} 読み出したテキスト
*/
function loadtext( filename ){
var fso = new ActiveXObject("Scripting.FileSystemObject");
if( !fso.FileExists(filename) ) return null; // ファイルが存在しないとき
var f = fso.OpenTextFile(filename, 1);
return f.readAll();
}
/**
* 指定されたJavaScriptのファイルを自分の中に取り込みます
* @param {String} filename ファイルのパス
* @return {Object} インクルードしたオブジェクト
*/
function include( filename ){
var s = loadtext(filename), o;
if( null==s ) return null;
try{ o=eval( '('+s+')' ); }catch(e){ return null; }
return o;
}
/**
* 外部xmlファイルを読み出すためのDOMオブジェクトを作成します
* @param {String} 外部XMLファイルのファイル名
* @return {DOMDocument} XMLドキュメント
*/
function loadxml( fname ){
// Instantiate a DOM object.
var doc;
try{
doc = new ActiveXObject("Microsoft.XMLDOM"); // MSXMLへのアクセスを出来るようにする
doc.async = false;
} catch ( e ){
App.Alert( "Error MakeDOM():"+e.description );
}
doc.load( fname ); // xml文書を読み出し
return doc;
}
/**
* 選択範囲を第1引数で与えられた正規表現で置換します
* 萌ディタの置換機能だと後方参照が何故か使えない、というかバグって止まるので変わりに作成
* @param {RegExp|String} re 置き換え位置を探す正規表現
* @param {String} rs 置き換える文字列
* @example
* // 選択部分だけ、tdタグをthタグに変更する
* sed( '(.*?) | ', '$1 | ' );
*/
function sed( re, rs ){
var c = App.Caret, slct = App.Caret.Selection;
if( !slct.Mode ) return App.Alert('選択範囲がありません!');
if( 'string'==typeof re ) re = new RegExp( re, 'g' ); // 文字列を正規表現オブジェクト化
UpdateGroup(
function(){
var s = slct.Text, scal={ col:c.Col, row:c.Row }; // 加工前のキャレット位置を保存
c.Delete( s.length );
if( 'string'==typeof re ) re=new RegExp( re, 'g' );
c.Send( s.replace( re, rs ) );
// キャレット位置を元に戻す
c.Col = scal.col;
c.Row = scal.row;
},
'正規表現による一括置換'
);
App.Alert( '置換完了!' );
}
var f = classes['srcfile'];
f.onEvaluate = function(arg, classname, methodname){
//ウィンドウの 1 行バッファにスクリプトが入力されたときに呼ばれる
var match_array, eval_func;
// \2 を文字列とみなして、\1 回 Send() する
// ex) "80 '-" -> 80 個の '-' を Send()
match_array = arg.match(/^ *([0-9]+) +['"]/);
if(match_array){
var original = eval('\'' + arg.substring(match_array.lastIndex).replace(/\'/g, '\\\'') + '\'');
if(original != '') {
var ret = original;
var whole_length = original.length * parseInt(match_array[1]);
while(ret.length * 2 <= whole_length) ret += ret;
while(ret.length < whole_length) ret += original;
App.Caret.Send(ret);
}
return;
}
// \2 を関数本体とみなして、\1 回評価する
// ex) "10 App.Caret.MoveNext(1)" -> キャレットを 10 行下へ移動
match_array = arg.match(/^ *([0-9]+) +/);
if(match_array) {
eval_func = new Function(arg.substring(match_array.lastIndex));
for(var j = 0; j < parseInt(match_array[1]); j++)
eval_func();
return;
}
// \2 を関数内の式とみなして評価し、結果を Send() する
// ex) "? 99*99" -> 99*99 の結果である 9801 を Send()
match_array = arg.match(/^ *\? */);
if(match_array) {
eval_func = new Function('return ' + arg.substring(match_array.lastIndex) + ';');
App.Caret.Send(eval_func().toString() + '\n');
return;
}
// arg 全体を関数本体とみなして評価する
// ex) "App.Buffer.Save('')" -> 保存する
var c = App.Caret, slct = App.Caret.Selection;
var $ = st = sxt = (function(){ return (slct.Mode)?slct.Text:''; })(); // 選択範囲テキスト
var alert = function(mes){ App.Alert(mes); } // alertダイアログ
eval('function eval_func(){'+arg.replace(/'/g,"\'")+'};');
eval_func.call(this);
}
/**
* よく使うので、操作グループの登録、削除を関数化
* @param {Function} f 内部で行う操作
* @param {String} desc 操作グループの説明
*/
function UpdateGroup( f, label ){
var desc = label ? label : f.toString().substring( 0, 10 );
var arg = (arguments.length>3) ? arguments.slice( 2, undefined ) : undefined; // 関数fに与える引数
var c=App.Caret, ctx = c.BeginUpdate();
try {
c.BeginOperateGroup('操作:'+desc);
try { (undefined==arg) ? f() : f(arg); } finally { c.EndOperateGroup(); }
} finally { c.EndUpdate(ctx); }
}
/**
* 汎用の URI に対する色づけ。本体のcore.javascript.txtにバグがあるので、こちらで上書き
*/
function addURIRule(lex, state) {
lex.Add( 'uri', (state?state:'') + '/\\max ) a.reverse();
return a;
}
var arg=arguments;
// 最大値のみ指定
if( 1==arg.length && 'number'==typeof max ) return crtarr( 0, max );
// 最小値、最大値を指定
if( 2==arg.length && 'number'==typeof arg[0] && 'number'==typeof arg[1] ) return crtarr( arg[0], arg[1] );
// 文字列で指定
var arr=[];
if( 'string'!=typeof max ) return arr;
var sp = max.split(','), m;
for( i=0; i/g, '' );
}
/**
* 文字列の長さを、指定した長さで調整する。
* 長さに足りない場合は、空白スペースで埋め合わせする
* @param {Integer} n 長さマッチ条件
* @param {String} [fill=' '] 埋め合わせ文字列
* @return {String} 置換処理後の文字列
* @example
* "abra".pad(10,'*'); // 「abra******」が返る
* "abcd".pad(10,'efg'); // 「abcdefgefg」が返る
* "abcdefghj".pad(5); // 長さが足りている場合はそのまま
*/
String.prototype.pad = function( n, fill ){
if( !fill ) fill = ' ';
var s = this;
s = s.substring( 0, n );
while( n>s.toString().length ) s+=fill;
return s;
}
/**
* マッチ条件に合致する部分が見つかったら
* 与えられた関数で処理を行った結果で置換を行います
* @param {RegExp} m マッチ条件
* @param {Function|String} fn 処理を行う関数
* @return {String} 置換処理後の文字列
*/
String.prototype.gsub = function( rx, fn ){
var s = this;
if( 'string'==typeof rx ) rx = new RegExp( rx );
var cnt=0, i=0, rs=''; // 置き換え後の文字を代入
while( -1 != (i=s.search(rx)) ){
if( cnt++>100 ) break; // 無限ループ回避
rs += s.substring( 0, i );
// 置き換え処理実行
s = s.substring( i-1, s.length ); // 直前まで回避
var r = s.match(rx)[0];
s = s.substring( r.length+1, s.length );
rs += ('function'==typeof fn)?fn(r):fn.toString();
}
rs += s;
return rs;
}
/**
* String.prototype.splitの簡略表記系
* 引数を指定しない場合、改行で区切ります
* @param {String} splitter 分割文字
* @param {Number} [limit] 分割数の制限
*/
String.prototype.toArray =
String.prototype.to_a =
String.prototype._a = function( splitter, limit ){
var arr=[];
for( var i=0; i