diff --git a/src/busybee/busybee.scm b/src/busybee/busybee.scm index 6c87a2c..889fac6 100644 --- a/src/busybee/busybee.scm +++ b/src/busybee/busybee.scm @@ -124,6 +124,63 @@ [(list sym hsh x ...) x] [_ '()]))) +;; (map-delim '(1 2 3 2) (lambda (x) (+ x 1)) 2) +;; (map-delim '(1 2 2 2) (lambda (x) (+ x 1)) 2) + +(define (map-delim lst func cnd delim) + (cond + [(< (length lst) 3) lst] + [(and (eq? (car lst) delim) (not (eq? (cadr lst) delim)) (eq? (caddr lst) delim)) + (cons delim + (cons (func (cadr lst)) + (map-delim (cddr lst) func delim)))] + [else (cons (car lst) + (map-delim (cdr lst) func delim))])) + +(define (wrap-p texpr) + `(p ,(mhash) ,@texpr)) + +;; should we parse text as (txt "We can (b mhash() "embolden") or ...) + +;; this doesn't apply to `root` out of luck. basically the first chunk before delimiters is ignored. + +(define (map-between lst #:func (func identity) #:delim (delim '(NEWLINE NEWLINE))) + (define (delim? lst) + (let [(l (length delim))] + (if (< (length lst) l) #f (equal? (take lst l) delim)))) + (let loop ([lst lst] [in-segment #f] [acc '()]) + (cond + [(null? lst) (if in-segment + (reverse (cons (func (reverse in-segment)) acc)) + (reverse acc))] + ;; wrap it up + [(delim? lst) + (if in-segment + (loop (drop lst (length delim)) '() (append delim (cons (func (reverse in-segment)) acc))) + (loop (drop lst (length delim)) '() (append delim acc)))] + [in-segment + (loop (cdr lst) (cons (car lst) in-segment) acc)] + [else + (loop (cdr lst) #f (cons (car lst) acc))]))) + +; (define (map-between foo lst) +; (let loop ([lst lst] [in-segment #f] [acc '()]) +; (cond +; [(null? lst) +; (reverse acc)] +; [(eq? (car lst) 'NEWLINE) +; (if in-segment +; (loop (cdr lst) '() (cons 'NEWLINE (append (reverse (map foo in-segment)) acc))) +; (loop (cdr lst) '() (cons 'NEWLINE acc)))] +; [in-segment +; (loop (cdr lst) (cons (car lst) in-segment) acc)] +; [else +; (loop (cdr lst) #f (cons (car lst) acc))]))) + +(define (decode-paragraphs texpr) + (map-between texpr #:func wrap-p #:delim '(NEWLINE NEWLINE))) + + (define (root-texpr? texpr) (if (texpr? texpr) (eq? (head texpr) 'root)) #f) @@ -140,6 +197,7 @@ (define (texpr->tgt texpr) ;; use texpr? function + (displayln texpr) (cond [(void? texpr) '()] [(empty? texpr) texpr] @@ -224,4 +282,5 @@ (define (render tgt txt) (parameterize ([target tgt]) - (flatten-txt-expr (texpr->tgt (parse txt))))) + (displayln (decode-paragraphs (parse txt))) + (flatten-txt-expr (texpr->tgt (decode-paragraphs (parse txt)))))) diff --git a/src/busybee/forester-test.bee b/src/busybee/forester-test.bee new file mode 100644 index 0000000..9cf1982 --- /dev/null +++ b/src/busybee/forester-test.bee @@ -0,0 +1,5 @@ +◊section{Hello!} + +This is ◊b{tree}. It's the basic unit of a Forester zettlekasten. + +Do paragraphs work here? diff --git a/src/busybee/forester.scm b/src/busybee/forester.scm new file mode 100644 index 0000000..0a43e74 --- /dev/null +++ b/src/busybee/forester.scm @@ -0,0 +1,30 @@ +(define-tag (p tree) (attrs els) + `(txt "\\p{" ,@els "}")) + +(define-tag (b tree) (attrs els) + `(txt "\\b{" ,@els "}")) + +(define-tag (em tree) (attrs els) + `(txt "\\em{" ,@els "}")) + +(define-tag (def tree) (attrs els) + `(txt "" ,@els "")) + +(define-tag (section tree) (attrs els) + `(txt "\\section{" ,@els "}\n")) + +(define-tag (ltx tree) (attrs els) + `(txt "\\${" ,@els "}")) + +(define-tag (cite tree) (attrs els) + (define src (attr-val attrs 'src)) + `(txt ,@src ,@els)) + +;; busybee-specific + +;; because of the awkwardness defining +(define-tag (transclude tree) (attrs els) + `(txt ,@els)) + +(define-tag (root tree) (attrs els) + `(txt ,@els)) diff --git a/src/busybee/parsing.scm b/src/busybee/parsing.scm index cfeb53c..7c3541e 100644 --- a/src/busybee/parsing.scm +++ b/src/busybee/parsing.scm @@ -27,8 +27,6 @@ (char=? c #\() (char=? c #\)) (char=? c #\[) (char=? c #\]))) -;; TODO replace with Newline(n) - (define (skip-whitespace chars) (cond [(null? chars) '()] ; [(char-whitespace? (car chars)) @@ -72,6 +70,8 @@ (cond [(empty? chars) (values (list->string (reverse acc)) '())] ; [(char-whitespace? (car chars)) ; (values (list->string (reverse acc)) chars)] + [(char=? (car chars) #\newline) + (values (list->string (reverse acc)) chars)] [(char-delimiter? (car chars)) (values (list->string (reverse acc)) chars)] [(char=? (car chars) #\◊) @@ -136,6 +136,7 @@ (lambda () (read-braces-string (cdddr chars))) (lambda (content rest) (tokenize-loop rest (cons (list 'LATEX content) acc))))] + ;; read the input literally [(and (>= (length chars) 4) (char=? (car chars) #\◊) (char=? (cadr chars) #\p) @@ -236,7 +237,8 @@ (cond [(empty? tokens) (values '() tokens)] - ;; case 1: command [kwargs] { content } + + ;; case 1: command [kwargs] { content } [(and (not (null? tokens)) (eq? (car tokens) 'LBRACKET)) (call-with-values (lambda () (parse-kwargs (cdr tokens))) @@ -253,7 +255,8 @@ [else (values `(,head ,kwargs ,@content) tokens)]))) (values (list head kwargs '()) '()))))] - ;; case 2: command { content } + + ;; case 2: command { content } [(and (not (null? tokens)) (eq? (car tokens) 'LBRACE)) (call-with-values (lambda () (parse-loop (cdr tokens))) diff --git a/src/busybee/query.md b/src/busybee/query.md index 790107a..e69de29 100644 --- a/src/busybee/query.md +++ b/src/busybee/query.md @@ -1,14 +0,0 @@ -# Querying - - -The atomic notes philosophy prescribes breaking notes into units of knowledge. They are recomposed through transclusion. Many notes may actually be of the same kind, such as a document of examples, which increases the amount of files that can be proliferated. - -In this example, we will transclude a specific example from another document. We will _restrict_ to only the examples in that file. - -This directory is relative to the file the file is being called in. It needs to be called from a project root. The do parameter can be written in code. - -Finset: Category of finite sets and finite functions - -Top: Category of topological spaces - - diff --git a/src/busybee/test/basic.bee b/src/busybee/test/basic.bee index 678e554..d8e9b04 100644 --- a/src/busybee/test/basic.bee +++ b/src/busybee/test/basic.bee @@ -1,6 +1,6 @@ ◊section[#:lvl 2]{Basic features} -◊b{enjoy!} +We can ◊b{enbolden} or ◊em{italicize} words. However, there are trailing newlines coming from this sentence. ◊def[#:term Transclusion]{This is the definition body} diff --git a/src/busybee/test/parse.scm b/src/busybee/test/parse.scm index 9a4b65d..d449005 100644 --- a/src/busybee/test/parse.scm +++ b/src/busybee/test/parse.scm @@ -1,24 +1,33 @@ -(require "parsing.scm") +(require "busybee.scm") + +(define parsed (read-and-parse "test/basic.bee")) + +(define parsed (read-and-parse "test/query.bee")) + +(define parsed (read-and-parse "test/template.bee")) + ;; Parsing shouldn't transclude, since that leaves it open to failure if a file doesn't exist +(require "parsing.scm") + (parse "◊![#:tag def:term=Transclusion]{test/basic.bee}") (parse "◊!{test/basic.bee}") -(require "busybee.scm") (require "markdown.scm") -(define parsed (read-and-parse "test/basic.bee")) -(define parsed (read-and-parse "test/query.bee")) +(require "latex.scm") -(define parsed (read-and-parse "test/template.bee")) +(define parsed (parse "◊section{Hello} + + My name is ◊b{Matt} and I am working on this feature")) -(require "latex.scm") +(paragraph-reader parsed) -(parameterize ([target "tex"]) +(parameterize ([target "tree"]) (flatten-txt-expr (texpr->tgt parsed))) (texpr->tgt parsed) diff --git a/src/busybee/test/test.bee b/src/busybee/test/test.bee new file mode 100644 index 0000000..c6a9959 --- /dev/null +++ b/src/busybee/test/test.bee @@ -0,0 +1,3 @@ +◊section{Hello!} + +What?? ◊em{no!} diff --git a/src/busybee/test/test.md b/src/busybee/test/test.md new file mode 100644 index 0000000..44e86c3 --- /dev/null +++ b/src/busybee/test/test.md @@ -0,0 +1,4 @@ +## Hello! + + +What?? _no!_ diff --git a/src/busybee/test/transcluding.md b/src/busybee/test/transcluding.md new file mode 100644 index 0000000..e69de29 diff --git a/src/core/document.rs b/src/core/document.rs index 3e04c54..f47c316 100644 --- a/src/core/document.rs +++ b/src/core/document.rs @@ -25,6 +25,8 @@ impl DocumentEngine { engine.run(format!(r"{}", latex)); let html = include_str!("../busybee/html.scm"); engine.run(format!(r"{}", html)); + let forester = include_str!("../busybee/forester.scm"); + engine.run(format!(r"{}", forester)); Self { engine: Some(engine), }