[racket] How `scribble` resolves relative paths

From: Greg Hendershott (greghendershott at gmail.com)
Date: Sun Sep 7 17:11:32 EDT 2014

If you don't mind requiring that `name` be supplied first, you could
simply pass the remaining args through unchanged:

(define-syntax (image/rp stx)
  (syntax-case stx ()
    [(_ name xs ...)
     #'(begin
         (define-runtime-path id name)
         (image id xs ...))]))

It's not ideal because normally it should be fine to put the keyword
arguments before the positional one. However if this is just a private
helper macro it's probably fine.  If you wanted, you could have the
macro sanity check that `name` is not keyword? -- or more to the
point, that it _is_ identifier?. (That kind of stuff is nice to
declare with syntax-parse; it make a nice error message for you.)


Separately, I think one gotcha with your original macro will be if you
use it more than once? I think you need to provide a fresh id to each
define-runtime-path, like so:

(define-syntax (image/rp stx)
  (syntax-case stx ()
    [(_ name xs ...)
     (with-syntax ([id (generate-temporary)])
       #'(begin
           (define-runtime-path id name)
           (image id xs ...)))]))


On Sun, Sep 7, 2014 at 2:18 PM, Matthew Butterick <mb at mbtype.com> wrote:
> I made a rudimentary helper macro called `image/rp` that upgrades a relative path-string into a runtime path:
>
> (define-syntax (image/rp stx)
>   (syntax-case stx ()
>     [(_ name) #'(image/rp name 1.0)]
>     [(_ name scale) #'(begin
>                         (define-runtime-path rp name)
>                         (image rp #:scale scale))]))
>
> Of course, the problem is that it disregards the interface for `image`, which includes keyword arguments.
>
> Is there a standard idiom for matching keyword arguments with `syntax-case` ...
>
> 1) To capture all keyword arguments and pass them through unaltered?
> 2) To unpack keyword arguments, alter them, and reapply them?
>
>
>
> On Sep 1, 2014, at 9:59 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
>
>> I think the docs are wrong. While `raco setup` does set the current
>> directory, `scribble` does not.
>>
>> It's better to use `define-runtime-path` instead of relying on the
>> current directory, since that composes better.
>>
>> At Mon, 1 Sep 2014 18:20:05 -0700, Matthew Butterick wrote:
>>> I am confused by this statement in the docs vs. the actual behavior:
>>>
>>> The docs for `image` say that "If path is a relative path, it is relative to
>>> the current directory, which is set by `raco setup` and `scribble` to the
>>> directory of the main document file." (I'm using `image` as an example but I've
>>> seen the same problem with CSS files.)
>>>
>>> Suppose I have a project set up like this:
>>>
>>> /project
>>>    /scribblings
>>>        main.scrbl
>>>        sample.gif
>>>
>>> And "main.scrbl" contains this:
>>>
>>> #lang scribble/manual
>>> @image["sample.gif"]
>>>
>>> If I do this:
>>>> cd project
>>>> cd scribblings
>>>> scribble main.html
>>>
>>> The HTML will render fine.
>>>
>>> But if I do this:
>>>
>>>> cd project
>>>> scribble --dest-name doc scribblings/main.scrbl
>>>
>>> I'll get this error:
>>>
>>> open-input-file: cannot open input file
>>>  path: /project/sample.gif
>>>
>>> Thus, the relative path "sample.gif" is being resolved relative to the
>>> directory where I invoke the `scribble` command, not the "directory of the main
>>> document file", which in both cases seems like it should be
>>> /project/scribblings (i.e., the directory containing "main.scrbl").
>>>
>>> What am I misunderstanding?
>>>
>>>
>>>
>>>
>>>
>>>
>>> [1]
>>> http://docs.racket-lang.org/scribble/base.html?q=image#%28def._%28%28lib._scribb
>>> le%2Fbase..rkt%29._image%29%29____________________
>>>  Racket Users list:
>>>  http://lists.racket-lang.org/users
>
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.