「
カッコで囲う
」を編集中 (節単位)
ナビゲーションに移動
検索に移動
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、さまざまなメリットもあります。
スパム攻撃防止用のチェックです。 決して、ここには、値の入力は
しない
でください!
== 引用符を追加/削除 == (最終更新 2020-06-23) 「[[#カッコで囲う (ポップアップメニューなし)|カッコで囲う (ポップアップメニューなし)]]」の機能強化版です。 ”引用符” を一発で追加する小マクロは 「マテリアルデザインっぽいアイコンと『小マクロ集』」 の 「[[マテリアルデザインっぽいアイコンと『小マクロ集』#”引用符”を追加|”引用符”を追加]]」 にもありますが、こちらのマクロでは 「引用符(または指定した文字列)で囲う」操作と「囲っている引用符を削除する」操作を '''トグル''' できます。 ※ 後ろにつける文字列の末尾が "'''\n'''" の場合はトグル不可。 <u>'''選択範囲の外側'''(前と後ろ)が ”引用符” の場合も、(自動的に検出して)削除することができます。</u> * 文字列指定は ”引用符” 以外の '''カッコ''' や '''HTML タグ''' などの任意の文字列に変更できます。 * 選択範囲が複数行(論理行)にまたがっている場合に、'''選択範囲全体''' を一組の ”引用符” で囲うか、選択範囲内の「'''各行ごと'''」に ”引用符” で囲うかを選択することもできます。 * マクロ実行後のカーソル位置を'''選択範囲なし'''のときと'''選択範囲あり'''のときとで変えたい場合には、数種類のパターンから選択できるようになっています。 カッコの追加/削除トグルの姉妹版マクロとして [[カッコをはずす|「カッコを削除/追加」、「カッコを追加/削除」]]があります。 === ソースコード === <syntaxhighlight lang="javascript" style="height:80em; overflow:auto;"> #title = "''引用符'' で囲う" #tooltip = "ダブルクォーテーションで囲う" #icon = "quote_4[2].ico" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",100 /** * ----------------------------------------------------------------------------- * "引用符" で囲う * sukemaru (2018-10-19 - 2020-06-23) * ----------------------------------------------------------------------------- * (Last modified: 2020-06-23) * マルチカーソル/複数選択範囲に対応 * (2020-06-03) * 終了後フラグ endPos = 3 での終了後のカーソル位置を調整 * * 選択範囲を指定の文字列("引用符")で囲う * 選択範囲がすでに "引用符" で囲われていたら引用符ふたつ "" を削除する * 選択範囲外側の外側が "引用符" のときも削除可 * 選択範囲が複数行のとき、さいごの改行はふくめない * */ // ---------- ▼ 設定項目 ▼ ---------- 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 = editor.ActiveDocument, s = d.selection; if ( d.ReadOnly ) { Status = " ドキュメントは書き換え禁止です。"; } // 挿入フラグが無効 ( insert = false ) で 選択範囲がないなら中止 else if ( ! insert && s.IsEmpty ) { Status = " 選択範囲がありません。"; } // 選択範囲がある または 挿入フラグが有効 ( s.length || insert = true ) なら ~ else { var sx = ScrollX, sy = ScrollY; // マルチカーソル対応 var arg = [ pre, sur, deleteOuter, multiLine, insert, endPos ]; // 選択範囲が1つで矩形選択ではないとき if ( ! s.Mode || s.Mode === meModeStream ) { AddDeleteQuote_Main( arg ); } // 複数行または複数選択のとき else { BeginUndoGroup(); AddUndo(); MultiFunction( AddDeleteQuote_Main, arg ); EndUndoGroup(); } ScrollX = sx; ScrollY = sy; } /** * 関数 AddDeleteQuote_Main( [ pre, sur, deleteOuter, multiLine, insert, endPos ] ) * 「引用符を追加/削除」マクロ * サブ関数群は適切に引数を設定していないので * Main の関数スコープ内に含める */ function AddDeleteQuote_Main( arg ) { var pre = arg[0]; var sur = arg[1]; var deleteOuter = arg[2]; var multiLine = arg[3]; var insert = arg[4]; var endPos = arg[5]; var delCount = 0; // 削除フラグ var addCount = 0; // 追加フラグ var isAdjusted = false; // 末尾調整フラグ // 選択範囲の各座標 var d = editor.ActiveDocument, s = d.selection; var anc = s.GetAnchorPos(), act = s.GetActivePos(); var tp = Math.min( anc, act ); var bp = Math.max( anc, act ); 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 delCount = DeleteOuterBrackets( st, pre, sur ); } // AddDelBrackets() で "引用符" を追加/削除 if ( ! delCount ) { var tmp = AddDelBrackets( st, pre, sur ); if ( delCount || addCount ) { s.Text = tmp; } // AddDelBrackets() 処理の前後で文字列に変化がないなら // 選択範囲を復帰する(undo 履歴を残さない) else { s.SetActivePos( act ); s.SetAnchorPos( anc ); } } if ( s.IsEmpty ) { // カーソルは "引用符" のうしろ var dp = s.GetActivePos(); // 終了後フラグの指定動作 ※カーソルを移動/選択範囲を復旧 FinalSelection(); } // ---------- ▼ 関数 ▼ ---------- /** * 関数 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 == tp ) { s.SetAnchorPos( tp ); } // マクロ実行前のキャレットの位置が先頭だったとき else { s.SetActivePos( tp, true ); } break; default: break; } } /* 関数 AddDelBrackets() */ function AddDelBrackets( str, o, c ) { // ■複数行フラグ ( 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 || /[^\s ]/.test( a[i] ) ) { a[i] = o + a[i] + c; addCount ++; // 追加フラグ } // 挿入フラグが無効のときの空白行はスルー else { continue; } } return a.join( "\n" ); } /* 関数 DeleteOuterBrackets() */ 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() */ // カーソルを最後の閉じカッコの前へ移動 ※範囲選択なし function SearchCloseBracket() { // カッコを削除したときは、末尾のまま if ( delCount ) { s.SetActivePos( dp ); } // カッコを追加したときは、選択範囲内の最後の閉じカッコの前へ else { var Quote = function( str ) { return str.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ); }; if ( sur.length || addCount ) { s.SetAnchorPos( tp ); s.SetActivePos( tp + s.Text.lastIndexOf( s.Text.match( Quote( sur ) ) ) ); } // 閉じカッコ sur が未指定 "" の場合は、末尾のまま } } /* 関数 MoveToEndPos() */ // マクロ実行前に選択範囲があったとき、カーソルを元の選択範囲の末尾位置へ移動 // ※範囲選択なし function MoveToEndPos() { // 選択範囲の末尾調整をしていたときは、カーソルを元の末尾位置に復帰 if ( isAdjusted ) { s.SetActivePoint( mePosLogical, 1, by ); } // 末尾調整をしていなかったときは、カーソル位置はそのまま else { s.SetActivePos( dp ); } } } /** * 関数 MultiFunction( Fn, arg1 ) * マルチカーソル(複数選択範囲)に対応させる * 第1引数: Function; 選択範囲ごとに適用する処理の関数 * 第2引数以降: Function に渡す引数をまとめた配列 */ function MultiFunction( Fn, arg ) { var d = editor.ActiveDocument; var s = d.selection; // 矩形選択範囲は行に分ける s.Mode = meModeMulti; // 選択範囲の座標を取得 var sCount = s.Count; var Sel = []; for ( var i = 0; i < sCount; i ++ ) { Sel[i] = { act: s.GetActivePos( i ), anc: s.GetAnchorPos( i ) }; } // 各選択範囲を処理; for ( var i = 0, diff = 0, dl; i < sCount; i ++ ) { dl = d.TextLength; s.SetActivePos( Sel[i].act + diff ); s.SetAnchorPos( Sel[i].anc + diff ); Fn( arg ); // AddDeleteQuote_Main() 関数 // Fn() の残した選択範囲(またはキャレット位置)を回収 Sel[i].act = s.GetActivePos(); Sel[i].anc = s.GetAnchorPos(); diff += d.TextLength - dl; // 文字数の増減量(累積) } // マルチカーソル(複数選択範囲)を復帰 for ( var i = 0; i < sCount; i ++ ) { s.AddPos( Sel[i].anc, Sel[i].act ); } } </syntaxhighlight>
編集内容の要約:
MeryWikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MeryWiki:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の数式を計算してその答えを欄に入力してください (
ヘルプ
):
いちたすには =
キャンセル
編集ヘルプ
(新しいウィンドウで開きます)
スポンサーリンク
ナビゲーション メニュー
個人用ツール
ログインしていません
トーク
投稿記録
アカウント作成
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
編集
履歴表示
その他
検索
スポンサーリンク
スポンサーリンク
案内
メインページ
ヘルプ
よくある質問
マクロリファレンス
マクロライブラリ
プラグインライブラリ
構文ファイル
テーマ
寄付・開発支援
練習用ページ
開発室
開発者のブログ
ツール
スポンサーリンク