「カッコで囲う」の版間の差分

提供:MeryWiki
ナビゲーションに移動 検索に移動
(「カッコで囲う(ポップアップメニューあり)」と「引用符を追加/削除」を更新)
1行目: 1行目:
<div style="float:right">__TOC__</div>
= ダウンロード =
[[ファイル:カッコで囲う_ポップアップメニュー.png|link=]]


全部入りのソースをダウンロード → 「[[メディア:カッコで囲う.zip|カッコで囲う.zip]](アイコン入り)」 (最終更新 2018/10/29)  
'''全部入りの書庫をダウンロード''' → 「[[メディア:カッコで囲う.zip|カッコで囲う.zip]](アイコン入り)」 (最終更新 2019/03/28)  


: ZIP 書庫には以下のマクロの .JS ファイルと、 "マテリアルデザインっぽい" それぞれの専用アイコンがふくまれています。
: ZIP 書庫には以下のマクロの .JS ファイルと、それぞれ専用の "マテリアルデザインっぽい" アイコンがふくまれています。
* カッコで囲う(ポップアップメニューあり)
* カッコで囲う(ポップアップメニューあり)
* カッコで囲う(ポップアップメニューなし)
* カッコで囲う(ポップアップメニューなし)
* 引用符を追加/削除
* 引用符を追加/削除
[[ファイル:カッコで囲う_ポップアップメニュー.png|link=]]




= カッコで囲う(ポップアップメニューあり) =
= カッコで囲う(ポップアップメニューあり) =
(最終更新 2019/03/28)


ポップアップメニューから任意の '''カッコ''' や '''ダッシュ''' などの種類を選択して、選択範囲をカッコやいろいろな記号、文字列で囲います。 <br>  
ポップアップメニューから任意の '''カッコ''' や '''ダッシュ''' などの種類を選択して、選択範囲をカッコやいろいろな記号、文字列で囲います。 <br>  
17行目: 19行目:
行番号のドラッグでの複数行選択やトリプルクリックでの行選択などで末尾改行が含まれているばあい、さいごの改行を無視します。
行番号のドラッグでの複数行選択やトリプルクリックでの行選択などで末尾改行が含まれているばあい、さいごの改行を無視します。


* 既存のポップアップメニュー項目を減らしたいばあいは、ソースコード内の <u>''"m.Add( … );"''</u> の行を '''//''' でコメントアウトするとその項目をメニューから隠せます。
* '''既存のポップアップメニュー項目を減らしたいばあいは'''、ソースコード内の <u>''"m.Add( … );"''</u> の行頭に '''//''' をつけてコメントアウトするとその項目をメニューから隠せます。
 
* '''メニュー項目を増やしたいばあいは、'''
# ソースコード冒頭の配列 p1, p2 の21番目~30番目に任意の <u> , "記号"</u> を追加する
# 対応する番号をつけて <u>''"m.Add( "カッコ・記号 の名前" , XX );"''</u> の行を追加する
# 対応する番号をつけて <u>"case XX:"</u> を適当なグループに追加する
 


