Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-cmm.1016.mcz
==================== Summary ====================
Name: Collections-cmm.1016 Author: cmm Time: 6 July 2022, 11:22:16.540715 pm UUID: 8eaa5fee-446e-4ccb-ae26-652e7a70e693 Ancestors: Collections-eem.1015
Let String>>#format: also support alphanumeric tokens (accessed via a Dictionary). Backward compatibility with classic numeric tokens via a SequenceableCollection is preserved.
=============== Diff against Collections-eem.1015 ===============
Item was changed: ----- Method: String>>format: (in category 'formatting') ----- + format: aCollection + "Substitute tokens in the receiver with element values of aCollection. The tokens are indicated in curly-braces and may be either numeric, e.g., {1}, {2}, etc. and map to a SequenceableCollection, OR, alphanumeric, e.g., {name}, {date}, etc., in which case aCollection should be a Dictionary. + The values can be static or, with the specification of a Block element, dynamic. + + Simplest examples: + 'foo {date} bar' format: ({'date'->Date today} as: Dictionary). + + Dynamic calculation is allowed via Blocks. + 'foo {NOW} bar' format: ({'NOW'-> [DateAndTime now]} as: Dictionary). + + Backward-compatible with numeric-only #format: - format: arguments - "Format the receiver with arguments. - - Simplest example: 'foo {1} bar' format: {Date today}. + + Now with block support: + 'foo {1} bar' format: {[Date today]}. + + Complete example with escaped characters: - - Complete example: '{ } \ foo {1} bar {2}' format: {12. 'string'}. + '{ } \ foo {FOO} bar {BAR}' format: ({'FOO'->12. 'BAR'->'string'} as: Dictionary). " + ^ self class new: self size * 11 // 10 "ready for +10% growth"streamContents: + [ : output | | lastIndex nextIndex key | + lastIndex := 1. + key := WriteStream on: (String new: 10). + [ "stream to output until first { or " + (nextIndex := self indexOfAnyOf: FormatCharacterSet startingAt: lastIndex) = 0 ] whileFalse: + [ nextIndex = lastIndex ifFalse: + [ output next: nextIndex - lastIndex putAll: self startingAt: lastIndex ]. + "special char hit, escape char?" + (self at: nextIndex) == $\ + ifTrue: [ "transfer the escaped character." + output nextPut: (self at: (nextIndex := nextIndex + 1)) ] + ifFalse: + [ | nextKeyChar | + "${ char, parse the key" + [ nextKeyChar := self at: (nextIndex := nextIndex + 1). + nextKeyChar isAlphaNumeric ] whileTrue: [ key nextPut: nextKeyChar ]. + nextKeyChar = $} ifFalse: [ self error: '$} expected' ]. + output nextPutAll: (aCollection at: key contents numberOrValue) value asString. + key reset ]. + lastIndex := nextIndex + 1 ]. + lastIndex <= self size ifTrue: + [ output + next: self size - lastIndex + 1 + putAll: self + startingAt: lastIndex ] ]! - ^ self class new: self size * 11 // 10 "+10%" streamContents: [ :output | - | lastIndex nextIndex | - lastIndex := 1. - [ (nextIndex := self indexOfAnyOf: FormatCharacterSet startingAt: lastIndex) = 0 ] whileFalse: [ - nextIndex = lastIndex ifFalse: [ - output next: nextIndex - lastIndex putAll: self startingAt: lastIndex ]. - (self at: nextIndex) caseOf: { - [ $\ ] -> [ output nextPut: (self at: (nextIndex := nextIndex + 1)) ]. - [ ${ ] -> [ - "Parse the index - a positive integer in base 10." - | digitValue collectionIndex | - collectionIndex := 0. - [ (digitValue := self basicAt: (nextIndex := nextIndex + 1)) between: 48 "$0 asciiValue" and: 57 "$9 asciiValue" ] whileTrue: [ - collectionIndex := collectionIndex * 10 + digitValue - 48 "$0 asciiValue". ]. - digitValue = 125 "$} asciiValue" ifFalse: [ self error: ('{1} expected' translated format: {$}}) ]. - output nextPutAll: (arguments at: collectionIndex) asString ] }. - lastIndex := nextIndex + 1 ]. - lastIndex <= self size ifTrue: [ - output next: self size - lastIndex + 1 putAll: self startingAt: lastIndex ] ]!
packages@lists.squeakfoundation.org