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