src/Pure/General/url.ML
author wenzelm
Mon, 09 Dec 2013 12:16:52 +0100
changeset 56044 3daeba5130f0
parent 29606 fedb8be05f24
child 59180 85ec71012df8
permissions -rw-r--r--
added document antiquotation @{url}, which produces formal markup for LaTeX and PIDE;
     1 (*  Title:      Pure/General/url.ML
     2     Author:     Markus Wenzel, TU Muenchen
     3 
     4 Basic URLs, see RFC 1738 and RFC 2396.
     5 *)
     6 
     7 signature URL =
     8 sig
     9   datatype T =
    10     File of Path.T |
    11     RemoteFile of string * Path.T |
    12     Http of string * Path.T |
    13     Ftp of string * Path.T
    14   val append: T -> T -> T
    15   val implode: T -> string
    16   val explode: string -> T
    17   val pretty: T -> Pretty.T
    18   val print: T -> string
    19 end;
    20 
    21 structure Url: URL =
    22 struct
    23 
    24 (* type url *)
    25 
    26 datatype T =
    27   File of Path.T |
    28   RemoteFile of string * Path.T |
    29   Http of string * Path.T |
    30   Ftp of string * Path.T;
    31 
    32 
    33 (* append *)
    34 
    35 fun append (File p)            (File p') = File (Path.append p p')
    36   | append (RemoteFile (h, p)) (File p') = RemoteFile (h, Path.append p p')
    37   | append (Http (h, p))       (File p') = Http (h, Path.append p p')
    38   | append (Ftp (h, p))        (File p') = Ftp (h, Path.append p p')
    39   | append _ url = url;
    40 
    41 
    42 (* implode *)
    43 
    44 fun implode_path p = if Path.is_current p then "" else Path.implode p;
    45 
    46 fun implode_url (File p) = implode_path p
    47   | implode_url (RemoteFile (h, p)) = "file://" ^ h ^ implode_path p
    48   | implode_url (Http (h, p)) = "http://" ^ h ^ implode_path p
    49   | implode_url (Ftp (h, p)) = "ftp://" ^ h ^ implode_path p;
    50 
    51 
    52 (* explode *)
    53 
    54 local
    55 
    56 val scan_host =
    57   (Scan.many1 (fn s => s <> "/" andalso Symbol.is_regular s) >> implode) --|
    58   Scan.ahead ($$ "/" || Scan.one Symbol.is_eof);
    59 
    60 val scan_path = Scan.many Symbol.is_regular >> (Path.explode o implode);
    61 val scan_path_root = Scan.many Symbol.is_regular >> (Path.explode o implode o cons "/");
    62 
    63 val scan_url =
    64   Scan.unless (Scan.this_string "file:" ||
    65     Scan.this_string "http:" || Scan.this_string "ftp:") scan_path >> File ||
    66   Scan.this_string "file:///" |-- scan_path_root >> File ||
    67   Scan.this_string "file://localhost/" |-- scan_path_root >> File ||
    68   Scan.this_string "file://" |-- scan_host -- scan_path >> RemoteFile ||
    69   Scan.this_string "file:/" |-- scan_path_root >> File ||
    70   Scan.this_string "http://" |-- scan_host -- scan_path >> Http ||
    71   Scan.this_string "ftp://" |-- scan_host -- scan_path >> Ftp;
    72 
    73 in
    74 
    75 fun explode_url s = Symbol.scanner "Malformed URL" scan_url (Symbol.explode s);
    76 
    77 end;
    78 
    79 
    80 (* print *)
    81 
    82 val pretty = Pretty.mark_str o `Markup.url o implode_url;
    83 
    84 val print = Pretty.str_of o pretty;
    85 
    86 
    87 (*final declarations of this structure!*)
    88 val implode = implode_url;
    89 val explode = explode_url;
    90 
    91 end;