「「クリップボード履歴」メニューのマクロ化」の版間の差分
ナビゲーションに移動
検索に移動
細編集の要約なし |
第2版 |
||
| 15行目: | 15行目: | ||
一見して '''誰得?''' なマクロですが、「クリップボード履歴」を「スニペット」機能とまとめてツールバーアイコン化できるという素敵なメリットがあります。 | 一見して '''誰得?''' なマクロですが、「クリップボード履歴」を「スニペット」機能とまとめてツールバーアイコン化できるという素敵なメリットがあります。 | ||
''cf.'' マクロライブラリには「[[定型文を挿入]]」機能に特化したマクロも別途あります。 | : ''cf.'' マクロライブラリには「[[定型文を挿入]]」機能に特化したマクロも別途あります。 | ||
== 更新履歴 == | |||
• 2019/08/01: 初版 | |||
• 2019/08/01: | |||
・「ピン止めアイテムを貼り付け」コードの変数ミスを修正 | |||
・クリップボード履歴内の重複アイテムを削除する設定を追加。 | |||
・ピン止めアイテムが少ないときはメインメニューにアイテムを表示。 | |||
・snippets.txt 内の空行を無視。 | |||
・クリップボード履歴に長大なデータがあるときの動作速度を少しだけ改善。 | |||
== ソースコード == | == ソースコード == | ||
ダウンロード: 「[[ファイル:クリップボード履歴.zip ]] | ; ダウンロード: 「[[ファイル:クリップボード履歴.zip ]]」(アイコン入り) | ||
<source lang="javascript"> | <source lang="javascript" style="height:40em; overflow:auto;"> | ||
#title = "クリップボード履歴..." | #title = "クリップボード履歴..." | ||
#tooltip = "クリップボード履歴 と スニペット" | #tooltip = "クリップボード履歴 と スニペット" | ||
| 30行目: | 41行目: | ||
* -------------------------------------------------- | * -------------------------------------------------- | ||
* 「クリップボード履歴 と スニペット」マクロ | * 「クリップボード履歴 と スニペット」マクロ | ||
* sukemaru, 2019/08/01 | * sukemaru, 2019/08/01 - 2019/08/05 | ||
* -------------------------------------------------- | * -------------------------------------------------- | ||
* 「クリップボード履歴」メニューと「スニペット」プラグインと同等の機能を | * 「クリップボード履歴」メニューと「スニペット」プラグインと同等の機能を | ||
* | * ひとつのポップアップメニューに統合します。 | ||
* | * | ||
* 【このマクロの仕様・制限事項】 | * 【このマクロの仕様・制限事項】 | ||
| 45行目: | 56行目: | ||
* | * | ||
* ※「スニペット」プラグインを導入していない場合でも、 | * ※「スニペット」プラグインを導入していない場合でも、 | ||
* 「ピン止めアイテム/スニペット」機能を使用できます。 | |||
* snippets.txt ファイルの保存場所は Mery\Plugins\Snippets フォルダです | * snippets.txt ファイルの保存場所は Mery\Plugins\Snippets フォルダです | ||
* (インストーラ版では %AppData%\Mery\Plugins\Snippets フォルダ)。 | * (インストーラ版では %AppData%\Mery\Plugins\Snippets フォルダ)。 | ||
* | * | ||
* ※「GetKeyState.exe」は Mery\Macros | * ※「GetKeyState.exe」は Mery\Macros フォルダに配置してください | ||
* | * (Macros フォルダ以外の場所にあるなら設定項目でパスを指定する)。 | ||
* ※「GetKeyState.exe」を導入していない場合は、 | |||
* 「貼り付けしてからアイテムを削除する」サブメニューを表示します。 | * 「貼り付けしてからアイテムを削除する」サブメニューを表示します。 | ||
* | |||
* (2019/08/05) | |||
* ・「ピン止めアイテムを貼り付け」のコードミスを修正 | |||
* ・クリップボード履歴内の重複アイテムを削除する設定を追加。 | |||
* ・ピン止めアイテムが少ないときはメインメニューにアイテムを表示。 | |||
* ・snippets.txt 内の空行を無視。 | |||
* ・クリップボード履歴に長大なデータがあるときの動作速度を少しだけ改善。 | |||
*/ | */ | ||
// ---------- ▼ 設定項目 ▼ ---------- // | // ---------- ▼ 設定項目 ▼ ---------- // | ||
// ■ クリップボード履歴内の重複アイテムを削除する | |||
var delDupEnable = true; // true: 削除する / false: 削除しない | |||
// ■ ピン止めアイテムをサブメニュー化するアイテム数の閾値 | |||
var snSubMenu = 5; // これよりアイテム数が多いときはサブメニューで表示する | |||
// ■ ポップアップメニューを表示する位置 | // ■ ポップアップメニューを表示する位置 | ||
| 59行目: | 85行目: | ||
// ■ ポップアップメニューに表示する文字数 | // ■ ポップアップメニューに表示する文字数 | ||
var menuWidth = | var menuWidth = 60; | ||
// ■ GetKeyState.exe のフルパスを指定する場合(「\」記号はふたつがさね「\\」で) | // ■ GetKeyState.exe のフルパスを指定する場合(「\」記号はふたつがさね「\\」で) | ||
| 95行目: | 121行目: | ||
var st = s.Text; | var st = s.Text; | ||
// ピン止めアイテム (スニペット) | |||
var snippets = "", snCount = 0; | |||
if ( snIsExist ) { | |||
snippets = IO.LoadFromFile( snippetsPath, "utf-8" ) || ""; | |||
var snArray = snippets.replace( /^\n/gm, "" ).replace( /\n$/, "" ) | |||
.split( "\n" ); | |||
snCount = snArray.length; | |||
var sn = ( snCount > snSubMenu ); | |||
} | |||
// クリップボード履歴 | |||
var cb = ClipboardData; | |||
var cbArray = []; | |||
for ( var i = 0; ; i ++ ) { | |||
cbItem = cb.GetData( i ) || ""; | |||
if ( ! cbItem ) { break; } | |||
// 重複するアイテムを履歴から削除する | |||
if ( delDupEnable ) { | |||
for ( var j = i + 1, cbNextItem; ; j ++ ) { | |||
cbNextItem = cb.GetData( j ) || ""; | |||
if ( ! cbNextItem ) { break; } | |||
if ( cbItem == cbNextItem ) { | |||
cb.ClearData( j ); | |||
j --; | |||
} | |||
} | |||
} | |||
// 履歴アイテムを配列に収納する | |||
cbArray.push( cbItem ); | |||
} | |||
var cbCount = cbArray.length; | |||
var width = String( Math.max( snCount, cbCount ) ).length; | |||
// ポップアップメニューの準備 | |||
var menu = CreatePopupMenu(); | var menu = CreatePopupMenu(); | ||
var sm0 = CreatePopupMenu(); | var sm0 = CreatePopupMenu(); | ||
| 101行目: | 161行目: | ||
var menuFlags = d.ReadOnly ? meMenuGrayed : 0; | var menuFlags = d.ReadOnly ? meMenuGrayed : 0; | ||
var t = ( sn || snArray[0] == "" ) ? "" : "▼ "; | |||
var | menu.AddPopup( t + "ピン止めアイテム/スニペット (&P) " + t, sm0 ); | ||
menu.AddPopup( "ピン止めアイテム/スニペット (&P)", sm0 ); | |||
// スニペットのアイテムをメニューに | |||
if ( snCount ) { | if ( snCount ) { | ||
var snMenu = sn ? sm0 : menu; | |||
for ( var i = 0, id, label; i < snCount; i ++ ) { | for ( var i = 0, id, label; i < snCount; i ++ ) { | ||
id = i + 1; | id = i + 1; | ||
label = snArray[i].replace( /\t[\s\S]*/, "" ); | label = snArray[i].replace( /\t[\s\S]*/, "" ); | ||
if ( label ) { | |||
snMenu.Add( MenuKey( label, id, width ), id + 300, menuFlags ); | |||
} | |||
} | |||
if ( sn ) { | |||
snMenu.Add( "", 0, meMenuSeparator ); | |||
} | } | ||
} | } | ||
if ( st ) { | if ( st ) { | ||
| 128行目: | 184行目: | ||
sm0.Add( "スニペットを編集 (&E) ...", 400 ); | sm0.Add( "スニペットを編集 (&E) ...", 400 ); | ||
} | } | ||
sm0.Add( "", 0, meMenuSeparator ); | |||
sm0.Add( "キャンセル & ", 0 ); | |||
// | // クリップボード履歴のアイテムをメニューに | ||
if ( cbCount ) { | if ( cbCount ) { | ||
menu.Add( "", 0, meMenuSeparator ); | menu.Add( "", 0, meMenuSeparator ); | ||
menu.Add( "▼ クリップボード履歴 ▼", 0, meMenuGrayed ); | menu.Add( "▼ クリップボード履歴 ▼", 0, meMenuGrayed ); | ||
for ( var i = 0, id, label; i < cbCount; i ++ ) { | for ( var i = 0, id, label; i < cbCount; i ++ ) { | ||
id = i + 1; | id = i + 1; | ||
label = MenuKey( cbArray[i], id, | label = MenuKey( cbArray[i], id, width ); | ||
menu.Add( label, id, menuFlags ); | menu.Add( label, id, menuFlags ); | ||
sm1.Add( label, id + 100, menuFlags ); | sm1.Add( label, id + 100, menuFlags ); | ||
| 157行目: | 204行目: | ||
} | } | ||
menu.AddPopup( "クリップボードの履歴からアイテムを削除する (&D)", sm2 ); | menu.AddPopup( "クリップボードの履歴からアイテムを削除する (&D)", sm2 ); | ||
// menu.Add( "", 0, meMenuSeparator ); | |||
menu.Add( "クリップボードのすべての履歴を削除する (&C)", 500 ); | menu.Add( "クリップボードのすべての履歴を削除する (&C)", 500 ); | ||
} | } | ||
| 166行目: | 214行目: | ||
// ポップアップメニューを表示 | // ポップアップメニューを表示 | ||
var r = menu.Track( + menuPosMouse ); | var r = menu.Track( + menuPosMouse ); | ||
var confirmStr = menu.GetText( r ).replace( | var confirmStr = menu.GetText( r ).replace( /する \(&\w\)$/, "しますか? "); | ||
if ( r == 0 ) { | |||
; | |||
} | |||
// 1 ~ 16: 貼り付け | // 1 ~ 16: 貼り付け | ||
if ( | else if ( r < 100 ) { | ||
d.Write( cbArray[ r -1 ] ); | d.Write( cbArray[ r -1 ] ); | ||
// Ctrl キーを押しながらのときは、貼り付けたアイテムを履歴から削除する | // Ctrl キーを押しながらのときは、貼り付けたアイテムを履歴から削除する | ||
| 193行目: | 245行目: | ||
// 301 ~ 399: ピン止めアイテムを貼り付け | // 301 ~ 399: ピン止めアイテムを貼り付け | ||
else if ( r > 300 && r < 400 ) { | else if ( r > 300 && r < 400 ) { | ||
var str = | var str = snArray[ r -301 ].replace( /^[^\t]*\t/, "" ) | ||
.replace( /(\\r)?\\n/g, "\n" ) | .replace( /(\\r)?\\n/g, "\n" ) | ||
.replace( /\\t/g, "\t" ) | .replace( /\\t/g, "\t" ) | ||
| 265行目: | 317行目: | ||
.replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g, " › " ) | .replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g, " › " ) | ||
.replace( /[&]/g, "&&" ) | .replace( /[&]/g, "&&" ) | ||
// .replace( /[\\]/g, "∖" ) | .slice( 0, menuWidth + 1 ) // (2019/08/05 追加) | ||
.replace( /[\\]/g, "∖" ) | |||
.replace( /([^∖!"',.:;`|\t ])([∖]+)/g, "$1 $2" ) | |||
.replace( /[!"%'(),.:;@\[\]`a-z{|}]/g, | |||
function( tmp ) { | |||
return String.fromCharCode( tmp.charCodeAt( 0 ) + 0xFEE0 ) | |||
} ); | |||
num = ( " " + num ).slice( - width ).replace( /\d$/, "&$&" ); | num = ( " " + num ).slice( - width ).replace( /\d$/, "&$&" ); | ||
menuKey = ( menuKey.length > menuWidth ) | menuKey = ( menuKey.length > menuWidth ) | ||
2019年8月6日 (火) 01:09時点における版
公式フォーラム[1] にて「クリップボード履歴」メニューの将来的に廃止されることが 予告?検討? されていますが、後継機能としては 「クリップボード履歴」プラグイン の登場により今後も安泰のようですね。
ということで、試験運用中だった自家用マクロを再度リサイクルして「クリップボード履歴とスニペット」の統合版ポップアップメニューにしてみました。
- 「クリップボード履歴」機能は Mery 2.8.1 以降の『延命措置』の新パラメータ[2] を利用したもの。
- 「スニペット」機能は スニペットプラグイン の設定ファイル snippets.txt を読み書きするというかたちにしています。
- あらかじめ「includeライブラリ」の導入が必要です。
- 「スニペットプラグイン」を導入していないでも「スニペット(定型文)」機能を利用できます。
- 外部実行ファイル「GetKeyState.exe 」で機能を拡張できます。
- このマクロは Mery 2.8.1 以降でしか利用できません。
- 動作確認は Windows XP sp3 (32bit) × Mery ベータ版 2.8.2 - 2.8.3 (ポータブル) でしかしていません。
一見して 誰得? なマクロですが、「クリップボード履歴」を「スニペット」機能とまとめてツールバーアイコン化できるという素敵なメリットがあります。
- cf. マクロライブラリには「定型文を挿入」機能に特化したマクロも別途あります。
更新履歴
• 2019/08/01: 初版
• 2019/08/01: ・「ピン止めアイテムを貼り付け」コードの変数ミスを修正 ・クリップボード履歴内の重複アイテムを削除する設定を追加。 ・ピン止めアイテムが少ないときはメインメニューにアイテムを表示。 ・snippets.txt 内の空行を無視。 ・クリップボード履歴に長大なデータがあるときの動作速度を少しだけ改善。
ソースコード
- ダウンロード: 「ファイル:クリップボード履歴.zip」(アイコン入り)
#title = "クリップボード履歴..."
#tooltip = "クリップボード履歴 と スニペット"
#include "include/IO.js"
// #icon = "clipboard_history[1].ico"
/**
* --------------------------------------------------
* 「クリップボード履歴 と スニペット」マクロ
* sukemaru, 2019/08/01 - 2019/08/05
* --------------------------------------------------
* 「クリップボード履歴」メニューと「スニペット」プラグインと同等の機能を
* ひとつのポップアップメニューに統合します。
*
* 【このマクロの仕様・制限事項】
* ・ver 2.8.0 以前の Mery では使用できません。
* ・「クリップボード履歴」は Mery 本体のメモリストアのものを使用します。
* ・「スニペット」プラグインの設定ファイル snippets.txt の読み書きをします。
* ・「include ライブラリ」が必要です(snippets.txt ファイルの読み書きに使用)。
* ・「GetKeyState.exe(キー状態取得実行ファイル) 」で機能を拡張できます。
* → クリップボード履歴のアイテムを Ctrl+クリックした場合、
* アイテムを貼り付けし、貼り終えたアイテムを削除します。
*
* ※「スニペット」プラグインを導入していない場合でも、
* 「ピン止めアイテム/スニペット」機能を使用できます。
* snippets.txt ファイルの保存場所は Mery\Plugins\Snippets フォルダです
* (インストーラ版では %AppData%\Mery\Plugins\Snippets フォルダ)。
*
* ※「GetKeyState.exe」は Mery\Macros フォルダに配置してください
* (Macros フォルダ以外の場所にあるなら設定項目でパスを指定する)。
* ※「GetKeyState.exe」を導入していない場合は、
* 「貼り付けしてからアイテムを削除する」サブメニューを表示します。
*
* (2019/08/05)
* ・「ピン止めアイテムを貼り付け」のコードミスを修正
* ・クリップボード履歴内の重複アイテムを削除する設定を追加。
* ・ピン止めアイテムが少ないときはメインメニューにアイテムを表示。
* ・snippets.txt 内の空行を無視。
* ・クリップボード履歴に長大なデータがあるときの動作速度を少しだけ改善。
*/
// ---------- ▼ 設定項目 ▼ ---------- //
// ■ クリップボード履歴内の重複アイテムを削除する
var delDupEnable = true; // true: 削除する / false: 削除しない
// ■ ピン止めアイテムをサブメニュー化するアイテム数の閾値
var snSubMenu = 5; // これよりアイテム数が多いときはサブメニューで表示する
// ■ ポップアップメニューを表示する位置
var menuPosMouse = true; // true: マウス位置 / false: キャレット位置
// ■ ポップアップメニューに表示する文字数
var menuWidth = 60;
// ■ GetKeyState.exe のフルパスを指定する場合(「\」記号はふたつがさね「\\」で)
var getKeyStatePath = ""; // editor.FullName.replace( /[^\\]+$/, "Macros\\GetKeyState.exe" );
// ---------- ▲ 設定項目 ▲ ---------- //
var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
var WshShell = new ActiveXObject( "WScript.Shell" );
// ClipboardData。Get/ClearData() に引数を指定できるのは ver 2.8.1 以降
if ( ! VersionCheck( "2.8.1" ) ) {
WshShell.SendKeys( "%TC" );
}
else {
var meryPath = editor.FullName;
var mery = Fso.GetBaseName( meryPath );
var meryDir = Fso.GetParentFolderName( meryPath ) + "\\";
var profileDir = meryDir;
var iniPath = meryDir + mery + ".ini";
if ( ! Fso.FileExists( iniPath ) ) {
profileDir = WshShell.SpecialFolders( "APPDATA" ) + "\\Mery\\";
}
var snippetsPath = profileDir + "Plugins\\Snippets\\Snippets.txt";
var snIsExist = Fso.FileExists( snippetsPath );
var getKeyStatePath;
var getKeyState = getKeyStatePath || meryDir + "Macros\\GetKeyState.exe";
var gksIsExist = Fso.FileExists( getKeyState );
var $ctrl = 0;
var d = editor.ActiveDocument;
var s = d.selection;
var st = s.Text;
// ピン止めアイテム (スニペット)
var snippets = "", snCount = 0;
if ( snIsExist ) {
snippets = IO.LoadFromFile( snippetsPath, "utf-8" ) || "";
var snArray = snippets.replace( /^\n/gm, "" ).replace( /\n$/, "" )
.split( "\n" );
snCount = snArray.length;
var sn = ( snCount > snSubMenu );
}
// クリップボード履歴
var cb = ClipboardData;
var cbArray = [];
for ( var i = 0; ; i ++ ) {
cbItem = cb.GetData( i ) || "";
if ( ! cbItem ) { break; }
// 重複するアイテムを履歴から削除する
if ( delDupEnable ) {
for ( var j = i + 1, cbNextItem; ; j ++ ) {
cbNextItem = cb.GetData( j ) || "";
if ( ! cbNextItem ) { break; }
if ( cbItem == cbNextItem ) {
cb.ClearData( j );
j --;
}
}
}
// 履歴アイテムを配列に収納する
cbArray.push( cbItem );
}
var cbCount = cbArray.length;
var width = String( Math.max( snCount, cbCount ) ).length;
// ポップアップメニューの準備
var menu = CreatePopupMenu();
var sm0 = CreatePopupMenu();
var sm1 = CreatePopupMenu();
var sm2 = CreatePopupMenu();
var menuFlags = d.ReadOnly ? meMenuGrayed : 0;
var t = ( sn || snArray[0] == "" ) ? "" : "▼ ";
menu.AddPopup( t + "ピン止めアイテム/スニペット (&P) " + t, sm0 );
// スニペットのアイテムをメニューに
if ( snCount ) {
var snMenu = sn ? sm0 : menu;
for ( var i = 0, id, label; i < snCount; i ++ ) {
id = i + 1;
label = snArray[i].replace( /\t[\s\S]*/, "" );
if ( label ) {
snMenu.Add( MenuKey( label, id, width ), id + 300, menuFlags );
}
}
if ( sn ) {
snMenu.Add( "", 0, meMenuSeparator );
}
}
if ( st ) {
sm0.Add( "選択範囲を登録 (&P)", 300 );
}
if ( snIsExist ) {
sm0.Add( "スニペットを編集 (&E) ...", 400 );
}
sm0.Add( "", 0, meMenuSeparator );
sm0.Add( "キャンセル & ", 0 );
// クリップボード履歴のアイテムをメニューに
if ( cbCount ) {
menu.Add( "", 0, meMenuSeparator );
menu.Add( "▼ クリップボード履歴 ▼", 0, meMenuGrayed );
for ( var i = 0, id, label; i < cbCount; i ++ ) {
id = i + 1;
label = MenuKey( cbArray[i], id, width );
menu.Add( label, id, menuFlags );
sm1.Add( label, id + 100, menuFlags );
sm2.Add( label, id + 200 );
}
menu.Add( "", 0, meMenuSeparator );
if ( ! gksIsExist ) {
menu.AddPopup( "貼り付けしてからアイテムを削除する (&M)", sm1 );
}
menu.AddPopup( "クリップボードの履歴からアイテムを削除する (&D)", sm2 );
// menu.Add( "", 0, meMenuSeparator );
menu.Add( "クリップボードのすべての履歴を削除する (&C)", 500 );
}
menu.Add( "", 0, meMenuSeparator );
menu.Add( "キャンセル & ", 0 );
// ポップアップメニューを表示
var r = menu.Track( + menuPosMouse );
var confirmStr = menu.GetText( r ).replace( /する \(&\w\)$/, "しますか? ");
if ( r == 0 ) {
;
}
// 1 ~ 16: 貼り付け
else if ( r < 100 ) {
d.Write( cbArray[ r -1 ] );
// Ctrl キーを押しながらのときは、貼り付けたアイテムを履歴から削除する
if ( gksIsExist ) {
$ctrl = WshShell.Run( "\"" + getKeyState + "\" c", 0, true );
}
if ( $ctrl == 1 ) {
cb.ClearData( r -1 );
}
}
// 101 ~ 116: 貼り付けして、そのアイテムをクリップボード履歴から削除する
else if ( r > 100 && r < 200 ) {
d.Write( cbArray[ r -101 ] );
cb.ClearData( r -101 );
}
// 201 ~ 216: アイテムをクリップボード履歴から削除する
else if ( r > 200 && r < 300 ) {
cb.ClearData( r -201 );
}
// 301 ~ 399: ピン止めアイテムを貼り付け
else if ( r > 300 && r < 400 ) {
var str = snArray[ r -301 ].replace( /^[^\t]*\t/, "" )
.replace( /(\\r)?\\n/g, "\n" )
.replace( /\\t/g, "\t" )
d.Write( str );
}
// 300: 選択範囲を登録(ピン止め)
else if ( r == 300 ) {
var snippetsDir = Fso.GetParentFolderName( snippetsPath );
var pluginsDir = Fso.GetParentFolderName( snippetsDir );
if ( ! Fso.FolderExists( pluginsDir ) ) {
Fso.CreateFolder( pluginsDir );
}
if ( ! Fso.FolderExists( snippetsDir ) ) {
Fso.CreateFolder( snippetsDir );
}
var str = snippets
+ ( snippets ? "\n" : "" )
+ st.replace( /\t/g, "\\t" )
.replace( /\r?\n/g, "\\n" );
IO.SaveToFile( snippetsPath, str, "utf-8", true );
}
// 400: ピン止めアイテムを編集(snippets.txt を開く)
else if ( r == 400 ) {
WshShell.Run( "\"" + editor.FullName + "\" \"" + snippetsPath + "\"" )
}
// 500: クリップボード履歴をすべて削除する
else if ( r == 500 && Confirm( confirmStr ) ) {
for ( var i = 0; i < cbCount; i ++ ) {
cb.ClearData( i );
}
}
}
// ---------- ▼ 関数 ▼ ---------- //
/**
* 関数 VersionCheck( versionStr )
* Mery 本体が引数で指定したバージョン以上かチェックする( i.e. "2.6.9" )
* 戻り値は、真偽値 true/false
*/
function VersionCheck( versionStr ) {
var Pad2 = function( str ) {
return str.replace( /[0-9]+/g , function( digit ) {
return digit.length < 2 ? "0" + digit : digit
} )
};
var editorVer = + ( Pad2( editor.Version ).replace( /\./g, "" ).slice( 0, 6 ) );
var requirement = + ( Pad2( versionStr ).replace( /\./g, "" ).slice( 0, 6 ) );
return ( editorVer >= requirement );
}
/**
* 関数 MenuKey( str, num, width )
* ポップアップメニューに表示するラベルを生成する
* ・行頭空白を除去、空白文字を圧縮
* ・削られてしまう「&」を補完
* ・「¥」(U+005C) を「∖」に置換:「∖」(U+2216) または「╲」(U+2572) 「﹨」(U+FE68)
* ・判別しづらいメタ文字を全角に置換: !"%'(),.:;@[]`{|}
* ・「a-z」を全角に置換
* ・行番号を空白でケタ埋め: EN SPACE「 」(U+2002)
* ・文字数を切り詰め
*/
function MenuKey( str, num, width ) {
var menuKey = str.replace( /^[\t ]+/gm, " › " )
.replace( /\r?\n/g, "⏎ " )
.replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g, " › " )
.replace( /[&]/g, "&&" )
.slice( 0, menuWidth + 1 ) // (2019/08/05 追加)
.replace( /[\\]/g, "∖" )
.replace( /([^∖!"',.:;`|\t ])([∖]+)/g, "$1 $2" )
.replace( /[!"%'(),.:;@\[\]`a-z{|}]/g,
function( tmp ) {
return String.fromCharCode( tmp.charCodeAt( 0 ) + 0xFEE0 )
} );
num = ( " " + num ).slice( - width ).replace( /\d$/, "&$&" );
menuKey = ( menuKey.length > menuWidth )
? menuKey.slice( 0, menuWidth ) + " ..."
: menuKey;
return num + ": " + menuKey;
}
スポンサーリンク