Search code examples
textracketediting

editing text in a file using racket


I have a racket program that (include file)'s several other files some of which contain racket code that I want to update using functions in the main program. I.e. This is what the file I want to edit looks like (basically)

(define somethings '(
        (some list)
        (some other list)
        (yet another list)))

I would like to be able to add more things to the list I presume there's a better way to do this but since I'm new to this is what I tried first:

(define (update-file arg1 arg2 arg3 . args)
    (call-with-output-file "somefile.rkt" #:exists 'append
       (lambda (output-port)
          (print "\b\b" output-port) ;; have tried several variations of this they all 
          (do other things)          ;; print the backspaces literally rather than 
          (display "))" output-port) ;; removing characters
          (newline output-port))))

I presume the problem is both A: I'm using append which presumably just sticks stuff on the end (but update and truncate don't seem like the answer) and B: printing \b doesn't work the way I'm trying to use it... :)

I'm hopelessly browsing through racket's documentation now, but I'm new to programming so a large part of it doesn't make any sense yet. Is there some way of making that particular function work and if so would it be worth it or is there a far superior method to achieve the same result?

Thanks very much


Solution

  • Give this a try:

    (call-with-input-file "somefile.rkt"
      (lambda (in)
        (let* ((input  (call-with-input-string (port->string in) read))
               (output (list (car input)  ; define
                             (cadr input) ; somethings
                             (list 'quote
                                   (append
                                    (car (cdaddr input))      ; old list
                                    '((do other things))))))) ; new elements
          (call-with-output-file "somefile.rkt" #:exists 'replace
            (lambda (out)
              (write output out))))))
    

    This is what's happening:

    1. First, we read the contents of "somefile.rkt" into a variable called input, the result is a list of S-Expressions
    2. Then, as suggested by Chris, we manipulate that list using standard operations until it has the desired value
    3. Finally, we write the result back into the same file, overwriting the previous contents

    At the end, "somefile.rkt" will contain the following text:

    (define somethings
      (quote
       ((some list)
        (some other list)
        (yet another list)
        (do other things))))
    

    Don't worry about the quote, that's the same as writing '. The only caveat is that the original format of the text will be lost, everything shows in a single line.