uri.relative

function

Library: URI handling (OMURI)
Import : omuri.xmd

Returns: relative form of absolute-uri


Declaration
export string function
   relative      value string absolute-uri
            from value string base-uri
    


Purpose

Use uri.relative to convert an absolute URI into a relative form with respect to another, base URI. This function performs the opposite operation from uri.extend, which converts a URI which is relative to another base URI into absolute form. For example, the result of

  uri.relative "ftp://ftp.omnimark.com/9.0/" from "ftp://ftp.omnimark.com/10.1/"
would be
  "../9.0/"
while
  uri.relative "ftp://ftp.omnimark.com/10.1/" from "ftp://ftp.omnimark.com/10.1/"
would evaluate to
  "."

If absolute-uri cannot be made relative to base-uri because they refer to different schemes, uri.relative throws uri.cannot-be-made-relative. If absolute-uri is already in a relative form, it will be returned unmodified. The fragment portion of absolute-uri will be preserved in the result if present.

Example

A common use of uri.relative is to transform all cross-references within a set of documents into relative form. This transformation allows moving the document set into a different root location without breaking the cross-references. The following program performs this task on all URIs specified in href attributes.

Note the two catch clauses for handling the exceptions. The uri.already-absolute exception indicates an href attribute that points to an outside resource, such as http://example.com/. These should not be modified. The uri.current-document-reference exception indicates that an attribute points to the file it is in. We can handle that case in different ways, but in this example we refer the attribute to the #head anchor.

  import "omuri.xmd"      prefixed by uri.
  import "omvfs.xmd"      prefixed by vfs.
  import "omxmlwrite.xmd" prefixed by xml.
  
  
  global string source-directory initial { "file:/origin/" }
  global string target-directory initial { "file:/destination/" }
  
  global string current-document
  
  
  process
     local string documents variable
  
     vfs.list matching source-directory || "/*.xml" into documents
  
     repeat over documents as doc
        set current-document to uri.extend source-directory with doc
        using output as xml.writer into file uri.extend target-directory with doc
        do xml-parse scan file current-document
           output "%c"
        done
     again
  
  
  element #implied
     local markup-element-event new-element
  
     do when attribute "href" is specified
        local specified-attribute new-attributes variable
  
        copy specified attributes to new-attributes
  
        do
           set new-attributes{"href"} to uri.relative new-attributes{"href"} from current-document
  
         catch uri.cannot-be-made-relative
        done
  
        set new-element to create-element-event declaration of #current-markup-event attributes new-attributes
  
     else
        set new-element to #current-markup-event
     done
  
     signal throw #markup-start new-element
     output "%c"
     signal throw #markup-end   new-element
            

Related Topics
Other Library Functions