module.exports = function normalize(path) { | |
var parts = path.split(/(\\+|\/+)/); | |
if(parts.length === 1) | |
return path; | |
var result = []; | |
var absolutePathStart = 0; | |
for(var i = 0, sep = false; i < parts.length; i++, sep = !sep) { | |
var part = parts[i]; | |
if(i === 0 && /^([A-Z]:)?$/i.test(part)) { | |
result.push(part); | |
absolutePathStart = 2; | |
} else if(sep) { | |
result.push(part[0]); | |
} else if(part === "..") { | |
switch(result.length) { | |
case 0: | |
// i. e. ".." => ".." | |
// i. e. "../a/b/c" => "../a/b/c" | |
result.push(part); | |
break; | |
case 2: | |
// i. e. "a/.." => "" | |
// i. e. "/.." => "/" | |
// i. e. "C:\.." => "C:\" | |
// i. e. "a/../b/c" => "b/c" | |
// i. e. "/../b/c" => "/b/c" | |
// i. e. "C:\..\a\b\c" => "C:\a\b\c" | |
i++; | |
sep = !sep; | |
result.length = absolutePathStart; | |
break; | |
case 4: | |
// i. e. "a/b/.." => "a" | |
// i. e. "/a/.." => "/" | |
// i. e. "C:\a\.." => "C:\" | |
// i. e. "/a/../b/c" => "/b/c" | |
if(absolutePathStart === 0) { | |
result.length -= 3; | |
} else { | |
i++; | |
sep = !sep; | |
result.length = 2; | |
} | |
break; | |
default: | |
// i. e. "/a/b/.." => "/a" | |
// i. e. "/a/b/../c" => "/a/c" | |
result.length -= 3; | |
break; | |
} | |
} else if(part === ".") { | |
switch(result.length) { | |
case 0: | |
// i. e. "." => "." | |
// i. e. "./a/b/c" => "./a/b/c" | |
result.push(part); | |
break; | |
case 2: | |
// i. e. "a/." => "a" | |
// i. e. "/." => "/" | |
// i. e. "C:\." => "C:\" | |
// i. e. "C:\.\a\b\c" => "C:\a\b\c" | |
if(absolutePathStart === 0) { | |
result.length--; | |
} else { | |
i++; | |
sep = !sep; | |
} | |
break; | |
default: | |
// i. e. "a/b/." => "a/b" | |
// i. e. "/a/." => "/" | |
// i. e. "C:\a\." => "C:\" | |
// i. e. "a/./b/c" => "a/b/c" | |
// i. e. "/a/./b/c" => "/a/b/c" | |
result.length--; | |
break; | |
} | |
} else if(part) { | |
result.push(part); | |
} | |
} | |
if(result.length === 1 && /^[A-Za-z]:$/.test(result)) | |
return result[0] + "\\"; | |
return result.join(""); | |
}; |