「カッコをはずす」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
Sukemaru (トーク | 投稿記録)
MSY-07 (トーク | 投稿記録)
空行と改行の除去
 
(2人の利用者による、間の19版が非表示)
1行目: 1行目:
選択範囲の "最初の1文字" と "最後の1文字" が「'''対になるカッコ'''」のとき、カッコ囲いをはずします。<br> それにくわえて
選択範囲の "最初の1文字" と "最後の1文字" が「'''対になるカッコ'''」のとき、カッコ囲いをはずします。<br> それにくわえて
*「カッコをはずす」マクロでは、選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときにも、カッコ囲いをはずします。
*「カッコをはずす」マクロでは、選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときにも、カッコ囲いをはずします。  
*「カッコを削除/追加」マクロでは、選択範囲の先頭と末尾が「対になるカッコ」でなかったときは、「さいごに削除(または追加)したカッコ」と同種のカッコで選択範囲を囲います。
*「カッコを追加/削除」マクロは、「さいごに削除したカッコ」と同種のカッコで選択範囲を囲います。<br> 任意のタイミングで「さいごに削除したカッコ」を記憶・更新することができるので、ソースコードや散文の校正のさいに使うと便利です。
*「カッコを追加/削除」マクロは、両者の機能を統合したものです。


削除できるカッコの種類はソースコード内で定義したもののみ(開き/閉じカッコはそれぞれ「1文字」ずつのペアで)。
削除できるカッコの種類は、ソースコード内で定義したもののみとなります。


: '''カッコの種類'''
:'''カッコの種類'''(開き/閉じ それぞれ「1文字」ずつ)
:* 各種のカッコ(半角/全角/縦書き)
:* 各種のカッコ(半角/全角/縦書き)のペア
::  ( ) 「 」 < > [ ] { } ⦅ ⦆ <br> ( ) 「 」 『 』 < > [ ] { } 【 】 〖 〗 ⦅ ⦆ 〚 〛 〔 〕 〘 〙 〈 〉 《 》 <br> ﹁﹂ ﹃﹄ ︵︶ ︿﹀ ︽︾ ︹︺ ︷︸ ︻︼ ︗︘
::  ( ) 「 」 < > [ ] { } ⦅ ⦆ <br> ( ) 「 」 『 』 < > [ ] { } 【 】 〖 〗 ⦅ ⦆ 〚 〛 〔 〕 〘 〙 〈 〉 《 》 <br> ﹁﹂ ﹃﹄ ︵︶ ︿﹀ ︽︾ ︹︺ ︷︸ ︻︼ ︗︘
:* 各種の引用符(半角/全角)
:* 各種の引用符(半角/全角)のペア
:: " "  ' '  ” ”  ’ ’  〝 〞  〝 〟  ‘ ’  “ ”
:: " "  ' '  ” ”  ’ ’  〝 〞  〝 〟  ‘ ’  “ ”
:* ーダーシー、〜波ダーシ〜、~全角チルダ~
:* ーダーシー、〜波ダーシ〜、~全角チルダ~
:* '''␣半角空白␣'''も含んでいるので、選択単語の左右の半角空白も削除できます。
:* '''␣半角空白␣'''、全角空白 のペア
:* 各種記号のペア
:: + + - - * * / / # # = = % % : : : : @ @ @ @ ※ ※ <br> ● ● ■ ■ ◆ ◆ ▼ ▼ ▲ ▲ ☆ ☆ ★ ★ † † <br> ← → → ← ↑ ↓ ↓ ↑ ← ← → → ↑ ↑ ↓ ↓
: など...


: ※ソースコード内に。各種の記号や諸外国後で使用される引用符などのペアを用意してあります。任意で追加してご利用下さい。
* 設定項目内の定義要配列 <syntaxhighlight lang="javascript" inline>var brackets2 = [ ... ];</syntaxhighlight> をカスタマイズすると、HTML タグなど「複数文字ずつのペア」も登録することができます。
 
: ※ <syntaxhighlight lang="javascript" inline>"===", "==="</syntaxhighlight> と <syntaxhighlight lang="javascript" inline>"==", "=="</syntaxhighlight> のように同一文字列をふくむペア(半角空白 あり/なし の差分なども)を登録する場合は、文字列の長さが大きいものが先になるようにしてください。
カッコを追加する機能は「さいごに削除したカッコ」を記憶しておくことと更新することができるので、ソースコードや散文の校正のさいに使うと便利です。


''c.f. ''「[[カッコで囲う]]」マクロ: ポップアップメニューから任意のカッコを追加する<br>
   「[[カッコで囲う#引用符を追加/削除|引用符を追加/削除]]」マクロ: 特定のカッコまたは引用符の追加/削除トグル


----
----
::'''ダウンロード:''' [[ファイル:カッコを削除/追加.zip]](アイコン入り) 2019/03/19 更新
::'''ダウンロード''' >> 「[[ファイル:カッコを削除/追加.zip]]」(アイコン入り)
----<br>
::; [[#変更履歴|最終更新]]:2020-06-28
:* マルチカーソル/複数選択範囲に対応
:* 「カッコを削除/追加」マクロを削除
----
   
   
= カッコをはずす =
== カッコをはずす ==
 
選択範囲の "最初の1文字" と "最後の1文字" が「'''対になるカッコ'''」のとき、または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときに、カッコ囲いをはずします。
選択範囲の "最初の1文字" と "最後の1文字" が「'''対になるカッコ'''」のとき、または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときに、カッコ囲いをはずします。


* 1回の実行につき1組のカッコ囲いをはずします(※内側の両端が優先。半角空白のペアも除去対象)。
:: 例. 以下の行で <span style="background:#bfdfff;">'''[ "hoge" ]'''</span> を範囲選択して連続で実行した場合、次のように作用します。


* 1回の実行につき1組のカッコ囲いをはずします(※内側の両端が優先)。
( <span style="background:#bfdfff;">[ "hoge" ]</span> ) // 元の文字列(下線部が選択範囲)
:: 例. 以下の行で <u>'''[ "hoge" ]'''</u> を範囲選択して連続で実行した場合、次のように作用します。
 
( <u>[ "hoge" ]</u> ) // 元の文字列(下線部が選択範囲)
   
   
  ( <u> "hoge" </u> ) // 1回目 実行後: ''[  と  ] を削除しました。''
  ( <span style="background:#bfdfff;"> "hoge" </span> ) // 1回目 実行後: ''[  と  ] を削除しました。''
  ( <u>"hoge"</u> ) // 2回目 実行後: ''␣ と ␣ を削除しました。''
  ( <span style="background:#bfdfff;">"hoge"</span> ) // 2回目 実行後: ''␣ と ␣ を削除しました。''
  ( <u>hoge</u> ) // 3回目 実行後: ''"  と  " を削除しました。''
  ( <span style="background:#bfdfff;">hoge</span> ) // 3回目 実行後: ''"  と  " を削除しました。''
  (<u>hoge</u>) // 4回目 実行後: ''␣ と ␣ を削除しました。'' ※選択範囲の外側
  (<span style="background:#bfdfff;">hoge</span>) // 4回目 実行後: ''␣ と ␣ を削除しました。'' ※選択範囲の外側
  <u>hoge</u> // 5回目 実行後: ''(  と  ) を削除しました。'' ※選択範囲の外側
  <span style="background:#bfdfff;">hoge</span> // 5回目 実行後: ''(  と  ) を削除しました。'' ※選択範囲の外側
:: <span style="background:#bfdfff;">'''( [ "hoge" ] )'''</span> 全体を範囲選択して連続で実行した場合は選択範囲内の外側から、<br> '''( [ "<span style="background:#bfdfff;">hoge</span>" ] )''' の <b style="background:#bfdfff;">hoge</b> だけを範囲選択して連続で実行した場合は選択範囲外の内側から <br> 順にカッコ囲いを解除します。


* 選択範囲(複数行)の各行の行頭/行末からカッコを除去したい場合は、「[[カッコで囲う]](ポップアップメニュー)」マクロや「[[テキスト整形]]」マクロの削除系コマンドをご利用ください。
* 選択範囲(複数行)の各行の行頭/行末からカッコを除去したい場合は、「[[カッコで囲う]](ポップアップメニュー)」マクロや「[[テキスト整形]]」マクロの削除系コマンドをご利用ください。


=== ソースコード ===
※ Mery Ver 3.0.1 以降では「マルチカーソル/複数選択範囲」にも対応します。


== ソースコード ==
<syntaxhighlight lang="javascript" style="height:80em; overflow:auto;">
 
<source lang="javascript">
#title="カッコをはずす"
#title="カッコをはずす"
#tooltip="対になるカッコを除去する"
#tooltip="対になるカッコを除去する"
// #icon="brackets(delete)[1].ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",286


/**
/**
  * ------------------------------------------------------------
  * ------------------------------------------------------------
  * カッコをはずす (2019/03/14 - 2019/03/18, sukemaru)
  * カッコをはずす
* sukemaru, 2019-03-14 - 2020-06-28
  * ------------------------------------------------------------
  * ------------------------------------------------------------
  * 選択範囲の最初の1文字と最後の1文字が「対になるカッコ」のとき、
  * 選択範囲の最初の1文字と最後の1文字が「対になるカッコ」のとき、
  * または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときに、
  * または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときに、
  * カッコ囲いをはずします。
  * カッコ囲いをはずします。
* ※「外側」オプションが有効な場合でも、
*  選択範囲"内側"の先頭/末尾のカッコの削除が優先されます。
  */
  */


// ▼「対になるカッコ」の種類 (始)+(終) を列挙する ▼
// ※ 開き/閉じカッコはそれぞれ「1文字」でないとダメ


var brackets = "()「」<>[]{}\"\"''()「」『』<>[]{}【】〖〗﹁﹂﹃﹄︵︶︿﹀︽︾︹︺︷︸︻︼︗︘⦅⦆⦅⦆〚〛〔〕〘〙〈〉《》””’’〝〞〝〟‘’“”――~~〜〜  ";
// ---------- ▼ 設定項目 ▼ ---------- //
 
// ■ 選択範囲の『外側』(前と後ろ) の各1文字がカッコのときも除去する? ■
// (※ 選択範囲の前後を1文字ずつ拡張してカッコを除去する)
var outerEnable = true; // true:する / false:しない
 
 
// ▼「対になるカッコ」の種類 (始)と(終) のペアを列挙する ▼
// ※ brackets に列挙する開き/閉じカッコのペアはそれぞれ「1文字」ずつでないとダメ
 
var brackets = "()「」<>[]{}\"\"''()「」『』<>[]{}【】〖〗﹁﹂﹃﹄︵︶︿﹀︽︾︹︺︷︸︻︼︗︘⦅⦆⦅⦆〚〛〔〕〘〙〈〉《》””’’〝〞〝〟‘’“”――~~〜〜    ";
 
brackets += "++--**\/\/##==%%::::@@@@※※○○●●□□■■◇◇◆◆▽▽▼▼△△▲▲☆☆★★††||←→→←↑↓↓↑←←→→↑↑↓↓……¿?¡!‚‘‚’„“„”“„‘‚‹››‹«»»«——‐‐--␣␣__≪≫";


// 削除対象に ▼各種記号のペア▼ を追加する場合は、コメントアウトを解除する
// brackets += "++--**//##==%%::::@@@@※※○○●●□□■■◇◇◆◆▽▽▼▼△△▲▲☆☆★★††||←→→←↑↓↓↑←←→→↑↑↓↓……¿?¡!‚‘‚’„“„”“„‘‚‹››‹«»»«——‐‐--␣␣__";


// ▼ HTML タグなど複数文字の要素での (始)と(終) のペアを列挙 ▼
var brackets2 = [
  "<i>" , "</i>" , "<u>" , "</u>" , "<s>" , "</s>" ,
  "<b>" , "</b>" , "<q>" , "</q>" ,
  "</" , ">" , "<" , "/>" ,
  "<li>" , "</li>" , "<h>" , "</h>" ,
  "<span>" , "</span>" , "<div>" , "</div>" ,
  "<pre>" , "</pre>" , "<code>" , "</code>" ,
  "===== " , " =====" , "=====" , "=====" , "==== " , " ====", "====" , "====",
  "=== " , " ===" , "===" , "===" , "== " , " ==" , "==" , "==" , "= " , " =",
  "'''''" , "'''''" , "'''" , "'''" , "''" , "''",
  "――" , "――" ,
  "/** \n" , "\n */" , "/** \n" , "\n*/" , "/**\n" , "\n */" , "/**\n" , "\n*/" ,
  "/* \n" , "\n */" , "/* \n" , "\n*/" , "/*\n" , "\n */" , "/*\n" , "\n*/" ,
  "/** " , " */" , "/* " , " */" , "/*" , "*/" ,
  "( ", " )" , " (", ") " , ' "' , '" ' ,
  "<!-- " , " -->" , "<!--" , "-->"
];


// ■ 選択範囲の『外側』(前と後ろ) の各1文字がカッコのときも除去する? ■
// ---------- ▲ 設定項目 ▲ ---------- //
// (※ 選択範囲の前後を1文字ずつ拡張してカッコを除去する)
var removeOuterBracketsEnable = true; // true:する / false:しない


// brackets2 が先、brackets が後
brackets = brackets2.concat( brackets.split( "" ) );


var d = document;
var d = editor.ActiveDocument;
if ( d.ReadOnly ) {
if ( d.ReadOnly ) {
   Status = " ドキュメントは書き換え禁止です。";
   Status = " ドキュメントは書き換え禁止です。";
  Quit();
}
}
else {
  var s = d.selection;
  var sx = ScrollX,  sy = ScrollY;


var s = document.selection;
  // マルチカーソル/複数選択に対応
var st = s.Text; // 選択範囲の文字列
  var arg = [ outerEnable, brackets ];
var act = s.GetActivePos();
  // 選択範囲が1つで矩形選択ではないとき
var anc = s.GetAnchorPos();
  if ( ! s.Mode || s.Mode === 1 ) {
var tp = ( anc < act ) ? anc : act; // 選択範囲の先頭位置
    DeleteBrackets_Main( arg );
var bp = ( anc < act ) ? act : anc; // 選択範囲の末尾位置
  }
var del = false;
  // 矩形選択または複数選択のとき
var o, c;
  else {
    var dt = d.Text;
    BeginUndoGroup();
    AddUndo();
    MultiFunction( DeleteBrackets_Main, arg );
    EndUndoGroup();
    if ( d.Text === dt ) { d.Undo(); }
  }


// 選択範囲内の最初と最後の各1文字がカッコのとき
   ScrollX = sx; ScrollY = sy;
for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
   o = brackets[ i ]; // 開きカッコ
  c = brackets[ i + 1 ] // 閉じカッコ
  if ( st.length >= o.length + c.length && i % 2 == 0
      && st.slice( 0, o.length ) == o
      && st.slice( - c.length ) == c ) {
    s.Text = st.slice( o.length, - c.length );// 先頭と末尾の各1文字ずつを削除
    s.SetAnchorPos( tp ); // 選択範囲を復帰する
    del = true;
    break;
  }
}
}


// 選択範囲の外側 (前と後) の各1文字がカッコのとき
 
if ( removeOuterBracketsEnable && ! del ) {
/**
* 関数 DeleteBrackets_Main()
* 「カッコをはずす」マクロ
*/
function DeleteBrackets_Main( arg ) {
  var outerEnable = arg[0];
  var brackets    = arg[1];
 
  var d = editor.ActiveDocument;
  var s = d.selection;
  var st = s.Text;
  var act = s.GetActivePos();
  var anc = s.GetAnchorPos();
  var tp = ( anc < act ) ? anc : act;
  var bp = ( anc < act ) ? act : anc;
  var $del = false;
  var o, c;
 
  // 選択範囲内の最初と最後の各1文字がカッコのとき
   for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
   for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
     o = brackets[ i ]; // 開きカッコ
     o = brackets[i];           // 開きカッコ
     c = brackets[ i + 1 ] // 閉じカッコ
     c = brackets[ i + 1 ]       // 閉じカッコ
     if ( i % 2 == 0
     if ( st.length >= o.length + c.length
        && d.Text.slice( tp - o.length, tp ) == o
    && i % 2 === 0
        && d.Text.slice( bp, bp + c.length ) == c ) {
    && st.slice( 0, o.length ) === o
       s.SetAnchorPos( tp - o.length ); // 選択範囲の先頭を1文字拡張
    && st.slice( - c.length ) === c ) {
      s.SetActivePos( bp + c.length, true ); // 選択範囲の末尾を1文字拡張
       // 先頭と末尾の各1文字ずつを削除し、選択範囲を復帰する
      st = s.Text;
       s.Text = st.slice( o.length, - c.length );
       s.Text = st.slice( o.length, - c.length );// 先頭と末尾の各1文字ずつを削除
       s.SetAnchorPos( tp );
       s.SetAnchorPos( tp - o.length ); // 選択範囲を復帰する
       $del = true;
       del = true;
       break;
       break;
     }
     }
   }
   }
  // 選択範囲の外側 (前と後) がカッコのとき
  if ( outerEnable && ! $del ) {
    for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
      o = brackets[i];          // 開きカッコ
      c = brackets[ i + 1 ]    // 閉じカッコ
      if ( i % 2 === 0
      && d.Text.slice( tp - o.length, tp ) === o
      && d.Text.slice( bp, bp + c.length ) === c ) {
        // 選択範囲の先頭/末尾をカッコの文字数ぶんだけ拡張
        s.SetAnchorPos( tp - o.length );
        s.SetActivePos( bp + c.length, true );
        st = s.Text;
        // 先頭と末尾のカッコを削除し、選択範囲を復帰する
        s.Text = st.slice( o.length, - c.length );
        s.SetAnchorPos( tp - o.length );
        $del = true;
        break;
      }
    }
  }
  // 終了ステータス
  Status = ( $del )
        ? " " + ( o == " " ? "␣" : o ) + "  と  "
          + ( c == " " ? "␣" : c ) + "  を削除しました。"
        : " カッコがありません。";
}
}


