「矩形ペースト」の版間の差分
見出しの修正、バージョンのフォーマットを修正 |
ソースコードの追加、ダウンロードの削除 |
||
| 81行目: | 81行目: | ||
** 初版 | ** 初版 | ||
== | == ソースコード == | ||
[[ | <syntaxhighlight lang="javascript"> | ||
#title="矩形ペースト" | |||
// BlockPaste.js | |||
// 2013/01/30 | |||
var use_popup = true; // true:ポップアップメニューを使う。 | |||
var bp_fix = true; // true:貼り付け要素の長さを最長のものに揃える。 | |||
var bp_overwrite = false; // true:上書き。 | |||
var bp_tail = false; // true:末尾に流し込み。 | |||
var bp_ignore_spc = true; // true:要素の先頭と末尾にある空白を無視する。 | |||
var spc = " "; // 桁数調整時に埋め込む文字。 | |||
var align = "left"; // left | right | center 貼り付け要素のアラインメント。 | |||
var aligned = "左寄せ" | |||
var leftmargin = 1; // 左マージン | |||
var rightmargin = 1; // 右マージン | |||
var r = 10; | |||
while ( r > 9 && use_popup ) { | |||
var menu = CreatePopupMenu(); | |||
menu.Add( "固定長:" + ( ( bp_fix ) ? "はい(" + aligned + ")" : "いいえ" ), 11, 0 ); | |||
menu.Add( ( ( bp_tail ) ? "末尾に流し込む" : ( ( bp_overwrite ) ? "上書きする" : "挿入する" ) ), 13, 0 ); | |||
menu.Add( "空白を無視" + ( ( bp_ignore_spc ) ? "する" : "しない" ), 14, 0 ); | |||
menu.Add( "-------", 0, meMenuSeparator ) | |||
menu.Add( "実行", 9, 0 ); | |||
r = menu.Track( 0 ); | |||
switch ( r ){ | |||
case 0 : | |||
Quit(); | |||
case 9 : | |||
break; | |||
case 11 : | |||
if ( !bp_fix ) { | |||
bp_fix = true; | |||
} else { | |||
switch( align ){ | |||
case "left" : | |||
align = "right"; | |||
aligned = "右寄せ"; | |||
break; | |||
case "right" : | |||
align = "center"; | |||
aligned = "中央揃え"; | |||
break; | |||
case "center" : | |||
align = "left"; | |||
aligned = "左寄せ"; | |||
bp_fix = false; | |||
break; | |||
default: Quit(); | |||
} | |||
} | |||
break; | |||
case 12 : | |||
bp_overwrite = !bp_overwrite; | |||
break; | |||
case 13 : | |||
if ( bp_tail ){ | |||
bp_tail = false; | |||
} else { | |||
if ( bp_overwrite ){ | |||
bp_overwrite = false; | |||
bp_tail = true; | |||
} else { | |||
bp_overwrite = true; | |||
} | |||
} | |||
break; | |||
case 14 : | |||
bp_ignore_spc = !bp_ignore_spc; | |||
break; | |||
default : | |||
Quit(); | |||
} | |||
} | |||
var clp = ClipboardData.GetData().replace( /\r\n/g, "\n" ); | |||
if ( clp.charCodeAt( clp.length - 1 ) == 0x0a ) { clp = clp.slice( 0, clp.length - 1 ) } | |||
var clpary = clp.split( "\n" ); | |||
var sele = document.selection; | |||
var ax = sele.GetActivePointX( mePosLogical ); | |||
var ay = sele.GetActivePointY( mePosLogical ); | |||
var len_ax = blength( document.GetLine( ay, 0 ).slice( 0, ax - 1 ) ); | |||
// 貼り付ける行のタブを空白にする。 | |||
sele.SetActivePoint( mePosLogical, 1, ay, false ); | |||
sele.SetActivePoint( mePosLogical, 1, ay + clpary.length - 1, true ); | |||
sele.EndOfLine( true, mePosLogical ); | |||
sele.Untabify(); | |||
if ( bp_ignore_spc ){ | |||
for ( var i = 0; i < clpary.length; i++ ) { | |||
clpary[ i ] = clpary[ i ].replace( /^\s+|\s+$/, "" ); | |||
} | |||
} | |||
var len_clp_max = 0; | |||
if ( bp_fix ) { | |||
for ( var i = 0; i < clpary.length; i++ ) { | |||
len_clp_max = ( blength( clpary[ i ] ) > len_clp_max ) ? blength( clpary[ i ] ) : len_clp_max ; | |||
} | |||
for ( var i = 0; i < clpary.length; i++ ) { | |||
clpary[ i ] = padding( clpary[ i ], len_clp_max, align, spc ); | |||
} | |||
} | |||
var output = []; | |||
for ( var i = 0; i < clpary.length; i++ ) { | |||
var s = document.GetLine( ay + i, 0 ); | |||
if ( bp_tail ) { | |||
var ds = { front : s, tail : "" }; | |||
} else { | |||
var ds = divide( padding( s, len_ax, "left", spc ), len_ax ); | |||
} | |||
if ( bp_overwrite ) { | |||
len_clp_max = ( bp_fix ) ? len_clp_max : blength( clpary[ i ] ); | |||
ds.tail = ds.tail.slice( bindex2i( ds.tail, len_clp_max ) ); | |||
} | |||
output.push( ds.front + repeat( spc, leftmargin ) + clpary[ i ] + repeat( spc, rightmargin ) + ds.tail ); | |||
} | |||
sele.Text = output.join( "\r\n" ); | |||
sele.SetActivePoint( mePosLogical, ax, ay, false ); | |||
// 文字列を指定箇所で二分割する。 | |||
function divide( str, bi ) { | |||
var i = bindex2i( str, bi ); | |||
return { | |||
front : padding( str.substr( 0, i ), bi, "left", spc ), | |||
tail : str.substr( i, str.length - 1 ) | |||
} | |||
} | |||
// 半角のインデックスに相当する標準のインデックスを返す。 | |||
function bindex2i( str, bi ) { | |||
var n = 0; | |||
for ( var i = 0; i < str.length; i++ ) { | |||
if ( !isHan( str.charAt( i ) ) ) { n++ } | |||
if ( i + n >= bi ) { return i } | |||
} | |||
return bi | |||
} | |||
// 指定桁数(半角)になるように spc を埋め込む。 | |||
function padding( str, len, align, spc ){ | |||
var x = len - blength( str ); | |||
if ( align == "right" ) { | |||
return repeat( spc, x ) + str; | |||
} else if ( align == "center" ) { | |||
return repeat( spc, Math.floor( x / 2 ) ) + str + repeat( spc, x - Math.floor( x / 2 ) ); | |||
} else { | |||
return str + repeat( spc, x ); | |||
} | |||
} | |||
// 文字列の繰り返し。 | |||
function repeat( str, n ) { | |||
var s = ""; | |||
for ( var i = 0; i < n; i++ ){ s += str } | |||
return s; | |||
} | |||
// 文字列の半角換算長さ。 | |||
function blength( str ) { | |||
var blen = 0; | |||
for ( var i = 0; i < str.length; i++ ) { | |||
( isHan( str.charAt( i ) ) ) ? blen += 1 : blen += 2; | |||
} | |||
return blen; | |||
} | |||
// 文字が半角のとき true。 | |||
function isHan( s ) { | |||
// Shift_JIS: 0x0 ~ 0x80, 0xa0 , 0xa1 ~ 0xdf , 0xfd ~ 0xff | |||
// Unicode : 0x0 ~ 0x80, 0xf8f0, 0xff61 ~ 0xff9f, 0xf8f1 ~ 0xf8f3 | |||
var c = s.charCodeAt( 0 ); | |||
return (( c >= 0x0 && c < 0x81 ) || ( c == 0xf8f0 ) || ( c >= 0xff61 && c < 0xffa0 ) || ( c >= 0xf8f1 && c < 0xf8f4 )); | |||
} | |||
</syntaxhighlight> | |||
スポンサーリンク