# Format for multimedia files?

**URL:** <https://racket.discourse.group/t/format-for-multimedia-files/3365>\
**Category:** Questions & Answers\
**Tags:** question, drracket\
**Created:** [November 28, 2024, 12:18am UTC](https://racket.discourse.group/t/format-for-multimedia-files/3365 "2024-11-28T00:18:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ToddOBryan](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/toddobryan/32/1962_2.png) [@ToddOBryan](https://racket.discourse.group/u/ToddOBryan)\
**Post date:** [November 28, 2024, 12:18am UTC](https://racket.discourse.group/t/format-for-multimedia-files/3365/1 "2024-11-28T00:18:18Z")

</div>

Where is the description of what the format for multimedia files is? A lot of my early assignments include images and I'd like to be able to look at student text inside the files for analysis and grading.

---

<div class="post-metadata">

**Author:** ![cadence](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/cadence/32/998_2.png) [@cadence](https://racket.discourse.group/u/cadence)\
**Post date:** [November 28, 2024, 1:04am UTC](https://racket.discourse.group/t/format-for-multimedia-files/3365/2 "2024-11-28T01:04:17Z")

</div>

I can't speak for the file format, but if you want to see the text, it's probably easiest to do so by opening the file in DrRacket and looking at it.

---

<div class="post-metadata">

**Author:** ![ToddOBryan](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/toddobryan/32/1962_2.png) [@ToddOBryan](https://racket.discourse.group/u/ToddOBryan)\
**Post date:** [November 28, 2024, 9:06pm UTC](https://racket.discourse.group/t/format-for-multimedia-files/3365/3 "2024-11-28T21:06:53Z")

</div>

Yeah. I want to programmatically look at the file.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 28, 2024, 10:35pm UTC](https://racket.discourse.group/t/format-for-multimedia-files/3365/4 "2024-11-28T22:35:11Z")

</div>

The format is called WXME.

[https://docs.racket-lang.org/gui/WXME\_Decoding.html](https://docs.racket-lang.org/gui/WXME_Decoding.html)

It's extensible in the sense that snips (see snip%) can define how they are read and written.  
So, you might need to look at the documentation/code of the snips that are in your file too.

---

<div class="post-metadata">

**Author:** ![blerner](https://avatars.discourse-cdn.com/v4/letter/b/74df32/32.png) [@blerner](https://racket.discourse.group/u/blerner)\
**Post date:** [December 1, 2024, 2:55pm UTC](https://racket.discourse.group/t/format-for-multimedia-files/3365/5 "2024-12-01T14:55:37Z")

</div>

The simplest way I know of to get _nearly_ the plain-text content of a WXME file is to (1) create a `text%`, (2) load the file into it, and (3) `send the-text% get-text` to get its content. I say "nearly" because this will render any embedded snips as `.`, which is not quite accurate and won't parse back in as valid student code, but is also likely good enough for text-processing.

```scheme
(require racket/gui/base)

(define (file->text filename)
  (define txt (new text%))
  (send txt load-file filename)
  (send txt get-text))

```

If you need to do more detailed processing, you'll need to actually walk the snip% tree, which is somewhat more tedious. Instead of sending `get-text`, you'll send `find-first-snip` (and send _that_ `next` to get its siblings), and then use `is-a?` on all the various snip classes you want to handle. I've used the following (believe it or not, edited somewhat for brevity! helper functions not included)

```scheme
;; display-all : (or/c snip? #f) output-port? -> #f
;; Walks the given snip tree and renders it as plaintext to the given output port.
(define (display-all snip out #:inline-numbers? [inline-numbers? #f])
  (if (not snip)
      out
      (let ((snip-name (send (send snip get-snipclass) get-classname)))
        (cond
          [(is-a? snip string-snip%)
           (display (send snip get-text 0 (send snip get-count))
                    out)]
          [(is-a? snip comment-box:snip%)
           (define comment (open-output-bytes))
           (define contents (display-all (send (send snip get-editor)
                                               find-first-snip)
                                         comment))
           (display (add-comment (get-output-string comment)) out)]
          [(equal? snip-name
                   "(lib \"number-snip.ss\" \"drscheme\" \"private\")")
           (define val (number->string (send snip get-number)))
           (display (if inline-numbers? val (add-number val)) out)]
          [(or (is-a? snip xml-snip<%>)
               (equal? snip-name "(lib \"xml-snipclass.ss\" \"xml\")")
               (equal? snip-name "(lib \"xml-snipclass.rkt\" \"xml\")")
               (equal? snip-name "(lib \"xml.ss\" \"wxme\")"))
           (define xml (open-output-bytes))
           (define contents (display-all (send (send snip get-editor)
                                               find-first-snip)
                                         xml))
           (display (add-xml (get-output-string xml)) out)]
          [(or (equal? snip-name "(lib \"text-snipclass.ss\" \"xml\")")
               (equal? snip-name "(lib \"text-snipclass.rkt\" \"xml\")")
               (equal? snip-name "(lib \"text.ss\" \"wxme\")"))
           (define text (open-output-bytes))
           (define contents (display-all (send (send snip get-editor)
                                               find-first-snip)
                                         text))
           (display (add-text (get-output-string text)) out)]
          [(equal? snip-name (format "~s" '((lib "collapsed-snipclass.ss" "framework")
                                            (lib "collapsed-snipclass-wxme.ss" "framework"))))
           ;; Display collapsed-snips in collapsed form isn't good for grading:
           ;; it hides code, and could hide badly long lines. So,
           ;; expand the snip to its hidden pieces, instead.
           (for ([kid (in-list (send snip get-saved-snips))])
             (display-all kid out))]
          [(or (is-a? snip scheme-snip<%>)
               (equal? snip-name "(lib \"scheme-snipclass.ss\" \"xml\")")
               (equal? snip-name "(lib \"scheme-snipclass.rkt\" \"xml\")")
               (equal? snip-name "(lib \"scheme.ss\" \"wxme\")"))
           (define rkt (open-output-bytes))
           (define contents (display-all (send (send snip get-editor)
                                               find-first-snip)
                                         rkt))
           (if (send snip get-splice?)
               (display (add-splice (get-output-string rkt)) out)
               (display (add-racket (get-output-string rkt)) out))]
          [(convertible? snip)
           (define bm (new bitmap-dc% [bitmap (make-object bitmap% 1 1)]))
           (define width (box 0))
           (define height (box 0))
           (send snip get-extent bm 0 0 width height)
           (if (or (= (unbox width) 0) (= (unbox height) 0))
               (display (add-empty-image "") out)
               (with-handlers
                   ([exn:fail:contract?
                     (λ(e)
                       (display
                        (add-comment
                         (string-append "Could not render this content;\n"
                                        "please contact a professor."))
                        out))])
                 (display (add-image (convert snip 'png-bytes)) out)))]
          [(syntax? snip)
           (display (syntax->datum snip) out)]
          [else
           (display (format ">?>~a<?<" snip-name) out)
           (display (format ">>>~a<<<" snip) out)]
          )
        (display-all (send snip next) out #:inline-numbers? inline-numbers?))))

```

(I'd love to know if there are ways to detect number, xml, collapsed and scheme snips without resorting to snip classnames! But this code has worked well for me for years.)
