function [rel_ref_file_path level] = absFile2relFile(abs_file, rel_to_abs_file)
% absFile2relFile Returns a relative path to given absolute file.
% Input:
% * abs_file ... absolute file for which to find the realtive path
% * rel_to_abs_file ... this is the basis for the relative path
%
% Output:
% * rel_ref_file_path ... relative path
% * level ... if in the same directory level equals zero, one directory
% below returns level -1, above returns +1
%
% Note: In case any of the files is not found or they are on different
% drives empty parameters are returned.
%
% Example
% first create diretories
%+ mkdir('c:\test\a\b\');
% and test files
%+ cd('c:\test\a\b\'); fid=fopen('c.txt','w'); fclose(fid);
%+ cd('c:\test\'); fid=fopen('d.txt','w'); fclose(fid);
% now execute the command
%+ [rel_ref_file_path level] = absFile2relFile('c:\test\a\b\c.txt', 'c:\test\d.txt')
% The file c.txt is to levels (directories) below d.txt, hence the result:
% a/b and level -2.
%
% Continue the example with ...
%+ mkdir('c:\test\x\y\');
%+ cd('c:\test\x\y\'); fid=fopen('z.txt','w'); fclose(fid);
% now execute the command
%+ [rel_ref_file_path level] = absFile2relFile('c:\test\a\b\c.txt', 'c:\test\x\y\z.txt')
%The absolute file is "abc", and "xyz" is relative to "abc", hence
% go twice up to 'c:\test' (../../) and then go to "z" (x/y)
% together we got ../../x/y
%
% See also: uigetfile, uiputfile, dir
%
%% Signature
% Author: W.Garn
% E-Mail: wgarn@yahoo.com
% Date: 2005/12/05 20:00:00
%
% Copyright 2005 W.Garn
%
if nargin<1
help absFile2relFile;
end
rel_ref_file_path=[]; level=0;
if exist(abs_file,'file') && exist(rel_to_abs_file,'file')
abs_dirs = getDirs(abs_file);
rel_dirs = getDirs(rel_to_abs_file);
n = length(abs_dirs);
m = length(rel_dirs);
% common basis but distinct branches
basis = min( find ( (abs_dirs(1:min(n,m)) == rel_dirs(1:min(n,m))) == 0 ) )-1;
% common basis but what goes deeper
if isempty(basis),
basis = max( find ( (abs_dirs(1:min(n,m)) == rel_dirs(1:min(n,m))) == 1 ) );
end
%if basis== min(n,m) % then one contains the other
if n<=m %above or same level
rel_ref_file_path = rel_dirs(basis+1:m);
level = length(allSlashes(rel_ref_file_path));
pp = '';
for k=1:level
pp = [pp '../'];
end
rel_ref_file_path = [pp rel_ref_file_path];
else %within
rel_ref_file_path = abs_dirs(basis+1:n);
level = -length(allSlashes(rel_ref_file_path));
end
%end
end
function dirs = getDirs(abs_file)
% Returns the directories including the slash or backslash.
Ib = strfind(abs_file,'\');
Is = strfind(abs_file,'/');
I = union(Ib,Is);
if ~isempty(I)
dirs = abs_file(1:max(I));
dirs(I) = '/'; % replace backslahs by slash
else
dirs=[];
end
function pos = allSlashes(str)
Ib = strfind(str,'\');
Is = strfind(str,'/');
pos = union(Ib,Is);