changeset 1358:32c8a3509369

Basis.cdataChar
author Adam Chlipala <adam@chlipala.net>
date Tue, 21 Dec 2010 18:01:23 -0500
parents a0f0823a54a0
children e525ad571e15
files doc/manual.tex include/urweb.h lib/ur/basis.urs src/c/urweb.c src/mono_opt.sml src/monoize.sml
diffstat 6 files changed, 42 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/doc/manual.tex	Tue Dec 21 17:01:51 2010 -0500
+++ b/doc/manual.tex	Tue Dec 21 18:01:23 2010 -0500
@@ -1838,6 +1838,11 @@
   \mt{val} \; \mt{cdata} : \mt{ctx} ::: \{\mt{Unit}\} \to \mt{use} ::: \{\mt{Type}\} \to \mt{string} \to \mt{xml} \; \mt{ctx} \; \mt{use} \; []
 \end{array}$$
 
+There is also a function to insert the literal value of a character.  Since Ur/Web uses the UTF-8 text encoding, the $\mt{cdata}$ function is only sufficient to encode characters with ASCII codes below 128.  Higher codes have alternate meanings in UTF-8 than in usual ASCII, so this alternate function should be used with them.
+$$\begin{array}{l}
+  \mt{val} \; \mt{cdataChar} : \mt{ctx} ::: \{\mt{Unit}\} \to \mt{use} ::: \{\mt{Type}\} \to \mt{char} \to \mt{xml} \; \mt{ctx} \; \mt{use} \; []
+\end{array}$$
+
 There is a function for producing an XML tree with a particular tag at its root.
 $$\begin{array}{l}
   \mt{val} \; \mt{tag} : \mt{attrsGiven} ::: \{\mt{Type}\} \to \mt{attrsAbsent} ::: \{\mt{Type}\} \to \mt{ctxOuter} ::: \{\mt{Unit}\} \to \mt{ctxInner} ::: \{\mt{Unit}\} \\
--- a/include/urweb.h	Tue Dec 21 17:01:51 2010 -0500
+++ b/include/urweb.h	Tue Dec 21 18:01:23 2010 -0500
@@ -89,12 +89,14 @@
 char *uw_Basis_htmlifyString(uw_context, uw_Basis_string);
 char *uw_Basis_htmlifyBool(uw_context, uw_Basis_bool);
 char *uw_Basis_htmlifyTime(uw_context, uw_Basis_time);
+char *uw_Basis_htmlifySpecialChar(uw_context, unsigned char);
 
 uw_unit uw_Basis_htmlifyInt_w(uw_context, uw_Basis_int);
 uw_unit uw_Basis_htmlifyFloat_w(uw_context, uw_Basis_float);
 uw_unit uw_Basis_htmlifyString_w(uw_context, uw_Basis_string);
 uw_unit uw_Basis_htmlifyBool_w(uw_context, uw_Basis_bool);
 uw_unit uw_Basis_htmlifyTime_w(uw_context, uw_Basis_time);
+uw_unit uw_Basis_htmlifySpecialChar_w(uw_context, unsigned char);
 
 char *uw_Basis_attrifyInt(uw_context, uw_Basis_int);
 char *uw_Basis_attrifyFloat(uw_context, uw_Basis_float);
--- a/lib/ur/basis.urs	Tue Dec 21 17:01:51 2010 -0500
+++ b/lib/ur/basis.urs	Tue Dec 21 18:01:23 2010 -0500
@@ -575,6 +575,7 @@
 
 con xml :: {Unit} -> {Type} -> {Type} -> Type
 val cdata : ctx ::: {Unit} -> use ::: {Type} -> string -> xml ctx use []
+val cdataChar : ctx ::: {Unit} -> use ::: {Type} -> char -> xml ctx use []
 val tag : attrsGiven ::: {Type} -> attrsAbsent ::: {Type}
           -> ctxOuter ::: {Unit} -> ctxInner ::: {Unit}
           -> useOuter ::: {Type} -> useInner ::: {Type}
--- a/src/c/urweb.c	Tue Dec 21 17:01:51 2010 -0500
+++ b/src/c/urweb.c	Tue Dec 21 18:01:23 2010 -0500
@@ -1963,6 +1963,28 @@
   return uw_unit_v;
 }
 
+char *uw_Basis_htmlifySpecialChar(uw_context ctx, unsigned char ch) {
+  unsigned int n = ch;
+  int len;
+  char *r;
+
+  uw_check_heap(ctx, INTS_MAX+3);
+  r = ctx->heap.front;
+  sprintf(r, "&#%u;%n", n, &len);
+  ctx->heap.front += len+1;
+  return r;
+}
+
+uw_unit uw_Basis_htmlifySpecialChar_w(uw_context ctx, unsigned char ch) {
+  unsigned int n = ch;
+  int len;
+
+  uw_check(ctx, INTS_MAX+3);
+  sprintf(ctx->page.front, "&#%u;%n", n, &len);
+  ctx->page.front += len;
+  return uw_unit_v;
+}
+
 char *uw_Basis_htmlifyFloat(uw_context ctx, uw_Basis_float n) {
   int len;
   char *r;
--- a/src/mono_opt.sml	Tue Dec 21 17:01:51 2010 -0500
+++ b/src/mono_opt.sml	Tue Dec 21 18:01:23 2010 -0500
@@ -64,6 +64,8 @@
                                        | #"&" => "&amp;"
                                        | ch => str ch)
 
+fun htmlifySpecialChar ch = "&#" ^ Int.toString (ord ch) ^ ";"
+
 fun hexIt ch =
     let
         val s = Int.fmt StringCvt.HEX (ord ch)
@@ -180,6 +182,11 @@
         ESeq ((EWrite (EPrim (Prim.String (s1 ^ s2)), loc), loc),
               e)
 
+      | EFfiApp ("Basis", "htmlifySpecialChar", [(EPrim (Prim.Char ch), _)]) =>
+        EPrim (Prim.String (htmlifySpecialChar ch))
+      | EWrite (EFfiApp ("Basis", "htmlifySpecialChar", [e]), _) =>
+        EFfiApp ("Basis", "htmlifySpecialChar_w", [e])
+
       | EFfiApp ("Basis", "htmlifyString", [(EFfiApp ("Basis", "intToString", [(EPrim (Prim.Int n), _)]), _)]) =>
         EPrim (Prim.String (htmlifyInt n))
       | EFfiApp ("Basis", "htmlifyString", [(EFfiApp ("Basis", "intToString", es), _)]) =>
--- a/src/monoize.sml	Tue Dec 21 17:01:51 2010 -0500
+++ b/src/monoize.sml	Tue Dec 21 18:01:23 2010 -0500
@@ -2849,6 +2849,11 @@
             in
                 ((L'.EFfiApp ("Basis", "htmlifyString", [se]), loc), fm)
             end
+          | L.ECApp (
+             (L.ECApp ((L.EFfi ("Basis", "cdataChar"), _), _), _),
+             _) =>
+            ((L'.EAbs ("ch", (L'.TFfi ("Basis", "char"), loc), (L'.TFfi ("Basis", "string"), loc),
+                       (L'.EFfiApp ("Basis", "htmlifySpecialChar", [(L'.ERel 0, loc)]), loc)), loc), fm)
 
           | L.EApp (
             (L.EApp (