src/Pure/Isar/antiquote.ML
changeset 27746 c7aa4c18739d
parent 27342 3945da15d410
child 27750 7f5fb39c6362
equal deleted inserted replaced
27745:31899d977a89 27746:c7aa4c18739d
    51 
    51 
    52 structure T = OuterLex;
    52 structure T = OuterLex;
    53 
    53 
    54 local
    54 local
    55 
    55 
       
    56 fun count scan = Scan.depend (fn pos => scan >> (fn x => (Position.advance [x] pos, x)));
       
    57 
    56 val scan_txt =
    58 val scan_txt =
    57   T.count ($$ "@" --| Scan.ahead (~$$ "{")) ||
    59   count ($$ "@" --| Scan.ahead (~$$ "{")) ||
    58   T.count (Scan.one (fn s =>
    60   count (Scan.one (fn s =>
    59     s <> "@" andalso s <> "\\<lbrace>" andalso s <> "\\<rbrace>" andalso Symbol.is_regular s));
    61     s <> "@" andalso s <> "\\<lbrace>" andalso s <> "\\<rbrace>" andalso Symbol.is_regular s));
    60 
    62 
    61 fun escape "\\" = "\\\\"
    63 fun escape "\\" = "\\\\"
    62   | escape "\"" = "\\\""
    64   | escape "\"" = "\\\""
    63   | escape s = s;
    65   | escape s = s;
    64 
    66 
    65 val quote_escape = Library.quote o implode o map escape o Symbol.explode;
    67 val quote_escape = Library.quote o implode o map escape o T.clean_value;
    66 
    68 
    67 val scan_ant =
    69 val scan_ant =
    68   T.scan_string >> quote_escape ||
    70   T.scan_string >> quote_escape ||
    69   T.count (Scan.one (fn s => s <> "}" andalso Symbol.is_regular s));
    71   count (Scan.one (fn s => s <> "}" andalso Symbol.is_regular s));
    70 
    72 
    71 val scan_antiq =
    73 val scan_antiq =
    72   T.count ($$ "@") |-- T.count ($$ "{") |--
    74   count ($$ "@") |-- count ($$ "{") |--
    73     T.!!! "missing closing brace of antiquotation"
    75     T.!!! "missing closing brace of antiquotation"
    74       (Scan.repeat scan_ant >> implode) --| T.count ($$ "}");
    76       (Scan.repeat scan_ant >> implode) --| count ($$ "}");
    75 
    77 
    76 in
    78 in
    77 
    79 
    78 fun scan_antiquote (pos, ss) = (pos, ss) |>
    80 fun scan_antiquote (pos, ss) = (pos, ss) |>
    79   (Scan.repeat1 scan_txt >> (Text o implode) ||
    81   (Scan.repeat1 scan_txt >> (Text o implode) ||
    80     scan_antiq >> (fn s => Antiq (s, pos)) ||
    82     scan_antiq >> (fn s => Antiq (s, pos)) ||
    81     T.count ($$ "\\<lbrace>") >> K (Open pos) ||
    83     count ($$ "\\<lbrace>") >> K (Open pos) ||
    82     T.count ($$ "\\<rbrace>") >> K (Close pos));
    84     count ($$ "\\<rbrace>") >> K (Close pos));
    83 
    85 
    84 end;
    86 end;
    85 
    87 
    86 
    88 
    87 (* scan_antiquotes *)
    89 (* scan_antiquotes *)