| package org.jetbrains.dokka |
| |
| import java.net.URI |
| |
| |
| fun URI.relativeTo(uri: URI): URI { |
| // Normalize paths to remove . and .. segments |
| val base = uri.normalize() |
| val child = this.normalize() |
| |
| fun StringBuilder.appendRelativePath() { |
| // Split paths into segments |
| var bParts = base.path.split('/').dropLastWhile { it.isEmpty() } |
| val cParts = child.path.split('/').dropLastWhile { it.isEmpty() } |
| |
| // Discard trailing segment of base path |
| if (bParts.isNotEmpty() && !base.path.endsWith("/")) { |
| bParts = bParts.dropLast(1) |
| } |
| |
| // Compute common prefix |
| val commonPartsSize = bParts.zip(cParts).takeWhile { (basePart, childPart) -> basePart == childPart }.count() |
| bParts.drop(commonPartsSize).joinTo(this, separator = "") { "../" } |
| cParts.drop(commonPartsSize).joinTo(this, separator = "/") |
| } |
| |
| return URI.create(buildString { |
| if (base.path != child.path) { |
| appendRelativePath() |
| } |
| child.rawQuery?.let { |
| append("?") |
| append(it) |
| } |
| child.rawFragment?.let { |
| append("#") |
| append(it) |
| } |
| }) |
| } |