@@ -119,6 +119,45 @@ def self.expand(base, relative, pop = true)
119119 return join ( simplify ( components ) )
120120 end
121121
122+ # Calculate the relative path from one absolute path to another.
123+ #
124+ # This is useful for generating relative URLs from one location to another,
125+ # such as creating page-specific import maps or relative links.
126+ #
127+ # @parameter target [String] The destination path (where you want to go).
128+ # @parameter from [String] The source path (where you are starting from).
129+ # @returns [String] The relative path from `from` to `target`.
130+ #
131+ # @example Calculate relative path between pages.
132+ # Path.relative("/_components/app.js", "/foo/bar/")
133+ # # => "../../_components/app.js"
134+ #
135+ # @example Calculate relative path in same directory.
136+ # Path.relative("/docs/guide.html", "/docs/index.html")
137+ # # => "guide.html"
138+ def self . relative ( target , from )
139+ target_components = split ( target )
140+ from_components = split ( from )
141+
142+ # Remove the last component from 'from' to get the directory
143+ from_components = from_components [ 0 ...-1 ] if from_components . size > 0
144+
145+ # Find the common prefix
146+ common_length = 0
147+ [ target_components . size , from_components . size ] . min . times do |i |
148+ break if target_components [ i ] != from_components [ i ]
149+ common_length = i + 1
150+ end
151+
152+ # Calculate how many levels to go up
153+ up_levels = from_components . size - common_length
154+
155+ # Build the relative path components
156+ relative_components = [ ".." ] * up_levels + target_components [ common_length ..-1 ]
157+
158+ return join ( relative_components )
159+ end
160+
122161 # Convert a URL path to a local file system path using the platform's file separator.
123162 #
124163 # This method splits the URL path on `/` characters, unescapes each component using
0 commit comments