// 終了ステータス
/**
if ( del ) {
* 関数 MultiFunction( Fn, arg1 )
   Status = " " + ( o == " " ? "␣" : o ) + "  と  "
* マルチカーソル(複数選択範囲)に対応させる
        + ( c == " " ? "␣" : c ) + "  を削除しました。";
* 第1引数: Function; 選択範囲ごとに適用する処理の関数
* 第2引数: Function に渡す引数をまとめた配列
*/
function MultiFunction( Fn, arg ) {
   var d = editor.ActiveDocument;
  var s = d.selection;
 
  // 矩形選択範囲は行に分ける
  s.Mode = meModeMulti;
 
  // 選択範囲の座標を取得
  var sCount = s.Count;
  var Sel = [];
  for ( var i = 0; i < sCount; i ++ ) {
    Sel[i] = {
      act: s.GetActivePos( i ),
      anc: s.GetAnchorPos( i )
    };
  }
 
  // 各選択範囲を処理;
  for ( var i = 0, diff = 0, dl; i < sCount; i ++ ) {
    dl = d.TextLength;
    s.SetActivePos( Sel[i].act + diff );
    s.SetAnchorPos( Sel[i].anc + diff );
 
    Fn( arg ); // DeleteBrackets_Main() 関数でカッコを削除
 
    // Fn() の残した選択範囲(またはキャレット位置)を回収
    Sel[i].act = s.GetActivePos();
    Sel[i].anc = s.GetAnchorPos();
    diff += d.TextLength - dl; // 文字数の増減量(累積)
  }
 
  // マルチカーソル(複数選択範囲)を復帰
  for ( var i = 0; i < sCount; i ++ ) {
    s.AddPos( Sel[i].anc, Sel[i].act );
  }
}
}
else {
</syntaxhighlight>
  Status = " カッコがありません。"
}
</source>


 
<!-- 2020-06-28:「カッコを削除/追加」マクロをコメントアウト
= カッコを削除/追加 =
== カッコを削除/追加 ==


選択範囲の先頭と末尾が「対になるカッコ」のときは、カッコ囲いをはずします。<br>
選択範囲の先頭と末尾が「対になるカッコ」のときは、カッコ囲いをはずします。<br>
141行目: 248行目:


<div id="注1" class="warningbox">
<div id="注1" class="warningbox">
: あらかじめ [[includeライブラリ]] を Macros フォルダにインストールしてください。
: あらかじめ [[includeライブラリ]] を Macros フォルダに配置してください。
:: 外部ファイルの保存場所は  Mery\Macros\MacroSettings\<カッコを削除/追加>.json <br> または  %AppData%\Mery\MacroSettings\<カッコを削除/追加>.json  です。 <br>( <u><カッコを削除/追加></u> の部分はこのマクロのファイル名と同一になります )
:: 外部ファイルの保存場所は  Mery\Macros\MacroSettings\<カッコを削除/追加>.json <br> または  %AppData%\Mery\MacroSettings\<カッコを削除/追加>.json  です。 <br>( <u><カッコを削除/追加></u> の部分はこのマクロのファイル名と同一になります )
</div>
</div>
153行目: 260行目:
* おなじ選択範囲のまま連続で実行すると、削除 ⇔ 追加 の繰り返しになります。
* おなじ選択範囲のまま連続で実行すると、削除 ⇔ 追加 の繰り返しになります。


 
=== ソースコード ===
== ソースコード ==
<syntaxhighlight lang="javascript">
 
