1 #title = "hotsnip"
  2 #tooltip = "スニペットファイルのホットキーを一覧表示"
  3 #include "lib\sgc4jsee.jsee"
  4 
  5 /**
  6  * @fileOverview
  7  * スニペットファイルから、使われているホットキーと、呼び出されるスニペットの一覧を作成します。
  8  * <p>
  9  * スニペットからeesnipファイルをエクスポートし、入力ダイアログにそのファイルへの絶対パスを入力して実行すると、<br />
 10  * そこからホットキーとスニペットの一覧(TSV)を作成し、EmEditorで開きます。
 11  * </p>
 12  * <p>
 13  * スニペットのフォルダ階層は以下のように表現されます。<br />
 14  * <pre>
 15  * Ctrl+Shift+1  |  folderA  |  snippet1
 16  * Ctrl+Shift+2  |  folderA  |  folderB   |  snippet2
 17  * Ctrl+Shift+3  |  folderA  |  folderC   |  snippet3
 18  * Ctrl+Shift+4  |  folderD  |  snippet4
 19  * </pre>
 20  * </p>
 21  * 
 22  * @author gecca from 雪月花 (http://setsugecca.org/)
 23  * @version 1.00
 24  */
 25 
 26 (function() {
 27 	var tempFilePath = JseeUtil.getTempDirPath() + "EmEditorMacros_スニペットファイルのホットキーを一覧表示.tmp";
 28 	
 29 	var snipXmlPath = prompt("スニペットからエクスポートしたeesnipファイルを指定してください。", "");
 30 	if(!snipXmlPath) {
 31 		return;
 32 	}
 33 	
 34 	if(!JseeUtil.fso().FileExists(snipXmlPath)) {
 35 		alert("以下のファイルが存在しません。\n" + snipXmlPath);
 36 		return;
 37 	}
 38 	
 39 	// 空の臨時ファイルを作成
 40 	JseeUtil.writeFile(tempFilePath, "");
 41 	
 42 	var xml = new ActiveXObject("MSXML.DOMDocument");
 43 	xml.load(snipXmlPath);
 44 	
 45 	// スニペット上のマクロフォルダの配下のマクロをファイル出力
 46 	var getParentFolderNode = function(target) {
 47 		var parent = target;
 48 		do {
 49 			parent = parent.parentNode;
 50 			if(!parent) {
 51 				return undefined;
 52 			}
 53 		} while(parent.tagName && parent.tagName != "Folder");
 54 		
 55 		return parent;
 56 	};
 57 	
 58 	// xmlノードを潜り、ホットキー一覧に表示する対象を臨時ファイルに書き出していく
 59 	(function processChildren(target) {
 60 		var children = target.childNodes;
 61 		
 62 		for(var i=0;i<children.length;i++) {
 63 			if(children[i].tagName) {
 64 				OutputBar.writeln(":"+children[i].tagName);
 65 				if(children[i].tagName == "Item") {
 66 					appendItemToFile(tempFilePath, children[i]);
 67 				} else {
 68 					processChildren(children[i]);
 69 				}
 70 			}
 71 		}
 72 	})(xml);
 73 	
 74 	// 臨時ファイルをTSVで開いて消す
 75 	JseeUtil.openFile(tempFilePath);
 76 	editor.ExecuteCommandByID(4471);
 77 	JseeUtil.fso().DeleteFile(tempFilePath);
 78 	
 79 	return;
 80 	
 81 	// アイテムノードからファイルにappend
 82 	function appendItemToFile(filePath, $item) {
 83 		var hotKeyString = shortcutKeyAndShortcutVirt2HotKeyString($item.getAttribute("ShortcutKey"), $item.getAttribute("ShortcutVirt"));
 84 		if(hotKeyString) {
 85 			JseeUtil.appendFile(filePath, quoteFileName(hotKeyString) + "\t" + getDirectLineElementsNameString($item) + "\r\n");
 86 		}
 87 		
 88 		return;
 89 		
 90 		// 直系の先祖要素と自分の要素を羅列した文字列を取得
 91 		function getDirectLineElementsNameString(itemNode) {
 92 			var getDirectLineElementsNames = [];
 93 			var parent = itemNode;
 94 			do {
 95 				getDirectLineElementsNames.push(quoteFileName(parent.getAttribute("Name")));
 96 				parent = getParentFolderNode(parent);
 97 			} while(parent.tagName && parent.getAttribute("Name") != "# sgc4eesnip");
 98 			
 99 			return getDirectLineElementsNames.reverse().join("\t");
100 		}
101 		
102 		// ファイル名に使えない文字を全角化
103 		function quoteFileName(str) {
104 			return JseeUtil.escEscSeq(str).replace(/\\/g, "¥").replace(/:/g, ":").replace(/\*/g, "*").replace(/\?/g, "?").replace(/\"/g, "”").replace(/</g, "<").replace(/>/g, ">").replace(/\|/g, "|").replace(/\//g, "/");
105 		}
106 		
107 		// ShortcutKeyとShortcutVirtを"Shift+Ctrl+Alt+C"な形に変換
108 		function shortcutKeyAndShortcutVirt2HotKeyString(shortcutKey, shortcutVirt) {
109 			if(shortcutKey == 0) {
110 				return "";
111 			}
112 			
113 			// ShortcutVirtを解析
114 			var createShortcutVirtObject = function(shortcutVirt) {
115 				if(shortcutVirt == 0) {
116 					return {
117 						shift: false,
118 						ctrl: false,
119 						alt: false
120 					};
121 				}
122 				return {
123 					shift: !!(shortcutVirt & 4),
124 					ctrl: !!(shortcutVirt & 8),
125 					alt: !!(shortcutVirt & 16)
126 				};
127 			};
128 			
129 			// ShortcutKeyを解析
130 			var createShortcutKeyString = function(shortcutKey) {
131 				return {8:"Backspace",9:"Tab",13:"Enter",19:"Pause",20:"Caps Lock",27:"Esc",28:"変換",29:"無変換",32:"Space",33:"Page Up",34:"Page Down",35:"End",36:"Home",37:"←",38:"↑",39:"→",40:"↓",44:"Print Screen",45:"Insert",46:"Delete",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",65:"A",66:"B",67:"C",68:"D",69:"E",70:"F",71:"G",72:"H",73:"I",74:"J",75:"K",76:"L",77:"M",78:"N",79:"O",80:"P",81:"Q",82:"R",83:"S",84:"T",85:"U",86:"V",87:"W",88:"X",89:"Y",90:"Z",96:"Num 0",97:"Num 1",98:"Num 2",99:"Num 3",100:"Num 4",101:"Num 5",102:"Num 6",103:"Num 7",104:"Num 8",105:"Num 9",106:"Num *",107:"Num +",108:"Num Enter",109:"Num -",110:"Num .",111:"Num /",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",124:"F13",125:"F14",126:"F15",127:"F16",128:"F17",129:"F18",130:"F19",131:"F20",132:"F21",133:"F22",134:"F23",135:"F24",144:"Num Lock",145:"Scroll Lock",186:":",187:";",188:",",189:"-",190:".",191:"/",192:"@",219:"[",220:"\\",221:"]",222:"^"}[shortcutKey] || "";
132 			};
133 			
134 			var shortcutVirtObject = createShortcutVirtObject(shortcutVirt);
135 			var buf = "";
136 			if(shortcutVirtObject.shift) {
137 				buf += "Shift+"
138 			}
139 			if(shortcutVirtObject.ctrl) {
140 				buf += "Ctrl+"
141 			}
142 			if(shortcutVirtObject.alt) {
143 				buf += "Alt+"
144 			}
145 			return buf + createShortcutKeyString(shortcutKey);
146 		}
147 	}
148 })();
149