13
$\begingroup$

I need to have backquotes in a StringTemplate.

For example

StringTemplate["``1``"][2]

Returns "21" instead of "`2`".

How can I get the correct result ?

Of course a solution would be to use another character than the backquote and replace it after but this is not elegant.

$\endgroup$
4
  • $\begingroup$ Would escaping the first and last back ticks by preceding them with a backslash work? Unfortunately I'm on a tablet and can't check for myself. $\endgroup$
    – MarcoB
    Commented Dec 6, 2015 at 16:47
  • $\begingroup$ No it doesn't I've tried. $\endgroup$
    – faysou
    Commented Dec 6, 2015 at 16:52
  • 3
    $\begingroup$ Another kludge: StringTemplate["`1``2``1`"]["`", 2] $\endgroup$
    – Michael E2
    Commented Dec 6, 2015 at 17:24
  • $\begingroup$ Yes, it's the same idea as Kuba in TemplateApply["`a``input``a`", <|"a" -> "`", "input" -> 2|>]. I think it's the easiest and most flexible answer. $\endgroup$
    – faysou
    Commented Dec 7, 2015 at 9:21

4 Answers 4

10
$\begingroup$

edit

One can use template expression too:

StringTemplate["<*\"`\"*>``<*\"`\"*>"][123]
"`123`" 

old answer

That's unfortunate design/coincidence, the more that accents are important part of package files. What I'm using is an additional "`a`" which later is part of input <|"a"->"`", ...|>.

So at the end I'd go with

TemplateApply["`a``input``a`", <|"a" -> "`", "input" -> 2|>]
"`2`" 

quite ugly, but in case of file full of accents, like a package, works well.

Other way is to choose a character that is not going to appear there ever and replace it with accent:

StringTemplate[
   "\[FormalA]`1`\[FormalA]", 
   CombinerFunction -> (StringReplace[StringJoin@#, "\[FormalA]" -> "`"] &)
][2]
$\endgroup$
6
  • 1
    $\begingroup$ "Of course a solution would be to use another character than the backquote and replace it after but this is not elegant." - quoted from the question :) $\endgroup$
    – eldo
    Commented Dec 6, 2015 at 17:13
  • $\begingroup$ @eldo still, the first suggestion is different enough (I hope ;)) I decided to post it ;) $\endgroup$
    – Kuba
    Commented Dec 6, 2015 at 17:15
  • $\begingroup$ Ok so it seems I'm not missing anything, it's more a design issue. Hopefully it will be solved at some point. I could do any ad hoc solution, this is not the problem, it's more that I wanted to be sure there isn't an elegant solution to the problem, like a simple escape of the backquote. $\endgroup$
    – faysou
    Commented Dec 6, 2015 at 17:21
  • $\begingroup$ I think your first suggestion is the most practical. $\endgroup$
    – faysou
    Commented Dec 6, 2015 at 19:36
  • 1
    $\begingroup$ indeed this would be the real way to escape, but I still prefer your answer with a, it makes the template easier to understand, and this is what matters. $\endgroup$
    – faysou
    Commented Dec 6, 2015 at 20:06
5
$\begingroup$

You could build your own TemplateObject instead of relying on StringTemplate to do that:

template = TemplateObject[
     {"`", TemplateSlot[1], "`"},
     CombinerFunction -> StringJoin,
     InsertionFunction -> ToString
   ];

template["hello"]
template[4]

(* Out:
"`hello`"
"`4`"
*)

This does not require any substitution after-the-fact. In this most recent iteration I have added the InsertionFunction -> ToString bit, as suggested by @AlbertRetey in his comment: this allows the template to handle numerical input as well as strings.

$\endgroup$
2
  • $\begingroup$ I really like this one. If you add InsertFunction->ToString the OPs example with a number will also work. $\endgroup$ Commented Dec 6, 2015 at 23:55
  • $\begingroup$ @AlbertRetey Thank you! That's an excellent point you made about InsertionFunction; I added that to my answer as well. $\endgroup$
    – MarcoB
    Commented Dec 7, 2015 at 0:11
1
$\begingroup$

Simplest way seems to be to use the InsertionFunction option to add the additional backquotes in:

    StringTemplate["`1`", InsertionFunction -> ("`" <> ToString[#] <> "`" &)][2]

Returns

    "`2`"
$\endgroup$
1
  • $\begingroup$ This wouldn't work in a real case with several arguments as I wouldn't want to put backquotes everywhere. I'm looking for a way to escape the backquote character. $\endgroup$
    – faysou
    Commented Dec 6, 2015 at 16:49
1
$\begingroup$

A possible alternative based on the syntax

StringTemplate["`1`"]["`2`"]
(* "`2`" *)

would be to use the function

stringTemplate[string_][seq___] := 
   StringTemplate[string][## & @@ ("`" <> ToString[#] <> "`" & /@ {seq})]

For instance, considering the first example of StringTemplate in the documentation

stringTemplate["The orbit of `1` has period `2`."]
              ["Jupiter", Quantity[11.8707, "Years"]]

(* "The orbit of `Jupiter` has period `11.8707 years`." *)
$\endgroup$
3
  • $\begingroup$ That's clever, but it doesn't work if you need to insert an argument inside backquotes. For example ``planet` is heavy` $\endgroup$
    – faysou
    Commented Dec 6, 2015 at 23:22
  • $\begingroup$ "``Jupiter` is heavy`" as output $\endgroup$
    – faysou
    Commented Dec 6, 2015 at 23:30
  • $\begingroup$ I've encountered such problems by building SQL queries where backquotes are necessary sometimes. $\endgroup$
    – faysou
    Commented Dec 6, 2015 at 23:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.