I might be mistaken, but it looks like Scribble depends very much on source location info for formatting this -- it looks like even a form read as "(a b)" will format as "(ab)" in some cases if the source location info is stripped.

If this is true, is my best bet to feed the generated syntax through the pretty-printer (with a sensible max. width), and read the output of that so that the location info is Scribble-friendly?

Neil Van Dyke wrote at 05/01/2012 02:57 AM:
Some more info...

I see that I am indeed stomping on the syntax location info for the "(or/c soundex-ordinal? #f)" syntax object, which I assume is a factor in it being formatted badly. I still have questions.

First, I made a procedure to do a detailed dump of the syntax object:

(define (debug-dump-syntax-object stx-or-pair)
  (cond ((pair? stx-or-pair)
         `(*NONSYNTAX-PAIR* ,(debug-dump-syntax-object (car stx-or-pair))
,(debug-dump-syntax-object (cdr stx-or-pair))))
        ((null? stx-or-pair)
         `(*NONSYNTAX-NULL*))
        (else
         `(*SYNTAX* :SRC ,(syntax-source    stx-or-pair)
                    :L   ,(syntax-line      stx-or-pair)
                    :C   ,(syntax-column    stx-or-pair)
                    :P   ,(syntax-position  stx-or-pair)
                    :S   ,(syntax-span      stx-or-pair)
                    :O   ,(syntax-original? stx-or-pair)
                    ,(let ((stx-e (syntax-e stx-or-pair)))
                       (cond ((pair? stx-e)
`(*SYNTAX-PAIR* ,(debug-dump-syntax-object (car stx-e)) ,(debug-dump-syntax-object (cdr stx-e))))
                             ((null? stx-e)
                              `(*SYNTAX-NULL*))
                             (else `(*ATOMIC* ,stx-e))))))))

So, the generated syntax object that looks pretty-printed like this:

