editing text in a file using racket

editing, racket, text

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:

- First, we `read` the contents of `"somefile.rkt"` into a variable called `input`, the result is a list of S-Expressions

- Then, as suggested by Chris, we manipulate that list using standard operations until it has the desired value

- 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.

Problem

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

Original source