「ラクラク罫線」の版間の差分
ナビゲーションに移動
検索に移動
コメントの追加 |
変数にvarの宣言を追加 |
||
| (同じ利用者による、間の2版が非表示) | |||
| 79行目: | 79行目: | ||
var notch = ""; | var notch = ""; | ||
var depth = 35; | var depth = 35; | ||
var single_spc = " " | var single_spc = " "; | ||
var bouble_spc = " "; | var bouble_spc = " "; | ||
| 88行目: | 88行目: | ||
String.prototype.spcW = bouble_spc; | String.prototype.spcW = bouble_spc; | ||
// インデックス番号iの文字が半角であるかどうか。 | // インデックス番号iの文字が半角であるかどうか。 | ||
String.prototype.isHan = function( i ){ | String.prototype.isHan = function(i) { | ||
// Shift_JIS: 0x0 ~ 0x80, 0xa0 , 0xa1 ~ 0xdf , 0xfd ~ 0xff | // Shift_JIS: 0x0 ~ 0x80, 0xa0 , 0xa1 ~ 0xdf , 0xfd ~ 0xff | ||
// Unicode : 0x0 ~ 0x80, 0xf8f0, 0xff61 ~ 0xff9f, 0xf8f1 ~ 0xf8f3 | // Unicode : 0x0 ~ 0x80, 0xf8f0, 0xff61 ~ 0xff9f, 0xf8f1 ~ 0xf8f3 | ||
var c = this.charCodeAt( i ); | var c = this.charCodeAt(i); | ||
return ( ( c >= 0x0 && c < 0x81 ) || ( c == 0xf8f0 ) || ( c >= 0xff61 && c < 0xffa0 ) || ( c >= 0xf8f1 && c < 0xf8f4 ) ); | return ((c >= 0x0 && c < 0x81) || (c == 0xf8f0) || (c >= 0xff61 && c < 0xffa0) || (c >= 0xf8f1 && c < 0xf8f4)); | ||
} | }; | ||
// 文字列の長さ。半角換算。 | // 文字列の長さ。半角換算。 | ||
String.prototype.blength = function(){ | String.prototype.blength = function() { | ||
var blen = 0; | var blen = 0; | ||
for ( var i = 0; i < this.length; i++ ){ | for (var i = 0; i < this.length; i++) { | ||
( this.isHan( i ) )? blen += 1: blen += 2; | (this.isHan(i)) ? blen += 1: blen += 2; | ||
} | } | ||
return blen; | return blen; | ||
} | }; | ||
// インデックス番号の変換(半角→通常)。 | // インデックス番号の変換(半角→通常)。 | ||
String.prototype.bindex2i = function( bi ){ | String.prototype.bindex2i = function(bi) { | ||
if ( bi < 0 ){Alert( "bi < 0 in bindex2i !!" );Quit()} | if (bi < 0) { | ||
Alert("bi < 0 in bindex2i !!"); | |||
Quit(); | |||
} | |||
var n = 0; | var n = 0; | ||
for ( var i = 0; i < this.length; i++ ){ | for (var i = 0; i < this.length; i++) { | ||
if ( !this.isHan( i ) ){ n++ } | if (!this.isHan(i)) { | ||
if ( i + n >= bi ){ return i } | n++; | ||
} | |||
if (i + n >= bi) { | |||
return i; | |||
} | |||
} | } | ||
return bi | return bi; | ||
} | }; | ||
// 文字列から指定した位置の文字を抜き出し。半角指定。 | // 文字列から指定した位置の文字を抜き出し。半角指定。 | ||
String.prototype.bcharAt = function( bi ){ | String.prototype.bcharAt = function(bi) { | ||
var i = this.bindex2i( bi ); | var i = this.bindex2i(bi); | ||
if ( bi >= this.blength() ){ i = this.length } | if (bi >= this.blength()) { | ||
return this.charAt( i ); | i = this.length; | ||
} | } | ||
return this.charAt(i); | |||
}; | |||
// 文字列を分割。半角指定。 | // 文字列を分割。半角指定。 | ||
String.prototype.bdiv2ary = function( bi ){ | String.prototype.bdiv2ary = function(bi) { | ||
var i = this.bindex2i( bi ); | var i = this.bindex2i(bi); | ||
return { front: this.substr( 0, i ), tail: this.substr( i, this.length - i ) } | return { | ||
} | front: this.substr(0, i), | ||
tail: this.substr(i, this.length - i) | |||
}; | |||
}; | |||
// 文字列の繰り返し。 | // 文字列の繰り返し。 | ||
String.prototype.repeat = function( n ){ | String.prototype.repeat = function(n) { | ||
var str = this | var str = this; | ||
var s = ""; | var s = ""; | ||
while ( n > 0 ){ | while (n > 0) { | ||
if( n & 1 ){ s += str } | if (n & 1) { | ||
n = n>>1; | s += str; | ||
} | |||
n = n >> 1; | |||
str += str; | str += str; | ||
} | } | ||
return s; | return s; | ||
} | }; | ||
// 文字列を指定桁数まで延長。半角指定。 | // 文字列を指定桁数まで延長。半角指定。 | ||
String.prototype.beven = function( bn ){ | String.prototype.beven = function(bn) { | ||
switch ( arguments.length ){ | switch (arguments.length) { | ||
case 0: bn = 0; | case 0: | ||
bn = 0; | |||
} | } | ||
var re = new RegExp( this.spcS + "+$", "ig" ); | var re = new RegExp(this.spcS + "+$", "ig"); | ||
var str = this; | var str = this; | ||
str = str.replace( re, "" ); | str = str.replace(re, ""); | ||
var s = ""; | var s = ""; | ||
if ( bn == 0 ){ | if (bn == 0) { | ||
s = | s = str + this.spcS.repeat(str.blength() % 2); | ||
}else{ | } else { | ||
bn += bn % 2; | bn += bn % 2; | ||
s = | s = str + this.spcS.repeat(bn - str.blength()); | ||
} | } | ||
var re = new RegExp( this.spcS + "{2}", "ig" ); | var re = new RegExp(this.spcS + "{2}", "ig"); | ||
s = s.replace( re, this.spcW ); | s = s.replace(re, this.spcW); | ||
return s; | return s; | ||
} | }; | ||
// 最長要素の長さ。半角換算。 | // 最長要素の長さ。半角換算。 | ||
Array.prototype.maxbLen = function(){ | Array.prototype.maxbLen = function() { | ||
var blen = 0; | var blen = 0; | ||
for ( var i = 0; i < this.length; i++ ){ | for (var i = 0; i < this.length; i++) { | ||
if ( typeof( this[i] ) != "string" ){ Alert( "maxbLen!" ); Quit() } | if (typeof(this[i]) != "string") { | ||
Alert("maxbLen!"); | |||
Quit(); | |||
} | |||
var s = this[i].blength(); | var s = this[i].blength(); | ||
( blen > s )? blen: blen = s; | (blen > s) ? blen: blen = s; | ||
} | } | ||
return blen; | return blen; | ||
} | }; | ||
// -- 罫線を引くオブジェクト -- | // -- 罫線を引くオブジェクト -- | ||
TblRuler = function(){ | var TblRuler = function() { | ||
this.initialize.apply(this, arguments); | |||
} | }; | ||
TblRuler.prototype = { | TblRuler.prototype = { | ||
spcS : single_spc, | spcS: single_spc, | ||
spcW : bouble_spc, | spcW: bouble_spc, | ||
action : "none", | action: "none", | ||
tbl : [], | tbl: [], | ||
x1 : 0, | x1: 0, | ||
y1 : 0, | y1: 0, | ||
x2 : 0, | x2: 0, | ||
y2 : 0, | y2: 0, | ||
initialize : function( tblTop, tblBottom, tx, ty, bx, by, str ){ | initialize: function(tblTop, tblBottom, tx, ty, bx, by, str) { | ||
this.tbl = str.split( "\n" ); | this.tbl = str.split("\n"); | ||
this.y1 = ty - tblTop; | this.y1 = ty - tblTop; | ||
this.x1 = this.tbl[ this.y1 ].substr( 0, tx-1 ).blength(); | this.x1 = this.tbl[this.y1].substr(0, tx - 1).blength(); | ||
this.y2 = by - tblTop; | this.y2 = by - tblTop; | ||
this.x2 = this.tbl[ this.y2 ].substr( 0, bx-1 ).blength(); | this.x2 = this.tbl[this.y2].substr(0, bx - 1).blength(); | ||
this.tx = tx; | this.tx = tx; | ||
this.bx = bx; | this.bx = bx; | ||
}, | }, | ||
length : function(){ return this.tbl.length}, | length: function() { | ||
vline : function(){ | return this.tbl.length; | ||
}, | |||
vline: function() { | |||
this.action = "vline"; | this.action = "vline"; | ||
var vksen = "│"; | var vksen = "│"; | ||
| 197行目: | 217行目: | ||
var l_ary = []; | var l_ary = []; | ||
var r_ary = []; | var r_ary = []; | ||
for ( var i = this.y1; i <= this.y2; i++ ){ | for (var i = this.y1; i <= this.y2; i++) { | ||
var ft = this.tbl[i].bdiv2ary( this.x1 ); | var ft = this.tbl[i].bdiv2ary(this.x1); | ||
l_ary.push( ft.front ); | l_ary.push(ft.front); | ||
r_ary.push( ft.tail ); | r_ary.push(ft.tail); | ||
} | } | ||
for ( var i = 0; i < r_ary.length; i++ ){ | for (var i = 0; i < r_ary.length; i++) { | ||
var r_aryi = r_ary[i].split( vksen ); | var r_aryi = r_ary[i].split(vksen); | ||
r_aryi[0] = r_aryi[0].beven(); | r_aryi[0] = r_aryi[0].beven(); | ||
r_ary [i] = r_aryi.join( vksen ); | r_ary[i] = r_aryi.join(vksen); | ||
} | } | ||
var lenL = l_ary.maxbLen(); | var lenL = l_ary.maxbLen(); | ||
var lenR = r_ary.maxbLen() | var lenR = r_ary.maxbLen(); | ||
for ( var i = 0; i < this.tbl.length; i++ ){ | for (var i = 0; i < this.tbl.length; i++) { | ||
if ( i >= this.y1 && i <= this.y2 ){ | if (i >= this.y1 && i <= this.y2) { | ||
this.tbl[i] = l_ary[ i - this.y1 ].beven( lenL ) + vksen + r_ary[ i - this.y1 ]; | this.tbl[i] = l_ary[i - this.y1].beven(lenL) + vksen + r_ary[i - this.y1]; | ||
} | } | ||
} | } | ||
}, | }, | ||
vline_at_end: function(){ | vline_at_end: function() { | ||
this.action = "vline_at_end"; | this.action = "vline_at_end"; | ||
for ( var i = this.y1; i <= this.y2; i++ ){ | for (var i = this.y1; i <= this.y2; i++) { | ||
var work = this.tbl[ i ].split( "" ); | var work = this.tbl[i].split(""); | ||
var rend = work.pop(); | var rend = work.pop(); | ||
if ( /[─│┌┐└┘├┤┬┴┼]/.test( rend ) ){ work.push( this.spcW + rend ) }else{ work.push( rend + this.spcW ) } | if (/[─│┌┐└┘├┤┬┴┼]/.test(rend)) { | ||
this.tbl[ i ] = work.join ( "" ); | work.push(this.spcW + rend); | ||
} else { | |||
work.push(rend + this.spcW); | |||
} | |||
this.tbl[i] = work.join(""); | |||
} | } | ||
}, | }, | ||
hline : function(){ | hline: function() { | ||
this.action = "hline"; | this.action = "hline"; | ||
var hksen = "─"; | var hksen = "─"; | ||
var s = this.tbl[ this.y1 ].slice( tx - 1, bx - 1 ); | var s = this.tbl[this.y1].slice(tx - 1, bx - 1); | ||
var regK = new RegExp( "[─│┌┐└┘├┤┬┴┼]", "i" ); | var regK = new RegExp("[─│┌┐└┘├┤┬┴┼]", "i"); | ||
var reg = new RegExp( "[^" + this.spcW + "]+","i" ); | var reg = new RegExp("[^" + this.spcW + "]+", "i"); | ||
var mid = s.slice( 1, s.length - 1 ); | var mid = s.slice(1, s.length - 1); | ||
if ( s.length >= 3 && regK.test(s.charAt(0)) && regK.test(s.charAt( s.length - 1 )) && !reg.test( mid )){ | if (s.length >= 3 && regK.test(s.charAt(0)) && regK.test(s.charAt(s.length - 1)) && !reg.test(mid)) { | ||
var reg2 = new RegExp( this.spcW ,"ig" ); | var reg2 = new RegExp(this.spcW, "ig"); | ||
var c = this.tbl[ this.y1 ].split("") | var c = this.tbl[this.y1].split(""); | ||
s = s.replace( reg2, hksen ); | s = s.replace(reg2, hksen); | ||
c.splice( tx - 1, bx - tx, s ); | c.splice(tx - 1, bx - tx, s); | ||
this.tbl[ this.y1 ] = c.join(""); | this.tbl[this.y1] = c.join(""); | ||
}else{ | } else { | ||
var xmax = 0; | var xmax = 0; | ||
if ( this.y1 >= this.tbl.length - 1 ){ | if (this.y1 >= this.tbl.length - 1) { | ||
xmax = this.tbl[ this.y1 ].blength(); | xmax = this.tbl[this.y1].blength(); | ||
}else{ | } else { | ||
xmax = Math.max( this.tbl[ this.y1 ].blength(), this.tbl[ this.y1 + 1 ].blength() ); | xmax = Math.max(this.tbl[this.y1].blength(), this.tbl[this.y1 + 1].blength()); | ||
} | } | ||
var s1 = this.spcW.repeat( ( this.x1 + 1 ) / 2 ); | var s1 = this.spcW.repeat((this.x1 + 1) / 2); | ||
var s2 = hksen.repeat( ( this.x2 - this.x1 + 1) / 2 ); | var s2 = hksen.repeat((this.x2 - this.x1 + 1) / 2); | ||
var s3 = this.spcW.repeat( ( xmax - s1.blength() - s2.blength() + 1 ) / 2 ); | var s3 = this.spcW.repeat((xmax - s1.blength() - s2.blength() + 1) / 2); | ||
var s = s1 + s2 + s3; | var s = s1 + s2 + s3; | ||
this.tbl.splice( this.y1 + 1, 0, s ); | this.tbl.splice(this.y1 + 1, 0, s); | ||
} | } | ||
}, | }, | ||
makeFrame : function(){ | makeFrame: function() { | ||
this.action = "makeFrame"; | this.action = "makeFrame"; | ||
var re = new RegExp( "[" + this.spcS + this.spcW + "]+$", "i" ); | var re = new RegExp("[" + this.spcS + this.spcW + "]+$", "i"); | ||
for ( var i = 0; i < this.tbl.length; i++ ){ | for (var i = 0; i < this.tbl.length; i++) { | ||
this.tbl[i] = this.tbl[i].replace( re, "" ); | this.tbl[i] = this.tbl[i].replace(re, ""); | ||
} | } | ||
var len = this.tbl.maxbLen() + this.tbl.maxbLen() % 2; | var len = this.tbl.maxbLen() + this.tbl.maxbLen() % 2; | ||
for ( var i = 0; i < this.tbl.length; i++ ){ | for (var i = 0; i < this.tbl.length; i++) { | ||
this.tbl[i] = "│" + this.tbl[i].beven( len ) + "│"; | this.tbl[i] = "│" + this.tbl[i].beven(len) + "│"; | ||
} | } | ||
this.tbl.unshift( "┌" + "─".repeat( len / 2 ) + "┐" ); | this.tbl.unshift("┌" + "─".repeat(len / 2) + "┐"); | ||
this.tbl.push( "└" + "─".repeat( len / 2 ) + "┘" ); | this.tbl.push("└" + "─".repeat(len / 2) + "┘"); | ||
}, | }, | ||
linkChk : function( bx, y ){ | linkChk: function(bx, y) { | ||
var s = 0; | var s = 0; | ||
// 上は? | // 上は? | ||
if ( y >= 1 ){ | if (y >= 1) { | ||
var c = this.tbl[ y-1 ].bcharAt( bx ); | var c = this.tbl[y - 1].bcharAt(bx); | ||
if ( /[┌┐│┬├┼┤]/.test( c ) ){ s += 8 } | if (/[┌┐│┬├┼┤]/.test(c)) { | ||
s += 8; | |||
} | |||
} | } | ||
// 下は? | // 下は? | ||
if ( y < this.tbl.length - 1 ){ | if (y < this.tbl.length - 1) { | ||
var c = this.tbl[ y+1 ].bcharAt( bx ); | var c = this.tbl[y + 1].bcharAt(bx); | ||
if ( /[└┘│┴├┼┤]/.test( c ) ){ s += 4 } | if (/[└┘│┴├┼┤]/.test(c)) { | ||
s += 4; | |||
} | |||
} | } | ||
// 左は? | // 左は? | ||
if ( this.tbl[ y ].bindex2i( bx ) >= 1 ){ | if (this.tbl[y].bindex2i(bx) >= 1) { | ||
var c = this.tbl[y].charAt( this.tbl[y].bindex2i( bx ) - 1 ); | var c = this.tbl[y].charAt(this.tbl[y].bindex2i(bx) - 1); | ||
if ( /[┌└─┬┼├┴]/.test( c ) ){ s += 2 } | if (/[┌└─┬┼├┴]/.test(c)) { | ||
s += 2; | |||
} | |||
} | } | ||
// 右は? | // 右は? | ||
if ( this.tbl[ y ].bindex2i( bx ) < this.tbl[y].length - 1 ){ | if (this.tbl[y].bindex2i(bx) < this.tbl[y].length - 1) { | ||
var c = this.tbl[y].charAt( this.tbl[y].bindex2i( bx ) + 1 ); | var c = this.tbl[y].charAt(this.tbl[y].bindex2i(bx) + 1); | ||
if ( /[┐┘─┬┼┤┴]/.test( c ) ){ s += 1 } | if (/[┐┘─┬┼┤┴]/.test(c)) { | ||
s += 1; | |||
} | |||
} | } | ||
return s; | return s; | ||
}, | }, | ||
code2char : function( code ){ | code2char: function(code) { | ||
switch ( code ){ | switch (code) { | ||
case | case 0: | ||
case | return ""; | ||
case | case 1: | ||
case | return ""; | ||
case | case 2: | ||
case | return ""; | ||
case | case 3: | ||
case | return "─"; // " LR" | ||
case | case 4: | ||
case | return ""; | ||
case 10 : return "┘"; | case 5: | ||
case 11 : return "┴"; | return "┌"; // " D R" | ||
case 12 : return "│"; | case 6: | ||
case 13 : return "├"; | return "┐"; // " DL" | ||
case 14 : return "┤"; | case 7: | ||
case 15 : return "┼"; | return "┬"; // " DLR" | ||
default : return ""; | case 8: | ||
return ""; | |||
case 9: | |||
return "└"; // "U R" | |||
case 10: | |||
return "┘"; // "U L " | |||
case 11: | |||
return "┴"; // "U LR" | |||
case 12: | |||
return "│"; // "UD " | |||
case 13: | |||
return "├"; // "UD R" | |||
case 14: | |||
return "┤"; // "UDL " | |||
case 15: | |||
return "┼"; // "UDLR" | |||
default: | |||
return ""; | |||
} | } | ||
}, | }, | ||
adjust : function(){ | adjust: function() { | ||
this.action = "adjust"; | this.action = "adjust"; | ||
var work = this.tbl.slice( 0 ); | var work = this.tbl.slice(0); | ||
var re = new RegExp( this.spcS + "{2}", "ig" ); | var re = new RegExp(this.spcS + "{2}", "ig"); | ||
for ( var y = 0; y < this.tbl.length; y++ ){ | for (var y = 0; y < this.tbl.length; y++) { | ||
var line = this.tbl[ y ].replace( re, this.spcW ); | var line = this.tbl[y].replace(re, this.spcW); | ||
var ex = ""; | var ex = ""; | ||
var bi = 0; | var bi = 0; | ||
while ( | while (bi < line.blength()) { | ||
var ks2 = this.code2char( this.linkChk( bi, y ) ); | var ks2 = this.code2char(this.linkChk(bi, y)); | ||
var s = line.bcharAt( bi ); | var s = line.bcharAt(bi); | ||
if ( /[─│┌┐└┘├┤┬┴┼ ]/.test( s ) && ks2.length != 0 ){ | if (/[─│┌┐└┘├┤┬┴┼ ]/.test(s) && ks2.length != 0) { | ||
ex += ks2; | ex += ks2; | ||
}else{ | } else { | ||
ex += s; | ex += s; | ||
} | } | ||
if ( s.isHan() ){ bi += 1 }else{ bi += 2 } | if (s.isHan()) { | ||
bi += 1; | |||
} else { | |||
bi += 2; | |||
} | |||
} | } | ||
work[ y ] = ex; | work[y] = ex; | ||
} | } | ||
this.tbl = work.slice( 0 ); | this.tbl = work.slice(0); | ||
var re = new RegExp( "[" + this.spcS + this.spcW + "]+$","i" ); | var re = new RegExp("[" + this.spcS + this.spcW + "]+$", "i"); | ||
for ( var i = 0; i < this.tbl.length; i++ ){ | for (var i = 0; i < this.tbl.length; i++) { | ||
this.tbl[ i ] = this.tbl[ i ].replace( re, "" ); | this.tbl[i] = this.tbl[i].replace(re, ""); | ||
} | } | ||
}, | }, | ||
adjust_line : function( y ){ | adjust_line: function(y) { | ||
this.action = "adjust_line"; | this.action = "adjust_line"; | ||
var re = new RegExp( this.spcS + "{2}", "ig" ); | var re = new RegExp(this.spcS + "{2}", "ig"); | ||
var line = this.tbl[ y ].replace( re, this.spcW ); | var line = this.tbl[y].replace(re, this.spcW); | ||
var ex = ""; | var ex = ""; | ||
var bi = 0; | var bi = 0; | ||
while ( | while (bi < line.blength()) { | ||
var ks2 = this.code2char( this.linkChk( bi, y ) ); | var ks2 = this.code2char(this.linkChk(bi, y)); | ||
var s = line.bcharAt( bi ); | var s = line.bcharAt(bi); | ||
if ( /[─│┌┐└┘├┤┬┴┼ ]/.test( s ) && ks2.length != 0 ){ ex += ks2 }else{ ex += s } | if (/[─│┌┐└┘├┤┬┴┼ ]/.test(s) && ks2.length != 0) { | ||
if ( s.isHan() ){ bi += 1 }else{ bi += 2 } | ex += ks2; | ||
} else { | |||
ex += s; | |||
} | |||
if (s.isHan()) { | |||
bi += 1; | |||
} else { | |||
bi += 2; | |||
} | |||
} | } | ||
this.tbl[ y ] = ex; | this.tbl[y] = ex; | ||
} | } | ||
} | }; | ||
function ruler_action(){ | function ruler_action() { | ||
if ( | if (tx == 1 && tx == bx && by == tblTop) { | ||
return "makeframe" | return "makeframe"; | ||
}else if ( tx == 1 && tx == bx && ty == tblBottom ){ | } else if (tx == 1 && tx == bx && ty == tblBottom) { | ||
return "adjust" | return "adjust"; | ||
}else if ( tx == 1 && by == ty && ax == 1 ){ | } else if (tx == 1 && by == ty && ax == 1) { | ||
return "adjust_line" | return "adjust_line"; | ||
}else if ( tx == document.GetLine( ty ).length + 1 ){ | } else if (tx == document.GetLine(ty).length + 1) { | ||
return "vline_at_end" | return "vline_at_end"; | ||
}else if ( tx != bx && ty == by ){ | } else if (tx != bx && ty == by) { | ||
return "hline" | return "hline"; | ||
} | } | ||
return "vline"; | return "vline"; | ||
| 372行目: | 433行目: | ||
// 選択範囲の記録と伸張。 | // 選択範囲の記録と伸張。 | ||
var sel = Editor.ActiveDocument.Selection; | var sel = Editor.ActiveDocument.Selection; | ||
var tx = sel.GetTopPointX( mePosLogical ); | var tx = sel.GetTopPointX(mePosLogical); | ||
var ty = sel.GetTopPointY( mePosLogical ); | var ty = sel.GetTopPointY(mePosLogical); | ||
var bx = sel.GetBottomPointX( mePosLogical ); | var bx = sel.GetBottomPointX(mePosLogical); | ||
var by = sel.GetBottomPointY( mePosLogical ); | var by = sel.GetBottomPointY(mePosLogical); | ||
var ax = sel.GetActivePointX( mePosLogical ); | var ax = sel.GetActivePointX(mePosLogical); | ||
var ay = sel.GetActivePointY( mePosLogical ); | var ay = sel.GetActivePointY(mePosLogical); | ||
sel.SetActivePoint( mePosLogical, | sel.SetActivePoint(mePosLogical, 1, ty, false); | ||
sel.SetActivePoint( mePosLogical, | sel.SetActivePoint(mePosLogical, 1, by, true); | ||
if ( ( bx == 1 )&&( ty != by ) ){ | if ((bx == 1) && (ty != by)) { | ||
sel.CharLeft( true, 1 ); | sel.CharLeft(true, 1); | ||
bx = sel.GetBottomPointX( mePosLogical ); | bx = sel.GetBottomPointX(mePosLogical); | ||
by--; | by--; | ||
}else{ | } else { | ||
sel.EndOfLine( true, mePosLogical ); | sel.EndOfLine(true, mePosLogical); | ||
} | } | ||
var tblTop = ty; | var tblTop = ty; | ||
var tblBottom = by; | var tblBottom = by; | ||
for ( var i = 0; i <= depth; i++ ){ | for (var i = 0; i <= depth; i++) { | ||
var line = document.GetLine( ty - i ); | var line = document.GetLine(ty - i); | ||
if( line.charAt( 0 )===( notch ) || ty - i <= 0 ){ | if (line.charAt(0) === (notch) || ty - i <= 0) { | ||
break; | break; | ||
} | } | ||
tblTop = ty - i; | tblTop = ty - i; | ||
} | } | ||
for ( var i = 0; i <= depth; i++ ){ | for (var i = 0; i <= depth; i++) { | ||
var line = document.GetLine( by + i ); | var line = document.GetLine(by + i); | ||
if( line.charAt( 0 )===( notch ) || by + i >= document.GetLines() ){ | if (line.charAt(0) === (notch) || by + i >= document.GetLines()) { | ||
break; | break; | ||
} | } | ||
tblBottom = by + i; | tblBottom = by + i; | ||
} | } | ||
if ( ty < tblTop ){ tblTop = ty } | if (ty < tblTop) { | ||
if ( by > tblBottom ){ tblBottom = by} | tblTop = ty; | ||
sel.SetActivePoint( mePosLogical, 1, tblTop, false ) | } | ||
sel.SetActivePoint( mePosLogical, 1, tblBottom, true ) | if (by > tblBottom) { | ||
sel.EndOfLine( true, mePosLogical ); | tblBottom = by; | ||
} | |||
sel.SetActivePoint(mePosLogical, 1, tblTop, false); | |||
sel.SetActivePoint(mePosLogical, 1, tblBottom, true); | |||
sel.EndOfLine(true, mePosLogical); | |||
var tblruler = new TblRuler( tblTop, tblBottom, tx, ty, bx, by, document.selection.text ); | var tblruler = new TblRuler(tblTop, tblBottom, tx, ty, bx, by, document.selection.text); | ||
switch ( ruler_action() ){ | switch (ruler_action()) { | ||
case "makeframe": | case "makeframe": | ||
tblruler.makeFrame(); | tblruler.makeFrame(); | ||
| 421行目: | 486行目: | ||
break; | break; | ||
case "adjust_line": | case "adjust_line": | ||
tblruler.adjust_line( ty - tblTop ); | tblruler.adjust_line(ty - tblTop); | ||
break; | break; | ||
case "hline": | case "hline": | ||
tblruler.hline(); | tblruler.hline(); | ||
break; | break; | ||
| 429行目: | 494行目: | ||
tblruler.vline_at_end(); | tblruler.vline_at_end(); | ||
break; | break; | ||
default : | default: | ||
tblruler.vline(); | tblruler.vline(); | ||
} | } | ||
sel.SetActivePoint( mePosLogical, 1, tblTop, false ) | sel.SetActivePoint(mePosLogical, 1, tblTop, false); | ||
sel.SetActivePoint( mePosLogical, 1, tblBottom, true ) | sel.SetActivePoint(mePosLogical, 1, tblBottom, true); | ||
sel.EndOfLine( true, mePosLogical ); | sel.EndOfLine(true, mePosLogical); | ||
sel.Text = tblruler.tbl.join( "\r\n" ); | sel.Text = tblruler.tbl.join("\r\n"); | ||
sel.SetActivePoint( mePosLogical, tx, ty, false ); | sel.SetActivePoint(mePosLogical, tx, ty, false); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| 447行目: | 512行目: | ||
var clp = ClipboardData.GetData(); | var clp = ClipboardData.GetData(); | ||
ClipboardData.SetData( document.Selection.Text ); | ClipboardData.SetData(document.Selection.Text); | ||
document.Selection.Text = clp; | document.Selection.Text = clp; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
2025年11月24日 (月) 20:40時点における最新版
概要[編集]
- 罫線での表組み作成を支援するマクロです。
- マウスの指定だけで、文字列を囲んだり、タテ・ヨコの罫線を引くことができます。
使い方[編集]
- 行(複数行の場合は、一番上の行)の最左にカーソルを置いてマクロを実行すると、その行を罫線で囲みます。
- 最下行の最左にカーソルを置いてマクロを実行すると、罫線の調整を行います。
- 単一行をダブルクリック等で選択した場合は、その行に対してのみ罫線の調整を行います。
- マウスドラッグで同一行内の範囲を選択してマクロを実行すると、選択した文字の下にヨコ罫線を引きます。このとき、選択領域の両端が罫線かつその間が全角空白のみであれば、全角空白をヨコ罫線に置きかえます。
- 行の最後から選択を始めると、最後の文字が罫線のときはその罫線の前に全角空白を挿入し、そうでないときは全角空白を最後尾に追加します。
- 上記以外の選択をしてマクロを実行すると、最上部の選択文字の左側の位置で選択行に渡ってタテ罫線を引きます。
(例1)
abcd
abcd
↓ 1行目のaの左にカーソルをおいて実行。
┌────┐
│abcd│
│abcd│
└────┘
(例2)
abcd
0123
ABCD
↓ 1行目のaとbの間から2行目まで(途中でも可)を選択して実行。(タテ罫線)
↓ 1行目のbcdを選択して実行。(ヨコ罫線)
↓ 3行目の0から3までを選択して実行。(ヨコ罫線)
↓ 1行目のaの左にカーソルをおいて実行。(囲み)
↓ 7行目の└の左にカーソルをおいて実行。(調整)
┌─┬───┐
│a│bcd│
│ ├───┤
│0│123│
├─┴───┤
│ABCD │
└─────┘
(例3)
abcd
↓ aとbの間にカーソルを置いて実行。(タテ罫線)
↓ cとdの間にカーソルを置いて実行。(タテ罫線)
↓ bcを選択して実行。(ヨコ罫線)
↓ もう一度bcを選択して実行。(ヨコ罫線)
↓ abcdを罫線の行の間にD&Dする。
↓ 最下行の行頭の空白の左にカーソルをおいて実行。(調整)
┌──┐
a│bc│d
└──┘
備考[編集]
- 表の前後に空行があると仮定しています。ない場合は、選択行の前後35行を表とみなします。
- 調整(罫線置換)の対象は、罫線と全角空白です。
- 半角文字にはある程度まで対応しています。が、微妙にずれます。マクロでは極力削除しないようにしているので微調整は手作業でお願いします。
変更履歴[編集]
- 1.0.3 (2012-12-22)
- 囲みと調整の指示方法を行末から行頭に変更しました
- 行末から選択を開始しているときは、最後の罫線を右に動かすようにしました
- 内部構成を変更しました
- 1.0.2 (2012-12-21)
- 一定の場合、単一行に対して罫線調整を行うようにしました
- 1.0.1 (2012-12-17)
- 一定の場合、連続する全角空白をヨコ罫線に置き換えるようにしました
- 1.0.0 (2012-12-15)
- 初版
ソースコード[編集]
// ruledliner.js(ラクラク罫線.js)
// 最終更新:2012/12/22
var notch = "";
var depth = 35;
var single_spc = " ";
var bouble_spc = " ";
// -- prototype関数 --
// String
// 桁揃えに使う文字。
String.prototype.spcS = single_spc;
String.prototype.spcW = bouble_spc;
// インデックス番号iの文字が半角であるかどうか。
String.prototype.isHan = function(i) {
// Shift_JIS: 0x0 ~ 0x80, 0xa0 , 0xa1 ~ 0xdf , 0xfd ~ 0xff
// Unicode : 0x0 ~ 0x80, 0xf8f0, 0xff61 ~ 0xff9f, 0xf8f1 ~ 0xf8f3
var c = this.charCodeAt(i);
return ((c >= 0x0 && c < 0x81) || (c == 0xf8f0) || (c >= 0xff61 && c < 0xffa0) || (c >= 0xf8f1 && c < 0xf8f4));
};
// 文字列の長さ。半角換算。
String.prototype.blength = function() {
var blen = 0;
for (var i = 0; i < this.length; i++) {
(this.isHan(i)) ? blen += 1: blen += 2;
}
return blen;
};
// インデックス番号の変換(半角→通常)。
String.prototype.bindex2i = function(bi) {
if (bi < 0) {
Alert("bi < 0 in bindex2i !!");
Quit();
}
var n = 0;
for (var i = 0; i < this.length; i++) {
if (!this.isHan(i)) {
n++;
}
if (i + n >= bi) {
return i;
}
}
return bi;
};
// 文字列から指定した位置の文字を抜き出し。半角指定。
String.prototype.bcharAt = function(bi) {
var i = this.bindex2i(bi);
if (bi >= this.blength()) {
i = this.length;
}
return this.charAt(i);
};
// 文字列を分割。半角指定。
String.prototype.bdiv2ary = function(bi) {
var i = this.bindex2i(bi);
return {
front: this.substr(0, i),
tail: this.substr(i, this.length - i)
};
};
// 文字列の繰り返し。
String.prototype.repeat = function(n) {
var str = this;
var s = "";
while (n > 0) {
if (n & 1) {
s += str;
}
n = n >> 1;
str += str;
}
return s;
};
// 文字列を指定桁数まで延長。半角指定。
String.prototype.beven = function(bn) {
switch (arguments.length) {
case 0:
bn = 0;
}
var re = new RegExp(this.spcS + "+$", "ig");
var str = this;
str = str.replace(re, "");
var s = "";
if (bn == 0) {
s = str + this.spcS.repeat(str.blength() % 2);
} else {
bn += bn % 2;
s = str + this.spcS.repeat(bn - str.blength());
}
var re = new RegExp(this.spcS + "{2}", "ig");
s = s.replace(re, this.spcW);
return s;
};
// 最長要素の長さ。半角換算。
Array.prototype.maxbLen = function() {
var blen = 0;
for (var i = 0; i < this.length; i++) {
if (typeof(this[i]) != "string") {
Alert("maxbLen!");
Quit();
}
var s = this[i].blength();
(blen > s) ? blen: blen = s;
}
return blen;
};
// -- 罫線を引くオブジェクト --
var TblRuler = function() {
this.initialize.apply(this, arguments);
};
TblRuler.prototype = {
spcS: single_spc,
spcW: bouble_spc,
action: "none",
tbl: [],
x1: 0,
y1: 0,
x2: 0,
y2: 0,
initialize: function(tblTop, tblBottom, tx, ty, bx, by, str) {
this.tbl = str.split("\n");
this.y1 = ty - tblTop;
this.x1 = this.tbl[this.y1].substr(0, tx - 1).blength();
this.y2 = by - tblTop;
this.x2 = this.tbl[this.y2].substr(0, bx - 1).blength();
this.tx = tx;
this.bx = bx;
},
length: function() {
return this.tbl.length;
},
vline: function() {
this.action = "vline";
var vksen = "│";
// 選択行の事前処理。
var l_ary = [];
var r_ary = [];
for (var i = this.y1; i <= this.y2; i++) {
var ft = this.tbl[i].bdiv2ary(this.x1);
l_ary.push(ft.front);
r_ary.push(ft.tail);
}
for (var i = 0; i < r_ary.length; i++) {
var r_aryi = r_ary[i].split(vksen);
r_aryi[0] = r_aryi[0].beven();
r_ary[i] = r_aryi.join(vksen);
}
var lenL = l_ary.maxbLen();
var lenR = r_ary.maxbLen();
for (var i = 0; i < this.tbl.length; i++) {
if (i >= this.y1 && i <= this.y2) {
this.tbl[i] = l_ary[i - this.y1].beven(lenL) + vksen + r_ary[i - this.y1];
}
}
},
vline_at_end: function() {
this.action = "vline_at_end";
for (var i = this.y1; i <= this.y2; i++) {
var work = this.tbl[i].split("");
var rend = work.pop();
if (/[─│┌┐└┘├┤┬┴┼]/.test(rend)) {
work.push(this.spcW + rend);
} else {
work.push(rend + this.spcW);
}
this.tbl[i] = work.join("");
}
},
hline: function() {
this.action = "hline";
var hksen = "─";
var s = this.tbl[this.y1].slice(tx - 1, bx - 1);
var regK = new RegExp("[─│┌┐└┘├┤┬┴┼]", "i");
var reg = new RegExp("[^" + this.spcW + "]+", "i");
var mid = s.slice(1, s.length - 1);
if (s.length >= 3 && regK.test(s.charAt(0)) && regK.test(s.charAt(s.length - 1)) && !reg.test(mid)) {
var reg2 = new RegExp(this.spcW, "ig");
var c = this.tbl[this.y1].split("");
s = s.replace(reg2, hksen);
c.splice(tx - 1, bx - tx, s);
this.tbl[this.y1] = c.join("");
} else {
var xmax = 0;
if (this.y1 >= this.tbl.length - 1) {
xmax = this.tbl[this.y1].blength();
} else {
xmax = Math.max(this.tbl[this.y1].blength(), this.tbl[this.y1 + 1].blength());
}
var s1 = this.spcW.repeat((this.x1 + 1) / 2);
var s2 = hksen.repeat((this.x2 - this.x1 + 1) / 2);
var s3 = this.spcW.repeat((xmax - s1.blength() - s2.blength() + 1) / 2);
var s = s1 + s2 + s3;
this.tbl.splice(this.y1 + 1, 0, s);
}
},
makeFrame: function() {
this.action = "makeFrame";
var re = new RegExp("[" + this.spcS + this.spcW + "]+$", "i");
for (var i = 0; i < this.tbl.length; i++) {
this.tbl[i] = this.tbl[i].replace(re, "");
}
var len = this.tbl.maxbLen() + this.tbl.maxbLen() % 2;
for (var i = 0; i < this.tbl.length; i++) {
this.tbl[i] = "│" + this.tbl[i].beven(len) + "│";
}
this.tbl.unshift("┌" + "─".repeat(len / 2) + "┐");
this.tbl.push("└" + "─".repeat(len / 2) + "┘");
},
linkChk: function(bx, y) {
var s = 0;
// 上は?
if (y >= 1) {
var c = this.tbl[y - 1].bcharAt(bx);
if (/[┌┐│┬├┼┤]/.test(c)) {
s += 8;
}
}
// 下は?
if (y < this.tbl.length - 1) {
var c = this.tbl[y + 1].bcharAt(bx);
if (/[└┘│┴├┼┤]/.test(c)) {
s += 4;
}
}
// 左は?
if (this.tbl[y].bindex2i(bx) >= 1) {
var c = this.tbl[y].charAt(this.tbl[y].bindex2i(bx) - 1);
if (/[┌└─┬┼├┴]/.test(c)) {
s += 2;
}
}
// 右は?
if (this.tbl[y].bindex2i(bx) < this.tbl[y].length - 1) {
var c = this.tbl[y].charAt(this.tbl[y].bindex2i(bx) + 1);
if (/[┐┘─┬┼┤┴]/.test(c)) {
s += 1;
}
}
return s;
},
code2char: function(code) {
switch (code) {
case 0:
return "";
case 1:
return "";
case 2:
return "";
case 3:
return "─"; // " LR"
case 4:
return "";
case 5:
return "┌"; // " D R"
case 6:
return "┐"; // " DL"
case 7:
return "┬"; // " DLR"
case 8:
return "";
case 9:
return "└"; // "U R"
case 10:
return "┘"; // "U L "
case 11:
return "┴"; // "U LR"
case 12:
return "│"; // "UD "
case 13:
return "├"; // "UD R"
case 14:
return "┤"; // "UDL "
case 15:
return "┼"; // "UDLR"
default:
return "";
}
},
adjust: function() {
this.action = "adjust";
var work = this.tbl.slice(0);
var re = new RegExp(this.spcS + "{2}", "ig");
for (var y = 0; y < this.tbl.length; y++) {
var line = this.tbl[y].replace(re, this.spcW);
var ex = "";
var bi = 0;
while (bi < line.blength()) {
var ks2 = this.code2char(this.linkChk(bi, y));
var s = line.bcharAt(bi);
if (/[─│┌┐└┘├┤┬┴┼ ]/.test(s) && ks2.length != 0) {
ex += ks2;
} else {
ex += s;
}
if (s.isHan()) {
bi += 1;
} else {
bi += 2;
}
}
work[y] = ex;
}
this.tbl = work.slice(0);
var re = new RegExp("[" + this.spcS + this.spcW + "]+$", "i");
for (var i = 0; i < this.tbl.length; i++) {
this.tbl[i] = this.tbl[i].replace(re, "");
}
},
adjust_line: function(y) {
this.action = "adjust_line";
var re = new RegExp(this.spcS + "{2}", "ig");
var line = this.tbl[y].replace(re, this.spcW);
var ex = "";
var bi = 0;
while (bi < line.blength()) {
var ks2 = this.code2char(this.linkChk(bi, y));
var s = line.bcharAt(bi);
if (/[─│┌┐└┘├┤┬┴┼ ]/.test(s) && ks2.length != 0) {
ex += ks2;
} else {
ex += s;
}
if (s.isHan()) {
bi += 1;
} else {
bi += 2;
}
}
this.tbl[y] = ex;
}
};
function ruler_action() {
if (tx == 1 && tx == bx && by == tblTop) {
return "makeframe";
} else if (tx == 1 && tx == bx && ty == tblBottom) {
return "adjust";
} else if (tx == 1 && by == ty && ax == 1) {
return "adjust_line";
} else if (tx == document.GetLine(ty).length + 1) {
return "vline_at_end";
} else if (tx != bx && ty == by) {
return "hline";
}
return "vline";
}
// --------------------
// 選択範囲の記録と伸張。
var sel = Editor.ActiveDocument.Selection;
var tx = sel.GetTopPointX(mePosLogical);
var ty = sel.GetTopPointY(mePosLogical);
var bx = sel.GetBottomPointX(mePosLogical);
var by = sel.GetBottomPointY(mePosLogical);
var ax = sel.GetActivePointX(mePosLogical);
var ay = sel.GetActivePointY(mePosLogical);
sel.SetActivePoint(mePosLogical, 1, ty, false);
sel.SetActivePoint(mePosLogical, 1, by, true);
if ((bx == 1) && (ty != by)) {
sel.CharLeft(true, 1);
bx = sel.GetBottomPointX(mePosLogical);
by--;
} else {
sel.EndOfLine(true, mePosLogical);
}
var tblTop = ty;
var tblBottom = by;
for (var i = 0; i <= depth; i++) {
var line = document.GetLine(ty - i);
if (line.charAt(0) === (notch) || ty - i <= 0) {
break;
}
tblTop = ty - i;
}
for (var i = 0; i <= depth; i++) {
var line = document.GetLine(by + i);
if (line.charAt(0) === (notch) || by + i >= document.GetLines()) {
break;
}
tblBottom = by + i;
}
if (ty < tblTop) {
tblTop = ty;
}
if (by > tblBottom) {
tblBottom = by;
}
sel.SetActivePoint(mePosLogical, 1, tblTop, false);
sel.SetActivePoint(mePosLogical, 1, tblBottom, true);
sel.EndOfLine(true, mePosLogical);
var tblruler = new TblRuler(tblTop, tblBottom, tx, ty, bx, by, document.selection.text);
switch (ruler_action()) {
case "makeframe":
tblruler.makeFrame();
break;
case "adjust":
tblruler.adjust();
break;
case "adjust_line":
tblruler.adjust_line(ty - tblTop);
break;
case "hline":
tblruler.hline();
break;
case "vline_at_end":
tblruler.vline_at_end();
break;
default:
tblruler.vline();
}
sel.SetActivePoint(mePosLogical, 1, tblTop, false);
sel.SetActivePoint(mePosLogical, 1, tblBottom, true);
sel.EndOfLine(true, mePosLogical);
sel.Text = tblruler.tbl.join("\r\n");
sel.SetActivePoint(mePosLogical, tx, ty, false);
おまけ[編集]
- 以下のマクロを登録して貼り付け時に使うと、入れ替えがラクになります。
// PasteWithCopy.js
var clp = ClipboardData.GetData();
ClipboardData.SetData(document.Selection.Text);
document.Selection.Text = clp;
スポンサーリンク