[racket] How `scribble` resolves relative paths

From: Matthew Butterick (mb at mbtype.com)
Date: Sun Sep 7 19:57:30 EDT 2014

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

For my purposes that's fine, though it's still a bit of a cheat. And cheating may not be an option next time ...


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

I thought that would be the case too, though it does work without `generate-temporaries`. (Looking at the macro expansion, it seems each time the macro operates, it assigns a unique subscript to each "rp" identifier so they don't collide). But I can't tell if that's just lucky behavior. `Generate-temporaries` is clearly the right way to do things. 

Thanks.



On Sep 7, 2014, at 2:11 PM, Greg Hendershott <greghendershott at gmail.com> wrote:

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