because py3k nor js can output fixed floats with full precision
[shellsnippets/shellsnippets.git] / mksh / website.common
1 # From $MirOS: www/mk/common,v 1.11 2018/08/29 02:54:14 tg Exp $
2 #-
3 # Copyright © 2007, 2008, 2012, 2013, 2014, 2018
4 #       Thorsten “mirabilos” Glaser <tg@mirbsd.org>
5 #
6 # Provided that these terms and disclaimer and all copyright notices
7 # are retained or reproduced in an accompanying document, permission
8 # is granted to deal in this work without restriction, including un‐
9 # limited rights to use, publicly perform, distribute, sell, modify,
10 # merge, give away, or sublicence.
11 #
12 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
13 # the utmost extent permitted by applicable law, neither express nor
14 # implied; without malicious intent or gross negligence. In no event
15 # may a licensor, author or contributor be held liable for indirect,
16 # direct, other damage, loss, or other issues arising in any way out
17 # of dealing in the work, even if advised of the possibility of such
18 # damage or existence of a defect, except proven that it results out
19 # of said person’s immediate fault when using the work as intended.
20 #-
21 # Anything not already in timefns but also used by MirWebsite, while
22 # being more generally useful; teckids/mk/common has an older adapt‐
23 # ed fork while website.shar contains an even older version of this.
24
25 # RFC 2396 and some optional characters _plus_ apostrophe
26 # -> escapes all shell meta-characters as well
27 function uri_escape {
28         if (( $# )); then
29                 print -nr -- "$@"
30         else
31                 cat
32         fi | sed -e '
33             s.%.%25.g
34             s.;.%3B.g
35             s./.%2F.g
36             s.?.%3F.g
37             s.:.%3A.g
38             s.@.%40.g
39             s.&.%26.g
40             s.=.%3D.g
41             s.+.%2B.g
42             s.\$.%24.g
43             s.,.%2C.g
44             s.  .%09.g
45             s. .%20.g
46             s.<.%3C.g
47             s.>.%3E.g
48             s.#.%23.g
49             s.".%22.g
50             s.{.%7B.g
51             s.}.%7D.g
52             s.|.%7C.g
53             s.\\.%5C.g
54             s.\^.%5E.g
55             s.\[.%5B.g
56             s.\].%5D.g
57             s.`.%60.g
58             s.'\''.%27.g
59         '
60 }
61
62 # escape XHTML characters (three mandatory XML ones plus double quotes,
63 # the latter in an XML safe fashion numerically though)
64 function xhtml_escape {
65         if (( $# )); then
66                 print -nr -- "$@"
67         else
68                 cat
69         fi | sed \
70             -e 's\ 1&\ 1\&amp;\ 1g' \
71             -e 's\ 1<\ 1\&lt;\ 1g' \
72             -e 's\ 1>\ 1\&gt;\ 1g' \
73             -e 's\ 1"\ 1\&#34;\ 1g'
74 }
75
76 # same as valsub avoiding fork
77 function xhtml_fesc {
78         REPLY=${1//'&'/'&amp;'}
79         REPLY=${REPLY//'<'/'&lt;'}
80         REPLY=${REPLY//'>'/'&gt;'}
81         REPLY=${REPLY//'"'/'&#34;'}
82 }
83
84 # escape string into JSON string (with surrounding quotes)
85 function json_escape {
86         [[ -o utf8-mode ]]; local u=$?
87         set -U
88         local o=\" s
89         if (( $# )); then
90                 read -raN-1 s <<<"$*"
91                 unset s[${#s[*]}-1]
92         else
93                 read -raN-1 s
94         fi
95         local -i i=0 n=${#s[*]} wc
96         local -Uui16 -Z7 x
97         local -i1 ch
98
99         while (( i < n )); do
100                 (( ch = x = wc = s[i++] ))
101                 case $wc {
102                 (8) o+=\\b ;;
103                 (9) o+=\\t ;;
104                 (10) o+=\\n ;;
105                 (12) o+=\\f ;;
106                 (13) o+=\\r ;;
107                 (34) o+=\\\" ;;
108                 (92) o+=\\\\ ;;
109                 (*)
110                         if (( wc < 0x20 || wc > 0xFFFD || \
111                             (wc >= 0xD800 && wc <= 0xDFFF) || \
112                             (wc > 0x7E && wc < 0xA0) )); then
113                                 o+=\\u${x#16#}
114                         else
115                                 o+=${ch#1#}
116                         fi
117                         ;;
118                 }
119         done
120         (( u )) && set +U
121         print -nr -- "$o\""
122 }
123
124 # escape ampersands for sed (pipe only: post-processing)
125 function sed_escape {
126         local REPLY=$1
127
128         REPLY=${REPLY//\\/\\\\}
129         REPLY=${REPLY//[&]/\\&}
130         REPLY=${REPLY//$'\n'/\\n}
131         print -nr -- "$REPLY"
132 }
133
134 # filter stdin into an HTML/XHTML JavaScript block
135 function script_escape {
136         print -r -- "<script type=\"text/javascript\"><!--//--><![CDATA[//><!--"
137         print -r -- "$(cat)"
138         print -r -- "//--><!]]></script>"
139 }
140
141 # filter stdin into an HTML/XHTML inline CSS block
142 function css_escape {
143         print -r -- "<style type=\"text/css\"><!--/*--><![CDATA[/*><!--*/"
144         print -r -- "$(cat)"
145         print -r -- "/*]]>*/--></style>"
146 }