<source lang="javascript">
#title="カッコを削除/追加"
#title="カッコを削除/追加"
#tooltip="対になるカッコを削除/追加する"
#tooltip="対になるカッコを削除/追加する"
163行目: 268行目:
/**
/**
  * ------------------------------------------------------------
  * ------------------------------------------------------------
  * カッコを削除/追加 (2019/03/18 - 2019/03/19, sukemaru)  
  * カッコを削除/追加 (2019-03-18 - 2019-03-19, sukemaru)  
  * ------------------------------------------------------------
  * ------------------------------------------------------------
  * 選択範囲の先頭と末尾が「対になるカッコ」のときは、カッコ囲いをはずします。
  * 選択範囲の先頭と末尾が「対になるカッコ」のときは、カッコ囲いをはずします。
188行目: 293行目:
if ( d.ReadOnly ) {
if ( d.ReadOnly ) {
   Status = " ドキュメントは書き換え禁止です。";
   Status = " ドキュメントは書き換え禁止です。";
  Quit();
}
}


var s = document.selection;
else {
var st = s.Text; // 選択範囲の文字列
  var s = document.selection;
var act = s.GetActivePos();
  var st = s.Text;
var anc = s.GetAnchorPos();
  var act = s.GetActivePos();
var tp = ( anc < act ) ? anc : act; // 選択範囲の先頭位置
  var anc = s.GetAnchorPos();
var del = false;
  var tp = ( anc < act ) ? anc : act;
var o, c;
  // var bp = ( anc < act ) ? act : anc;
  var del = false;
  var o, c;


// ループ処理で「対になるカッコ」と一致するかチェック
  // ループ処理で「対になるカッコ」と一致するかチェック
for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
  for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
  o = brackets[ i ]; // 開きカッコ
    o = brackets[ i ];
  c = brackets[ i + 1 ] // 閉じカッコ
    c = brackets[ i + 1 ];


  // 選択範囲内の先頭と末尾が「対になるカッコ」のとき
    // 選択範囲内の先頭と末尾が「対になるカッコ」のとき
  if ( st.length >= o.length + c.length && i % 2 == 0
    if ( st.length >= o.length + c.length && i % 2 == 0
      && st.slice( 0, o.length ) == o
        && st.slice( 0, o.length ) == o
      && st.slice( - c.length ) == c ) {
        && st.slice( - c.length ) == c ) {
    s.Text = st.slice( o.length, - c.length ); // 先頭と末尾のカッコを削除
      s.Text = st.slice( o.length, - c.length );
    s.SetAnchorPos( tp ); // 選択範囲を復帰する
      s.SetAnchorPos( tp );
    del = true;
      del = true;


    if ( o != setting.openBracket || c != setting.closeBracket ) {
      if ( o != setting.openBracket || c != setting.closeBracket ) {
      setting.openBracket = o;
        setting.openBracket = o;
      setting.closeBracket = c;
        setting.closeBracket = c;
      IO.Serialize( setting ); // ヒットしたカッコを JSON ファイルに保存する
        IO.Serialize( setting );
      }
      break;
     }
     }
    break;
   }
   }
}


// 選択範囲内の先頭と末尾が「対になるカッコ」ではなかったとき
  // 選択範囲内の先頭と末尾が「対になるカッコ」ではなかったとき
if ( ! del ) {
  if ( ! del ) {
  // 「最後に使用したカッコ」
    // 「最後に使用したカッコ」
  o = setting.openBracket ? setting.openBracket : "(";
    o = setting.openBracket ? setting.openBracket : "(";
  c = setting.closeBracket ? setting.closeBracket : ")";
    c = setting.closeBracket ? setting.closeBracket : ")";
  s.Text = o + st + c; // 先頭と末尾にカッコを追加
    s.Text = o + st + c;
  s.SetAnchorPos( tp ); // 選択範囲を復帰する
    s.SetAnchorPos( tp );
}
  }


// 終了ステータス
  // 終了ステータス
if ( del ) {
  if ( del ) {
  Status = " " + o.replace( /[ ]+/g , "␣" ) + "  と  "
    Status = " " + o.replace( /[ ]+/g , "␣" ) + "  と  "
        + c.replace( /[ ]+/g , "␣" ) + "  を削除しました。";
          + c.replace( /[ ]+/g , "␣" ) + "  を削除しました。";
}
  }
else {
  else {
  Status = " " +  o.replace( /[ ]+/g , "␣" )  + " カッコ "
    Status = " " +  o.replace( /[ ]+/g , "␣" )  + " カッコ "
        + c.replace( /[ ]+/g , "␣" ) + "  で囲いました。";
          + c.replace( /[ ]+/g , "␣" ) + "  で囲いました。";
  }
}
}
</source>
</syntaxhighlight>
 
-->
 
== カッコを追加/削除 ==
= カッコを追加/削除 =
マクロライブラリで公開・配布されている pizz 氏作成の「[[GetKeyState.exe(キー状態取得実行ファイル)|GetKeyState]]」を利用して、「'''[[#カッコをはずす|カッコをはずす]]'''」マクロに「'''カッコを追加'''」の機能を加えたマクロです。


マクロ「[[Eclipse風コメントアウト(改)]]」のページで配布されている pizz 氏作成の "GetKeyState" も利用して、「[[#カッコをはずす|カッコをはずす]]」マクロと「[[#カッコを削除/追加|カッコを削除/追加]]」マクロの機能を統合してあります。
* マクロ実行時に '''Ctrl キー''' が押されているときは、選択範囲を「さいごに削除したカッコ」で囲います。
 
* マクロ実行時に Ctrl キーが押されているときは、選択範囲を「さいごに 削除/追加 したカッコ」で囲います(→ 詳細は「[[#カッコを削除/追加|カッコを削除/追加]]」マクロの項を参照)。


* マクロ実行時に Ctrl キーが押されていないとき、選択範囲の最初の1文字と最後の1文字が「対になるカッコ」の場合か、または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」の場合には、カッコ囲いをはずします(→ 詳細は「[[#カッコをはずす|カッコをはずす]]」マクロの項を参照)。
* マクロ実行時に Ctrl キーが押されていないとき、選択範囲の最初の1文字と最後の1文字が「対になるカッコ」の場合か、または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」の場合には、カッコ囲いをはずします(→ 詳細は「[[#カッコをはずす|カッコをはずす]]」マクロの項を参照)。


※ 設定項目 <syntaxhighlight lang="javascript" inline>var ctrlToDel = true;</syntaxhighlight> にすると、Ctrl キーが押されているときは「カッコを削除」、押されていないときは「カッコを追加」になります。


<div id="注2" class="warningbox">
<div id="注2" class="warningbox">
* '''外部実行ファイル "GetKeyState.exe" を利用して Ctrl キー押し下げ判定をします。'''
* '''外部実行ファイル [[GetKeyState.exe(キー状態取得実行ファイル)|GetKeyState.exe]] を利用して Ctrl キーと Alt キーの押し下げ状態を取得します。'''
: あらかじめ 「[[Eclipse風コメントアウト(改)]]」のページから "GetKeyState.zip" をダウンロードして、書庫内の "GetKeyState.exe" を Macros フォルダに配置してください。
: あらかじめ "GetKeyState.zip" をダウンロードして、書庫内の「GetKeyState.exe」を Macros フォルダに配置してください。


* '''[[includeライブラリ]] を利用して「さいごに 追加/削除 したカッコ」を外部ファイルに保存します。'''
* '''[[includeライブラリ]] を利用して「さいごに 追加/削除 したカッコ」を外部ファイルに保存します。'''
: あらかじめ [[includeライブラリ]] を Macros フォルダに配置してください。
: あらかじめ「includeライブラリ」を Macros フォルダに配置してください。
:: 外部ファイルの保存場所は  Mery\Macros\MacroSettings\<カッコを追加/削除>.json <br> または  %AppData%\Mery\MacroSettings\<カッコを追加/削除>.json  です。 <br>( <u><カッコを追加/削除></u> の部分はこのマクロのファイル名と同一になります )
:: 外部ファイルの保存場所は  Mery\Macros\MacroSettings\<カッコを追加/削除>.json <br> または  %AppData%\Mery\MacroSettings\<カッコを追加/削除>.json  です。 <br>(<code><カッコを追加/削除></code> の部分はこのマクロのファイル名と同一になります)
※ Mery Ver 3.0.0 以降では「includeライブラリ」なしでも動作します。
</div>
</div>


* Ctrl キーの押し下げ状態でカッコの「追加/削除」の機能を切り替えるので、'''このマクロに[[ヘルプ:ツール#オプション|ショートカットキー]]を割り当てる場合は、 Ctrl キーをふくむキーパターンと Ctrl キーをふくまないキーパターンの2つを登録する必要があります。'''
; 「カッコを追加」の動作
:: e.g. Ctrl+F8 と F8  /  Ctrl+8 と Alt+8  など
 
:: <span style="color:#c00;"> ※ F8 だけで登録して、 Ctrl+F8 には別のコマンドへのショートカット登録がされている場合、 Ctrl+F8 での「カッコの追加」はできません。</span>
* 定義されたカッコのペアを削除したときに「さいごに削除したカッコ」を更新しますので、「カッコを削除」の動作をしたことがない場合には、設定項目の <code>defaultOpenBrc</code> と <code>defaultCloseBrc</code> で定義されたカッコのペアで選択範囲を囲います。
: ※ Mery Ver 3.0.0 以降で「includeライブラリ」を導入していない場合は、Mery の再起動ごとに「さいごに 追加/削除 したカッコ」の一時記憶内容が破棄されます。
 
* カッコの追加に使用する前に、一度「使いたいカッコ」の削除を実行して、設定ファイルの「さいごに 追加/削除 したカッコ」を更新する必要があります。<br>  e.g. "削除" → "追加" → "追加" ……  (削除) → (追加) → (追加) ……
 
; Ctrl キーによる動作の切り替え
 
* ツールバーにアイコンを置いて実行する場合、アイコンをクリックするときの Ctrl キーの押し下げ状態(Ctrl+クリックか、ただのクリックか)で機能を切り替えます
 
* [マクロ]メニューや右クリックメニュー内から実行する場合も、実行するときの Ctrl キーの押し下げ状態(Ctrl+クリック or ただの左クリック、または Ctrl+Enter or Enter)で機能を切り替えます


* ツールバーにアイコンを置いて実行する場合、アイコンをクリックするときの Ctrl キーの押し下げ状態(Ctrl+クリックか、ただのクリックか)で機能を切り替えます<br>
* 外部リソースからの読み込みコストがあるため、ショートカットキー( e.g. Ctrl+F8)や Ctrl+クリックが速すぎると Ctrl キーの押し下げ状態を正しく取得できないことがあります。<br> 「カッコを追加/削除」がうまく機能しないときは、Ctrl キーを放すタイミングを遅らせてください <br>(マクロが発動するまで、またはマクロの処理が終了するまで Ctrl キーを押し下げたままにする)。


* 外部リソースからの読み込みコストがあるため、Ctrl+F8 キーなどや Ctrl+クリックが速すぎると Ctrl キーの押し下げ状態を正しく取得できないことがあります。<br> 「カッコの追加」がうまく機能しないときは、Ctrl キーを放すタイミングを遅らせてください <br>(マクロが発動するまで、またはマクロの処理が終了するまで Ctrl キーを押し下げたままにする)。
; Alt キーによる動作の切り替え


* Ctrl キーを押していないときで、選択範囲がカッコで囲われていない場合はなにもしません。
* Ctrl キーが押されていないときで、Alt キーを押しながら実行したときは「さいごに削除したカッコ」ではなく、「つねに特定のカッコ」(設定項目 <code>altOpenBrc</code> と <code>altCloseBrc</code> で指定)で選択範囲を囲います。
: ※ 設定項目で <syntaxhighlight lang="javascript" inline>var altOpenBrc = "";</syntaxhighlight>, <syntaxhighlight lang="javascript" inline>var altCloseBrc = ""; </syntaxhighlight> にすると「GetKeyState.exe」による Alt キーの状態取得処理がなくなるので、処理速度がすこし速くなります。


; マルチカーソル/複数選択範囲への対応


'''カスタマイズ'''
'''Mery Ver 3.0.1 以降''' の「マルチカーソル/複数選択範囲」にたいしても、それぞれの選択範囲ごとに「カッコを追加/削除」できます。


* ソースコード内の ''"Ctrl", "ctrl", "control"'' を ''"shift"'' に書き換えれば、カッコの「追加」用のトリガーを Shift キーに変更できます。
<code>(小カッコで囲われた選択範囲)</code> <code>「カギカッコで囲われた選択範囲」</code> のカッコを同時に削除できます。
* ソースコード内の ''if ( $ctrl == 1 )'' を ''if ( $ctrl == 0'' ) に書き換えれば、<br>  Ctrl キーの押し下げありで「カッコを削除」<br>  Ctrl キーの押し下げなしで「カッコを追加」<br> に変更できます。
* 「カッコの種類」の定義に <nowiki>"<!-- " と " -->"</nowiki> など「複数文字の文字列のペア」を追加したい場合は、ページ末尾の「[[#メモ|メモ]]」の項のサンプルコードを参考にカスタマイズしてください。


: 「カッコを削除」での注意事項
:* カッコで囲われていない選択範囲は無視されます。
:* 複数選択範囲や矩形選択範囲からカッコを削除したときは「さいごに削除したカッコ」を外部ファイルに保存しません(外部ファイルへの連続アクセス・書き込みによるエラー抑止のための仕様)。
:* Mery Ver 3.0.1 以降で「includeライブラリ」を導入していない環境では、複数選択範囲や矩形選択範囲からカッコを削除したときに「さいごに削除したカッコ」を一時記憶させることができますが、保存されるカッコは「いちばん後ろの選択範囲から削除したカッコ」になります(複数範囲選択したときの順番を考慮しない)。


== ソースコード ==
=== ソースコード ===
※ Mery Ver 3.0.0 以降では <code>#include "include/IO.js"</code> を削除しても動作します。<br>
※ Mery Ver 3.0.1 以降では「マルチカーソル/複数選択範囲」にも対応します。


<source lang="javascript">
<syntaxhighlight lang="javascript" style="height:100em; overflow:auto;">
#title="カッコを追加/削除"
#title="カッコを追加/削除"
#tooltip="対になるカッコを追加/削除する"
#tooltip="対になるカッコを追加/削除する"
#include "include/IO.js"
#include "include/IO.js"
// #icon="brackets(delete)[3].ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",288
var start = new Date();
editor.ExecuteCommandByID( MEID_WINDOW_ACTIVE_PANE = 2189 );


/**
/**
  * ------------------------------------------------------------
  * ------------------------------------------------------------
  * カッコを追加/削除 (2019/03/19, sukemaru)
  * カッコを追加/削除
* sukemaru, 2019-03-19 - 2020-06-28
  * ------------------------------------------------------------
  * ------------------------------------------------------------
  * ※ このマクロの実行には、以下の外部ライブラリと実行ファイルが必要です。
  * ※ 以下の外部実行ファイルが必要です。
  *
  * ・pizz 氏作成の "GetKeySatate.exe(キー状態取得実行ファイル)" を Macros フォルダに配置してください。
*  https://www.haijin-boys.com/wiki/GetKeyState.exe(キー状態取得実行ファイル)
* ------------------------------------------------------------
* ※ Mery Ver 2.x では、以下の外部ライブラリが必要です。
  *  ・ks 氏作成の "includeライブラリ" を Macros フォルダに配置してください。
  *  ・ks 氏作成の "includeライブラリ" を Macros フォルダに配置してください。
  *  https://www.haijin-boys.com/wiki/include%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA
  *  https://www.haijin-boys.com/wiki/includeライブラリ
*  ・pizz 氏作成の "GetKeyState.exe" を Macros フォルダに配置してください。
*  https://www.haijin-boys.com/wiki/Eclipse%E9%A2%A8%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%82%A2%E3%82%A6%E3%83%88(%E6%94%B9)
  * ------------------------------------------------------------
  * ------------------------------------------------------------
*
  */
  */
