(import (scheme base) (scheme char) (chibi) (chibi string) (chibi sxml) (srfi 1)) (include "barcode.scm") ; GUILE #;(use-modules (sxml simple) (srfi srfi-1)) ;; CONTENTS (define isbn "9780201379624") (define book-title "Programación en Python") (define book-subtitle "Introducción a la programación y al lenguaje") (define book-title-before "") ; TODO: Thinking about removing this (define book-title-word book-title) (define book-title-after book-subtitle) (define book-category "Básico") (define book-authors '("Giacomo Tesio" "Ekaitz Zarraga")) (define book-summary " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vitae rhoncus augue. Donec blandit ligula dui, vitae commodo sem sodales ac. Donec varius sed ipsum vitae gravida. Morbi nec ipsum quis sapien commodo lacinia. Sed at risus at nisl mollis consectetur ac non mauris. Pellentesque ipsum leo, accumsan scelerisque convallis ut, condimentum nec libero. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras pharetra rhoncus eros, eu auctor nibh sollicitudin quis. Praesent sodales ultricies ex. Aliquam erat volutpat. Donec aliquam faucibus enim sit amet facilisis. Pellentesque at pretium risus. Nullam ac vehicula purus, sed pharetra magna. Morbi mollis luctus nisi vel porta. Duis tempus erat eu ante congue consequat. In ac leo sem. Quisque bibendum bibendum rutrum. Fusce interdum in metus sed congue. Sed nunc mauris, mattis vitae fermentum eu, dignissim vitae nulla. Donec blandit at mi eu luctus. Fusce pharetra ipsum fringilla quam faucibus, ut lobortis risus varius. Ut nec sem lectus. Integer porta justo a augue sodales, nec malesuada libero varius. Sed convallis cursus efficitur. Cras maximus, ligula et dapibus ultrices, sapien lectus pellentesque purus, nec dignissim augue dolor eu ligula. Morbi consequat fringilla mauris, vitae aliquet metus sodales in. ") (define company-info "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; UTILS ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define num number->string) (define (mm x) ; add mm mark (string-append (num x) "mm")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DEFINITIONS ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SIZE ; Take spine from the outside because it's related to the amount of pages (define spine-width 5) ;mm (define spine-title-margin-min (* 0.1 spine-width)) (define spine-title-max-size 10) (define spine-title-size (let ((size (- spine-width (* 2 spine-title-margin-min)))) (if (> size spine-title-max-size) spine-title-max-size size))) ;B5 Paper size (define page-height 250) ;mm (define page-width 176) ;mm (define margin 3) ;mm (define text-size (exact->inexact (/ page-height 70))); mm (define category-size (* 1.5 text-size)); mm (define authors-size (* 1.8 text-size)) (define title-size (* 2.5 text-size)); mm (define main-title-size ; mm (let ((size (exact->inexact (* 3 (/ page-width (length (string->list book-title-word))))))) (if (< (/ page-height 4) size) (exact->inexact (/ page-height 4)) size))) (define main-subtitle-size (* 2 text-size)) (define width (+ (* 2 margin) (* 2 page-width) spine-width)) ;mm (define height (+ (* 2 margin) page-height)) ;mm (define viewBox (string-append "0 0 " (num width) " " (num height))) ; INFO: Setting viewbox and size to the same it makes the measurements real ; world ones, in this case millimeters ; Read more: https://mpetroff.net/2013/08/analysis-of-svg-units/ (define (elenq-logo sub size x y . extra) ; 10 x 4mm `(g (@ (id "elenq-logo") (transform ,(string-append "translate(" (num x) "," (num y) ")" "scale(" (num size) ")" (if (< 0 (length extra)) (string-append "rotate (" (num (first extra)) ")") "") ))) (g (@ (transform "scale(0.1667)")) (text (@ (x 0) (y 0) (style "font-size: 30; line-height: 1.25; font-family: armata; stroke: none; text-anchor: middle")) "ElenQ") (text (@ (x 0) (y 8) (style "font-size: 10; line-height: 1.25; font-family: armata; stroke: none; text-anchor: middle;")) ,sub)))) ;(define elenq-technology (elenq-logo "TECHNOLOGY" 1 0 0)) ;(define elenq-publishing (elenq-logo "PUBLISHING" 1 0 0)) (define style (string-append " .margin-mark { stroke-width: 0.1; stroke-linecap: butt; stroke: red; } .title-back { font-family: 'Pathway Gothic One'; font-size: "(num title-size)"; fill: white; } .title-spine { font-family: 'Pathway Gothic One'; font-size: "(num spine-title-size)"; dominant-baseline: mathematical; fill: black; } .authors-spine { font-family: 'Lato'; font-size: "(num text-size)"; dominant-baseline: mathematical; text-anchor: end; } #black-part { fill: black; } .text-elenq{ font-family:Lato; -inkscape-font-specification:'Lato Light Italic'; font-style: italic; font-weight: 300; fill: black; font-size: "(num text-size)"; text-align: justify; } .text-summary { font-family:Lato; font-size: "(num text-size)"; fill: white; text-align: justify; } rect.category{ fill: black; } text.category{ fill: white; font-size: "(num category-size)"; -inkscape-font-specification:'Lato Light'; font-family:Lato; font-weight: 300; } .main-title { font-size: "(num main-title-size)"; font-family: 'Pathway Gothic One'; } .main-title-before { font-size: "(num (* 1 title-size))"; font-family: 'Pathway Gothic One'; font-weight:300; } .main-title-after { font-size: "(num main-subtitle-size)"; -inkscape-font-specification:'Lato Light Italic'; line-height: 0.9; font-style: italic; font-family:Lato; font-weight: 300; text-anchor: end; } .author { font-size: "(num authors-size)"; font-family:Lato; font-style:normal; font-stretch:normal; font-variant:normal; text-anchor: end; } ")) ; Text area, Inkscape-only svg parameter (define (textArea text class x y w h) `(flowRoot (@ (class ,class)) (flowRegion (rect (@ (width ,w) (height ,h) (x ,x) (y ,y)))) ,(map (lambda (p) `(flowPara ,p)) (reverse (fold (lambda (s acc) (if (string=? s "") (cons "" acc) (let* ((prev (car acc)) (val (string-append prev (if (string=? "" prev) "" " ") s))) (cons val (cdr acc))))) (list "") (string-split text #\newline)))))) (display "") (display (sxml->xml `(svg (@ (width ,(mm width)) (height ,(mm height)) (viewBox ,viewBox)) (defs (style ,style)) ; BLACK BACKGROUND FOR SUMMARY (g (@ (transform ,(string-append ; TODO extender lo negro en el margen "translate( 0," (num (+ margin (* 0.05 page-height))) ") scale(" (num (+ margin (* 0.95 page-width))) ")"))) (path (@ (id "black-part") (d "M 1.00, 0.10 L 0.30, 0.00 L 0.00, 0.16 L 0.00, 0.67 L 0.45, 0.76 L 0.97, 0.67 Z")))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; CUTTING MARKS ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ,(map (lambda (posx posy rot) `(g (@ (id ,(string-append "marks-" (num posx) "-" (num posy))) (transform ,rot)) (line (@ (x1 ,(+ posx)) (y1 ,(+ posy margin)) (x2 ,(+ posx (* 0.6 margin))) (y2 ,(+ posy margin)) (class "margin-mark"))) (line (@ (x1 ,(+ posx margin)) (y1 ,(+ posy)) (x2 ,(+ posx margin)) (y2 ,(+ posy (* 0.6 margin))) (class "margin-mark"))))) (list 0 0 width width) (list 0 height 0 height) (list "rotate(0,0,0)" (string-append "rotate(-90, 0," (num height) ")") (string-append "rotate(-270," (num width) ", 0)") (string-append "rotate(-180," (num width) "," (num height) ")"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; BACK SIDE ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TITLE + BOOK SUMMARY (text (@ (class "title-back") (x ,(+ margin (* 0.15 page-width))) (y ,(+ margin (* page-height 0.20)))) ,(string-upcase book-title)) ,(textArea book-summary "text-summary" (+ margin (* 0.15 page-width)) (+ margin (* page-height 0.20)) (* 0.7 page-width) (* 0.25 page-height)) ; LOGO + ELENQ SUMMARY ,(elenq-logo "TECHNOLOGY" 3 (* (+ (+ margin (* 0.5 page-width)) (+ margin (* 0.5 page-width) (- (* 0.5 page-width) (* 0.1 page-width)))) 0.5) (+ margin (* 0.70 page-height) -10)) ,(textArea company-info "text-elenq" (+ margin (* 0.5 page-width)) (+ margin (* 0.70 page-height)) (- (* 0.5 page-width) (* 0.1 page-width)) (- (* 0.25 page-height) (* 0.1 page-height))) ; BARCODE ,(barcode-sxml isbn (+ margin (* 0.1 page-width)) (+ margin (* 0.75 page-height)) (* 0.25 page-width)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SPINE ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ,(let ((x (+ margin page-width)) (y height) (width (+ margin margin page-height)) (height spine-width)) `(g (@ (transform ,(string-append "translate(" (num x) "," (num y) ") rotate (-90)"))) (rect (@ (height ,height) (width ,width) (style "fill: white;"))) (text (@ (class "title-spine") (x ,(* 0.2 width)) (y ,(* 0.5 spine-width)) (width ,(* 0.3 width)) (height ,spine-title-size)) ,book-title) (text (@ (class "authors-spine") (x ,(* 0.9 width)) (y ,(* 0.5 spine-width)) (width ,(* 0.3 width)) (height ,spine-title-size)) ,(string-join book-authors ", ")))) ,(if (< spine-width 10) ; Smaller than 10mm -> Renders just a Q `(text (@ (style ,(string-append "font-family: armata; text-anchor: middle; font-size: " (num spine-width))) (x ,(+ margin page-width (* 0.5 spine-width))) (y ,(+ margin (* 0.95 page-height)))) "Q") (elenq-logo "PUBLISHING" ; Max logo size is as the spine was 40mm thick (* (if (< 40 spine-width) 40 spine-width) 0.1 0.75) (+ margin page-width (* 0.5 spine-width)) ;anchor is centered (+ margin (* 0.95 page-height)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; FRONT SIDE ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ,(let* ((win (* 0.35 page-width)) (w (+ win margin)) (h (* 1.5 category-size)) (x (- width margin win)) (y (+ margin (* 0.15 page-height)))) `(g (rect (@ (class "category") (x ,x) (y ,y) (width ,w) (height ,h))) (text (@ (class "category") (x ,(+ x (* 0.10 w))) (y ,(+ y (* 0.75 h))) (w ,w) (h ,h)) ,book-category))) (text (@ (class "main-title-before") (x ,(exact->inexact (- width (- page-width (/ page-width 8)) margin))) (y ,(+ margin (* 0.30 page-height)))) ,book-title-before) (text (@ (class "main-title") (textLength ,(* page-width 6/8)) (lengthAdjust ,"spacingAndGlyphs") (x ,(exact->inexact (- width (- page-width (/ page-width 8)) margin))) (y ,(+ main-title-size margin (* 0.30 page-height)))) ,(string-upcase book-title-word)) #;(text (@ (class "main-title-after") (x ,(exact->inexact (- width (/ page-width 8) margin))) (y ,(+ main-title-size (* 1.25 title-size) margin (* 0.30 page-height)))) ,book-title-after) ; TODO WORK ON THIS ,(textArea book-title-after "main-title-after" (exact->inexact (- width (- page-width (/ page-width 8)) margin)) (+ main-title-size (* main-subtitle-size 0.5) margin (* 0.30 page-height)) (* page-width 6/8) (* 2 1.25 main-subtitle-size)) ,(map (lambda (author pos) `(text (@ (class "author") (x ,(exact->inexact (- width (/ page-width 8) margin))) (y ,(+ main-title-size margin (* 0.35 page-height) (* (+ 2 pos) (* 1.5 authors-size))))) ,author)) book-authors (iota (length book-authors))) ,(elenq-logo "PUBLISHING" 3 (exact->inexact (- width (/ page-width 2) margin)) (+ margin (* 0.95 page-height))))))