{ "<foo>" } [ "<foo>" html-unescape ] unit-test
{ "This &that" } [ "This &that" html-unescape ] unit-test
{ "This &that" } [ "This &that" html-unescape ] unit-test
+{ "a&b<c>d" } [ "a&b<c>d" html-unescape ] unit-test
{ "&" } [ "&" html-escape ] unit-test
{ "<foo>" } [ "<foo>" html-escape ] unit-test
+{ "a&b<c>d" } [ "a&b<c>d" html-escape ] unit-test
! Copyright (C) 2014 John Benediktsson
! See http://factorcode.org/license.txt for BSD license
-USING: assocs combinators.short-circuit kernel locals make math
-math.order math.parser math.ranges regexp sequences splitting
-strings ;
+USING: assocs combinators.short-circuit kernel literals locals
+make math math.order math.parser math.ranges regexp sequences
+splitting strings ;
IN: html.entities
+<PRIVATE
+
+CONSTANT: html-escapes {
+ { CHAR: & "&" }
+ { CHAR: < "<" }
+ { CHAR: > ">" }
+ { CHAR: \" """ }
+ { CHAR: ' "'" }
+}
+
+: next-escape ( seq -- i elt )
+ [ html-escapes key? ] find ;
+
+: escape, ( seq i elt -- seq' )
+ [ [ head-slice , ] [ 1 + tail-slice ] 2bi ]
+ [ html-escapes at , ] bi* ;
+
+PRIVATE>
+
: html-escape ( str -- newstr )
- {
- { "&" "&" }
- { "<" "<" }
- { ">" ">" }
- { "\"" """ }
- { "'" "'" }
- } [ replace ] assoc-each ;
+ [
+ [ dup next-escape dup ] [ escape, ] while 2drop ,
+ ] { } make dup length 1 > [ concat ] [ first ] if ;
<PRIVATE