// ---------- ▼ 設定項目 ▼ ---------- //
// ■ Ctrl キーを押しながら実行したときの動作モード
var ctrlToDel = false; // true:カッコを追加 / false:カッコを削除
// ■ 選択範囲の『外側』(前と後ろ) の各1文字がカッコのときも削除する? ■
// (※ 選択範囲の前後を1文字ずつ拡張してカッコを削除する)
var outerEnable = true; // true:する / false:しない
// ■ 追加するカッコの初期値(Tag プロパティや JSON がないとき)
var defaultOpenBrc = "「";
var defaultCloseBrc = "」";
// ■ Alt キー押し下げ時は指定したカッコを追加(※強制)
var altOpenBrc  = "(";
var altCloseBrc = ")";
// ■ JSON ファイルのベース名(要:include ライブラリ)
var jsonName = ScriptName.replace( /\.js$/i, "" );
// var jsonName = "カッコを追加/削除";
// ■ 削除したカッコの一時記憶方法(要:Mery Ver 3.0.0 以上)
var tagType = 1;
  // 0 : 一時記憶なし
  // 1 : タブ(文書)ごとに一時記憶する(Document.Tag)
  // 2 : ウインドウごとに一時記憶する(Editor.Tag)
  // 3 : すべてのタブとウインドウ共通で一時記憶する(window.Tag)




// ▼「対になるカッコ」の種類 (始)と(終) のペアを列挙する ▼  
// ▼「対になるカッコ」の種類 (始)と(終) のペアを列挙する ▼  
// ※ 開き/閉じカッコはそれぞれ「1文字」でないとダメ
// ※ brackets に列挙する開き/閉じカッコのペアはそれぞれ「1文字」ずつでないとダメ
var brackets = "()「」<>[]{}\"\"''()「」『』<>[]{}【】〖〗﹁﹂﹃﹄︵︶︿﹀︽︾︹︺︷︸︻︼︗︘⦅⦆⦅⦆〚〛〔〕〘〙〈〉《》””’’〝〞〝〟‘’“”――~~〜〜  ";
 
var brackets = "()「」<>[]{}\"\"''()「」『』<>[]{}【】〖〗﹁﹂﹃﹄︵︶︿﹀︽︾︹︺︷︸︻︼︗︘⦅⦆⦅⦆〚〛〔〕〘〙〈〉《》””’’〝〞〝〟‘’“”――~~〜〜    ";
 
brackets += "++--**\/\/##==%%::::@@@@※※○○●●□□■■◇◇◆◆▽▽▼▼△△▲▲☆☆★★††||←→→←↑↓↓↑←←→→↑↑↓↓……¿?¡!‚‘‚’„“„”“„‘‚‹››‹«»»«——‐‐--␣␣__≪≫";
 
 
// ▼ HTML タグなど複数文字の要素での (始)と(終) のペアを列挙 ▼
var brackets2 = [
  "<i>" , "</i>" , "<u>" , "</u>" , "<s>" , "</s>" ,
  "<b>" , "</b>" , "<q>" , "</q>" ,
  "</" , ">" , "<" , "/>" ,
  "<li>" , "</li>" , "<h>" , "</h>" ,
  "<span>" , "</span>" , "<div>" , "</div>" ,
  "<pre>" , "</pre>" , "<code>" , "</code>" ,
  "===== " , " =====" , "=====" , "=====" , "==== " , " ====", "====" , "====",
  "=== " , " ===" , "===" , "===" , "== " , " ==" , "==" , "==" , "= " , " =",
  "'''''" , "'''''" , "'''" , "'''" , "''" , "''",
  "――" , "――" ,
  "/** \n" , "\n */" , "/** \n" , "\n*/" , "/**\n" , "\n */" , "/**\n" , "\n*/" ,
  "/* \n" , "\n */" , "/* \n" , "\n*/" , "/*\n" , "\n */" , "/*\n" , "\n*/" ,
  "/** " , " */" , "/* " , " */" , "/*" , "*/" ,
  "( ", " )" , " (", ") " , ' "' , '" ' ,
  "<!-- " , " -->" , "<!--" , "-->"
];
 
// ---------- ▲ 設定項目 ▲ ---------- //


// brackets += "++--**\/\/##==%%::::@@@@※※○○●●□□■■◇◇◆◆▽▽▼▼△△▲▲☆☆★★††||←→→←↑↓↓↑←←→→↑↑↓↓……¿?¡!‚‘‚’„“„”“„‘‚‹››‹«»»«——‐‐--␣␣__";
brackets = brackets2.concat( brackets.split( "" ) ); // brackets2 が先、brackets が後


// OutputBar.Writeln( ( brackets.length / 2 ) + " pairs of brckets" );
// OutputBar.Writeln( brackets.toString().replace( /\n/g , "\\n" ).replace( /\t/g , "\\t" ).replace( /[ ]/g , "▯" ) + "\n" );


// ■ 選択範囲の『外側』(前と後ろ) の各1文字がカッコのときも除去する? ■
// (※ 選択範囲の前後を1文字ずつ拡張してカッコを除去する)
var removeOuterBracketsEnable = true; // true:する / false:しない


var d = editor.ActiveDocument;
var $end  = false; // 完了フラグ
var $ctrl = $alt = false;
var gks = editor.FullName.replace( /[^\\]+$/, "" )
        + "Macros\\GetKeyState.exe";


var d = document;
if ( d.ReadOnly ) {
if ( d.ReadOnly ) {
   Status = " ドキュメントは書き換え禁止です。";
   Status = " ドキュメントは書き換え禁止です。";
   Quit();
   $end = true;
}
else if ( ! new ActiveXObject( "Scripting.FileSystemObject" ).FileExists( gks ) ) {
  Status = " GetKeyState.exe がありません。";
  $end = true;
}
else {
  var WshShell = new ActiveXObject( "WScript.Shell" );
  // Ctrl, Alt キーの状態を取得
  $ctrl = ( WshShell.Run( "\"" + gks + "\" ctrl", 0, true ) === 1 );
  if ( ! $ctrl && altOpenBrc && altCloseBrc ) {
    $alt = ( WshShell.Run( "\"" + gks + "\" alt" , 0, true ) === 1 );
  }
}
}


// Ctrl キーの状態を取得
// メインコード
var getKeyState = '"' + editor.FullName.replace( /mery\.exe$/i , "Macros" ) + '\\GetKeyState.exe" control';
if ( ! $end ) {
var $ctrl = new ActiveXObject( "WScript.Shell" ).Run( getKeyState, 0, true );
  $ctrl = $alt ? false : ( ctrlToDel ? $ctrl : ! $ctrl );
 
  var s = d.selection;
  var sMode = s.Mode || 0;
  var setting = {
    openBracket:    defaultOpenBrc,
    closeBracket:    defaultCloseBrc,
    altOpenBrc:      altOpenBrc,
    altCloseBrc:    altCloseBrc,
    defaultOpenBrc:  defaultOpenBrc,
    defaultCloseBrc: defaultCloseBrc
  };
 
  // Tag プロパティに対応
  var ioEnable  = ( typeof IO === "object" );
  var tagEnable = ( "Tag" in window );
  var tagKey    = "addDeleteBrackets";
 
  // JSON ファイルから「最後に使用したカッコ」を読みこむ
  if ( ioEnable ) {
    jsonName = jsonName || ScriptName.replace( /\.js$/i, "" );
    setting  = IO.Deserialize( setting, jsonName ); // JSON 読み込み
  }
  // Tag プロパティから「最後に使用したカッコ」を読みこむ
  else if ( tagEnable ) {
    setting = GetTag( tagType, tagKey ) || setting;
  }


if ( $ctrl == -1 ) {
  var sx = ScrollX,  sy = ScrollY;
   Status = " GetKeyState.exe エラー ";
 
  Quit();
  // マルチカーソル/複数選択に対応
  // ※ マルチカーソル/複数選択では削除したカッコを外部 JSON ファイルに保存しない
  var arg = [
    tagType, jsonName, outerEnable, brackets, $ctrl, $alt, sMode,
    setting, ioEnable, tagEnable, tagKey, start
  ];
  // 選択範囲が1つで矩形選択ではないとき
  if ( ! s.Mode || s.Mode === 1 ) {
    AddDeleteBrackets_Main( arg );
  }
  // 矩形選択または複数選択のとき
   else {
    var dt = d.Text;
    BeginUndoGroup();
    AddUndo();
    MultiFunction( AddDeleteBrackets_Main, arg );
    EndUndoGroup();
    if ( d.Text === dt ) { d.Undo(); }
  }
 
  ScrollX = sx;  ScrollY = sy;
}
}


var s = document.selection;
var st = s.Text; // 選択範囲の文字列
var act = s.GetActivePos();
var anc = s.GetAnchorPos();
var tp = ( anc < act ) ? anc : act; // 選択範囲の先頭位置
var bp = ( anc < act ) ? act : anc; // 選択範囲の末尾位置
var $del = false;
var $add = false;
var o, c;
var setting = {};


// JSON ファイルから「最後に使用したカッコ」を読み込む
/**
setting = IO.Deserialize( setting );
* 関数 AddDeleteBrackets_Main()
* 「カッコを追加/削除」マクロ
*/
function AddDeleteBrackets_Main( arg ) {
  var tagType    = arg[0];
  var jsonName    = arg[1];
  var outerEnable = arg[2];
  var brackets    = arg[3];
  var $ctrl      = arg[4];
  var $alt        = arg[5];
  var sMode      = arg[6];
  var setting     = arg[7];
  var ioEnable    = arg[8];
  var tagEnable  = arg[9];
  var tagKey      = arg[10];
  var start      = arg[11];
 
  var d = editor.ActiveDocument;
  var s = d.selection;
  var act = s.GetActivePos();
  var anc = s.GetAnchorPos();
  var tp = Math.min( anc, act );
  var bp = Math.max( anc, act );
  var $end = $del = $add = false; // 削除フラグ/追加フラグ/完了フラグ
  var len = brackets.length;
  var tmp = {};
 
  // 選択範囲を「最後に使用したカッコ」で囲う
  // Alt キーありで「指定したカッコを強制追加」モード(※優先)
  // ショートカットキー [ Alt+F8 ] or [ Shift+F8 ]
  if ( $alt || ! $ctrl ) {
    AddBrackets( setting, tp, $alt );
    $add = $end = true;
  }
 
  // 選択範囲の先頭と末尾から「対になるカッコ」を削除
  // ショートカットキー [ Ctrl+F8 ]
  if ( ! $end && $ctrl ) {
    tmp = DeleteBrackets(
      brackets, setting, sMode, ioEnable, jsonName, tagEnable, tagKey, tagType, tp
    );
    setting = tmp.setting;
    $end = tmp.$end;  $del = tmp.$del;
  }
 
  // 選択範囲内の先頭と末尾が「対になるカッコ」ではなかったとき
  if ( ! $end && outerEnable ) {
    tmp = RemoveOuterBrackets(
      brackets, setting, sMode, ioEnable, jsonName, tagEnable, tagKey, tagType, tp, bp
    );
    setting = tmp.setting;
    $end = tmp.$end;  $del = tmp.$del;
  }
  var o = $alt ? setting.altOpenBrc
        : setting.openBracket;
  var c = $alt ? setting.altCloseBrc
        : setting.closeBracket;
 
  // 終了ステータス
  Status = $add ? " " + o.replace( /[ ]+/g , "␣" ) + " カッコ "
                      + c.replace( /[ ]+/g , "␣" ) + " で囲いました。"
        : $del ? " " + o.replace( /[ ]+/g , "␣" ) + " と "
                      + c.replace( /[ ]+/g , "␣" ) + " を削除しました。"
        : $end ? " カッコの 追加/削除 なし。 "
    /* else */ : " カッコがありません。 ( searched for "
                  + ( ( len / 2 ) + " pairs of brckets )" );
  Status += TimerElapsed( new Date(), start );
}


// Ctrl キーが押されているときは「最後に使用したカッコ」で囲う
/**
if ( $ctrl == 1 ) {
* 関数 TimerElapsed( end, start )
  // 「最後に使用したカッコ」
* start からの経過時間を [ s.sss 秒 ] で返す
  o = setting.openBracket ? setting.openBracket : "(";
*/
   c = setting.closeBracket ? setting.closeBracket : ")";
