about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile93
-rw-r--r--jimmy.egg15
-rw-r--r--src/emit.scm69
-rw-r--r--src/html.scm58
-rw-r--r--src/read.scm29
-rw-r--r--src/util.scm12
-rw-r--r--src/wrap.scm2
-rw-r--r--tests/run.scm160
8 files changed, 283 insertions, 155 deletions
diff --git a/Makefile b/Makefile index b4f54b6..8eead3a 100644 --- a/Makefile +++ b/Makefile
@@ -1,64 +1,51 @@
1NAME = jimmy 1# Automatically generated by scramble
2
3LIBS = read emit util
4
5BUILD = $(PWD)/build
6SRC = $(PWD)/src
7TESTS = $(PWD)/tests
8 2
3NAME = jimmy
9CSC = /usr/bin/csc 4CSC = /usr/bin/csc
5CSC_OPTIONS = -setup-mode -host -I $(PWD) -C -I$(PWD)
6CSC_LIB_OPTIONS = -D compiling-extension -emit-all-import-libraries -dynamic -regenerate-import-libraries
7CSC_OPTIONS_EXTRA = -X utf8 -X module-declarations
10CSI = /usr/bin/csi 8CSI = /usr/bin/csi
11CSC_OPTIONS = \ 9BUILD = $(PWD)/build
12 -setup-mode \ 10TESTS = $(PWD)/tests
13 -host \ 11TEST_ENV = env BUILD=$(BUILD) TESTS=$(TESTS)
14 -D compiling-extension \ 12TEST_ENV_EXTRA = TEST_USE_ANSI=0
15 -emit-all-import-libraries \
16 -dynamic \
17 -regenerate-import-libraries \
18 -I $(SRC) \
19 -C -I$(SRC)
20
21CSC_OPTIONS_EXTRA = \
22 -X utf8 \
23 -X module-declarations
24
25## Library dependency graph
26# here's a convenience macro
27lib = $(BUILD)/$(NAME).$(1).so
28# and another
29src = $(SRC)/$(1).scm
30
31LIBS_ = $(foreach l,$(LIBS),$(call lib,$(l)))
32
33## Phonies
34
35.PHONY: build test clean
36build: $(LIBS_)
37 -mv *.import.scm build/
38
39test: build
40 cd $(BUILD) && \
41 $(CSI) -setup-mode -s $(TESTS)/run.scm $(NAME)
42 13
14.PHONY: all test clean install uninstall
15all: build/jimmy.util.so build/jimmy.read.so build/jimmy.emit.so build/jimmy.html.so build/jimmy.wrap.so
16test: all
17 cd $(BUILD) && $(TEST_ENV) $(TEST_ENV_EXTRA) $(CSI) -setup-mode -s $(TESTS)/run.scm $(NAME)
43clean: 18clean:
44 -rm -rf $(BUILD) 19 -rm -rf $(BUILD) *.build.sh *.install.sh $(NAME) *.import.scm *.so *.link *.static.o
45
46install: 20install:
47 chicken-install -s 21 chicken-install -s
48
49uninstall: 22uninstall:
50 chicken-uninstall -s 23 chicken-uninstall -s
51 24
52# Scm -> So 25# jimmy
53
54$(BUILD)/$(NAME).%.so: src/%.scm
55 mkdir -p "$(dir $@)"
56 $(CSC) $(CSC_OPTIONS) $(CSC_OPTIONS_EXTRA) $< -o $@
57
58# Libraries!
59$(call lib,util): $(call src,util)
60 26
61$(call lib,read): $(call src,read) $(call lib,util) 27build/jimmy.util.so: src/util.scm
62$(call lib,emit): $(call src,emit) $(call lib,util) 28 @mkdir -p $(BUILD)
63 29 cd $(BUILD) && \
64# Program! 30 $(CSC) $(CSC_OPTIONS) $(CSC_LIB_OPTIONS) $(CSC_OPTIONS_EXTRA) ../$< -o $(@F)
31 @test -f jimmy.util.import.scm &&mv jimmy.util.import.scm $(BUILD)/||true
32build/jimmy.read.so: src/read.scm src/util.scm
33 @mkdir -p $(BUILD)
34 cd $(BUILD) && \
35 $(CSC) $(CSC_OPTIONS) $(CSC_LIB_OPTIONS) $(CSC_OPTIONS_EXTRA) ../$< -o $(@F)
36 @test -f jimmy.read.import.scm &&mv jimmy.read.import.scm $(BUILD)/||true
37build/jimmy.emit.so: src/emit.scm src/util.scm
38 @mkdir -p $(BUILD)
39 cd $(BUILD) && \
40 $(CSC) $(CSC_OPTIONS) $(CSC_LIB_OPTIONS) $(CSC_OPTIONS_EXTRA) ../$< -o $(@F)
41 @test -f jimmy.emit.import.scm &&mv jimmy.emit.import.scm $(BUILD)/||true
42build/jimmy.html.so: src/html.scm src/util.scm src/emit.scm
43 @mkdir -p $(BUILD)
44 cd $(BUILD) && \
45 $(CSC) $(CSC_OPTIONS) $(CSC_LIB_OPTIONS) $(CSC_OPTIONS_EXTRA) ../$< -o $(@F)
46 @test -f jimmy.html.import.scm &&mv jimmy.html.import.scm $(BUILD)/||true
47build/jimmy.wrap.so: src/wrap.scm src/util.scm src/emit.scm
48 @mkdir -p $(BUILD)
49 cd $(BUILD) && \
50 $(CSC) $(CSC_OPTIONS) $(CSC_LIB_OPTIONS) $(CSC_OPTIONS_EXTRA) ../$< -o $(@F)
51 @test -f jimmy.wrap.import.scm &&mv jimmy.wrap.import.scm $(BUILD)/||true
diff --git a/jimmy.egg b/jimmy.egg index 108cf7d..84fe949 100644 --- a/jimmy.egg +++ b/jimmy.egg
@@ -7,11 +7,24 @@
7 (component-options 7 (component-options
8 (csc-options -X utf8 -X module-declarations)) 8 (csc-options -X utf8 -X module-declarations))
9 (components 9 (components
10 ;; Utility library
10 (extension jimmy.util 11 (extension jimmy.util
11 (source src/util.scm)) 12 (source src/util.scm))
13 ;; Read gemini files into internal format
12 (extension jimmy.read 14 (extension jimmy.read
13 (source src/read.scm) 15 (source src/read.scm)
14 (component-dependencies jimmy.util)) 16 (component-dependencies jimmy.util))
17 ;; Emit the output format (includes gemini)
15 (extension jimmy.emit 18 (extension jimmy.emit
16 (source src/emit.scm) 19 (source src/emit.scm)
17 (component-dependencies jimmy.util)))) 20 (component-dependencies jimmy.util))
21 ;; Emit HTML -- import this *after* emit (is this the best way?)
22 (extension jimmy.html
23 (source src/html.scm)
24 (component-dependencies jimmy.util
25 jimmy.emit))
26 ;; Wrap output in templates
27 (extension jimmy.wrap
28 (source src/wrap.scm)
29 (component-dependencies jimmy.util
30 jimmy.emit))))
diff --git a/src/emit.scm b/src/emit.scm index e57e437..4c3581f 100644 --- a/src/emit.scm +++ b/src/emit.scm
@@ -1,3 +1,5 @@
1(declare (module (jimmy emit)))
2
1(import scheme (chicken base) 3(import scheme (chicken base)
2 (chicken format) 4 (chicken format)
3 (chicken irregex) 5 (chicken irregex)
@@ -9,41 +11,36 @@
9 (for-each display (map format-stanza doc))) 11 (for-each display (map format-stanza doc)))
10 12
11(define-public formats 13(define-public formats
12 ;;; (TYPE (line . LINE-FMT) (stanza . STANZA-FMT) (inline . INLINE-FMT)) 14 (make-parameter
13 '((para (line . "~A") 15 ;; (TYPE (line . LINE-FMT) (stanza . STANZA-FMT) (inline . INLINE-FMT))
14 (stanza . "~A~%~%")) 16 '((para (line . "~A")
15 (verb (line . "~A~%") 17 (stanza . "~A~%~%"))
16 (stanza . "```~%~A```~%~%")) 18 (verb (line . "~A~%")
17 (link (line . "=> ~A ~A~%") ; Note: link has 2 format arguments 19 (stanza . "```~%~A```~%~%"))
18 (stanza . "~A~%") 20 (link (line . "=> ~A ~A~%") ; Note: link has 2 format arguments
19 (inline . "~%=> ~A ~A~%")) 21 (stanza . "~A~%")
20 (list (line . "* ~A~%") 22 (inline . "~%=> ~A ~A~%"))
21 (stanza . "~A~%")) 23 (list (line . "* ~A~%")
22 (quot (line . "~A") 24 (stanza . "~A~%"))
23 (stanza . "> ~A~%~%")) 25 (quot (line . "~A")
24 (hdr1 (line . "# ~A~%") 26 (stanza . "> ~A~%~%"))
25 (stanza . "~A~%")) 27 (hdr1 (line . "# ~A~%")
26 (hdr2 (line . "## ~A~%") 28 (stanza . "~A~%"))
27 (stanza . "~A~%")) 29 (hdr2 (line . "## ~A~%")
28 (hdr3 (line . "### ~A~%") 30 (stanza . "~A~%"))
29 (stanza . "~A~%")) 31 (hdr3 (line . "### ~A~%")
30 (meta (line . "") 32 (stanza . "~A~%")))))
31 (stanza . ""))
32 (default
33 (line . "~A")
34 (stanza . "~A~%~%"))))
35 33
36(define-public filters 34(define-public filters
37 ;;; (TYPE (line . LINE-FILTER) (stanza . STANZA-FILTER)) 35 (make-parameter
38 ;; line-filter : (lambda (list-of-strs) ...) -> list-of-strs (for format) 36 ;; (TYPE (line . LINE-FILTER) (stanza . STANZA-FILTER))
39 ;; stanza-filter : (lambda (list-of-strs) ...) -> str 37 ;; line-filter : (lambda (list-of-strs) ...) -> list-of-strs (for format)
40 `((verb (line . ,identity) 38 ;; stanza-filter : (lambda (list-of-strs) ...) -> str
41 (stanza . ,(lambda (lines) (apply string-append lines)))) 39 `((verb (line . ,identity)
42 (default 40 (stanza . ,join-lines))
43 (line . ,identity) 41 (default
44 (stanza . ,(lambda (lines) 42 (line . ,identity)
45 (irregex-replace/all '(: bol (* space)) 43 (stanza . ,flush-lines-left)))))
46 (string-join lines) ""))))))
47 44
48(define (format-line line el) 45(define (format-line line el)
49 (cond 46 (cond
@@ -72,8 +69,10 @@
72 (and (eq? scope 'inline) 69 (and (eq? scope 'inline)
73 (alist-walk alist 'default 'line)))) 70 (alist-walk alist 'default 'line))))
74 71
75(define (get-format el scope) (get-from formats el scope)) 72(define (get-format el scope)
76(define (get-filter el scope) (get-from filters el scope)) 73 (or (get-from (formats) el scope)
74 ""))
75(define (get-filter el scope) (get-from (filters) el scope))
77 76
78(define (sprintf* fmt lis) 77(define (sprintf* fmt lis)
79 (let loop ((num (length (irregex-extract "~[aA]" fmt))) 78 (let loop ((num (length (irregex-extract "~[aA]" fmt)))
diff --git a/src/html.scm b/src/html.scm index 371d407..07cd921 100644 --- a/src/html.scm +++ b/src/html.scm
@@ -1,3 +1,61 @@
1(declare (module (jimmy html))) 1(declare (module (jimmy html)))
2 2
3(import scheme (chicken base)
4 (chicken irregex)
5 (jimmy emit)
6 (jimmy util))
3 7
8(define (escape-entities s)
9 (irregex-replace/all "[&<>]" s
10 (lambda (m)
11 (let ((c (irregex-match-substring m)))
12 (cond
13 ((equal? c "&") "&amp;")
14 ((equal? c "<") "&lt;")
15 ((equal? c ">") "&gt;"))))))
16
17(define (add-inline-markup s)
18 (define (char->tag ch tag)
19 (lambda (s)
20 (irregex-replace/all `(: ,ch ($ (* (~ ,ch))) ,ch) s
21 "<" tag ">" 1 "</" tag ">")))
22
23 ((o (char->tag "*" "b")
24 (char->tag "_" "i")
25 (char->tag "`" "code")) s))
26
27(formats
28 '((para (line . "~a~%")
29 (stanza . "<p>~% ~a</p>~%"))
30 (verb (line . "~a~%")
31 (stanza . "<pre><code>~a</code></pre>~%"))
32 (link (line . "<li><a href=\"~a\">~a</a></li>~%")
33 (stanza . "<ul>~% ~a</ul>~%")
34 (inline . "<a href=\"~a\">~a</a>~%"))
35 (list (line . "<li>~a</li>~%")
36 (stanza . "<ul>~% ~a</ul>~%"))
37 (quot (line . "~a~%")
38 (stanza . "<blockquote>~% ~a</blockquote>~%"))
39 (hdr1 (line . "~a")
40 (stanza . "<h1>~a</h1>~%"))
41 (hdr2 (line . "~a")
42 (stanza . "<h2>~a</h2>~%"))
43 (hdr3 (line . "~a")
44 (stanza . "<h3>~a</h3>~%"))))
45
46(filters
47 `((verb (line . ,identity)
48 (stanza . ,join-lines))
49 (link (line . ,(lambda (ln)
50 (cons (car ln)
51 ((o list
52 add-inline-markup
53 escape-entities
54 string-join)
55 (cdr ln))))))
56 (default
57 (line . ,(o list
58 add-inline-markup
59 escape-entities
60 string-join))
61 (stanza . ,string-join))))
diff --git a/src/read.scm b/src/read.scm index 94708ef..1b611bb 100644 --- a/src/read.scm +++ b/src/read.scm
@@ -36,19 +36,34 @@
36 ((null? words) ; empty line 36 ((null? words) ; empty line
37 (parse-lines (cdr lines) doc)) 37 (parse-lines (cdr lines) doc))
38 ((equal? (car words) "```") ; verbatim 38 ((equal? (car words) "```") ; verbatim
39 (parse-verbatim (cdr lines) doc '())) 39 ;; Format for verbatim header:
40 ;; ``` ?html | command ...
41 ;; -- only run command on block with html output.
42 ;; other outputs process the block normally
43 ;; ``` ?!html | command ...
44 ;; -- only run command on block when *not* outputting html.
45 ;; html processes the block normally
46 ;; ``` ?:html | command ...
47 ;; -- like ?html, but ignore the block in non-html outputs.
48 ;;;; FIXME: I think this necessitates a special emit-verbatim
49 ;;;; function.
50 (parse-verbatim (cdr lines) doc '()
51 #; (if (< 1 (length words))
52 (cons 'verb (cdr words))
53 'verb)
54 'verb))
40 (else ; another line type 55 (else ; another line type
41 (apply parse-stanza lines doc '() (line-type words))))))) 56 (apply parse-stanza lines doc '() (line-type words)))))))
42 57
43(define (parse-verbatim lines doc block) 58(define (parse-verbatim lines doc block bhead)
44 (define (close-verbatim) (cons (cons 'verb (reverse block)) doc)) 59 (define (close-verbatim) (cons (cons bhead (reverse block)) doc))
45 (cond 60 (cond
46 ((null? lines) ; end of document 61 ((null? lines) ; end of document
47 (parse-lines lines (close-verbatim))) 62 (parse-lines lines (close-verbatim)))
48 ((equal? (car lines) "```") ; end of verbatim block 63 ((equal? (car lines) "```") ; end of verbatim block
49 (parse-lines (cdr lines) (close-verbatim))) 64 (parse-lines (cdr lines) (close-verbatim)))
50 (else ; verbatim block continues 65 (else ; verbatim block continues
51 (parse-verbatim (cdr lines) doc (cons (list (car lines)) block))))) 66 (parse-verbatim (cdr lines) doc (cons (list (car lines)) block) bhead))))
52 67
53(define (parse-stanza lines doc stanza st-type 68(define (parse-stanza lines doc stanza st-type
54 #!optional (st-inlines '()) (st-words cdr)) 69 #!optional (st-inlines '()) (st-words cdr))
diff --git a/src/util.scm b/src/util.scm index 41da769..c71c600 100644 --- a/src/util.scm +++ b/src/util.scm
@@ -2,6 +2,7 @@
2 2
3 (import scheme (chicken base) 3 (import scheme (chicken base)
4 (chicken condition) 4 (chicken condition)
5 (only (chicken irregex) irregex-replace/all)
5 (chicken string)) 6 (chicken string))
6 7
7 (define-syntax define-public 8 (define-syntax define-public
@@ -34,6 +35,15 @@
34 (apply alist-walk (cdr kv) (cdr keys))))))) 35 (apply alist-walk (cdr kv) (cdr keys)))))))
35 36
36 (define (string-join ss #!optional (sep " ")) 37 (define (string-join ss #!optional (sep " "))
37 (string-intersperse ss sep))) 38 (string-intersperse ss sep))
39
40 (define (flush-lines-left lines)
41 (irregex-replace/all '(: bol (* space))
42 (string-join lines) ""))
43
44 (define (join-lines lines)
45 (apply string-append lines))
46
47 )
38 48
39 49
diff --git a/src/wrap.scm b/src/wrap.scm index 0ed8868..aa077d8 100644 --- a/src/wrap.scm +++ b/src/wrap.scm
@@ -5,7 +5,7 @@
5 (jimmy util) 5 (jimmy util)
6 (only (chicken io) read-string) 6 (only (chicken io) read-string)
7 (only (chicken port) with-output-to-string) 7 (only (chicken port) with-output-to-string)
8 (only (chicken string) string-translate*)) 8 (only (chicken string) string-translate* string-intersperse))
9 9
10;; templates are strings with variables interpolated with "{{variables}}" 10;; templates are strings with variables interpolated with "{{variables}}"
11 11
diff --git a/tests/run.scm b/tests/run.scm index 1ec4ffe..49da815 100644 --- a/tests/run.scm +++ b/tests/run.scm
@@ -1,80 +1,126 @@
1(import scheme 1(import scheme
2 (chicken base) 2 (chicken base)
3 (chicken load) 3 (chicken load)
4 (chicken pathname)
4 (chicken port) 5 (chicken port)
5 (chicken process-context) 6 (chicken process-context)
6 test) 7 test)
7 8
9(define test-dir (or (get-environment-variable "TESTS")
10 "tests"))
11
8;;; Setup 12;;; Setup
9 13
10(import (jimmy emit) 14(import (jimmy emit)
11 (jimmy read) 15 (jimmy read)
12 #;(jimmy wrap)) 16 #;(jimmy wrap))
13 17
14(define test-doc #<<end-document 18(test-begin)
15: title a test document
16: date 2024-05-13T03:02:45Z
17: uuid b3daebf1-440b-4828-a4d9-9089c7bd7c61
18
19# a test document of some kind
20 19
21here is a test document. 20;;; Reading
22it has paragraphs
23=> example.com with links!
24and other things.
25 21
26## a code example 22(define test-file (make-pathname (list test-dir) "test" "gmi"))
27``` 23(define expected-doc
28for (a=1;a<=4;a++) { 24 '((meta ("title" "a" "test" "document")
29 printf("%d\n", a); 25 ("date" "2024-05-13T03:02:45Z")
30} 26 ("uuid" "b3daebf1-440b-4828-a4d9-9089c7bd7c61"))
31``` 27 (hdr1 ("a" "test" "document" "of" "some" "kind"))
28 (para ("here" "is" "a" "test" "document.")
29 ("it" "has" "paragraphs")
30 (link "example.com" "with" "links!")
31 ("and" "other" "things."))
32 (hdr2 ("a" "code" "example"))
33 (verb ("for (a=1;a<=4;a++) {") ("\tprintf(\"%d\\n\", a);") ("}"))
34 (hdr3 ("other" "examples"))
35 (quot ("a" "blockquote" "is" "a" "quote") ("that" "is" "blocky."))
36 (list ("list" "1") ("list" "2") ("list" "3"))
37 (link ("example.com" "link" "list" "1")
38 ("example.com" "link" "list" "2")
39 ("example.com" "link" "list" "3"))
40 (para ("ok," "now" "for" "another" "test:")
41 ("will" "*strong*" "in-line" "text" "be" "converted?")
42 ("as" "well" "as" "`code`," "_emph_" "and" "such?")
43 ("what" "if" "*i" "_nest_" "them*")
44 ("what" "if" "*i" "_nest" "them*" "wrong_" "?")
45 ("what" "about" "*breaking" "them")
46 ("over" "two" "lines?*"))))
47(define actual-doc (with-input-from-file test-file parse))
32 48
33### other examples 49(test "read" expected-doc actual-doc)
34 50
35> a blockquote is a quote 51(define doc expected-doc)
36> that is blocky.
37 52
38* list 1 53;;; Emitting
39* list 2
40* list 3
41=> example.com link list 1
42=> example.com link list 2
43=> example.com link list 3
44 54
45ok, now for another test: 55(test-group "gemini"
46will *strong* in-line text be converted? 56 (define expected-gmi
47as well as `code`, _emph_ and such? 57 (string-append "# a test document of some kind\n\n"
48what if *i _nest_ them* 58 "here is a test document. it has paragraphs \n"
49what if *i _nest them* wrong_ ? 59 "=> example.com with links!\n"
50what about *breaking them 60 "and other things.\n\n"
51over two lines?* 61 "## a code example\n\n"
52end-document 62 "```\nfor (a=1;a<=4;a++) {\n"
53) 63 "\tprintf(\"%d\\n\", a);"
64 "\n}\n```\n\n"
65 "### other examples\n\n"
66 "> a blockquote is a quote that is blocky.\n\n"
67 "* list 1\n"
68 "* list 2\n"
69 "* list 3\n\n"
70 "=> example.com link list 1\n"
71 "=> example.com link list 2\n"
72 "=> example.com link list 3\n\n"
73 "ok, now for another test: "
74 "will *strong* in-line text be converted? "
75 "as well as `code`, _emph_ and such? "
76 "what if *i _nest_ them* what if *i _nest them* wrong_ ? "
77 "what about *breaking them over two lines?*\n\n"))
78 (define actual-gmi (with-output-to-string (lambda () (emit doc))))
79 (test "emit" expected-gmi actual-gmi))
54 80
55;;; Tests 81;;; HTML
56 82
57(test "read" 83(test-group "html"
58 '((meta ("title" "a" "test" "document") 84 (import (jimmy html))
59 ("date" "2024-05-13T03:02:45Z") 85 (define expected-html
60 ("uuid" "b3daebf1-440b-4828-a4d9-9089c7bd7c61")) 86 (string-append "<h1>a test document of some kind</h1>\n"
61 (hdr1 ("a" "test" "document" "of" "some" "kind")) 87 "<p>\n"
62 (para "here is a test document." "it has paragraphs" (link "example.com" 88 " here is a test document.\n"
63 "with" 89 " it has paragraphs\n"
64 "links!") 90 " <a href=\"example.com\">with links!</a>\n"
65 "and other things.") 91 " and other things.\n"
66 (hdr2 ("a" "code" "example")) 92 "</p>\n"
67 (verb "for (a=1;a<=4;a++) {" "\tprintf(\"%d\\n\", a);" "}") 93 "<h2>a code example</h2>\n"
68 (hdr3 ("other" "examples")) 94 "<pre><code>for (a=1;a<=4;a++) {\n"
69 (quot ("a" "blockquote" "is" "a" "quote") ("that" "is" "blocky.")) 95 "\tprintf(\"%d\\n\", a);\n"
70 (list ("list" "1") ("list" "2") ("list" "3")) 96 "}\n"
71 (link ("example.com" "link" "list" "1") ("example.com" "link" "list" 97 "</code></pre>\n"
72 "2") ("example.com" "link" 98 "<h3>other examples</h3>\n"
73 "list" "3")) 99 "<blockquote>\n"
74 (para "ok, now for another test:" "will *strong* in-line text be 100 " a blockquote is a quote\n"
75converted?" "as well as `code`, _emph_ and such?" "what if *i _nest_ them*" 101 " that is blocky.\n"
76"what if *i _nest them* wrong_ ?" "what about *breaking them" "over two 102 "</blockquote>\n"
77lines?*")) 103 "<ul>\n"
78 (call-with-input-string test-doc parse)) 104 " <li>list 1</li>\n"
105 " <li>list 2</li>\n"
106 " <li>list 3</li>\n"
107 "</ul>\n"
108 "<ul>\n"
109 " <li><a href=\"example.com\">link list 1</a></li>\n"
110 " <li><a href=\"example.com\">link list 2</a></li>\n"
111 " <li><a href=\"example.com\">link list 3</a></li>\n"
112 "</ul>\n"
113 "<p>\n"
114 " ok, now for another test:\n"
115 " will <b>strong</b> in-line text be converted?\n"
116 " as well as <code>code</code>, <i>emph</i> and such?\n"
117 " what if <b>i <i>nest</i> them</b>\n"
118 " what if <b>i <i>nest them</b> wrong</i> ?\n"
119 " what about *breaking them\n"
120 " over two lines?*\n"
121 "</p>\n"))
122 (define actual-html (with-output-to-string (lambda () (emit doc))))
123 (test "emit html" expected-html actual-html))
79 124
125(test-end)
80(test-exit) 126(test-exit)