mbutterick / pollen-users

please use https://forums.matthewbutterick.com/c/typesetting/ instead
https://forums.matthewbutterick.com/c/typesetting/
52 stars 0 forks source link

`here` using wrong slashes on Windows #71

Closed soapdog closed 3 years ago

soapdog commented 3 years ago

Unfortunately functions and variables that generate paths such as ◊|here| end up using \ instead of / on Windows. This means that if you generate your website using Pollen on Windows you'll end up with wrong paths all over the place. It would be better if Pollen always used / since webservers kinda expect that to be the path separator.

mbutterick commented 3 years ago

Racket’s default policy is that “paths are created and manipulated for the current platform”. Furthermore, Pollen is not strictly a system for generating web pages. For these reasons, I’m not yet persuaded that it should adopt web-path conventions by default.

soapdog commented 3 years ago

I understand, @mbutterick, no worries. I just built myself a little helper here to solve this when doing interpolation in HTML. Thanks.

otherjoel commented 3 years ago

If working on Windows you can add a utility function to replace backslashes with slashes.

(define (windows->web s)
  (string-replace (symbol->string s) "\\" "/"))

It's surprising to me, though, that on Windows there seems to be no way to generate convert between Windows and Unix paths using only Racket’s path functions. build-path/convention-type simply refuses to generate a Unix path on a Windows system, even when building from plain strings.

> (build-path/convention-type 'windows "tutorial" "other.html")
#<path:tutorial\other.html>
> (build-path/convention-type 'unix "tutorial" "other.html")
build-path/convention-type: specified convention incompatible with string path element
  path element: "tutorial"
  convention: 'unix
soapdog commented 3 years ago

@otherjoel your windows->web function is exactly the same as the helper I built here. :heart:

mbutterick commented 3 years ago

You can make a path for a different platform, but you have to make path elements that are compatible with the target by explicitly converting from byte strings On my Mac, I can’t do this:

(build-path/convention-type 'windows "tutorial" "other.html")

But this works:

(build-path/convention-type 'windows
                            (bytes->path-element #"tutorial" 'windows)
                            (bytes->path-element #"other.html" 'windows))
#<windows-path:tutorial\other.html>

Handling paths as if they were strings is a little like mixing up eq? and equal? — it seems to give good results, until it suddenly doesn’t. Likewise, be aware that windows->web won’t behave correctly on all cases, even if it behaves correctly on some.