// バージョン:1.01 // 公開日 :2004.11.13 // 動作に必要なもの:田楽DLL $ini = macrodir + "\\Nepo101.ini"; //設定ファイルのパス $env = macrodir + "\\NepoEnv101.mac"; //環境設定マクロのパス //マクロ開始 call initialize; //マクロ終了 ////// ■ メイン関数群 ■ ////// 基本的に上から下へ実行 // &initialize 初期化 // initialize: //Ctrl,Shift,Altが押されていればメニューをキャレット(文字カーソル)に出す if (iskeydown(0x10) || iskeydown(0x11) || iskeydown(0x12)) #menuPosition = 1; //caret else #menuPosition = 0; //mouse #menuSize = 0; $menuName = ""; $menuPath = ""; disabledraw; #currentX = x; #currentY = y; $sbuffer = searchbuffer; #soption = searchoption; #debugMode = getininum($ini, "System", "UseDebugMode"); $indexList = getinistr($ini, "IndexSearch", "IndexFileList"); #webPathFlag = 0; #replacePathFlag = 0; #replaceAliasFlag = 0; //田楽DLLロード loaddll hidemarudir + "\\DengakuDLL.dll"; if (!result) call error "「文字列からファイルを開くマクロ」\n\n田楽DLLのロードに失敗しました。\n" + hidemarudir +" に DengakuDLL.dll があるか確認してください。"; else if (!existfile($ini)) { enabledraw; question "initialize : 設定ファイルが見つかりません\n\n開こうとした設定ファイルのパス = " + $ini + "\n\n「はい」  … 環境設定ダイアログを開きます。\n「いいえ」 … そのまま終了します。\n\n※初回起動では設定ファイルがないので、「はい」を押してください。"; if (result) { message "\"" + $ini + "\" を作ります。\nなにか問題があって設定を初期化したい時は、このファイルを削除してください。"; execmacro $env; } call exit; } call interpretPath; //次へ return; //initialize.end // interpretPath パス部分を解釈して選択 // interpretPath: if (!getininum($ini, "System", "UseFastSelect")) enabledraw; //セパレータ識別子が見つかるまで右へ行く while (code != ' ' && code != '"' && code != '\'' && code != '\t' && code != 0x0D && code != '>' && code != '|' && code != eof) right; ##sep = code; //セパレータを記憶 beginsel; //選択開始 //パスの左端まで選択する while (1) { left; if ((x == 0 && y == 0) || code == '\t' || code == 0x0D || //ファイルの先頭・タブ・改行にきたらそこまで (##sep != ' ' && ##sep == code) || (##sep == '>' && code == '<') || //セパレータがある時は、対のセパレータが見つかるまで code == ' ' //セパレータがない時は半角空白が見つかるまで ) break; } //カーソル位置がセパレータの時は選択範囲を調整 if (code == '\t' || code == 0x0D || code == '"' || code == '\'' || code == '<' || code == '|') right; endsel; //選択完了 disabledraw; call acquirePath; //次へ return; //interpretPath.end // &acquirePath パス文字列の取得 // acquirePath: if (!selecting) call interpretPath; ##sX = seltopx; //タグジャンプ判定用 $$path = dllfuncstr("RTRIM", dllfuncstr("LTRIM", gettext(seltopx, seltopy, selendx, selendy))); //前後の空白文字を削除 $$keyword = getinistr($ini, "System", "EnvsetKeyword"); if ($$path == $$keyword || ($$path == "" && $$keyword == "EnvsetKeywordNoneStrings")) { if (#debugMode) call alert "環境設定マクロの起動キーワードにマッチング"; execmacro $env; call exit; } else if ($$path == "") { if (#debugMode) call alert "acquirePath: パスを取得できませんでした"; call exit; } //JavaScriptやCSSやPerlとかのコメントをパスと勘違いしないように //頭に // があるとネットワークパスと判断する //頭に /* があるとルートパスと勘違いする //頭に # があるとアンカーと勘違いする //"///" は "//" にしてもいい(ただし //remotePC/... 形式のネットワークパスには対応しなくなる) if (leftstr($$path, 3) == "///" || leftstr($$path, 2) == "/*" || leftstr($$path, 1) == "#") call exit 1; //パスにエスケープとしての \\ が含まれる時は \ に置換 if (strstr($$path, "\\\\") != -1) { if (leftstr($$path, 4) == "\\\\\\\\") //ネットワークパスで先頭が \\\\ の時は先に // にして置換を避ける $$path = dllfuncstr("GSUB", $$path, "\\\\\\\\", "//", 1); if (leftstr($$path, 2) == "\\\\") //ネットワークパスで先頭が \\ の時は先に // にして置換を避ける $$path = dllfuncstr("GSUB", $$path, "\\\\", "//", 1); $$path = dllfuncstr("GSUB", $$path, "\\\\", "/", -1); //すべての \\ を / へ置換 } $$path = dllfuncstr("GSUB", $$path, "\\", "/", -1); //すべての \ を / へ置換 //パスに%が複数含まれる時は環境変数を展開してみる if (dllfunc("STRCOUNT", $$path, "%") > 1) { call envexpand $$path; $$path = $$return; } if (#debugMode) call alert "acquirePath: パスとして認識した文字列\n\n" + $$path; //選択開始が行頭から && 末尾が ) : の時はタグジャンプ if (##sX == 0 && (rightstr($$path, 1) == ")") || rightstr($$path, 1) == ":") { moveto #currentX, #currentY; tagjump; call exit 2; } call createAbsolutePath $$path; //次へ return; //acquirePath.end // createAbsolutePath 絶対パスの生成 // createAbsolutePath: $$path = $$1; //パスの区切りはすべて / に置換済(この関数の最後でまた置換) //URL・ネットワークパス・すでに絶対パス → そのまま if (leftstr($$path, 7) == "http://" || leftstr($$path, 8) == "https://" || leftstr($$path, 6) == "ftp://" || leftstr($$path, 2) == "//" || midstr($$path, 1, 2) == ":/") { $$abs = $$path; //ルートパス → "ドライブレター+取得したパス" } else if (leftstr($$path, 1) == "/") { #replaceAliasFlag = 0; //変換にマッチしたら1 call replaceAliasPath $$path; //エイリアスパス変換 $$abs = $$return; if (!#replaceAliasFlag) //マッチしたらすでに絶対パスになってる $$abs = leftstr(directory, 2) + $$path; //カレントフォルダ → ./ を削除して "カレントディレクトリ+取得したパス" } else if (leftstr($$path, 2) == "./") { call substr $$path, 2; $$abs = directory + "\\" + $$return; //相対パス → 絶対パスに変換 } else if (strstr($$path, "../") != -1) { //カレントディレクトリのパスを配列へ分割 $$dir[0] = dllfuncstr("GETTOKEN", directory, "\\"); ##n = 1; while (1) { if (!dllfunc("HASMORETOKENS")) break; $$s = dllfuncstr("GETTOKEN", "", "/\\"); if ($$s != "") { $$dir[##n] = $$s; ##n = ##n +1; } } ##dirlength = ##n; ##upNum = dllfunc("STRCOUNT", $$path, "../"); //上がる階層数 $$file = dllfuncstr("GSUB", $$path, "../", "", -1); //"../"を削除 ##n = 0; ##stopNum = ##dirlength - ##upNum; //総階層数−上がる階層数 while (1) { $$abs = $$abs + $$dir[##n] + "\\"; ##n = ##n +1; if (##stopNum == ##n) break; } $$abs = $$abs + $$file; //その他 → "カレントディレクトリ+取得したパス" } else if ($$path != "") { $$abs = directory + "/" + $$path; //取得文字列なし } else call exit; if (#debugMode) call alert "createAbsolutePath: 取得文字列から生成した絶対パス\n\n" + $$abs; call execute $$abs; //次へ(directoryを使ったので再置換しておく) return; //createAbsolutePath.end // &execute ■処理分岐 // 処理に応じた選択メニューを作成する事実上のメイン関数。このマクロで一番ややこしい部分。 execute: $$abs = dllfuncstr("GSUB", $$1, "\\", "/", -1); //取得した絶対パス(区切りは / に置換しておく) call checkScheme $$abs; //スキームチェック ##webPath = ##return; #menuSize = 0; //Webパスの時 if (##webPath) { call replacePath $$abs; //Webパス変換 $$abs = $$return; if (#replacePathFlag) { //ヒットあり call checkScheme $$abs; //もう一度スキームチェックしてWebパスのままか確認(Webパス変換が Web>Web Web>Local だった時) if (!##return) //ローカルパスになってる call execute $$abs; } call createMenu "Browser"; //パスの末尾が / の時はファイラ } else if (rightstr($$abs, 1) == "/") { Filer: //インデックスファイル補完に失敗するか「このファイルがあるフォルダを開く」を選んだ時に飛んでくる call createMenu "Filer"; call createMenu "index"; //ファイルの時 } else { call extselect $$abs; //拡張子ごとの分岐 $$res = $$return; if (#debugMode) call alert "execute: 拡張子ごとの分岐判定\n\n" + $$res + ""; #replacePathFlag = 0; //replacePath でHTTP変換にマッチしたら1 //パスに /? /# が含まれる(ファイル名なし+クエリあり) if ($$res == "クエリ選択") { ##res = 1; call replacePath $$abs; //絶対パスから$$docrootを$$webrootへ置換 $$webpath = $$return; call cutQueryString $$abs; $$abs = $$return; ##size = 1; $$menu[0] = "クエリをカットしてファイラで開く → " + $$abs; if (#replacePathFlag) { //ヒットがあれば追加 $$menu[1] = "Webパスに変換してブラウザで開く → " + $$webpath; ##size = 2; } enabledraw; if (#menuPosition) menuarray $$menu, ##size; else mousemenuarray $$menu, ##size; disabledraw; ##res = result; if (!##res) call exit; else if (##res == 1) goto Filer: else if (##res == 2) { call createMenu "Browser"; call createMenu "index"; $$abs = $$webpath; } } //以下はファイル名があるので存在チェック if (!existfile($$abs)) { call cutQueryString $$abs; if (!existfile($$return)) { //クエリをカットして再挑戦 if (#debugMode) call alert "execute: ファイルが存在しません。\n\n開こうとしたパス = " + $$abs; call exit 1; } } //サーバーに渡す html,xht,cgi,shtml if ($$res == "Webパス変換") { $$webpath = $$abs; call replacePath $$abs; //絶対パスから$docrootを$webrootへ置換 $$webpath = $$return; call cutQueryString $$abs; $$abs = $$return; call createMenu "replacewebpath", $$abs, $$webpath; call createMenu "cutfilename"; // $$menu[0] = $$abs + " をエディタで開く"; // $$menu[1] = $$abs + " をブラウザで開く"; // if (#replacePathFlag) { //ヒットがあれば追加 // $$menu[2] = $$webpath + " をブラウザで開く"; // ##menunum = 3; // } else if // ##menunum = 2; enabledraw; if (#menuPosition) menuarray $menuName, #menuSize; else mousemenuarray $menuName, #menuSize; disabledraw; ##n = result; call clearMenu; if (##n == 1) call createMenu "Editor"; else if (##n == 2) call createMenu "Browser"; else if (##n == 3 && #replacePathFlag) { //フラグが立ってれば追加メニューが入ってる call createMenu "Browser"; $$abs = $$webpath; } else if (##n == 3 || ##n == 4) { call cutFileName $$abs; $$abs = $$return; goto Filer; } else call exit; } else { if ($$res == "エディタ") { EditorSelect: //インデックスファイル補完に成功した時に飛んでくる call createMenu "Editor"; call createMenu "cutfilename"; } else if ($$res == "ブラウザ") { BrowserSelect: //Webパス変換にマッチすると飛んでくる call createMenu "Browser"; call createMenu "cutfilename"; } else if ($$res == "ビューア") { call createMenu "Viewer"; call createMenu "cutfilename"; } else if ($$res == "プレイヤー") { call createMenu "Player"; call createMenu "cutfilename"; } else if ($$res == "実行ファイル") { call apprun "\"" + $$abs + "\""; } else { call exit 1; } } } //メニュー作成終わり //アプリケーション起動 if ($menuName[0] != "" && $menuName[1] == "") { //選択メニューがひとつしかない時はそのまま開く call apprun $menuName[0], $menuPath[0], $$abs; } else { //選択メニューが複数ある時はメニュー表示 moveto #currentX, #currentY; enabledraw; if (#menuPosition) menuarray $menuName, #menuSize; else mousemenuarray $menuName, #menuSize; disabledraw; ##n = result; if (##n) { ##n = ##n -1; //メニューは1から、配列は0から始まるので-1 //インデックスファイル補完 if ($menuPath[##n] == "index") { call clearMenu; $$filename = dllfuncstr("GETTOKEN", $indexList, ">"); //インデックスファイル名リストから検索 while (1) { if (existfile($$abs + $$filename)) { //インデックスファイルが存在する $$abs = $$abs + $$filename; goto EditorSelect; } else if (!dllfunc("HASMORETOKENS")) break; $$filename = dllfuncstr("GETTOKEN", "", ">"); } $indexList = ""; //存在しない時は次のファイラメニューに選択肢を出さない goto Filer: //ファイラのメニューからやり直し //「このファイルがあるフォルダを開く」ファイル名を削ってファイラのパスへ整形 } else if ($menuPath[##n] == "cutfilename") { call cutFileName $$abs; $$abs = $$return; call clearMenu; goto Filer: //選択したアプリケーションで開く } else { call apprun $menuName[##n], $menuPath[##n], $$abs; } } } if (result) call exit; else call exit 1; return; //execute.end // e&xit 終了処理 // exit: setsearch $sbuffer, #soption; //検索条件を復元 escape; if (##1 != 2) //タグジャンプした時はすでに戻してある moveto #currentX, #currentY; if (##1 == 1) //パスの取得に失敗した時は単語選択 selectword; freedll; endmacro; //exit.end ////// ■ サブ関数群 ■ ////// 基本的にメイン関数群の可読性を高めるために分離されたモジュール類 // envexpand 環境変数の展開 // envexpand: $$path = $$1; while (1) { $$temp = $$path; //加工するのでパスをコピーする ##spos = strstr($$temp, "%"); //最初の%を検索 $$temp = dllfuncstr("GSUB", $$temp, "%", "", 1); //最初の%を削除 ##epos = strstr($$temp, "%"); //次の%を検索 $$temp = dllfuncstr("GSUB", $$temp, "%", "", 1); //次の%を削除 ##strings = ##epos - ##spos; //%〜%間の文字数 $$envstr = midstr($$temp, ##spos, ##strings); //環境変数と思われる文字列を抽出 if (getenv($$envstr) != "") { //展開してみる if (#debugMode) call alert "envexpand: 環境変数の展開にマッチング\n\n展開前の環境変数 = %" + $$envstr + "%\n展開後の環境変数 = " + getenv($$envstr); $$path = dllfuncstr("GSUB", $$path, "%" + $$envstr + "%", getenv($$envstr), 1); //展開できたら%ごと置換 } else //展開できなかったらスキップマークに置換 $$path = dllfuncstr("GSUB", $$path, "%" + $$envstr + "%", "::{skipmark}::" + $$envstr + "::{skipmark}::", 1); if (dllfunc("STRCOUNT", $$path, "%") < 2) //パスに含まれる%が1個以下になったら終了 break; } return dllfuncstr("GSUB", $$path, "::{skipmark}::", "%", -1); //スキップマークを元に戻す //envexpand.end // &createMenu メニュー配列作成 // createMenu: ##i = 0; while (1) { if ($$1 == "index" && $indexList != "" && str(getininum($ini, "IndexSearch", "UseIndexSearch")) == "1") { $menuName[#menuSize] = "インデックスファイル名を補完してエディタで開く"; $menuPath[#menuSize] = "index"; #menuSize = #menuSize +1; break; } else if ($$1 == "cutfilename" && getininum($ini, "System", "UseFolderOpen")) { $menuName[#menuSize] = "このファイルがあるフォルダを開く"; $menuPath[#menuSize] = "cutfilename"; #menuSize = #menuSize +1; break; } else if ($$1 == "replacewebpath") { $menuName[0] = $$2 + " をエディタで開く"; $menuName[1] = $$2 + " をブラウザで開く"; if (#replacePathFlag) { //ヒットがあれば追加 $menuName[2] = $$3 + " をブラウザで開く"; #menuSize = 3; } else #menuSize = 2; break; } else { $$name = getinistr($ini, $$1, $$1 + "Name" + str(##i)); call envexpand getinistr($ini, $$1, $$1 + "Path" + str(##i)); $$path = $$return; $$opt = getinistr($ini, $$1, $$1 + "Optn" + str(##i)); if ($$name != "" && $$path != "") { if ($$opt != "") $$path = $$path + " " + $$opt; $menuName[#menuSize] = $$name; $menuPath[#menuSize] = $$path; #menuSize = #menuSize +1; } else break; } ##i = ##i +1; } // ##i = 0; // while (1) { // if ($$menu == "filer") { // $$addmenu = $filer[##i]; // else if ($$menu == "editor") // $$addmenu = $editor[##i]; // else if ($$menu == "browser") // $$addmenu = $browser[##i]; // else if ($$menu == "viewer") // $$addmenu = $viewer[##i]; // else if ($$menu == "player") // $$addmenu = $player[##i]; // else if ($$menu == "index" && $indexList != "") { // $$addmenu = "インデックスファイル名を補完してエディタで開く||index"; // $$menu = ""; // } else if ($$menu == "cutfilename" && getininum($ini, "System", "UseFolderOpen")) { // $$addmenu = "このファイルがあるフォルダを開く||cutfilename"; // $$menu = ""; // } // // if ($$addmenu != "") { // call subleft $$addmenu, "||"; // $menuName[#menuSize] = $$return; // call subright $$addmenu, "||"; // $menuPath[#menuSize] = $$return; // // #menuSize = #menuSize +1; // $$addmenu = ""; // ##i = ##i +1; // } else // break; // } return; //createMenu.end // clearMenu メニュー配列を消去 // clearMenu: ##i = 0; while (1) { if ($menuName[##i] != "") { $menuName[##i] = ""; $menuPath[##i] = ""; } else break; ##i = ##i +1; } #menuSize = 0; return; //clearMenu.end // &replacePath パス変換 // replacePath: if (!getininum($ini, "ReplaceWebPath", "UseReplaceWebPath")) return $$1; $$abs = $$1; $$abslower = dllfuncstr("TOLOWER", $$abs); ##i = 0; while (1) { $$droot = getinistr($ini, "ReplaceWebPath", "DocRoot" + str(##i)); $$wroot = getinistr($ini, "ReplaceWebPath", "WebRoot" + str(##i)); if ($$droot == "" || $$wroot == "") break; else if (strstr($$abslower, dllfuncstr("TOLOWER", $$droot)) != -1) { #replacePathFlag = 1; //グローバル $$abs = dllfuncstr("GSUB", $$abs, $$droot, $$wroot, 1); break; } ##i = ##i +1; } if (#debugMode && #replacePathFlag) call alert "replacePath: 取得したパスがパス変換の設定にマッチング\n\n変換前のパス = " + $$1 + "\n変換後のパス = " + $$abs; return $$abs; //replacePath.end // replace&AliasPath エイリアスパス変換 // replaceAliasPath: if (!getininum($ini, "ReplaceAliasPath", "UseReplaceAliasPath")) return $$1; $$abs = $$1; $$abslower = dllfuncstr("TOLOWER", $$abs); ##i = 0; while (1) { $$alias = getinistr($ini, "ReplaceAliasPath", "AliasPath" + str(##i)); $$local = getinistr($ini, "ReplaceAliasPath", "LocalPath" + str(##i)); if ($$alias == "" || $$local == "") break; else if (strstr($$abslower, dllfuncstr("TOLOWER", $$alias)) != -1) { #replaceAliasFlag = 1; //グローバル $$abs = dllfuncstr("GSUB", $$abs, $$alias, $$local, 1); break; } ##i = ##i +1; } if (#debugMode && #replaceAliasFlag) call alert "replaceAliasPath: パスがエイリアスパス変換にマッチング\n\n変換前のパス = " + $$1 + "\n変換後のパス = " + $$abs; return $$abs; //replaceAliasPath.end // extselect 拡張子ごとの動作判定 // extselect: $$abs = $$1; //"../?query" などファイル名がなくてクエリかアンカーがある時 if (strstr($$abs, "/?") != -1 || strstr($$abs, "/#") != -1) return "クエリ選択"; //クエリをカットして拡張子を取得 call cutQueryString $$abs; $$abs = $$return; call lastIndexOf $$abs, "."; if (##return == -1) return ""; call substr $$abs, ##return +1; $$ext = $$return; if (#debugMode) call alert "extselet: パスから取得された拡張子\n\nパス = " + $$abs + "\n拡張子 = " + $$ext + ""; call listExist getinistr($ini, "ExtensionList", "SelectExt"), $$ext, ",", 0; if (##return) return "Webパス変換"; call listExist getinistr($ini, "ExtensionList", "EditorExt"), $$ext, ",", 1; if (##return) return "エディタ"; call listExist getinistr($ini, "ExtensionList", "BrowserExt"), $$ext, ",", 1; if (##return) return "ブラウザ"; call listExist getinistr($ini, "ExtensionList", "ViewerExt"), $$ext, ",", 1; if (##return) return "ビューア"; call listExist getinistr($ini, "ExtensionList", "PlayerExt"), $$ext, ",", 1; if (##return) return "プレイヤー"; call listExist getinistr($ini, "ExtensionList", "ExecuteExt"), $$ext, ",", 1; if (##return) return "実行ファイル"; return ""; //extselect.end // apprun アプリケーションの起動 // apprun: $$appname = $$1; $$apppath = $$2; $$abs = $$3; if (leftstr($$abs, 7) == "http://" || leftstr($$abs, 8) == "https://" || leftstr($$abs, 6) == "ftp://") ##webpath = 1; else ##webpath = 0; if (!##webpath) $$abs = dllfuncstr("GSUB", $$abs, "/", "\\", -1); // \ でないと動かないソフトがあるので置換しておく if ($$abs != "") { if (##webpath || (rightstr($$abs, 1) == "\\" || rightstr($$abs, 1) == "/" || existfile($$abs))) run $$apppath + " \"" + $$abs + "\""; else if (#debugMode) call error "apprun: ファイルが存在しません\n\nパス = " + $$3; } else run $$apppath; if (result) call exit; else call exit 1; return; //apprun.end ////// ■ 汎用関数群 ■ ////// alert: enabledraw; message $$1; disabledraw; return; error: call alert $$1; call exit; return; //$$1=リスト, $$2=検索文字列, $$3=区切り子, ##4=小文字変換フラグ listExist: if (##4) { $$1 = dllfuncstr("TOLOWER", $$1); $$2 = dllfuncstr("TOLOWER", $$2); } $$s = dllfuncstr("GETTOKEN", $$1, $$3); ##n = 1; while (1) { if ($$s == $$2) return 1; if (!dllfunc("HASMORETOKENS")) break; $$s = dllfuncstr("GETTOKEN", "", ","); } return 0; checkScheme: if (leftstr($$1, 5) == "http:") return 1; else if (leftstr($$1, 6) == "https:") return 2; else if (leftstr($$1, 4) == "ftp:") return 3; else if (leftstr($$1, 7) == "mailto:") return 4; else if (leftstr($$1, 5) == "file:") return 0; else return 0; cutFileName: call lastIndexOf $$1, "/"; $$1 = leftstr($$1, ##return +1); return $$1; cutQueryString: $$p = $$1; if (strstr($$p, "?") != -1) { //クエリカット call subleft $$p, "?"; $$p = $$return; } if (strstr($$p, "#") != -1) { //アンカーカット call subleft $$p, "#"; $$p = $$return; } return $$p; lastIndexOf: return dllfunc("STRRSTR2", $$1, $$2); substr: if (!##3) ##3 = dllfunc("STRLEN2", $$1) - ##2; return dllfuncstr("MIDSTR2", $$1, ##2, ##3); subleft: ##n = dllfunc("STRSTR2", $$1, $$2); $$s = dllfuncstr("LEFTSTR2", $$1, ##n); return $$s; subright: ##n = dllfunc("STRSTR2", $$1, $$2); $$s = dllfuncstr("MIDSTR2", $$1, ##n + dllfunc("STRLEN2", $$2), dllfunc("STRLEN2", $$1) - ##n); return $$s; test: message $$1; call exit; return; test2: message str(##1); call exit; return;