] writingAs: s
].
+s@(String traits) sprintf*
+[| *args input argsIndex |
+ input: s reader.
+ argsIndex: args indexFirst.
+ [| :result |
+ input do:
+ [| :char |
+ char == $%
+ ifTrue: "Placeholder"
+ [| nextChar arg |
+ nextChar: input next.
+ nextChar == $%
+ ifTrue: [result nextPut: nextChar]
+ ifFalse:
+ [| specifier width precision space position alternative plus minus zero star |
+ input skip: -1.
+ specifier: (input upToAnyOf: 'diueEfFgGxXoscpn') reader.
+
+ [specifier isAtEnd] whileFalse:
+ [nextChar: specifier next.
+ "Check for a parameter index spec:"
+ ('123456789' includes: nextChar)
+ ifTrue:
+ [(specifier peek: 1) == $$
+ ifTrue:
+ [specifier skip: -1.
+ position: (Integer readFrom: specifier).
+ specifier next]
+ ifFalse:
+ [specifier skip: -1.
+ width: (Integer readFrom: specifier).
+ ]]
+ ifFalse:
+ ["Check for flags:"
+ nextChar caseOf: {
+ $\s -> [space: True].
+ $# -> [alternative: True].
+ $+ -> [plus: True].
+ $- -> [minus: True].
+ $0 -> [zero: True].
+ $* -> [star: True].
+ $. -> [precision: (Integer readFrom: specifier)]}]].
+
+ input skip: -1.
+ "Check for type specifiers:"
+ position ifNil:
+ [position: argsIndex.
+ argsIndex: argsIndex + 1].
+ width isNil /\ [star isNotNil] ifTrue:
+ [width: (args at: position).
+ position: position + 1.
+ argsIndex: argsIndex + 1].
+ arg: (args at: position).
+ nextChar: input next.
+ ('diu' includes: nextChar) ifTrue:
+ [arg: (arg printString &radix: 10 &precision: precision &forceSign: plus isNotNil)].
+ ('xX' includes: nextChar) ifTrue:
+ [arg: (arg printString &radix: 16 &precision: precision &forceSign: plus isNotNil).
+ nextChar = $X ifTrue: [arg toUppercase]].
+ ('o' includes: nextChar) ifTrue:
+ [arg: (arg printString &radix: 8 &precision: precision &forceSign: plus isNotNil)].
+ ('fFeE' includes: nextChar) ifTrue:
+ [arg: (arg printString &precision: precision &forceSign: plus isNotNil).
+ ('FE' includes: nextChar) ifTrue: [arg toUppercase]].
+ nextChar == $r ifTrue:
+ [arg: arg printString].
+ nextChar == $s ifTrue:
+ [arg: (arg as: s)].
+ width ifNotNil:
+ [arg: (arg truncateTo: width paddedBy: (zero ifNil: [$\s] ifNotNil: [$0]) &onRight: minus isNotNil)].
+ result ; arg.
+ ]]
+ ifFalse: [result nextPut: char]]
+ ] writingAs: s
+].
+
s@(String traits) evaluate
[
s evaluateIn: lobby