Sascha Ziemann writes: > All you need is quasiquote, unquote and a function which formats SXML as XML. > > (html > `("" I use something like this with Guile: https://hg.sr.ht/~arnebab/guile-freenet/browse/fetchpull-standalone.scm?rev=tip#L604 (define (website-content port) (define title "Fetch-Pull-Stats re-woven") (sxml->xml `(*TOP* (html (head (title ,title) (meta (@ (charset "utf-8")))) (body (h1 ,title) (p (img (@ (src "fetchpull.png") (alt "fetch-pull-statistics")))) (p "created with " (a (@ (href "https://bitbucket.org/ArneBab/freenet-guile/src/default/fetchpull.w") (title "link to project")) "fetchpull.w")) (p "plotted with " (a (@ (href "fetchpull-plot.gnuplot")) "fetchpull-plot.gnuplot"))))) port)) More complex version with more examples for solutions to needs: https://hg.sr.ht/~arnebab/guile-freenet/browse/fetchpull.w?rev=tip#L794 (this one is with wisp: https://www.draketo.de/software/wisp ) define : website-content port _ define title "Fetch-Pull-Stats re-woven" _ sxml->xml _ ` *TOP* _ html _ head : meta : @ (charset "utf-8") _ title ,title _ body : h1 ,title _ p "These are the fetch-pull statistics. They provide an estimate of lifetimes of real files in Freenet and a somewhat early warning when network quality should degrade." _ p "Realtime are 80 bytes. Small are 128 kiB. Bulk is 1MiB." _ p "Further details are explained below the diagrams." _ ,@ map : λ (attributes) : ` p : img ,attributes ;; create multiple images without unnecessary ceremony _ ' _ @ (src "fetchpull-lifetime-realtime-success-count.png") (alt "lifetime plot: successes per month, realtime") _ @ (src "fetchpull-lifetime-small-success-count.png") (alt "lifetime plot: successes per month, small bulk") _ @ (src "fetchpull-lifetime-bulk-success-count.png") (alt "lifetime plot: successes per month, large bulk") _ @ (src "fetchpull-get-realtime.png") (alt "fetch-pull realtime download graph") _ @ (src "fetchpull-get-small.png") (alt "fetch-pull small download graph") _ @ (src "fetchpull-get-bulk.png") (alt "fetch-pull bulk download graph") _ @ (src "fetchpull-get-failed-realtime.png") (alt "fetch-pull failed realtime download graph") _ @ (src "fetchpull-get-failed-small.png") (alt "fetch-pull failed small download graph") _ @ (src "fetchpull-get-failed-bulk.png") (alt "fetch-pull failed bulk download graph") _ @ (src "fetchpull-put.png") (alt "fetch-pull upload graph") _ @ (src "fetchpull-put-failed.png") (alt "fetch-pull failed upload graph") _ @ (src "fetchpull-lifetime-realtime.png") (alt "lifetime plot: time per download, realtime") _ @ (src "fetchpull-lifetime-small.png") (alt "lifetime plot: time per download, small bulk") _ @ (src "fetchpull-lifetime-bulk.png") (alt "lifetime plot: time per download, large bulk") _ h2 "explanation" _ p "Files uploaded regularly with the download attempted after some delay. Realtime is uploaded with realtime priority, small and bulk with bulk priority. Details are available in fetchpull.w (see sources)" _ p "Realtime is a raw KSK without any redirect. Size 80 bytes, Uploaded and downloaded in realtime mode without compression, using all tricks to reduce latency. This is the fake chat-message: What you would use for interactive status updates and such." _ p "Small is a KSK splitfile (a KSK that has the links to about 7 CHKs, needs 3-4). Size 128kiB uncompressed, around 80kiB compressed, Uploaded and downloaded in bulk mode." _ p "Bulk is a KSK which forwards to a CHK splitfile that has around 40 blocks, needs about 20 to download. Size 1MiB uncompressed, around 650kiB compressed, uploaded and downloaded in bulk mode." _ p "This page is generated by running " : code "./fetchpull.w --site fetchpullstats" _ ;; the following is just for fun. Not ready for production. You have been warned :-) _ . " " ,(> and then ,(string-append "uploaded" " " "with") freesitemgr (from pyFreenet ,{1 + 2}) as freesite.) _ br _ . "Feel free to create your own version." _ h2 "Sources" _ ul _ li "created with " _ a : @ (href "fetchpull.w") (title "link to exact file which generated this site") _ . "fetchpull.w" _ li "from project " _ a : @ (href "https://bitbucket.org/ArneBab/freenet-guile") (title "link to project") _ . "guile-fcp" _ li "plotted with " _ a : @ (href "fetchpull-plot.gnuplot") (title "plotting script for gnuplot") _ . "fetchpull-plot.gnuplot" _ li "using data from " _ a : @ (href "fetchpull-stats-get.csv") (title "download stats") _ . "fetchpull-stats-get.csv" _ . " and " _ a : @ (href "fetchpull-stats-put.csv") (title "upload stats") _ . "fetchpull-stats-put.csv" _ p _ a : @ (href "/?newbookmark=USK@lwR9sLnZD3QHveZa1FB0dAHgeck~dFNBg368mY09wSU,0Vq~4FXSUj1-op3QdzqjZsIvrNMYWlnSdUwCl-Z1fYA,AQACAAE/fetchpullstats/8/&desc=fetchpullstats&hasAnActivelink=true") _ . "bookmark this freesite" _ . port Best wishes, Arne -- Unpolitisch sein heißt politisch sein, ohne es zu merken. draketo.de