
Yes. Vector based image formats are more difficult to handle than bitmaps.

There are binding for svg libraries available if you need to work with them.

The rsvg
package provides functions that load SVGs as bitmaps. rsvg
needs to call libRSVG using FFI

So converting to pngs outside of Racket is the easiest approach

I am trying to write my first real macro (meaning one that is not a pure exercise) thanks to the syntax-parse bee. Unsurprisingly, I am stuck - or rather, I got it working, but in an incredibly dumb way. First the code, then some explanations:
(require (for-syntax racket/base syntax/parse))
;;; Define some functions just so the example that I care about makes sense without other libraries (it uses Bogdan's `forms` library)
(define (rw a b)
(cond [(list? b)
(for/list ([item b])
(rw a item))]
[else
`(div ,(format "rw of ~a for '~a'" b a))]))
(define (widget-text)
"Text widget")
(define (widget-number)
'"Number widget")
(define (widget-errors)
(list "Error widget 1" "Error widget 2"))
;;; The way to write the html for a single survey question in the original way
(define original-question
`(div ((class "group"))
(label
"What is your gender?"
,(rw "gender" (widget-text)))
,@(rw "gender" (widget-errors))))
(define-syntax (survey-question0 stx)
(syntax-parse stx
[(_ ?template:expr ?question:expr ?label:expr ?question-widget:expr)
#'(?template ?question ?label ?question-widget)]))
;;; The first step in the direction of separating html and content of survey question
(define how-to-write-question0
(survey-question0
(λ (:question :label :widget)
``(div ((class "group"))
(label
,,:question
,(rw ,:label (,:widget))
,@(rw ,:label (widget-errors)))))
"What is your gender?" "gender" 'widget-text))

So, the point is that I have a bunch of survey questions that all have the same boilerplate. More importantly, it means that rather than writing (survey-question "What is your gender?" "gender" text)
— which has all the information a survey designer cares about, namely the question, the name for the data field, and they type — I intermingle presentation and content.
The problem I am having above is that I have to double escape the key-words :question
, :label
and :widget
. Ideally I would write it as follows:
(define how-to-write-question0
(survey-question0
`(div ((class "group"))
(label
:question
,(rw :label (:widget))
,@(rw :label (widget-errors)))))
"What is your gender?" "gender" 'widget-text))
That is, the three variables that I care about are simply replaced in the template, but otherwise it is left alone, including that ,(rw ...)
is not run. I tried to use syntax-parameters
to achieve this goal, but that fails. For some reason syntax-parameters
don’t seem to get along with syntax-parse
? I understand that what I want to do something that is considered unhygenic, so my question is how to do that in a sensible way with syntax-parse? The final macro is going to do quite a bit more work, as it should define the template only once, and then accept a list of survey questions, so I believe that I will want to remain with syntax-parse for error messages etc.

I kind of get it until the double escaping part. Is there any issue with keeping the single escape, and passing widget-text
as a function? (define how-to-write-question0-nde
(survey-question0
(λ (:question :label :widget)
`(div ((class "group"))
(label
,:question
,(rw :label (:widget))) ;; <= here
,@(rw :label (widget-errors))))
"What is your gender?"
"gender"
widget-text ;; <= here
))
Is this not sufficient?

(The parenthesis over label
in survey-question0
is different from that of the original-question
’s so I adjusted it a little.

If I don’t double escape, then ,(rw :label (:widget))
is evaluated, but what I want is for :label
and :widget
to be replaced, but not for ,(rw ...)
to be evaluated. Does that makes sense?

Hmm, so do you want the output of survey-question0
to be a datum with quasiquote
and unquote
in it? Is there an input-output example?

And one more question is that are the things that :...
denotes going to be values?

I didn’t give enough context. The reason is that I want to use the macro in the following type of situation:
(λ (rw)
`(div
(div ((class "group"))
(label
"What is your gender?"
,(rw "gender" (widget-text)))
,@(rw "gender" (widget-errors)))))
Hence in that location, the macro should not run (rw ...)
, but return the syntax object for the sequence ,(rw ...)
.

This post may help. Michael Ballantyne explains how to evaluate an expression (perhaps to another syntax object or so) at compile time, so those :quesion
s and :label
s can be considered as some compiled-time variables https://groups.google.com/g/racket-users/c/61cQImHJfZI/m/tyq3f8omAwAJ?utm_medium=email&utm_source=footer

Yes, they are values. In the example, :question
is supposed to take the value “What is your gender?”, :label
should be bound to "gender"
, and :widget
should be bound to 'widget-text
.

The macro is not evaluating rw
though, and taking rw
as another argument seems fine, such as (define make-write-question
(survey-question0
(λ (:question :label :widget)
(λ (rw)
`(div ((class "group"))
(label
,:question
,(rw :label (:widget))) ;; <= here
,@(rw :label (widget-errors)))))
"What is your gender?"
"gender"
widget-text ;; <= here
))
and (equal? (make-write-question rw) original-question)
;; => #t

I’ll have a look, I didn’t immediately understand the case described there.

I guess my question should be: without the syntax extension power from macros, how could the plain procedure version work?

OK, but there might be more such functions, and more questions, and I do not want to pass in rw
as an argument to all. Example:
(λ (rw)
`(div
(div ((class "group"))
(label
"What is your gender?"
,(rw "gender" (widget-text)))
,@(rw "gender" (widget-errors)))
(div ((class "group"))
(label
"How clear were the instructions on a scale from 1 (very unclear) to 5 (very clear)?"
,(rw "how-clear" (widget-number)))
,@(rw "how-clear" (widget-errors)))
(div ((class "group"))
(label
"If not, what could have been clearer?"
,(rw "what-could-be-clearer" (widget-text)))
,@(rw "what-could-be-clearer" (widget-errors)))
(div ((class "group"))
(label
"How restful did you find the tracks after the required tasks, from 1 (very un-relaxing) to 5 (very relaxing)?"
,(rw "how-relaxing" (widget-number)))
,@(rw "how-relaxing" (widget-errors)))... ;;; More stuff

And from that point adding macros to extend the syntax and hide runtime details

I agree, I think the macro for the current use-case is overkill - but (a) I am practicing macros and (b) the further extensions and syntax-simplifications I have in mind will require macros. It’s just that I got stuck on step number 1.

Yes, I understand the goal of practicing macros. Nonetheless, understanding how to make the expanded-by-hand version work will help implementing the macro

Ah, I see. I’ll have a look at that, but there will always be the possibility of having arbitrary racket code in the survey questions, but which I do not want to evaluate — all I want is to replace the information about the survey questions inside of the template, yet allow.

For example, if hiding the rw
part is what you want, then the macro could be helping that part

Sure. In that not-to-evaluate case, the macro could te helping adding thunks and calling thunks :smile:

Thanks though (I gotta dash now, will check in later). I’ll try and clarify what I want also, and provide a better use case. I was hopelessly unclear.

does racket have the equivalent of gcc main.c -O3
, debug vs optimized builds, e.g O3
? or is everything you run in already producing O3?

It already produces O3

If you want to debug, you would use stuff like errortrace

ahh, so compiling to an executable just makes startup time faster? not the general runtime?

Compiling to an executable doesn’t make startup faster, usually.