function TimerElapsed( end, start ) {
   s.Text = o + st + c; // 先頭と末尾にカッコを追加
   var elapsedSec = ( end - start ) / 1000;
   s.SetAnchorPos( tp ); // 選択範囲を復帰する
   // start からの経過時間を [ s.sss 秒 ] で返す
  $add = true;
   return "  [ "
        + elapsedSec.toFixed( 3 ).replace( /\./, ". " )
        + " 秒 ]";
}
}


// Ctrl キーが押されていないときは「対になるカッコ」を削除する
/**
else {
* 関数 AddBrackets( setting )
* 選択範囲をカッコで囲う
*/
function AddBrackets( setting, tp, $alt ) {
  // 追加するカッコ ( Alt強制 > 「最後に使用したカッコ」 > 初期値 )
  var o = $alt ? setting.altOpenBrc
              : setting.openBracket;
  var c = $alt ? setting.altCloseBrc
              : setting.closeBracket;
 
  var s = editor.ActiveDocument.selection;
  // カッコを追加
  s.Text = o + s.Text + c;
  s.SetAnchorPos( tp ); // 選択範囲を復帰
  return true;
}


/**
* 関数 DeleteBrackets( brackets, setting, jsonName )
* 選択範囲の先頭と末尾からカッコを削除する
*/
function DeleteBrackets( brackets, setting, sMode, ioEnable, jsonName, tagEnable, tagKey, tagType, tp ) {
  var $del = $end = false;
  var s = editor.ActiveDocument.selection,  st = s.Text;
  var o = c = "",  oLen = cLen = 0;
   // ループ処理で「対になるカッコ」と一致するかチェック
   // ループ処理で「対になるカッコ」と一致するかチェック
   for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
   for ( var i = 0, len = brackets.length; i < len; i += 2 ) {
     o = brackets[ i ]; // 開きカッコ
    if ( i % 2 == 1 ) { continue; }
     c = brackets[ i + 1 ] // 閉じカッコ
     o = brackets[ i ];     oLen = o.length; // 開きカッコ
     c = brackets[ i + 1 ];  cLen = c.length; // 閉じカッコ


     // 選択範囲内の先頭と末尾が「対になるカッコ」のとき
     // 選択範囲内の先頭と末尾が「対になるカッコ」のとき
     if ( st.length >= o.length + c.length && i % 2 == 0
     if ( st.length >= oLen + cLen
        && st.slice( 0, o.length ) == o
    &&   st.slice( 0, oLen ) === o
        && st.slice( - c.length ) == c ) {
    &&   st.slice( - cLen ) === c ) {
       s.Text = st.slice( o.length, - c.length ); // 先頭と末尾のカッコを削除
 
       s.SetAnchorPos( tp ); // 選択範囲を復帰する
      // 先頭・末尾のカッコを削除して選択範囲を復帰
       $del = true;
       s.Text = st.slice( oLen, - cLen );
       s.SetAnchorPos( tp ); // 選択範囲を復帰
       $del = $end = true;


       if ( o != setting.openBracket || c != setting.closeBracket ) {
      // ヒットしたカッコを JSONファイル/Tagプロパティ に保存
         setting.openBracket = o;
       if ( ( o !== setting.openBracket || c !== setting.closeBracket ) ) {
         setting.openBracket = o;
         setting.closeBracket = c;
         setting.closeBracket = c;
         IO.Serialize( setting ); // ヒットしたカッコをJSONファイルに保存する
         if ( ioEnable && jsonName && sMode < 2 ) { // JSON 書き込み
          IO.Serialize( setting, jsonName );
        }
        else if ( tagEnable ) { // Tag 書き込み
          SetTag( setting, tagType, tagKey );
        }
       }
       }
       break;
       break;
     }
     }
   }
   }
  return { setting : setting,  $del : $del,  $end : $end };
}
/*
* 関数 RemoveOuterBrackets( brackets, setting, jsonName )
* 選択範囲の外側(前と後ろ)にあるカッコを削除する
*/
function RemoveOuterBrackets( brackets, setting, sMode, ioEnable, jsonName, tagEnable, tagKey, tagType, tp, bp ) {
  var $del = $end = false;
  var d = editor.ActiveDocument,  s = d.selection;
  var dt = d.Text,  st = s.Text;
  var o = c = "",  oLen = cLen = 0;
  for ( var i = 0, len = brackets.length; i < len; i += 2 ) {
    if ( i % 2 === 1 ) { continue; }
    o = brackets[ i ];      oLen = o.length; // 開きカッコ
    c = brackets[ i + 1 ];  cLen = c.length; // 閉じカッコ


  // 選択範囲内の先頭と末尾が「対になるカッコ」ではなかったとき
  if ( removeOuterBracketsEnable && ! $del ) {
     // 選択範囲の外側 (前と後) の各1文字がカッコのとき
     // 選択範囲の外側 (前と後) の各1文字がカッコのとき
     for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
     // カッコの文字数だけ選択範囲を拡張してカッコを削除
      o = brackets[ i ]; // 開きカッコ
    if ( dt.slice( tp - oLen, tp ) === o
      c = brackets[ i + 1 ] // 閉じカッコ
    &&   dt.slice( bp, bp + cLen ) === c ) {
      if ( i % 2 == 0
 
          && d.Text.slice( tp - o.length, tp ) == o
      s.SetAnchorPos( tp - oLen );
          && d.Text.slice( bp, bp + c.length ) == c ) {
      s.SetActivePos( bp + cLen, true );
        s.SetAnchorPos( tp - o.length ); // 選択範囲の先頭を1文字拡張
      s.Text = s.Text.slice( oLen, - cLen );
        s.SetActivePos( bp + c.length, true ); // 選択範囲の末尾を1文字拡張
      s.SetAnchorPos( tp - oLen ); // 選択範囲を復帰
        s.Text = s.Text.slice( o.length, - c.length ); // 先頭と末尾の各1文字ずつを削除
      $del = $end = true;
        s.SetAnchorPos( tp - o.length ); // 選択範囲を復帰する
        $del = true;


        if ( o != setting.openBracket || c != setting.closeBracket ) {
      // ヒットしたカッコを Tag プロパティ/JSON ファイル に保存
          setting.openBracket = o;
      if ( o !== setting.openBracket || c !== setting.closeBracket ) {
          setting.closeBracket = c;
        setting.openBracket = o;
           IO.Serialize( setting ); // ヒットしたカッコをJSONファイルに保存する
        setting.closeBracket = c;
        if ( ioEnable && jsonName && sMode < 2 ) { // JSON 書き込み
           IO.Serialize( setting, jsonName );
        }
        else if ( tagEnable ) { // Tag 書き込み
          SetTag( setting, tagType, tagKey );
         }
         }
        break;
       }
       }
      break;
     }
     }
   }
   }
  return { setting : setting,  $del : $del,  $end : $end };
}
}


// 終了ステータス
 
