「
「クリップボード履歴」メニューのマクロ化
」を編集中 (節単位)
ナビゲーションに移動
検索に移動
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、さまざまなメリットもあります。
スパム攻撃防止用のチェックです。 決して、ここには、値の入力は
しない
でください!
== ソースコード == <syntaxhighlight lang="javascript" style="height:120em; overflow:auto;" highlight="29-38,41-47,50-57,60-67,70-78,81-91,340,342"> #title = "クリップボード履歴..." #tooltip = "クリップボード履歴 と スニペット" #include "include/IO.js" #icon = "clipboard_history[1].ico" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",314 /** * -------------------------------------------------- * 「クリップボード履歴 と スニペット」マクロ * sukemaru, 2019-08-01 - 2020-06-27 * https://www.haijin-boys.com/wiki/「クリップボード履歴」メニューのマクロ化 * -------------------------------------------------- * 「クリップボード履歴」メニューと「スニペット」プラグインと同等の機能を * ひとつのポップアップメニューに統合します。 * * ※ Ver 2.8.0 以前の Mery では「クリップボード履歴」機能を使用できません。 * ※「スニペット」プラグインを導入していない場合でも * 「スニペット」機能(ピン止め)を使用できます。 * * ※「include ライブラリ」が必要です。 * https://www.haijin-boys.com/wiki/includeライブラリ * ※「GetKeyState.exe」で機能を拡張できます。 * https://www.haijin-boys.com/wiki/GetKeyState.exe(キー状態取得実行ファイル) */ // ---------- ▼ 設定項目 ▼ ---------- // // ■ 貼り付けたアイテムをクリップボード履歴の先頭に移動する var toTop = false; // true: 移動する / false: 移動しない // true にすると、Ctrl+V でつづけて貼り付け可 // false なら、クリップボードのアイテムの順番を維持する // ■ toTop = true のとき // 「n 番目から m 番目までをつなげて貼り付け」したアイテムを // クリップボード履歴の先頭に登録する(※ただし 16 番目だったアイテムが消える) var unitToTop = false; // true: 登録する / false: 登録しない // ■ 「任意の文字列でつなげて貼り付け」で入力した文字列の一時記憶方法 var tagType = 2; // 0 : 一時記憶なし // 1 : タブ(文書)ごとに一時記憶する(Document.Tag) // 2 : ウインドウごとに一時記憶する(Editor.Tag) // 3 : すべてのタブとウインドウ共通で一時記憶する(window.Tag) // ■ "@@@" をふくむピン止めアイテムを "選択範囲の囲いこみ用" にする var sandwich = false; // true: する / false: しない var cheese = "@" // 初期値:"@" // sandwich = true なら、ピン止めアイテムが "@@@" をふくむときに... // ⇒ "@@@@" (cheese × 4) で区切られた前後の文字列で「選択範囲の各行」を囲う // ⇒ "@@@" (cheese × 3) で区切られた前後の文字列で「選択範囲全体」を囲う // cheese = "@" の「@」は任意の文字に変更可 // ■ ポップアップメニューを表示する位置 var menuPosMouse = true; // true: マウス位置 / false: キャレット位置 // ■ ポップアップメニューに表示する文字数の目安 var menuWidth = 60; // ■ 半角英小文字や ascii 記号を全角で表示する var toWideWidth = 0; // (0 しない / 1 文字間を広げる / 2 全角にする) // ■ 連番アイテムの桁埋め(右寄せ/空白埋め)用の空白文字の定義 var blankChr = " "; // " " or "\u2002" or "\u3000" or "\u2007" or ... /* 半角数字の幅に等しい空白文字として MS UI Gothic では「2分アキ」 = EN SPACE: "\u2002" (MeiryoKe_UI Gothic は MS UI Gothic に同じ) Meiryo UI では「和字間隔」 = 全角空白: "\u3000" Segoe UI では「図形間隔」 = FIGURE SPACE: "\u2007" にすると具合がよさそうですが、ウエイトによって幅が変わるので... */ // ■ GetKeyState.exe のフルパスを指定する場合( \ 記号はふたつがさね「\\」で) // 未指定 "" なら、Mery インストールフォルダの Macros\GetKeyState.exe var getKeyStatePath = ""; // ※ GetKeyState.exe なしのときも "" にする // ■ クリップボードのアイテムの Ctrl+クリックで // ¥ を ¥¥ に置換して貼り付ける var ctrlEscape = false; // true なら、 Ctrl+クリックで ¥ を ¥¥ に置換して貼り付け // false なら、Ctrl+クリックで 貼り付けしてからアイテムを削除 // GetKeyState.exe がない場合は無効 // ---------- ▲ 設定項目 ▲ ---------- // var start = new Date(); var Fso = new ActiveXObject( "Scripting.FileSystemObject" ); var WshShell = new ActiveXObject( "WScript.Shell" ); var meryPath = editor.FullName; var meryDir = meryPath.replace( /[^\\]+$/, "" ); var isPortable = Fso.FileExists( meryPath.replace( /\.exe$/i, ".ini" ) ); var profileDir = ( isPortable ) ? meryDir : WshShell.SpecialFolders( "APPDATA" ) + "\\Mery\\"; var snPath = profileDir + "Plugins\\Snippets\\Snippets.txt"; var snIsExist = Fso.FileExists( snPath ); var versionCheck = VersionCheck( "2.8.1" ); var d = editor.ActiveDocument; var s = d.selection; var st = s.Text; var $status = Status; var gksPath = getKeyStatePath || meryDir + "Macros\\GetKeyState.exe"; var gksExists = Fso.FileExists( gksPath ); var $ctrl = false; var $Ctrl = function() { return ( gksExists && WshShell.Run( '"' + gksPath + '" c', 0, true ) === 1 ); } var p = ""; var tagKey = "ClipboardMenu"; var ham = cheese ? cheese.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ) : ""; sandwich = ham ? sandwich : false; var b1 = ( ! blankChr || ( "" + blankChr ).length > 1 ) ? " " : blankChr; Object.prototype.PadSpace = function(len, chr) { var dgt = String(this); len = Number(len) || dgt.length; chr = chr ? chr.toString() : b1; if (len < 0 || len < dgt.length || chr.length !== 1) return dgt; for (var i = 0; i < len; i++) chr += chr; return (chr + dgt).slice( - len); }; // ピン止めアイテム (スニペット)の準備 var snText = "", snArray = [], snCount = 0; if ( snIsExist ) { // snippet.txt を読みこむ snText = IO.LoadFromFile( snPath, "utf-8" ) || ""; // 空白行とセパレータ用の "-" の行を除去した配列にする snArray = snText.split( "\n" ); for ( var i = 0; i < snArray.length; i ++ ) { if ( /(?:^-\t|^\s*-?\s*$)/.test( snArray[i] ) ) { snArray.splice( i --, 1 ); } } } snCount = snArray.length; // クリップボード履歴の準備 var cb = ClipboardData; var cbData = cb.GetData(); var cbArray = []; if ( versionCheck ) { var cbData0 = cb.GetData( 0 ); if ( cbData0 ) { outer: for ( var i = 0, cbItem; i < 16 ; i ++ ) { cbItem = cb.GetData( i ) || ""; if ( ! cbItem ) { break outer; } // 重複するアイテムを履歴から削除する inner: for ( var j = i + 1, cbNextItem; ; j ++ ) { cbNextItem = cb.GetData( j ) || ""; if ( ! cbNextItem ) { break inner; } if ( cbItem === cbNextItem ) { cb.ClearData( j -- ); } } // 履歴アイテムを配列に収納する cbArray.push( cbItem ); } } } var cbCount = cbArray.length; var numWidth = String( Math.max( snCount, cbCount ) ).length; // ポップアップメニューの準備 var menu = CreatePopupMenu(); var grayFlag = d.ReadOnly ? meMenuGrayed : 0; var t = ( snCount ) ? "▼ " : ""; var label, id; // 「ピン止めアイテム/スニペット」サブメニュー var subMenu0 = CreatePopupMenu(); menu.AddPopup( t + "ピン止めアイテム/スニペット (&S) " + t, subMenu0 ); if ( st ) { subMenu0.Add( "選択範囲を登録 (&P)", 300 ); } if ( snIsExist ) { subMenu0.Add( "スニペットを編集 (&E) ...", 400 ); } if ( st || snIsExist ) { subMenu0.Add( "", 0, meMenuSeparator ); subMenu0.Add( "キャンセル & ", 0 ); } if ( snCount ) { subMenu0.Add( "", 0, meMenuSeparator ); } // スニペットのアイテムをメニューに if ( snText ) { var sn0, sn1, sn2, tab1, tab2; var subArray = []; // サブメニュー: 10 階層までを想定 for ( var i = 0; i < 10; i ++ ) { subArray.push( [] ); } var subID, subID1, subID2; for ( var i = 0, j = 1, tab0 = 0; i < snCount; i ++, j ++ ) { try { sn1 = snArray[i]; sn2 = snArray[j] || ""; // 次の有効文字列の行(空行やセパレータ行は除外) // 行頭のタブのケタ数(階層の深さ) tab1 = ( sn1.charAt( 0 ) == "\t" ) ? sn1.search( /[^\t]/ ) : 0; tab2 = ( sn2.charAt( 0 ) == "\t" ) ? sn2.search( /[^\t]/ ) : 0; // メニューに表示させるラベル部分とメニューID label = MenuKey( sn1.replace( /^\t+|\t+[^\t]*$/g, "" ) , j, numWidth, menuWidth, b1, true ); id = j + 400; // メインメニューにサブメニュー項目(見出し)を追加 if ( tab1 == 0 && tab1 + 1 == tab2 ) { subID = subArray[0].length; subArray[0].push( CreatePopupMenu() ); if ( grayFlag ) { menu.Add( label + "\t\u25B6", id, grayFlag ); //「▶」(\u25B6) } else { menu.AddPopup( label, subArray[0][ subID ] ); } subMenu0.Add( "", 0, meMenuSeparator ); sn0 = false; } // メインメニュー直下にアイテムを追加 else if ( tab1 == 0 && ( tab1 == tab2 || tab1 + 1 < tab2 ) ) { menu.Add( label, id, grayFlag ); if ( tab1 < tab0 && sn0 ) { subMenu0.Add( "", 0, meMenuSeparator ); } subMenu0 .Add( label, id, grayFlag ); sn0 = true; } // サブメニュー内にサブメニュー項目(見出し)を追加 else if ( tab1 > 0 && tab1 + 1 == tab2 ) { subID1 = subArray[ tab1 ].length; subID2 = subArray[ tab1 - 1 ].length - 1; subArray[ tab1 ].push( CreatePopupMenu() ); subArray[ tab1 - 1 ][ subID2 ].AddPopup( label, subArray[ tab1 ][ subID1 ] ); if ( sn0 ) { subMenu0.Add( "", 0, meMenuSeparator ); } sn0 = false; } // サブメニュー内にアイテムを追加 else if ( tab1 > 0 && ( tab1 >= tab2 || tab1 + 1 < tab2 ) ) { subID = subArray[ tab1 - 1 ].length - 1; subArray[ tab1 - 1 ][ subID ].Add( label, id, grayFlag ); if ( tab1 < tab0 && sn0 ) { subMenu0.Add( "", 0, meMenuSeparator ); } subMenu0.Add( label, id, grayFlag ); sn0 = true; } tab0 = tab1; } catch( e ) { ; /** * snArray[i] (行_A) と次の有効文字列の行 snArray[j] (行_B) の * タブインデントを比較して、行_A よりも 行_B が二段以上深い場合、 * 行_A をサブメニュー見出し項目にせず、通常アイテムとして扱います。 * 行_B から始まるグループは、親になる項目が適切に処理されないことにより、 * メインメニュー部分の階層構造に正しく反映されなくなります * (状況によっては部分的にエラー扱いになります)。 * ただし「▼ ピン止めアイテム/スニペット ▼」配下の * ベタ置きのアイテムとしては(状況によっては不完全に)表示されます。 */ } } } menu.Add( "", 0, meMenuSeparator ); // クリップボード履歴のアイテムをメニューに if ( cbCount ) { var subMenu1 = CreatePopupMenu(); // クリップボード履歴の一覧 var subMenu2 = CreatePopupMenu(); // 履歴のアイテムをスニペットに登録 var subMenu3 = CreatePopupMenu(); // 貼り付けしてからアイテムを削除 var subMenu4 = CreatePopupMenu(); // 履歴からアイテムを削除 menu.AddPopup( "▼ クリップボード履歴の一覧 (&H) ▼", subMenu1 ); for ( var i = 0; i < cbCount; i ++ ) { id = i + 1; label = MenuKey( cbArray[i], id, numWidth, menuWidth, b1 ); menu.Add( label, id, grayFlag ); subMenu2. Add( label, id + 100, grayFlag ); subMenu3. Add( label, id + 200 ); subMenu4. Add( label, id + 300 ); } // subMenu1.Add( "", 0, meMenuSeparator ); subMenu1.AddPopup( "履歴のアイテムをスニペットに登録 (&P)", subMenu4 ); subMenu1.AddPopup( "貼り付けしてからアイテムを削除 (&M)", subMenu2 ); subMenu1.AddPopup( "履歴からアイテムを削除 (&D)", subMenu3 ); subMenu1.Add( "", 0, meMenuSeparator ); subMenu1.Add( "すべての履歴を削除 (&E)", 99 ); subMenu1.Add( "", 0, meMenuSeparator ); subMenu1.Add( "キャンセル & ", 0 ); } // Windows のクリップボードデータ else if ( cbData.length ) { label = MenuKey( cbData, 1, numWidth, menuWidth, b1 ); menu.Add( "▼ クリップボード ▼", 0, meMenuGrayed ); menu.Add( label, 17, grayFlag ); } else { menu.Add( "※ クリップボードにテキストデータはありません ※" , 0, meMenuGrayed ); } if ( ! ctrlEscape && ( cbData0 || cbData ).indexOf( "\\" ) > -1 ) { menu.Add( "", 0, meMenuSeparator ); menu.Add( "\u00A5 を \u00A5\u00A5 に置換して " //「¥」(\u00A5) + "履歴の先頭アイテム を貼り付け (&E)" , 18, grayFlag ); } if ( cbCount > 1 ) { var u1 = "履歴の n 番目から m 番目までを"; var u2 = "つなげて貼り付け "; menu.Add( "", 0, meMenuSeparator ); menu.Add( u1 + u2 + "(&M)", 94, grayFlag ); menu.Add( u1 + " 任意の文字列 で" + u2 + "(&P)...", 95, grayFlag ); // menu.Add( u1 + " 半角空白 で" + u2 + "(&W)", 96, grayFlag ); menu.Add( u1 + " 改行 で" + u2 + "(&N)", 97, grayFlag ); // menu.Add( u1 + " 空行 で" + u2 + "(&B)", 98, grayFlag ); } menu.Add( "", 0, meMenuSeparator ); menu.Add( "追加コピー (&C)", 92 ); menu.Add( "追加切り取り (&T)", 93, grayFlag ); if ( cbData || cbCount ) { menu.Add( "", 0, meMenuSeparator ); menu.Add( "クリップボードのすべての履歴を削除する (&E)", 99 ); } menu.Add( "", 0, meMenuSeparator ); menu.Add( "キャンセル & ", 0 ); // ステータスバーの表示 Status = ( grayFlag ) ? " ドキュメントは書き換え禁止です。" : ( ! versionCheck ) ? " 「クリップボード履歴」機能の動作要件は" + " \"Mery Ver 2.8.1\" 以上です。" : ( ctrlEscape && gksExists && ( cbCount || cbData ) ) ? " 履歴アイテムの Ctrl+クリック で" //「¥」(\u00A5) + " \u00A5 を \u00A5\u00A5 に置換して貼り付けます。" : ( gksExists && cbCount ) ? " 履歴アイテムの Ctrl+クリック で" + " 「貼り付けしてからアイテムを削除」" : ( gksExists && snCount ) ? " ピン止めアイテムの Ctrl+クリック で" + " 「クリップボードにコピーして貼り付け」" : " 「クリップボード履歴 と スニペット」マクロ"; Status += " [ " + ( ( new Date() - start ) / 1000 ).toFixed( 3 ).replace( /\./, ". " ) + " 秒 ]"; // ポップアップメニューを表示 var r = menu.Track( + menuPosMouse ); main: { if ( ! r ) { Status = $status; break main; } editor.ExecuteCommandByID( MEID_WINDOW_ACTIVE_PANE = 2189 ); // 94, 95, 96, 97, 98: n 番目から m 番目まで貼り付け unit: if ( r >= 94 && r <= 98 ) { $ctrl = $Ctrl(); // 半角変換した ascii 文字列を返す関数 var ToHalfWidth = function( strVal ) { return strVal.replace( /[!-~]/g, function( tmp ) { return String.fromCharCode( tmp.charCodeAt(0) - 0xFEE0 ) } ) }; // 入力ダイアログ×2回 ※全角/半角の数字のみを有効文字列として取得する var p1 = + ToHalfWidth( Prompt( "さいしょのアイテムの番号", "" ) ) .replace( /\D/g, "" ); if ( p1 <= 0 || p1 > cbCount ) { Status = " キャンセル"; break unit; } var p2 = + ToHalfWidth( Prompt( "さいごのアイテムの番号", p1 ) ) .replace( /\D/g, "" ); if ( p2 <= 0 || p2 > cbCount ) { Status = " キャンセル"; break unit; } // 入力された番号が同一なら、通常の貼り付けコマンド r == 1~16 に飛ぶ if ( p1 === p2 ) { r = p1; break unit; } // 上から順 または 下から順 else { var str = ""; var b = ( r === 95 ) ? AddStrPrompt( tagType, tagKey ) : ( r === 96 ) ? " " : ( r === 97 ) ? "\n" : ( r === 98 ) ? "\n\n" :/* r ===94 */ ""; if ( p1 < p2 ) { // 上から順 for ( var i = p1; i <= p2; i ++ ) { str += cbArray[ i - 1 ] + b; } } else { // 下から順 for ( var i = p2; i <= p1; i ++ ) { str = cbArray[ i - 1 ] + b + str; } } str = str.slice( 0, b ? - b.length : str.length ); // 貼り付け ※ Ctrl キーを押しながらのときは、 ¥ を ¥¥ に置換 s.Text = ( ctrlEscape && $ctrl ) ? str.replace( /\\/g, "\\\\" ) : str; // まとめたデータを履歴の先頭に登録 if ( toTop && unitToTop ) { cb.SetData( pStr ); } } } // unit:{} // 1 ~ 17: クリップボード履歴のアイテムを貼り付け // ※ Ctrl キーを押しながらのときは、 ¥ を ¥¥ に置換 if ( ctrlEscape && r > 0 && r <= 17 ) { $ctrl = $ctrl || $Ctrl(); var str = ( r === 17 ) ? cbData : cbArray[ r -1 ]; s.Text = $ctrl ? str.replace( /\\/g, "\\\\" ) : str; // 貼り付けたデータを履歴の先頭に移動 if ( toTop && r <= 16 ) { cbArray.unshift( cbArray.splice( r - 1, 1 ) ); for ( var i = 0; i < cbCount; i ++ ) { cb.SetData( cbArray[i], i ); } cb.SetData( cbArray[0] ); } } else if ( r > 0 && r <= 16 ) { s.Text = cbArray[ r - 1 ]; // Ctrl キーを押しながらのときは、貼り付けしてからアイテムを削除 if ( $Ctrl() ) { cb.ClearData( r - 1 ); if ( r === 1 ) { cb.ClearData(); } Status = " クリップボード履歴からアイテムを削除しました。"; } // 貼り付けたデータを履歴の先頭に移動 else if ( toTop ) { cbArray.unshift( cbArray.splice( r - 1, 1 ) ); for ( var i = 0; i < cbCount; i ++ ) { cb.SetData( cbArray[i], i ); } cb.SetData( cbArray[0] ); } } // Windows のクリップボードデータから貼り付け else if ( r === 17 ) { s.Text = cbData; // Ctrl キーを押しながらのときは、貼り付けしてからアイテムを削除 if ( $Ctrl() ) { cb.ClearData(); Status = " クリップボードからアイテムを削除しました。"; } } // ¥ を ¥¥ に置換して 履歴の先頭アイテム を貼り付け else if ( r === 18 ) { s.Text = ( cbData0 || cbData ).replace( /\\/g, "\\\\" ); } // 追加コピー else if ( r === 92 ) { var line = d.GetLine( s.GetActivePointY( mePosLogical ), 0 ); var str = s.IsEmpty ? ( line ? line + "\n" : "" ) : s.Text; if ( str ) { var oldData = cbData0 || cbData || ""; cb.ClearData( 0 ); cb.SetData( oldData + str ); } } // 追加切り取り else if ( r === 93 ) { if ( s.IsEmpty ) { s.SelectLine(); } var str = s.Text; if ( str ) { var oldData = cbData0 || cbData || ""; cb.ClearData( 0 ); cb.SetData( oldData + str ); } s.Delete(); } // 99: クリップボード履歴をすべて削除する else if ( r === 99 && Confirm( "クリップボードのすべての履歴を削除しますか? " ) ) { for ( var i = cbCount - 1; i >= 0; i -- ) { cb.ClearData( i ); } cb.ClearData(); Status = " クリップボード履歴からすべてのアイテムを削除しました。"; } // 101 ~ 116: 貼り付けしてからアイテムを削除 else if ( r > 100 && r < 200 ) { s.Text = cbArray[ r - 101 ]; cb.ClearData( r - 101 ); Status = " 履歴からアイテムを削除しました。"; } // 201 ~ 216: クリップボード履歴からアイテムを削除 else if ( r > 200 && r < 300 ) { cb.ClearData( r - 201 ); Status = " 履歴からアイテムを削除しました。"; } // 300 ~ 316: スニペットに登録(ピン止め) else if ( r >= 300 && r < 400 ) { try { // データフォルダに Plugins\\Snippets フォルダがなければフォルダを生成 var snippetsDir = Fso.GetParentFolderName( snPath ); var pluginsDir = Fso.GetParentFolderName( snippetsDir ); if ( ! Fso.FolderExists( pluginsDir ) ) { Fso.CreateFolder( pluginsDir ); } if ( ! Fso.FolderExists( snippetsDir ) ) { Fso.CreateFolder( snippetsDir ); } // 選択範囲 または クリップボード履歴のアイテム var str = ( r === 300 ) ? st : ( cb.GetData( r - 301 ) || cb.GetData() ); // snippets.txt の末尾に追加登録する str = snText + ( ( ! snText || snText.charAt( snText.length - 1 ) === "\n" ) ? "" : "\n" ) + str.replace( /[\\\t\n\r]/g, function( tmp ) { return ( tmp === "\\" ) ? "\\\\" : ( tmp === "\t" ) ? "\\t" : ( tmp === "\n" ) ? "\\n" :/* tmp === "\r" */ "\\r"; } ); IO.SaveToFile( snPath, str, "utf-8", true ); var copyFrom = ( r === 300 ) ? " 選択範囲" : " 選択したアイテム"; Status = copyFrom + "をスニペットに登録しました。"; } catch( e ) { Status = " スニペットに登録できませんでした。"; } } // 400: スニペットを編集(snippets.txt を開く) else if ( r === 400 ) { WshShell.Run( "\"" + meryPath + "\" \"" + snPath + "\"" ); Status = " " + snPath; } // 401 ~ : ピン止めアイテムを貼り付け else if ( r > 400 ) { var $ctrl = $Ctrl(); var snStr = snArray[ r - 401 ].replace( /^(?:\t)*[^\t]*\t/, "" ) .split( "\\\\" ); for ( var i = 0, len = snStr.length; i < len; i ++ ) { snStr[i] = snStr[i].replace( /\\t|\\r|\\n|\\/g, function( tmp ) { return ( tmp === "\\t" ) ? "\t" : ( tmp === "\\r" ) ? "\r" : ( tmp === "\\n" ) ? "\n" :/* tmp === "\\" */ ""; } ); } snStr = snStr.join( "\\" ); // ピン止めアイテムで選択範囲を囲う var ham3 = ham + ham + ham, ham4 = ham3 + ham; var reg = /\n?$/, n = st.match( reg ); var str = st.replace( reg, "" ); // "@@@@" で区切られた前後の文字列で選択範囲の各行を囲う if ( sandwich && snStr.indexOf( ham4 ) > -1 ) { var a = str.split( "\n" ); for ( var i = 0, len = a.length; i < len; i ++ ) { a[i] = snStr.replace( RegExp( ham4, "g" ), a[i] ); } // クリップボード経由で「貼り付け」 cb.SetData( str = a.join( "\n" ) + n ); s.Paste(); // クリップボードデータを復帰 cb.ClearData(); for ( var i = 0; i < 16; i ++ ) { cb.SetData( cbArray[i] || "", i ); } cb.SetData( cbArray[0] ); if ( $ctrl ) { cb.SetData( str ); } } // "@@@" で区切られた前後の文字列で選択範囲全体を囲う else if ( sandwich && snStr.indexOf( ham3 ) > -1 ) { s.Text = str = snStr.replace( RegExp( ham3, "g" ), str ) + n; if ( $ctrl ) { cb.SetData( str ); } } // ピン止めアイテムを貼り付け else { s.Text = snStr; // Ctrl キーを押しながらのときは、貼り付けたアイテムをコピー if ( $ctrl ) { cb.SetData( snStr ); Status = " クリップボードにアイテムをコピーしました。"; } } } } // main:{} // ---------- ▼ 関数 ▼ ---------- // /** * 関数 VersionCheck( versionStr ) * Mery 本体が引数で指定したバージョン以上かチェックする( e.g. "2.6.9" ) * 戻り値は、真偽値 true/false */ function VersionCheck( versionStr ) { var editorVer, requirement; var Pad2 = function( str ) { return str.replace( /[0-9]+/g , function( digit ) { return digit.length < 2 ? "0" + digit : digit } ) }; editorVer = Pad2( editor.Version ).replace( /\./g, "" ).slice( 0, 6 ); requirement = Pad2( versionStr ).replace( /\./g, "" ).slice( 0, 6 ); return ( Number( editorVer ) >= Number( requirement ) ); } /** * 関数 MenuKey( str, num, numWidth, menuWidth, blankChr, boolean ) * ポップアップメニューに表示するラベルを生成する * ・行頭空白を除去、空白文字を圧縮: → 「›」(U+203A) * ・改行記号を可視化: → 「↲」(U+21B2) * ・削られてしまう 「&」 を補完 * ・「¥」(U+005C) を 「∖」(U+2216) に置換: → 「╲」(U+2572) * ・ゼロ幅や特殊な空白文字を豆腐に置換: → 「▯」(U+25AF) * ・判別しづらい半角記号を全角に置換: !"%'(),.:;@[]`{|} * + 「a-z」 を全角に置換 * または半角記号の前後にスキマをつける: HAIR SPACE 「 」(U+200A) * ・行番号を空白でケタ埋め: * ・menuWidth を目安に文字数を切り詰め */ function MenuKey( str, num, numWidth, menuWidth, b1, conv ) { var keyWidth = menuWidth; if ( conv ) { var strArr = str.replace( /^[^\t]*\t/, "" ).split( "\\\\" ); for ( var i = 0; i < strArr.length; i ++ ) { strArr[i] = strArr[i].replace( /\\t/g, " \u203A " ) //「›」 .replace( /\\r|(\\r)?\\n/g, " \u21B2 " ) //「↲」 .replace( /\\/g, "" ); } str = strArr.join( "\\" ); } var reg = /[\u00A0\u1680\u180E\u2000-\u200E\u2028\u2029\u202F\u205F\u2062\u2063\uFEFF]/g; var key = str.replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g, " \u203A " ) //「›」 .slice( 0, menuWidth *2) .replace( /(?:\r?\n|\r)/g, " \u21B2 " ) //「↲」 .replace( /[&]/g, "&&" ) .replace( /[\\]/g, "\u2216" ) //「∖」 .replace( reg, "\u25AF" ); //「▯」 if ( toWideWidth === 2 ) { key = key.replace( /[!"%'(),.:;@\[\]`a-z{|}]/g, function( tmp ) { return String.fromCharCode( tmp.charCodeAt( 0 ) + 0xFEE0 ) } ); } else if ( toWideWidth ) { // スラッシュ 以外の ascii 記号と fijl に HAIR SPACE (\u200A) を付加 // [!"#$%'()*+,-.:;<=>?@\[\]^_`{|}~] + "&&" key = key.replace( /[!-%'-.:-@\[-`{-~fijl\u00A5\u22A0\u25AF]|&&/g , "\u200A$&\u200A" ) //「¥」「⊠」「▯」 .replace( /\u200A+/g, "\u200A" ) .replace( RegExp( b1 + "\u200A", "g" ), b1 ); // HAIR SPACE,「›」,「↲」 keyWidth += ( key.match( /[\u200A\u203A\u21B2]|&&/g ) || "" ).length; } num = num.PadSpace( numWidth ).replace( /\d$/, "&$&:" + b1 ); key = ( key.length > keyWidth ) ? key.slice( 0, keyWidth ) + " ..." : key; return num + key; } /** * 関数 GetTag( tagType, tagKey, property ) * 指定された Tag の値を返す */ function GetTag( tagType, tagKey, property ) { try { var obj = ( typeof tagType === "object" ) ? tagType : ( tagType === 1 ) ? editor.ActiveDocument : ( tagType === 2 ) ? editor : ( tagType === 3 ) ? window : window; return ( obj.Tag.Exists( tagKey ) && ( property ? property in obj.Tag( tagKey ) : true ) ) ? property ? obj.Tag( tagKey )[ property ] : obj.Tag( tagKey ) : null; } catch( e ) { Status = e; return null; } } /** * 関数 SetTag( value, tagType, tagKey, property ) * 指定された値を Tag に書き込む */ function SetTag( value, tagType, tagKey, property ) { try { var obj = ( typeof tagType === "object" ) ? tagType : ( tagType === 1 ) ? editor.ActiveDocument : ( tagType === 2 ) ? editor : ( tagType === 3 ) ? window : window; if ( property ) { if ( obj.Tag.Exists( tagKey ) ) { obj.Tag( tagKey )[ property ] = value; } else { obj.Tag( tagKey ) = { property: value }; } } else { obj.Tag( tagKey ) = value; } } catch( e ) { Status = e; } finally { return; } } /** * 関数 AddStrPrompt( tagType, tagKey ) * 「任意の文字列」コマンド * 入力ダイアログで指定された文字列を返す */ function AddStrPrompt( tagType, tagKey ) { // 前回使用した文字列があればダイアログの初期値に再利用 var str = ""; if ( tagType && ( t = GetTag( tagType, tagKey, "addStr" ) ) ) { str = t; } // 入力ダイアログ var msg = "連結用文字列:\t" + "改行 = \\\\\\n ; タブ = \\\\\\t (注:¥記号3つ)"; p = Prompt( msg, str ) || ""; if ( p && tagType ) { SetTag( p, tagType, tagKey, "addStr" ); } return p.replace( /\\\\\\t/g, "\t" ).replace( /\\\\\\n/g, "\n" ); } </syntaxhighlight>
編集内容の要約:
MeryWikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MeryWiki:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の数式を計算してその答えを欄に入力してください (
ヘルプ
):
いちたすには =
キャンセル
編集ヘルプ
(新しいウィンドウで開きます)
スポンサーリンク
ナビゲーション メニュー
個人用ツール
ログインしていません
トーク
投稿記録
アカウント作成
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
編集
履歴表示
その他
検索
スポンサーリンク
スポンサーリンク
案内
メインページ
ヘルプ
よくある質問
マクロリファレンス
マクロライブラリ
プラグインライブラリ
構文ファイル
テーマ
寄付・開発支援
練習用ページ
開発室
開発者のブログ
ツール
スポンサーリンク