; docformat = 'rst' ;+ ; String substitution routine which substitutes values into a given string ; using the correspondences found in the provided hash or structure. ; ; :Examples: ; A single hash or structure can be created with all the possible values ; needed and then a template string can selectively access the desired ; values. For example, create a hash of a couple values:: ; ; IDL> h = hash('name', 'Mike', 'height', 72) ; ; If desired, the `name` key can be used to access just one of the keys in ; the hash:: ; ; IDL> print, mg_subs('Name: %(name)s', h) ; Name: Mike ; ; But the other (or all of the other) attributes can also be accessed:: ; ; IDL> print, mg_subs('Height: %(height)d inches', h) ; Height: 72 inches ; ; The main-level program at the end of this file also contains examples. ; Run them with:: ; ; IDL> .run mg_subs ; ; This does the following examples:: ; ; IDL> print, mg_subs('%(name)s is located in zip code %(zipcode)05d.', $ ; IDL> { name: 'Exelis VIS', zipcode: 80301 }) ; Exelis VIS is located in zip code 80301. ; IDL> h = hash('loc', 'Boulder, CO', 'temp', 80, 'units', 'degrees F') ; IDL> print, mg_subs('It is %(temp)d %(units)s in %(loc)s today!', h) ; It is 80 degrees F in Boulder, CO today! ; IDL> obj_destroy, h ; ; :Requires: ; IDL 8.0 ;- ;+ ; Perform a lookup in a hash or structure given a name of the key/field. ; ; :Private: ; ; :Returns: ; value of the key/field ; ; :Params: ; hash : in, required, type=hash/structure ; hash or structure to lookup key in; if structure, then key lookup is ; done case-insensitively; if hash object, the hash mush have a `hasKey` ; method and allow hash lookup using overloaded `[]`s ; name : in, required, type=string ; name of key/field to lookup ; ; :Keywords: ; found : out, optional, type=boolean ; set to a named variable to get whether the `name` was found in the ; `hash` ;- function mg_subs_getvalue, hash, name, found=found compile_opt strictarr on_error, 2 case size(hash, /type) of 8: begin ind = where(tag_names(hash) eq strupcase(name), found) return, found ? hash.(ind[0]) : -1L end 11: begin found = hash->hasKey(name) return, found ? hash[name] : -1L end else: message, 'unknown hash type' endcase end ;+ ; String substitution routine which substitutes values into a given string ; using the correspondences found in the provided hash or structure. ; ; :Returns: ; string ; ; :Params: ; template : in, optional, type=string ; string to substitute into ; hash : in, required, type=hash/structure ; hash table or structure with key-value pairs to subsitute into the ; template ;- function mg_subs, template, hash compile_opt strictarr on_error, 2 result = '' re = '%\(([[:alnum:]_]+)\)([[:digit:].]*[[:alpha:]])' cur = 0L while (cur lt strlen(template)) do begin pos = stregex(strmid(template, cur), re, length=len, /subexpr) + cur if (pos[0] lt cur) then begin pos[0] = strlen(template) len[0] = 0 endif ; add normal string since last substitution result += strmid(template, cur, pos[0] - cur) ; lookup key and substitute it if (pos[0] lt strlen(template)) then begin name = strmid(template, pos[1], len[1]) value = mg_subs_getvalue(hash, name, found=found) if (~found) then begin message, string(name, $ format='(%"format key error: key \"%s\" not found")') endif format = string('%' + strmid(template, pos[2], len[2]), $ format='(%"(\%\"%s\")")') result += string(value, format=format) endif cur = pos[0] + len[0] endwhile return, result end ; main-level example program print, mg_subs('%(name)s is located in zip code %(zipcode)05d.', $ { name: 'Exelis VIS', zipcode: 80301 }) h = hash('loc', 'Boulder, CO', 'temp', 80, 'units', 'degrees F') print, mg_subs('It is %(temp)d %(units)s in %(loc)s today!', h) obj_destroy, h end