絶対パスと相対パスの相互変換を行う方法No.08617
kuke さん 18/01/15 17:46
 
秀丸エディタのマクロで、基準パスと対象パスの2つのパスから、
相対パスを作成する。基準パスと相対パスから、絶対パスを作成する。これらの操作
は、どうやって行ったら良いのでしょうか?

htmlファイルに、ファイルダイアログから、リンクさせるファイルを選択し、編集し
ているファイル名との比較で、相対パスを挿入する。

htmlファイルに記述された相対パスで指定されたリンクが、きちんと指定された場所
に存在するかを確認する。

これらの操作を行うために、2つのファイルを指定して、相対パスと絶対パスを作成
したいのですが、操作方法が思いつきません。

[ ]
RE:08617 絶対パスと相対パスの相互変換をNo.08618
Iranoan さん 18/01/15 21:59
 
kukeさん今日は、Iranoan です
> 秀丸エディタのマクロで、基準パスと対象パスの2つのパスから、
> 相対パスを作成する。基準パスと相対パスから、絶対パスを作成する。これらの操
>作は、どうやって行ったら良いのでしょうか?
カレント・フォルダを基準として、相対 path に変更するサブルーチンだと次のよう
感じでしょうか
//----------------------------------------------------------------------
relative_path:
  if( strlen( directory ) != 3 )$$path=directory+"\\";
  else $$path=directory;
  $$url=tolower($$1);
  if(leftstr($$path,3)!=leftstr($$url,3))return $$1;
  while(1){
    ##yen=strstr($$path,"\\")+1;
    if((leftstr($$url,##yen)!=leftstr($$path,##yen))||##yen==0)break;
    $$path=midstr( $$path, ##yen );
    $$url=midstr( $$url, ##yen );
  }
  $$1 = rightstr( $$1, strlen( $$url ) );
  ##i=0;
  while(1){
    ##yen=strstr($$path,"\\")+1;
    $$path=midstr( $$path, ##yen );
    if(##yen==0)break
    ##i=##i+1;
  }##j=0;
  while(##i>##j){
    ##j=##j+1;
    $$1="..\\"+$$1;
  }return $$1;
//----------------------------------------------------------------------
> htmlファイルに、ファイルダイアログから、リンクさせるファイルを選択し、編集
>しているファイル名との比較で、相対パスを挿入する。
これは insert 文
> htmlファイルに記述された相対パスで指定されたリンクが、きちんと指定された場
>所に存在するかを確認する。
これは existfile() 関数を使えば OK ですね
> これらの操作を行うために、2つのファイルを指定して、相対パスと絶対パスを作
>成したいのですが、操作方法が思いつきません。
絶対パスはカレントファイル/ディレクトリなら filename2 や directory2 で取得で
きますが、それ以外のケースも必要ですか?

[ ]
RE:08618 絶対パスと相対パスの相互変換をNo.08619
kuke さん 18/01/16 17:11
 
Iranoanさん、ありがとうございます。

「\」区切りごとに、文字列を比較しているところまでは、理解できたのですが、ぱ
っとコードを見だだけでは、何をしているのかよくわからなかったので、じっくり考
えてみることにします。
しばらくして、ある程度、理解できたところで、助けを求めると思いますので、よろ
しくお願いします。

[ ]
RE:08619 絶対パスと相対パスの相互変換をNo.08624
kuke さん 18/01/17 23:24
 
Iranoanさん、

おかげさまで、2つの絶対パスから、相対パスを求めるマクロの基本部分が完成しま
した。またバグが取れきっていないかもしれませんが、使いながら直していこうと思
います。
ありがとうございました。

// ---------------------------------------------------------

// 相対パス変換マクロ

// 対象パスと基準パスから、相対パスを返す


// 対象ファイル 動作確認用
// ファイル名が必要なのは、対象側のみ
$TargetFile = @"H:\MyWebSite\WebDesign\Tools\CMS\CMS.html";

// 対象パスの作業変数
$T_Pass = @"H:\MyWebSite\WebDesign\Tools\CMS";

// 基準パスの作業変数
$S_Pass = @"H:\MyWebSite\WebDesign\TagScript";

// ドライブ文字が同じことを確認する ex. H:\

if(leftstr($T_Pass,3) != leftstr($S_Pass,3))
{
 message "2つのファイルが異なるドライブに存在します";
 // マクロを終了する
 endmacro;
}

// ドライブ文字を取得する ex. H:\
$DriveLetter = leftstr($T_Pass,3);

// 対象ファイル名を取得する
#FileNamePosition=strrstr($TargetFile,"\\")+1;
$T_FileName= midstr($TargetFile,#FileNamePosition);

// 状態確認用MessageBox
 $msg = "ファイル名 " + $T_FileName;
 message $msg;

// 「\\」までごとに、2つのパスの同じ部分を削除する
  while(1){
// $T_Pass内の「\」の位置を確認する「\\」と2つあるので、+1
// #YenPosition内の位置を示す値は、0から開始される
    #YenPosition=strstr($T_Pass,"\\")+1;
 
 // \が見つからない場合
 if(#YenPosition==0){
  // $S_Passに、\が存在するか確認する
  #YenPosition=strstr($S_Pass,"\\")+1;
  if(#YenPosition==0){
  // どちらにも\がない場合
   if($T_Pass==$S_Pass){
    // $T_Passと$S_Passが同じであれば、どちらの内容も削除する
    $T_Pass="";
    $S_Pass="";
    break;
   }
   // $T_Passと$S_Passが異なれば、そのまま、ループから抜ける
   break;
  }
 }
 
 //  左から「\」の位置までの文字列が異なる場合、
    if(leftstr($T_Pass,#YenPosition)!=leftstr($S_Pass,#YenPosition))
 {
  // 一方のパスが最後まで削除された時の処理
  // 片側が **\ もう一方が、**になる。
  if(leftstr($T_Pass,#YenPosition-1)!=leftstr($S_Pass,#YenPosition-1))
  {
   // while[ループ](Loop)から抜ける。
   break;
  }
  else
  {
      // ディレクトリ部分のみ削除する
   $T_Pass= midstr( $T_Pass, #YenPosition-1);
   $S_Pass= midstr( $S_Pass, #YenPosition-1);
   
   // 一方のパスの先頭にある「\」を削除する
   if(leftstr($T_Pass,1)=="\\"){
    $T_Pass= midstr( $T_Pass,1);
   }
   if(leftstr($S_Pass,1)=="\\"){
    $S_Pass= midstr( $S_Pass,1);
   }
   
   // while[ループ](Loop)から抜ける。
   break;
  }
 }


// 「\」までの内容を削除する。

 $T_Pass= midstr( $T_Pass, #YenPosition);
 $S_Pass= midstr( $S_Pass, #YenPosition);

  }


// 動作確認用 ループを抜けた後のパスを表示
   $msg = "同じフォルダを削除した相対パスを作成する前のパス" + "\n";
   $msg = $msg + "対象パス" + $T_Pass + "\n";
  $msg = $msg + "基準パス" + $S_Pass;
   message $msg;

// 相対パスを作成する

// 対象パスの区切り文字「\」を「/」に変更する
$T_Result="";

#YenPosition=strstr($T_Pass,"\\")+1;

if(#YenPosition==0){
// \が見つからない場合で、
 if(strlen($T_Pass)>0){
 // 文字列(フォルダ)が存在すれば、$T_Resultの結果はその文字列(フォルダ)
  $T_Result=$T_Pass;
  if($T_Result!=""){
   $T_Result=$T_Result+"/";
  }
 }
}else{
 // 対象パスの区切り文字「\」を全て「/」に変更する
 while(1)
 {
  $T_Result=$T_Result+leftstr($T_Pass,#YenPosition-1);
  $T_Pass= midstr($T_Pass, #YenPosition);
  #YenPosition=strstr($T_Pass,"\\")+1;
  if(#YenPosition == 0){
   // \が見つからないとき、
   $T_Result=$T_Result+"/"+$T_Pass;
   
   // while[ループ](Loop)から抜ける。
   break;
  }

 }
 $T_Result=$T_Result+"/";
}
// 状態確認用MessageBox
 $msg = "$T_Result " + $T_Result;
 message $msg;
 
// 基準パスのフォルダを../に変更する

$S_Result="";

#YenPosition=strstr($S_Pass,"\\")+1;

if(#YenPosition==0){
// \が見つからない場合で、
 if(strlen($S_Pass)>0){
 // 文字列(フォルダ)が存在すれば、../を結果に追加する
  $S_Result=$S_Result+"../";
 }
}
 
while(#YenPosition)
{
// \が見つかれば、../を結果に追加する
 $S_Result=$S_Result+"../";
 // \までの文字列を削除する
 $S_Pass= midstr( $S_Pass, #YenPosition);
 // 再度、\を探す。
 #YenPosition=strstr($S_Pass,"\\")+1;
 if(#YenPosition==0){
  // \が見つからない場合で、
  if(strlen($S_Pass)>0){
  // 文字列(フォルダ)が存在すれば、../を結果に追加する
   $S_Result=$S_Result+"../";
  }
 }
}

// 状態確認用MessageBox
 $msg = "$S_Result " + $S_Result;
 message $msg;

// 状態確認用MessageBox
 $msg = "相対パス " + $S_Result + $T_Result + $T_FileName;
 message $msg;

// ---------------------------------------------------------

[ ]
RE:08624 絶対パスと相対パスの相互変換をNo.08625
vscode-life さん 18/01/22 19:18
 
絶対パスや相対パスには、Windowsのシステムに基づいた
やり方がありますよ、といったことの参考の1つとして掲載します。



#r = dllfuncw( #JS, "DoString", R"JS(

function GetBaseDirectory() {

    // 秀丸マクロのシンボル"filename2"を利用。今編集中のファイルのフルパス
    let filename2 = hm.Macro.Var["filename2"];

    // パスからディレクトリへ
    let strBaseUrl = clr.System.IO.Path.GetDirectoryName(filename2);
    return strBaseUrl + "/";
}

function GetTargetFilePath(strBaseDirectory) {

    // ダイアログ表示のため
    let lib = host.lib("System.Windows.Forms");

    let ofd = new lib.System.Windows.Forms.OpenFileDialog();

    // 最初に選択するフォルダを指定する
    ofd.InitialDirectory = strBaseDirectory;

    ofd.Filter = "HTMLファイル(*.html;*.htm;*.png)|*.html;*.htm;*.png|すべて
のファイル(*.*)|*.*"

    // ダイアログ表示して選択した?
    if (ofd.ShowDialog() == lib.System.Windows.Forms.DialogResult.OK)
    {
        return ofd.FileName;
    } else {
        throw "未選択";
    }
}

try {
    // ファイルを選択し、ベースのディレクトリを得る。
    let strBaseDirectory = GetBaseDirectory();
    let baseUrl = new clr.System.Uri(strBaseDirectory);

    let strTargetPath = GetTargetFilePath(strBaseDirectory);
    let targetUrl = new clr.System.Uri(strTargetPath);


    // 絶対Uriから相対Uriを取得する
    let relativeUri = baseUrl.MakeRelativeUri(targetUrl);

    //文字列に変換する
    let relativePath = relativeUri.ToString();

    // そのパスはローカルに本当に存在するのか?
    if ( !clr.System.IO.File.Exists(targetUrl.LocalPath) ) {
        throw "ファイルが無い";
    }

    // 秀丸マクロへと伝搬
    hm.Macro.Var["$relativePath"] = relativePath;
    hm.Macro.Var["$localPath"] = targetUrl.LocalPath;
    hm.Macro.Var["$absolutePath"] = targetUrl.AbsolutePath;

} catch(e) {
    hm.Macro.Var["$exceptionMessage"] = e;
}


)JS"
);

if ($exceptionMessage != "") {
    message $exceptionMessage;
} else {
    message $relativePath;
    message $localPath;
    message $absolutePath;
}

freedll(#JS);


[ ]
RE:08625 絶対パスと相対パスの相互変換をNo.08626
vscode-life さん 18/01/22 19:19
 
× 絶対Uriから相対Uriを取得する

〇 ベースUriから対象のUrlの相対Uriを得る

[ ]
RE:08626 絶対パスと相対パスの相互変換をNo.08627
vscode-life さん 18/01/22 19:25
 
最初のdllのロードが抜けていました。何回も連投すみません。




#JS = loaddll( hidemarudir + @"\hmV8.dll" );


// 以下すでに投稿済み
#r = dllfuncw( #JS, "DoString", R"JS(

function ・・・・

[ ]
RE:08626 絶対パスと相対パスの相互変換をNo.08628
kuke さん 18/01/26 08:37
 
ご指摘、ありがとうございます。
このあたりの正しい表現は、ぼんやりしているので、教えていただけて嬉しいです。
よりわかりやすく表現できますね。

[ ]
RE:08627 絶対パスと相対パスの相互変換をNo.08629
kuke さん 18/01/26 08:53
 
おお!
これは、秀丸マクロ.net系のjavaバージョンのものですね。

残念ながら、私は、java使えないのです。
C#は、学習しようとして、途中で止まっているので、hm.NETが、使えないかと考えた
のですが、どこから、どうやって学んだらいいのかよくわからなかったので、使えな
かったのです。

秀丸マクロ.net系やcom関連も使えるようになれば、より複雑な事ができそうなので
すが、どうやって学んだらいいのかよくわからないのが現状です。

参考にさせてもらいます。

[ ]