Improve automatic text quoting so it minimizes escape sequences when
possible.
This commit is contained in:
parent
6012a00763
commit
75e0201fad
@ -1027,7 +1027,7 @@ static inline Text_t _quoted(Text_t text, bool colorize, char quote_char)
|
||||
add_char('$');
|
||||
add_char(quote_char);
|
||||
|
||||
#define add_escaped(str) ({ if (colorize) add_str("\x1b[34;1m"); add_char('\\'); add_str(str); if (colorize) add_str("\x1b[0;35m"); })
|
||||
#define add_escaped(str) ({ if (colorize) add_str("\x1b[34;1m"); add_str("$\\"); add_str(str); if (colorize) add_str("\x1b[0;35m"); })
|
||||
TextIter_t state = {text, 0, 0};
|
||||
for (int64_t i = 0; i < text.length; i++) {
|
||||
int32_t g = Text$get_grapheme_fast(&state, i);
|
||||
@ -1040,7 +1040,7 @@ static inline Text_t _quoted(Text_t text, bool colorize, char quote_char)
|
||||
case '\r': add_escaped("r"); break;
|
||||
case '\t': add_escaped("t"); break;
|
||||
case '\v': add_escaped("v"); break;
|
||||
case '\\': add_escaped("\\"); break;
|
||||
case '$': if (quote_char == '\'') add_char('$'); else add_escaped("$"); break;
|
||||
case '\x00' ... '\x06': case '\x0E' ... '\x1A':
|
||||
case '\x1C' ... '\x1F': case '\x7F' ... '\x7F': {
|
||||
if (colorize) add_str("\x1b[34;1m");
|
||||
@ -1082,7 +1082,43 @@ public Text_t Text$as_text(const void *text, bool colorize, const TypeInfo *info
|
||||
}
|
||||
|
||||
if (!text) return info && info->TextInfo.lang ? Text$from_str(info->TextInfo.lang) : Text("Text");
|
||||
Text_t as_text = _quoted(*(Text_t*)text, colorize, info == &Pattern$info ? '/' : '"');
|
||||
char quote_char;
|
||||
if (info == &Pattern$info) {
|
||||
quote_char = '/';
|
||||
} else {
|
||||
// Figure out the best quotation mark to use:
|
||||
bool has_dollar = false, has_double_quote = false, has_backtick = false,
|
||||
has_single_quote = false, needs_escapes = false;
|
||||
TextIter_t state = {*(Text_t*)text, 0, 0};
|
||||
for (int64_t i = 0; i < state.text.length; i++) {
|
||||
int32_t g = Text$get_grapheme_fast(&state, i);
|
||||
if (g == '$') {
|
||||
has_dollar = true;
|
||||
} else if (g == '"') {
|
||||
has_double_quote = true;
|
||||
} else if (g == '`') {
|
||||
has_backtick = true;
|
||||
} else if (g == (g & 0x7F) && (g == '\'' || g == '\n' || g == '\r' || g == '\t' || !isprint((char)g))) {
|
||||
needs_escapes = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If there's dollar signs and/or double quotes in the string, it would
|
||||
// be nice to avoid needing to escape them by using single quotes, but
|
||||
// only if we don't have single quotes or need to escape anything else
|
||||
// (because single quotes don't have interpolation):
|
||||
if ((has_dollar || has_double_quote) && !has_single_quote && !needs_escapes)
|
||||
quote_char = '\'';
|
||||
// If there is a double quote, but no backtick, we can save a bit of
|
||||
// escaping by using backtick instead of double quote:
|
||||
else if (has_double_quote && !has_backtick)
|
||||
quote_char = '`';
|
||||
// Otherwise fall back to double quotes as the default quoting style:
|
||||
else
|
||||
quote_char = '"';
|
||||
}
|
||||
|
||||
Text_t as_text = _quoted(*(Text_t*)text, colorize, quote_char);
|
||||
if (info && info->TextInfo.lang && info != &Text$info && info != &Pattern$info)
|
||||
as_text = Text$concat(
|
||||
colorize ? Text("\x1b[1m$") : Text("$"),
|
||||
|
@ -55,11 +55,11 @@ func main():
|
||||
>> choose_text(Foo.Two(123, 456))
|
||||
= "Two: x=123, y=456"
|
||||
>> choose_text(Foo.Three(123, "hi", yes))
|
||||
= "Three: Three(x=123, y=\"hi\", z=yes)"
|
||||
= 'Three: Three(x=123, y="hi", z=yes)'
|
||||
>> choose_text(Foo.Four(1,2,3,4))
|
||||
= "Four"
|
||||
>> choose_text(Foo.Last("XX"))
|
||||
= "else: Foo.Last(\"XX\")"
|
||||
= 'else: Foo.Last("XX")'
|
||||
|
||||
i := 1
|
||||
cases := [Foo.One(1), Foo.One(2), Foo.Zero]
|
||||
@ -72,6 +72,3 @@ func main():
|
||||
else:
|
||||
-1
|
||||
= 2
|
||||
|
||||
|
||||
|
||||
|
@ -40,4 +40,4 @@ func main():
|
||||
= $HTML"<p>Hello I <3 hax!</p>"
|
||||
|
||||
>> Text(html)
|
||||
= "$HTML\"Hello I <3 hax!\""
|
||||
= '$HTML"Hello I <3 hax!"'
|
||||
|
@ -20,7 +20,7 @@ func main():
|
||||
= ["PENGUIN"]
|
||||
|
||||
>> \[31;1]
|
||||
= "\e[31;1m"
|
||||
= "$\e[31;1m"
|
||||
|
||||
>> \UE9 == \U65\U301
|
||||
= yes
|
||||
@ -91,20 +91,20 @@ func main():
|
||||
line one
|
||||
line two
|
||||
"
|
||||
= "line one\nline two"
|
||||
= "line one$\nline two"
|
||||
|
||||
!! Interpolation tests:
|
||||
>> "A $(1+2)"
|
||||
= "A 3"
|
||||
>> 'A $(1+2)'
|
||||
= "A $(1+2)"
|
||||
= 'A $(1+2)'
|
||||
>> `A $(1+2)`
|
||||
= "A 3"
|
||||
|
||||
>> $"A $(1+2)"
|
||||
= "A 3"
|
||||
>> $$"A $(1+2)"
|
||||
= "A $(1+2)"
|
||||
= 'A $(1+2)'
|
||||
>> $="A =(1+2)"
|
||||
= "A 3"
|
||||
>> ${one {nested} two $(1+2)}
|
||||
|
Loading…
Reference in New Issue
Block a user