From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Andy Wingo Newsgroups: gmane.lisp.guile.user Subject: Re: Example usages of guile-cairo Date: Thu, 04 Aug 2016 23:06:13 +0200 Message-ID: <87mvkss0qi.fsf@pobox.com> References: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1470344834 27534 195.159.176.226 (4 Aug 2016 21:07:14 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 4 Aug 2016 21:07:14 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) Cc: "guile-user@gnu.org" To: Panicz Maciej Godek Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Thu Aug 04 23:07:09 2016 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bVPr7-0005lb-9K for guile-user@m.gmane.org; Thu, 04 Aug 2016 23:07:05 +0200 Original-Received: from localhost ([::1]:41757 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bVPr3-0000qR-W4 for guile-user@m.gmane.org; Thu, 04 Aug 2016 17:07:02 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:55518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bVPqZ-0000qJ-M2 for guile-user@gnu.org; Thu, 04 Aug 2016 17:06:34 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bVPqU-00028i-Il for guile-user@gnu.org; Thu, 04 Aug 2016 17:06:30 -0400 Original-Received: from pb-sasl1.pobox.com ([64.147.108.66]:53061 helo=sasl.smtp.pobox.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bVPqU-00027y-C0 for guile-user@gnu.org; Thu, 04 Aug 2016 17:06:26 -0400 Original-Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by pb-sasl1.pobox.com (Postfix) with ESMTP id 159FD2EC39; Thu, 4 Aug 2016 17:06:22 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=xAQmNSCqPsdVyeZmXS4pc0XAfxA=; b=VM8r4T pixczIy+lWId9ByGM1Kh7MFzCpFbeJ9/hxX/EPvFyKQfc8dPXCtjw0qhdPShnDB1 aIaNL/MKBoeIL1ZeyV0DlZKDhGcWNXc/SavKMtaGIrixuNT5tcDkvY57APZBIWbT ZUsMjuYavb0yQDjz6bDLHWkuqeb8UmTrmrpcE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=Rbnt22Uuf3kPAxXZGFSS1lzc93mPA8Z1 518dhTz8j8bt3SCCtAStLUyJiv5IChFuW/lajYXlKOGLMAnn44Md8KLkxNTk82Ul RRNi91bPZfCLhZ0IiQE5JE7hyBxQpztjRbw5ri+0sQRurc/R3EYUtw9ZpCj5f7L0 Hb5OCi5TvXw= Original-Received: from pb-sasl1.nyi.icgroup.com (unknown [127.0.0.1]) by pb-sasl1.pobox.com (Postfix) with ESMTP id 0DA772EC38; Thu, 4 Aug 2016 17:06:22 -0400 (EDT) Original-Received: from clucks (unknown [88.160.190.192]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by pb-sasl1.pobox.com (Postfix) with ESMTPSA id AC66D2EC37; Thu, 4 Aug 2016 17:06:20 -0400 (EDT) In-Reply-To: (Panicz Maciej Godek's message of "Wed, 6 Jul 2016 22:01:52 +0200") X-Pobox-Relay-ID: 4B17978C-5A87-11E6-9017-C1836462E9F6-02397024!pb-sasl1.pobox.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 64.147.108.66 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.org gmane.lisp.guile.user:12819 Archived-At: --=-=-= Content-Type: text/plain On Wed 06 Jul 2016 22:01, Panicz Maciej Godek writes: > I've been trying to cooperate with guile-cairo. However, the documentation > serves as a reference rather than a tutorial, and I've been trying to agree > the tutorial from the Cairo website with guile bindings, to no avail. Attached is a part of guile-present that uses cairo to render slides. I think I need to find guile-present a new home, as gitorious went away... Andy --=-=-= Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename=cairo.scm Content-Transfer-Encoding: quoted-printable ;; guile-present ;; Copyright (C) 2007, 2009, 2010, 2011, 2012, 2014 Andy Wingo ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either ;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; Lesser General Public License for more details. ;; ;; You should have received a copy of the GNU Lesser General Public ;; License along with this library; if not, see ;; . ;;; Commentary: ;; ;; Routines to render SXML documents from the presentation vocabulary ;; using the Cairo graphics library. ;; ;;; Code: (define-module (present cairo) #:use-module (cairo) #:use-module (present fold) #:use-module (ice-9 match) #:export (presentation-render-cairo)) (define rsvg-handle-render-cairo #f) (define rsvg-handle-new-from-file #f) (define rsvg-handle-get-dimensions #f) (cond ((resolve-module '(rsvg) #:ensure #f) =3D> (lambda (mod) (set! rsvg-handle-render-cairo (module-ref mod 'rsvg-handle-render-cairo)) (set! rsvg-handle-new-from-file (module-ref mod 'rsvg-handle-new-from-file)) (set! rsvg-handle-get-dimensions (module-ref mod 'rsvg-handle-get-dimensions)))) (else (let () (define (no-rsvg . args) (warn "SVG support not available. Install guile-rsvg.")) (set! rsvg-handle-render-cairo no-rsvg) (set! rsvg-handle-new-from-file no-rsvg) (set! rsvg-handle-get-dimensions no-rsvg)))) (define jpeg-dimensions #f) (define jpeg->rgb #f) (define interleaved-image-buffer #f) (cond ((resolve-module '(jpeg) #:ensure #f) =3D> (lambda (mod) (set! jpeg-dimensions (eval 'jpeg-dimensions mod)) (set! jpeg->rgb (eval 'jpeg->rgb mod)) (set! interleaved-image-buffer (eval 'interleaved-image-buffer mod))= )) (else (let () (define (no-jpeg . args) (warn "JPEG support not available. Install guile-jpeg.")) (set! jpeg-dimensions no-jpeg) (set! jpeg->rgb no-jpeg) (set! interleaved-image-buffer no-jpeg)))) (define (fold-cairo cr tree bindings params layout stylesheet) (define (munge-bindings bindings) (define (munge-post-proc p) (lambda (tag params layout klayout kids) (values (p cr tag params layout klayout) (if (null? (car params)) (cons tag kids) (cons* tag (cons '@ (car params)) kids))))) (define (munge-pre-layout-proc p) (lambda (tag params layout) (p cr tag params layout))) (define (munge-text-proc p) (lambda (text params layout) (values (p cr text params layout) text))) (define (munge-handler h) (case (car h) ((post) (cons 'post (munge-post-proc (cdr h)))) ((pre-layout) (cons 'pre-layout (munge-pre-layout-proc (cdr h)))) ((bindings) (cons 'bindings (munge-bindings (cdr h)))) (else h))) (define (munge-binding b) (case (car b) ((*text*) (cons '*text* (munge-text-proc (cdr b)))) (else (cons (car b) (map munge-handler (cdr b)))))) (map munge-binding bindings)) (call-with-values (lambda () (fold-layout tree (munge-bindings bindings) params layout stylesheet)) (lambda (ret layout) layout))) ;; Probably, more of this could be public. (define* (lookup params key #:optional (default-thunk (lambda () (error "unbound param" key)))) (cond ((null? params) (default-thunk)) ((assq key (car params)) =3D> cadr) (else (lookup (cdr params) key default-thunk)))) (define-syntax let-params (syntax-rules () ((_ (param-exp ...) (k ...) b b* ...) (let ((p (param-exp ...))) (let-params p (k ...) b b* ...))) ((_ params () b b* ...) (begin b b* ...)) ((_ params ((k default) k* ...) b b* ...) (let ((k (lookup params 'k (lambda () default)))) (let-params params (k* ...) b b* ...))) ((_ params (k k* ...) b b* ...) (let ((k (lookup params 'k))) (let-params params (k* ...) b b* ...))))) (define* (make-layout left top x line-height #:optional (space 0)) (vector left top x line-height space)) (define (layout-left layout) (vector-ref layout 0)) (define (layout-top layout) (vector-ref layout 1)) (define (layout-x layout) (vector-ref layout 2)) (define (layout-line-height layout) (vector-ref layout 3)) (define (layout-space layout) (vector-ref layout 4)) (define (layout-beginning-of-line? layout) (=3D (layout-x layout) (layout-left layout))) (define (layout-indent layout indent) (make-layout (+ (layout-left layout) indent) (layout-top layout) (+ (layout-left layout) indent) (layout-line-height layout))) (define (layout-scroll layout scroll) (make-layout (layout-left layout) (+ (layout-top layout) scroll) (layout-left layout) (layout-line-height layout))) (define (layout-next-line layout line-spacing) (layout-scroll layout (* (layout-line-height layout) line-spacing))) (define (layout-enter layout line-height) (make-layout (layout-left layout) (layout-top layout) (layout-left layout) line-height)) (define (layout-return layout block-spacing line-spacing) (if (layout-beginning-of-line? layout) layout (layout-next-line layout (* block-spacing line-spacing)))) (define* (layout-advance layout dx #:optional (space 0)) (make-layout (layout-left layout) (layout-top layout) (+ (layout-x layout) dx) (layout-line-height layout) space)) (define (layout-ensure-space layout space) (if (layout-beginning-of-line? layout) layout (layout-advance layout 0 (max (layout-space layout) space)))) (define (layout-apply-space layout) (layout-advance layout (layout-space layout))) (define (default-pre-layout cr tree params layout) (let-params params (inline? absolute? margin-left margin-top text-height text-scaling) (cond (inline? layout) (absolute? (make-layout margin-left margin-top margin-left (* text-height text-scaling))) (else (and layout (layout-enter layout (* text-height text-scaling))))= ))) (define (default-post cr tag params old-layout layout) (let-params params (inline? absolute? block-spacing line-spacing) (cond (inline? layout) (absolute? old-layout) (else (layout-return layout block-spacing line-spacing))))) (define (specialize-param params k v) (cons (list (list k v)) params)) (define (text-x-advance cr text) (cairo-text-extents:x-advance (cairo-text-extents cr text))) (define *punctuation* '(("``" . "=E2=80=9C") ("''" . "=E2=80=9D") ("`" . "=E2=80=98") ("'" . "=E2=80=99") ("---" . "=E2=80=94") ("--" . "=E2=80=93"))) (define (prettify-punctuation word) (let lp ((word word) (punctuation *punctuation*)) (match punctuation (() word) (((needle . replacement) . punctuation) (cond ((string-contains word needle) =3D> (lambda (pos) (lp (string-append (substring word 0 pos) replacement (substring word (+ pos (string-length needle)))) punctuation))) (else (lp word punctuation))))))) (define *subword-charset* (char-set #\/ #\- )) (define (find-subword-right word end) (let ((tail (string-index-right word (char-set-complement *subword-charset*) 0 end))) (and tail (and=3D> (string-index-right word *subword-charset* 0 tail) 1+)))) (define* (next-subword cr word available #:optional (end (string-length wor= d))) (let* ((subword-end (find-subword-right word end)) (end (or subword-end end))) (let* ((subword (substring word 0 end)) (width (text-x-advance cr subword))) (if (or (< width available) (not subword-end)) (values subword width) (next-subword cr word available end))))) (define (terminal? word) (case (string-ref word (1- (string-length word))) ((#\. #\! #\?) #t) (else #f))) (define (flow-text cr params layout text) (let-params params (text-height text-scaling font-family line-spacing wid= th margin-right font-weight font-slant pretty-punctuatio= n? can-end-sentence?) (define (maybe-prettify word) (if pretty-punctuation? (prettify-punctuation word) word)) (cairo-select-font-face cr font-family font-slant font-weight) (cairo-set-font-size cr (* text-height text-scaling)) (let ((space-width (text-x-advance cr " "))) (let render ((text text) (layout layout)) (cond ((string-null? text) ;; Done. layout) ((char-whitespace? (string-ref text 0)) ;; Interword space. (render (substring text 1) (layout-ensure-space layout space-widt= h))) ;; Print a word at a time. Ignore whitespace; interword spacing ;; is uniform, except a little bit more after a terminator (.?!). (else (let* ((word-end (or (string-index text char-whitespace?) (string-length text))) (word (maybe-prettify (substring text 0 word-end)))) (let retry ((word word) (subword? #f) (text (substring text word-end)) (word-width (text-x-advance cr word)) (layout (layout-apply-space layout)) (force? #f)) (cond ((and (> (+ (layout-x layout) word-width) (- width margin-ri= ght)) (not force?)) ;; Word doesn't fit. (let ((available (- width margin-right (layout-x layout)))) (call-with-values (lambda () (next-subword cr word available)) (lambda (subword subword-width) (if (or (layout-beginning-of-line? layout) (< subword-width available) (string-every char-set:punctuation word)) (let ((tail (substring word (string-length subwor= d)))) (retry subword #t (string-append tail text) subword-width layout #t)) (retry word subword? text word-width (layout-next-line layout line-spacing) #f)))))) (else (cairo-move-to cr (layout-x layout) (+ (layout-top layout) (layout-line-height layout))) (cairo-show-text cr word) (render text (layout-advance layout word-width (cond ((or subword? (string-null? text))= 0) ((and can-end-sentence? (terminal? word)) (* 1.5 space-width)) (else space-width)))))))))))))) (define (verbatim-text cr params layout text) (let-params params (text-height text-scaling font-family line-spacing font-weight font-slant) (cairo-select-font-face cr font-family font-slant font-weight) (cairo-set-font-size cr (* text-height text-scaling)) (let lp ((lines (string-split text #\newline)) (layout layout)) (cairo-move-to cr (layout-x layout) (+ (layout-top layout) (layout-line-height layout))) (cairo-show-text cr (car lines)) (if (null? (cdr lines)) (layout-advance layout (text-x-advance cr (car lines))) (lp (cdr lines) (layout-next-line layout line-spacing)))))) (define (text-handler cr text params layout)=20 (let-params params (verbatim?) ((if verbatim? verbatim-text flow-text) cr params layout text))) (define (ul-pre-layout cr tree params layout) (let-params params (indent-width text-height text-scaling) (layout-enter (layout-indent layout indent-width) (* text-height text-scaling)))) (define (ul-post cr tag params old-layout layout) (let-params params (indent-width block-spacing line-spacing) (layout-return (layout-indent layout (- indent-width)) block-spacing line-spacing))) (define (make-bullet cr params layout) (let-params params (bullet-string bullet-font-family) (flow-text cr (specialize-param params 'font-family bullet-font-family) layout bullet-string))) (define (li-post cr tag params old-layout layout) (let-params params (indent-width) (make-bullet cr params (layout-indent old-layout (- indent-width))) (default-post cr tag params old-layout layout))) (define (title-pre-layout cr tree params layout) (let-params params (margin-top text-height text-scaling) ;; go to the middle of the page? (layout-enter (layout-scroll layout margin-top) (* text-height text-scaling)))) (define (image-width-for-height filename target-height) (cond ((string-suffix? ".svg" (string-downcase filename)) (call-with-values (lambda () (rsvg-handle-get-dimensions (rsvg-handle-new-from-file filename))) (lambda (width height em ex) (* target-height 1.0 (/ width height))))) ((string-suffix? ".png" (string-downcase filename)) (let ((surf (cairo-image-surface-create-from-png filename))) (* target-height 1.0 (/ (cairo-image-surface-get-width surf) (cairo-image-surface-get-height surf))))) ((or (string-suffix? ".jpg" (string-downcase filename)) (string-suffix? ".jpeg" (string-downcase filename))) (call-with-values (lambda () (jpeg-dimensions filename)) (lambda (width height) (* target-height 1.0 (/ width height))))) (else (error "unknown image type" filename)))) (define (create-image-surface filename target-width target-height) (cond ((string-suffix? ".svg" (string-downcase filename)) (let ((surf (cairo-image-surface-create 'argb32 target-width target-hei= ght))) (let ((cr (cairo-create surf))) (rsvg-handle-render-cairo (rsvg-handle-new-from-file filename) cr) (cairo-surface-flush surf) (values surf target-width target-height)))) ((string-suffix? ".png" (string-downcase filename)) (let ((surf (cairo-image-surface-create-from-png filename))) (values surf (cairo-image-surface-get-width surf) (cairo-image-surface-get-height surf)))) ((or (string-suffix? ".jpg" (string-downcase filename)) (string-suffix? ".jpeg" (string-downcase filename))) (call-with-values (lambda () (jpeg-dimensions filename)) (lambda (width height) (let* ((stride (cairo-format-stride-for-width 'rgb24 width)) (rgb (jpeg->rgb filename #:argb? #t #:stride-for-width (lambda (_) stride)))) (values (cairo-image-surface-create-for-data (interleaved-image-buffer rgb) 'rgb24 width height stride) width height))))) (else (warn "unknown image type" filename) (values #f #f #f)))) (define* (paint-image cr filename x0 y0 width height #:key stretch? (center-horizontally? #t) (center-vertically? #t)) (define (scale-dimensions aspect) (cond (stretch? (values x0 y0 width height)) ((< aspect (/ width height)) ;; Tall source. (let ((new-width (* height aspect))) (values (if center-horizontally? (+ x0 (/ (- width new-width) 2)) x0) y0 new-width height))) (else ;; Wide source. (let ((new-height (/ width aspect))) (values x0 (if center-vertically? (+ y0 (/ (- height new-height) 2)) y0) width new-height))))) (call-with-values (lambda () (create-image-surface filename width height)) (lambda (surface swidth sheight) (if surface (call-with-values (lambda () (scale-dimensions (/ swidth 1.0 shei= ght))) (lambda (x0 y0 width height) (cairo-save cr) (cairo-translate cr x0 y0) (cairo-scale cr (/ width swidth) (/ height sheight)) (cairo-set-source-surface cr surface 0 0) (cairo-pattern-set-filter (cairo-get-source cr) 'best) (cairo-rectangle cr 0 0 swidth sheight) (cairo-fill cr) (cairo-restore cr) (values width height))) (values 0 0))))) (define (image-post cr tag params old-layout layout) (let-params params (image-filename (image-width #f) (image-height #f) height width margin-right margin-bottom inline? text-height text-scaling line-spacing) (cond (inline? ;; An image in a text block: restrict to the line height. (let* ((layout (layout-apply-space layout)) (avail-x (- width margin-right (layout-x layout))) (width-for-height (image-width-for-height image-filename (* text-height text-scaling))) (layout (if (< avail-x width-for-height) (layout-next-line layout line-spacing) layout))) (paint-image cr image-filename (layout-x layout) (layout-top layout) width-for-height (* text-height text-scaling) #:stretch? #t) (layout-advance layout width-for-height))) (else ;; An image at the top level: horizontally center in available ;; space. (let* ((avail-x (- width margin-right (layout-x layout))) (avail-y (- height (layout-top layout) margin-bottom)) (max-width (or image-width avail-x)) (max-height (or image-height avail-y)) (x0 (+ (layout-x layout) (/ (- avail-x max-width) 2.0)))) (call-with-values (lambda () (paint-image cr image-filename x0 (layout-top layout) max-width max-height #:center-vertically? #f)) (lambda (width height) (layout-scroll layout height)))))))) (define (set-source-rgb cr rgb) (cairo-set-source-rgb cr (/ (logand (ash rgb -16) #xff) 255.0) (/ (logand (ash rgb -8) #xff) 255.0) (/ (logand (ash rgb 0) #xff) 255.0))) (define (slide-pre-layout cr tree params layout) (let-params params (margin-left margin-top background background-color foreground-color width height text-height text-scalin= g) (set-source-rgb cr background-color) (cairo-rectangle cr 0 0 width height) (cairo-fill cr) (when background (paint-image cr background 0 0 width height)) (set-source-rgb cr foreground-color) (make-layout margin-left margin-top margin-left (* text-height text-scaling)))) (define (slide-post cr tag params old-layout layout) (cairo-show-page cr) old-layout) (define (presentation-post cr tag params old-layout layout) old-layout) (define *presentation->svg-rules* `((presentation (post . ,presentation-post)) (slide (pre-layout . ,slide-pre-layout) (post . ,slide-post)) (title (pre-layout . ,title-pre-layout)) (image (post . ,image-post)) (ul (pre-layout . ,ul-pre-layout) (post . ,ul-post)) (li (post . ,li-post)) (*text* . ,text-handler) (*default* (pre-layout . ,default-pre-layout) (post . ,default-post)))) (define *default-params* '((indent-width 64) (margin-left 64) (margin-right 64) (margin-top 64) (margin-bottom 64) (line-spacing 1.1) (inline? #f) (absolute? #f) (can-end-sentence? #t) (verbatim? #f) (pretty-punctuation? #t) (block-spacing 1.4) (font-family "Serif") (font-slant normal) (font-weight normal) (bullet-string "=E2=9D=A7") (bullet-font-family "Sans") (text-height 42) (text-scaling 1/1) (background #f) (background-color #xFFFFFF) (foreground-color #x000000) (width 1024) (height 768))) (define *null-layout* #f) (define *presentation-stylesheet* '((title (text-height 96)) (header (text-height 64)) (tt (font-family "Monospace") (inline? #t) (can-end-sentence? #f) (pretty-punctuation? #f) (text-height 36)) (pre (font-family "Monospace") (verbatim? #t) (pretty-punctuation? #f) = (text-height 36) (line-spacing 1.2)) (span (inline? #t)) (image (inline? #t)) (i (font-slant italic) (inline? #t)) (b (font-weight bold) (inline? #t)))) (define (adjoin-stylesheets presentation stylesheet) (define (adjoin tag key value stylesheet) (match stylesheet (() `((,tag (,key ,value)))) (((t . params) . stylesheet) (if (eq? t tag) `((,t (,key ,value) . ,params) . ,stylesheet) (acons t params (adjoin tag key value stylesheet)))))) (match presentation (('presentation ('@ . params) . body) (let lp ((in params) (out '()) (stylesheet stylesheet)) (match in (() (values `(presentation (@ ,@(reverse out)) . ,body) stylesheet)) (((and param (tag key value)) . in) (lp in out (adjoin tag key value stylesheet))) ((param . in) (lp in (cons param out) stylesheet))))) (_ (values presentation stylesheet)))) (define (presentation-render-cairo presentation cr) "Convert an SXML document in the @code{presentation} vocabulary to a multi-layered SVG. The result will still be a document in SXML format, so if you want to write it to disk, use @code{sxml->xml}. @xref{sxml simple,(sxml simple),(sxml simple),guile-library,Guile Library}, for more information. The resulting SVG will be written with annotations readable by Inkscape, a vector graphics editor, which help to make the SVG easily editable. If your toolchain does not understand namespaces, you might want to filter out elements that start with @samp{sodipodi:}, @samp{xmlns:}, and @samp{inkscape:}. " (call-with-values (lambda () (adjoin-stylesheets presentation *presentation-stylesheet*)) (lambda (presentation stylesheet) (fold-cairo cr presentation *presentation->svg-rules* *default-params* *null-layout* stylesheet)))) --=-=-=--