You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
typesetting/quad/fontproof/main.rkt

116 lines
5.4 KiB
Racket

#lang debug racket/base
(require quadwriter/core
racket/date
racket/file
racket/string
racket/list
racket/match
racket/path
txexpr
quad/qexpr)
(provide (all-defined-out))
(define-logger fontproof)
(define (increment-path path)
(for*/first ([i (in-naturals 2)]
[incremented-path (in-value
(path-replace-extension path
(string->bytes/utf-8
(format " ~a~a.pdf" (if (< i 10) "0" "") i))))]
#:unless (file-exists? incremented-path))
incremented-path))
(define (boolean->string bool) (if bool "true" "false"))
(define font-file-extensions '(#".otf" #".ttf" #".woff"))
(define (font-path-string? x)
(and (path-string? x)
(member (path-get-extension (string->path x)) font-file-extensions)
#true))
(define (resolve-family-bold-italic font-name-arg)
(define bi-suffix-pat #px"\\s*((?i:bold))?\\s*((?i:italic))?$")
(match-define (list suffix bold? italic?) (regexp-match bi-suffix-pat font-name-arg))
(values (string-trim font-name-arg suffix #:left? #false) bold? italic?))
(define (make-proof font-or-qml [sample-text #f]
#:bold [make-bold #false]
#:italic [make-italic #false]
#:font-sizes [font-sizes-arg #false]
#:page-size [page-size-arg #false]
#:line-heights [line-heights-arg #false]
#:output-file-path [output-file-path-arg #false]
#:qml [output-qml? #true]
#:replace [replace #false])
(define-values (doc output-file-path)
(match font-or-qml
[(? qml-path? qml-ps)
(define doc (qml->qexpr (file->string qml-ps)))
(define output-file-path (path-replace-extension qml-ps #".pdf"))
(values doc output-file-path)]
[font-name-arg
(unless (and sample-text (non-empty-string? sample-text))
(raise-user-error "no text to proof; exiting"))
(define-values (initial-font-family initial-font-bold initial-font-italic)
(match font-name-arg
[(? font-path-string? ps) (values (path->string (path->complete-path ps)) #f #f)]
[_ (resolve-family-bold-italic font-name-arg)]))
(log-fontproof-info (format "generating proof for ~a" font-name-arg))
(define page-size (or page-size-arg "letter"))
(define font-sizes (string-split (or font-sizes-arg "12 10.5 9")))
(define line-heights (string-split (or line-heights-arg "1.25em")))
(define bold-variants (cond
[initial-font-bold '(#t)]
[make-bold '(#f #t)]
[else '(#f)]))
(define italic-variants (cond
[initial-font-italic '(#t)]
[make-italic '(#f #t)]
[else '(#f)]))
(when (and initial-font-bold make-bold)
(log-fontproof-info (format "starting font is bold; omitting bold proof~a" (match (length italic-variants) [2 "s"] [_ ""]))))
(when (and initial-font-italic make-italic)
(log-fontproof-info (format "starting font is italic; omitting italic proof~a" (format "starting font is bold; omitting bold proof~a" (match (length italic-variants) [2 "s"] [_ ""])))))
(define doc-interior
(cons 'q
(add-between
(for*/list ([font-size (in-list font-sizes)]
[font-bold (in-list bold-variants)]
[font-italic (in-list italic-variants)]
[line-height (in-list line-heights)])
(attr-set*
(txexpr* 'q null sample-text)
'font-size font-size
'font-italic (boolean->string font-italic)
'font-bold (boolean->string font-bold)
'line-height line-height
'footer-text (format "~a test ~a/~a · ~a"
initial-font-family
font-size
line-height
(date->string (current-date) #t))))
page-break)))
(define doc (attr-set*
doc-interior
'page-size page-size
'page-margin-left "12p"
'page-margin-right "12p"
'font-family initial-font-family
'hyphenate "false"
'footer-display "true"))
(define output-file-path
(match (path->complete-path
(or output-file-path-arg
(build-path (find-system-path 'desk-dir)
(format "~a proof.pdf" font-name-arg))))
[(? file-exists? path) #:when (not replace) (increment-path path)]
[path path]))
(values doc output-file-path)]))
(begin0
(render-pdf doc output-file-path)
(when output-qml?
(define qml-path (path-replace-extension output-file-path #".qml"))
(call-with-output-file* qml-path
(λ (op) (display (qexpr->qml doc) op ))
#:exists 'replace))))