* メニュー項目を増やしたいばあいは、
作成にあたり、「'''引用の追加'''」マクロとキーアサイン集の「[[キーアサイン集#括弧で挟む|括弧で挟む]]」マクロのコードを参考にしました(※「引用の追加」マクロは 2018/10/14 付けで公開停止になりました)。
:# ソースコード冒頭の配列 p1, p2 の21番目~30番目に <u>"記号"</u> を追加する
:# 対応する番号をつけて <u>''"m.Add( … );"''</u> の行を追加する
:# 対応する番号をつけて <u>"case XX:"</u> を適当なグループに追加する


* 作成にあたり、「'''引用の追加'''」マクロとキーアサイン集の「[[キーアサイン集#括弧で挟む|括弧で挟む]]」マクロのコードを参考にしました(※「引用の追加」マクロは 2018/10/14 付けで公開停止になりました)。


姉妹版として [[カッコをはずす|「カッコをはずす」、「カッコを削除/追加」、「カッコを追加/削除」]]マクロ、[[引用符/コメント|「引用符/コメント」]]マクロがあります。


----
* [[カッコで囲う(ポップアップメニューあり)のソースコード|ソースコード]] は長すぎるのでページの下のほうに移動しました。
----




== メニューの項目 ==
== メニューの項目 ==
=== 任意の文字列 ===
 
=== 任意の文字列で囲う ===


文字入力用のダイアログで「前につける文字列」と「後ろにつける文字列」を指定します。
文字入力用のダイアログで「前につける文字列」と「後ろにつける文字列」を指定します。


* 任意の文字列1
* '''任意の文字列1'''
:: 選択範囲全体を一組の指定文字列で前後を囲います。
:: 選択範囲全体を'''一組の'''指定文字列で前後を囲います。
* 任意の文字列2
* '''任意の文字列2'''
:: 選択範囲内の各行ごとに指定文字列で前後を囲います。 <br> ソースコード冒頭の ''skip'' フラグで、複数行選択のさいに空白行をスキップするか指定してください。 <br> 「wiki 文字装飾タグ」以外のカッコ/記号で各行ごとに囲いたい場合は、「任意の文字列2」を使用してください。
:: 選択範囲内の'''各行ごとに'''指定文字列で前後を囲います。 <br> ソースコード冒頭の '''''skip''''' フラグで、複数行選択のさいに空白行をスキップするか指定してください。 <br> 「wiki 文字装飾タグ」以外のカッコ/記号で'''各行ごとに囲いたい場合は、「任意の文字列2」を使用してください。'''


改行コードとタブ文字は、それぞれ「'''\\\n'''」と「'''\\\t'''」で入力されたもの (注:¥記号3つ) を改行コードとタブ文字に置換するようにしてあります。
改行コードとタブ文字は、それぞれ「'''\\\n'''」と「'''\\\t'''」で入力されたもの (注:¥記号3つ) を改行コードとタブ文字に置換するようにしてあります。
: ※「\n」、「\t」と入力するとそのままの文字列「\n」、「\t」を返します。
: ※「\n」、「\t」と入力するとそのままの文字列「\n」、「\t」を返します。 <br> ※文字コードでの入力には非対応です(入力されたままの文字列を返します)。
文字コードでの入力には非対応です(入力されたままの文字列を返します)。




=== カッコ/記号 で囲う ===
=== カッコ/記号 で囲う ===


選択範囲を指定したカッコ/記号で囲います。 <br> 選択範囲なしで実行した場合は、カーソル位置にカッコ一組を挿入します。
選択範囲全体を指定したカッコ/記号で囲います。 <br> 選択範囲なしで実行した場合は、カーソル位置にカッコ一組を挿入します。


* (半角丸カッコ) 、 <半角山カッコ> 、 [半角角カッコ] 、 {半角波カッコ}、 <br> (全角丸カッコ) 、 「全角かぎカッコ」 、 『二重かぎカッコ』 、 【スミ付きカッコ】
* (半角丸カッコ) 、 <半角山カッコ> 、 [半角角カッコ] 、 {半角波カッコ}、 <br> (全角丸カッコ) 、 「全角かぎカッコ」 、 『二重かぎカッコ』 、 【スミ付きカッコ】
55行目: 57行目:


* ␣(半角丸カッコ)␣ 、 ␣"半角二重引用符"␣
* ␣(半角丸カッコ)␣ 、 ␣"半角二重引用符"␣
:: 選択範囲をカッコで囲い、さらに半角スペースで囲います。
:: 選択範囲をカッコまたは引用符で囲い、さらに半角スペースで囲います。


* ␣半角スペース␣
* ␣半角スペース␣
61行目: 63行目:


*  - 半角ハイフン -  、 ――ダッシュ×2―― 、 ~チルダ~
*  - 半角ハイフン -  、 ――ダッシュ×2―― 、 ~チルダ~
:: 「半角ハイフン」は、半角ハイフン=マイナス記号の両側に各1つずつ半角スペースがつきます(片側で半角3文字分)。<br> ※この3種については、選択範囲なしで実行したときに片側分だけを挿入します。
:: 「半角ハイフン」は、半角ハイフン=マイナス記号の両側に各1つずつ半角スペースがつきます(片側で半角3文字分)。<br> ※このグループにかぎり、選択範囲なしで実行したときは、片側分だけ "<span style="color:#c0c0c0;">␣</span>-<span style="color:#c0c0c0;">␣</span>" "――" "~" 記号を挿入します。




=== n文字ずつ前後を削除 ===
=== ひとつ削除 ===


* 1文字ずつ前後を削除 / 2文字ずつ前後を削除 / 3文字ずつ前後を削除
* 「[[カッコをはずす]]」マクロのコードを移植しました。<br> '''選択範囲全体の先頭/末尾'''があらかじめ用意された「対になるカッコ・記号」のペアであれば、その一組のペアを削除します。
:: 選択範囲内の先頭/末尾から指定の文字数ずつ削除します。
※ポップアップメニューの "カッコの追加用" の項目にない多種多様な記号のペアに対応します。<br> ※「カッコをはずす」マクロの "選択範囲の外側 (前と後) にあるカッコの削除" 機能はありません。




=== 挿入型コメントアウト ===
=== 任意の 文字列/文字数 を削除 ===


3種類の '''挿入型コメントアウト''' のメタ記号で選択範囲の文字列をコメントアウトできます。また、アンコメント用のコマンドでコメントアウト状態を解除できます。
「任意の文字列2」や「wiki用 マークアップ」と同様に、選択範囲内の論理行の'''各行頭と行末にたいして'''作用します。
* /* JavaScript 挿入型コメントアウト1 */
<br> ※選択範囲を "論理行単位" で拡張しないので、先頭行と末行においては行頭/行末ではなく「選択範囲の先頭/末尾」にたいして作用します。
:: 選択範囲の両端を '''/* ''' と ''' */''' で囲います。


* /* *JavaScript コメントアウト2(複数行) */
* '''任意の文字数を削除''' ではアラビア数字(半角/全角)以外で入力された文字列をすべて無視します。例えば「'''1a2あ'''」と入力された場合は、半角数字の「'''12'''」として扱います。
:: /* <br> ​ * 選択範囲の両端を "'''/* \n'''" と "'''\n */'''" で囲い、<br> ​ * 範囲内の各行の行頭に "''' * '''" を付けます。<br> ​ */
* '''任意の文字列を削除''' は簡易的な処理コードなので、正規表現を使用できません。<br> また、タブ文字の扱いは「任意の文字列2(追加)」の場合とおなじく「'''\\\t'''」で入力されたもの (注:¥記号3つ) をタブ文字('''\t''')として処理します。


* <nowiki><!-- XML 挿入型コメントアウト --></nowiki>
:: 選択範囲の両端を '''<nowiki><!-- </nowiki>''' と '''<nowiki> --></nowiki>''' で囲います。


=== 先頭/末尾の空白を削除 ===


※ "JS アンコメント" と "XML アンコメント" では、<u>先頭と末尾のコメントマークは選択範囲の両端でなければ削除されません</u>(選択範囲の先頭/末尾に半角スペース×1が付いていても、コメントマークといっしょに削除できます)。 <br> また、選択範囲内に2組以上のコメントがあると、正常にアンコメントできません。
* '''先頭/末尾から空白を削除'''
* '''先頭の空白を削除'''*'''末尾の空白を削除'''
:: 選択範囲内の論理行の'''各行頭と行末にたいして'''作用します。
:: 削除対象の空白文字は、「半角スペース」「全角スペース」「タブ文字」の3種です。<br> インデント(字下げ)の解除や、行末のムダな空白文字の削除に利用できます。


"JS アンコメント" は中間行の行頭記号(アスタリスクと全角/半角中黒)とその前後の半角スペースを削除します。これらの行頭記号を使用した箇条書きを範囲選択して実行すると、同様に行頭記号を削除します。
※選択範囲を "論理行単位" で拡張しないので、先頭行と末行においては行頭/行末ではなく「選択範囲の先頭/末尾」にたいして作用します。




=== wiki用 文字列装飾 ===
=== n文字ずつ前後を削除 ===


5種類の wiki用 文字列装飾タグ([https://www.mediawiki.org/wiki/Help:Formatting/ja テキスト整形マークアップ])を挿入できます。
* '''1文字ずつ前後を削除'''
* '''2文字ずつ前後を削除'''
* '''3文字ずつ前後を削除'''
:: '''選択範囲全体の先頭/末尾から'''指定の文字数ずつ削除します。


選択範囲内の各行ごとに指定のタグで前後を囲います。 <br> ソースコード冒頭の ''skip'' フラグで、複数行選択のさいに空白行をスキップするか指定してください。


* '''太字'''
* '''1文字ずつ前後を削除(外側)'''
:: 選択範囲の両端を '''<nowiki>'''</nowiki>'''(シングルクオート×3) で囲います。
:: '''選択範囲全体の前と後ろの'''各1文字を削除します。 <br> ※選択範囲が先頭行の行頭から始まっている場合や、最終行の行末で終わっている場合は、選択範囲内の先頭または末尾の1文字が削除されます。


* ''斜体(Italic)''
:: 選択範囲の両端を '''<nowiki>''</nowiki>'''(シングルクオート×2) で囲います。


* <u>下線</u>
=== JS / XML コメントアウト ===
:: 選択範囲の両端を '''<nowiki><u></nowiki>''' と '''<nowiki></u></nowiki>''' で囲います。
 
* <nowiki>[[内部リンク]]</nowiki>
:: 選択範囲の両端を '''<nowiki>[[</nowiki>''' と '''<nowiki>]]</nowiki>''' で囲い、<nowiki>[[リンク|ラベル]]</nowiki> 型の [https://www.mediawiki.org/wiki/Help:Links/ja#Internal_links 内部リンク] にします。
 
* <​nowiki>マークアップ回避<​/nowiki>
:: 選択範囲の両端を '''<​nowiki>''' と '''<​/nowiki>''' で囲います。


3種類の '''挿入型コメントアウト''' のメタ記号で選択範囲の文字列をコメントアウトできます。また、アンコメント用のコマンドでコメントアウト状態を解除できます。
* '''/* JavaScript 挿入型コメントアウト1 */'''
:: 選択範囲全体を '''/* ''' と ''' */''' で囲います。


※ wiki用 文字列装飾タグのままでは使いみちがないとおもいますので、HTML タグ <nowiki><a> </a></nowiki> などに書き換えてしまうか、ポップアップメニュー項目をコメントアウトしてしまうとよいでしょう(ZIP のソースでは初期状態でコメントアウトしてあります)。
* '''/* *JavaScript コメントアウト2(ブロックコメント) */'''
:: /* <br> ​ * (複数行の)選択範囲全体を "'''/* \n'''" と "'''\n */'''" で囲い、<br> ​ * 範囲内の各行の行頭に "''' * '''" を付けます。<br> ​ */


* '''<nowiki><!-- XML 挿入型コメントアウト --></nowiki>'''
:: 選択範囲全体を '''<nowiki><!-- </nowiki>''' と '''<nowiki> --></nowiki>''' で囲います。


= カッコで囲う (ポップアップメニューなし) =
簡易版です。 <br>
: ''c.f.''  追加と削除ができる機能強化版 → 「[[#引用符を追加/削除|引用符を追加/削除]]」
特定の種類のカッコを一発で追加する小マクロは[[キーアサイン集#括弧で挟む|キーアサイン集]]にもありますが、コードを改変して前後に付ける "カッコ" のかわりに "任意の文字列" を指定するばあいに「折り返し」表示と相性のよくない部分があります。
また、マクロ実行後のカーソル位置を選択範囲'''なし'''のときと'''あり'''のときとで変えたいばあいも、こちらのコードがよいでしょう。
<source lang="javascript">
#title = "( カッコ )"
#tooltip = "( カッコ ) で囲う"
// MeryWiki の マクロライブラリ >> キーアサイン集 の「括弧で挟む」を改変
// 選択範囲の前後にカッコ以外にも任意の文字列を追加するマクロとしても流用できます


var s = document.selection;
* '''JS アンコメント'''
* '''XML アンコメント'''
:: 上の3種のコメントアウトのメタ記号を削除してアンコメントします。


// 選択範囲の各座標を取得
※ <u>先頭と末尾のコメントマークは選択範囲の両端でなければ削除されません</u>(選択範囲の先頭/末尾に半角スペース×1が付いていても、コメントマークといっしょに削除できます)。 <br> また、選択範囲内に2組以上のコメントがあると、正常にアンコメントできません。
var ax = s.GetTopPointX( mePosLogical );
var ay = s.GetTopPointY( mePosLogical );


// 選択範囲のテキストを取得し、カッコを追加
"JS アンコメント" は中間行の行頭記号(アスタリスクと全角/半角中黒)とその前後の半角スペースを削除します。これらの行頭記号を使用した'''箇条書き'''を範囲選択して実行すると、同様に行頭記号を削除します。
var st = s.Text;
var pre = "("; // 前に付ける文字列
var sur = ")"; // 後ろに付ける文字列
s.Text = pre + st + sur;


// カーソルを移動、または範囲選択
※ プログラミングをしない人には使いみちがないとおもいますので、ZIP のソースでは初期状態でコメントアウトしてあります。
if ( ! st ) // 選択範囲なしだったばあい
  s.SetActivePos( s.GetActivePos() - sur.length ); // 後ろに付けた文字列 sur の前にカーソルを移動
else // 選択範囲があったばあい
  s.SetAnchorPoint( mePosLogical, ax, ay ); // カッコを含めて範囲選択
</source>




= 引用符を追加/削除 =
=== wiki用 マークアップ ===
「[[#カッコで囲う (ポップアップメニューなし)|カッコで囲う (ポップアップメニューなし)]]」の強化版です。


”引用符” を一発で追加する小マクロは 「マテリアルデザインっぽいアイコンと『小マクロ集』」 の 「[[マテリアルデザインっぽいアイコンと『小マクロ集』#”引用符”を追加|”引用符”を追加]]」 にもありますが、こちらのマクロでは 「引用符(または指定した文字列)で囲う」操作と「囲っている引用符を削除する」操作をトグルできます。<br> ※ 後ろにつける文字列の末尾が "'''\n'''" の場合はトグル不可。<!-- 2018/10/27: 一文追加 (sukemaru) -->
5種類の wiki用 文字列装飾タグ(マークアップ)([https://www.mediawiki.org/wiki/Help:Formatting/ja テキスト整形マークアップ])を挿入できます。
* 文字列指定は ”引用符” 以外の '''カッコ''' や '''HTML タグ''' などに変更できます。
* 選択範囲が複数行(論理行)にまたがっている場合に、選択範囲「全体」を一組の ”引用符” で囲うか、選択範囲内の「各行ごと」に ”引用符” で囲うかを選択することもできます。
* マクロ実行後のカーソル位置を選択範囲'''なし'''のときと'''あり'''のときとで変えたい場合には、数種類のパターンから選択できるようになっています。
<source lang="javascript">
#title = "''引用符'' で囲う"
#tooltip = "ダブルクォーテーションで囲う"
// -------------------------------------------------------------------
// 選択範囲を指定の文字列("引用符")で囲う
// 選択範囲がすでに "引用符" で囲われていたら引用符ふたつ "" を削除する
// 複数行の選択範囲のとき、さいごの改行はふくめない
// -------------------------------------------------------------------


/* ■文字列を指定 */
選択範囲内の'''各行ごとに'''指定のタグで前後を囲います。 <br> ソースコード冒頭の ''skip'' フラグで、複数行選択のさいに空白行をスキップするか指定してください。
var pre = '"'; // 前に付ける文字列
var sur = '"'; // 後に付ける文字列
  // ※ 文字列をダブルクォーテーション "" で囲うなら、中の「 " 」は要エスケープ 「'"'」=> 「"\""」
  // ※ 引用符以外の文字列を指定するなら 「'"'」=> 「"ほげ"」「"ふが"」
  // ※ 片側しか必要ないならいずれかを 「'"'」=> 「""」


* '''太字'''
:: 選択範囲全体を '''<nowiki>'''</nowiki>'''(シングルクオート×3) で囲います。


/* ■複数行フラグ */
* ''斜体(Italic)''
var multi = true;
:: 選択範囲全体を '''<nowiki>''</nowiki>'''(シングルクオート×2) で囲います。
  // ・multi = false; では、選択範囲「全体」の前後に文字列 pre / sur を追加
  // ・multi = true; では、選択範囲の「各行」ごとに文字列 pre / sur で囲う


* <u>下線</u>
:: 選択範囲全体を '''<nowiki><u></nowiki>''' と '''<nowiki></u></nowiki>''' で囲います。


/* ■挿入フラグ */
* <nowiki>[[内部リンク]]</nowiki>
var ins = false;
:: 選択範囲全体を '''<nowiki>[[</nowiki>''' と '''<nowiki>]]</nowiki>''' で囲い、<nowiki>[[リンク|ラベル]]</nowiki> 型の [https://www.mediawiki.org/wiki/Help:Links/ja#Internal_links 内部リンク] にします。
  // ・ins = false; では、選択範囲がないときはマクロを中止する
  //   また、■複数行フラグが有効 ( multi = true ) のときに、空行には挿入しない
  //   選択範囲の末尾に空行があった場合、マクロ実行後のカーソルの復帰位置が■終了後フラグの説明どおりにならないことがある
  // ・ins = true; では、選択範囲がないときにはカーソル位置に pre / sur を挿入する
  //  また、■複数行フラグが有効 ( multi = true ) のときに、空行にも挿入する
  // ※■複数行フラグが有効 ( multi = true ) のときは、空白文字だけの行は空行と見做す


/* ■終了後フラグ */
* <​nowiki>マークアップ回避<​/nowiki>
var endPos = 5; // 指定できる値は 0 ~ 5 ( 6 以上の値は 0 と同じ)
:: 選択範囲全体を '''<​nowiki>''' と '''<​/nowiki>''' で囲います。
  // 0. カーソルは "引用符" の後ろへ  (※範囲選択なし)
  // 1. カーソルは最後の "引用符" の中へ移動する  (※範囲選択なし)
  // 2. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ、
  //    あれば "引用符" の後ろへ移動する  (※範囲選択なし)
  // 3. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ移動  (※範囲選択なし)、
  //    あれば "引用符" を含めた全体を選択範囲にする  (※カーソルは選択範囲の後ろへ)
  // 4. "引用符" を含めた全体を選択範囲にする  (※カーソルは選択範囲の後ろへ)
  // 5. "引用符" を含めた全体を選択範囲にする  (※カーソル位置はマクロ実行前の側(先頭 or 末尾)へ)
  //
  //  ※ "引用符" を含めた選択範囲を残すようにすると、連続実行で 追加 <=> 削除 のトグルができる( 3 ~ 5 )
  //  ※ 複数フラグが有効 ( multi = true ) のとき、"引用符" の中へ移動する「0 と 1」は適さないとおもわれる
  //  ※ 「範囲選択なし」になる終了後フラグで "引用符" を削除したとき、カーソルの復帰位置は上の説明どおりにはならないことがある


// -------------------------------------------------------------------


Redraw = false;
※ wiki用 文字列装飾タグのままでは使いみちがないとおもいますので、HTML タグ <nowiki><a> </a></nowiki> などに書き換えてしまうか、ポップアップメニュー項目をコメントアウトしてしまうとよいでしょう(ZIP のソースでは初期状態でコメントアウトしてあります)。
 
// 選択範囲
var s = document.selection;
var anc = s.GetAnchorPos(); // 選択範囲の開始位置 (キャレットのない側)
var act = s.GetActivePos(); // 選択範囲の終了位置 (キャレットのある側)
var tp = ( anc < act ) ? anc : act; // 選択範囲の先頭位置
var bp = ( anc < act ) ? act : anc; // 選択範囲の末尾位置
 
// 選択範囲の先頭&末尾の各座標
var ty = s.GetTopPointY( mePosLogical );
var bx = s.GetBottomPointX( mePosLogical );
var by = s.GetBottomPointY( mePosLogical );
 
// 選択範囲の末尾が行頭 x = 1 にあるときの調整(末尾の改行を含めない)
if ( ty < by && bx == 1 ) {
  s.SetActivePos( tp );
  s.SetAnchorPos( bp - 1 );
}
 
// 選択範囲の文字列を取得
var st = s.Text;


// AddDelBrackets() で "引用符" を追加/削除
var t = AddDelBrackets( st, pre, sur );


// AddDelBrackets() 処理の前後で文字列に変化がないなら undo 履歴を残さない
=== Mery マクロ用 ===
if ( t == st ) {
  s.SetActivePos( act );
  s.SetAnchorPos( anc );
  Quit();
}


// "引用符" を追加/削除
選択範囲の文字列をコピーし、"二重引用符" つきにして、以下の各種の構文で囲います。
s.Text = t;


// case 0. この時点でカーソルは "引用符" のうしろ ※範囲選択なし(末尾調整されたままの位置)
※選択文字列のある行の'''ひとつしたの行'''に各構文を挿入します。
var dp = s.GetActivePos();
<br> ※選択範囲が複数行の場合は "'''+ \n +'''" でつなぎ合わせます。


* '''アウトプット'''
:: Outputbar.Writeln( "..." ); の構文にしてアウトプットバーを表示状態にします。
* '''アラート'''
:: Alert( "..." ); の構文にします。
* '''コンファーム'''
:: Confirm( "..." ); の構文にします。
* '''ステータス'''
:: Status = "..."; の構文にします。


// ■終了後フラグの指定動作  ※カーソルを移動/選択範囲を復旧
switch ( endPos ) {


  case 1: // カーソルは最後の "引用符" の中へ移動する  ※範囲選択なし
※ マクロのプログラミングをしない人には使いみちがないとおもいますので、ZIP のソースでは初期状態でコメントアウトしてあります。
    SearchLastBracket();
    break;


  case 2: // マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ
// あれば選択範囲の後ろへ移動する  ※範囲選択なし
    if ( ! st ) // マクロ実行前に選択範囲がなかったとき
      SearchLastBracket();
    else // マクロ実行前に選択範囲があったときは選択範囲の後ろへ
      MoveToEndPos();
    break;


  case 3: // マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ移動  ※範囲選択なし
== ソースコード ==
// あれば "引用符" を含めた全体を選択範囲にする  ※カーソルは選択範囲の後ろへ
    if ( ! st ) // マクロ実行前に選択範囲がなかったとき
      SearchLastBracket();
    else { // マクロ実行前に選択範囲があったとき
      MoveToEndPos();
      s.SetAnchorPos( tp ); // 先頭まで範囲選択
    }
    break;


  case 4: // "引用符" を含めた全体を選択範囲にする  ※カーソルは選択範囲の後ろへ
<source lang="javascript" style="height:80em; overflow:auto;">
    MoveToEndPos();
#title = "カッコ ..."
    s.SetAnchorPos( tp );
#tooltip = "カッコで囲う (ポップアップメニュー)"
    break;
#icon = "Mery用 マテリアルデザインっぽいアイコン.icl",255


  case 5: // "引用符" を含めた全体を選択範囲にする ※カーソル位置はマクロ実行前の側(先頭 or 末尾)へ
/**
    if ( anc <= act ) { // マクロ実行前のキャレットの位置が選択範囲の末尾だったとき
  * -----------------------------------------------------------------------------
      MoveToEndPos();
* カッコで囲う(ポップアップメニュー)
      s.SetAnchorPos( tp );
  * sukemaru, 2018/08/24 - 2019/03/28
    }
  * -----------------------------------------------------------------------------
    else { // マクロ実行前のキャレットの位置が選択範囲の先頭だったとき
*
      MoveToEndPos();
* ポップアップメニューからカッコの種類を選択して、選択範囲をカッコで囲う。
      s.SetActivePos( tp, true );
  * 公式 wiki のマクロライブラリより「引用の追加」と「括弧で挟む」のコードを参考にした
    }
*
    break;
 
  default:
    break;
}
 
// -------------------------------------------------------------------
 
// 関数 AddDelBrackets() カッコを 追加/削除
function AddDelBrackets( arg1, arg2, arg3 ) { // ← AddDelBrackets( t, pre, sur )
 
  // ■複数行フラグ ( multi ) 判定
  // 有効なら ( true ) 選択範囲 st を行で区切って配列 a に格納する
  var a = ( multi ) ? arg1.split( "\n" ) : [];
  // 無効なら ( false )  選択範囲の文字列全体 st をそのまま配列 a に格納する
  if ( ! multi )
    a.push( arg1 );
 
  for ( var i = 0; i < a.length; i ++ ) { // 「1行め」から繰りかえし処理
 
    // 選択範囲がカッコで囲われているとき (先頭と末尾の文字列をカッコと比較して一致したとき)
    if ( a[i].substr( 0, arg2.length ) == arg2 && a[i].substr( a[i].length - arg3.length, arg3.length ) == arg3 )
      // 各行のカッコを削除
      a[i] = a[i].slice( arg2.length, a[i].length - arg3.length );
 
    // 選択範囲がカッコで囲われていないとき
    // ■挿入フラグが有効 ( ins = true ) なら、または a[i] が空白文字列でないなら、前後にカッコをつける
    else if ( ins || ! a[i].match( /^[\s ]*$/g ) )
      a[i] = arg2 + a[i] + arg3;
    else
      // ■挿入フラグが無効 ( ins = false ) のときの空白文字列は、スルー(空白のまま)
      continue;
  }
  // 各行を "\n" で区切って連結しなおす
  return a.join( "\n" );
}
 
 
// 関数 SearchLastBracket() カーソルを最後の閉じカッコの前へ移動 ※範囲選択なし
function SearchLastBracket() {
  if ( t.length < st.length ) // カッコを削除したときは。先頭へ
    s.SetActivePos( tp );
  else { // カッコを追加したときは、選択範囲内の最後の閉じカッコの前へ
    if ( sur.length ) {
      s.SetAnchorPos( tp );
      s.SetActivePos( tp + s.Text.lastIndexOf( s.Text.match( sur.replace( /[$()*+.?\[\\\]^{|}]/g , "\\$&" ) ) ) );
    }
    else // 閉じカッコ sur が未指定 "")の場合は、先頭へ
      s.SetActivePos( tp );
  }
}
 
// 関数 MoveToEndPos() マクロ実行前に選択範囲があったとき、カーソルを元の選択範囲の末尾位置へ移動 ※範囲選択なし
function MoveToEndPos() {
  if ( ty < by && bx == 1 ) // 選択範囲の末尾調整をしていたときは
    s.SetActivePoint( mePosLogical, bx, by ); // カーソルは元の末尾位置に復帰
  else // 末尾調整をしていなかったときは
    s.SetActivePos( dp ); // カーソル位置はそのまま
}
</source>
<!--
*「引用符を追加/削除」の項目を追加 (2018/10/18 sukemaru)
* 終了後の動作コードを変更し、不自然な位置にキャレットが移動する不具合を修正した (2018/10/26 sukemaru)
  -->
 
 
= カッコで囲う(ポップアップメニューあり)のソースコード =
 
組み込み用コードをすべて追加済みの状態にしました。
 
<source lang="javascript">
#title = "カッコ..."
#tooltip = "カッコで囲う"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",255
 
// ポップアップメニューからカッコの種類を選択して、選択範囲をカッコで囲う。
// 公式wikiのマクロライブラリより「引用の追加」と「括弧で挟む」のコードを参考にした
// (2018/08/24 - 2018/10/29)
 
/*
  * ・複数行の選択範囲で末尾が改行 \n のとき、さいごの改行は除外する。
  * ・複数行の選択範囲で末尾が改行 \n のとき、さいごの改行は除外する。
  * ・非選択時には、それぞれことなる動作をする。
  * ・非選択時には、それぞれことなる動作をする。
  *  
  *  
* ※ 「任意の文字列」について ※
* ・「任意の文字列1」は選択範囲全体をひとくくりに、
*  「任意の文字列2」は選択範囲内の "各行ごと" で個別に、指定した文字列で前後を囲う。
* ・wiki 文字装飾タグ以外のカッコで "各行ごと" に囲いたい場合は、「任意の文字列2」を使用する。
* ・文字コードでの入力には非対応(入力されたままの文字列を返す)。
* ・改行コードとタブ文字は、それぞれ「\\\n」と「\\\t」で入力されたものを置換する。
*  パスの入力に配慮しただけの簡易的な置換処理なので、「\」を4つ以上かさねた場合を考慮していない。
*
* ※ 「wiki 文字装飾タグ」について ※
* ・選択範囲内の "各行ごと" で個別に、指定したタグで前後を囲う。
* ・空行にもマークアップタグを挿入する場合は、skip オプションを無効にすること。
*
* ※ JS/XML コメントアウト と アンコメント について ※
* ・「カッコで囲う」マクロでは行の中間部分だけをコメントアウトするので、
*  行単位でコメントアウトするなら「引用の追加」マクロが適する。
* ・「カッコで囲う」マクロでは行の先頭部分のコメントマークだけにしかマッチしないので、
*  コメント部分がインデント(字下げ)されている場合も「引用の追加」マクロが適する。
* ・ほかにも注意事項があるので、該当コード部分の注意書きを参照のこと。
*
* ※ 「ひとつ削除」について ※
* ・「開きカッコ」「閉じカッコ」の定義とは別に削除用の定義を使用して、
*  選択範囲の先頭と末尾の1組の「カッコ」を削除する。
*  各種カッコ、引用符のほかにも各種の記号のペア、半角空白などを削除対象とする。
*
* ※ 削除系のコマンドについて ※
* ・選択範囲がないときはポップアップメニュー上に表示しない。
*
* -----------------------------------------------------------------------------
  * ※ ポップアップメニューの項目は、m.Add( … ); の不要な行を行をコメントアウトすれば隠せる。
  * ※ ポップアップメニューの項目は、m.Add( … ); の不要な行を行をコメントアウトすれば隠せる。
  * (配列から削除する場合は中身だけ消して "" として空要素を残しておかないと、メニューや処理コードの ID と一致しなくなる)
  * (配列から削除する場合は中身だけ消して "" として空要素を残しておかないと
*  メニューや処理コードの ID と一致しなくなる)
*
  */
  */


// ■「任意の文字列2」と、wiki 文字装飾タグで、複数行の選択範囲内の空白行をスキップするか?
// ■「任意の文字列2」と、wiki 文字装飾タグで、複数行の選択範囲内の空白行をスキップするか?
var skip = true;
var skip = true; // (true; スキップする / false; スキップしない)
  // (skip = true; スキップする / skip = false; スキップしない)
 


// 開きカッコ p1 を配列で定義
// ■開きカッコ p1 を配列で定義する
var p1 = new Array( "" , // 以下 r = 1~10、11~20、21~ の ID 順
var p1 = new Array( "" , // 以下 r = 1~10、11~20、21~ の ID 順
   "(" ,  "<" ,  "[" ,  "{" ,  "(" ,  "「" ,  "『" ,  "【" ,  " (" ,  " (" ,
   "(" ,  "<" ,  "[" ,  "{" ,  "(" ,  "「" ,  "『" ,  "【" ,  " (" ,  " (" ,
   " \"" ,  " " ,  " - " ,  "――" ,  "~" ,  "'''" ,  "''" ,  "<u>" ,  "[[" , "<nowiki>" ,
   " \"" ,  " " ,  " - " ,  "――" ,  "~" ,  "'''" ,  "''" ,  "<u>" ,  "[[" , "<nowiki>" ,
   "" );
   "" , "" , "" , "" , "" );
// 閉じカッコ p2 を配列で定義
 
var p2 = new Array( "" , // 以下 1~10、11~20、21~ の ID 順
// ■閉じカッコ p2 を配列で定義する
var p2 = new Array( "" , // 以下 1~10、11~20、21~ の ID 順
   ")" ,  ">" ,  "]" ,  "}" ,  ")" ,  "」" ,  "』" ,  "】" ,  ") " ,  ") " ,
   ")" ,  ">" ,  "]" ,  "}" ,  ")" ,  "」" ,  "』" ,  "】" ,  ") " ,  ") " ,
   "\" " ,  " " ,  " - " ,  "――" ,  "~" ,  "'''" ,  "''" ,  "</u>" ,  "]]" , "</nowiki>" ,
   "\" " ,  " " ,  " - " ,  "――" ,  "~" ,  "'''" ,  "''" ,  "</u>" ,  "]]" , "</nowiki>" ,
   "" );
   "" , "" , "" , "" , "" );
 
 
var s = document.selection


// ポップアップメニュー項目の定義
// ポップアップメニュー項目の定義
var m = CreatePopupMenu();
var m = CreatePopupMenu(),
  sm1 = CreatePopupMenu(),
  sm2 = CreatePopupMenu(),
  sm3 = CreatePopupMenu();
var grayFlag = s.Text ? 0 : meMenuGrayed;
   // m.Add( "ラベル", r ); の各行は、任意に上下移動(並べ替え)してよいが、
   // m.Add( "ラベル", r ); の各行は、任意に上下移動(並べ替え)してよいが、
   // r の数値は上の配列の並び順やテキスト変換処理の case r: に対応しているので変更しないこと!
   // r の数値は上の配列の並び順やテキスト変換処理の case r: に対応しているので変更しないこと!


m.Add( "任意の文字列 (&E)", 50 ); // ダイアログのテキストボックス
/* 入力 ダイアログ */
m.Add( "任意の文字列 2 (&E)", 51 ); // 各行ごとに指定文字列で囲う(skip フラグを指定すること)
m.Add( "任意の文字列 で前後を囲う (&E) ...", 1050 );   // Enter the custom string(s)
m.Add( "任意の文字列 2 (&E) ...", 1051 ); // 各行ごとに指定文字列で囲う(skip フラグを指定すること)
 
/* 削除系コマンド */
if ( s.Text ) { // 選択範囲がないときは表示しない
  m.Add( "", 0, meMenuSeparator );
  m.Add( "▲ ひとつ削除 (&1)", 1038 );
  m.AddPopup( "● 削除 (&T)", sm1 );
    sm1.Add( "  先頭/末尾から任意の 文字列 を削除 (各行) (&Z) ...", 1053 );
    sm1.Add( "  先頭/末尾から任意の 文字数 を削除 (各行) (&X) ...", 1052 );
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "≫ 先頭/末尾から 空白 を削除 ≪ (各行) (&W)", 1037 );
    sm1.Add( "≫ 先頭の 空白 を削除   (各行) (&T)", 1035 );
    sm1.Add( "  末尾の 空白 を削除 ≪ (各行) (&B)", 1036 );
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "◀  1文字ずつ 前後を削除  ▶ (外側) (&0)", 1034 );
    sm1.Add( " ▶ &1文字ずつ前後を削除 ◀  (1)", 1031 );
    sm1.Add( " ▶ &2文字ずつ前後を削除 ◀  (2)", 1032 );
    sm1.Add( " ▶ &3文字ずつ前後を削除 ◀  (3)", 1033 );
}


/* カッコ */
m.Add( "", 0, meMenuSeparator );
m.Add( "", 0, meMenuSeparator );
m.Add( " ( 半角 小カッコ )  (&P)", 1 );
m.Add( " ( 半角 小カッコ )  (&P)", 1 ); // Parenthesis
m.Add( "< 半角 山カッコ > (&A)", 2 );
m.Add( " [ 半角 大カッコ ]  (&B)", 3 );
m.Add( " { 半角 中カッコ }  (&C)", 4 );
m.Add( "", 0, meMenuSeparator );
m.Add( "", 0, meMenuSeparator );
m.Add( "( 全角 小カッコ ) (&R)", 5 );
m.Add( "< 半角 山カッコ > (&A)", 2 ); // Angle brackets
m.Add( " [ 半角 大カッコ ]  (&B)", 3 ); // square Brackets
m.Add( " { 半角 中カッコ }  (&C)", 4 ); // Curly brackets
 
m.Add( "", 0, meMenuSeparator );
m.Add( "", 0, meMenuSeparator );
m.Add( "全角 かぎカッコ 」 (&K)", 6 );
m.Add( "全角 小カッコ ) (&R)", 5 );     // Round brackets
m.Add( "『 全角 二重かぎカッコ 』 (&W)", 7 );
m.Add( "【 全角 スミ付きカッコ 】 (&L)", 8 );
m.Add( "", 0, meMenuSeparator );
m.Add( "", 0, meMenuSeparator );
m.Add( "␣( 全角 小カッコ )␣ (&Z)", 9 );
m.Add( "全角 かぎカッコ 」 (&K)", 6 );   // Kakko
m.Add( "␣ ( 半角 小カッコ ) ␣ (&H)", 10 );
m.Add( "『 全角 二重かぎカッコ 』 (&W)", 7 ); // White corner brackets
m.Add( '␣ "  半角 引用符  " ␣ (&Q)', 11 );
m.Add( "【 全角 スミ付きカッコ 】 (&L)", 8 ); // Lenticular brackets
m.Add( "␣ 半角 スペース ␣ (&S)", 12 );


m.Add( "", 0, meMenuSeparator );
m.Add( "", 0, meMenuSeparator );
m.Add( " -  半角 ハイフン  -  (&-)", 13 );
m.Add( "␣( 全角 小カッコ )␣ (&F)", 9 ); // Full width parenthesis (w/ space)
m.Add( "―― 全角 ダッシュ ―― (&D)", 14 );
m.Add( "␣ ( 半角 小カッコ ) ␣ (&H)", 10 ); // Half-width parenthesis (w/ space)
m.Add( "~ 全角 チルダ ~ (&T)", 15 );
m.Add( '␣ "  半角 引用符  " ␣ (&Q)', 11 ); // double-Quotation mark (w/ space)
m.Add( "␣ 半角 スペース ␣ (&S)", 12 ); // Space


m.Add( "", 0, meMenuSeparator );
m.Add( "", 0, meMenuSeparator );
m.Add( "1文字ずつ前後を削除 (&1)", 31 );
m.Add( " -  半角 ハイフン  -  (&-)", 13 ); // hyphen-minus (w/ spaces)
m.Add( "2文字ずつ前後を削除 (&2)", 32 );
m.Add( "―― 全角 ダッシュ ―― (&D)", 14 );  // Dash
m.Add( "3文字ずつ前後を削除 (&3)", 33 );
m.Add( "~ 全角 チルダ ~ (&T)", 15 );        // Tilde
 
/* JS コメントアウト / XML コメントアウト */
// m.Add( "", 0, meMenuSeparator );
// m.Add( "/* *  JS コメントアウト 2  */ (&J)", 1041 ); // JavaScript comment out (block comment)
// m.Add( "/*  JS コメントアウト 1  */ (&V)", 1042 );  // jaVascript comment out
// m.Add( "▲ JS アンコメント (&U)", 1043, grayFlag ); // Uncomment
// m.Add( "", 0, meMenuSeparator );
// m.Add( "<!--  XML コメントアウト  --> (&X)", 1044 ); // Xml comment out
// m.Add( "▲ XML アンコメント (&M)", 1045, grayFlag ); // xMl uncomment


m.Add( "", 0, meMenuSeparator );
/* wiki マークアップ
m.Add( "/*  *  JS コメントアウト 2  */ (&J)", 34 );
  このブロックの項目は、複数行を選択しているとき「選択範囲の各行ごとに囲う」処理をおこなう
m.Add( "/*  JS コメントアウト 1 */ (&V)", 36 );
  (※ skip フラグを指定すること) */
m.Add( "JS アンコメント (&U)", 35 );
// m.Add( "", 0, meMenuSeparator );
m.Add( "", 0, meMenuSeparator );
// m.AddPopup( "wiki 文字修飾 (&W)", sm2 );
m.Add( "<!-- XML コメントアウト  --> (&X)", 38 );
//  sm2.Add( "''' wiki 太字 ''' (&B)", 16 ); // Bold
m.Add( "XML アンコメント (&M)", 39 );
//  sm2.Add( "''  wiki 斜体  ''  ( &I )", 17 ); // Italic
//  sm2.Add( "<u> wiki 下線 </u>  (&U)", 18 );   // Under line
//  sm2.Add( "[[  wiki リンク  ]] (&L)", 19 ); // Link
//  sm2.Add( "<nowiki> </nowiki>  (&N)", 20 );     // Nowiki


/* このブロックの項目は、複数行を選択しているとき「選択範囲の各行ごとに囲う」処理をおこなう
/* Mery マクロ用
  (skip フラグを指定すること) */
  以下の項目は、選択範囲の文字列をコピーして、一行下でそれぞれの構文で囲う */  
/* とりあえずコメントアウトしておく */  
// m.Add( "", 0, meMenuSeparator );
// m.Add( "", 0, meMenuSeparator );
// m.Add( "'''  wiki 太字  ''' (&O)", 16 );
// m.AddPopup( "Mery マクロ (&Y)", sm3 );
// m.Add( "''   wiki 斜体   '' (&I)", 17 );
//   sm3.Add( "アウトプット (&O)", 1060 ); // OutputBar.Writeln( ... )
// m.Add( "<u> wiki 下線 </u> (&\\)", 18 );
//   sm3.Add( "アラート (&A)", 1061 );   // Alert( ... )
// m.Add( "[[  wiki リンク  ]] (&@)", 19 );
//   sm3.Add( "コンファーム (&C)", 1062 ); // Confirm( ... )
// m.Add( "<nowiki> </nowiki> (&N)", 20 );
//   sm3.Add( "ステータス (&S)", 1063 ); // Status = ...


// m.Add( "", 0, meMenuSeparator );
// m.Add( "", 0, meMenuSeparator );
// m.Add( "キャンセル", 0 ); // Escキーでキャンセルできるのでアクセラレータなし
// m.Add( "キャンセル", 0 ); // Escキー でキャンセルできるのでアクセラレータなし
 


// ポップアップメニューを表示
// ポップアップメニューを表示
  var r = m.Track( mePosMouse = 1 ); // 選択されたメニュー項目のIDを r
// m.Track(0); ならキャレット位置、m.Track(1); ならカーソル位置にポップアップ
  // m.Track(0); ならキャレット位置、Track(1); ならカーソル位置にサブメニューがポップアップ
var r = m.Track( mePosMouse = 1 ); // 選択されたメニュー項目のIDを r に格納する


if ( r > 0 ) {
if ( r > 0 ) {
   Redraw = false;
   Redraw = false;
   var s = document.selection
 
   var anc = s.GetAnchorPos();        // 選択範囲の開始位置 (キャレットのない側)
  var act = s.GetActivePos();        // 選択範囲の終了位置 (キャレットのある側)
  var tp = ( anc < act ) ? anc : act; // 選択範囲の先頭位置
  var bp = ( anc < act ) ? act : anc; // 選択範囲の末尾位置
 
  if ( s.IsEmpty ) {          // 選択範囲がなければ
    var pos = s.GetActivePos(); // カーソル位置を取得
  }


   // マクロ実行前の選択範囲の各座標を取得
   // マクロ実行前の選択範囲の各座標を取得
   var ax = s.GetTopPointX( mePosLogical );
   var tx = s.GetTopPointX( mePosLogical );
   var ay = s.GetTopPointY( mePosLogical );
   var ty = s.GetTopPointY( mePosLogical );
   var bx = s.GetBottomPointX( mePosLogical );
   var bx = s.GetBottomPointX( mePosLogical );
   var by = s.GetBottomPointY( mePosLogical );
   var by = s.GetBottomPointY( mePosLogical );
  var anc = s.GetAnchorPos(); // 選択範囲の開始位置 (キャレットのない側)
  var act = s.GetActivePos(); // 選択範囲の終了位置 (キャレットのある側)
  var tp = ( anc < act ) ? anc : act; // 選択範囲の先頭位置  ( ax, ay )
  var bp = ( anc < act ) ? act : anc; // 選択範囲の末尾位置
  if ( !s.Text.length ) // 選択範囲がなければ
    var pos = s.GetActivePos(); // カーソル位置を取得


   // 選択範囲の末尾位置を調整(最後の \n を含めない)
   // 選択範囲の末尾位置を調整(最後の \n を含めない)
   if ( ! s.IsEmpty && bx == 1 && r != 4 ) { //※ { 中カッコ } のばあいは末尾の調整をしない
  // 選択範囲の末尾が行頭 x = 1 にあるばあい ~ ※ { 中カッコ } のばあいは末尾の調整をしない
     s.SetActivePos( bp - 1 );
   if ( ! s.IsEmpty && bx == 1 && r != 4 ) {
    s.EndOfLine( false, mePosLogical );
     s.SetActivePos( bp - 1 ); // 元の選択範囲の末尾より1行うえの末尾 // 先頭
     s.SetAnchorPos( tp );
     s.SetAnchorPos( tp );   // 元の選択範囲の先頭まで選択
   }
   }


472行目: 368行目:


   // IDごとのテキスト変換処理
   // IDごとのテキスト変換処理
   switch (r) {
   switch ( r ) {


     // カッコ
     // カッコ
     case 1:  case 2:  case 3:  case 4:  case 5:  case 6:
     case 1:  case 2:  case 3:  case 4:  case 5:  case 6:
     case 7:  case 8:  case 9:  case 10:  case 11:  case 12:
     case 7:  case 8:  case 9:  case 10:  case 11:  case 12:
       if ( pos ) {
    // case 21:  case 22:  case 23:  case 24:  case 25:
        document.Write( p1[r] + p2[r] );
       s.Text = p1[r] + st + p2[r]; // カッコ p1 & p2 で囲う
         s.SetActivePos( pos + p1[r].length );
 
      if ( pos ) { // 選択範囲がなければ
         s.SetActivePos( pos + p1[r].length ); // カーソルをカッコのなかに移動
       }
       }
       else {
       else { // 選択範囲があれば
         s.Text = p1[r] + st + p2[r];
         s.Text = p1[r] + st + p2[r]; // 選択範囲 st をカッコ p1 & p2 で囲う
         s.SetAnchorPos( tp );
         s.SetAnchorPos( tp ); // 選択範囲を復元
       }
       }
       break;
       break;
490行目: 388行目:
     // ハイフン、ダッシュ、チルダ
     // ハイフン、ダッシュ、チルダ
     case 13:  case 14:  case 15:
     case 13:  case 14:  case 15:
       if ( pos ) {
       if ( pos ) { // 選択範囲がなければ
         document.Write( p1[r] );
         document.Write( p1[r] ); // 片側分 p1 だけ挿入
       }
       }
       else {
       else { // 選択範囲があれば
         s.Text = p1[r] + st + p2[r];
         s.Text = p1[r] + st + p2[r]; // 選択範囲 st をダーシ p1 & p2 で囲う
        s.SetAnchorPos( tp );
         s.SetAnchorPos( tp ); // 選択範囲を復元
      }
      break;
 
 
    // n文字ずつ前後を削除
    case 31:  case 32:  case 33:
      if ( ! s.IsEmpty ) {
        var n;
        if ( r == 31 )  n = 1;
        else if ( r == 32 )  n = 2;
        else n = 3; // ( r == 33 )
        s.Text = st.slice( n, st.length - n );
         s.SetAnchorPos( tp );
       }
       }
       break;
       break;
516行目: 401行目:
     case 16:  case 17:  case 18:  case 20:
     case 16:  case 17:  case 18:  case 20:
       // 選択範囲内の「各行を囲う」処理をおこなう。
       // 選択範囲内の「各行を囲う」処理をおこなう。
      // 複数行選択で空白行をスキップするかは冒頭の skip フラグで決定する。
       // 選択範囲なしで実行するとタグの間がわかりづらくなるので全角スペースを挿入する。
       // 選択範囲なしで実行するとタグの間がわかりづらくなるので全角スペースを挿入する。
       if ( pos ) {
 
         document.Write( p1[r] + " " + p2[r] );
       if ( pos ) { // 選択範囲がなければ
         s.SetAnchorPos( pos + p1[r].length );
         document.Write( p1[r] + " " + p2[r] ); // p1 & p2 と全角スペースを挿入
         s.SetActivePos( s.GetAnchorPos() + 1, true );
         s.SetAnchorPos( pos + p1[r].length ); // カーソルをタグのなかに移動
         s.SetActivePos( s.GetAnchorPos() + 1, true ); // タグの中の全角スペースを範囲選択
       }
       }
       else {
       else { // 選択範囲があれば
         var ad = AddBrackets( st, p1[r], p2[r] );
         var ad = AddBrackets( st, p1[r], p2[r] ); // 選択範囲 st の各行を p1 & p2 で囲う
         if ( ad != st ) {
         if ( ad != st ) {
           s.Text = ad;
           s.Text = ad;
           s.SetAnchorPos( tp );
           s.SetAnchorPos( tp ); // 選択範囲を復元
         }
         }
         else {
         else { // テキストに変更なし ( skip && st.match( /^\s*$/g ) )
           s.SetActivePos( act );
           s.SetActivePos( act ); // 選択範囲を復元
           s.SetAnchorPos( anc );
           s.SetAnchorPos( anc );
         }
         }
536行目: 423行目:




     // wiki 文字装飾 ※ 内部リンク用タグ [[リンク|ラベル]]
     // wiki 文字装飾 ※ 内部リンク用タグ [[リンク|ラベル]]
     case 19:
     case 19:
       // 選択範囲内の「各行を囲う」処理をおこなう。
       // 選択範囲内の「各行を囲う」処理をおこなう。
       if ( pos ) {
      // 複数行選択で空白行をスキップするかは冒頭の skip フラグで決定する。
         document.Write( p1[r] + " | " + p2[r] );
 
         s.SetActivePos( pos + p1[r].length );
       if ( pos ) { // 選択範囲がなければ
         s.SetAnchorPos( s.GetActivePos() + " | ".length );
         document.Write( p1[r] + " | " + p2[r] ); // p1 & p2 と " | " を挿入
         s.SetActivePos( pos + p1[r].length ); // カーソルをカッコの中に移動
         s.SetAnchorPos( s.GetActivePos() + " | ".length ); // カッコの中を範囲選択
       }
       }
       else {
       else { // 選択範囲があれば
         var ad = AddWikiLink( st, p1[r], p2[r] );
         var ad = AddWikiLink( st, p1[r], p2[r] ); // 選択範囲 st の各行を [[str|str]] に変換
         if ( ad != st ) {
         if ( ad != st ) {
           s.Text = ad;
           s.Text = ad;
           s.SetActivePos( tp + p1[r].length );
           s.SetActivePos( tp + p1[r].length ); // p1 の後ろにカーソルを移動
         }
         }
         else {
         else { // テキストに変更なし ( skip && st.match( /^\s*$/g ) )
           s.SetActivePos( act );
           s.SetActivePos( act ); // 選択範囲を復元
           s.SetAnchorPos( anc );
           s.SetAnchorPos( anc );
         }
         }
      }
      break;
    // n文字ずつ前後を削除(内)
    case 1031:  case 1032:  case 1033:
      if ( ! s.IsEmpty ) { // 選択範囲があれば
        var n = ( r == 1031 ) ? 1 : // 1文字ずつ
                ( r == 1032 ) ? 2 : // 2文字ずつ
              /* r == 1033 */  3 ; // 3文字ずつ
        s.Text = st.slice( n, st.length - n ); // 選択範囲の両端から n 文字ずつ消す
        s.SetAnchorPos( tp ); // 選択範囲を復元
      }
      break;
    // 1文字ずつ前後を削除(外)
    case 1034:
      s.SetAnchorPos( tp - 1 ); // 選択範囲の先頭側を1文字拡張
      s.SetActivePos( bp + 1, true ); // 選択範囲の末尾側を1文字拡張
      s.Text = s.Text.slice( 1, - 1 ); // 先頭/末尾を1文字ずつ削除
      s.SetAnchorPos( tp - 1 ); // 選択範囲を復帰する
      break;
    // 行頭/行末の空白を削除 ※選択範囲を論理行単位に拡張はしない
    case 1035:  case 1036:  case 1037:
      if ( ! s.IsEmpty ) { // 選択範囲があれば
        var d = ( r == 1037 ) ? st.replace( /^[\s ]*|[\s ]*$/gm , "" ) : // 行頭/行末
                ( r == 1035 ) ? st.replace( /^[\s ]*/gm , "" ) : // 行頭
              /* r == 1036 */  st.replace( /[\s ]*$/gm , "" ) ; // 行末
        // 選択範囲に指定文字列がなかった場合 undo 履歴を残さない
        if ( d != st ) {
          s.Text = d; // 削除完了
          s.SetAnchorPos( tp ); // 選択範囲を復元
        }
      }
      break;
    // ひとつ削除 (※「カッコをはずす」マクロのコードを流用)
    case 1038:
      // 「ひとつ削除」用のカッコの定義
      var brackets = "()「」<>[]{}\"\"''()「」『』<>[]{}【】〖〗⦅⦆⦅⦆〚〛〔〕〘〙〈〉《》"
                  + "””’’〝〞〝〟‘’“”――~~〜〜  "
                  + "++--**\/\/##==%%::::@@@@※※††||……␣␣__"
                  + "○○●●□□■■◇◇◆◆▽▽▼▼△△▲▲☆☆★★"
                  + "←→→←↑↓↓↑←←→→↑↑↓↓"
                  + "¿?¡!‚‘‚’„“„”“„‘‚‹››‹«»»«——‐‐--"
                  + "﹁﹂﹃﹄︵︶︿﹀︽︾︹︺︷︸︻︼︗︘";
      var brackets2 = [
        "<b>" , "</b>" , "<i>" , "</i>" , "<u>" , "</u>" , "</" , ">" , "<" , "/>" ,
        "<!-- " , " -->" , "<!--" , "-->" ,
        "/** \n" , "\n */" , "/** \n" , "\n*/" , "/**\n" , "\n */" , "/**\n" , "\n*/" ,
        "/* \n" , "\n */" , "/* \n" , "\n*/" , "/*\n" , "\n */" , "/*\n" , "\n*/" ,
        "/** " , " */" , "/**" , " */" , "/* " , " */" , "/*" , " */" ,
        "'''''" , "'''''" , "'''" , "'''" , "''" , "''" , "[[" , "]]" , 
        "<nowiki>" , "</nowiki>" , "<span>" , "</span>" , "<div>" , "</div>" ,
        "<pre>" , "</pre>" , "<source lang=\"javascript\">" , "<\/source>"
      ];
      brackets = brackets2.concat( brackets.split( "" ) );
      var db = DeleteBrackets( st, brackets );
      if ( st != db ) {
        s.Text = db;
        s.SetAnchorPos( tp ); // 選択範囲を復帰する
      }
      else { // テキストに変更なしなら
        s.SetActivePos( act ); // 選択範囲を復元
        s.SetAnchorPos( anc );
       }
       }
       break;
       break;
559行目: 520行目:


     // /* * JavaScriptコメントアウト 2 */
     // /* * JavaScriptコメントアウト 2 */
     case 34:
     case 1041:
       // 選択範囲の先頭/末尾が行の途中にある状態でコメントアウトする場合は、改行を追加する。
/*
       var p1 = ( ax > 1 ) ? "\n/*\n" : "/*\n"; // */
*    基本的に1行めが行の先頭から始まることしか想定していないので、
*       あらかじめコメントアウトする文字列は、行単位でまとまったブロックにしておくとよい。
*    選択範囲の先頭/末尾が行の途中にある状態でコメントアウトする場合は、改行を追加する。
*/
       var p1 = ( tx > 1 ) ? "\n/*\n" : "/*\n"; // */
       var p2 = ( document.Text.charAt( bp ) != "\n" ) ? "\n */\n" : "\n */";
       var p2 = ( document.Text.charAt( bp ) != "\n" ) ? "\n */\n" : "\n */";
       var ast = " * ";
       var ast = " * ";
       if ( ax > 1 ) // 選択範囲の先頭座標が x = 1 でなければ改行させるので
       if ( tx > 1 ) { // 選択範囲の先頭座標が x = 1 でなければ改行させるので
         tp ++; // 選択範囲の復元用座標を調整
         tp ++; // 選択範囲の復元用座標を調整
      if ( pos ){
        document.Write( p1 + ast + p2 );
        s.SetActivePos( s.GetActivePos() - p2.length );
       }
       }
       else {
 
        s.Text = CommentOutJS( st, p1, p2, ast );
       // コメントアウト
         s.SetAnchorPos( tp );
//    s.Text = CommentOutJS( st, p1, p2, ast ); // コメントアウト(関数バージョン)
      /*  ※ JS コメントアウト の正規表現置換バージョンの検証は不十分 ※ */
      s.Text = p1 + st.replace( /^(.*)$/gm , ast + "$1" ) + p2;
 
      if ( pos ) { // 選択範囲がなければ
        s.SetActivePos( s.GetActivePos() - p2.length ); // カーソルをコメント枠のなかに移動
      }
      else { // 選択範囲があれば
         s.SetAnchorPos( tp ); // 選択範囲を復元
       }
       }
       break;
       break;
579行目: 549行目:
     /* JavaScript コメントアウト 1 */
     /* JavaScript コメントアウト 1 */
     // <!-- XML コメントアウト -->  
     // <!-- XML コメントアウト -->  
     case 36:  case 38:
     case 1042:  case 1044:
       var p1, p2;
       var p1, p2;
       if ( r == 36 ) { // /* JavaScript コメントアウト 1 */
       if ( r == 1042 ) { /* JavaScript コメントアウト 1 */
         p1 = " /* "; p2 = " */ ";
         p1 = " /* "; p2 = " */ ";
       }
       }
       else { // ( r == 38 ) // <!-- XML コメントアウト -->  
       else { // ( r == 1044 ) // <!-- XML コメントアウト -->  
         p1 = " <!-- "; p2 = " --> ";
         p1 = " <!-- "; p2 = " --> ";
       }
       }
       if ( pos ){
 
         document.Write( p1 + p2 );
       if ( pos ) { // 選択範囲がなければ
         s.SetActivePos( pos + p1.length );
         document.Write( p1 + p2 ); // コメントマーク p1 & p2 だけ挿入
         s.SetActivePos( pos + p1.length ); // カーソルをコメント枠のなかに移動
       }
       }
       else {
       else { // 選択範囲があれば
         s.Text = p1 + st + p2;
         s.Text = p1 + st + p2; // 選択範囲 st をコメントアウト
         s.SetAnchorPos( tp );
         s.SetAnchorPos( tp ); // 選択範囲を復元
       }
       }
       break;
       break;




// case 35: ※ JS アンコメント
    // JS アンコメント
       // case 34 と case 36: の /* JavaScriptコメント */ をアンコメントする。
       // case 1041 と case 1042: の /* JavaScriptコメント */ をアンコメントする。
      // 選択範囲内の各行頭のコメントマーク "/* "  と " * " と " */" のみマッチ。
      // 「カッコで囲う」では行の先頭部分のコメントマークだけにしかマッチしないので、
      //  コメント部分がインデントされている場合は「引用符/コメント」マクロのJSアンコメントを使うこと。
/*
* ・選択範囲に複数のコメントブロックがある場合を想定していない。
* ・中間行の行頭記号はアスタリスク「 * 」、全角中黒「・」、半角中黒「・」を削除対象とする。
*  (行頭記号と前後の半角スペース各1を削除する)
* ・JSコメントでない箇条書き文で実行した場合も行頭のビュレット「* ・ ・」を削除する。
*/
/* このタイプのコメントにたいしてもアンコメント処理する。 */


// case 39: ※ XMLアンコメント
    // XML アンコメント
       // case 38 の <!-- XMLコメント --> をアンコメントする。
       // case 1044 の <!-- XMLコメント --> をアンコメントする。
      // 選択範囲の先頭の " <!-- " と 末尾の " --> " のみマッチ。
      // 選択範囲に複数のコメントがあると正常にアンコメントしない。


     case 35:  case 39:
     case 1043:  case 1045:
       // 選択範囲の先頭と末尾のコメントマークを削除
       // 選択範囲の先頭と末尾のコメントマークを削除
       var dc
       var dc;
       if ( r == 35 ) // JS アンコメント
//    if ( r == 1043 ) {
         dc = UnCommentJS( st );
//      dc = UnCommentJS( st ); // JS アンコメント(関数バージョン)
       else // ( r == 39 ) // XMLアンコメント
//    }
         dc = st.replace( /^ ?<!-- ?| ?-- *>\ ?$/g , "" );
      /*  ※ JS アンコメントの正規表現置換バージョンの検証は不十分 ※ */
       if ( r == 1043 ) { // JS アンコメント(正規表現バージョン)
         dc = st.replace( /^ ?\/\*+ ?\n?|\n? ?\*+\/ ?$/gm , "" )
                  .replace( /^ ?(?:\*+|[・・]) ?/gm , "" );
      }
       else { // ( r == 1045 ) // XML アンコメント
         dc = st.replace( /^ ?<!-+ ?| ?-+ *>\ ?$/g , "" );
      }
 
       // 選択範囲にコメントマークがなかった場合 undo 履歴を残さない
       // 選択範囲にコメントマークがなかった場合 undo 履歴を残さない
       if ( dc == st ) {
       if ( dc == st ) { // アンコメント処理の前後でテキストが一致したら
         s.SetActivePos( act );
         s.SetActivePos( act ); // 選択範囲を復元
         s.SetAnchorPos( anc );
         s.SetAnchorPos( anc );
        break;
       }
       }
       s.Text = dc;
      else {
       s.SetAnchorPos( tp );
       s.Text = dc; // アンコメント完了
       s.SetAnchorPos( tp ); // 選択範囲を復元
      }
       break;
       break;




     // 任意の文字列を追加 ※テキストボックス
     // 任意の文字列を追加 ※テキストボックス
     case 50:  case 51:
     case 1050:  case 1051:
       // 文字コードには非対応
       // 文字コードには非対応
       // ダイアログのテキスト入力フィールドから文字列を取得
       // ダイアログのテキスト入力フィールドから文字列を取得
       var p1 = Prompt(
       var p1 = Prompt(
        "前につける文字列:\t改行=\\\\\\n ; タブ=\\\\\\t  (注:¥記号3つ)", ""
                  "前につける文字列:\t改行=\\\\\\n ; タブ=\\\\\\t  (注:¥記号3つ)", ""
      ).replace( /\\\\\\n/g , "\n" ).replace( /\\\\\\t/g , "\t" );
              ).replace( /\\\\\\n/g , "\n" ).replace( /\\\\\\t/g , "\t" );
       var p2 = Prompt(
       var p2 = Prompt(
        "後ろにつける文字列:\t改行=\\\\\\n ; タブ=\\\\\\t  (注:¥記号3つ)", ""
                  "後ろにつける文字列:\t改行=\\\\\\n ; タブ=\\\\\\t  (注:¥記号3つ)", ""
      ).replace( /\\\\\\n/g , "\n" ).replace( /\\\\\\t/g , "\t" );
              ).replace( /\\\\\\n/g , "\n" ).replace( /\\\\\\t/g , "\t" );
 
       if ( p1 || p2 ) {
       if ( p1 || p2 ) {
         if ( pos ) {
         if ( pos ) { // 選択範囲がなければ
           document.Write( p1 + p2 );
           document.Write( p1 + p2 ); //  p1 & p2 を挿入
           s.SetActivePos( pos + p1.length );
           s.SetActivePos( pos + p1.length ); //  カーソルをカッコのなかに移動
         }
         }
         else {
         else { // 選択範囲があれば
           if ( r == 50 ) //  「任意の文字列1」なら
           if ( r == 1050 ) //  「任意の文字列1」なら
             s.Text = p1 + st + p2;
             s.Text = p1 + st + p2; //    選択範囲 st 全体を p1 & p2 で囲う
           else { // ( r == 51 ) //  「任意の文字列2」なら
           else { // ( r == 1051 ) //  「任意の文字列2」なら
             var ab = AddBrackets( st, p1, p2 );
             var ab = AddBrackets( st, p1, p2 ); //    選択範囲 st の各行を p1 & p2 で囲う
             if ( ab != st )
             if ( ab != st )
               s.Text = ab;
               s.Text = ab;
             else
             else // テキストに変更なし ( skip && st.match( /^\s*$/g ) )
               s.SetActivePos( bp );
               s.SetActivePos( bp );
           }
           }
           s.SetAnchorPos( tp );
           s.SetAnchorPos( tp ); // 選択範囲を復元
        }
      }
      break;
 
 
    // 各行の前後から任意の文字数/文字列を削除 ※テキストボックス
    case 1052:  case 1053:
      if ( ! pos ) { // 選択範囲があれば
 
        if ( r == 1052 ) { // 「任意の 文字数 を削除」なら
          // ダイアログのテキスト入力フィールドから文字列を取得
          // ※ 半角に変換して数字以外の文字は削除
          var p1 = ToHalfWidth(
                      Prompt( "先頭(行頭)から削除する文字数 (数字のみ有効):", "" )
                  ).replace( /[^0-9]/g , "" );
          var p2 = ToHalfWidth(
                      Prompt( "末尾(行末)から削除する文字数 (数字のみ有効):", "" )
                  ).replace( /[^0-9]/g , "" );
          var dt = DeleteCharByNum( st, p1, p2 ); // 各行の先頭/末尾から指定文字数を削除
        }
 
        else { // ( r == 1053 ) // 「任意の 文字列 を削除」なら
        // ダイアログのテキスト入力フィールドから文字列を取得
          var p1 = Prompt(
                      "先頭(行頭)から削除する文字列:\tタブ = \\\\\\t  (¥記号3つ)", ""
                  ).replace( /\\\\\\t/g , "\t" );
          var p2 = Prompt(
                      "末尾(行末)から削除する文字列:\tタブ = \\\\\\t  (¥記号3つ)", ""
                  ).replace( /\\\\\\t/g , "\t" );
          var reg = new RegExp( "^" + Quote( p1 ) + "|" + Quote( p2 ) + "$", "gm" );
          dt = st.replace( reg , "" ); // 各行の先頭/末尾の指定文字列を削除
        }
 
        // 選択範囲に指定文字列がなかった場合 undo 履歴を残さない
        if ( dt != st ) {
          s.Text = dt; // 削除完了
          s.SetAnchorPos( tp ); // 選択範囲を復元
         }
         }
       }
       }
       break;
       break;
    // アウトプット / アラート / コンファーム / ステータス
    /**
    * 選択範囲の文字列 st をコピーして、1行下に
    * OutputBar.Writeln( "st" );
    * Alert( "st" );
    * Confirm( "st" );
    * Status = "st";
    * の行を追加する → 追加した行の移動は「行を上/下に移動」マクロで…
    */
    case 1060:  case 1061:  case 1062:  case 1063:
      s.SetActivePoint( mePosLogical, 1, by + 1 );
      // 選択範囲が複数行なら +"\n"+ でつなぐ
      var str = '"' + st.replace( /\n/g , '" + "\\n" + "' ) + '"';
      var sur = ( ( r == 1063 ) ? ";" : " );" ) + "\n";
      s.Text = ( ( r == 1060 ) ? "OutputBar.Writeln( " :
                ( r == 1061 ) ? "Alert( " :
                ( r == 1062 ) ? "Confirm( " :
                /* r == 1063 */  "Status = "
              ) + str + sur;
      // カッコの中の文字列を範囲選択する
      s.SetActivePos( s.GetActivePos() - sur.length );
      s.SetAnchorPos( s.GetActivePos() - str.length );
      // アウトプットの場合は、アウトプットバーを表示
      if ( r == 1060 ) {
        ScrollY = s.GetActivePointY( mePosView );
        OutputBar.Visible = true;
      }
      break;


     default:
     default:
659行目: 720行目:




// -------------------------------------------------------------------
// ------------------------------------------------------------
// 関数
// ------------------------------------------------------------


/* 関数 AddBrackets() */
/* 関数 AddBrackets() */
function AddBrackets( arg1, arg2, arg3 ) {
function AddBrackets( arg0, arg1, arg2 ) { // AddBrackets( st, p1[r], p2[r] )
   var a = arg1.split( "\n" );
   var a = arg0.split( "\n" ); // 選択範囲 st を "\n" で区切って配列 a に
   for ( var i = 0; i < a.length; i ++ ) {
   for ( var i = 0; i < a.length; i ++ ) {
     if ( skip && a[i].match( /^\s*$/g ) ) // skip = true のときは空白行をスキップ
     if ( ! pos && skip && a[i].match( /^\s*$/g ) ) {
      continue;
      continue; // skip = true のときは、空白行をスキップ
     a[i] = arg2 + a[i] + arg3; // 各行をカッコ p1 & p2 で囲う
    }
    // 空行にカッコを挿入する場合は全角スペースをはさむ
    var space = ( ( arg1.length && arg2.length ) && ( pos || ! a[i].length ) ) ? " " : "" ;
     a[i] = arg1 + space + a[i] + arg2; // 各行をカッコ p1 & p2 で囲う
   }
   }
   return a.join( "\n" );
   return a.join( "\n" );
}
}


/* 関数 AddWikiLink() */
/* 関数 AddWikiLink() */
function AddWikiLink( arg1, arg2, arg3 ) {
function AddWikiLink( arg0, arg1, arg2 ) { // AddWikiLink( st, p1[r], p2[r] )
   var a = arg1.split( "\n" );
   var a = arg0.split( "\n" ); // 選択範囲 st を "\n" で区切って配列 a に
   for ( var i = 0; i < a.length; i ++ ) {
   for ( var i = 0; i < a.length; i ++ ) {
     if ( skip && a[i].match( /^\s*$/g ) ) // skip = true のときは空白行をスキップ
     if ( ! pos && skip && a[i].match( /^\s*$/g ) ) {
      continue;
      continue; // skip = true のときは、空白行をスキップ
     a[i] =  arg2 + a[i] + "|" + a[i] + arg3; // 各行を [[str|str]] に変換
    }
    // 空行には全角スペースつきではさむ
    var bar = ( pos || ! a[i].length ) ? " | " : "|" ;
     a[i] =  arg1 + a[i] + bar + a[i] + arg2; // 各行を [[str|str]] に置換
  }
  return a.join( "\n" );
}
 
 
/* 関数 DeleteCharByNum( st, p1, p2 ) */
function DeleteCharByNum( str, p1, p2 ) {
  var a = str.split( "\n" );
  for ( var i = 0; i < a.length; i ++ ) {
    a[i] = a[i].slice( p1, a[i].length - p2 ); // 各行の先頭/末尾からの指定文字数を削除
   }
   }
   return a.join( "\n" );
   return a.join( "\n" );
}
/* 関数 DeleteBrackets( str, brackets ) */
// 選択範囲の先頭と末尾から1組のカッコを削除する
function DeleteBrackets( str, brackets ) {
  // ループ処理で「対になるカッコ」と一致するかチェック
  for ( var i = 0, len = brackets.length; i < len; i ++ ) {
    if ( i % 2 == 1 || ! brackets[i].length ) {
      continue;
    }
    var o = brackets[ i ]; // 開きカッコ
    var c = brackets[ i + 1 ]; // 閉じカッコ
    // 選択範囲内の先頭と末尾が「対になるカッコ」のとき
    if ( str.length >= o.length + c.length
        && str.slice( 0, o.length ) == o
        && str.slice( - c.length ) == c ) {
      str = str.slice( o.length, - c.length ); // 先頭/末尾のカッコを削除
      break;
    }
  } // end for
  return str;
}
/* 関数 quote( str ) */
// 『JavaScript/正規表現 - Wikibooks』より
// https://ja.wikibooks.org/wiki/JavaScript/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE
//
// PerlのquotemetaやRubyのRegExp.quoteのように、()や[]など正規表現のメタ文字と解釈される可能性のある文字をエスケープして返す関数は、Stringオブジェクトのreplaceメソッドを使用して簡単に作成することができます。
function Quote( str ) {
    return str.replace( /\W/g, function( $0 ) {
        return '\\' + $0;
    } );
};
/**
* 全角から半角への変革関数 toHalfWidth( strVal )
* 入力値の英数記号を半角変換して返却
* [引数]  strVal: 入力値
* [返却値] String(): 半角変換された文字列
*/
// https://webllica.com/add-comma-as-thousands-separator/ より
function ToHalfWidth( strVal ){
  // 半角変換
  var halfVal = strVal.replace( /[!-~]/g,
    function( tmpStr ) {
      // 文字コードをシフト
      return String.fromCharCode( tmpStr.charCodeAt(0) - 0xFEE0 );
    }
  );
  return halfVal;
}




// -----------------------------------------------------------------------------
// 以下の2つの関数は破棄してよいかも
// (switch - case 文の中で replace メソッドでの置換処理に変更した)
// -----------------------------------------------------------------------------
/*  
/*  
  * 関数 CommentOutJS()
  * 関数 CommentOutJS()
688行目: 827行目:
  */
  */
function CommentOutJS( arg1, arg2, arg3, arg4 ) {
function CommentOutJS( arg1, arg2, arg3, arg4 ) {
   var a = arg1.split( "\n" );
   var a = arg1.split( "\n" ); // 選択範囲 st を "\n" で区切って配列 a に
   for ( var i = 0; i < a.length; i ++ )
   for ( var i = 0; i < a.length; i ++ ) // 「1行め」から繰りかえし処理
     a[i] = arg4 + a[i]; // 各行の先頭に " * " を追加
     a[i] = arg4 + a[i]; // 各行の先頭に " * " を追加する
   // 各行を "\n" で区切って連結し、先頭に "/*\n"、末尾に "\n */" を追加
 
   // 各行を "\n" で区切って連結し、先頭に "/*\n"、末尾に "\n */" を追加する
   return arg2 + a.join( "\n" ) + arg3;
   return arg2 + a.join( "\n" ) + arg3;
}
}


/*  
/*  
  * 関数 UnCommentJS()  
  * 関数 UnCommentJS( arg1 )  
  * 基本的にこのかたちのコメントブロックしか想定していない。
  * 基本的にこのかたちのコメントブロックしか想定していない(インデントには非対応)。
  * また、複数のコメントブロックがある場合を想定していない。
  * また、複数のコメントブロックがある場合を想定していない。
  * 中間行の行頭記号はアスタリスク「*」と中黒「・」「・」を削除対象とする。
  * 中間行の行頭記号はアスタリスク「*」と中黒「・」「・」を削除対象とする。
  */  
  */  
function UnCommentJS( arg1 ) {
function UnCommentJS( arg1 ) {
   var re1 = "^ ?\\/\\*+ ?\\n?"; // 先頭行のコメントマークの正規表現
 
   var re2 = "\\n? ?\\*+\\/ ?$"; // 末行のコメントマークの正規表現
   var re1 = "^ ?\\/\\*+ ?\\n?"; // 先頭行のコメントマークの正規表現
   var re2 = "\\n? ?\\*+\\/ ?$"; // 末行のコメントマークの正規表現
   var reg = new RegExp( re1 + "|" + re2 , "g" ); // 正規表現 / … /g に変換
   var reg = new RegExp( re1 + "|" + re2 , "g" ); // 正規表現 / … /g に変換
   var re3 = /^ ?(\*+|[・・]) ?/; // 中間行の行頭記号の正規表現
   var re3 = /^ ?(\*+|[・・]) ?/; // 中間行の行頭記号の正規表現
   var a = arg1.split( "\n" ); // 選択範囲 st を "\n" で区切って配列 a に
   var a = arg1.split( "\n" ); // 選択範囲 st を "\n" で区切って配列 a に
 
   // 中間行の行頭記号を削除する
   // 中間行の行頭記号を削除する
   for ( var i = 0; i < a.length; i ++ ) {
   for ( var i = 0; i < a.length; i ++ ) { // 「1行め」から繰りかえし処理
     if ( a[i].match( reg ) ) // 先頭行と末行のコメントマークがある行はスキップ
     if ( a[i].match( reg ) ) // 先頭行と末行のコメントマークがある行はスキップ
       continue;
       continue;
     a[i] = a[i].replace( re3 , "" ); // 中間行の行頭記号を削除
     a[i] = a[i].replace( re3 , "" ); // 中間行の行頭記号を削除
   }
   }
   // 各行を "\n" で区切って連結し、先頭行と末行のコメントマークを削除
   // 各行を "\n" で区切って連結し、先頭行と末行のコメントマークを削除
   return a.join( "\n" ).replace( reg , "" );
   return a.join( "\n" ).replace( reg , "" );
}
}
</source>
</source>
<br>


= カッコで囲う (ポップアップメニューなし) =
(最終更新 2018/10/26)


= 人柱用 追加コード =
簡易版です。 <br>
「カッコで囲う (ポップアップメニューあり)」のポップアップメニューの項目に
: ''c.f.'' 追加と削除ができる機能強化版 → 「[[#引用符を追加/削除|引用符を追加/削除]]」
* 「行頭/行末から任意の '''文字数''' を削除」
* 「行頭/行末から任意の '''文字列''' を削除」
のふたつを追加します。 <br>


*「任意の文字列2」や「wiki 用文字修飾タグ」と同様に、選択範囲内の論理行の各行頭と行末にたいして作用します(選択範囲を論理行単位で拡張しないので、先頭行と末行においては行頭/行末ではなく「選択範囲の先頭/末尾」にたいして作用します)。
特定の種類のカッコを一発で追加する小マクロは[[キーアサイン集#括弧で挟む|キーアサイン集]]にもありますが、コードを改変して前後に付ける "カッコ" のかわりに "任意の文字列" を指定するばあいに「折り返し」表示と相性のよくない部分があります。
*「任意の文字数を削除」ではアラビア数字以外で入力された文字列をすべて排除します。例えば「'''1a2あ'''」と入力された場合は、「'''12'''」として扱います。
*「任意の文字列を削除」は簡易的な処理コードなので、正規表現を使用できません。<br> また、タブ文字の扱いは「任意の文字列2(追加)」の場合とおなじく「'''\\\t'''」で入力されたもの (注:¥記号3つ) をタブ文字('''\t''')として処理します。
<br>
作ってみたものの使う機会にとぼしく、動作検証が不十分なままなので<b style="color:#c00;">人柱版</b>としてコードだけ置いておきます。(2018/11/19 sukemaru)


また、マクロ実行後のカーソル位置を'''選択範囲なし'''のときと'''選択範囲あり'''のときとで変えたいばあいも、こちらのコードがよいでしょう。


== 任意の文字数/文字列を削除 ==
▼'''m.Add( ... );''' のグループ内に追加(位置は任意で)▼
<source lang="javascript">
<source lang="javascript">
/* 以下の2項目は動作検証不十分 */  
#title = "( カッコ )"
// m.Add( "", 0, meMenuSeparator );
#tooltip = "( カッコ ) で囲う"
m.Add( "行頭/行末から任意の 文字数 を削除 (&Y)", 52 );
// MeryWiki の マクロライブラリ >> キーアサイン集 の「括弧で挟む」を改変
m.Add( "行頭/行末から任意の 文字列 を削除 (&Z)", 53 );
// 選択範囲の前後にカッコ以外にも任意の文字列を追加するマクロとしても流用できます
 
var s = document.selection;
 
// 選択範囲の各座標を取得
var ax = s.GetTopPointX( mePosLogical );
var ay = s.GetTopPointY( mePosLogical );
 
// 選択範囲のテキストを取得し、カッコを追加
var st = s.Text;
var pre = "("; // 前に付ける文字列
var sur = ")"; // 後ろに付ける文字列
s.Text = pre + st + sur;
 
// カーソルを移動、または範囲選択
if ( ! st ) // 選択範囲なしだったばあい
  s.SetActivePos( s.GetActivePos() - sur.length ); // 後ろに付けた文字列 sur の前にカーソルを移動
else // 選択範囲があったばあい
  s.SetAnchorPoint( mePosLogical, ax, ay ); // カッコを含めて範囲選択
</source>
</source>
<br>
= 引用符を追加/削除 =
(最終更新 2019/03/28)
「[[#カッコで囲う (ポップアップメニューなし)|カッコで囲う (ポップアップメニューなし)]]」の機能強化版です。
”引用符” を一発で追加する小マクロは 「マテリアルデザインっぽいアイコンと『小マクロ集』」 の 「[[マテリアルデザインっぽいアイコンと『小マクロ集』#”引用符”を追加|”引用符”を追加]]」 にもありますが、こちらのマクロでは 「引用符(または指定した文字列)で囲う」操作と「囲っている引用符を削除する」操作を'''トグル'''できます。<br> ※ 後ろにつける文字列の末尾が "'''\n'''" の場合はトグル不可。
<u>'''選択範囲の外側'''(前と後ろ)が ”引用符” の場合も、(自動的に検出して)削除することができます。</u>
* 文字列指定は ”引用符” 以外の '''カッコ''' や '''HTML タグ''' などの任意の文字列に変更できます。
* 選択範囲が複数行(論理行)にまたがっている場合に、'''選択範囲全体''' を一組の ”引用符” で囲うか、選択範囲内の「'''各行ごと'''」に ”引用符” で囲うかを選択することもできます。
* マクロ実行後のカーソル位置を'''選択範囲なし'''のときと'''選択範囲あり'''のときとで変えたい場合には、数種類のパターンから選択できるようになっています。
== ソースコード ==
<source lang="javascript" style="height:80em; overflow:auto;">
#title = "''引用符'' で囲う"
#tooltip = "ダブルクォーテーションで囲う"
#icon = "Mery用 マテリアルデザインっぽいアイコン.icl",100
/**
* -----------------------------------------------------------------------------
* "引用符" で囲う
* sukemaru (2018/10/19 - 2019/03/26)
* -----------------------------------------------------------------------------
* 選択範囲を指定の文字列("引用符")で囲う
* 選択範囲がすでに "引用符" で囲われていたら引用符ふたつ "" を削除する
* 選択範囲外側の外側が "引用符" のときも削除できる
* 選択範囲が複数行のとき、さいごの改行はふくめない
*
*/
// ---------- ▼ 設定項目 ▼ ----------
var pre = '"'; // 前に付ける文字列
var sur = '"'; // 後に付ける文字列
  /**
  * ■"引用符" の文字列を指定
  *
  * ※ 文字列をダブルクォーテーション "" で囲うなら、中の「 " 」は要エスケープ 「'"'」=> 「"\""」
  * ※ 引用符以外の文字列を指定するなら 「'"'」=> 「"ほげ"」「"ふが"」
  *  ただし、改行 \n を含む文字列は想定していない(カーソル位置の復帰が…)。
  * ※ 片側しか必要ないならいずれかを 「'"'」=> 「""」にしてよいが、実行後のカーソルの復帰位置が…
  */
var deleteOuter = true;
  /**
  *  ■外側削除フラグ
  *
  * ・false で選択範囲内側の先頭/末尾の文字列 pre / sur のみを削除。
  * ・true で選択範囲外側の前後の文字列 pre / sur も削除対象にする。
  * ※ 「複数行フラグ」の true / false によらず、選択範囲全体の外側が対象。
  */
var multiLine = true;
  /**
  * ■複数行フラグ
  *
  * ・false で選択範囲「全体」の前後に文字列 pre / sur を追加
  * ・true で選択範囲の「各行」ごとに文字列 pre / sur で囲う
  */
var insert = false;
  /**
  * ■挿入フラグ
  *
  * ・false では、選択範囲がないときはマクロを中止する
  *  また、「複数行フラグ」が有効のときに、空行には挿入しない
  *  選択範囲の末尾に空行があった場合、マクロ実行後のカーソルの復帰位置が
  *  「終了後フラグ」の説明どおりにならないことがある
  * ・true では、選択範囲がないときにはカーソル位置に pre / sur を挿入する
  *  また、「複数行フラグ」が有効のときに、空行にも挿入する
  * ※ 「複数行フラグ」が有効 のときは、空白文字だけの行は空行と見做す
  */
var endPos = 5; // 指定できる値は 0 ~ 5 ( 6 以上の値は 0 と同じ)
  /**
  * ■終了後フラグ
  *
  * 0. カーソルは "引用符" の後ろへ。  (※範囲選択なし)
  * 1. カーソルは最後の "引用符" の中へ移動する。  (※範囲選択なし)
  * 2. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ。  (※要 「挿入フラグ」 = true)
  *    あれば "引用符" の後ろへ移動する。  (※範囲選択なし)
  * 3. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ移動。  (※範囲選択なし)、
  *    あれば "引用符" を含めた全体を選択範囲にする。  (※カーソルは選択範囲の後ろへ)
  * 4. "引用符" を含めた全体を選択範囲にする。  (※カーソルは選択範囲の後ろへ)
  * 5. "引用符" を含めた全体を選択範囲にする。  (※カーソル位置はマクロ実行前の側(先頭 or 末尾)へ)
  *
  *  ※ "引用符" を含めた選択範囲を残すようにすると、
  *    連続実行で 追加 <=> 削除 のトグルができる。( 3 ~ 5 )
  *    ただし、後に付ける文字列の末尾が "\n" の場合、連続実行での 追加 <=> 削除 のトグルはできない。
  *  ※ "マクロ実行前に範囲選択がなければ~" は「挿入フラグ」が有効のときだけ。
  *  ※ 選択範囲を残す場合、マクロ実行前の選択範囲末尾に改行 \n を含んでいたときには
  *  ※ 「複数フラグ」が有効のとき、 "引用符" の中へ移動する「0 と 1」は適さないとおもわれる。
  *  ※ "範囲選択なし" になる「終了後フラグ」で "引用符" を削除したとき、
  *      カーソルの復帰位置は上の説明どおりにはならないことがある。
  */
// ---------- ▲ 設定項目 ▲ ----------




▼␣␣␣␣'''default:''' ␣␣␣␣␣␣'''break;''' の上に追加▼
var d = document;
<source lang="javascript">
var s = document.selection; // 選択範囲
    // 各行の前後から任意の文字数/文字列を削除 ※テキストボックス
    case 52:  case 53:
      if ( ! pos ) { // 選択範囲があれば


        // 「任意の文字数を削除」
// 挿入フラグが無効 ( insert = false ) で 選択範囲がないなら中止
        if ( r == 52 ) {
if ( d.ReadOnly || ! insert && s.IsEmpty ) {
          // ダイアログのテキスト入力フィールドから文字列を取得
  Quit();
          // 半角に変換して数字以外の文字は削除
}
          var p1 = ToHalfWidth(
            Prompt( "行頭から削除する文字数 (数字のみ有効):", "" )
          ).replace( /[^0-9]/g , "" );
          var p2 = ToHalfWidth(
            Prompt( "行末から削除する文字数 (数字のみ有効):", "" )
          ).replace( /[^0-9]/g , "" );
          // 各行の先頭/末尾から指定文字数を削除
          var dt = DeleteCharByNum( st, p1, p2 );
        }


        // 「任意の文字列を削除」
// 選択範囲がある または 挿入フラグが有効 ( s.length || insert = true ) なら ~
        else { // ( r == 53 )
Redraw = false;
        // ダイアログのテキスト入力フィールドから文字列を取得
        var p1 = Prompt(
          "行頭から削除する文字列:\tタブ=\\\\\\t  (注:¥記号3つ)", ""
        ).replace( /\\\\\\t/g , "\t" );
        var p2 = Prompt(
          "行末から削除する文字列:\tタブ=\\\\\\t  (注:¥記号3つ)", ""
        ).replace( /\\\\\\t/g , "\t" );
        var reg1 = new RegExp( "^" + Quote( p1 ) , "gm" );
        var reg2 = new RegExp( Quote( p2 ) + "$" , "gm" );
        // 各行の先頭/末尾の指定文字列を削除
        dt = st.replace( reg1 , "" ).replace( reg2 , "" );
        }


        // 選択範囲に指定文字列がなかった場合 undo 履歴を残さない
var delCount = 0; // 削除フラグ
        if ( dt != st ) {
var addCount = 0; // 追加フラグ
          s.Text = dt; // 削除完了
var isAdjusted = false; // 末尾調整フラグ
          s.SetAnchorPos( tp ); // 選択範囲を復元
        }
      }
      break;
</source>


// 選択範囲の各座標
var anc = s.GetAnchorPos();
var act = s.GetActivePos();
var tp = ( anc < act ) ? anc : act; // 選択範囲の先頭位置
var bp = ( anc < act ) ? act : anc; // 選択範囲の末尾位置
// var ty = s.GetTopPointY( mePosLogical );
var bx = s.GetBottomPointX( mePosLogical );
var by = s.GetBottomPointY( mePosLogical );


▼ソースコード末尾(末行)に追加▼
// 選択範囲の末尾が行頭 x = 1 にあるときの調整(末尾の改行を含めない)
<source lang="javascript">
if ( tp < bp && bx == 1 ) {
/* 関数 DeleteCharByNum( st, p1, p2 ) */
   s.SetActivePos( tp );
  // 各行の先頭/末尾からの指定文字数を削除
   s.SetAnchorPos( bp - 1 );
function DeleteCharByNum( str, p1, p2 ) {
   isAdjusted = true;
   var a = str.split( "\n" );
   for ( var i = 0; i < a.length; i ++ )
    a[i] = a[i].slice( p1, a[i].length - p2 );
   return a.join( "\n" );
}
}


// 選択範囲の文字列を取得
var st = s.Text;


/* 関数 quote( str ) */
// 外側フラグが有効のとき
// 『JavaScript/正規表現 - Wikibooks』より
if ( deleteOuter ) {
// ref. https://ja.wikibooks.org/wiki/JavaScript/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE
  // 選択範囲外側の前後の文字列が "引用符" なら削除する
// PerlのquotemetaやRubyのRegExp.quoteのように、()や[]など正規表現のメタ文字と解釈される可能性のある文字をエスケープして返す関数は、Stringオブジェクトのreplaceメソッドを使用して簡単に作成することができます。
  // ※削除したときの戻り値は delCount = 1
  DeleteOuterBrackets( st, pre, sur );
}


function Quote( str ) {
// AddDelBrackets() で "引用符" を追加/削除
     return str.replace( /\W/g, function( $0 ) {
if ( ! delCount ) {
        return '\\' + $0;
  var ad = AddDelBrackets( st, pre, sur );
     } );
  if ( delCount || addCount ) {
     s.Text = ad;
  }
  // AddDelBrackets() 処理の前後で文字列に変化がないなら
  // 選択範囲を復帰する(undo 履歴を残さない)
  else {
    s.SetActivePos( act );
    s.SetAnchorPos( anc );
     Quit();
  }
}
}
// カーソルは "引用符" のうしろ
var dp = s.GetActivePos();
// 終了後フラグの指定動作  ※カーソルを移動/選択範囲を復旧
FinalSelection();
Redraw = true;
Quit();


// ---------- ▼ 関数 ▼ ----------


/**
/**
  * 全角から半角への変革関数 toHalfWidth( strVal )
  * 関数 FinalSelection()  
  * 入力値の英数記号を半角変換して返却
  *   終了後フラグの指定動作  ※カーソルを移動/選択範囲を復旧
  * [引数]   strVal: 入力値
  *  0. カーソルは "引用符" の後ろへ。  (※範囲選択なし)
  * [返却値] String(): 半角変換された文字列
  *   1. カーソルは最後の "引用符" の中へ移動する。  (※範囲選択なし)
*  2. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ。  (※要 挿入フラグ = true)
*  あれば "引用符" の後ろへ移動する。  (※範囲選択なし)
*  3. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ移動。  (※範囲選択なし)、
*  あれば "引用符" を含めた全体を選択範囲にする。  (※カーソルは選択範囲の後ろへ)
*  4. "引用符" を含めた全体を選択範囲にする。  (※カーソルは選択範囲の後ろへ)
*  5. "引用符" を含めた全体を選択範囲にする。  (※カーソル位置はマクロ実行前の側(先頭 or 末尾)へ)
  */
  */
// ref. https://webllica.com/add-comma-as-thousands-separator/ より
function FinalSelection() {
  // 0. カーソルは "引用符" のうしろ
  // ※範囲選択なし(末尾調整されたままの位置)
  switch ( endPos ) {
 
    // 1. カーソルは "引用符" の中へ移動する  ※範囲選択なし
    case 1:
      SearchCloseBracket ();
      break;
 
    // 2. マクロ実行前に範囲選択がなければカーソルは "引用符" の中へ
    //    あれば選択範囲の後ろへ移動する  ※範囲選択なし
    case 2:
      // マクロ実行前に選択範囲がなかったとき → case 1 と同じ
      if ( ! st ) {
        SearchCloseBracket();
      }
      break;
 
    // 3. マクロ実行前に範囲選択がなければカーソルは "引用符" の中へ移動  ※範囲選択なし
    //    あれば "引用符" を含めた全体を選択範囲にする  ※カーソルは選択範囲の後ろへ
    case 3:
      // マクロ実行前に選択範囲がなかったとき → case 1 と同じ
      if ( ! st ) {
        SearchCloseBracket();
      }
      // マクロ実行前に選択範囲があったとき → case 2 と同じ
      else {
        MoveToEndPos();
        s.SetAnchorPos( tp ); // 先頭まで範囲選択
      }
      break;


function ToHalfWidth( strVal ){
    // 4. "引用符" を含めた全体を選択範囲にする
   // 半角変換
    // ※カーソルは選択範囲の後ろへ(末尾位置を復帰)
   var halfVal = strVal.replace( /[!-~]/g,
    case 4:
    function( tmpStr ) {
      MoveToEndPos();
       // 文字コードをシフト
      s.SetAnchorPos( tp );
      return String.fromCharCode( tmpStr.charCodeAt(0) - 0xFEE0 );
      break;
 
    // 5. "引用符" を含めた全体を選択範囲にする(末尾位置を復帰)
    // ※カーソル位置はマクロ実行前の側(先頭 or 末尾)へ
    case 5:
      MoveToEndPos();
      // マクロ実行前のキャレットの位置が末尾だったとき
      if ( anc <= act ) {
        s.SetAnchorPos( tp );
      }
      // マクロ実行前のキャレットの位置が先頭だったとき
      else {
        s.SetActivePos( tp, true );
      }
      break;
 
    default:
      break;
  }
}
 
/* 関数 AddDelBrackets() */
function AddDelBrackets( str, o, c ) { // ← AddDelBrackets( st, pre, sur )
 
   // ■複数行フラグ ( multiLine ) にしたがい選択範囲 st を配列 a に
   var a = ( multiLine ) ? str.split( "\n" ) : [ str ];
 
  for ( var i = 0, len = a.length; i < len; i ++ ) {
 
    // 選択範囲がカッコで囲われているときは、各行のカッコを削除
    if ( a[i].slice( 0, o.length ) == o
        && a[i].slice( - c.length ) == c ) {
       a[i] = a[i].slice( o.length, a[i].length - c.length );
      delCount ++; // 削除フラグ
    }
    // 選択範囲がカッコで囲われていないとき
    // 挿入フラグが有効ならカッコをつける
    else if ( insert || ! a[i].match( /^[\s ]*$/g ) ) {
      a[i] = o + a[i] + c;
      addCount ++; // 追加フラグ
    }
    // 挿入フラグが無効のときの空白行はスルー
    else {
      continue;
     }
     }
   );
   }
   return halfVal;
 
  return a.join( "\n" );
}
 
/* 関数 DeleteOuterBrackets() */ // ← DeleteOuterBrackets( st, pre, sur )
function DeleteOuterBrackets( str, o, c ) {
 
  // 選択範囲外側の前後の文字列が "引用符" なら削除する
  if ( d.Text.slice( tp - o.length, tp ) == o
      && d.Text.slice( bp, bp + c.length ) == c ) {
    s.SetActivePos( tp - o.length );
    s.SetAnchorPos( bp + c.length );
    s.Text = s.Text.slice( o.length, - c.length );
 
    tp = tp - o.length; // 先頭の座標を調整
    delCount ++;
  }
   return delCount; // 戻り値として削除フラグを返す
}
 
/* 関数 SearchCloseBracket() */
// カーソルを最後の閉じカッコの前へ移動  ※範囲選択なし
// ※閉じカッコ sur が未指定 "" の場合は、末尾のまま
function SearchCloseBracket() {
  if ( delCount ) {
    // カッコを削除したときは、末尾のまま
    s.SetActivePos( dp );
  }
  else if ( addCount ) {
    // カッコを追加したときは、選択範囲内の最後の閉じカッコの前へ
    s.SetActivePos( dp - sur.length );
  }
}
 
/* 関数 MoveToEndPos() */
// マクロ実行前に選択範囲があったとき、カーソルを元の選択範囲の末尾位置へ移動
// ※範囲選択なし
function MoveToEndPos() {
  // 選択範囲の末尾調整をしていたときは、カーソルを元の末尾位置に復帰
  if ( isAdjusted ) {
    s.SetActivePoint( mePosLogical, 1, by );
  }
  // 末尾調整をしていなかったときは、カーソル位置はそのまま
  else {
    s.SetActivePos( dp );
  }
}
}
</source>
</source>
<!-- 記
*「引用符を追加/削除」の項目を追加 (2018/10/18 sukemaru)
* 終了後の動作コードを変更し、不自然な位置にキャレットが移動する不具合を修正した (2018/10/26 sukemaru)
* 選択範囲の外側の引用符の削除に対応。終了時のカーソルの位置、範囲選択の動作を修正 (2019/03/28 sukemaru)
-->
<br>


= メモ =
= メモ =
<div style="height:40em; overflow:auto;">
* 2018/08/24 (sukemaru)
* 2018/08/24 (sukemaru)
: ページを新規作成
: ページを新規作成
* 2018/08/26 (sukemaru)
* 2018/08/26 (sukemaru)
: 「カッコで囲う (ポップアップメニューなし)」の節を追加
: 「カッコで囲う (ポップアップメニューなし)」の節を追加
* 2018/08/27 (sukemaru)
* 2018/08/27 (sukemaru)
:・「カッコで囲う (ポップアップメニューあり)」のソースコードを修正
:・「カッコで囲う (ポップアップメニューあり)」のソースコードを修正
:・case1~8 の "<u>s.CharLeft( false, p2[r].length );</u>" を "<u>s.SetActivePos( s.GetActivePos() - p2[r].length );</u>" に変更
:・case1~8 の "<u>s.CharLeft( false, p2[r].length );</u>" を "<u>s.SetActivePos( s.GetActivePos() - p2[r].length );</u>" に変更
* 2018/10/12 (sukemaru)
* 2018/10/12 (sukemaru)
: 「カッコで囲う (ポップアップメニューあり)」のソースコードに "3文字ずつ前後を削除" を追加
: 「カッコで囲う (ポップアップメニューあり)」のソースコードに "3文字ずつ前後を削除" を追加
: 組みこみ用コード「wiki用 文字列装飾」と「挿入型コメントアウト」の節を追加
: 組みこみ用コード「wiki用 文字列装飾」と「挿入型コメントアウト」の節を追加
: 「カッコで囲う.zip」のダウンロードリンクを追加
: 「カッコで囲う.zip」のダウンロードリンクを追加
* 2018/10/13 - 2018/10/16 (sukemaru)
* 2018/10/13 - 2018/10/16 (sukemaru)
:・マクロのコードを微修正
:・マクロのコードを微修正
:・「カッコで囲う.zip」を差し替え
:・「カッコで囲う.zip」を差し替え
* 2018/10/19 (sukemaru)
* 2018/10/19 (sukemaru)
:・「引用符を追加/削除」の節を追加
:・「引用符を追加/削除」の節を追加
:・「カッコで囲う.zip」を差し替え
:・「カッコで囲う.zip」を差し替え
* 2018/10/26 (sukemaru)
* 2018/10/26 (sukemaru)
:・コードの体裁を修正 (※変数名を変更したので、追加コードは最新の「カッコで囲う」でないとエラーになる)
:・コードの体裁を修正 (※変数名を変更したので、追加コードは最新の「カッコで囲う」でないとエラーになる)
857行目: 1,263行目:
:・「引用符を追加/削除」の終了後の動作コードを変更し、不自然な位置にキャレットが移動する不具合を修正した
:・「引用符を追加/削除」の終了後の動作コードを変更し、不自然な位置にキャレットが移動する不具合を修正した
:・「カッコで囲う.zip」を差し替え
:・「カッコで囲う.zip」を差し替え
* 2018/10/29 (sukemaru)
* 2018/10/29 (sukemaru)
:・「カッコで囲う (ポップアップメニューあり)」の節を更新(本体のソースコードに追加コードを包摂)
:・「カッコで囲う (ポップアップメニューあり)」の節を更新(本体のソースコードに追加コードを包摂)
864行目: 1,271行目:
* 2018/11/19 (sukemaru)
* 2018/11/19 (sukemaru)
:・「カッコで囲う (ポップアップメニューあり)」用の人柱版追加コード「行頭/行末から任意の 文字数 を削除」「行頭/行末から任意の 文字列 を削除」を追加
:・「カッコで囲う (ポップアップメニューあり)」用の人柱版追加コード「行頭/行末から任意の 文字数 を削除」「行頭/行末から任意の 文字列 を削除」を追加
* 2019/03/28 (sukemaru)
:・「カッコで囲う (ポップアップメニューあり)」のコードを増補・改変。人柱版追加コードを統合。
::・「JS コメントアウト/アンコメント」を正規表現置換メソッドに変更
::・「任意の 文字数/文字列 を削除」を追加
::・「行頭/行末の空白を削除」を追加
::・「1文字ずつ前後を削除(外)」を追加
::・「ひとつ削除」を追加(「カッコをはずす」マクロから転用)
::・「アウトプット/アラート/コンファーム/ステータス」を追加
::・「カッコの定義」を使わないコマンドの ID を 1030~ に変更
::・ サブメニューを追加してネスト化
:・「引用符を追加/削除」に選択範囲の外側の”引用符”の削除機能を追加
:・「引用符を追加/削除」の終了時の動作コードを再変更
:・「カッコで囲う.zip」を差し替え
</div>
----
◆ '''動作の不具合などがあったらお知らせ下さい。'''(sukemaru)◆

2019年3月28日 (木) 17:02時点における版

ダウンロード

全部入りの書庫をダウンロード → 「カッコで囲う.zip(アイコン入り)」 (最終更新 2019/03/28)

ZIP 書庫には以下のマクロの .JS ファイルと、それぞれ専用の "マテリアルデザインっぽい" アイコンがふくまれています。
  • カッコで囲う(ポップアップメニューあり)
  • カッコで囲う(ポップアップメニューなし)
  • 引用符を追加/削除

カッコで囲う ポップアップメニュー.png


カッコで囲う(ポップアップメニューあり)

(最終更新 2019/03/28)

ポップアップメニューから任意の カッコダッシュ などの種類を選択して、選択範囲をカッコやいろいろな記号、文字列で囲います。
選択範囲がないばあい、基本的にはカーソル位置に ( ), < >, [ ], { }, 「 」, … などを挿入します。

行番号のドラッグでの複数行選択やトリプルクリックでの行選択などで末尾改行が含まれているばあい、さいごの改行を無視します。

  • 既存のポップアップメニュー項目を減らしたいばあいは、ソースコード内の "m.Add( … );" の行頭に // をつけてコメントアウトするとその項目をメニューから隠せます。
  • メニュー項目を増やしたいばあいは、
  1. ソースコード冒頭の配列 p1, p2 の21番目~30番目に任意の , "記号" を追加する
  2. 対応する番号をつけて "m.Add( "カッコ・記号 の名前" , XX );" の行を追加する
  3. 対応する番号をつけて "case XX:" を適当なグループに追加する


作成にあたり、「引用の追加」マクロとキーアサイン集の「括弧で挟む」マクロのコードを参考にしました(※「引用の追加」マクロは 2018/10/14 付けで公開停止になりました)。


姉妹版として 「カッコをはずす」、「カッコを削除/追加」、「カッコを追加/削除」マクロ、「引用符/コメント」マクロがあります。


メニューの項目

任意の文字列で囲う

文字入力用のダイアログで「前につける文字列」と「後ろにつける文字列」を指定します。

  • 任意の文字列1
選択範囲全体を一組の指定文字列で前後を囲います。
  • 任意の文字列2
選択範囲内の各行ごとに指定文字列で前後を囲います。
ソースコード冒頭の skip フラグで、複数行選択のさいに空白行をスキップするか指定してください。
「wiki 文字装飾タグ」以外のカッコ/記号で各行ごとに囲いたい場合は、「任意の文字列2」を使用してください。

改行コードとタブ文字は、それぞれ「\\\n」と「\\\t」で入力されたもの (注:¥記号3つ) を改行コードとタブ文字に置換するようにしてあります。

※「\n」、「\t」と入力するとそのままの文字列「\n」、「\t」を返します。
※文字コードでの入力には非対応です(入力されたままの文字列を返します)。


カッコ/記号 で囲う

選択範囲全体を指定したカッコ/記号で囲います。
選択範囲なしで実行した場合は、カーソル位置にカッコ一組を挿入します。

  • (半角丸カッコ) 、 <半角山カッコ> 、 [半角角カッコ] 、 {半角波カッコ}、
    (全角丸カッコ) 、 「全角かぎカッコ」 、 『二重かぎカッコ』 、 【スミ付きカッコ】
選択範囲をカッコで囲います。
  • ␣(半角丸カッコ)␣ 、 ␣"半角二重引用符"␣
選択範囲をカッコまたは引用符で囲い、さらに半角スペースで囲います。
  • ␣半角スペース␣
選択範囲を半角スペースで囲います。
  • - 半角ハイフン - 、 ――ダッシュ×2―― 、 ~チルダ~
「半角ハイフン」は、半角ハイフン=マイナス記号の両側に各1つずつ半角スペースがつきます(片側で半角3文字分)。
※このグループにかぎり、選択範囲なしで実行したときは、片側分だけ "-" "――" "~" 記号を挿入します。


ひとつ削除

  • カッコをはずす」マクロのコードを移植しました。
    選択範囲全体の先頭/末尾があらかじめ用意された「対になるカッコ・記号」のペアであれば、その一組のペアを削除します。

※ポップアップメニューの "カッコの追加用" の項目にない多種多様な記号のペアに対応します。
※「カッコをはずす」マクロの "選択範囲の外側 (前と後) にあるカッコの削除" 機能はありません。


任意の 文字列/文字数 を削除

「任意の文字列2」や「wiki用 マークアップ」と同様に、選択範囲内の論理行の各行頭と行末にたいして作用します。
※選択範囲を "論理行単位" で拡張しないので、先頭行と末行においては行頭/行末ではなく「選択範囲の先頭/末尾」にたいして作用します。

  • 任意の文字数を削除 ではアラビア数字(半角/全角)以外で入力された文字列をすべて無視します。例えば「1a2あ」と入力された場合は、半角数字の「12」として扱います。
  • 任意の文字列を削除 は簡易的な処理コードなので、正規表現を使用できません。
    また、タブ文字の扱いは「任意の文字列2(追加)」の場合とおなじく「\\\t」で入力されたもの (注:¥記号3つ) をタブ文字(\t)として処理します。


先頭/末尾の空白を削除

  • 先頭/末尾から空白を削除
  • 先頭の空白を削除*末尾の空白を削除
選択範囲内の論理行の各行頭と行末にたいして作用します。
削除対象の空白文字は、「半角スペース」「全角スペース」「タブ文字」の3種です。
インデント(字下げ)の解除や、行末のムダな空白文字の削除に利用できます。

※選択範囲を "論理行単位" で拡張しないので、先頭行と末行においては行頭/行末ではなく「選択範囲の先頭/末尾」にたいして作用します。


n文字ずつ前後を削除

  • 1文字ずつ前後を削除
  • 2文字ずつ前後を削除
  • 3文字ずつ前後を削除
選択範囲全体の先頭/末尾から指定の文字数ずつ削除します。


  • 1文字ずつ前後を削除(外側)
選択範囲全体の前と後ろの各1文字を削除します。
※選択範囲が先頭行の行頭から始まっている場合や、最終行の行末で終わっている場合は、選択範囲内の先頭または末尾の1文字が削除されます。


JS / XML コメントアウト

3種類の 挿入型コメントアウト のメタ記号で選択範囲の文字列をコメントアウトできます。また、アンコメント用のコマンドでコメントアウト状態を解除できます。

  • /* JavaScript 挿入型コメントアウト1 */
選択範囲全体を /* */ で囲います。
  • /* *JavaScript コメントアウト2(ブロックコメント) */
/*
​ * (複数行の)選択範囲全体を "/* \n" と "\n */" で囲い、
​ * 範囲内の各行の行頭に " * " を付けます。
​ */
  • <!-- XML 挿入型コメントアウト -->
選択範囲全体を <!--  と  --> で囲います。


  • JS アンコメント
  • XML アンコメント
上の3種のコメントアウトのメタ記号を削除してアンコメントします。

先頭と末尾のコメントマークは選択範囲の両端でなければ削除されません(選択範囲の先頭/末尾に半角スペース×1が付いていても、コメントマークといっしょに削除できます)。
また、選択範囲内に2組以上のコメントがあると、正常にアンコメントできません。

※ "JS アンコメント" は中間行の行頭記号(アスタリスクと全角/半角中黒)とその前後の半角スペースを削除します。これらの行頭記号を使用した箇条書きを範囲選択して実行すると、同様に行頭記号を削除します。

※ プログラミングをしない人には使いみちがないとおもいますので、ZIP のソースでは初期状態でコメントアウトしてあります。


wiki用 マークアップ

5種類の wiki用 文字列装飾タグ(マークアップ)(テキスト整形マークアップ)を挿入できます。

選択範囲内の各行ごとに指定のタグで前後を囲います。
ソースコード冒頭の skip フラグで、複数行選択のさいに空白行をスキップするか指定してください。

  • 太字
選択範囲全体を '''(シングルクオート×3) で囲います。
  • 斜体(Italic)
選択範囲全体を ''(シングルクオート×2) で囲います。
  • 下線
選択範囲全体を <u> と </u> で囲います。
  • [[内部リンク]]
選択範囲全体を [[ と ]] で囲い、[[リンク|ラベル]] 型の 内部リンク にします。
  • <​nowiki>マークアップ回避<​/nowiki>
選択範囲全体を <​nowiki> と <​/nowiki> で囲います。


※ wiki用 文字列装飾タグのままでは使いみちがないとおもいますので、HTML タグ <a> </a> などに書き換えてしまうか、ポップアップメニュー項目をコメントアウトしてしまうとよいでしょう(ZIP のソースでは初期状態でコメントアウトしてあります)。


Mery マクロ用

選択範囲の文字列をコピーし、"二重引用符" つきにして、以下の各種の構文で囲います。

※選択文字列のある行のひとつしたの行に各構文を挿入します。
※選択範囲が複数行の場合は "+ \n +" でつなぎ合わせます。

  • アウトプット
Outputbar.Writeln( "..." ); の構文にしてアウトプットバーを表示状態にします。
  • アラート
Alert( "..." ); の構文にします。
  • コンファーム
Confirm( "..." ); の構文にします。
  • ステータス
Status = "..."; の構文にします。


※ マクロのプログラミングをしない人には使いみちがないとおもいますので、ZIP のソースでは初期状態でコメントアウトしてあります。


ソースコード

#title = "カッコ ..."
#tooltip = "カッコで囲う (ポップアップメニュー)"
#icon = "Mery用 マテリアルデザインっぽいアイコン.icl",255

/**
 * -----------------------------------------------------------------------------
 * カッコで囲う(ポップアップメニュー)
 * sukemaru, 2018/08/24 - 2019/03/28
 * -----------------------------------------------------------------------------
 *
 * ポップアップメニューからカッコの種類を選択して、選択範囲をカッコで囲う。
 * 公式 wiki のマクロライブラリより「引用の追加」と「括弧で挟む」のコードを参考にした
 *
 * ・複数行の選択範囲で末尾が改行 \n のとき、さいごの改行は除外する。
 * ・非選択時には、それぞれことなる動作をする。
 * 
 * ※ 「任意の文字列」について ※
 * ・「任意の文字列1」は選択範囲全体をひとくくりに、
 *   「任意の文字列2」は選択範囲内の "各行ごと" で個別に、指定した文字列で前後を囲う。
 * ・wiki 文字装飾タグ以外のカッコで "各行ごと" に囲いたい場合は、「任意の文字列2」を使用する。
 * ・文字コードでの入力には非対応(入力されたままの文字列を返す)。
 * ・改行コードとタブ文字は、それぞれ「\\\n」と「\\\t」で入力されたものを置換する。
 *   パスの入力に配慮しただけの簡易的な置換処理なので、「\」を4つ以上かさねた場合を考慮していない。
 * 
 * ※ 「wiki 文字装飾タグ」について ※
 * ・選択範囲内の "各行ごと" で個別に、指定したタグで前後を囲う。
 * ・空行にもマークアップタグを挿入する場合は、skip オプションを無効にすること。
 * 
 * ※ JS/XML コメントアウト と アンコメント について ※
 * ・「カッコで囲う」マクロでは行の中間部分だけをコメントアウトするので、
 *   行単位でコメントアウトするなら「引用の追加」マクロが適する。
 * ・「カッコで囲う」マクロでは行の先頭部分のコメントマークだけにしかマッチしないので、
 *   コメント部分がインデント(字下げ)されている場合も「引用の追加」マクロが適する。
 * ・ほかにも注意事項があるので、該当コード部分の注意書きを参照のこと。
 * 
 * ※ 「ひとつ削除」について ※
 * ・「開きカッコ」「閉じカッコ」の定義とは別に削除用の定義を使用して、
 *   選択範囲の先頭と末尾の1組の「カッコ」を削除する。
 *   各種カッコ、引用符のほかにも各種の記号のペア、半角空白などを削除対象とする。
 * 
 * ※ 削除系のコマンドについて ※
 * ・選択範囲がないときはポップアップメニュー上に表示しない。
 * 
 * -----------------------------------------------------------------------------
 * ※ ポップアップメニューの項目は、m.Add( … ); の不要な行を行をコメントアウトすれば隠せる。
 * (配列から削除する場合は中身だけ消して  ""  として空要素を残しておかないと
 *   メニューや処理コードの ID と一致しなくなる)
 *
 */


// ■「任意の文字列2」と、wiki 文字装飾タグで、複数行の選択範囲内の空白行をスキップするか?
var skip = true;	// (true; スキップする / false; スキップしない)


// ■開きカッコ p1 を配列で定義する
var p1 = new Array( "" ,		// 以下 r = 1~10、11~20、21~ の ID 順
  "(" ,  "<" ,  "[" ,  "{" ,  "(" ,  "「" ,  "『" ,  "【" ,  " (" ,  " (" ,
  " \"" ,  " " ,  " - " ,  "――" ,  "~" ,  "'''" ,  "''" ,  "<u>" ,  "[[" , "<nowiki>" ,
  "" , "" , "" , "" , "" );

// ■閉じカッコ p2 を配列で定義する
var p2 = new Array( "" ,		// 以下 1~10、11~20、21~ の ID 順
  ")" ,  ">" ,  "]" ,  "}" ,  ")" ,  "」" ,  "』" ,  "】" ,  ") " ,  ") " ,
  "\" " ,  " " ,  " - " ,  "――" ,  "~" ,  "'''" ,  "''" ,  "</u>" ,  "]]" , "</nowiki>" ,
  "" , "" , "" , "" , "" );


var s = document.selection

// ポップアップメニュー項目の定義
var m = CreatePopupMenu(),
  sm1 = CreatePopupMenu(),
  sm2 = CreatePopupMenu(),
  sm3 = CreatePopupMenu();
var grayFlag = s.Text ? 0 : meMenuGrayed;
  // m.Add( "ラベル", r ); の各行は、任意に上下移動(並べ替え)してよいが、
  // r の数値は上の配列の並び順やテキスト変換処理の case r: に対応しているので変更しないこと!

/* 入力 ダイアログ */
m.Add( "任意の文字列 で前後を囲う (&E) ...", 1050 );   	// Enter the custom string(s)
m.Add( "任意の文字列 2 (&E) ...", 1051 );	// 各行ごとに指定文字列で囲う(skip フラグを指定すること)

/* 削除系コマンド */
if ( s.Text ) {					// 選択範囲がないときは表示しない
  m.Add( "", 0, meMenuSeparator );
  m.Add( "▲ ひとつ削除 (&1)", 1038 );
  m.AddPopup( "● 削除 (&T)", sm1 );
    sm1.Add( "  先頭/末尾から任意の 文字列 を削除 (各行) (&Z) ...", 1053 );
    sm1.Add( "  先頭/末尾から任意の 文字数 を削除 (各行) (&X) ...", 1052 );
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "≫ 先頭/末尾から 空白 を削除 ≪ (各行) (&W)", 1037 );
    sm1.Add( "≫ 先頭の 空白 を削除   (各行) (&T)", 1035 );
    sm1.Add( "  末尾の 空白 を削除 ≪ (各行) (&B)", 1036 );
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "◀  1文字ずつ 前後を削除  ▶ (外側) (&0)", 1034 );
    sm1.Add( " ▶ &1文字ずつ前後を削除 ◀  (1)", 1031 );
    sm1.Add( " ▶ &2文字ずつ前後を削除 ◀  (2)", 1032 );
    sm1.Add( " ▶ &3文字ずつ前後を削除 ◀  (3)", 1033 );
}

/* カッコ */
m.Add( "", 0, meMenuSeparator );
m.Add( " ( 半角 小カッコ )  (&P)", 1 );		// Parenthesis
m.Add( "", 0, meMenuSeparator );
m.Add( "< 半角 山カッコ > (&A)", 2 );  		// Angle brackets
m.Add( " [ 半角 大カッコ ]  (&B)", 3 );		// square Brackets
m.Add( " { 半角 中カッコ }  (&C)", 4 );		// Curly brackets

m.Add( "", 0, meMenuSeparator );
m.Add( "( 全角 小カッコ ) (&R)", 5 );      	// Round brackets
m.Add( "", 0, meMenuSeparator );
m.Add( "「 全角 かぎカッコ 」 (&K)", 6 );    	// Kakko
m.Add( "『 全角 二重かぎカッコ 』 (&W)", 7 );	// White corner brackets
m.Add( "【 全角 スミ付きカッコ 】 (&L)", 8 );	// Lenticular brackets

m.Add( "", 0, meMenuSeparator );
m.Add( "␣( 全角 小カッコ )␣ (&F)", 9 ); 	// Full width parenthesis (w/ space)
m.Add( "␣ ( 半角 小カッコ ) ␣ (&H)", 10 );	// Half-width parenthesis (w/ space)
m.Add( '␣ "  半角 引用符  " ␣ (&Q)', 11 );	// double-Quotation mark (w/ space)
m.Add( "␣ 半角 スペース ␣ (&S)", 12 );  	// Space

m.Add( "", 0, meMenuSeparator );
m.Add( "  -  半角 ハイフン  -   (&-)", 13 );	// hyphen-minus	 (w/ spaces)
m.Add( "―― 全角 ダッシュ ―― (&D)", 14 );  	// Dash
m.Add( "~ 全角 チルダ ~ (&T)", 15 );        	// Tilde

/* JS コメントアウト / XML コメントアウト */
// m.Add( "", 0, meMenuSeparator );
// m.Add( "/* *  JS コメントアウト 2  */ (&J)", 1041 );	// JavaScript comment out (block comment)
// m.Add( "/*  JS コメントアウト 1  */ (&V)", 1042 );  	// jaVascript comment out
// m.Add( "▲ JS アンコメント (&U)", 1043, grayFlag );	// Uncomment
// m.Add( "", 0, meMenuSeparator );
// m.Add( "<!--  XML コメントアウト  --> (&X)", 1044 ); 	// Xml comment out
// m.Add( "▲ XML アンコメント (&M)", 1045, grayFlag );	// xMl uncomment

/* wiki マークアップ
   このブロックの項目は、複数行を選択しているとき「選択範囲の各行ごとに囲う」処理をおこなう
  (※ skip フラグを指定すること) */ 
// m.Add( "", 0, meMenuSeparator );
// m.AddPopup( "wiki 文字修飾 (&W)", sm2 );
//   sm2.Add( "''' wiki 太字 '''  (&B)", 16 );  	// Bold
//   sm2.Add( "''  wiki 斜体  ''  ( &I )", 17 );	// Italic
//   sm2.Add( "<u> wiki 下線 </u>  (&U)", 18 );   	// Under line	
//   sm2.Add( "[[  wiki リンク  ]]  (&L)", 19 );	// Link
//   sm2.Add( "<nowiki> </nowiki>  (&N)", 20 );      	// Nowiki

/* Mery マクロ用
   以下の項目は、選択範囲の文字列をコピーして、一行下でそれぞれの構文で囲う */ 
// m.Add( "", 0, meMenuSeparator );
// m.AddPopup( "Mery マクロ (&Y)", sm3 );
//   sm3.Add( "アウトプット (&O)", 1060 );		// OutputBar.Writeln( ... )
//   sm3.Add( "アラート (&A)", 1061 );    		// Alert( ... )
//   sm3.Add( "コンファーム (&C)", 1062 );		// Confirm( ... )
//   sm3.Add( "ステータス (&S)", 1063 );  		// Status = ... 

// m.Add( "", 0, meMenuSeparator );
// m.Add( "キャンセル", 0 );	// Escキー でキャンセルできるのでアクセラレータなし


// ポップアップメニューを表示
// m.Track(0); ならキャレット位置、m.Track(1); ならカーソル位置にポップアップ
var r = m.Track( mePosMouse = 1 );	// 選択されたメニュー項目のIDを r に格納する

if ( r > 0 ) {
  Redraw = false;

  var anc = s.GetAnchorPos();        	// 選択範囲の開始位置 (キャレットのない側)
  var act = s.GetActivePos();        	// 選択範囲の終了位置 (キャレットのある側)
  var tp = ( anc < act ) ? anc : act;	// 選択範囲の先頭位置
  var bp = ( anc < act ) ? act : anc;	// 選択範囲の末尾位置

  if ( s.IsEmpty ) {           		// 選択範囲がなければ
    var pos = s.GetActivePos();		// カーソル位置を取得
  }

  // マクロ実行前の選択範囲の各座標を取得
  var tx = s.GetTopPointX( mePosLogical );
  var ty = s.GetTopPointY( mePosLogical );
  var bx = s.GetBottomPointX( mePosLogical );
  var by = s.GetBottomPointY( mePosLogical );

  // 選択範囲の末尾位置を調整(最後の \n を含めない)
  // 選択範囲の末尾が行頭 x = 1 にあるばあい ~	※ { 中カッコ } のばあいは末尾の調整をしない
  if ( ! s.IsEmpty && bx == 1 && r != 4 ) {
    s.SetActivePos( bp - 1 );			// 元の選択範囲の末尾より1行うえの末尾	// 先頭
    s.SetAnchorPos( tp );    			// 元の選択範囲の先頭まで選択
  }

  // 選択範囲の文字列を取得
  var st = s.Text;

  // IDごとのテキスト変換処理
  switch ( r ) {

    // カッコ
    case 1:  case 2:  case 3:  case 4:  case 5:  case 6:
    case 7:  case 8:  case 9:  case 10:  case 11:  case 12:
    // case 21:  case 22:  case 23:  case 24:  case 25:
      s.Text = p1[r] + st + p2[r];		// カッコ p1 & p2 で囲う

      if ( pos ) {				// 選択範囲がなければ
        s.SetActivePos( pos + p1[r].length );	// カーソルをカッコのなかに移動
      }
      else {					// 選択範囲があれば
        s.Text = p1[r] + st + p2[r];		// 選択範囲 st をカッコ p1 & p2 で囲う
        s.SetAnchorPos( tp );			// 選択範囲を復元
      }
      break;


    // ハイフン、ダッシュ、チルダ
    case 13:  case 14:  case 15:
      if ( pos ) {			// 選択範囲がなければ
        document.Write( p1[r] );	// 片側分 p1 だけ挿入
      }
      else {				// 選択範囲があれば
        s.Text = p1[r] + st + p2[r];	// 選択範囲 st をダーシ p1 & p2 で囲う
        s.SetAnchorPos( tp );		// 選択範囲を復元
      }
      break;


    // wiki 文字装飾タグ	※ 太字/斜体/下線/<nowiki>
    case 16:  case 17:  case 18:  case 20:
      // 選択範囲内の「各行を囲う」処理をおこなう。
      // 複数行選択で空白行をスキップするかは冒頭の skip フラグで決定する。
      // 選択範囲なしで実行するとタグの間がわかりづらくなるので全角スペースを挿入する。

      if ( pos ) {					// 選択範囲がなければ
        document.Write( p1[r] + " " + p2[r] );		// p1 & p2 と全角スペースを挿入
        s.SetAnchorPos( pos + p1[r].length );		// カーソルをタグのなかに移動
        s.SetActivePos( s.GetAnchorPos() + 1, true );	// タグの中の全角スペースを範囲選択
      }
      else {						// 選択範囲があれば
        var ad = AddBrackets( st, p1[r], p2[r] );	// 選択範囲 st の各行を p1 & p2 で囲う
        if ( ad != st ) {
          s.Text = ad;
          s.SetAnchorPos( tp );				// 選択範囲を復元
        }
        else {				// テキストに変更なし ( skip && st.match( /^\s*$/g ) )
          s.SetActivePos( act );	// 選択範囲を復元
          s.SetAnchorPos( anc );
        }
      }
      break;


    // wiki 文字装飾		※ 内部リンク用タグ	[[リンク|ラベル]]
    case 19:
      // 選択範囲内の「各行を囲う」処理をおこなう。
      // 複数行選択で空白行をスキップするかは冒頭の skip フラグで決定する。

      if ( pos ) {						// 選択範囲がなければ
        document.Write( p1[r] + " | " + p2[r] );		// p1 & p2 と " | " を挿入
        s.SetActivePos( pos + p1[r].length );			// カーソルをカッコの中に移動
        s.SetAnchorPos( s.GetActivePos() + " | ".length );	// カッコの中を範囲選択
      }
      else {						// 選択範囲があれば
        var ad = AddWikiLink( st, p1[r], p2[r] );	// 選択範囲 st の各行を [[str|str]] に変換
        if ( ad != st ) {
          s.Text = ad;
          s.SetActivePos( tp + p1[r].length );		// p1 の後ろにカーソルを移動
        }
        else {				// テキストに変更なし ( skip && st.match( /^\s*$/g ) )
          s.SetActivePos( act );	// 選択範囲を復元
          s.SetAnchorPos( anc );
        }
      }
      break;


    // n文字ずつ前後を削除(内)
    case 1031:  case 1032:  case 1033:
      if ( ! s.IsEmpty ) {		// 選択範囲があれば
        var n = ( r == 1031 ) ? 1 :	// 1文字ずつ
                ( r == 1032 ) ? 2 :	// 2文字ずつ
               /* r == 1033 */  3 ;	// 3文字ずつ

        s.Text = st.slice( n, st.length - n );	// 選択範囲の両端から n 文字ずつ消す
        s.SetAnchorPos( tp );			// 選択範囲を復元
      }
      break;


    // 1文字ずつ前後を削除(外)
    case 1034:
      s.SetAnchorPos( tp - 1 );		// 選択範囲の先頭側を1文字拡張
      s.SetActivePos( bp + 1, true );	// 選択範囲の末尾側を1文字拡張
      s.Text = s.Text.slice( 1, - 1 );	// 先頭/末尾を1文字ずつ削除
      s.SetAnchorPos( tp - 1 );		// 選択範囲を復帰する
      break;


    // 行頭/行末の空白を削除	※選択範囲を論理行単位に拡張はしない
    case 1035:  case 1036:  case 1037:
      if ( ! s.IsEmpty ) {	// 選択範囲があれば
        var d = ( r == 1037 ) ? st.replace( /^[\s ]*|[\s ]*$/gm , "" ) :	// 行頭/行末
                ( r == 1035 ) ? st.replace( /^[\s ]*/gm , "" ) :		// 行頭
               /* r == 1036 */  st.replace( /[\s ]*$/gm , "" ) ;		// 行末

        // 選択範囲に指定文字列がなかった場合 undo 履歴を残さない
        if ( d != st ) {
          s.Text = d;			// 削除完了
          s.SetAnchorPos( tp );		// 選択範囲を復元
        }
      }
      break;


    // ひとつ削除 (※「カッコをはずす」マクロのコードを流用)
    case 1038:
      // 「ひとつ削除」用のカッコの定義
      var brackets = "()「」<>[]{}\"\"''()「」『』<>[]{}【】〖〗⦅⦆⦅⦆〚〛〔〕〘〙〈〉《》"
                   + "””’’〝〞〝〟‘’“”――~~〜〜  "
                   + "++--**\/\/##==%%::::@@@@※※††||……␣␣__"
                   + "○○●●□□■■◇◇◆◆▽▽▼▼△△▲▲☆☆★★"
                   + "←→→←↑↓↓↑←←→→↑↑↓↓"
                   + "¿?¡!‚‘‚’„“„”“„‘‚‹››‹«»»«——‐‐--"
                   + "﹁﹂﹃﹄︵︶︿﹀︽︾︹︺︷︸︻︼︗︘";
      var brackets2 = [
        "<b>" , "</b>" , "<i>" , "</i>" , "<u>" , "</u>" , "</" , ">" , "<" , "/>" ,
        "<!-- " , " -->" , "<!--" , "-->" , 
        "/** \n" , "\n */" , "/** \n" , "\n*/" , "/**\n" , "\n */" , "/**\n" , "\n*/" , 
        "/* \n" , "\n */" , "/* \n" , "\n*/" , "/*\n" , "\n */" , "/*\n" , "\n*/" , 
        "/** " , " */" , "/**" , " */" , "/* " , " */" , "/*" , " */" , 
        "'''''" , "'''''" , "'''" , "'''" , "''" , "''" , "[[" , "]]" ,  
        "<nowiki>" , "</nowiki>" , "<span>" , "</span>" , "<div>" , "</div>" , 
        "<pre>" , "</pre>" , "<source lang=\"javascript\">" , "<\/source>" 
      ];
      brackets = brackets2.concat( brackets.split( "" ) );

      var db = DeleteBrackets( st, brackets );
      if ( st != db ) {
        s.Text = db;
        s.SetAnchorPos( tp );	// 選択範囲を復帰する
      }
      else {			// テキストに変更なしなら
        s.SetActivePos( act );	// 選択範囲を復元
        s.SetAnchorPos( anc );
      }
      break;


    // /* * JavaScriptコメントアウト 2 */
    case 1041:
/*
 *     基本的に1行めが行の先頭から始まることしか想定していないので、
 *       あらかじめコメントアウトする文字列は、行単位でまとまったブロックにしておくとよい。
 *     選択範囲の先頭/末尾が行の途中にある状態でコメントアウトする場合は、改行を追加する。
 */
      var p1 = ( tx > 1 ) ? "\n/*\n" : "/*\n";		// */
      var p2 = ( document.Text.charAt( bp ) != "\n" ) ? "\n */\n" : "\n */";
      var ast = " * ";
      if ( tx > 1 ) {	// 選択範囲の先頭座標が x = 1 でなければ改行させるので
        tp ++;		// 選択範囲の復元用座標を調整
      }

      // コメントアウト
//    s.Text = CommentOutJS( st, p1, p2, ast );	// コメントアウト(関数バージョン)
      /*  ※ JS コメントアウト の正規表現置換バージョンの検証は不十分 ※ */ 
      s.Text = p1 + st.replace( /^(.*)$/gm , ast + "$1" ) + p2;

      if ( pos ) {					// 選択範囲がなければ
        s.SetActivePos( s.GetActivePos() - p2.length );	// カーソルをコメント枠のなかに移動
      }
      else {						// 選択範囲があれば
        s.SetAnchorPos( tp );				// 選択範囲を復元
      }
      break;


    /* JavaScript コメントアウト 1 */
    // <!-- XML コメントアウト --> 
    case 1042:  case 1044:
      var p1, p2;
      if ( r == 1042 ) {			/* JavaScript コメントアウト 1 */
        p1 = " /* "; p2 = " */ ";
      }
      else {	// ( r == 1044 )		// <!-- XML コメントアウト --> 
        p1 = " <!-- "; p2 = " --> ";
      }

      if ( pos ) {				// 選択範囲がなければ
        document.Write( p1 + p2 );		// コメントマーク p1 & p2 だけ挿入
        s.SetActivePos( pos + p1.length );	// カーソルをコメント枠のなかに移動
      }
      else {					// 選択範囲があれば
        s.Text = p1 + st + p2;			// 選択範囲 st をコメントアウト
        s.SetAnchorPos( tp );			// 選択範囲を復元
      }
      break;


    // JS アンコメント
      // case 1041 と case 1042: の /* JavaScriptコメント */ をアンコメントする。
      // 選択範囲内の各行頭のコメントマーク "/* "  と " * " と " */" のみマッチ。
      // 「カッコで囲う」では行の先頭部分のコメントマークだけにしかマッチしないので、
      //   コメント部分がインデントされている場合は「引用符/コメント」マクロのJSアンコメントを使うこと。
/* 
 * ・選択範囲に複数のコメントブロックがある場合を想定していない。
 * ・中間行の行頭記号はアスタリスク「 * 」、全角中黒「・」、半角中黒「・」を削除対象とする。
 *   (行頭記号と前後の半角スペース各1を削除する)
 * ・JSコメントでない箇条書き文で実行した場合も行頭のビュレット「* ・ ・」を削除する。
 */
/* このタイプのコメントにたいしてもアンコメント処理する。 */

    // XML アンコメント
      // case 1044 の <!-- XMLコメント --> をアンコメントする。
      // 選択範囲の先頭の " <!-- " と 末尾の " --> " のみマッチ。
      // 選択範囲に複数のコメントがあると正常にアンコメントしない。

    case 1043:  case 1045:
      // 選択範囲の先頭と末尾のコメントマークを削除
      var dc;
//    if ( r == 1043 ) {
//      dc = UnCommentJS( st );		// JS アンコメント(関数バージョン)
//    }
      /*  ※ JS アンコメントの正規表現置換バージョンの検証は不十分 ※ */ 
      if ( r == 1043 ) {		// JS アンコメント(正規表現バージョン)
        dc = st.replace( /^ ?\/\*+ ?\n?|\n? ?\*+\/ ?$/gm , "" )
                   .replace( /^ ?(?:\*+|[・・]) ?/gm , "" );
      }
      else {	// ( r == 1045 )	// XML アンコメント
        dc = st.replace( /^ ?<!-+ ?| ?-+ *>\ ?$/g , "" );
      }

      // 選択範囲にコメントマークがなかった場合 undo 履歴を残さない
      if ( dc == st ) {		// アンコメント処理の前後でテキストが一致したら
        s.SetActivePos( act );	// 選択範囲を復元
        s.SetAnchorPos( anc );
      }
      else {
      s.Text = dc;		// アンコメント完了
      s.SetAnchorPos( tp );	// 選択範囲を復元
      }
      break;


    // 任意の文字列を追加	※テキストボックス
    case 1050:  case 1051:
      // 文字コードには非対応
      // ダイアログのテキスト入力フィールドから文字列を取得
      var p1 = Prompt(
                  "前につける文字列:\t改行=\\\\\\n ; タブ=\\\\\\t  (注:¥記号3つ)", ""
               ).replace( /\\\\\\n/g , "\n" ).replace( /\\\\\\t/g , "\t" );
      var p2 = Prompt(
                  "後ろにつける文字列:\t改行=\\\\\\n ; タブ=\\\\\\t  (注:¥記号3つ)", ""
               ).replace( /\\\\\\n/g , "\n" ).replace( /\\\\\\t/g , "\t" );

      if ( p1 || p2 ) {
        if ( pos ) {				// 選択範囲がなければ
          document.Write( p1 + p2 );		//   p1 & p2 を挿入
          s.SetActivePos( pos + p1.length );	//   カーソルをカッコのなかに移動
        }
        else {					// 選択範囲があれば
          if ( r == 1050 )			//  「任意の文字列1」なら
            s.Text = p1 + st + p2;		//     選択範囲 st 全体を p1 & p2 で囲う
          else {	// ( r == 1051 )	//  「任意の文字列2」なら
            var ab = AddBrackets( st, p1, p2 );	//     選択範囲 st の各行を p1 & p2 で囲う
            if ( ab != st )
              s.Text = ab;
            else		// テキストに変更なし ( skip && st.match( /^\s*$/g ) )
              s.SetActivePos( bp );
          }
          s.SetAnchorPos( tp );			// 選択範囲を復元
        }
      }
      break;


    // 各行の前後から任意の文字数/文字列を削除	※テキストボックス
    case 1052:  case 1053:
      if ( ! pos ) {		// 選択範囲があれば

        if ( r == 1052 ) {	// 「任意の 文字数 を削除」なら
          // ダイアログのテキスト入力フィールドから文字列を取得
          // ※ 半角に変換して数字以外の文字は削除
          var p1 = ToHalfWidth(
                      Prompt( "先頭(行頭)から削除する文字数 (数字のみ有効):", "" )
                   ).replace( /[^0-9]/g , "" );	
          var p2 = ToHalfWidth(
                      Prompt( "末尾(行末)から削除する文字数 (数字のみ有効):", "" )
                   ).replace( /[^0-9]/g , "" );
          var dt = DeleteCharByNum( st, p1, p2 );	// 各行の先頭/末尾から指定文字数を削除
        }

        else {	// ( r == 1053 )	// 「任意の 文字列 を削除」なら
        // ダイアログのテキスト入力フィールドから文字列を取得
          var p1 = Prompt(
                      "先頭(行頭)から削除する文字列:\tタブ = \\\\\\t  (¥記号3つ)", ""
                   ).replace( /\\\\\\t/g , "\t" );
          var p2 = Prompt(
                      "末尾(行末)から削除する文字列:\tタブ = \\\\\\t  (¥記号3つ)", ""
                   ).replace( /\\\\\\t/g , "\t" );
          var reg = new RegExp( "^" + Quote( p1 ) + "|" + Quote( p2 ) + "$", "gm" );
          dt = st.replace( reg , "" );	// 各行の先頭/末尾の指定文字列を削除
        }

        // 選択範囲に指定文字列がなかった場合 undo 履歴を残さない
        if ( dt != st ) {
          s.Text = dt;			// 削除完了
          s.SetAnchorPos( tp );		// 選択範囲を復元
        }
      }
      break;


    // アウトプット / アラート / コンファーム / ステータス
    /**
     * 選択範囲の文字列 st をコピーして、1行下に
     * OutputBar.Writeln( "st" );
     * Alert( "st" );
     * Confirm( "st" );
     * Status = "st";
     * の行を追加する → 追加した行の移動は「行を上/下に移動」マクロで…
     */
    case 1060:  case 1061:  case 1062:  case 1063:
      s.SetActivePoint( mePosLogical, 1, by + 1 );
      // 選択範囲が複数行なら +"\n"+ でつなぐ
      var str = '"' + st.replace( /\n/g , '" + "\\n" + "' ) + '"';
      var sur = ( ( r == 1063 ) ? ";" : " );" ) + "\n";
      s.Text = ( ( r == 1060 ) ? "OutputBar.Writeln( " :
                 ( r == 1061 ) ? "Alert( " :
                 ( r == 1062 ) ? "Confirm( " :
                /* r == 1063 */  "Status = "
               ) + str + sur;
      // カッコの中の文字列を範囲選択する
      s.SetActivePos( s.GetActivePos() - sur.length );
      s.SetAnchorPos( s.GetActivePos() - str.length );
      // アウトプットの場合は、アウトプットバーを表示
      if ( r == 1060 ) {
        ScrollY = s.GetActivePointY( mePosView );
        OutputBar.Visible = true;
      }
      break;


    default:
      break;
  }
}
Redraw = true;


// ------------------------------------------------------------
// 関数
// ------------------------------------------------------------

/* 関数 AddBrackets() */
function AddBrackets( arg0, arg1, arg2 ) {	// AddBrackets( st, p1[r], p2[r] )
  var a = arg0.split( "\n" );			// 選択範囲 st を "\n" で区切って配列 a に
  for ( var i = 0; i < a.length; i ++ ) {
    if ( ! pos && skip && a[i].match( /^\s*$/g ) ) {
      continue;		// skip = true のときは、空白行をスキップ
    }
    // 空行にカッコを挿入する場合は全角スペースをはさむ
    var space = ( ( arg1.length && arg2.length ) && ( pos || ! a[i].length ) ) ? " " : "" ;
    a[i] = arg1 + space + a[i] + arg2;		// 各行をカッコ p1 & p2 で囲う
  }
  return a.join( "\n" );
}


/* 関数 AddWikiLink() */
function AddWikiLink( arg0, arg1, arg2 ) {	// AddWikiLink( st, p1[r], p2[r] )
  var a = arg0.split( "\n" );			// 選択範囲 st を "\n" で区切って配列 a に
  for ( var i = 0; i < a.length; i ++ ) {
    if ( ! pos && skip && a[i].match( /^\s*$/g ) ) {
      continue;		// skip = true のときは、空白行をスキップ
    }
    // 空行には全角スペースつきではさむ
    var bar = ( pos || ! a[i].length ) ? " | " : "|" ;
    a[i] =  arg1 + a[i] + bar + a[i] + arg2;	// 各行を [[str|str]] に置換
  }
  return a.join( "\n" );
}


/* 関数 DeleteCharByNum( st, p1, p2 ) */
function DeleteCharByNum( str, p1, p2 ) {
  var a = str.split( "\n" );
  for ( var i = 0; i < a.length; i ++ ) {
    a[i] = a[i].slice( p1, a[i].length - p2 );	// 各行の先頭/末尾からの指定文字数を削除
  }
  return a.join( "\n" );
}


/* 関数 DeleteBrackets( str, brackets ) */
// 選択範囲の先頭と末尾から1組のカッコを削除する
function DeleteBrackets( str, brackets ) {
  // ループ処理で「対になるカッコ」と一致するかチェック
  for ( var i = 0, len = brackets.length; i < len; i ++ ) {
    if ( i % 2 == 1 || ! brackets[i].length ) {
      continue;
    }
    var o = brackets[ i ];	// 開きカッコ
    var c = brackets[ i + 1 ];	// 閉じカッコ

    // 選択範囲内の先頭と末尾が「対になるカッコ」のとき
    if ( str.length >= o.length + c.length
        && str.slice( 0, o.length ) == o
        && str.slice( - c.length ) == c ) {
      str = str.slice( o.length, - c.length );	// 先頭/末尾のカッコを削除
      break;
    }
  }	// end for
  return str;
}


/* 関数 quote( str ) */
// 『JavaScript/正規表現 - Wikibooks』より
// https://ja.wikibooks.org/wiki/JavaScript/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE
// 
// PerlのquotemetaやRubyのRegExp.quoteのように、()や[]など正規表現のメタ文字と解釈される可能性のある文字をエスケープして返す関数は、Stringオブジェクトのreplaceメソッドを使用して簡単に作成することができます。
function Quote( str ) {
    return str.replace( /\W/g, function( $0 ) {
        return '\\' + $0;
    } );
};


/**
 * 全角から半角への変革関数 toHalfWidth( strVal )
 * 入力値の英数記号を半角変換して返却
 * [引数]   strVal: 入力値
 * [返却値] String(): 半角変換された文字列
 */
// https://webllica.com/add-comma-as-thousands-separator/ より
function ToHalfWidth( strVal ){
  // 半角変換
  var halfVal = strVal.replace( /[!-~]/g,
    function( tmpStr ) {
      // 文字コードをシフト
      return String.fromCharCode( tmpStr.charCodeAt(0) - 0xFEE0 );
    }
  );
  return halfVal;
}


// ----------------------------------------------------------------------------- 
// 以下の2つの関数は破棄してよいかも
// (switch - case 文の中で replace メソッドでの置換処理に変更した)
// -----------------------------------------------------------------------------
/* 
 * 関数 CommentOutJS()
 * このかたちにコメントアウトする
 */
function CommentOutJS( arg1, arg2, arg3, arg4 ) {
  var a = arg1.split( "\n" );			// 選択範囲 st を "\n" で区切って配列 a に
  for ( var i = 0; i < a.length; i ++ )		// 「1行め」から繰りかえし処理
    a[i] = arg4 + a[i];				// 各行の先頭に " * " を追加する

  // 各行を "\n" で区切って連結し、先頭に "/*\n"、末尾に "\n */" を追加する
  return arg2 + a.join( "\n" ) + arg3;
}


/* 
 * 関数 UnCommentJS( arg1 ) 
 * 基本的にこのかたちのコメントブロックしか想定していない(インデントには非対応)。
 * また、複数のコメントブロックがある場合を想定していない。
 * 中間行の行頭記号はアスタリスク「*」と中黒「・」「・」を削除対象とする。
 */ 
function UnCommentJS( arg1 ) {

  var re1 = "^ ?\\/\\*+ ?\\n?";			// 先頭行のコメントマークの正規表現
  var re2 = "\\n? ?\\*+\\/ ?$";			// 末行のコメントマークの正規表現
  var reg = new RegExp( re1 + "|" + re2 , "g" );	// 正規表現 / … /g に変換
  var re3 = /^ ?(\*+|[・・]) ?/;			// 中間行の行頭記号の正規表現
  var a = arg1.split( "\n" );			// 選択範囲 st を "\n" で区切って配列 a に

  // 中間行の行頭記号を削除する
  for ( var i = 0; i < a.length; i ++ ) {	// 「1行め」から繰りかえし処理
    if ( a[i].match( reg ) )			// 先頭行と末行のコメントマークがある行はスキップ
      continue;
    a[i] = a[i].replace( re3 , "" );		// 中間行の行頭記号を削除
  }

  // 各行を "\n" で区切って連結し、先頭行と末行のコメントマークを削除
  return a.join( "\n" ).replace( reg , "" );
}



カッコで囲う (ポップアップメニューなし)

(最終更新 2018/10/26)

簡易版です。

c.f. 追加と削除ができる機能強化版 → 「引用符を追加/削除

特定の種類のカッコを一発で追加する小マクロはキーアサイン集にもありますが、コードを改変して前後に付ける "カッコ" のかわりに "任意の文字列" を指定するばあいに「折り返し」表示と相性のよくない部分があります。

また、マクロ実行後のカーソル位置を選択範囲なしのときと選択範囲ありのときとで変えたいばあいも、こちらのコードがよいでしょう。

#title = "( カッコ )"
#tooltip = "( カッコ ) で囲う"
// MeryWiki の マクロライブラリ >> キーアサイン集 の「括弧で挟む」を改変
// 選択範囲の前後にカッコ以外にも任意の文字列を追加するマクロとしても流用できます

var s = document.selection;

// 選択範囲の各座標を取得
var ax = s.GetTopPointX( mePosLogical );
var ay = s.GetTopPointY( mePosLogical );

// 選択範囲のテキストを取得し、カッコを追加
var st = s.Text;
var pre = "(";	// 前に付ける文字列
var sur = ")";	// 後ろに付ける文字列
s.Text = pre + st + sur;

// カーソルを移動、または範囲選択
if ( ! st )	// 選択範囲なしだったばあい
  s.SetActivePos( s.GetActivePos() - sur.length );	// 後ろに付けた文字列 sur の前にカーソルを移動
else	// 選択範囲があったばあい
  s.SetAnchorPoint( mePosLogical, ax, ay );	// カッコを含めて範囲選択



引用符を追加/削除

(最終更新 2019/03/28)

カッコで囲う (ポップアップメニューなし)」の機能強化版です。

”引用符” を一発で追加する小マクロは 「マテリアルデザインっぽいアイコンと『小マクロ集』」 の 「”引用符”を追加」 にもありますが、こちらのマクロでは 「引用符(または指定した文字列)で囲う」操作と「囲っている引用符を削除する」操作をトグルできます。
※ 後ろにつける文字列の末尾が "\n" の場合はトグル不可。

選択範囲の外側(前と後ろ)が ”引用符” の場合も、(自動的に検出して)削除することができます。


  • 文字列指定は ”引用符” 以外の カッコHTML タグ などの任意の文字列に変更できます。
  • 選択範囲が複数行(論理行)にまたがっている場合に、選択範囲全体 を一組の ”引用符” で囲うか、選択範囲内の「各行ごと」に ”引用符” で囲うかを選択することもできます。
  • マクロ実行後のカーソル位置を選択範囲なしのときと選択範囲ありのときとで変えたい場合には、数種類のパターンから選択できるようになっています。


ソースコード

#title = "''引用符'' で囲う"
#tooltip = "ダブルクォーテーションで囲う"
#icon = "Mery用 マテリアルデザインっぽいアイコン.icl",100

/**
 * -----------------------------------------------------------------------------
 * "引用符" で囲う
 * sukemaru (2018/10/19 - 2019/03/26)
 * -----------------------------------------------------------------------------
 * 選択範囲を指定の文字列("引用符")で囲う
 * 選択範囲がすでに "引用符" で囲われていたら引用符ふたつ "" を削除する
 * 選択範囲外側の外側が "引用符" のときも削除できる
 * 選択範囲が複数行のとき、さいごの改行はふくめない
 * 
 */

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

var pre = '"';		// 前に付ける文字列
var sur = '"';		// 後に付ける文字列
  /**
   * ■"引用符" の文字列を指定
   *
   * ※ 文字列をダブルクォーテーション "" で囲うなら、中の「 " 」は要エスケープ 「'"'」=> 「"\""」
   * ※ 引用符以外の文字列を指定するなら 「'"'」=> 「"ほげ"」「"ふが"」
   *   ただし、改行 \n を含む文字列は想定していない(カーソル位置の復帰が…)。
   * ※ 片側しか必要ないならいずれかを 「'"'」=> 「""」にしてよいが、実行後のカーソルの復帰位置が…
   */


var deleteOuter = true;
  /**
   *  ■外側削除フラグ 
   *
   * ・false で選択範囲内側の先頭/末尾の文字列 pre / sur のみを削除。
   * ・true で選択範囲外側の前後の文字列 pre / sur も削除対象にする。
   * ※ 「複数行フラグ」の true / false によらず、選択範囲全体の外側が対象。
   */


var multiLine = true;
  /**
   * ■複数行フラグ
   *
   * ・false で選択範囲「全体」の前後に文字列 pre / sur を追加
   * ・true で選択範囲の「各行」ごとに文字列 pre / sur で囲う
   */


var insert = false;
  /**
   * ■挿入フラグ
   *
   * ・false では、選択範囲がないときはマクロを中止する
   *   また、「複数行フラグ」が有効のときに、空行には挿入しない
   *   選択範囲の末尾に空行があった場合、マクロ実行後のカーソルの復帰位置が
   *   「終了後フラグ」の説明どおりにならないことがある
   * ・true では、選択範囲がないときにはカーソル位置に pre / sur を挿入する
   *   また、「複数行フラグ」が有効のときに、空行にも挿入する
   * ※ 「複数行フラグ」が有効 のときは、空白文字だけの行は空行と見做す
   */


var endPos = 5;		// 指定できる値は 0 ~ 5 ( 6 以上の値は 0 と同じ)
  /**
   * ■終了後フラグ 
   *
   * 0. カーソルは "引用符" の後ろへ。  (※範囲選択なし)
   * 1. カーソルは最後の "引用符" の中へ移動する。  (※範囲選択なし)
   * 2. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ。  (※要 「挿入フラグ」 = true)
   *    あれば "引用符" の後ろへ移動する。  (※範囲選択なし)
   * 3. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ移動。  (※範囲選択なし)、
   *    あれば "引用符" を含めた全体を選択範囲にする。  (※カーソルは選択範囲の後ろへ) 
   * 4. "引用符" を含めた全体を選択範囲にする。  (※カーソルは選択範囲の後ろへ) 
   * 5. "引用符" を含めた全体を選択範囲にする。  (※カーソル位置はマクロ実行前の側(先頭 or 末尾)へ)
   * 
   *   ※ "引用符" を含めた選択範囲を残すようにすると、
   *     連続実行で 追加 <=> 削除 のトグルができる。( 3 ~ 5 )
   *     ただし、後に付ける文字列の末尾が "\n" の場合、連続実行での 追加 <=> 削除 のトグルはできない。
   *   ※ "マクロ実行前に範囲選択がなければ~" は「挿入フラグ」が有効のときだけ。
   *   ※ 選択範囲を残す場合、マクロ実行前の選択範囲末尾に改行 \n を含んでいたときには
   *   ※ 「複数フラグ」が有効のとき、 "引用符" の中へ移動する「0 と 1」は適さないとおもわれる。
   *   ※ "範囲選択なし" になる「終了後フラグ」で "引用符" を削除したとき、
   *      カーソルの復帰位置は上の説明どおりにはならないことがある。
   */

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


var d = document;
var s = document.selection;	// 選択範囲

// 挿入フラグが無効 ( insert = false ) で 選択範囲がないなら中止
if ( d.ReadOnly || ! insert && s.IsEmpty ) {
  Quit();
}

// 選択範囲がある または 挿入フラグが有効 ( s.length || insert = true ) なら ~
Redraw = false;

var delCount = 0;		// 削除フラグ
var addCount = 0;		// 追加フラグ
var isAdjusted = false;		// 末尾調整フラグ

// 選択範囲の各座標
var anc = s.GetAnchorPos();
var act = s.GetActivePos();
var tp = ( anc < act ) ? anc : act;	// 選択範囲の先頭位置
var bp = ( anc < act ) ? act : anc;	// 選択範囲の末尾位置
// var ty = s.GetTopPointY( mePosLogical );
var bx = s.GetBottomPointX( mePosLogical );
var by = s.GetBottomPointY( mePosLogical );

// 選択範囲の末尾が行頭 x = 1 にあるときの調整(末尾の改行を含めない)
if ( tp < bp && bx == 1 ) {
  s.SetActivePos( tp );
  s.SetAnchorPos( bp - 1 );
  isAdjusted = true;
}

// 選択範囲の文字列を取得
var st = s.Text;

// 外側フラグが有効のとき
if ( deleteOuter ) {
  // 選択範囲外側の前後の文字列が "引用符" なら削除する
  // ※削除したときの戻り値は delCount = 1
  DeleteOuterBrackets( st, pre, sur );
}

// AddDelBrackets() で "引用符" を追加/削除
if ( ! delCount ) {
  var ad = AddDelBrackets( st, pre, sur );
  if ( delCount || addCount ) {
    s.Text = ad;
  }
  // AddDelBrackets() 処理の前後で文字列に変化がないなら
  // 選択範囲を復帰する(undo 履歴を残さない)
  else {
    s.SetActivePos( act );
    s.SetAnchorPos( anc );
    Quit();
  }
}
// カーソルは "引用符" のうしろ
var dp = s.GetActivePos();

// 終了後フラグの指定動作  ※カーソルを移動/選択範囲を復旧
FinalSelection();	

Redraw = true;
Quit();


// ---------- ▼ 関数 ▼ ----------

/**
 * 関数 FinalSelection() 
 *   終了後フラグの指定動作  ※カーソルを移動/選択範囲を復旧
 *   0. カーソルは "引用符" の後ろへ。  (※範囲選択なし)
 *   1. カーソルは最後の "引用符" の中へ移動する。  (※範囲選択なし)
 *   2. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ。  (※要 挿入フラグ = true)
 *   あれば "引用符" の後ろへ移動する。  (※範囲選択なし)
 *   3. マクロ実行前に範囲選択がなければカーソルは最後の "引用符" の中へ移動。  (※範囲選択なし)、
 *   あれば "引用符" を含めた全体を選択範囲にする。  (※カーソルは選択範囲の後ろへ) 
 *   4. "引用符" を含めた全体を選択範囲にする。  (※カーソルは選択範囲の後ろへ) 
 *   5. "引用符" を含めた全体を選択範囲にする。  (※カーソル位置はマクロ実行前の側(先頭 or 末尾)へ)
 */
function FinalSelection() {
  // 0. カーソルは "引用符" のうしろ 
  // ※範囲選択なし(末尾調整されたままの位置)
  switch ( endPos ) {

    // 1. カーソルは "引用符" の中へ移動する  ※範囲選択なし
    case 1:
      SearchCloseBracket ();
      break;

    // 2. マクロ実行前に範囲選択がなければカーソルは "引用符" の中へ
    //    あれば選択範囲の後ろへ移動する  ※範囲選択なし
    case 2:
      // マクロ実行前に選択範囲がなかったとき → case 1 と同じ
      if ( ! st ) {
        SearchCloseBracket();
      }
      break;

    // 3. マクロ実行前に範囲選択がなければカーソルは "引用符" の中へ移動  ※範囲選択なし
    //    あれば "引用符" を含めた全体を選択範囲にする  ※カーソルは選択範囲の後ろへ
    case 3:
      // マクロ実行前に選択範囲がなかったとき → case 1 と同じ
      if ( ! st ) {
        SearchCloseBracket();
      }
      // マクロ実行前に選択範囲があったとき → case 2 と同じ
      else {
        MoveToEndPos();
        s.SetAnchorPos( tp );	// 先頭まで範囲選択
      }
      break;

    // 4. "引用符" を含めた全体を選択範囲にする 
    // ※カーソルは選択範囲の後ろへ(末尾位置を復帰)
    case 4:
      MoveToEndPos();
      s.SetAnchorPos( tp );
      break;

    // 5. "引用符" を含めた全体を選択範囲にする(末尾位置を復帰)
    // ※カーソル位置はマクロ実行前の側(先頭 or 末尾)へ
    case 5:
      MoveToEndPos();
      // マクロ実行前のキャレットの位置が末尾だったとき
      if ( anc <= act ) {
        s.SetAnchorPos( tp );
      }
      // マクロ実行前のキャレットの位置が先頭だったとき
      else {	
        s.SetActivePos( tp, true );
      }
      break;

    default:
      break;
  }
}

/* 関数 AddDelBrackets() */ 
function AddDelBrackets( str, o, c ) {	// ← AddDelBrackets( st, pre, sur )

  // ■複数行フラグ ( multiLine ) にしたがい選択範囲 st を配列 a に
  var a = ( multiLine ) ? str.split( "\n" ) : [ str ];

  for ( var i = 0, len = a.length; i < len; i ++ ) {

    // 選択範囲がカッコで囲われているときは、各行のカッコを削除
    if ( a[i].slice( 0, o.length ) == o
        && a[i].slice( - c.length ) == c ) {
      a[i] = a[i].slice( o.length, a[i].length - c.length );
      delCount ++;	// 削除フラグ
    }
    // 選択範囲がカッコで囲われていないとき
    // 挿入フラグが有効ならカッコをつける
    else if ( insert || ! a[i].match( /^[\s ]*$/g ) ) {
      a[i] = o + a[i] + c;
      addCount ++;	// 追加フラグ
    }
    // 挿入フラグが無効のときの空白行はスルー
    else {
      continue;
    }
  }

  return a.join( "\n" );
}

/* 関数 DeleteOuterBrackets() */ 	// ← DeleteOuterBrackets( st, pre, sur )
function DeleteOuterBrackets( str, o, c ) {

  // 選択範囲外側の前後の文字列が "引用符" なら削除する
  if ( d.Text.slice( tp - o.length, tp ) == o
      && d.Text.slice( bp, bp + c.length ) == c ) {
    s.SetActivePos( tp - o.length );
    s.SetAnchorPos( bp + c.length );
    s.Text = s.Text.slice( o.length, - c.length );

    tp = tp - o.length;		// 先頭の座標を調整
    delCount ++;
  }
  return delCount;		// 戻り値として削除フラグを返す
}

/* 関数 SearchCloseBracket() */ 
// カーソルを最後の閉じカッコの前へ移動  ※範囲選択なし
// ※閉じカッコ sur が未指定 "" の場合は、末尾のまま
function SearchCloseBracket() {
  if ( delCount ) {
    // カッコを削除したときは、末尾のまま
    s.SetActivePos( dp );
  }
  else if ( addCount ) {
    // カッコを追加したときは、選択範囲内の最後の閉じカッコの前へ
    s.SetActivePos( dp - sur.length );
  }
}

/* 関数 MoveToEndPos() */ 
// マクロ実行前に選択範囲があったとき、カーソルを元の選択範囲の末尾位置へ移動 
// ※範囲選択なし
function MoveToEndPos() {
  // 選択範囲の末尾調整をしていたときは、カーソルを元の末尾位置に復帰
  if ( isAdjusted ) {
    s.SetActivePoint( mePosLogical, 1, by );
  }
  // 末尾調整をしていなかったときは、カーソル位置はそのまま
  else {
    s.SetActivePos( dp );
  }
}


メモ

  • 2018/08/24 (sukemaru)
ページを新規作成
  • 2018/08/26 (sukemaru)
「カッコで囲う (ポップアップメニューなし)」の節を追加
  • 2018/08/27 (sukemaru)
・「カッコで囲う (ポップアップメニューあり)」のソースコードを修正
・case1~8 の "s.CharLeft( false, p2[r].length );" を "s.SetActivePos( s.GetActivePos() - p2[r].length );" に変更
  • 2018/10/12 (sukemaru)
「カッコで囲う (ポップアップメニューあり)」のソースコードに "3文字ずつ前後を削除" を追加
組みこみ用コード「wiki用 文字列装飾」と「挿入型コメントアウト」の節を追加
「カッコで囲う.zip」のダウンロードリンクを追加
  • 2018/10/13 - 2018/10/16 (sukemaru)
・マクロのコードを微修正
・「カッコで囲う.zip」を差し替え
  • 2018/10/19 (sukemaru)
・「引用符を追加/削除」の節を追加
・「カッコで囲う.zip」を差し替え
  • 2018/10/26 (sukemaru)
・コードの体裁を修正 (※変数名を変更したので、追加コードは最新の「カッコで囲う」でないとエラーになる)
・各マクロの動作コードを変更し、実行後の文字列に変化なしになる場合に undo 履歴を残さないようにした
・追加コード「任意の文字列」の項目を追加
・追加コードの「JS コメントアウト1」と「XML コメントアウト」のコードをまとめた
・追加コードの「JS アンコメント」で先頭/末尾のコメントマーク /* */ がある行では中間行の行頭記号を削除しないようにした
・「引用符を追加/削除」の終了後の動作コードを変更し、不自然な位置にキャレットが移動する不具合を修正した
・「カッコで囲う.zip」を差し替え
  • 2018/10/29 (sukemaru)
・「カッコで囲う (ポップアップメニューあり)」の節を更新(本体のソースコードに追加コードを包摂)
・「カッコで囲う (ポップアップメニューあり)」のメニュー項目に「任意の文字列2」を追加
・「カッコで囲う (ポップアップメニューあり)」のソースコードをまとめてページ下部に移動
・「カッコで囲う.zip」を差し替え
  • 2018/11/19 (sukemaru)
・「カッコで囲う (ポップアップメニューあり)」用の人柱版追加コード「行頭/行末から任意の 文字数 を削除」「行頭/行末から任意の 文字列 を削除」を追加
  • 2019/03/28 (sukemaru)
・「カッコで囲う (ポップアップメニューあり)」のコードを増補・改変。人柱版追加コードを統合。
・「JS コメントアウト/アンコメント」を正規表現置換メソッドに変更
・「任意の 文字数/文字列 を削除」を追加
・「行頭/行末の空白を削除」を追加
・「1文字ずつ前後を削除(外)」を追加
・「ひとつ削除」を追加(「カッコをはずす」マクロから転用)
・「アウトプット/アラート/コンファーム/ステータス」を追加
・「カッコの定義」を使わないコマンドの ID を 1030~ に変更
・ サブメニューを追加してネスト化
・「引用符を追加/削除」に選択範囲の外側の”引用符”の削除機能を追加
・「引用符を追加/削除」の終了時の動作コードを再変更
・「カッコで囲う.zip」を差し替え



動作の不具合などがあったらお知らせ下さい。(sukemaru)◆

スポンサーリンク