(doc scribble (defproc (soundex-ordinal (chr char?))
                (or/c soundex-ordinal? #f)
                "Yields the Soundex ordinal value of character "
                (racket chr)
                "!!!"))

...has a debugging dump like this:

(*SYNTAX* :SRC "myfile" :L 56 :C 0 :P 2065 :S 648 :O #f
(*SYNTAX-PAIR* (*SYNTAX* :SRC "myfile" :L 56 :C 1 :P 2066 :S 3 :O #t
                                   (*ATOMIC* doc))
                         (*NONSYNTAX-PAIR*
                          (*SYNTAX* :SRC #f :L #f :C #f :P #f :S 0 :O #f
                                    (*ATOMIC* scribble))
                          (*NONSYNTAX-PAIR*
                           (*SYNTAX* :SRC #f :L #f :C #f :P #f :S 0 :O #f
                                     (*SYNTAX-PAIR*
(*SYNTAX* :SRC #f :L #f :C #f :P #f :S 0 :O #f
                                                (*ATOMIC* defproc))
                                      (*NONSYNTAX-PAIR*
(*SYNTAX* :SRC #f :L #f :C #f :P #f :S 0 :O #f
                                                 (*SYNTAX-PAIR*
(*SYNTAX* :SRC "myfile" :L 75 :C 9 :P 2798 :S 15 :O #t (*ATOMIC* soundex-ordinal)) (*SYNTAX* :SRC #f :L #f :C #f :P #f :S 0 :O #f (*SYNTAX-PAIR* (*SYNTAX* :SRC #f :L #f :C #f :P #f :S 0 :O #f (*SYNTAX-PAIR* (*SYNTAX* :SRC "myfile" :L 75 :C 25 :P 2814 :S 3 :O #t (*ATOMIC* chr)) (*NONSYNTAX-PAIR* (*SYNTAX* :SRC "myfile" :L 74 :C 39 :P 2753 :S 5 :O #t (*ATOMIC* char?)) (*NONSYNTAX-NULL*)))) (*NONSYNTAX-NULL*)))))
                                       (*NONSYNTAX-PAIR*
(*SYNTAX* :SRC #f :L #f :C #f :P #f :S 0 :O #f
                                                  (*SYNTAX-PAIR*
(*SYNTAX* :SRC "myfile" :L 74 :C 46 :P 2760 :S 4 :O #t (*ATOMIC* or/c))
                                                   (*NONSYNTAX-PAIR*
(*SYNTAX* :SRC "myfile" :L 74 :C 51 :P 2765 :S 16 :O #t (*ATOMIC* soundex-ordinal?))
                                                    (*NONSYNTAX-PAIR*
(*SYNTAX* :SRC "myfile" :L 74 :C 68 :P 2782 :S 2 :O #t (*ATOMIC* #f)) (*NONSYNTAX-NULL*))))) (*SYNTAX* :SRC #f :L #f :C #f :P #f :S 0 :O #f
                                                  (*SYNTAX-PAIR*
(*SYNTAX* :SRC "myfile" :L 57 :C 5 :P 2101 :S 48 :O #t

(*ATOMIC* "Yields the Soundex ordinal value of character "))
                                                   (*NONSYNTAX-PAIR*
(*SYNTAX* :SRC "myfile" :L 58 :C 5 :P 2155 :S 12 :O #t (*SYNTAX-PAIR* (*SYNTAX* :SRC "myfile" :L 58 :C 6 :P 2156 :S 6 :O #t (*ATOMIC* racket)) (*NONSYNTAX-PAIR* (*SYNTAX* :SRC "myfile" :L 58 :C 13 :P 2163 :S 3 :O #t (*ATOMIC* chr)) (*NONSYNTAX-NULL*))))
                                                    (*NONSYNTAX-PAIR*
(*SYNTAX* :SRC "myfile" :L 59 :C 5 :P 2173 :S 5 :O #t (*ATOMIC* "!!!")) (*NONSYNTAX-NULL*)))))))))
                           (*NONSYNTAX-NULL*)))))

If you search for "or/c" in the debug dump, you can see that its parent "(*SYNTAX* (*SYNTAX-PAIR* ...))" has nulled/zero location info, whereas "or/c" syntax object has valid info. This is presumably my fault and fixable, since I see no reason to replace the location info in this case. But even if I fix this one, I suspect I will have similar situations in the code that cannot be fixed, and that I imagine might mess up formatting similarly.

Also, I have both "*SYNTAX-PAIR*" and "*NONSYNTAX-PAIR*" in the dump. I can change all the latter kind to the former kind easily enough, if that actually matters.

Or perhaps I'm smoking crack, and Scribble is not as sensitive to source positions as it seems to me at the moment.


Neil Van Dyke wrote at 05/01/2012 01:51 AM:
Can someone who knows Scribble internals point me in the right direction on this?

I have a generated "defproc" syntax object that gets formatted badly by Scribble, as shown in screenshot: http://i.imgur.com/FmdQr.png

The "defproc" syntax object is generated in this case by piecing together information from three syntax objects read from a source file:

(doc procedure soundex-ordinal
     "Yields the Soundex ordinal value of character "
     (racket chr)
     [...])

(provide/contract (soundex-ordinal (-> char? (or/c soundex-ordinal? #f))))

(define (soundex-ordinal chr)
   [...])

Note that the other "defproc" in the screenshot is formatted fine. That "defproc" result of that one is an identifier, rather than a parenthesized form.

The "syntax->datum" looks fine, and formats correctly if pasted into a file and processed from there:

@(defproc (soundex-ordinal (chr char?))
   (or/c soundex-ordinal? #f)
   "Yields the Soundex ordinal value of character "
   (racket chr)
   [...])

I'm wondering whether the problem is the combinations of syntax location info in the generated "defproc" syntax object. I try to preserve the location info of the individual pieces, and often use "quasisyntax/loc". Also, the "(or/c soundex-ordinal? #f)" syntax object should be intact just as read originally, including its parentheses.

Neil V.

____________________
 Racket Users list:
 http://lists.racket-lang.org/users

____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to