From 2f698e6cc976872afee51a0fd4a6510a54df1c18 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Tue, 27 Feb 2018 12:44:36 -0800 Subject: [PATCH] successful typewriter test --- quad/quad/typewriter-test.rkt | 26 +++++++++++++++++++++++- quad/quad/typewriter.rkt | 37 +++++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/quad/quad/typewriter-test.rkt b/quad/quad/typewriter-test.rkt index e968e78c..0fc9ea73 100644 --- a/quad/quad/typewriter-test.rkt +++ b/quad/quad/typewriter-test.rkt @@ -1,3 +1,27 @@ #lang quad/typewriter -a b cd ef g h \ No newline at end of file +To get started with Racket, download it from the web page and install it. If you are a beginner or would like to use a graphical environment to run programs, run the DrRacket executable. Otherwise, the racket executable will run a command-line Read-Eval-Print-Loop (REPL). + +On Windows, you can start DrRacket from the Racket entry in the Start menu. In Windows Vista or newer, you can just type DrRacket. You can also run it from its folder, which you can find in Program Files → Racket → DrRacket. + +On Mac OS, double click on the DrRacket icon. It is probably in a Racket folder that you dragged into your Applications folder. If you want to use command-line tools, instead, Racket executables are in the "bin" directory of the Racket folder (and if you want to set your PATH environment variable, you’ll need to do that manually). + +On Unix (including Linux), the drracket executable can be run directly from the command-line if it is in your path, which is probably the case if you chose a Unix-style distribution when installing. Otherwise, navigate to the directory where the Racket distribution is installed, and the drracket executable will be in the "bin" subdirectory. + +If you are new to programming or if you have the patience to work through a textbook: + +How to Design Programs is the best place to start. Whenever the book says “Scheme,” you can read it as “Racket.” + +Continue: Web Applications in Racket introduces you to modules and building web applications. + +The Racket Guide describes the rest of the Racket language, which is much bigger than the learning-oriented languages of the textbook. Since you learned functional programming from the textbook, you’ll be able to skim chapters 1 and 2 of the Guide. + +If you’re already a programmer and you’re in more of a hurry: + +Quick: An Introduction to Racket with Pictures gives you a taste of Racket. + +More: Systems Programming with Racket dives much deeper and much faster. If it’s too much, just skip to the Guide. + +The Racket Guide starts with a tutorial on Racket basics, and then it describes the rest of the Racket language. + +Of course, you should feel free to mix and match the above two tracks, since there is information in each that is not in the other. \ No newline at end of file diff --git a/quad/quad/typewriter.rkt b/quad/quad/typewriter.rkt index d9c6d406..69bffc6a 100644 --- a/quad/quad/typewriter.rkt +++ b/quad/quad/typewriter.rkt @@ -1,11 +1,12 @@ #lang debug br/quicklang -(require racket/promise racket/list sugar/debug "quad.rkt" "atomize.rkt" "wrap.rkt" "qexpr.rkt" "generic.rkt" "position.rkt") +(require racket/promise racket/list sugar/list sugar/debug "quad.rkt" "atomize.rkt" "wrap.rkt" "qexpr.rkt" "generic.rkt" "position.rkt") +(require pitfall/document) (provide (rename-out [mb #%module-begin])) (define optional-break? (λ (q) (and (quad? q) (memv (car (elems q)) '(#\space))))) (struct $shim $quad () #:transparent) (struct $char $quad () #:transparent) -(define (charify q) ($char (attrs q) (elems q))) +(define (charify q) ($char (hash-set (attrs q) 'size '(7.2 12)) (elems q))) (define (shimify xs) (add-between (map charify xs) (list ($shim (hasheq) null)) #:splice? #t @@ -16,11 +17,13 @@ (struct $doc $quad () #:transparent) (struct $break $quad () #:transparent) (define (break . xs) ($break (hasheq 'size '(0 0)) xs)) + +(define line-height 16) (define (lbs xs size [debug #f]) (wrap xs size debug #:break-val (break #\newline) #:optional-break-proc optional-break? - #:finish-segment-proc (λ (pcs) (list ($line (hasheq 'size '(0 12) 'out 'sw) (map charify pcs)))))) + #:finish-segment-proc (λ (pcs) (list ($line (hasheq 'size (list +inf.0 line-height) 'out 'sw) pcs))))) (define (pbs xs size [debug #f]) (wrap xs size debug @@ -29,11 +32,29 @@ #:finish-segment-proc (λ (pcs) (list ($page (hasheq) (filter-not $break? pcs)))))) (define (typeset args) - ($doc (hasheq) (map position (filter-not $break? (pbs (lbs (atomize (apply quad #f args)) 3) (* 5 12)))))) + (define chars 60) + (define line-width (* 7.2 chars)) + (define lines-per-page (* 40 line-height)) + (position ($doc (hasheq 'origin '(72 72)) (filter-not $break? (pbs (lbs (map charify (atomize (apply quad #f args))) line-width) lines-per-page))))) + -(define-syntax-rule (mb lang-line-config-arg . args) - (#%module-begin - (typeset (list . args)))) +(define-macro (mb . ARGS) + (with-pattern ([PS (syntax-property #'ARGS 'ps)]) + #'(#%module-begin + (define q (typeset (list . ARGS))) + ;q + (let () + (define doc (make-object PDFDocument (hasheq 'compress #f))) + (send doc pipe (open-output-file PS #:exists 'replace)) + (send doc font "Courier") + (send doc fontSize 12) + (let loop ([q q]) + (cond + [($char? q) + (send/apply doc text (apply string (elems q)) (origin q))] + [(quad? q) (map loop (elems q))])) + (send doc end) + (void))))) (module reader syntax/module-reader quad/typewriter @@ -48,4 +69,4 @@ (define quad-at-reader (make-at-reader #:syntax? #t #:inside? #t)) - (quad-at-reader path-string p))) \ No newline at end of file + (syntax-property (quad-at-reader path-string p) 'ps (path-replace-extension path-string #".pdf")))) \ No newline at end of file