##// END OF EJS Templates
templater: make strings in template expressions be "string-escape"-ed correctly...
templater: make strings in template expressions be "string-escape"-ed correctly Changeset 64b4f0cd7336 (released with 2.8.1) fixed "recursively evaluate string literals as templates" problem (issue4102) by moving the location of "string-escape"-ing from "tokenizer()" to "compiletemplate()". But some parts in template expressions below are not processed by "compiletemplate()", and it may cause unexpected result. - 'expr' of 'if(expr, then, else)' - 'expr's of 'ifeq(expr, expr, then, else)' - 'sep' of 'join(list, sep)' - 'text' and 'style' of 'rstdoc(text, style)' - 'text' and 'chars' of 'strip(text, chars)' - 'pat' and 'repl' of 'sub(pat, repl, expr)' For example, '\n' of "{join(extras, '\n')}" is not "string-escape"-ed and treated as a literal '\n'. This breaks "Display the contents of the 'extra' field, one per line" example in "hg help templates". Just "string-escape"-ing on each parts above may not work correctly, because inside expression of nested ones already applies "string-escape" on string literals. For example: - "{join(files, '\n')}" doesn't return "string-escape"-ed string, but - "{join(files, if(branch, '\n', '\n'))}" does To fix this problem, this patch does: - introduce "rawstring" token and "runrawstring" method to handle strings not to be "string-escape"-ed correctly, and - make "runstring" method return "string-escape"-ed string, and delay "string-escape"-ing until evaluation This patch invokes "compiletemplate()" with "strtoken=exp[0]" in "gettemplate()", because "exp[1]" is not yet evaluated. This code path is tested via mapping ("expr % '{template}'"). In the other hand, this patch invokes it with "strtoken='rawstring'" in "_evalifliteral()", because "t" is the result of "arg" evaluation and it should be "string-escape"-ed if "arg" is "string" expression. This patch doesn't test "string-escape"-ing on 'expr' of 'if(expr, then, else)', because it doesn't affect the result.

File last commit:

r15156:143c78b4 default
r20663:5ab28a2e stable
Show More
map-cmdline.bisect
25 lines | 1.3 KiB | text/plain | TextLexer
changeset = 'changeset: {rev}:{node|short}\nbisect: {bisect}\n{branches}{bookmarks}{tags}{parents}user: {author}\ndate: {date|date}\nsummary: {desc|firstline}\n\n'
changeset_quiet = '{bisect|shortbisect} {rev}:{node|short}\n'
changeset_verbose = 'changeset: {rev}:{node|short}\nbisect: {bisect}\n{branches}{bookmarks}{tags}{parents}user: {author}\ndate: {date|date}\n{files}{file_copies_switch}description:\n{desc|strip}\n\n\n'
changeset_debug = 'changeset: {rev}:{node}\nbisect: {bisect}\n{branches}{bookmarks}{tags}{parents}{manifest}user: {author}\ndate: {date|date}\n{file_mods}{file_adds}{file_dels}{file_copies_switch}{extras}description:\n{desc|strip}\n\n\n'
start_files = 'files: '
file = ' {file}'
end_files = '\n'
start_file_mods = 'files: '
file_mod = ' {file_mod}'
end_file_mods = '\n'
start_file_adds = 'files+: '
file_add = ' {file_add}'
end_file_adds = '\n'
start_file_dels = 'files-: '
file_del = ' {file_del}'
end_file_dels = '\n'
start_file_copies = 'copies: '
file_copy = ' {name} ({source})'
end_file_copies = '\n'
parent = 'parent: {rev}:{node|formatnode}\n'
manifest = 'manifest: {rev}:{node}\n'
branch = 'branch: {branch}\n'
tag = 'tag: {tag}\n'
bookmark = 'bookmark: {bookmark}\n'
extra = 'extra: {key}={value|stringescape}\n'