(module slides racket
(require scribble/core scribble/base scribble/html-properties scribble/decode scriblib/render-cond)
(require "common.rkt")
(require setup/dirs)
(require scribble/decode)
(require (planet jaymccarthy/sqlite))
(require racket/vector)
(require racket/list)
(require racket/dict)
(require racket/system racket/file)
(require racket/provide-syntax)
(require (prefix-in xml: xml) (prefix-in xml: xml/path))
(provide (struct-out bystro))
(struct bystro (
formula-processor
formula-database-name
formula-dir-name
formula-size
autoalign-adjust
manual-base-alignment
)
#:mutable)
(provide (contract-out
[bystro-conf bystro?]))
(define bystro-conf (bystro (find-executable-path "amkhlv-java-formula.sh")
"formulas.sqlite"
"formulas"
25
1
(- 2)
))
(define slide-part-number 0)
(define slide-number 0)
(define slidename "SLIDE")
(define content '())
(define formulanumber 0)
(define formula-ref-dict '())
(define singlepage-mode #f)
(define running-database #f)
(define (bystro-css-element-from-file filename)
(make-element
(make-style #f (list (make-css-addition filename))) '())
)
(provide (contract-out
[bystro-titlepage-init (->* () (#:singlepage-mode boolean?) element?)]))
(define (bystro-titlepage-init #:singlepage-mode [spm #f])
(if spm
(begin
(set! singlepage-mode #t)
(bystro-css-element-from-file "misc.css")
(bystro-css-element-from-file "slide.css")
)
(bystro-css-element-from-file "slide-title.css")
)
)
(provide (contract-out
[bystro-afterpause (->* ()
(#:tag (or/c symbol? string? #f))
#:rest (listof (or/c part? pre-flow?) )
(or/c part? nested-flow?))]))
(define (bystro-afterpause #:tag [tg #f] . more-content)
(set! slide-part-number (+ 1 slide-part-number))
(when (pair? more-content)
(set! content (append content more-content )))
(let ([ stl (if (slide-part-number . < . 2)
(list 'non-toc 'no-toc 'unnumbered 'hidden 'hidden-number 'quiet)
(list 'non-toc 'no-toc 'unnumbered 'hidden 'toc-hidden 'hidden-number 'quiet))]
[ nm (if (slide-part-number . < . 2)
slidename
(if (pair? slidename)
(append slidename (list " " (number->string slide-part-number)))
(string-append slidename " " (number->string slide-part-number))))]
[ tgs (if tg (list (list 'part tg)) (list)) ]
)
(if singlepage-mode
(decode (list
(title-decl
#f
tgs
#f
(style
#f
(list 'non-toc 'no-toc 'unnumbered 'hidden 'toc-hidden 'hidden-number 'quiet))
"")
more-content))
(decode (list
(title-decl #f tgs #f (style #f stl) nm)
(decode content))))))
(provide (contract-out
[bystro-remove (-> void?)]))
(define (bystro-remove)
(if (pair? content)
(set! content (reverse (cdr (reverse content))))
(error "nothing to remove !")))
(define (fn-to-collect-slide-link slide-shortname slide-title slide-num)
(lambda (ci)
(collect-put! ci `(amkhlv-slide ,slide-shortname ,slide-num) slide-title)))
(provide (contract-out
[bystro-slide (->* (content?)
(#:tag (or/c symbol? string? #f) #:showtitle boolean?)
#:rest (listof (or/c pre-flow? part-start?) )
(or/c part? nested-flow?))]))
(define (bystro-slide stitle #:tag [tg #f] #:showtitle [sttl #f] . init-content)
(set! slide-number (+ 1 slide-number))
(set! slide-part-number 0)
(set! slidename (if tg
tg
(string-replace stitle " " "_")))
(if singlepage-mode
(decode (list
(title-decl
#f
(if tg (list (list 'part tg)) (list))
#f
(style #f (list 'non-toc 'no-toc 'unnumbered 'hidden 'hidden-number 'quiet))
stitle)
(linebreak)
(if sttl (para (bystro-clr "blue" (larger stitle)) (linebreak)) "")
(bystro-css-element-from-file "misc.css")
(bystro-css-element-from-file "slide.css")
(collect-element
(make-style #f '())
""
(fn-to-collect-slide-link slidename stitle slide-number))
init-content))
(begin
(set! content
(list
(title-decl
#f
'()
#f
(style #f (list 'non-toc 'no-toc 'unnumbered 'hidden 'hidden-number 'quiet))
stitle)
(if sttl (para (bystro-clr "blue" (larger stitle)) (linebreak)) "")
(bystro-css-element-from-file "misc.css")
(bystro-css-element-from-file "slide.css")
(collect-element
(make-style #f '())
""
(fn-to-collect-slide-link slidename stitle slide-number))
init-content))
(bystro-afterpause #:tag tg))))
(provide (contract-out
[bystro-initialize-formula-collection
(-> db?)]))
(define (bystro-initialize-formula-collection)
(unless (directory-exists? (string->path (bystro-formula-dir-name bystro-conf)))
(make-directory (string->path (bystro-formula-dir-name bystro-conf))))
(let* ([mydb (open (string->path (bystro-formula-database-name bystro-conf)))]
[query (prepare mydb "select name from SQLITE_MASTER")]
[tbls (step* query)]
)
(and (not (for/or ([tbl tbls]) (equal? (vector-ref tbl 0) "formulas")))
(exec/ignore mydb "CREATE TABLE formulas (tex, scale, filename, depth, tags)")
)
(finalize query)
(set! running-database mydb)
mydb))
(provide (contract-out
[bystro-number-for-formula (-> string? string?)]))
(define (bystro-number-for-formula lbl)
(set! formulanumber (+ 1 formulanumber))
(set! formula-ref-dict
(if (dict-has-key? formula-ref-dict lbl)
formula-ref-dict (cons (cons lbl formulanumber) formula-ref-dict)))
(string-append "(" (number->string formulanumber) ")"))
(provide (contract-out
[bystro-ref-formula (-> string? string?)]))
(define (bystro-ref-formula lbl)
(number->string (cdr (assoc lbl formula-ref-dict))))
(provide (contract-out
[bystro-command-to-typeset-formula (-> path-string? string? number? string? string?)]))
(define (bystro-command-to-typeset-formula shell-command-path texstring size filename)
(define-values (pr outport inport errport)
(subprocess #f #f #f shell-command-path))
(display "\n")
(xml:write-xml/content
(xml:xexpr->xml `(formula ((size ,(number->string size)) (filename ,filename)) ,texstring)))
(xml:write-xml/content
(xml:xexpr->xml `(formula ((size ,(number->string size)) (filename ,filename)) ,texstring))
inport)
(close-output-port inport)
(let* (
[report-xml (xml:read-xml outport)]
[report-xexpr (xml:xml->xexpr (xml:document-element report-xml))]
[found-error (xml:se-path* '(error) report-xexpr)]
)
(close-input-port outport)
(close-input-port errport)
(if found-error
(begin
(display (string-append found-error "<--- ERROR processing LaTeX formula: \n" texstring))
(error "*** please make corrections and run again ***")
)
(xml:se-path* '(depth) report-xexpr))))
(provide (contract-out
[bystro-equation (->* ((listof string?)
#:size natural-number/c)
(#:label (or/c string? #f))
nested-flow?)]))
(define (bystro-equation x
#:size n
#:label [l #f]
)
(nested
(make-table
(make-style #f
(list
(make-attributes (list (cons 'style "width:100%;")))
(make-table-cells
(list (list (make-style #f (list 'center)) (make-style #f (list 'right)))))))
(list (list
(para (keyword-apply bystro-formula '() '() x #:size n #:align #f #:use-depth #t))
(para (if l (elemtag l (bystro-number-for-formula l)) "")))))))
(define (aligned-formula manual-adj use-depth depth aa-adj filepath sz)
(element
(bystro-elemstyle
(cond
[manual-adj (string-append
"vertical-align:-"
(number->string (+ aa-adj depth (- (round (/ (* manual-adj sz) 18)))))
"px")]
[use-depth (string-append
"vertical-align:-"
(number->string (+ aa-adj depth))
"px" )]
[else "vertical-align:middle"]))
(image filepath)))
(provide (contract-out
[bystro-formula (->* ()
(#:shell-command path?
#:database db?
#:formulas-in-dir string?
#:size natural-number/c
#:align (or/c (integer-in (- 99) 99) #f)
#:use-depth boolean?
#:aa-adjust (integer-in (- 99) 99)
)
#:rest (listof string?)
element? )]))
(define (bystro-formula
#:shell-command [shell-command-path (bystro-formula-processor bystro-conf)]
#:database [mydb running-database]
#:formulas-in-dir [formdir (bystro-formula-dir-name bystro-conf)]
#:size [bsz (bystro-formula-size bystro-conf)]
#:align [align #f]
#:use-depth [use-depth #f]
#:aa-adjust [aa-adj (bystro-autoalign-adjust bystro-conf)]
. tex)
(let* (
[query (prepare
mydb
(string-append
"select filename,depth from formulas where scale = ? and tex = ?"
))]
[row (begin (load-params query bsz (apply string-append tex))
(step query)
)]
[totalnumber (vector-ref (car (cdr (select mydb "select count(*) from formulas"))) 0)]
)
(finalize query)
(if row
(aligned-formula
align
use-depth
(string->number (vector-ref row 1))
aa-adj
(build-path formdir (string-append (vector-ref row 0) ".png"))
bsz)
(let*
([formnum (totalnumber . + . 1)]
[filename (string-append formdir "/" (number->string formnum) ".png")]
[insert-stmt (prepare mydb "insert into formulas values (?,?,?,?,?)")]
[dpth-str (bystro-command-to-typeset-formula
shell-command-path
(apply string-append tex)
bsz
filename)])
(run insert-stmt (apply string-append tex) bsz (number->string formnum) dpth-str "")
(finalize insert-stmt)
(aligned-formula
align
use-depth
(string->number dpth-str)
aa-adj
(build-path filename)
bsz)))))
(provide (contract-out
[bystro-toc (-> delayed-block?)]))
(define (bystro-toc)
(make-delayed-block
(lambda (renderer pt ri)
(let ([ks (resolve-get-keys pt ri (lambda (key)
(eq? (car key) 'amkhlv-slide)))])
(apply
nested
(apply
append
(for/list ([k (sort ks < #:key (lambda (k) (caddr k)))])
(list (seclink (car (cdr k)) (resolve-get pt ri k)) (linebreak)))))))))
)