|
|
| (他の1人の利用者による、間の5版が非表示) |
| 1行目: |
1行目: |
| | =マクロ「テキスト整形」の仕様変更について (2019/05/01)= |
| | マクロ「テキスト整形」の処理の流れを「前処理」「本処理」「後処理」の3段階に分けて考えたとき、モード (F/R/RS) 別に異なっていた流れを統合し、モードを廃止しようと考えています。 |
| | |
| | {|class="wikitable" |
| | !colspan="4"| 旧仕様 |
| | |- |
| | ! モード !! 前処理 !! 本処理 !! 後処理 |
| | |- |
| | ! F |
| | | なし |
| | | 引数に Selection を渡して処理 |
| | | なし |
| | |- |
| | ! R |
| | | なし |
| | |rowspan="2"| 引数に Selection.Text を渡して処理 |
| | |rowspan="2"| 戻り値で選択範囲を置換、再選択 |
| | |- |
| | ! RS |
| | | 選択範囲を行全体に拡張 |
| | |- |
| | !colspan="4"| 新仕様 |
| | |- |
| | | |
| | | オプションで指定 |
| | | 第1引数に Selection.Text を、<br>第2引数に Selection を渡して処理 |
| | | 戻り値で置換・再選択を制御 |
| | |} |
| | |
| | ==後処理:戻り値による選択範囲の置換・再選択の制御== |
| | Mery 2.7.0 にて「マクロで Chakra (jscript9.dll) における [[マクロリファレンス:Window_インターフェイス#Quit_メソッド|Quit メソッド]]をサポート外にした」([https://www.haijin-boys.com/software/mery/mery-2-7-0 公式記事])ことを受け、戻り値により後処理(選択範囲の置換・再選択)を制御できる仕組みを導入します。 |
| | |
| | String (文字列) か Array (配列) を return すると、選択範囲を置換してカーソルを移動します。それ以外 (undefined など) の場合は、選択範囲に対し何もしません。<br> |
| | <code>Quit();</code> (処理を中断) の代替策として <code>return;</code> (undefined を返す) などとすることで処理を終了させることができます。 |
| | |
| | <syntaxhighlight lang="javascript"> |
| | f.push(["例1","",function(){ |
| | return "abcd" }]); |
| | f.push(["例2","",function(){ |
| | return ["ab","cd"] }]); |
| | f.push(["例3","",function(){ |
| | return ["ab","cd",""] }]); |
| | f.push(["例4","",function(){ |
| | return; }]); |
| | </syntaxhighlight> |
| | {|class="wikitable" |
| | ! 例 !! 動作 |
| | |- |
| | | <code>"abcd"</code> || abcd に置換後、abcd を選択 = <code>["","abcd",""]</code> |
| | |- |
| | | <code>["ab","cd"]</code> || abcd に置換後、ab と cd の間に移動 |
| | |- |
| | | <code>["ab","cd",""]</code> || abcd に置換後、cd を選択 |
| | |- |
| | | String / Array 以外 || 選択範囲に対し何もしない |
| | |} |
| | |
| | ==本処理:第2引数を復活== |
| | マクロ「[[テキスト変換]]」の第2引数を復活し、第1引数に Document.Selection.Text を、第2引数に Document.Selection を渡すようにします。 |
| | |
| | 「テキスト整形」で第2引数を削除したのは、「テキスト変換」で Selection を利用したコマンドが無かったこと、戻り値で選択範囲が置換されるため Selection を利用しづらいと感じたことが理由でした。 |
| | |
| | 「テキスト整形」でモード F を設け分離したのも、そうした理由によりますが、戻り値で選択範囲を置換するかしないか制御できるようになったため状況が変わりました。 |
| | |
| | ==前処理:モードを廃止、オプションに変更== |
| | 「モード」を「オプション」に変更し、機能を追加します。 |
| | {|class="wikitable" |
| | | <code>s</code> || 実行に範囲選択を要求 (require selection)<br>非選択時はメニュー項目がグレーになり実行不可 |
| | |- |
| | | <code>c</code> || 実行にクリップボードを要求 (require clipboard)<br>貼り付けが行えない状況では同上 |
| | |- |
| | | <code>L</code> || 行選択してから処理 (select Line)<br>モード RS はオプション L に変更 |
| | |- |
| | | <code>O</code> || 非選択時はすべて選択してから処理 (select OR all)<br>※実験的機能(変更・廃止の可能性あり) |
| | |} |
| | * 複数指定する場合、空白で区切ります。順序は問いません。 |
| | * モードは必須でしたが、オプションは任意です。 |
| | * 上記以外の文字(オプション)を指定してもエラーにはなりません。<br>モード F/R/RS はオプション F/R/RS と認識されるが効果は無い、ということになります。 |
| | |
| | ==旧仕様から新仕様への移行方法== |
| | 移行を補助するコマンドを用意しました。 |
| | |
| | ※新仕様の基本コード用。旧仕様で使用する場合は、オプション "L" をモード "RS" に書き換えてください。 |
| | <pre> |
| | f.push(["拡張コードを旧→新仕様に変換","L",function(_){ //2019/06/01 |
| | return _.replace(/^(\s*(?:\/\/[\/\s]*)?)f\.push\(\[("[^\\"]*(?:\\.[^\\"]*)*"|'[^\\']*(?:\\.[^\\']*)*'),"(RS?|F)",function\(([$0-9A-Za-z_]*)\)/gm,function(_,cmnt,name,mode,arg){return cmnt+'f.push(['+name+',"'+(mode==="RS"?"L":"")+'",function('+(mode==="F"&&arg?"_,":"")+arg+')'}) }]); |
| | </pre> |
| | 旧仕様のコマンドに対し、上記のコマンドを実行すると、以下のように置換され、新仕様の基本コードで問題なく動作するようになります。 |
| | ;モード F |
| | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><samp>f.push(["コマンド名","<span style="background:#fcc;">F</span>",function(a) 以下略</samp></p> |
| | :↓ |
| | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><samp>f.push(["コマンド名","",function(<span style="background:#fcc;">_,</span>a) 以下略</samp></p> |
| | ;モード R |
| | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><samp>f.push(["コマンド名","<span style="background:#fcc;">R</span>",function(a) 以下略</samp></p> |
| | :↓ |
| | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><samp>f.push(["コマンド名","",function(a) 以下略</samp></p> |
| | ;モード RS |
| | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><samp>f.push(["コマンド名","<span style="background:#fcc;">RS</span>",function(a) 以下略</samp></p> |
| | :↓ |
| | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><samp>f.push(["コマンド名","<span style="background:#fcc;">L</span>",function(a) 以下略</samp></p> |
| | |
| | ==変更点まとめ== |
| | {|class="wikitable" |
| | ! 機能 !! 旧仕様 !! 新仕様 !! 備考 |
| | |- |
| | ! モード F |
| | |style="background:#cfc;"| 利用可 ||style="background:#fc6;"| 動作不良 |
| | | 引数を利用しているものは動作しなくなります |
| | |- |
| | ! モード R |
| | |style="background:#cfc;"| 利用可 ||style="background:#fc6;"| 動作可 |
| | | 動作しますが、モード名の R は不要です(削除推奨) |
| | |- |
| | ! モード RS |
| | |style="background:#cfc;"| 利用可 ||style="background:#fc6;"| 動作不良 |
| | | 動作しますが、行選択はされなくなります |
| | |- |
| | ! 戻り値制御 |
| | |style="background:#fc6;"| 動作不良 ||style="background:#cfc;"| 利用可 |
| | | 旧仕様では文字列以外に非対応、モード F では利用不可 |
| | |- |
| | ! 第2引数 |
| | |style="background:#fcc;"| 利用不可 ||style="background:#cfc;"| 利用可 |
| | | モード F は第2引数利用に移行 |
| | |- |
| | ! オプション |
| | |style="background:#fcc;"| 利用不可 ||style="background:#cfc;"| 利用可 |
| | | モード RS はオプション L に移行 |
| | |} |
| | |
| | ==記事ソースから拡張コードを抽出== |
| | 「テキスト整形」の記事ソースから拡張コードを抽出するコマンドを用意しました。 |
| | |
| | ※新仕様の基本コード用。文書全体を対象に置換が行われます。 |
| | <pre> |
| | f.push(["記事ソースから拡張コードを抽出","",function(_,$){ //2019/12/21 |
| | $.SelectAll(); var src=$.Text.match(/(?:^|\n)=拡張コード=\n[\s\S]*?(\n==[\s\S]*?)(?:\n=拡張コード:書式=\n|$)/); if(src)$.Text=src[1].replace(/\n==([^=]+)==\n([\s\S]*?)(?=\n==[^=]|$)/g,function(_,ctg,src){var cmd=[], res, re=new RegExp(/^<pre(?: [^>]*)?>\s*(f\.push\(\[[\s\S]*?\]\);)\s*<\/pre>/gm); while(res=re.exec(src)){cmd.push(res[1].replace(/&amp;/g,"&"))} return 'f.push(["'+ctg+'",function(f){\n\n'+ cmd.join("\n\n") +'\n\n}]);\n\n'}).slice(0,-1) }]); |
| | </pre> |
| | <b>使用手順</b> |
| | # 「[[テキスト整形]]」の記事上部にある [編集] タブをクリックする。<br>または、記事の「[[テキスト整形#拡張コード|拡張コード]]」見出しの [編集] リンクをクリックする。 |
| | # 記事編集ページに移動するので、テキストボックス内の文章をすべて選択し、コピーする。<br>※テキストボックス内を右クリックしてメニューから実行するのが一番わかりやすいと思われます。 |
| | #* コピーした後は戻る(ブラウザバック)か閉じるかして記事編集ページから離れてください。 |
| | # Mery で文書を新規作成し、コピーした文章を貼り付ける。 |
| | # 「テキスト整形」マクロを起動し、「記事ソースから拡張コードを抽出」コマンドを実行する。 |
| | |
| =マクロ「テキスト整形」の仕様変更について (2015/02/14)= | | =マクロ「テキスト整形」の仕様変更について (2015/02/14)= |
|
| |
|
| ==モード R/RS 実行後、処理した範囲を選択し直すように== | | ==モード R/RS 実行後、処理した範囲を選択し直すように== |
| <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><code>旧仕様では、コマンド実行後は<span style="background:#bfdfff; border-right:2px solid;">範囲選択が 解 除 されました。↵<br>新仕様では、コマンド実行前に選択範囲を 記 憶 し、実行後に 復 元 します。↵<br>処理の結果、字数が 増 減 した場合は、選択範囲が 調 整 </span>されます。↵</code></p> | | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;">旧仕様では、コマンド実行後は<span style="background:#bfdfff; border-right:2px solid;">範囲選択が 解 除 されました。↵<br>新仕様では、コマンド実行前に選択範囲を 記 憶 し、実行後に 復 元 します。↵<br>処理の結果、字数が 増 減 した場合は、選択範囲が 調 整 </span>されます。↵</p> |
| :↓ コマンド「空白文字を除去」実行 | | :↓ コマンド「空白文字を除去」実行 |
| <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><code>旧仕様では、コマンド実行後は<span style="background:#bfdfff; border-right:2px solid;">範囲選択が解除されました。↵<br>新仕様では、コマンド実行前に選択範囲を記憶し、実行後に復元します。↵<br>処理の結果、字数が増減した場合は、選択範囲が調整</span>されます。↵</code></p> | | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;">旧仕様では、コマンド実行後は<span style="background:#bfdfff; border-right:2px solid;">範囲選択が解除されました。↵<br>新仕様では、コマンド実行前に選択範囲を記憶し、実行後に復元します。↵<br>処理の結果、字数が増減した場合は、選択範囲が調整</span>されます。↵</p> |
|
| |
|
| この変更により、コマンドの効果範囲が目視できるようになり、また、選択し直す手間なく別の処理に移ることができるようになります。 | | この変更により、コマンドの効果範囲が目視できるようになり、また、選択し直す手間なく別の処理に移ることができるようになります。 |
| 11行目: |
156行目: |
| * コマンド実行中にカーソル位置を移動させる処理がある場合には対応できません。 | | * コマンド実行中にカーソル位置を移動させる処理がある場合には対応できません。 |
|
| |
|
| ==モード RM の廃止== | | ==モード RM を廃止== |
| モード RM (一行ごとに処理) は、マクロ「[[テキスト変換]]」の関数タイプ replaceL に相当し、モード RS で実現可能な処理をより簡素に記述するために設けられた機能です。<br> | | モード RM (一行ごとに処理) は、マクロ「[[テキスト変換]]」の関数タイプ replaceL に相当し、モード RS で実現可能な処理をより簡素に記述するために設けられた機能です。<br> |
| しかし、以下のような難点が見受けられることから、廃止を考えるに至りました。 | | しかし、以下のような難点が見受けられることから、廃止を考えるに至りました。 |
| 17行目: |
162行目: |
| * モード RS で実現可能=代替可能であり、RM ならではの利点が無い。 | | * モード RS で実現可能=代替可能であり、RM ならではの利点が無い。 |
| * モード R/RS に比べ処理が異質で、コマンドを作る際はそれを考慮しなければならない。<br>※異質=R/RS が「選択範囲の文字列」を対象に処理を行うのに対し、RM は「選択範囲の各行の文字列」を対象に処理を行う。 | | * モード R/RS に比べ処理が異質で、コマンドを作る際はそれを考慮しなければならない。<br>※異質=R/RS が「選択範囲の文字列」を対象に処理を行うのに対し、RM は「選択範囲の各行の文字列」を対象に処理を行う。 |
| <source lang="javascript" style="word-wrap:break-word;"> | | <syntaxhighlight lang="javascript"> |
| //※モード RM では「クロージャ」という仕組みを使用する必要があり難解 | | //※モード RM では「クロージャ」という仕組みを使用する必要があり難解 |
| f.push(["各行行頭に文字列付加...","RM",(function(a){ | | f.push(["各行行頭に文字列付加...","RM",(function(a){ |
| 24行目: |
169行目: |
| f.push(["各行行頭に文字列付加...","RS",function(a){ | | f.push(["各行行頭に文字列付加...","RS",function(a){ |
| var p=Prompt("各行行頭に付加する文字列:",""); if(!p)Quit(); return a.replace(/^/gm,p) }]); | | var p=Prompt("各行行頭に付加する文字列:",""); if(!p)Quit(); return a.replace(/^/gm,p) }]); |
| </source> | | </syntaxhighlight> |
| <source lang="javascript" style="word-wrap:break-word;"> | | <syntaxhighlight lang="javascript"> |
| //※モード RM でも、 | | //※モード RM でも、 |
| f.push(["空白行を削除","RM",function(a){ | | f.push(["空白行を削除","RM",function(a){ |
| 32行目: |
177行目: |
| f.push(["空白行を削除","RS",function(a){ | | f.push(["空白行を削除","RS",function(a){ |
| return a.replace(/^[ \t]*$\n?/gm,"") }]); | | return a.replace(/^[ \t]*$\n?/gm,"") }]); |
| </source> | | </syntaxhighlight> |
| <source lang="javascript" style="word-wrap:break-word;"> | | <syntaxhighlight lang="javascript"> |
| //※モード RM なら正規表現に頼らず簡素に記述できるコマンドもあるが、 | | //※モード RM なら正規表現に頼らず簡素に記述できるコマンドもあるが、 |
| f.push(["インデント(半角空白2個)","RM",function(a){ | | f.push(["インデント(半角空白2個)","RM",function(a){ |
| 44行目: |
189行目: |
| f.push(["行頭 \/\/ を付加/削除","RS",function(a){ | | f.push(["行頭 \/\/ を付加/削除","RS",function(a){ |
| return a.replace(/^(\/\/)?/gm,function(s){return s? "": "\/\/"}) }]); | | return a.replace(/^(\/\/)?/gm,function(s){return s? "": "\/\/"}) }]); |
| </source> | | </syntaxhighlight> |
|
| |
|
| ==モード CR の廃止、String.replaceBatch メソッドの追加== | | ==モード CR を廃止、replaceBatch メソッドを追加== |
| モード CR (連続置換) は、<code>replace</code> を連鎖させる記法(メソッドチェーン)をより簡素に記述するために設けられた機能です。 | | モード CR (連続置換) は、<code>replace</code> を連鎖させる記法(メソッドチェーン)をより簡素に記述するために設けられた機能です。 |
| <source lang="javascript"> | | <syntaxhighlight lang="javascript"> |
| f.push(["コマンド名","R",function(a){ | | f.push(["コマンド名","R",function(a){ |
| return a.replace(/ABC/g,"DEF").replace(/\(1\)/g,"①").replace(/GHI/gi,"JKL") }]); | | return a.replace(/ABC/g,"DEF").replace(/\(1\)/g,"①").replace(/GHI/gi,"JKL") }]); |
| 54行目: |
199行目: |
| f.push(["コマンド名","CR",function(a){ | | f.push(["コマンド名","CR",function(a){ |
| return [ ["ABC","DEF"],["(1)","①"],[/GHI/gi,"JKL"] ]}]); | | return [ ["ABC","DEF"],["(1)","①"],[/GHI/gi,"JKL"] ]}]); |
| </source> | | </syntaxhighlight> |
| しかし、モードの一種としたがゆえに、他のモードでは利用できない事、<code>replace</code> のような使い方ができない事が難点としてありました。<br> | | しかし、モードの一種としたがゆえに、他のモードでは利用できない事、<code>replace</code> のような使い方ができない事が難点としてありました。<br> |
| <code>replaceBatch</code> メソッドは、この難点を解消するために設けられる機能です。 | | <code>replaceBatch</code> メソッドは、この難点を解消するために設けられる機能です。 |
| <source lang="javascript"> | | <syntaxhighlight lang="javascript"> |
| //※モード R で利用する(基本形) | | //※モード R で利用する(基本形) |
| f.push(["コマンド名","R",function(a){ | | f.push(["コマンド名","R",function(a){ |
| 67行目: |
212行目: |
| f.push(["コマンド名","F",function(a){ | | f.push(["コマンド名","F",function(a){ |
| a.Text = a.Text.replaceBatch([ ["ABC","DEF"],["(1)","①"],[/GHI/gi,"JKL"] ]) }]); | | a.Text = a.Text.replaceBatch([ ["ABC","DEF"],["(1)","①"],[/GHI/gi,"JKL"] ]) }]); |
| </source> | | </syntaxhighlight> |
| <source lang="javascript"> | | <syntaxhighlight lang="javascript"> |
| //※replace のようにメソッドチェーンが可能 | | //※replace のようにメソッドチェーンが可能 |
| f.push(["コマンド名","R",function(a){ | | f.push(["コマンド名","R",function(a){ |
| return a.replace(省略).replaceBatch([ 省略 ]).replace(省略) }]); | | return a.replace(省略).replaceBatch([ 省略 ]).replace(省略) }]); |
| </source> | | </syntaxhighlight> |
|
| |
|
| ===モード CR ⇒ R (replaceBatch) への移行方法=== | | ===モード CR → R (replaceBatch) への移行方法=== |
| 基本的にモード CR を継承した機能であるため、手直しすることで移行が可能です。
| | 以下のように書き換えることで移行が可能です。 |
| <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><code>f.push(["コマンド名","<span style="background:#fcc;">CR</span>",function(a){<br> return <span style="background:#fcc;">[</span> [検索1,置換1],[検索2,置換2],[検索3,置換3]… <span style="background:#fcc;">]</span>}]);</code></p> | | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><samp>f.push(["コマンド名","<span style="background:#fcc;">CR</span>",function(a){<br> return <span style="background:#fcc;">[</span> [検索1,置換1],[検索2,置換2] 中略 <span style="background:#fcc;">]</span>}]);</samp></p> |
| :↓ | | :↓ |
| <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><code>f.push(["コマンド名","<span style="background:#fcc;">R</span>",function(a){<br> return <span style="background:#fcc;">a.replaceBatch([</span> [検索1,置換1],[検索2,置換2],[検索3,置換3]… <span style="background:#fcc;">]) </span>}]);</code></p> | | <p style="background:#f9f9f9; border:1px dashed #999; padding:6px;"><samp>f.push(["コマンド名","<span style="background:#fcc;">R</span>",function(a){<br> return <span style="background:#fcc;">a.replaceBatch([</span> [検索1,置換1],[検索2,置換2] 中略 <span style="background:#fcc;">]) </span>}]);</samp></p> |
|
| |
|
| ==変更点まとめ== | | ==変更点まとめ== |
| {| class="wikitable" | | {|class="wikitable" |
| ! 機能 !! 旧仕様 !! 新仕様 !! 備考 | | ! 機能 !! 旧仕様 !! 新仕様 !! 備考 |
| |- | | |- |
| 98行目: |
243行目: |
| ! モード RM | | ! モード RM |
| |style="background:#cfc;"| 利用可 ||style="background:#fcc;"| 廃止 | | |style="background:#cfc;"| 利用可 ||style="background:#fcc;"| 廃止 |
| | モード RS に作り替え | | | モード RS で作り直し |
| |- | | |- |
| ! モード CR | | ! モード CR |
| 106行目: |
251行目: |
| ! replaceBatch | | ! replaceBatch |
| |style="background:#fcc;"| エラー ||style="background:#cfc;"| 利用可 | | |style="background:#fcc;"| エラー ||style="background:#cfc;"| 利用可 |
| | ※旧仕様ではコマンド実行時にエラーが発生する | | | 旧仕様ではコマンド実行時にエラーが発生する |
| |} | | |} |
|
| |
| ==基本コード(先行版)==
| |
| <span style="color:#c00;">※正式版では変更となる場合があります。ご了承ください。</span>
| |
|
| |
| <source lang="javascript">
| |
| //■テキスト整形
| |
| // 2013/09/15-2015/02/14 (先行版)
| |
|
| |
| //■拡張コード:コマンド一覧
| |
| var f = [];
| |
| // ----------------- ↓ここより下に拡張コードを追加
| |
|
| |
| // ----------------- ↑ここより上に拡張コードを追加
| |
| /*■拡張コード:書式
| |
| //▼コマンド
| |
| f.push(["コマンド名","モード",function(引数){マクロ}]);
| |
| //▽モード F (Function) - 関数を実行
| |
| function( Document.Selection ) : 戻値なし
| |
| //▽モード R (Replace) - 選択範囲を置換
| |
| //▽モード RS (Select-line) - 選択範囲を行頭行末まで拡張して置換
| |
| function( Document.Selection.Text ) : String
| |
| //▼サブメニュー
| |
| f.push(["メニュー名",function(f){コマンドなど}]);
| |
| //▼セパレータ
| |
| f.push(["----"]);
| |
| // ----------------- */
| |
|
| |
| //■メソッド:連続置換
| |
| //String.replaceBatch([ [検索1,置換1],[検索2,置換2],[検索3,置換3]… ]);
| |
| String.prototype.replaceBatch = function(a) { //▲引数の型検査はしていない
| |
| var _this = this;
| |
| for (var i=0,n=a.length; i<n; i++) {
| |
| if (typeof a[i][0]==="string") //◆特殊文字をエスケープし、"g"フラグを付加
| |
| a[i][0] = new RegExp(a[i][0].replace(/([$()*+.?[\\\]^{|}])/g,"\\$1"),"g");
| |
| _this = _this.replace(a[i][0],a[i][1]);
| |
| }
| |
| return _this;
| |
| };
| |
|
| |
| //■実行コード
| |
| (function(){
| |
| var sel = Document.Selection;
| |
| var cmd = [], cid = 1; //コマンド格納用,ID
| |
| //メニュー生成用関数
| |
| function ListToMenu(List, Menu) {
| |
| for (var i=0, n=List.length; i<n; i++) {
| |
| var $L = List[i], $Ln = List[i].length;
| |
| if (typeof $L[0]!=="string") continue;
| |
| switch (true) {
| |
| //◆コマンド $L = ["コマンド名","モード",function]
| |
| case ($Ln===3 && /^(F|RS?)$/.test($L[1]) && typeof $L[2]==="function"):
| |
| cmd[cid] = {"mode":$L[1], "func":$L[2]};
| |
| Menu.Add($L[0]+"\t"+$L[1], cid++);
| |
| break;
| |
| //◆サブメニュー $L = ["メニュー名",function]
| |
| case ($Ln===2 && typeof $L[1]==="function"):
| |
| var sub_f = [], sub_popup = CreatePopupMenu();
| |
| $L[1](sub_f);
| |
| Menu.AddPopup($L[0], sub_popup);
| |
| ListToMenu(sub_f, sub_popup); //再帰処理:サブメニュー作成
| |
| break;
| |
| //◆セパレータ $L = ["----"]
| |
| case ($Ln===1 && /^-+$/.test($L[0])):
| |
| Menu.Add("", 0, meMenuSeparator);
| |
| break;
| |
| }
| |
| }
| |
| };
| |
| //コマンド一覧からメニュー生成
| |
| var popup = CreatePopupMenu();
| |
| ListToMenu(f, popup);
| |
| //ポップアップメニューを表示して処理
| |
| if (cid = popup.Track(mePosMouse)) { //※キャンセル(Esc)時は0が返る
| |
| var $C = cmd[cid];
| |
| switch ($C["mode"]) {
| |
| case "F": //関数を実行
| |
| $C["func"](sel);
| |
| break;
| |
| case "RS": //選択範囲を行頭行末まで拡張
| |
| selectLine();
| |
| case "R": //選択範囲を置換
| |
| var pos = new Pos(); //選択範囲の記憶
| |
| sel.Text = $C["func"](sel.Text);
| |
| pos.set(); //選択範囲の設定
| |
| break;
| |
| }
| |
| }
| |
|
| |
| //■選択範囲を行頭行末まで拡張
| |
| function selectLine() {
| |
| var sel = Document.Selection;
| |
| var ty = sel.GetTopPointY(mePosLogical);
| |
| var by = sel.GetBottomPointY(mePosLogical);
| |
| var bx = sel.GetBottomPointX(mePosLogical);
| |
| var br =(sel.Text.match(/\n/g)||[]).length;
| |
| if (bx==1 && by-ty==br && br) by--; //次行行頭を含めないよう対策
| |
| sel.SetActivePoint(mePosLogical, 1, by);
| |
| sel.EndOfLine(false, mePosLogical);
| |
| sel.SetAnchorPoint(mePosLogical, 1, ty);
| |
| };
| |
| //■位置情報オブジェクト
| |
| function Pos() {
| |
| var sel = Document.Selection;
| |
| this.get = function() {
| |
| this.acp = sel.GetActivePos();
| |
| this.anp = sel.GetAnchorPos();
| |
| this.len = Document.Text.length;
| |
| };
| |
| this.set = function() { //字数変化を加味して範囲選択
| |
| var acp = this.acp, anp = this.anp, gap = Document.Text.length - this.len;
| |
| sel.SetActivePos((acp<anp)? acp: acp+gap);
| |
| sel.SetAnchorPos((acp<anp)? anp+gap: anp);
| |
| };
| |
| return this.get();
| |
| };
| |
|
| |
| })();
| |
| </source>
| |
|
| |
| ==拡張コード(先行版)==
| |
| <span style="color:#c00;">※正式版では変更となる場合があります。ご了承ください。</span>
| |
|
| |
| ===モード RM ⇒ RS===
| |
| ※上段=旧仕様/下段=新仕様
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["行頭 \/\/ を付加/削除","RM",function(a){
| |
| return a.match(/^\/\/.*$/)? a.slice(2): "\/\/"+a }]);
| |
|
| |
| f.push(["行頭 \/\/ を付加/削除","RS",function(a){
| |
| return a.replace(/^(\/\/)?/gm,function(s){return s? "": "\/\/"}) }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["インデント(半角空白2個)","RM",function(a){
| |
| return " "+a }]);
| |
|
| |
| f.push(["インデント(半角空白2個)","RS",function(a){
| |
| return a.replace(/^/gm," ") }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["各行行頭に貼り付け","RM",function(a){
| |
| return ClipboardData.GetData().replace(/(\r?\n|\r)$/,"")+a }]);
| |
| f.push(["各行行末に貼り付け","RM",function(a){
| |
| return a+ClipboardData.GetData().replace(/(\r?\n|\r)$/,"") }]);
| |
|
| |
| f.push(["各行行頭に貼り付け","RS",function(a){
| |
| var c=ClipboardData.GetData().replace(/(\r?\n|\r)$/,""); return a.replace(/^/gm,c) }]);
| |
| f.push(["各行行末に貼り付け","RS",function(a){
| |
| var c=ClipboardData.GetData().replace(/(\r?\n|\r)$/,""); return a.replace(/$/gm,c) }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["各行行頭に文字列付加...","RM",(function(a){
| |
| var c=null; return function(a){ if(!c){ if(!(c=Prompt("各行行頭に付加する文字列:",""))){Quit()} } return c+a } })()]);
| |
| f.push(["各行行末に文字列付加...","RM",(function(a){
| |
| var c=null; return function(a){ if(!c){ if(!(c=Prompt("各行行末に付加する文字列:",""))){Quit()} } return a+c } })()]);
| |
|
| |
| f.push(["各行行頭に文字列付加...","RS",function(a){
| |
| var p=Prompt("各行行頭に付加する文字列:",""); if(!p)Quit(); return a.replace(/^/gm,p) }]);
| |
| f.push(["各行行末に文字列付加...","RS",function(a){
| |
| var p=Prompt("各行行末に付加する文字列:",""); if(!p)Quit(); return a.replace(/$/gm,p) }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["空白行を削除","RM",function(a){
| |
| return a.match(/^[ \t]*$/)? null:a }]);
| |
|
| |
| f.push(["空白行を削除","RS",function(a){
| |
| return a.replace(/^[ \t]*$\n?/gm,"") }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["入力文字列を含む行を削除...","RM",(function(a){
| |
| var c=null; return function(a){ if(!c){ if(!(c=Prompt("以下の文字列を含む行を削除:",""))){Quit()} } return (a.indexOf(c)>=0)? null:a } })()]);
| |
| f.push(["入力文字列を含まない行を削除...","RM",(function(a){
| |
| var c=null; return function(a){ if(!c){ if(!(c=Prompt("以下の文字列を含まない行を削除:",""))){Quit()} } return (a.indexOf(c)>=0)? a:null } })()]);
| |
|
| |
| f.push(["入力文字列を含む行を削除...","RS",function(a){
| |
| var p=Prompt("以下の文字列を含む行を削除:",""); if(!p)Quit(); return a.replace(/^(.*)$\n?/gm,function(s,t){return (t.indexOf(p)>=0)? "":s}) }]);
| |
| f.push(["入力文字列を含まない行を削除...","RS",function(a){
| |
| var p=Prompt("以下の文字列を含まない行を削除:",""); if(!p)Quit(); return a.replace(/^(.*)$\n?/gm,function(s,t){return (t.indexOf(p)>=0)? s:""}) }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["正規表現に一致する行を削除...","RM",(function(a){
| |
| var c=null; return function(a){ if(!c){ if(!(c=Prompt("以下の正規表現に一致する行を削除:",""))){Quit()}else{c=new RegExp(c)} } return c.test(a)? null:a } })()]);
| |
| f.push(["正規表現に一致しない行を削除...","RM",(function(a){
| |
| var c=null; return function(a){ if(!c){ if(!(c=Prompt("以下の正規表現に一致しない行を削除:",""))){Quit()}else{c=new RegExp(c)} } return c.test(a)? a:null } })()]);
| |
|
| |
| f.push(["正規表現に一致する行を削除...","RS",function(a){
| |
| var p=Prompt("以下の正規表現に一致する行を削除:",""); if(!p)Quit(); p=new RegExp(p); return a.replace(/^(.*)$\n?/gm,function(s,t){return p.test(t)? "":s}) }]);
| |
| f.push(["正規表現に一致しない行を削除...","RS",function(a){
| |
| var p=Prompt("以下の正規表現に一致しない行を削除:",""); if(!p)Quit(); p=new RegExp(p); return a.replace(/^(.*)$\n?/gm,function(s,t){return p.test(t)? s:""}) }]);
| |
| </source>
| |
|
| |
| ===モード CR ⇒ R (replaceBatch)===
| |
| ※新仕様のみ掲載
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["連続する!?を整形","R",function(a){
| |
| return a.replaceBatch([ [/[!!][!!??]*[!!]/g,"!!"],[/[!!][!!??]*[??]/g,"!?"],[/[??][!!??]*[!!]/g,"?!"],[/[??][!!??]*[??]/g,"??"] ]) }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(['実体参照 &&"<> → &&xxx;',"R",function(a){
| |
| return a.replaceBatch([ ["&","&"],['"',"""],["<","<"],[">",">"] ]) }]);
| |
| f.push(['実体参照 &&xxx; → \u2423><"&&',"R",function(a){
| |
| return a.replaceBatch([ [" "," "],[">",">"],["<","<"],[""",'"'],["&","&"] ]) }]);
| |
| f.push(['実体参照 &&"<>\u2423 → &&xxx;',"R",function(a){
| |
| return a.replaceBatch([ ["&","&"],['"',"""],["<","<"],[">",">"],[" "," "] ]) }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["半角カナ→全角","R",function(a){
| |
| return a.replaceBatch([ ["。","。"],["「","「"],["」","」"],["、","、"],["・","・"],["ヲ","ヲ"],["ァ","ァ"],["ィ","ィ"],["ゥ","ゥ"],["ェ","ェ"],["ォ","ォ"],["ャ","ャ"],["ュ","ュ"],["ョ","ョ"],["ッ","ッ"],["ー","ー"],["ア","ア"],["イ","イ"],["ヴ","ヴ"],["ウ","ウ"],["エ","エ"],["オ","オ"],["ガ","ガ"],["ギ","ギ"],["グ","グ"],["ゲ","ゲ"],["ゴ","ゴ"],["カ","カ"],["キ","キ"],["ク","ク"],["ケ","ケ"],["コ","コ"],["ザ","ザ"],["ジ","ジ"],["ズ","ズ"],["ゼ","ゼ"],["ゾ","ゾ"],["サ","サ"],["シ","シ"],["ス","ス"],["セ","セ"],["ソ","ソ"],["ダ","ダ"],["ヂ","ヂ"],["ヅ","ヅ"],["デ","デ"],["ド","ド"],["タ","タ"],["チ","チ"],["ツ","ツ"],["テ","テ"],["ト","ト"],["ナ","ナ"],["ニ","ニ"],["ヌ","ヌ"],["ネ","ネ"],["ノ","ノ"],["バ","バ"],["ビ","ビ"],["ブ","ブ"],["ベ","ベ"],["ボ","ボ"],["パ","パ"],["ピ","ピ"],["プ","プ"],["ペ","ペ"],["ポ","ポ"],["ハ","ハ"],["ヒ","ヒ"],["フ","フ"],["ヘ","ヘ"],["ホ","ホ"],["マ","マ"],["ミ","ミ"],["ム","ム"],["メ","メ"],["モ","モ"],["ヤ","ヤ"],["ユ","ユ"],["ヨ","ヨ"],["ラ","ラ"],["リ","リ"],["ル","ル"],["レ","レ"],["ロ","ロ"],["ワ","ワ"],["ン","ン"],["゙","゛"],["゚","゜"] ]) }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["全角カナ→半角","R",function(a){
| |
| return a.replaceBatch([ ["。","。"],["「","「"],["」","」"],["、","、"],["・","・"],["ヲ","ヲ"],["ァ","ァ"],["ィ","ィ"],["ゥ","ゥ"],["ェ","ェ"],["ォ","ォ"],["ャ","ャ"],["ュ","ュ"],["ョ","ョ"],["ッ","ッ"],["ー","ー"],["ア","ア"],["イ","イ"],["ヴ","ヴ"],["ウ","ウ"],["エ","エ"],["オ","オ"],["ガ","ガ"],["ギ","ギ"],["グ","グ"],["ゲ","ゲ"],["ゴ","ゴ"],["カ","カ"],["キ","キ"],["ク","ク"],["ケ","ケ"],["コ","コ"],["ザ","ザ"],["ジ","ジ"],["ズ","ズ"],["ゼ","ゼ"],["ゾ","ゾ"],["サ","サ"],["シ","シ"],["ス","ス"],["セ","セ"],["ソ","ソ"],["ダ","ダ"],["ヂ","ヂ"],["ヅ","ヅ"],["デ","デ"],["ド","ド"],["タ","タ"],["チ","チ"],["ツ","ツ"],["テ","テ"],["ト","ト"],["ナ","ナ"],["ニ","ニ"],["ヌ","ヌ"],["ネ","ネ"],["ノ","ノ"],["バ","バ"],["ビ","ビ"],["ブ","ブ"],["ベ","ベ"],["ボ","ボ"],["パ","パ"],["ピ","ピ"],["プ","プ"],["ペ","ペ"],["ポ","ポ"],["ハ","ハ"],["ヒ","ヒ"],["フ","フ"],["ヘ","ヘ"],["ホ","ホ"],["マ","マ"],["ミ","ミ"],["ム","ム"],["メ","メ"],["モ","モ"],["ヤ","ヤ"],["ユ","ユ"],["ヨ","ヨ"],["ラ","ラ"],["リ","リ"],["ル","ル"],["レ","レ"],["ロ","ロ"],["ワ","ワ"],["ン","ン"],["゛","゙"],["゜","゚"] ]) }]);
| |
| </source>
| |
|
| |
| <source lang="javascript" style="word-wrap:break-word;">
| |
| f.push(["標準変換","R",function(a){
| |
| return a.replaceBatch([ [" "," "],["!","!"],["“",'"'],["”",'"'],["#","#"],["$","$"],["%","%"],["&","&"],["‘","'"],["’","'"],["(","("],[")",")"],["*","*"],["+","+"],[",",","],["-","-"],[".","."],["/","/"],["0","0"],["1","1"],["2","2"],["3","3"],["4","4"],["5","5"],["6","6"],["7","7"],["8","8"],["9","9"],[":",":"],[";",";"],["<","<"],["=","="],[">",">"],["?","?"],["@","@"],["A","A"],["B","B"],["C","C"],["D","D"],["E","E"],["F","F"],["G","G"],["H","H"],["I","I"],["J","J"],["K","K"],["L","L"],["M","M"],["N","N"],["O","O"],["P","P"],["Q","Q"],["R","R"],["S","S"],["T","T"],["U","U"],["V","V"],["W","W"],["X","X"],["Y","Y"],["Z","Z"],["[","["],["¥","\\"],["]","]"],["^","^"],["_","_"],["`","`"],["a","a"],["b","b"],["c","c"],["d","d"],["e","e"],["f","f"],["g","g"],["h","h"],["i","i"],["j","j"],["k","k"],["l","l"],["m","m"],["n","n"],["o","o"],["p","p"],["q","q"],["r","r"],["s","s"],["t","t"],["u","u"],["v","v"],["w","w"],["x","x"],["y","y"],["z","z"],["{","{"],["|","|"],["}","}"],["~","~"],["。","。"],["「","「"],["」","」"],["、","、"],["・","・"],["ヲ","ヲ"],["ァ","ァ"],["ィ","ィ"],["ゥ","ゥ"],["ェ","ェ"],["ォ","ォ"],["ャ","ャ"],["ュ","ュ"],["ョ","ョ"],["ッ","ッ"],["ー","ー"],["ア","ア"],["イ","イ"],["ヴ","ヴ"],["ウ","ウ"],["エ","エ"],["オ","オ"],["ガ","ガ"],["ギ","ギ"],["グ","グ"],["ゲ","ゲ"],["ゴ","ゴ"],["カ","カ"],["キ","キ"],["ク","ク"],["ケ","ケ"],["コ","コ"],["ザ","ザ"],["ジ","ジ"],["ズ","ズ"],["ゼ","ゼ"],["ゾ","ゾ"],["サ","サ"],["シ","シ"],["ス","ス"],["セ","セ"],["ソ","ソ"],["ダ","ダ"],["ヂ","ヂ"],["ヅ","ヅ"],["デ","デ"],["ド","ド"],["タ","タ"],["チ","チ"],["ツ","ツ"],["テ","テ"],["ト","ト"],["ナ","ナ"],["ニ","ニ"],["ヌ","ヌ"],["ネ","ネ"],["ノ","ノ"],["バ","バ"],["ビ","ビ"],["ブ","ブ"],["ベ","ベ"],["ボ","ボ"],["パ","パ"],["ピ","ピ"],["プ","プ"],["ペ","ペ"],["ポ","ポ"],["ハ","ハ"],["ヒ","ヒ"],["フ","フ"],["ヘ","ヘ"],["ホ","ホ"],["マ","マ"],["ミ","ミ"],["ム","ム"],["メ","メ"],["モ","モ"],["ヤ","ヤ"],["ユ","ユ"],["ヨ","ヨ"],["ラ","ラ"],["リ","リ"],["ル","ル"],["レ","レ"],["ロ","ロ"],["ワ","ワ"],["ン","ン"],["゙","゛"],["゚","゜"] ]) }]);
| |
| </source>
| |