Search code examples
lispschemegimpscript-fu

How can I make a string with expandable keywords in Scheme?


I'm writing a GIMP script to export layers to files. I want to provide a user-specifiable field where they can provide the format for the filenames to be exported, with tilde-character combinations for each element (ie. a file named "foo" with layers "bar" and "baz", with the output filename format being "~f-~l.png", would output "foo-bar.png" and "foo-baz.png"). I know how I would do this in Lua:

local nameformat = "~f-~l.png"
local function layer_export_name(filename, layername)
  return string.gsub(nameformat, '~.', {f=filename, l=layername})
end

How can I do this in GIMP's Scheme?

To reiterate: I need to replace keywords in a string. I don't need a function that creates a string I've already defined.


Solution

  • There is no standard Scheme procedure to do this. I wrote the following in-efficient but portable procedure:

    (define (expand-keywords string tokens)
      (let loop ((slist (string->list string))
                 (in-replace-mode #f)
                 (result ""))
        (if (not (null? slist))        
            (let ((c (car slist)))
              (cond (in-replace-mode
                     (let ((token (car (cdr (assoc c tokens)))))
                       (loop (cdr slist) #f (string-append result token))))
                    ((char=? c #\~)
                     (loop (cdr slist) #t result))
                    (else 
                     (loop (cdr slist) #f (string-append result 
                                                         (make-string 1 c))))))
            result)))
    

    Sample usage:

    > (expand-keywords "~f-~l.png" '((#\f "vijay") (#\l "9")))
    "vijay-9.png"
    > (expand-keywords "~f-~l.~e" '((#\f "vijay") (#\l "10") (#\e "jpg")))
    "vijay-10.jpg"
    

    If your Scheme implementation provides a procedure to modify a string in-place, use that instead of string-append.