if ( $add ) {
/**
   Status = " " +  o.replace( /[ ]+/g , "␣" ) + " カッコ "
* 関数 GetTag( tagType, tagKey, property )
        + c.replace( /[ ]+/g , "␣" ) + " で囲いました。";
* 指定された Tag の値を返す
*/
function GetTag( tagType, tagKey, property ) {
   try {
    var obj = ( typeof tagType === "object" ) ? tagType
            : ( tagType === 1 ) ? editor.ActiveDocument
            : ( tagType === 2 ) ? editor
            : ( tagType === 3 ) ? window
            : window;
    return ( obj.Tag.Exists( tagKey )
    && ( property ? property in obj.Tag( tagKey ) : true ) )
    ? property
      ? obj.Tag( tagKey )[ property ]
      : obj.Tag( tagKey )
    : null;
  } catch( e ) { Status = e; return null; }
}
}
else if ( $del ) {
 
   Status = " " + o.replace( /[ ]+/g , "␣" ) + "  と  "
/**
        + c.replace( /[ ]+/g , "␣" ) + "  を削除しました。";
* 関数 SetTag( value, tagType, tagKey, property )
}
* 指定された値を Tag に書き込む
else {
*/
   Status = " カッコがありません。"
function SetTag( value, tagType, tagKey, property ) {
   try {
    var obj = ( typeof tagType === "object" ) ? tagType
            : ( tagType === 1 ) ? editor.ActiveDocument
            : ( tagType === 2 ) ? editor
            : ( tagType === 3 ) ? window
            : window;
    if ( property ) {
      if ( obj.Tag.Exists( tagKey ) ) {
        obj.Tag( tagKey )[ property ] = value;
      }
      else { obj.Tag( tagKey ) = { property: value }; }
    }
    else { obj.Tag( tagKey ) = value; }
  }
   catch( e ) { Status = e; }
  finally { return; }
}
}
</source>
= メモ =
'''共通'''
* 注釈では「開きカッコ/閉じカッコの指定は '''各1文字''' ずつ」としてありますが、削除ループのコードは'''「任意の複数文字の文字列」'''を扱えるようにしてあります。<br> 変数 blackets の最初の代入値を配列形式にすれば、 (始)と(終) のペアは「任意の複数文字の文字列」も追加できます。<br>  e.g. ''var brackets = [ "(" , ")" , "<" , ">" , "<nowiki><!-- " , " --></nowiki>" , "<" , " />" ];''
* カッコの定義文字列に "\n" を含めることを想定していません(問題ないはずですが動作検証していません)。<br>
----
* (2019/03/19 sukemaru)
: 既存の ''var brackets = " …… ";'' 文字列部分を配列形式に変換してから、'''「任意の複数文字の文字列」のペアを追加する'''こともできます。<br>
'''サンプルコード''' <br>
( ''// brackets += " …… ";'' の行のしたに追加する)
<source lang="javascript">
// brackets を配列形式に変換する
brackets = brackets.match( /./g );


// ① 配列の末尾にカッコの種類を追加する ※(始) (終) の順
brackets[ brackets.length ] = "≪";
brackets[ brackets.length ] = "≫";


/**
/**
  * "<!-- " , " -->" や "<" , "/>" のように
  * 関数 MultiFunction( Fn, arg1 )
* (始) & (終) が複数文字のペアで、(始)の先頭/(終)の末尾 の文字が
  * マルチカーソル(複数選択範囲)に対応させる
  * 既存の「カッコの種類」に含まれている(この例では < > のペア)ものは、
  * 第1引数: Function; 選択範囲ごとに適用する処理の関数
  * ・unshift() メソッドで配列の先頭に追加するか
  * 第2引数: Function に渡す引数をまとめた配列
  * ・別の配列に列挙してから concat() メソッドで brackets と統合する
  */
  */
function MultiFunction( Fn, arg ) {
  var d = editor.ActiveDocument;
  var s = d.selection;


// ② unshift() メソッドでカッコの種類を配列の先頭に追加する場合は
  // 矩形選択範囲は行に分ける
//  brackets.unshift("終"); brackets.unshift("始"); の順にすること
  s.Mode = meModeMulti;
brackets.unshift( " -->" );
 
brackets.unshift( "<!-- " );
  // 選択範囲の座標を取得
   var sCount = s.Count;
  var Sel = [];
  for ( var i = 0; i < sCount; i ++ ) {
    Sel[i] = {
      act: s.GetActivePos( i ),
      anc: s.GetAnchorPos( i )
    };
  }


// ③ 別の配列に (始),(終),(始),(終) の順に列挙して brackets と統合する
  // 各選択範囲を処理;
brackets2 = [ "<b>", "</b>", "<u>", "</u>", "</", ">", "<", "/>", "/* ", "*/" ];
  for ( var i = 0, diff = 0, dl; i < sCount; i ++ ) {
brackets = brackets2.concat( brackets );
    dl = d.TextLength;
    s.SetActivePos( Sel[i].act + diff );
    s.SetAnchorPos( Sel[i].anc + diff );


    Fn( arg ); // AddDeleteBrackets_Main() 関数でカッコを追加/削除


// 配列 brackets の中身をアウトプットバーに出力する
    // Fn() の残した選択範囲(またはキャレット位置)を回収
// OutputBar.Writeln( brackets.toString().replace( /[ ]+/g , "␣" ) );
    Sel[i].act = s.GetActivePos();
</source>
    Sel[i].anc = s.GetAnchorPos();
    diff += d.TextLength - dl; // 文字数の増減量(累積)
  }


'''アウトプットの出力結果'''(半角空白は ␣ で表示)
  // マルチカーソル(複数選択範囲)を復帰
: <span style="color:#c00;"><nowiki><b>,</b>,<u>,</u>,</,>,<,/>,/*␣,*/,<!--␣,␣-->,</nowiki></span>(,),「,」,<,>,[,],{,},",",',',(,),「,」,『,』,<,>,[,],{,},【,】,〖,〗,﹁,﹂,﹃,﹄,︵,︶,︿,﹀,︽,︾,︹,︺,︷,︸,︻,︼,︗,︘,⦅,⦆,⦅,⦆,〚,〛,〔,〕,〘,〙,〈,〉,《,》,”,”,’,’,〝,〞,〝,〟,‘,’,“,”,―,―,~,~,〜,〜,␣,␣<span style="color:#c00;">,≪,≫</span>
  for ( var i = 0; i < sCount; i ++ ) {
    s.AddPos( Sel[i].anc, Sel[i].act );
  }
}
</syntaxhighlight>


これで「カッコをはずす」や「カッコを追加」の操作で <nowiki><!-- --> や /* */</nowiki> などのペアを扱えるようになります。
== 変更履歴 ==
* 1.0.5 (2020-06-28)
** 「カッコを削除/追加」マクロを削除
** マルチカーソル/複数選択範囲に対応
* 1.0.4 (2019-05-03)
** 「カッコを追加/削除」の変数の記述ミスによるエラーを修正
* 1.0.3 (2019-04-07)
** Quit() メソッドを削除して ZIP を更新(ソースコード内の年月日の表記はまま)
* 1.0.2 (2019-03-19)
** 「カッコを追加/削除」マクロを追加
** ZIP をアップロード
* 1.0.1 (2019-03-18)
** 「カッコを削除/追加」マクロを追加
* 1.0.0 (2019-03-14)
** 「カッコをはずす」マクロの初版

2024年9月9日 (月) 09:57時点における最新版

選択範囲の "最初の1文字" と "最後の1文字" が「対になるカッコ」のとき、カッコ囲いをはずします。
それにくわえて

  • 「カッコをはずす」マクロでは、選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときにも、カッコ囲いをはずします。
  • 「カッコを追加/削除」マクロは、「さいごに削除したカッコ」と同種のカッコで選択範囲を囲います。
    任意のタイミングで「さいごに削除したカッコ」を記憶・更新することができるので、ソースコードや散文の校正のさいに使うと便利です。

削除できるカッコの種類は、ソースコード内で定義したもののみとなります。

カッコの種類(開き/閉じ それぞれ「1文字」ずつ)
  • 各種のカッコ(半角/全角/縦書き)のペア
 ( ) 「 」 < > [ ] { } ⦅ ⦆
( ) 「 」 『 』 < > [ ] { } 【 】 〖 〗 ⦅ ⦆ 〚 〛 〔 〕 〘 〙 〈 〉 《 》
﹁﹂ ﹃﹄ ︵︶ ︿﹀ ︽︾ ︹︺ ︷︸ ︻︼ ︗︘
  • 各種の引用符(半角/全角)のペア
" "  ' '  ” ”  ’ ’  〝 〞  〝 〟  ‘ ’  “ ”
  • ーダーシー、〜波ダーシ〜、~全角チルダ~
  • ␣半角空白␣、全角空白 のペア
  • 各種記号のペア
+ + - - * * / / # # = = % % : : : : @ @ @ @ ※ ※
● ● ■ ■ ◆ ◆ ▼ ▼ ▲ ▲ ☆ ☆ ★ ★ † †
← → → ← ↑ ↓ ↓ ↑ ← ← → → ↑ ↑ ↓ ↓
など...
  • 設定項目内の定義要配列 var brackets2 = [ ... ]; をカスタマイズすると、HTML タグなど「複数文字ずつのペア」も登録することができます。
"===", "===""==", "==" のように同一文字列をふくむペア(半角空白 あり/なし の差分なども)を登録する場合は、文字列の長さが大きいものが先になるようにしてください。

c.f. カッコで囲う」マクロ: ポップアップメニューから任意のカッコを追加する
   「引用符を追加/削除」マクロ: 特定のカッコまたは引用符の追加/削除トグル


ダウンロード >> 「ファイル:カッコを削除/追加.zip」(アイコン入り)
最終更新:2020-06-28
  • マルチカーソル/複数選択範囲に対応
  • 「カッコを削除/追加」マクロを削除

カッコをはずす[編集]

選択範囲の "最初の1文字" と "最後の1文字" が「対になるカッコ」のとき、または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときに、カッコ囲いをはずします。

  • 1回の実行につき1組のカッコ囲いをはずします(※内側の両端が優先。半角空白のペアも除去対象)。
例. 以下の行で [ "hoge" ] を範囲選択して連続で実行した場合、次のように作用します。
( [ "hoge" ] )	// 元の文字列(下線部が選択範囲)

(  "hoge"  )	// 1回目 実行後: [  と  ] を削除しました。
( "hoge" )	// 2回目 実行後: ␣ と ␣ を削除しました。
( hoge )	// 3回目 実行後: "  と  " を削除しました。
(hoge)		// 4回目 実行後: ␣ と ␣ を削除しました。	※選択範囲の外側
hoge		// 5回目 実行後: (  と  ) を削除しました。	※選択範囲の外側
( [ "hoge" ] ) 全体を範囲選択して連続で実行した場合は選択範囲内の外側から、
( [ "hoge" ] ) の hoge だけを範囲選択して連続で実行した場合は選択範囲外の内側から
順にカッコ囲いを解除します。
  • 選択範囲(複数行)の各行の行頭/行末からカッコを除去したい場合は、「カッコで囲う(ポップアップメニュー)」マクロや「テキスト整形」マクロの削除系コマンドをご利用ください。

ソースコード[編集]

※ Mery Ver 3.0.1 以降では「マルチカーソル/複数選択範囲」にも対応します。

#title="カッコをはずす"
#tooltip="対になるカッコを除去する"
// #icon="brackets(delete)[1].ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",286

/**
 * ------------------------------------------------------------
 * カッコをはずす
 * sukemaru, 2019-03-14 - 2020-06-28
 * ------------------------------------------------------------
 * 選択範囲の最初の1文字と最後の1文字が「対になるカッコ」のとき、
 * または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」のときに、
 * カッコ囲いをはずします。
 */


// ---------- ▼ 設定項目 ▼ ---------- //

// ■ 選択範囲の『外側』(前と後ろ) の各1文字がカッコのときも除去する? ■ 
// (※ 選択範囲の前後を1文字ずつ拡張してカッコを除去する)
var outerEnable = true;	// true:する / false:しない


// ▼「対になるカッコ」の種類 (始)と(終) のペアを列挙する ▼ 
// ※ brackets に列挙する開き/閉じカッコのペアはそれぞれ「1文字」ずつでないとダメ

var brackets = "()「」<>[]{}\"\"''()「」『』<>[]{}【】〖〗﹁﹂﹃﹄︵︶︿﹀︽︾︹︺︷︸︻︼︗︘⦅⦆⦅⦆〚〛〔〕〘〙〈〉《》””’’〝〞〝〟‘’“”――~~〜〜    ";

brackets += "++--**\/\/##==%%::::@@@@※※○○●●□□■■◇◇◆◆▽▽▼▼△△▲▲☆☆★★††||←→→←↑↓↓↑←←→→↑↑↓↓……¿?¡!‚‘‚’„“„”“„‘‚‹››‹«»»«——‐‐--␣␣__≪≫";


// ▼ HTML タグなど複数文字の要素での (始)と(終) のペアを列挙 ▼
var brackets2 = [
  "<i>" , "</i>" , "<u>" , "</u>" , "<s>" , "</s>" , 
  "<b>" , "</b>" , "<q>" , "</q>" , 
  "</" , ">" , "<" , "/>" , 
  "<li>" , "</li>" , "<h>" , "</h>" , 
  "<span>" , "</span>" , "<div>" , "</div>" , 
  "<pre>" , "</pre>" , "<code>" , "</code>" , 
  "===== " , " =====" , "=====" , "=====" , "==== " , " ====", "====" , "====", 
  "=== " , " ===" , "===" , "===" , "== " , " ==" , "==" , "==" , "= " , " =", 
  "'''''" , "'''''" , "'''" , "'''" , "''" , "''", 
  "――" , "――" , 
  "/** \n" , "\n */" , "/** \n" , "\n*/" , "/**\n" , "\n */" , "/**\n" , "\n*/" , 
  "/* \n" , "\n */" , "/* \n" , "\n*/" , "/*\n" , "\n */" , "/*\n" , "\n*/" , 
  "/** " , " */" , "/* " , " */" , "/*" , "*/" , 
  "( ", " )" , " (", ") " , ' "' , '" ' , 
  "<!-- " , " -->" , "<!--" , "-->" 
];

// ---------- ▲ 設定項目 ▲ ---------- //

// brackets2 が先、brackets が後
brackets = brackets2.concat( brackets.split( "" ) );

var d = editor.ActiveDocument;
if ( d.ReadOnly ) {
  Status = " ドキュメントは書き換え禁止です。";
}
else {
  var s = d.selection;
  var sx = ScrollX,  sy = ScrollY;

  // マルチカーソル/複数選択に対応
  var arg = [ outerEnable, brackets ];
  // 選択範囲が1つで矩形選択ではないとき
  if ( ! s.Mode || s.Mode === 1 ) {
    DeleteBrackets_Main( arg );
  }
  // 矩形選択または複数選択のとき
  else {
    var dt = d.Text;
    BeginUndoGroup();
    AddUndo();
    MultiFunction( DeleteBrackets_Main, arg );
    EndUndoGroup();
    if ( d.Text === dt ) { d.Undo(); }
  }

  ScrollX = sx;  ScrollY = sy;
}


/**
 * 関数 DeleteBrackets_Main()
 * 「カッコをはずす」マクロ
 */
function DeleteBrackets_Main( arg ) {
  var outerEnable = arg[0];
  var brackets    = arg[1];

  var d = editor.ActiveDocument;
  var s = d.selection;
  var st = s.Text;
  var act = s.GetActivePos();
  var anc = s.GetAnchorPos();
  var tp = ( anc < act ) ? anc : act;
  var bp = ( anc < act ) ? act : anc;
  var $del = false;
  var o, c;

  // 選択範囲内の最初と最後の各1文字がカッコのとき
  for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
    o = brackets[i];            // 開きカッコ
    c = brackets[ i + 1 ]       // 閉じカッコ
    if ( st.length >= o.length + c.length
    && i % 2 === 0
    && st.slice( 0, o.length ) === o
    && st.slice( - c.length ) === c ) {
      // 先頭と末尾の各1文字ずつを削除し、選択範囲を復帰する
      s.Text = st.slice( o.length, - c.length );
      s.SetAnchorPos( tp );
      $del = true;
      break;
    }
  }

  // 選択範囲の外側 (前と後) がカッコのとき
  if ( outerEnable && ! $del ) {
    for ( var i = 0, len = brackets.length - 1; i < len; i ++ ) {
      o = brackets[i];          // 開きカッコ
      c = brackets[ i + 1 ]     // 閉じカッコ
      if ( i % 2 === 0
      && d.Text.slice( tp - o.length, tp ) === o
      && d.Text.slice( bp, bp + c.length ) === c ) {
        // 選択範囲の先頭/末尾をカッコの文字数ぶんだけ拡張
        s.SetAnchorPos( tp - o.length );
        s.SetActivePos( bp + c.length, true );
        st = s.Text;
        // 先頭と末尾のカッコを削除し、選択範囲を復帰する
        s.Text = st.slice( o.length, - c.length );
        s.SetAnchorPos( tp - o.length );
        $del = true;
        break;
      }
    }
  }

  // 終了ステータス
  Status = ( $del )
         ? " " + ( o == " " ? "␣" : o ) + "  と  "
           + ( c == " " ? "␣" : c ) + "  を削除しました。"
         : " カッコがありません。";
}

/**
 * 関数 MultiFunction( Fn, arg1 )
 * マルチカーソル(複数選択範囲)に対応させる
 * 第1引数: Function; 選択範囲ごとに適用する処理の関数
 * 第2引数: Function に渡す引数をまとめた配列
 */
