clean up and add test-case support
svn: r5406
This commit is contained in:
parent
4baff4e975
commit
f7e85c5045
|
@ -1,15 +1,26 @@
|
|||
|
||||
(module cache-image mzscheme
|
||||
(require (lib "class.ss"))
|
||||
(require (lib "class.ss")
|
||||
"wxme.ss")
|
||||
|
||||
(provide reader
|
||||
(struct cache-image (argb width height pin-x pin-y)))
|
||||
cache-image%)
|
||||
|
||||
(define-struct cache-image (argb width height pin-x pin-y))
|
||||
(define cache-image%
|
||||
(class object%
|
||||
(init-field argb width height pin-x pin-y)
|
||||
|
||||
(define (get-argb) argb)
|
||||
(define (get-width) width)
|
||||
(define (get-height) height)
|
||||
(define (get-pin-x) pin-x)
|
||||
(define (get-pin-y) pin-y)
|
||||
|
||||
(super-new)))
|
||||
|
||||
(define reader
|
||||
(new
|
||||
(class object%
|
||||
(class* object% (snip-reader<%>)
|
||||
(define/public (read-header vers stream)
|
||||
(void))
|
||||
(define/public (read-snip text? cvers stream)
|
||||
|
@ -17,14 +28,10 @@
|
|||
(if text?
|
||||
#"."
|
||||
(let ([l (read (open-input-bytes content))])
|
||||
(make-cache-image (car l)
|
||||
(cadr l)
|
||||
(/ (vector-length (car l)) (cadr l) 4)
|
||||
(caddr l)
|
||||
(cadddr l))))))
|
||||
(make-object cache-image%
|
||||
(car l)
|
||||
(cadr l)
|
||||
(/ (vector-length (car l)) (cadr l) 4)
|
||||
(caddr l)
|
||||
(cadddr l))))))
|
||||
(super-new)))))
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -5,12 +5,16 @@
|
|||
"wxme.ss"
|
||||
"private/readable-editor.ss")
|
||||
|
||||
(provide reader)
|
||||
(provide reader
|
||||
comment-editor%)
|
||||
|
||||
(define comment-editor% (class readable-editor% (super-new)))
|
||||
|
||||
(define reader
|
||||
(new (class editor-reader%
|
||||
(new (class* editor-reader% (snip-reader<%>)
|
||||
(inherit read-editor-snip)
|
||||
(define/override (read-snip text? vers stream)
|
||||
(let ([s (super read-snip text? vers stream)])
|
||||
(let ([s (read-editor-snip text? vers stream #f comment-editor%)])
|
||||
(if text?
|
||||
(apply bytes-append
|
||||
(map (lambda (s)
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
|
||||
(module compat mzscheme
|
||||
(require "wxme.ss")
|
||||
|
||||
(register-lib-mapping!
|
||||
"(lib \"comment-snip.ss\" \"framework\")"
|
||||
"(lib \"comment.ss\" \"wxme\")")
|
||||
|
||||
(register-lib-mapping!
|
||||
"drscheme:number"
|
||||
"(lib \"number.ss\" \"wxme\")")
|
||||
(register-lib-mapping!
|
||||
"(lib \"number-snip.ss\" \"drscheme\" \"private\")"
|
||||
"(lib \"number.ss\" \"wxme\")")
|
||||
|
||||
(register-lib-mapping!
|
||||
"drscheme:xml-snip"
|
||||
"(lib \"xml.ss\" \"wxme\")")
|
||||
(register-lib-mapping!
|
||||
"(lib \"xml-snipclass.ss\" \"xml\")"
|
||||
"(lib \"xml.ss\" \"wxme\")")
|
||||
|
||||
(register-lib-mapping!
|
||||
"drscheme:scheme-snip"
|
||||
"(lib \"scheme.ss\" \"wxme\")")
|
||||
(register-lib-mapping!
|
||||
"(lib \"scheme-snipclass.ss\" \"xml\")"
|
||||
"(lib \"scheme.ss\" \"wxme\")")
|
||||
|
||||
(register-lib-mapping!
|
||||
"text-box%"
|
||||
"(lib \"text.ss\" \"wxme\")")
|
||||
(register-lib-mapping!
|
||||
"(lib \"text-snipclass.ss\" \"xml\")"
|
||||
"(lib \"text.ss\" \"wxme\")")
|
||||
|
||||
(register-lib-mapping!
|
||||
"(lib \"cache-image-snip.ss\" \"mrlib\")"
|
||||
"(lib \"cache-image.ss\" \"wxme\")"))
|
|
@ -1,22 +1,318 @@
|
|||
|
||||
_wxme.ss_ in mred/wxme
|
||||
======================================================================
|
||||
_wxme.ss_ --- reading PLT graphical format (WXME) files without MrEd
|
||||
======================================================================
|
||||
|
||||
Utilities for reading PLT graphical format files without MrEd.
|
||||
> (is-wxme-stream? input-port)
|
||||
|
||||
> (wxme-port->port input-port [snip-filter-proc-or-false])
|
||||
Peeks from `input-port' and returns #t if it starts with magic bytes
|
||||
indicating a WXME-format stream, #f otherwise.
|
||||
|
||||
If `snip-filter-proc-or-false' is #f, then the generated port is pure
|
||||
text. Otherwise, the generated port may return "special" values for
|
||||
non-text items in the original stream.
|
||||
The magic bytes are "WXME01<n><m> ##" for digits <n> and <n>, followed
|
||||
by either a space, carriage return, or newline, and optionally
|
||||
prefixed with "#reader(\"read.ss\"\"wxme\")".
|
||||
|
||||
> (wxme-port->text-port input-port [close?])
|
||||
|
||||
Takes an import port whose stream starts with WXME-format data and
|
||||
returns an input port that produces a text form of the WXME content,
|
||||
like the result of opening a WXME file in DrScheme and saving it as
|
||||
text.
|
||||
|
||||
If `close?' is true (the default), then closing the result port close
|
||||
the original port.
|
||||
|
||||
See "Snip Class Mapping" (below) for information about the kinds of
|
||||
non-text content that can be read.
|
||||
|
||||
> (wxme-port->port input-port [close? snip-filter-proc-or-false])
|
||||
|
||||
Takes an import port whose stream starts with WXME-format data and
|
||||
returns an input port that produces text content converted to bytes,
|
||||
and non-text content as "special" values.
|
||||
|
||||
If `close?' is true (the default), then closing the result port close
|
||||
the original port.
|
||||
|
||||
The `snip-filter-proc' is applied to any special value generated for
|
||||
the stream, and its result is used as an alternate special value. The
|
||||
default `snip-filter-proc' is the identity function.
|
||||
|
||||
If a special value (possibly produced by the filter procedure) is an
|
||||
object implementing the `readable<%>' interface provided by "wxme.ss",
|
||||
then the object's `read-special' method is called to produce the
|
||||
special value.
|
||||
|
||||
See "Snip Class Mapping" (below) for information about the kinds of
|
||||
non-text content that can be read.
|
||||
|
||||
> (register-lib-mapping! string quoted-module-path)
|
||||
|
||||
Maps a snip-class name to a quoted module path that provides a reader%
|
||||
implementation. The module path must have the form '(lib <str> ...),
|
||||
where each <str> contains only alpha-numeric ASCII characters, ".",
|
||||
"_", "-", and spaces.
|
||||
|
||||
> unknown-extensions-skip-enabled
|
||||
|
||||
A parameter. When set to #f (the default), an exception is raised when
|
||||
an unrecognized snip class is encountered in a WXME stream. When set to
|
||||
a true value, instances of unrecognized snip classes are simply
|
||||
omitted from the transformed stream.
|
||||
|
||||
> (wxme-read port)
|
||||
|
||||
Like `read', but for a WXME format input stream.
|
||||
Like `read', but for a stream that starts with WXME-format data. If
|
||||
multiple S-expressions are in the WXME data, they are all read and
|
||||
combined with `begin'.
|
||||
|
||||
> (wxme-read-syntax source-v port)
|
||||
|
||||
Like `read-syntax', but for a WXME format input stream.
|
||||
Like `read-syntax', but for a WXME format input stream. If multiple
|
||||
S-expressions are in the WXME data, they are all read and combined
|
||||
with `begin'.
|
||||
|
||||
> prop:readable
|
||||
|
||||
A property for a structure representation of a snip.
|
||||
> snip-reader<%>
|
||||
|
||||
An interface to be implemented by a reader for a specific kind of data
|
||||
in a WXME stream.
|
||||
|
||||
The interface has two methods:
|
||||
|
||||
> (read-header version-k stream-object)
|
||||
> (read-snip text-only? version-k stream-object)
|
||||
|
||||
The first method is called at most once per WXME stream to initialize
|
||||
the data type's stream-specific information. This method usually does
|
||||
nothing.
|
||||
|
||||
The second method is called when an instance of the data type is
|
||||
encountered in the stream. This method reads the data and returns
|
||||
either bytes to be returned as part of the decoded stream or any other
|
||||
kind of value to be returned as a "special" value from the decoded
|
||||
stream.
|
||||
|
||||
> readable<%>
|
||||
|
||||
An interface to be implemented by values returned from a snip reader.
|
||||
The only method is `read-special', which takes four arguments related
|
||||
to source location: a value indicating the source, the line (positive
|
||||
integer or #f), column (non-negative integer or #f), and position
|
||||
(positive integer or #f).
|
||||
|
||||
When a value implements this interface, its `read-special' method is
|
||||
called with source-location information to obtain the "special" result
|
||||
from the WXME-decoding port.
|
||||
|
||||
------------------------------------------------------------
|
||||
Snip Class Mapping
|
||||
------------------------------------------------------------
|
||||
|
||||
When graphical data is marshaled to the WXME format, it is associated
|
||||
with a snip-class name to be matched with an implementation at load
|
||||
time.
|
||||
|
||||
Ideally, the snip-class name is generated as
|
||||
|
||||
(format "~s" (list '(lib <str> ...)
|
||||
'(lib <str> ...)))
|
||||
|
||||
where each element of the list is a quoted module path. The <str>s
|
||||
must contain only alpha-numeric ASCII characters, plus ".", "-", "_",
|
||||
or space, and must not be "." or "..".
|
||||
|
||||
In that case, the first quoted module path is used by MrEd for loading
|
||||
WXME files in graphical mode; the corresponding module must provide
|
||||
`snip-class' object that implements MrEd's `snip-class%' class. the
|
||||
second quoted module path is used by the "wxme.ss" library for
|
||||
converting WXME streams without MrEd support; the corresponding module
|
||||
must provide a `reader' object that implements `reader<%>' interface
|
||||
described above. Of course, the `snip-class%' instance and `reader<%>'
|
||||
instance are expected to parse the same format, but generate different
|
||||
results suitable for the different contexts (graphical or not).
|
||||
|
||||
If a snip-class name is generated as
|
||||
|
||||
(format "~s" '(lib <str> ...))
|
||||
|
||||
then MrEd uses the sole module path, and the "wxme.ss" needs a
|
||||
compatibility mapping. Install one with `register-lib-mapping!'.
|
||||
|
||||
If a snip-class name has neither of the above formats, then MrEd can
|
||||
use the data only if a snip class is registered for the name, or if it
|
||||
the name of one of the built-in classes: "wxtext", "wxtab", "wximage",
|
||||
or "wxmedia" (for nested editors). The "wxme.ss" library needs a
|
||||
compatibility mapping installed with `register-lib-mapping!' if it is
|
||||
not one of the built-in classes.
|
||||
|
||||
Several compatibility mappings are installed automatically for the
|
||||
"wxme.ss" library. They correspond to popular graphical elements
|
||||
supported by various versions of DrScheme, including comment boxes,
|
||||
fractions, XML boxes, Scheme boxes, text boxes, and images generated
|
||||
by the "world.ss" and "image.ss" teachpacks (or, more generally, from
|
||||
"cache-image-snip.ss" in "mrlib"), and test-case boxes.
|
||||
|
||||
For a port created by `wxme-port->port', nested editors are
|
||||
represented by instances of the `editor%' class provided by the
|
||||
"editor.ss" library of the "wxme" collection. This class provides a
|
||||
single method, `get-content-port', which returns a port for the
|
||||
editor's content. Images are represented as instances of the `image%'
|
||||
class provided by the "image.ss" library (see below).
|
||||
|
||||
Comment boxes are represented as instances of a class that extends
|
||||
`editor%' to implement `readable<%>' (see "comment.ss"); the read form
|
||||
produces a special comment (created by `make-special-comment'), so
|
||||
that the comment box disappears when `read' is used to read the
|
||||
stream; the special-comment content is the readable instance. XML,
|
||||
Scheme, and text boxes similarly produce instances of `editor%' and
|
||||
`readable<%>' that expand in the usual way (see "xml.ss", "scheme.ss",
|
||||
and "text.ss"). Images from the "world.ss" and "image.ss" teachpacks
|
||||
are packaged as instances of `cache-image%' from the "cache-image.ss"
|
||||
library (see below). Test-case boxes are packaged as instances of
|
||||
`test-case%' from the "test-case.ss" library (see below).
|
||||
|
||||
======================================================================
|
||||
_editor.ss_ --- MrEd nested editors
|
||||
======================================================================
|
||||
|
||||
Provides
|
||||
|
||||
> editor%
|
||||
|
||||
that is instantiated for plain nested editors in a WXME stream.
|
||||
The class has one method:
|
||||
|
||||
> (get-content-port)
|
||||
|
||||
which returns a port (like the one from `wxme-port->port') for the
|
||||
editor's content.
|
||||
|
||||
======================================================================
|
||||
_image.ss_ --- MrEd images
|
||||
======================================================================
|
||||
|
||||
Provides
|
||||
|
||||
> image%
|
||||
|
||||
that is instantiated for MrEd images in a WXME stream. The class
|
||||
provides several methods:
|
||||
|
||||
> (get-filename) - returns a filename as bytes, or #f if
|
||||
data is available instead
|
||||
> (get-data) - returns bytes for a PNG, XBM,or XPM file for the
|
||||
image
|
||||
> (get-width) - returns the display width of the image, which may
|
||||
differ from the width of the actual image secified
|
||||
as data or by a filename
|
||||
> (get-height) - returns the display height of the image, which may
|
||||
differ from the width of the actual image secified
|
||||
as data or by a filename
|
||||
> (get-x-offset) - returns an offset into the actual image to be used
|
||||
as the left of the display image
|
||||
> (get-y-offset) - returns an offset into the actual image to be used
|
||||
as the top of the display image
|
||||
|
||||
======================================================================
|
||||
_comment.ss_ --- DrScheme comment boxes
|
||||
======================================================================
|
||||
|
||||
In addition to `reader', an instance of `snip-reader<%>', this library
|
||||
provides
|
||||
|
||||
> comment-editor%
|
||||
|
||||
which is a sub-class of `editor%' and implementation of `readable<%>'
|
||||
that is instantiated for Drscheme comment boxes in a WXME stream. The
|
||||
class includes a `get-data' method that always returns #f.
|
||||
|
||||
======================================================================
|
||||
_xml.ss_ --- DrScheme XML boxes
|
||||
======================================================================
|
||||
|
||||
In addition to `reader', an instance of `snip-reader<%>', this library
|
||||
provides
|
||||
|
||||
> xml-editor%
|
||||
|
||||
which is a sub-class of `editor%' and implementation of `readable<%>'
|
||||
that is instantiated for Drscheme XML boxes in a WXME stream. The
|
||||
class includes a `get-data' method that returns #t if whitespace is
|
||||
elimited from the contained XML literal, #f otherwise.
|
||||
|
||||
======================================================================
|
||||
_scheme.ss_ --- DrScheme Scheme boxes
|
||||
======================================================================
|
||||
|
||||
In addition to `reader', an instance of `snip-reader<%>', this library
|
||||
provides
|
||||
|
||||
> scheme-editor%
|
||||
|
||||
which is a sub-class of `editor%' and implementation of `readable<%>'
|
||||
that is instantiated for Drscheme Scheme boxes in a WXME stream. The
|
||||
class includes a `get-data' method that returns #t if the box
|
||||
corresponds to a spliciing unquote, #f for a non-splicing unquote.
|
||||
|
||||
======================================================================
|
||||
_text.ss_ --- DrScheme text boxes
|
||||
======================================================================
|
||||
|
||||
In addition to `reader', an instance of `snip-reader<%>', this library
|
||||
provides
|
||||
|
||||
> text-editor%
|
||||
|
||||
which is a sub-class of `editor%' and implementation of `readable<%>'
|
||||
that is instantiated for DrScheme text boxes in a WXME stream. The
|
||||
class includes a `get-data' method that always returns #f.
|
||||
|
||||
======================================================================
|
||||
_number.ss_ --- DrScheme fractions
|
||||
======================================================================
|
||||
|
||||
This library provides just `reader', which an instance of
|
||||
`snip-reader<%>' that converts DrScheme fractions in a WXME stream to
|
||||
exact numbers.
|
||||
|
||||
======================================================================
|
||||
_cache-image.ss_ --- DrScheme teachpack images
|
||||
======================================================================
|
||||
|
||||
In addition to `reader', an instance of `snip-reader<%>', this library
|
||||
provides
|
||||
|
||||
> cache-image%
|
||||
|
||||
which is instantiated for images in a WXME stream generated by the
|
||||
"image.ss" and "world.ss" teachpacks (or, more generally, by
|
||||
"cache-image-snip.ss" of "mrlib". The class provides several methods:
|
||||
|
||||
> (get-argb) - returns a vector of integersin [0,255] representing
|
||||
the content of the image
|
||||
> (get-width) - returns the width of the image
|
||||
> (get-height) - returns the height of the image
|
||||
> (get-pin-x) - returns an offset into the image for the pinhole
|
||||
> (get-pin-y) - returns an offset into the image for the pinhole
|
||||
|
||||
======================================================================
|
||||
_test-case.ss_ --- DrScheme test-case boxes
|
||||
======================================================================
|
||||
|
||||
In addition to `reader', an instance of `snip-reader<%>', this library
|
||||
provides
|
||||
|
||||
> test-case%
|
||||
|
||||
which is instantiated for DrScheme test-case boxes in a WXME stream.
|
||||
The class provides several methods:
|
||||
|
||||
> (get-comment) - returns a port or #f for the comment field (if any)
|
||||
> (get-test) - returns a port for the "test" field
|
||||
> (get-expected) - returns a port for the "expected" field
|
||||
> (get-should-raise) - returns a port/#f for the "should raise" field
|
||||
> (get-error-message) - returns a port/#f for the "error msg" field
|
||||
> (get-enabled?) - returns #t if the test is enabled
|
||||
> (get-collapsed?) - returns #t if the test is collapsed
|
||||
> (get-error-box?) - return #t if the test is for an exception
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
|
||||
(module editor mzscheme
|
||||
(define-struct editor (content-port))
|
||||
(provide (struct editor (content-port))))
|
||||
(require (lib "class.ss")
|
||||
"private/class-help.ss")
|
||||
|
||||
(provide editor%)
|
||||
|
||||
(define editor%
|
||||
(class object%
|
||||
(init-accessible content-port)
|
||||
(super-new))))
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
|
||||
(module image mzscheme
|
||||
(define-struct image (filename data w h dx dy))
|
||||
(provide (struct image (filename data w h dx dy))))
|
||||
(require (lib "class.ss")
|
||||
"private/class-help.ss")
|
||||
|
||||
(provide image%)
|
||||
|
||||
(define image%
|
||||
(class object%
|
||||
(init-accessible filename data w h dx dy)
|
||||
(super-new))))
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
|
||||
(module number mzscheme
|
||||
(require (lib "class.ss"))
|
||||
(require (lib "class.ss")
|
||||
"wxme.ss")
|
||||
|
||||
(provide reader)
|
||||
|
||||
(define reader
|
||||
(new
|
||||
(class object%
|
||||
(class* object% (snip-reader<%>)
|
||||
(define/public (read-header vers stream)
|
||||
(void))
|
||||
(define/public (read-snip text? cvers stream)
|
||||
|
|
25
collects/wxme/private/class-help.ss
Normal file
25
collects/wxme/private/class-help.ss
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
(module class-help mzscheme
|
||||
(require (lib "class.ss"))
|
||||
|
||||
(provide init-accessible)
|
||||
|
||||
;; like `init-field', but makes a `get-' public method
|
||||
;; instead of a public field
|
||||
(define-syntax (init-accessible stx)
|
||||
(syntax-case stx ()
|
||||
[(_ id)
|
||||
(identifier? #'id)
|
||||
#'(init-accessible [id])]
|
||||
[(_ [id . val])
|
||||
(with-syntax ([get-id (datum->syntax-object
|
||||
#'id
|
||||
(string->symbol (format "get-~a" (syntax-e #'id)))
|
||||
#'id)])
|
||||
#'(begin
|
||||
(init [(internal-id id) . val])
|
||||
(define private-id internal-id)
|
||||
(define/public (get-id) private-id)))]
|
||||
[(_ binding ...)
|
||||
#'(begin (init-accessible binding) ...)])))
|
||||
|
44
collects/wxme/private/compat.ss
Normal file
44
collects/wxme/private/compat.ss
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
(module compat mzscheme
|
||||
(provide register-compatibility-mappings!)
|
||||
|
||||
(define (register-compatibility-mappings! register-lib-mapping!)
|
||||
(register-lib-mapping!
|
||||
"(lib \"comment-snip.ss\" \"framework\")"
|
||||
'(lib "comment.ss" "wxme"))
|
||||
|
||||
(register-lib-mapping!
|
||||
"drscheme:number"
|
||||
'(lib "number.ss" "wxme"))
|
||||
(register-lib-mapping!
|
||||
"(lib \"number-snip.ss\" \"drscheme\" \"private\")"
|
||||
'(lib "number.ss" "wxme"))
|
||||
|
||||
(register-lib-mapping!
|
||||
"drscheme:xml-snip"
|
||||
'(lib "xml.ss" "wxme"))
|
||||
(register-lib-mapping!
|
||||
"(lib \"xml-snipclass.ss\" \"xml\")"
|
||||
'(lib "xml.ss" "wxme"))
|
||||
|
||||
(register-lib-mapping!
|
||||
"drscheme:scheme-snip"
|
||||
'(lib "scheme.ss" "wxme"))
|
||||
(register-lib-mapping!
|
||||
"(lib \"scheme-snipclass.ss\" \"xml\")"
|
||||
'(lib "scheme.ss" "wxme"))
|
||||
|
||||
(register-lib-mapping!
|
||||
"text-box%"
|
||||
'(lib "text.ss" "wxme"))
|
||||
(register-lib-mapping!
|
||||
"(lib \"text-snipclass.ss\" \"xml\")"
|
||||
'(lib "text.ss" "wxme"))
|
||||
|
||||
(register-lib-mapping!
|
||||
"(lib \"cache-image-snip.ss\" \"mrlib\")"
|
||||
'(lib "cache-image.ss" "wxme"))
|
||||
|
||||
(register-lib-mapping!
|
||||
"test-case-box%"
|
||||
'(lib "test-case.ss" "wxme"))))
|
|
@ -5,24 +5,34 @@
|
|||
"../wxme.ss"
|
||||
"../editor.ss")
|
||||
|
||||
(provide editor-reader%
|
||||
(struct readable-editor (reader data)))
|
||||
(provide readable-editor%
|
||||
editor-reader%)
|
||||
|
||||
(define-struct/properties (readable-editor editor) (reader data)
|
||||
([prop:readable (lambda (this src line col pos)
|
||||
(send (readable-editor-reader this) generate-special this src line col pos))]))
|
||||
(define readable-editor%
|
||||
(class* editor% (readable<%>)
|
||||
(init content reader data)
|
||||
(define the-reader reader)
|
||||
(define the-data data)
|
||||
|
||||
(define/public (read-special src line col pos)
|
||||
(send the-reader generate-special this src line col pos))
|
||||
|
||||
(define/public (get-data)
|
||||
the-data)
|
||||
|
||||
(super-make-object content)))
|
||||
|
||||
(define editor-reader%
|
||||
(class object%
|
||||
(class* object% (snip-reader<%>)
|
||||
(define/public (read-header vers stream)
|
||||
(void))
|
||||
(define/public (read-editor-snip text? vers stream data)
|
||||
(let ([s (send stream read-editor-snip)])
|
||||
(define/public (read-editor-snip text? vers stream data %)
|
||||
(let ([s (send stream read-editor-snip "box content")])
|
||||
(if text?
|
||||
s
|
||||
(make-readable-editor s this data))))
|
||||
(make-object % s this data))))
|
||||
(define/public (read-snip text? vers stream)
|
||||
(read-editor-snip text? vers stream #f))
|
||||
(read-editor-snip text? vers stream #f readable-editor%))
|
||||
|
||||
(define/public (generate-special editor src line col pos)
|
||||
(make-special-comment editor))
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
"editor.ss"
|
||||
"private/readable-editor.ss")
|
||||
|
||||
(provide reader)
|
||||
(provide reader
|
||||
scheme-editor%)
|
||||
|
||||
(define scheme-editor% (class readable-editor% (super-new)))
|
||||
|
||||
(define reader
|
||||
(new
|
||||
|
@ -13,12 +16,12 @@
|
|||
(inherit read-editor-snip)
|
||||
(define/override (read-snip text? vers stream)
|
||||
(let ([splice? (zero? (send stream read-integer "splice?"))])
|
||||
(read-editor-snip text? vers stream splice?)))
|
||||
(read-editor-snip text? vers stream splice? scheme-editor%)))
|
||||
|
||||
(define/override (generate-special editor src line col pos)
|
||||
(list (if (readable-editor-data editor)
|
||||
(list (if (send editor get-data)
|
||||
'unquote-splicing
|
||||
'unquote)
|
||||
(read (editor-content-port editor))))
|
||||
(read (send editor get-content-port))))
|
||||
|
||||
(super-new)))))
|
||||
|
|
65
collects/wxme/test-case.ss
Normal file
65
collects/wxme/test-case.ss
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
(module test-case mzscheme
|
||||
(require (lib "class.ss")
|
||||
"wxme.ss"
|
||||
"private/class-help.ss")
|
||||
|
||||
(provide reader
|
||||
test-case%)
|
||||
|
||||
(define test-case%
|
||||
(class object%
|
||||
(init-accessible test
|
||||
expected
|
||||
[comment #f]
|
||||
[predicate #f]
|
||||
[should-raise #f]
|
||||
[error-message #f]
|
||||
[enabled? #t]
|
||||
[collapsed? #f]
|
||||
[error-box? #f])
|
||||
(super-new)))
|
||||
|
||||
(define (concat port)
|
||||
(if port
|
||||
(let loop ([accum null])
|
||||
(let ([s (read-bytes 4096 port)])
|
||||
(if (eof-object? s)
|
||||
(apply bytes-append (reverse accum))
|
||||
(loop (cons s accum)))))
|
||||
#""))
|
||||
|
||||
(define reader
|
||||
(new
|
||||
(class* object% (snip-reader<%>)
|
||||
(define/public (read-header vers stream)
|
||||
(void))
|
||||
(define/public (read-snip text? cvers stream)
|
||||
(let ([v (cond
|
||||
[(= cvers 1)
|
||||
(new test-case%
|
||||
[comment (send stream read-editor-snip "test-case-box content")]
|
||||
[test (send stream read-editor-snip "test-case-box test")]
|
||||
[expected (send stream read-editor-snip "test-case-box expected")])]
|
||||
[else
|
||||
(new test-case%
|
||||
[test (send stream read-editor-snip "test-case-box test")]
|
||||
[expected (send stream read-editor-snip "test-case-box expected")]
|
||||
[predicate (send stream read-editor-snip "test-case-box predicate")]
|
||||
[should-raise (send stream read-editor-snip "test-case-box should-raise")]
|
||||
[error-message (send stream read-editor-snip "test-case-box error-message")]
|
||||
[enabled? (= 1 (send stream read-integer "test-case-box enabled?"))]
|
||||
[collapsed? (= 1 (send stream read-integer "test-case-box collapsed?"))]
|
||||
[error-box? (= 1 (send stream read-integer "test-case-box error-box?"))])])])
|
||||
(if text?
|
||||
(apply
|
||||
bytes-append
|
||||
(map concat
|
||||
(send v get-comment)
|
||||
(send v get-test)
|
||||
(send v get-expected)
|
||||
(send v get-predicate)
|
||||
(send v get-should-raise)
|
||||
(send v error-message)))
|
||||
v)))
|
||||
(super-new)))))
|
|
@ -5,12 +5,18 @@
|
|||
"editor.ss"
|
||||
"private/readable-editor.ss")
|
||||
|
||||
(provide reader)
|
||||
(provide reader
|
||||
text-editor%)
|
||||
|
||||
(define text-editor% (class readable-editor% (super-new)))
|
||||
|
||||
(define reader
|
||||
(new (class editor-reader%
|
||||
(inherit read-editor-snip)
|
||||
(define/override (read-snip text? vers stream)
|
||||
(read-editor-snip text? vers stream #f text-editor%))
|
||||
(define/override (generate-special editor src line col pos)
|
||||
(let ([port (editor-content-port editor)])
|
||||
(let ([port (send editor get-content-port)])
|
||||
(let loop ([accum null])
|
||||
(let ([s (read-bytes 4096 port)])
|
||||
(if (eof-object? s)
|
||||
|
|
|
@ -4,16 +4,12 @@
|
|||
(lib "string.ss")
|
||||
(lib "kw.ss")
|
||||
(lib "class.ss")
|
||||
(lib "contract.ss")
|
||||
"image.ss"
|
||||
"editor.ss")
|
||||
"editor.ss"
|
||||
"private/compat.ss")
|
||||
|
||||
(define (expect rx port who msg)
|
||||
(let ([m (regexp-match rx port)])
|
||||
(unless m
|
||||
(error who "bad WXME stream; ~a" msg))
|
||||
(car m)))
|
||||
|
||||
(define (decode who port snip-filter)
|
||||
(define (decode who port snip-filter close?)
|
||||
(expect #rx#"^WXME" port who "does not start with \"WXME\"")
|
||||
(expect #rx#"^01" port who "unrecognized format (not \"01\")")
|
||||
(let ([vers (string->number
|
||||
|
@ -22,7 +18,15 @@
|
|||
(unless (vers . < . 4)
|
||||
(expect #rx#"^ ##[ \r\n]" port who "missing \" ## \" tag in the expected place"))
|
||||
(let ([header (read-header who port vers snip-filter)])
|
||||
(port->decoded-port who port vers header))))
|
||||
(port->decoded-port who port vers header close?))))
|
||||
|
||||
(define (expect rx port who msg)
|
||||
(let ([m (regexp-match rx port)])
|
||||
(unless m
|
||||
(error who "bad WXME stream; ~a" msg))
|
||||
(car m)))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(define-struct header (classes data-classes styles snip-filter skip-unknown? snips-to-go stream))
|
||||
(define (header-plain-text? h)
|
||||
|
@ -66,7 +70,8 @@
|
|||
(and (pair? results)
|
||||
(begin0
|
||||
(car results)
|
||||
(set! results (cdr results)))))))))
|
||||
(set! results (cdr results))))))
|
||||
void)))
|
||||
(loop (sub1 cnt)
|
||||
(cons (read-snip who port vers header)
|
||||
accum))))))
|
||||
|
@ -182,23 +187,37 @@
|
|||
(let ([len (and (or (not class)
|
||||
(not (snip-class-required? class)))
|
||||
(read-fixed-integer who port vers "snip length"))])
|
||||
(if class
|
||||
(if (and class
|
||||
(snip-class-manager class))
|
||||
(let ([style (read-integer who port vers "snip style index")]
|
||||
[m (snip-class-manager class)]
|
||||
[cvers (snip-class-version class)])
|
||||
(let ([s (if (procedure? m)
|
||||
;; Built-in snip class:
|
||||
(m who port vers cvers header)
|
||||
(send m read-snip
|
||||
(header-plain-text? header)
|
||||
cvers
|
||||
(header-stream header)))])
|
||||
;; Extension snip class:
|
||||
(let* ([text? (header-plain-text? header)]
|
||||
[s (send m read-snip
|
||||
text?
|
||||
cvers
|
||||
(header-stream header))])
|
||||
(if (and text?
|
||||
(not (bytes? s)))
|
||||
(error 'read-snip
|
||||
"reader for ~a in text-only mode produced something other than bytes: ~e"
|
||||
(snip-class-name class)
|
||||
s)
|
||||
s)))])
|
||||
(read-buffer-data who port vers header)
|
||||
(if (bytes? s)
|
||||
;; Return bytes for the stream:
|
||||
s
|
||||
;; Filter the non-bytes result, and then wrap it as
|
||||
;; a special stream result:
|
||||
(let ([s ((header-snip-filter header) s)])
|
||||
(lambda (src line col pos)
|
||||
(if (readable? s)
|
||||
((readable-ref s) s src line col pos)
|
||||
(if (s . is-a? . readable<%>)
|
||||
(send s read-special src line col pos)
|
||||
s))))))
|
||||
(begin
|
||||
(skip-data port vers len)
|
||||
|
@ -319,8 +338,14 @@
|
|||
|
||||
;; ----------------------------------------
|
||||
|
||||
(define-values (prop:readable readable? readable-ref)
|
||||
(make-struct-type-property 'readable))
|
||||
(define snip-reader<%>
|
||||
(interface ()
|
||||
read-header
|
||||
read-snip))
|
||||
|
||||
(define readable<%>
|
||||
(interface ()
|
||||
read-special))
|
||||
|
||||
(define (find-class pos header who port vers)
|
||||
(define classes (header-classes header))
|
||||
|
@ -372,7 +397,7 @@
|
|||
(let ([n (read-editor-snip who port vers header)])
|
||||
(if (header-plain-text? header)
|
||||
n
|
||||
(make-editor n))))]
|
||||
(make-object editor% n))))]
|
||||
[(equal? name #"wximage")
|
||||
(lambda (who port vers cvers header)
|
||||
(let ([filename (read-a-string who port vers "image-snip filename")]
|
||||
|
@ -398,12 +423,14 @@
|
|||
(loop (add1 i))))))))])
|
||||
(if (header-plain-text? header)
|
||||
#"."
|
||||
(make-image (if data #f filename) data w h dx dy)))))]
|
||||
(make-object image% (if data #f filename) data w h dx dy)))))]
|
||||
[else
|
||||
;; Load a manager for this snip class?
|
||||
(let ([lib (string->lib-path (bytes->string/latin-1 name))])
|
||||
(if lib
|
||||
(let ([mgr (dynamic-require lib 'reader)])
|
||||
(unless (mgr . is-a? . snip-reader<%>)
|
||||
(error who "reader provided by ~s is not an instance of snip-reader<%>" lib))
|
||||
mgr)
|
||||
(if (header-skip-unknown? header)
|
||||
#f
|
||||
|
@ -450,7 +477,7 @@
|
|||
(read-a-string who port vers what))
|
||||
|
||||
(public [rne read-editor-snip])
|
||||
(define (rne)
|
||||
(define (rne what)
|
||||
(read-editor-snip who port vers header))
|
||||
|
||||
(super-new)))
|
||||
|
@ -473,11 +500,9 @@
|
|||
(andmap ok-string-element? (cdr m))))
|
||||
|
||||
(define (register-lib-mapping! str target)
|
||||
(let ([lib (with-handlers ([exn:fail? (lambda (x) #f)])
|
||||
(read (open-input-string target)))])
|
||||
(unless (ok-lib-path? lib)
|
||||
(error 'register-lib-mapping! "given target is not a valid lib path: ~s" target))
|
||||
(hash-table-put! lib-mapping str lib)))
|
||||
(unless (ok-lib-path? target)
|
||||
(error 'register-lib-mapping! "given target is not a valid marshalable lib path: ~s" target))
|
||||
(hash-table-put! lib-mapping str target))
|
||||
|
||||
(define (string->lib-path str)
|
||||
(or (let ([m (and (regexp-match #rx"^[(].*[)]$" str)
|
||||
|
@ -492,6 +517,8 @@
|
|||
(cadr m)))
|
||||
(hash-table-get lib-mapping str #f)))
|
||||
|
||||
(register-compatibility-mappings! register-lib-mapping!)
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(define plain-params
|
||||
|
@ -516,7 +543,7 @@
|
|||
|
||||
;; ----------------------------------------
|
||||
|
||||
(define (port->decoded-port who port vers header)
|
||||
(define (port->decoded-port who port vers header close?)
|
||||
(snip-results->port
|
||||
(object-name port)
|
||||
(lambda ()
|
||||
|
@ -525,9 +552,12 @@
|
|||
[(zero? snips-to-go) #f]
|
||||
[else
|
||||
(set-header-snips-to-go! header (sub1 snips-to-go))
|
||||
(read-snip who port vers header)])))))
|
||||
(read-snip who port vers header)])))
|
||||
(if close?
|
||||
(lambda () (close-input-port port))
|
||||
void)))
|
||||
|
||||
(define (snip-results->port name next-item!)
|
||||
(define (snip-results->port name next-item! close)
|
||||
(define-values (r w) (make-pipe))
|
||||
(define (read-proc buffer)
|
||||
(if (char-ready? r)
|
||||
|
@ -545,20 +575,31 @@
|
|||
name
|
||||
read-proc
|
||||
#f
|
||||
void))
|
||||
close))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(define (wxme-convert-port port close? snip-filter)
|
||||
;; read optional #reader header:
|
||||
(regexp-match/fail-without-reading #rx#"^#reader[(]lib\"read.ss\"\"wxme\"[)]" port)
|
||||
;; decode:
|
||||
(decode 'read-bytes port snip-filter close?))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(define unknown-extensions-skip-enabled (make-parameter #f))
|
||||
|
||||
(define/kw (wxme-port->port port #:optional [snip-filter (lambda (x) x)])
|
||||
;; read optional #reader header:
|
||||
(regexp-match/fail-without-reading #rx#"^#reader[(]lib\"wxme.ss\"\"mred\"[)]" port)
|
||||
;; decode:
|
||||
(decode 'read-bytes port snip-filter))
|
||||
(define (is-wxme-stream? p)
|
||||
(regexp-match-peek #rx#"^(?:#reader(lib\"read[.]ss\"\"wxme\"))?WXME01[0-9][0-9] ##[ \r\n]" p))
|
||||
|
||||
(define/kw (wxme-port->port port #:optional [close? #t] [snip-filter (lambda (x) x)])
|
||||
(wxme-convert-port port close? snip-filter))
|
||||
|
||||
(define/kw (wxme-port->text-port port #:optional [close? #t])
|
||||
(wxme-convert-port port close? #f))
|
||||
|
||||
(define (do-read port who read)
|
||||
(let ([port (decode who port #t)])
|
||||
(let ([port (decode who port #t #f)])
|
||||
(let ([v (read port)])
|
||||
(let ([v2 (let loop ()
|
||||
(let ([v2 (read port)])
|
||||
|
@ -579,14 +620,19 @@
|
|||
(do-read port 'read read))
|
||||
|
||||
(define (wxme-read-syntax source-name-v port)
|
||||
(do-read port 'read-syntax
|
||||
(lambda (port)
|
||||
(read-syntax source-name-v port))))
|
||||
(datum->syntax-object
|
||||
#f
|
||||
(do-read port 'read-syntax
|
||||
(lambda (port)
|
||||
(read-syntax source-name-v port)))))
|
||||
|
||||
(provide wxme-port->port
|
||||
register-lib-mapping!
|
||||
unknown-extensions-skip-enabled
|
||||
prop:readable
|
||||
(provide/contract [is-wxme-stream? (input-port? . -> . any)]
|
||||
[wxme-port->text-port ((input-port?) (any/c) . opt-> . input-port?)]
|
||||
[wxme-port->port ((input-port?) (any/c (any/c . -> . any)) . opt-> . input-port?)]
|
||||
[register-lib-mapping! (string? string? . -> . void?)])
|
||||
|
||||
(provide unknown-extensions-skip-enabled
|
||||
snip-reader<%>
|
||||
readable<%>
|
||||
wxme-read
|
||||
wxme-read-syntax))
|
||||
|
||||
|
|
|
@ -7,20 +7,23 @@
|
|||
"editor.ss"
|
||||
"private/readable-editor.ss")
|
||||
|
||||
(provide reader)
|
||||
(provide reader
|
||||
xml-editor%)
|
||||
|
||||
(define xml-editor% (class readable-editor% (super-new)))
|
||||
|
||||
(define reader
|
||||
(new (class editor-reader%
|
||||
(inherit read-editor-snip)
|
||||
(define/override (read-snip text? vers stream)
|
||||
(let ([elim-whitespace? (zero? (send stream read-integer "elim-whitespace?"))])
|
||||
(read-editor-snip text? vers stream elim-whitespace?)))
|
||||
(read-editor-snip text? vers stream elim-whitespace? xml-editor%)))
|
||||
|
||||
(define/override (generate-special editor src line col pos)
|
||||
(let* ([port (editor-content-port editor)]
|
||||
(let* ([port (send editor get-content-port)]
|
||||
[xml (read-xml port)]
|
||||
[xexpr (xml->xexpr (document-element xml))]
|
||||
[clean-xexpr (if (readable-editor-data editor)
|
||||
[clean-xexpr (if (send editor get-data)
|
||||
(eliminate-whitespace-in-empty-tags xexpr)
|
||||
xexpr)])
|
||||
(list 'quasiquote clean-xexpr)))
|
||||
|
|
Loading…
Reference in New Issue
Block a user