You can make what amounts to an "ordered dictionary" by making your
substitution table both an array and a dictionary, something like
this:
subs = {
1 = ">~h|",
2 = "<~h|",
3 = ">~w|",
...
23 = "<p",
">~h|" = GREEK_SMALL_LETTER_ETA_WITH_PSILI_AND_[...snip...]
...
"<p" = GREEK_SMALL_LETTER_RHO_WITH_DASIA
}
Then you can write something like this:
local function mysubs(lines)
for _,v in ipairs(subs) do
lines = string.gsub(lines,v,subs[v]);
end;
return lines;
end;
This works because ipairs() does bring out the "array-style"
entries (i.e. those with index 1..n) in a table in numeric order.