From 0a00742d2b026366dbe664fa42eb224930544017 Mon Sep 17 00:00:00 2001 From: Jack Snoeyink Date: Wed, 22 Jun 2022 21:15:27 -0400 Subject: [PATCH 1/3] debugging test fucn fh for escaping $ for htl_str. --- src/macro.jl | 59 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/src/macro.jl b/src/macro.jl index 34977ef..c04bacb 100644 --- a/src/macro.jl +++ b/src/macro.jl @@ -52,6 +52,53 @@ could also work within the `@htl` macro syntax. [1] There are also a few edge cases, see `@raw_str` documentation and Julia #22926 for more detail. """ +function fh(expr::String) + # Essentially this is an ad-hoc scanner of the string, splitting + # it by `$` to find interpolated parts and delegating the hard work + # to `Meta.parse`, treating everything else as a literal string. + args = Any[] + start = idx = 1 + strlen = lastindex(expr) + DOLLAR_NOESCAPE = r"(^\$)|([^\\](\\\\)*\$)" + while true + if match(DOLLAR_NOESCAPE,expr[start:strlen]) === nothing + #chunk = expr[start:strlen] # unused varible can be removed + println("done: $(expr[start:strlen])") + push!(args, expr[start:strlen]) + break + end + idx = last(findnext(DOLLAR_NOESCAPE, expr, start)) # last char of match is "$" + println("found\$: $(expr[start:idx])") + push!(args, expr[start:prevind(expr, idx)]) + start = nextind(expr, idx) + if length(expr) >= start && expr[start] == '$' + println("push: $(start)") + push!(args, "\$") + start += 1 + continue + end + (nest, tail) = Meta.parse(expr, start; greedy=false) + if nest === nothing + throw("missing expression at $idx: $(expr[start:end])") + end + if !(expr[start] == '(' || nest isa Symbol) + throw(DomainError(nest, + "interpolations must be symbols or parenthesized")) + end + if Meta.isexpr(nest, :(=)) + throw(DomainError(nest, + "assignments are not permitted in an interpolation")) + end + if nest isa String + # this is an interpolated string literal + nest = Expr(:string, nest) + end + push!(args, nest) + start = tail + end + return interpolate(args) +end + macro htl_str(expr::String) # Essentially this is an ad-hoc scanner of the string, splitting # it by `$` to find interpolated parts and delegating the hard work @@ -59,22 +106,26 @@ macro htl_str(expr::String) args = Any[] start = idx = 1 strlen = lastindex(expr) + DOLLAR_NOESCAPE = r"(^\$)|([^\\](\\\\)*\$)" while true - idx = findnext(isequal('$'), expr, start) - if idx == nothing - chunk = expr[start:strlen] + if match(DOLLAR_NOESCAPE,expr[start:strlen]) === nothing + #chunk = expr[start:strlen] # unused varible can be removed + #println("done: $(expr[start:strlen])") push!(args, expr[start:strlen]) break end + idx = last(findnext(DOLLAR_NOESCAPE, expr, start)) # last char of match is "$" + #println("found\$: $(expr[start:idx])") push!(args, expr[start:prevind(expr, idx)]) start = nextind(expr, idx) if length(expr) >= start && expr[start] == '$' + #println("push: $(start)") push!(args, "\$") start += 1 continue end (nest, tail) = Meta.parse(expr, start; greedy=false) - if nest == nothing + if nest === nothing throw("missing expression at $idx: $(expr[start:end])") end if !(expr[start] == '(' || nest isa Symbol) From 7621db1c66b3106854cfb897de1b3549d290f646 Mon Sep 17 00:00:00 2001 From: Jack Snoeyink Date: Wed, 22 Jun 2022 21:20:11 -0400 Subject: [PATCH 2/3] Interpolate only unescaped $ by findnext regexp. --- src/macro.jl | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) diff --git a/src/macro.jl b/src/macro.jl index c04bacb..f96a2bd 100644 --- a/src/macro.jl +++ b/src/macro.jl @@ -52,53 +52,6 @@ could also work within the `@htl` macro syntax. [1] There are also a few edge cases, see `@raw_str` documentation and Julia #22926 for more detail. """ -function fh(expr::String) - # Essentially this is an ad-hoc scanner of the string, splitting - # it by `$` to find interpolated parts and delegating the hard work - # to `Meta.parse`, treating everything else as a literal string. - args = Any[] - start = idx = 1 - strlen = lastindex(expr) - DOLLAR_NOESCAPE = r"(^\$)|([^\\](\\\\)*\$)" - while true - if match(DOLLAR_NOESCAPE,expr[start:strlen]) === nothing - #chunk = expr[start:strlen] # unused varible can be removed - println("done: $(expr[start:strlen])") - push!(args, expr[start:strlen]) - break - end - idx = last(findnext(DOLLAR_NOESCAPE, expr, start)) # last char of match is "$" - println("found\$: $(expr[start:idx])") - push!(args, expr[start:prevind(expr, idx)]) - start = nextind(expr, idx) - if length(expr) >= start && expr[start] == '$' - println("push: $(start)") - push!(args, "\$") - start += 1 - continue - end - (nest, tail) = Meta.parse(expr, start; greedy=false) - if nest === nothing - throw("missing expression at $idx: $(expr[start:end])") - end - if !(expr[start] == '(' || nest isa Symbol) - throw(DomainError(nest, - "interpolations must be symbols or parenthesized")) - end - if Meta.isexpr(nest, :(=)) - throw(DomainError(nest, - "assignments are not permitted in an interpolation")) - end - if nest isa String - # this is an interpolated string literal - nest = Expr(:string, nest) - end - push!(args, nest) - start = tail - end - return interpolate(args) -end - macro htl_str(expr::String) # Essentially this is an ad-hoc scanner of the string, splitting # it by `$` to find interpolated parts and delegating the hard work From b81e47c2b76414755a626d6eb6d6c50c955d6658 Mon Sep 17 00:00:00 2001 From: Jack Snoeyink Date: Wed, 22 Jun 2022 21:43:08 -0400 Subject: [PATCH 3/3] htl_str interpolate only unesc $ : rm debug code --- src/macro.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/macro.jl b/src/macro.jl index f96a2bd..4e5c63b 100644 --- a/src/macro.jl +++ b/src/macro.jl @@ -62,17 +62,13 @@ macro htl_str(expr::String) DOLLAR_NOESCAPE = r"(^\$)|([^\\](\\\\)*\$)" while true if match(DOLLAR_NOESCAPE,expr[start:strlen]) === nothing - #chunk = expr[start:strlen] # unused varible can be removed - #println("done: $(expr[start:strlen])") push!(args, expr[start:strlen]) break end idx = last(findnext(DOLLAR_NOESCAPE, expr, start)) # last char of match is "$" - #println("found\$: $(expr[start:idx])") push!(args, expr[start:prevind(expr, idx)]) start = nextind(expr, idx) if length(expr) >= start && expr[start] == '$' - #println("push: $(start)") push!(args, "\$") start += 1 continue