I would the use the % operator (https://nim-lang.org/docs/strtabs.html#%25%2Cstring%2CStringTableRef%2Cset%5BFormatFlag%5D) but for an OrderedTable rather than a StringTable. Is this possible?
As an aside, does the % operator have an actual name? 'percent operator'? If so it should be included in the documentation as google searching '% operator' doesn't yield meaningful results. Obviously this applies to all the 'char' operators.
Might make more sense to throw stuff like this in a package for implementation agnostic formatting/interactions, but anywho quickly modified the strtabs.% implementation for a completely agnostic solution(well with simple rules).
import std/tables
type
FormatableTable = concept f
f[""] isnot void
$f[""] is string
proc `%`*(f: string, t: FormatableTable): string =
## The `%` operator for string tables.
runnableExamples:
var t = {"name": "John", "city": "Monaco"}.newStringTable
doAssert "${name} lives in ${city}" % t == "John lives in Monaco"
const
PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF'}
result = ""
var i = 0
while i < len(f):
if f[i] == '$':
case f[i+1]
of '$':
add(result, '$')
inc(i, 2)
of '{':
var j = i + 1
while j < f.len and f[j] != '}': inc(j)
add(result, $t[substr(f, i+2, j-1)])
i = j + 1
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_':
var j = i + 1
while j < f.len and f[j] in PatternChars: inc(j)
add(result, $t[substr(f, i+2, j-1)])
i = j
else:
add(result, f[i])
inc(i)
else:
add(result, f[i])
inc(i)
let
someOrderedTable = {"age": 100i64, "uid": 320130213021}.toOrderedTable
someTable = {"name": "Steve", "city": "Calgary"}.toTable
echo "${age} years old, and ${uid} is their ID" % someOrderedTable
echo "${name} was born in ${city}" % someTable
The above code changed the strtabs.nim origin from i+1 in the substr in the of 'a'..'z' case branch to i+2, breaking "a$name" formats. The original calling the set PatternChars instead of, say, noBraces may have influenced the introduction of the bug? Dunno.
{ Also, IMO, in the concept you should use t not f for the Table-ish thing, since right below you use f for a format string and t for FormatableTable. [ Not strictly a bug, I know. ] }
The code as posted with i+2 in both branches has the described bug. Change ${name} to $name in any test to see it.
Looks from the Nim git log that the expression was i+1, j-1 going back to its 2009 introduction. Maybe your text editor played tricks on you? :-)