@@ -382,8 +382,8 @@ escape_nul(c::Union{Nothing, AbstractChar}) =
382382 (c != = nothing && ' 0' <= c <= ' 7' ) ? " \\ x00" : " \\ 0"
383383
384384"""
385- escape_string(str::AbstractString[, esc]; keep = () )::AbstractString
386- escape_string(io, str::AbstractString[, esc]; keep = ())::Nothing
385+ escape_string(str::AbstractString[, esc]; keep=(), ascii=false, fullhex=false )::AbstractString
386+ escape_string(io, str::AbstractString[, esc]; keep= ())::Nothing
387387
388388General escaping of traditional C and Unicode escape sequences. The first form returns the
389389escaped string, the second prints the result to `io`.
@@ -398,11 +398,23 @@ escaped by a prepending backslash (`\"` is also escaped by default in the first
398398The argument `keep` specifies a collection of characters which are to be kept as
399399they are. Notice that `esc` has precedence here.
400400
401+ The argument `ascii` can be set to `true` to escape all non-ASCII characters,
402+ whereas the default `ascii=false` outputs printable Unicode characters as-is.
403+ (`keep` takes precedence over `ascii`.)
404+
405+ The argument `fullhex` can be set to `true` to require all `\\ u` escapes to be
406+ printed with 4 hex digits, and `\\ U` escapes to be printed with 8 hex digits,
407+ whereas by default (`fullhex=false`) they are printed with fewer digits if
408+ possible (omitting leading zeros).
409+
401410See also [`unescape_string`](@ref) for the reverse operation.
402411
403412!!! compat "Julia 1.7"
404413 The `keep` argument is available as of Julia 1.7.
405414
415+ !!! compat "Julia 1.12"
416+ The `ascii` and `fullhex` arguments require Julia 1.12.
417+
406418# Examples
407419```jldoctest
408420julia> escape_string("aaa\\ nbbb")
@@ -421,7 +433,7 @@ julia> escape_string(string('\\u2135','\\0','0')) # \\0 would be ambiguous
421433"ℵ\\\\ x000"
422434```
423435"""
424- function escape_string (io:: IO , s:: AbstractString , esc= " " ; keep = ())
436+ function escape_string (io:: IO , s:: AbstractString , esc= " " ; keep = (), ascii :: Bool = false , fullhex :: Bool = false )
425437 a = Iterators. Stateful (s)
426438 for c:: AbstractChar in a
427439 if c in esc
@@ -436,10 +448,10 @@ function escape_string(io::IO, s::AbstractString, esc=""; keep = ())
436448 isprint (c) ? print (io, c) :
437449 print (io, " \\ x" , string (UInt32 (c), base = 16 , pad = 2 ))
438450 elseif ! isoverlong (c) && ! ismalformed (c)
439- isprint (c) ? print (io, c) :
440- c <= ' \x 7f' ? print (io, " \\ x" , string (UInt32 (c), base = 16 , pad = 2 )) :
441- c <= ' \u ffff' ? print (io, " \\ u" , string (UInt32 (c), base = 16 , pad = need_full_hex (peek (a):: Union{AbstractChar,Nothing} ) ? 4 : 2 )) :
442- print (io, " \\ U" , string (UInt32 (c), base = 16 , pad = need_full_hex (peek (a):: Union{AbstractChar,Nothing} ) ? 8 : 4 ))
451+ ! ascii && isprint (c) ? print (io, c) :
452+ c <= ' \x 7f' ? print (io, " \\ x" , string (UInt32 (c), base = 16 , pad = 2 )) :
453+ c <= ' \u ffff' ? print (io, " \\ u" , string (UInt32 (c), base = 16 , pad = fullhex || need_full_hex (peek (a):: Union{AbstractChar,Nothing} ) ? 4 : 2 )) :
454+ print (io, " \\ U" , string (UInt32 (c), base = 16 , pad = fullhex || need_full_hex (peek (a):: Union{AbstractChar,Nothing} ) ? 8 : 4 ))
443455 else # malformed or overlong
444456 u = bswap (reinterpret (UInt32, c):: UInt32 )
445457 while true
@@ -450,8 +462,8 @@ function escape_string(io::IO, s::AbstractString, esc=""; keep = ())
450462 end
451463end
452464
453- escape_string (s:: AbstractString , esc= (' \" ' ,); keep = ()) =
454- sprint ((io)-> escape_string (io, s, esc; keep = keep ), sizehint= lastindex (s))
465+ escape_string (s:: AbstractString , esc= (' \" ' ,); keep = (), ascii :: Bool = false , fullhex :: Bool = false ) =
466+ sprint ((io)-> escape_string (io, s, esc; keep, ascii, fullhex ), sizehint= lastindex (s))
455467
456468function print_quoted (io, s:: AbstractString )
457469 print (io, ' "' )
0 commit comments