summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual.tex5
-rw-r--r--include/urweb.h2
-rw-r--r--lib/ur/basis.urs1
-rw-r--r--src/c/urweb.c22
-rw-r--r--src/mono_opt.sml7
-rw-r--r--src/monoize.sml5
6 files changed, 42 insertions, 0 deletions
diff --git a/doc/manual.tex b/doc/manual.tex
index c9920a66..067d5aa4 100644
--- a/doc/manual.tex
+++ b/doc/manual.tex
@@ -1838,6 +1838,11 @@ $$\begin{array}{l}
\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}\} \\
diff --git a/include/urweb.h b/include/urweb.h
index 4c86e7ec..13beb643 100644
--- a/include/urweb.h
+++ b/include/urweb.h
@@ -89,12 +89,14 @@ char *uw_Basis_htmlifyFloat(uw_context, uw_Basis_float);
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);
diff --git a/lib/ur/basis.urs b/lib/ur/basis.urs
index 9fa37c5d..025e4281 100644
--- a/lib/ur/basis.urs
+++ b/lib/ur/basis.urs
@@ -575,6 +575,7 @@ con tag :: {Type} -> {Unit} -> {Unit} -> {Type} -> {Type} -> Type
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}
diff --git a/src/c/urweb.c b/src/c/urweb.c
index aea2c6ba..d3b8c770 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -1963,6 +1963,28 @@ uw_unit uw_Basis_htmlifyInt_w(uw_context ctx, uw_Basis_int n) {
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;
diff --git a/src/mono_opt.sml b/src/mono_opt.sml
index 6e137dc5..34f43143 100644
--- a/src/mono_opt.sml
+++ b/src/mono_opt.sml
@@ -64,6 +64,8 @@ val htmlifyString = String.translate (fn #"<" => "&lt;"
| #"&" => "&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 @@ fun exp e =
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), _)]) =>
diff --git a/src/monoize.sml b/src/monoize.sml
index eccf5714..0c0d9d2e 100644
--- a/src/monoize.sml
+++ b/src/monoize.sml
@@ -2849,6 +2849,11 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
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 (