xref: /aosp_15_r20/external/kotlinpoet/docs/p-for-string-templates.md (revision 3c321d951dd070fb96f8ba59e952ffc3131379a0)
1*3c321d95SSadaf Ebrahimi%P for String Templates
2*3c321d95SSadaf Ebrahimi=======================
3*3c321d95SSadaf Ebrahimi
4*3c321d95SSadaf Ebrahimi`%S` also handles the escaping of dollar signs (`$`), to avoid inadvertent creation of string
5*3c321d95SSadaf Ebrahimitemplates, which may fail to compile in generated code:
6*3c321d95SSadaf Ebrahimi
7*3c321d95SSadaf Ebrahimi```kotlin
8*3c321d95SSadaf Ebrahimival stringWithADollar = "Your total is " + "$" + "50"
9*3c321d95SSadaf Ebrahimival funSpec = FunSpec.builder("printTotal")
10*3c321d95SSadaf Ebrahimi  .returns(String::class)
11*3c321d95SSadaf Ebrahimi  .addStatement("return %S", stringWithADollar)
12*3c321d95SSadaf Ebrahimi  .build()
13*3c321d95SSadaf Ebrahimi```
14*3c321d95SSadaf Ebrahimi
15*3c321d95SSadaf Ebrahimiproduces:
16*3c321d95SSadaf Ebrahimi
17*3c321d95SSadaf Ebrahimi```kotlin
18*3c321d95SSadaf Ebrahimifun printTotal(): String = "Your total is ${'$'}50"
19*3c321d95SSadaf Ebrahimi```
20*3c321d95SSadaf Ebrahimi
21*3c321d95SSadaf EbrahimiIf you need to generate string templates, use `%P`, which doesn't escape dollars:
22*3c321d95SSadaf Ebrahimi
23*3c321d95SSadaf Ebrahimi```kotlin
24*3c321d95SSadaf Ebrahimival amount = 50
25*3c321d95SSadaf Ebrahimival stringWithADollar = "Your total is " + "$" + "amount"
26*3c321d95SSadaf Ebrahimival funSpec = FunSpec.builder("printTotal")
27*3c321d95SSadaf Ebrahimi  .returns(String::class)
28*3c321d95SSadaf Ebrahimi  .addStatement("return %P", stringWithADollar)
29*3c321d95SSadaf Ebrahimi  .build()
30*3c321d95SSadaf Ebrahimi```
31*3c321d95SSadaf Ebrahimi
32*3c321d95SSadaf Ebrahimiproduces:
33*3c321d95SSadaf Ebrahimi
34*3c321d95SSadaf Ebrahimi```kotlin
35*3c321d95SSadaf Ebrahimifun printTotal(): String = "Your total is $amount"
36*3c321d95SSadaf Ebrahimi```
37*3c321d95SSadaf Ebrahimi
38*3c321d95SSadaf EbrahimiYou can also use `CodeBlock`s as arguments to `%P`, which is handy when you need to reference
39*3c321d95SSadaf Ebrahimiimportable types or members inside the string template:
40*3c321d95SSadaf Ebrahimi
41*3c321d95SSadaf Ebrahimi```kotlin
42*3c321d95SSadaf Ebrahimival file = FileSpec.builder("com.example", "Digits")
43*3c321d95SSadaf Ebrahimi  .addFunction(
44*3c321d95SSadaf Ebrahimi    FunSpec.builder("print")
45*3c321d95SSadaf Ebrahimi      .addParameter("digits", IntArray::class)
46*3c321d95SSadaf Ebrahimi      .addStatement("println(%P)", buildCodeBlock {
47*3c321d95SSadaf Ebrahimi        val contentToString = MemberName("kotlin.collections", "contentToString")
48*3c321d95SSadaf Ebrahimi        add("These are the digits: \${digits.%M()}", contentToString)
49*3c321d95SSadaf Ebrahimi      })
50*3c321d95SSadaf Ebrahimi      .build()
51*3c321d95SSadaf Ebrahimi  )
52*3c321d95SSadaf Ebrahimi  .build()
53*3c321d95SSadaf Ebrahimiprintln(file)
54*3c321d95SSadaf Ebrahimi```
55*3c321d95SSadaf Ebrahimi
56*3c321d95SSadaf EbrahimiThe snippet above will produce the following output, handling the imports properly:
57*3c321d95SSadaf Ebrahimi
58*3c321d95SSadaf Ebrahimi```kotlin
59*3c321d95SSadaf Ebrahimipackage com.example
60*3c321d95SSadaf Ebrahimi
61*3c321d95SSadaf Ebrahimiimport kotlin.IntArray
62*3c321d95SSadaf Ebrahimiimport kotlin.collections.contentToString
63*3c321d95SSadaf Ebrahimi
64*3c321d95SSadaf Ebrahimifun print(digits: IntArray) {
65*3c321d95SSadaf Ebrahimi  println("""These are the digits: ${digits.contentToString()}""")
66*3c321d95SSadaf Ebrahimi}
67*3c321d95SSadaf Ebrahimi```
68