The other day I was hacking away, using DrScheme as a scratchpad and a Google Spreadsheet to visualize data.
After way too many rows of data entry, it hit me - I can trivially automate copying values from DrScheme to a Google Spreadsheet. PLT-Scheme gives you access to a clipboard object that you can simply call set-clipboard-string. Using this method, I was able to write a Scheme function that injected data into the system clipboard, which I could then paste into my spreadsheet.
To smooth things out a bit, I wrote a function which takes in lists of lists, and converts them to tab-and-newline-delimited strings, that Google knows how to parse into cells.
The result is that I can now type:
;; ctc is an alias for copy-to-clipboard (ctc '((Name Rank Serial-Number) (Ben Private 123) (Shira General 456)))
and then hit Control-V to get:
Of course, if Ireally wanted to push data to a Google Spreadsheet, there are much cleaner ways to do it. But, this copy and paste hack gave me just the solution I needed.
It's also worth mentioning that I do this sort of thing all the time from the command line. There's a standard Windows command, C:\Windows\System32\clip.exe that allows you to send content to the clipboard via the shell. (In cygwin, I can do: cat /etc/passwd | tr a-z A-Z | clip).
Though, in this case, I was already poking around DrScheme so a it made more scheme to develop a PLT specific solution.
Here's the code:
#lang scheme (require scheme/gui ; used to get the-clipboard variable srfi/26 ; for cut ) ;; ;; The clipboard functions choke on null strings. So I replace ;; them with this character. Most of the time, you won't need ;; to worry about this ;; (define null-character-replacement (make-parameter "$")) (define as-string (cut format "~a" <>)) ;; ;; gridify: take in a list of lists and turn it into a tab/newline ;; delimited string, ready to be copied and pasted into a spreadsheet. ;; Also handles the case where the data isn't a lists of lists. ;; (define (gridify any) (if (list? any) (string-join (map (compose as-string (lambda (row) (if (list? row) (string-join (map as-string row) "\t") row))) any) "\n") (as-string any))) ;; ;; Copy any content to the clipboard as a string. Note: we call (gridify any) ;; to make the data more clipboard friendly ;; ;; As a convenience, return the data sent in. Useful to allow calling ;; this function in a debugging context. ;; (define (copy-to-clipboard any) (let ([scrubbed (regexp-replace* "[\0]" (gridify any) (null-character-replacement))]) (send the-clipboard set-clipboard-string scrubbed 0) any)) ;; ;; provide a compact alias for (copy-to-clipboard ...) ;; (define ctc copy-to-clipboard) (provide/contract [copy-to-clipboard (any/c . -> . any/c)] [ctc (any/c . -> . any/c)])