#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 ) ) ) )