function MultiFunction( Fn, arg ) {
  var d = editor.ActiveDocument;
  var s = d.selection;

  // 矩形選択範囲は行に分ける
  s.Mode = meModeMulti;

  // 選択範囲の座標を取得
  var sCount = s.Count;
  var Sel = [];
  for ( var i = 0; i < sCount; i ++ ) {
    Sel[i] = {
      act: s.GetActivePos( i ),
      anc: s.GetAnchorPos( i )
    };
  }

  // 各選択範囲を処理;
  for ( var i = 0, diff = 0, dl; i < sCount; i ++ ) {
    dl = d.TextLength;
    s.SetActivePos( Sel[i].act + diff );
    s.SetAnchorPos( Sel[i].anc + diff );

    Fn( arg );	// DeleteBrackets_Main() 関数でカッコを削除

    // Fn() の残した選択範囲(またはキャレット位置)を回収
    Sel[i].act = s.GetActivePos();
    Sel[i].anc = s.GetAnchorPos();
    diff += d.TextLength - dl;	// 文字数の増減量(累積)
  }

  // マルチカーソル(複数選択範囲)を復帰
  for ( var i = 0; i < sCount; i ++ ) {
    s.AddPos( Sel[i].anc, Sel[i].act );
  }
}

カッコを追加/削除[編集]

マクロライブラリで公開・配布されている pizz 氏作成の「GetKeyState」を利用して、「カッコをはずす」マクロに「カッコを追加」の機能を加えたマクロです。

  • マクロ実行時に Ctrl キー が押されているときは、選択範囲を「さいごに削除したカッコ」で囲います。
  • マクロ実行時に Ctrl キーが押されていないとき、選択範囲の最初の1文字と最後の1文字が「対になるカッコ」の場合か、または選択範囲の外側 (前と後) の各1文字が「対になるカッコ」の場合には、カッコ囲いをはずします(→ 詳細は「カッコをはずす」マクロの項を参照)。

※ 設定項目 var ctrlToDel = true; にすると、Ctrl キーが押されているときは「カッコを削除」、押されていないときは「カッコを追加」になります。

  • 外部実行ファイル GetKeyState.exe を利用して Ctrl キーと Alt キーの押し下げ状態を取得します。
あらかじめ "GetKeyState.zip" をダウンロードして、書庫内の「GetKeyState.exe」を Macros フォルダに配置してください。
  • includeライブラリ を利用して「さいごに 追加/削除 したカッコ」を外部ファイルに保存します。
あらかじめ「includeライブラリ」を Macros フォルダに配置してください。
外部ファイルの保存場所は Mery\Macros\MacroSettings\<カッコを追加/削除>.json
または %AppData%\Mery\MacroSettings\<カッコを追加/削除>.json です。
(<カッコを追加/削除> の部分はこのマクロのファイル名と同一になります)

※ Mery Ver 3.0.0 以降では「includeライブラリ」なしでも動作します。

「カッコを追加」の動作
  • 定義されたカッコのペアを削除したときに「さいごに削除したカッコ」を更新しますので、「カッコを削除」の動作をしたことがない場合には、設定項目の defaultOpenBrcdefaultCloseBrc で定義されたカッコのペアで選択範囲を囲います。
※ Mery Ver 3.0.0 以降で「includeライブラリ」を導入していない場合は、Mery の再起動ごとに「さいごに 追加/削除 したカッコ」の一時記憶内容が破棄されます。
  • カッコの追加に使用する前に、一度「使いたいカッコ」の削除を実行して、設定ファイルの「さいごに 追加/削除 したカッコ」を更新する必要があります。
      e.g. "削除" → "追加" → "追加" …… (削除) → (追加) → (追加) ……
Ctrl キーによる動作の切り替え
  • ツールバーにアイコンを置いて実行する場合、アイコンをクリックするときの Ctrl キーの押し下げ状態(Ctrl+クリックか、ただのクリックか)で機能を切り替えます
  • [マクロ]メニューや右クリックメニュー内から実行する場合も、実行するときの Ctrl キーの押し下げ状態(Ctrl+クリック or ただの左クリック、または Ctrl+Enter or Enter)で機能を切り替えます
  • 外部リソースからの読み込みコストがあるため、ショートカットキー( e.g. Ctrl+F8)や Ctrl+クリックが速すぎると Ctrl キーの押し下げ状態を正しく取得できないことがあります。
    「カッコを追加/削除」がうまく機能しないときは、Ctrl キーを放すタイミングを遅らせてください
    (マクロが発動するまで、またはマクロの処理が終了するまで Ctrl キーを押し下げたままにする)。
Alt キーによる動作の切り替え
  • Ctrl キーが押されていないときで、Alt キーを押しながら実行したときは「さいごに削除したカッコ」ではなく、「つねに特定のカッコ」(設定項目 altOpenBrcaltCloseBrc で指定)で選択範囲を囲います。
※ 設定項目で var altOpenBrc = "";, var altCloseBrc = ""; にすると「GetKeyState.exe」による Alt キーの状態取得処理がなくなるので、処理速度がすこし速くなります。
マルチカーソル/複数選択範囲への対応

Mery Ver 3.0.1 以降 の「マルチカーソル/複数選択範囲」にたいしても、それぞれの選択範囲ごとに「カッコを追加/削除」できます。

(小カッコで囲われた選択範囲)「カギカッコで囲われた選択範囲」 のカッコを同時に削除できます。

「カッコを削除」での注意事項
  • カッコで囲われていない選択範囲は無視されます。
  • 複数選択範囲や矩形選択範囲からカッコを削除したときは「さいごに削除したカッコ」を外部ファイルに保存しません(外部ファイルへの連続アクセス・書き込みによるエラー抑止のための仕様)。
  • Mery Ver 3.0.1 以降で「includeライブラリ」を導入していない環境では、複数選択範囲や矩形選択範囲からカッコを削除したときに「さいごに削除したカッコ」を一時記憶させることができますが、保存されるカッコは「いちばん後ろの選択範囲から削除したカッコ」になります(複数範囲選択したときの順番を考慮しない)。

ソースコード[編集]

※ Mery Ver 3.0.0 以降では #include "include/IO.js" を削除しても動作します。
※ Mery Ver 3.0.1 以降では「マルチカーソル/複数選択範囲」にも対応します。

#title="カッコを追加/削除"
#tooltip="対になるカッコを追加/削除する"
#include "include/IO.js"
// #icon="brackets(delete)[3].ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",288

var start = new Date();
editor.ExecuteCommandByID( MEID_WINDOW_ACTIVE_PANE = 2189 );

/**
 * ------------------------------------------------------------
 * カッコを追加/削除
 * sukemaru, 2019-03-19 - 2020-06-28
 * ------------------------------------------------------------
 * ※ 以下の外部実行ファイルが必要です。
 *  ・pizz 氏作成の "GetKeySatate.exe(キー状態取得実行ファイル)" を Macros フォルダに配置してください。
 *  	https://www.haijin-boys.com/wiki/GetKeyState.exe(キー状態取得実行ファイル)
 * ------------------------------------------------------------
 * ※ Mery Ver 2.x では、以下の外部ライブラリが必要です。
 *  ・ks 氏作成の "includeライブラリ" を Macros フォルダに配置してください。
 *  	https://www.haijin-boys.com/wiki/includeライブラリ
 * ------------------------------------------------------------
 */

// ---------- ▼ 設定項目 ▼ ---------- //

// ■ Ctrl キーを押しながら実行したときの動作モード
var ctrlToDel = false;	// true:カッコを追加 / false:カッコを削除


// ■ 選択範囲の『外側』(前と後ろ) の各1文字がカッコのときも削除する? ■ 
// (※ 選択範囲の前後を1文字ずつ拡張してカッコを削除する)
var outerEnable = true;	// true:する / false:しない


// ■ 追加するカッコの初期値(Tag プロパティや JSON がないとき)
var defaultOpenBrc = "「";
var defaultCloseBrc = "」";


// ■ Alt キー押し下げ時は指定したカッコを追加(※強制)
var altOpenBrc  = "(";
var altCloseBrc = ")";


// ■ JSON ファイルのベース名(要:include ライブラリ)
var jsonName = ScriptName.replace( /\.js$/i, "" );
// var jsonName = "カッコを追加/削除";


// ■ 削除したカッコの一時記憶方法(要:Mery Ver 3.0.0 以上)
var tagType = 1;
  // 0 : 一時記憶なし
  // 1 : タブ(文書)ごとに一時記憶する(Document.Tag)
  // 2 : ウインドウごとに一時記憶する(Editor.Tag)
  // 3 : すべてのタブとウインドウ共通で一時記憶する(window.Tag)


// ▼「対になるカッコ」の種類 (始)と(終) のペアを列挙する ▼ 
// ※ brackets に列挙する開き/閉じカッコのペアはそれぞれ「1文字」ずつでないとダメ

var brackets = "()「」<>[]{}\"\"''()「」『』<>[]{}【】〖〗﹁﹂﹃﹄︵︶︿﹀︽︾︹︺︷︸︻︼︗︘⦅⦆⦅⦆〚〛〔〕〘〙〈〉《》””’’〝〞〝〟‘’“”――~~〜〜    ";

brackets += "++--**\/\/##==%%::::@@@@※※○○●●□□■■◇◇◆◆▽▽▼▼△△▲▲☆☆★★††||←→→←↑↓↓↑←←→→↑↑↓↓……¿?¡!‚‘‚’„“„”“„‘‚‹››‹«»»«——‐‐--␣␣__≪≫";


// ▼ HTML タグなど複数文字の要素での (始)と(終) のペアを列挙 ▼
var brackets2 = [
  "<i>" , "</i>" , "<u>" , "</u>" , "<s>" , "</s>" , 
  "<b>" , "</b>" , "<q>" , "</q>" , 
  "</" , ">" , "<" , "/>" , 
  "<li>" , "</li>" , "<h>" , "</h>" , 
  "<span>" , "</span>" , "<div>" , "</div>" , 
  "<pre>" , "</pre>" , "<code>" , "</code>" , 
  "===== " , " =====" , "=====" , "=====" , "==== " , " ====", "====" , "====", 
  "=== " , " ===" , "===" , "===" , "== " , " ==" , "==" , "==" , "= " , " =", 
  "'''''" , "'''''" , "'''" , "'''" , "''" , "''", 
  "――" , "――" , 
  "/** \n" , "\n */" , "/** \n" , "\n*/" , "/**\n" , "\n */" , "/**\n" , "\n*/" , 
  "/* \n" , "\n */" , "/* \n" , "\n*/" , "/*\n" , "\n */" , "/*\n" , "\n*/" , 
  "/** " , " */" , "/* " , " */" , "/*" , "*/" , 
  "( ", " )" , " (", ") " , ' "' , '" ' , 
  "<!-- " , " -->" , "<!--" , "-->" 
];

// ---------- ▲ 設定項目 ▲ ---------- //

brackets = brackets2.concat( brackets.split( "" ) );	// brackets2 が先、brackets が後

// OutputBar.Writeln( ( brackets.length / 2 ) + " pairs of brckets" );
// OutputBar.Writeln( brackets.toString().replace( /\n/g , "\\n" ).replace( /\t/g , "\\t" ).replace( /[ ]/g , "▯" ) + "\n" );


var d = editor.ActiveDocument;
var $end  = false;	// 完了フラグ
var $ctrl = $alt = false;
var gks = editor.FullName.replace( /[^\\]+$/, "" )
        + "Macros\\GetKeyState.exe";

if ( d.ReadOnly ) {
  Status = " ドキュメントは書き換え禁止です。";
  $end = true;
}
else if ( ! new ActiveXObject( "Scripting.FileSystemObject" ).FileExists( gks ) ) {
  Status = " GetKeyState.exe がありません。";
  $end = true;
}
else {
  var WshShell = new ActiveXObject( "WScript.Shell" );
  // Ctrl, Alt キーの状態を取得
  $ctrl = ( WshShell.Run( "\"" + gks + "\" ctrl", 0, true ) === 1 );
  if ( ! $ctrl && altOpenBrc && altCloseBrc ) {
    $alt = ( WshShell.Run( "\"" + gks + "\" alt" , 0, true ) === 1 );
  }
}

// メインコード
if ( ! $end ) {
  $ctrl = $alt ? false : ( ctrlToDel ? $ctrl : ! $ctrl );

  var s = d.selection;
  var sMode = s.Mode || 0;
  var setting = {
    openBracket:     defaultOpenBrc,
    closeBracket:    defaultCloseBrc,
    altOpenBrc:      altOpenBrc,
    altCloseBrc:     altCloseBrc,
    defaultOpenBrc:  defaultOpenBrc,
    defaultCloseBrc: defaultCloseBrc
  };

  // Tag プロパティに対応
  var ioEnable  = ( typeof IO === "object" );
  var tagEnable = ( "Tag" in window );
  var tagKey    = "addDeleteBrackets";

  // JSON ファイルから「最後に使用したカッコ」を読みこむ
  if ( ioEnable ) {
    jsonName = jsonName || ScriptName.replace( /\.js$/i, "" );
    setting  = IO.Deserialize( setting, jsonName );	// JSON 読み込み
  }
  // Tag プロパティから「最後に使用したカッコ」を読みこむ
  else if ( tagEnable ) {
    setting = GetTag( tagType, tagKey ) || setting;
  }

  var sx = ScrollX,  sy = ScrollY;

  // マルチカーソル/複数選択に対応
  // ※ マルチカーソル/複数選択では削除したカッコを外部 JSON ファイルに保存しない
  var arg = [
    tagType, jsonName, outerEnable, brackets, $ctrl, $alt, sMode,
    setting, ioEnable, tagEnable, tagKey, start
  ];
  // 選択範囲が1つで矩形選択ではないとき
  if ( ! s.Mode || s.Mode === 1 ) {
    AddDeleteBrackets_Main( arg );
  }
  // 矩形選択または複数選択のとき
  else {
    var dt = d.Text;
    BeginUndoGroup();
    AddUndo();
    MultiFunction( AddDeleteBrackets_Main, arg );
    EndUndoGroup();
    if ( d.Text === dt ) { d.Undo(); }
  }

  ScrollX = sx;  ScrollY = sy;
}


/**
 * 関数 AddDeleteBrackets_Main()
 * 「カッコを追加/削除」マクロ
 */
function AddDeleteBrackets_Main( arg ) {
  var tagType     = arg[0];
  var jsonName    = arg[1];
  var outerEnable = arg[2];
  var brackets    = arg[3];
  var $ctrl       = arg[4];
  var $alt        = arg[5];
  var sMode       = arg[6];
  var setting     = arg[7];
  var ioEnable    = arg[8];
  var tagEnable   = arg[9];
  var tagKey      = arg[10];
  var start       = arg[11];

  var d = editor.ActiveDocument;
  var s = d.selection;
  var act = s.GetActivePos();
  var anc = s.GetAnchorPos();
  var tp = Math.min( anc, act );
  var bp = Math.max( anc, act );
  var $end = $del = $add = false;	// 削除フラグ/追加フラグ/完了フラグ
  var len = brackets.length;
  var tmp = {};

  // 選択範囲を「最後に使用したカッコ」で囲う
  // Alt キーありで「指定したカッコを強制追加」モード(※優先)
  // ショートカットキー [ Alt+F8 ] or [ Shift+F8 ]
  if ( $alt || ! $ctrl ) {
    AddBrackets( setting, tp, $alt );
    $add = $end = true;
  }

  // 選択範囲の先頭と末尾から「対になるカッコ」を削除
  // ショートカットキー [ Ctrl+F8 ]
  if ( ! $end && $ctrl ) {
    tmp = DeleteBrackets(
      brackets, setting, sMode, ioEnable, jsonName, tagEnable, tagKey, tagType, tp
    );
    setting = tmp.setting;
    $end = tmp.$end;  $del = tmp.$del;
  }

  // 選択範囲内の先頭と末尾が「対になるカッコ」ではなかったとき
  if ( ! $end && outerEnable ) {
    tmp = RemoveOuterBrackets(
      brackets, setting, sMode, ioEnable, jsonName, tagEnable, tagKey, tagType, tp, bp
    );
    setting = tmp.setting;
    $end = tmp.$end;  $del = tmp.$del;
  }
  var o = $alt ? setting.altOpenBrc
        : setting.openBracket;
  var c = $alt ? setting.altCloseBrc
        : setting.closeBracket;

  // 終了ステータス
  Status = $add ? " " + o.replace( /[ ]+/g , "␣" ) + " カッコ "
                       + c.replace( /[ ]+/g , "␣" ) + " で囲いました。"
         : $del ? " " + o.replace( /[ ]+/g , "␣" ) + " と "
                       + c.replace( /[ ]+/g , "␣" ) + " を削除しました。"
         : $end ? " カッコの 追加/削除 なし。 "
     /* else */ : " カッコがありません。 ( searched for " 
                  + ( ( len / 2 ) + " pairs of brckets )" );
  Status += TimerElapsed( new Date(), start );
}

/**
 * 関数 TimerElapsed( end, start )
 * start からの経過時間を [ s.sss 秒 ] で返す
 */
function TimerElapsed( end, start ) {
  var elapsedSec = ( end - start ) / 1000;
  // start からの経過時間を [ s.sss 秒 ] で返す
  return "  [ "
         + elapsedSec.toFixed( 3 ).replace( /\./, ". " )
         + " 秒 ]";
}

/**
 * 関数 AddBrackets( setting )
 * 選択範囲をカッコで囲う
 */
function AddBrackets( setting, tp, $alt ) {
  // 追加するカッコ ( Alt強制 > 「最後に使用したカッコ」 > 初期値 )
  var o = $alt ? setting.altOpenBrc
               : setting.openBracket;
  var c = $alt ? setting.altCloseBrc
               : setting.closeBracket;

  var s = editor.ActiveDocument.selection;
  // カッコを追加
  s.Text = o + s.Text + c;
  s.SetAnchorPos( tp );	// 選択範囲を復帰
  return true;
}

/**
 * 関数 DeleteBrackets( brackets, setting, jsonName )
 * 選択範囲の先頭と末尾からカッコを削除する
 */
function DeleteBrackets( brackets, setting, sMode, ioEnable, jsonName, tagEnable, tagKey, tagType, tp ) {
  var $del = $end = false;
  var s = editor.ActiveDocument.selection,  st = s.Text;
  var o = c = "",  oLen = cLen = 0;
  // ループ処理で「対になるカッコ」と一致するかチェック
  for ( var i = 0, len = brackets.length; i < len; i += 2 ) {
    if ( i % 2 == 1 ) { continue; }
    o = brackets[ i ];      oLen = o.length;	// 開きカッコ
    c = brackets[ i + 1 ];  cLen = c.length;	// 閉じカッコ

    // 選択範囲内の先頭と末尾が「対になるカッコ」のとき
    if ( st.length >= oLen + cLen
    &&   st.slice( 0, oLen ) === o
    &&   st.slice( - cLen )  === c ) {

      // 先頭・末尾のカッコを削除して選択範囲を復帰
      s.Text = st.slice( oLen, - cLen );
      s.SetAnchorPos( tp );	// 選択範囲を復帰
      $del = $end = true;

      // ヒットしたカッコを JSONファイル/Tagプロパティ に保存
      if ( ( o !== setting.openBracket || c !== setting.closeBracket ) ) {
        setting.openBracket  = o;
        setting.closeBracket = c;
        if ( ioEnable && jsonName && sMode < 2 ) {	// JSON 書き込み
          IO.Serialize( setting, jsonName );
        }
        else if ( tagEnable ) {	// Tag 書き込み
          SetTag( setting, tagType, tagKey );
        }
      }
      break;
    }
  }
  return { setting : setting,  $del : $del,  $end : $end };
}

/*
 * 関数 RemoveOuterBrackets( brackets, setting, jsonName )
 * 選択範囲の外側(前と後ろ)にあるカッコを削除する
 */
function RemoveOuterBrackets( brackets, setting, sMode, ioEnable, jsonName, tagEnable, tagKey, tagType, tp, bp ) {
  var $del = $end = false;
  var d = editor.ActiveDocument,  s = d.selection;
  var dt = d.Text,  st = s.Text;
  var o = c = "",  oLen = cLen = 0;
  for ( var i = 0, len = brackets.length; i < len; i += 2 ) {
    if ( i % 2 === 1 ) { continue; }
    o = brackets[ i ];      oLen = o.length;	// 開きカッコ
    c = brackets[ i + 1 ];  cLen = c.length;	// 閉じカッコ

    // 選択範囲の外側 (前と後) の各1文字がカッコのとき
    // カッコの文字数だけ選択範囲を拡張してカッコを削除
    if ( dt.slice( tp - oLen, tp ) === o
    &&   dt.slice( bp, bp + cLen ) === c ) {

      s.SetAnchorPos( tp - oLen );
      s.SetActivePos( bp + cLen, true );
      s.Text = s.Text.slice( oLen, - cLen );
      s.SetAnchorPos( tp - oLen );	// 選択範囲を復帰
      $del = $end = true;

      // ヒットしたカッコを Tag プロパティ/JSON ファイル に保存
      if ( o !== setting.openBracket || c !== setting.closeBracket ) {
        setting.openBracket  = o;
        setting.closeBracket = c;
        if ( ioEnable && jsonName && sMode < 2 ) {	// JSON 書き込み
          IO.Serialize( setting, jsonName );
        }
        else if ( tagEnable ) {	// Tag 書き込み
          SetTag( setting, tagType, tagKey );
        }
      }
      break;
    }
  }
  return { setting : setting,  $del : $del,  $end : $end };
}


/**
 * 関数 GetTag( tagType, tagKey, property )
 * 指定された Tag の値を返す
 */
function GetTag( tagType, tagKey, property ) {
  try {
    var obj = ( typeof tagType === "object" ) ? tagType
            : ( tagType === 1 ) ? editor.ActiveDocument
            : ( tagType === 2 ) ? editor
            : ( tagType === 3 ) ? window
            : window;
    return ( obj.Tag.Exists( tagKey )
    && ( property ? property in obj.Tag( tagKey ) : true ) )
    ? property
      ? obj.Tag( tagKey )[ property ]
      : obj.Tag( tagKey )
    : null;
  } catch( e ) { Status = e;  return null; }
}

/**
 * 関数 SetTag( value, tagType, tagKey, property )
 * 指定された値を Tag に書き込む
 */
function SetTag( value, tagType, tagKey, property ) {
  try {
    var obj = ( typeof tagType === "object" ) ? tagType
            : ( tagType === 1 ) ? editor.ActiveDocument
            : ( tagType === 2 ) ? editor
            : ( tagType === 3 ) ? window
            : window;
    if ( property ) {
      if ( obj.Tag.Exists( tagKey ) ) {
        obj.Tag( tagKey )[ property ] = value;
      }
      else { obj.Tag( tagKey ) = { property: value }; }
    }
    else { obj.Tag( tagKey ) = value; }
  }
  catch( e ) { Status = e; }
  finally { return; }
}


/**
 * 関数 MultiFunction( Fn, arg1 )
 * マルチカーソル(複数選択範囲)に対応させる
 * 第1引数: Function; 選択範囲ごとに適用する処理の関数
 * 第2引数: Function に渡す引数をまとめた配列
 */
function MultiFunction( Fn, arg ) {
  var d = editor.ActiveDocument;
  var s = d.selection;

  // 矩形選択範囲は行に分ける
  s.Mode = meModeMulti;

  // 選択範囲の座標を取得
  var sCount = s.Count;
  var Sel = [];
  for ( var i = 0; i < sCount; i ++ ) {
    Sel[i] = {
      act: s.GetActivePos( i ),
      anc: s.GetAnchorPos( i )
    };
  }

  // 各選択範囲を処理;
  for ( var i = 0, diff = 0, dl; i < sCount; i ++ ) {
    dl = d.TextLength;
    s.SetActivePos( Sel[i].act + diff );
    s.SetAnchorPos( Sel[i].anc + diff );

    Fn( arg );	// AddDeleteBrackets_Main() 関数でカッコを追加/削除

    // Fn() の残した選択範囲(またはキャレット位置)を回収
    Sel[i].act = s.GetActivePos();
    Sel[i].anc = s.GetAnchorPos();
    diff += d.TextLength - dl;	// 文字数の増減量(累積)
  }

  // マルチカーソル(複数選択範囲)を復帰
  for ( var i = 0; i < sCount; i ++ ) {
    s.AddPos( Sel[i].anc, Sel[i].act );
  }
}

変更履歴[編集]

  • 1.0.5 (2020-06-28)
    • 「カッコを削除/追加」マクロを削除
    • マルチカーソル/複数選択範囲に対応
  • 1.0.4 (2019-05-03)
    • 「カッコを追加/削除」の変数の記述ミスによるエラーを修正
  • 1.0.3 (2019-04-07)
    • Quit() メソッドを削除して ZIP を更新(ソースコード内の年月日の表記はまま)
  • 1.0.2 (2019-03-19)
    • 「カッコを追加/削除」マクロを追加
    • ZIP をアップロード
  • 1.0.1 (2019-03-18)
    • 「カッコを削除/追加」マクロを追加
  • 1.0.0 (2019-03-14)
    • 「カッコをはずす」マクロの初版
スポンサーリンク