読者です 読者をやめる 読者になる 読者になる

見出しに対応。

Kahua

wiki-ikiのソースをぱくって見出しに対応した。h4/とかの/で終わる手続きを使いたかったからいろいろ試行錯誤した。

(list-ref '(_ h2/ h3/ h4/ h5/ h6/) 2)

(list-ref `(_ ,h2/ ,h3/ ,h4/ ,h5/ ,h6/) 2)

の返り値って違うのね。シンボルと手続きじゃだいぶ違う。
もちろんこんなものできない。

((list-ref '(_ h2/ h3/ h4/ h5/ h6/) 2) "hogehoge")

できると思ってはまってた。。。基礎知識が足りなすぎ。

;; 文字列をsxmlのnodeにする。
(define (format-content/ content)
  (apply node-set/
	 ((compose paragraphs->node/
		   lines->paragraphs
		   content->lines) content)))
;; コメント ;; 
;; 行の継続 ~  
(define (content->lines content)
  (call-with-input-string
      content
    (lambda (in)
      (let loop ((lines '()))
	(let1 line (read-line in)
	  (if (eof-object? line)
	      (reverse lines)
	      (cond 
	       ((#/^\;\;/ line) (loop lines))
	       ((#/^~/ line)
		(loop (cons (string-append (car lines)
					   (substring line 1 (string-length line)))
			    (cdr lines))))
	       (else (loop (cons line lines))))))))))
;; 見出し #/^!{1,5}/ -> "" string
;; 段落                 ("" "") string-list
(define (lines->paragraphs lines)
  (let make-paragraphs ((lines lines) (paragraphs '()))
    (cond ((null? lines) (reverse paragraphs)) 
	  ((or (string-null? (car lines))
	       (#/^\s*$/     (car lines))) ; empty line
	   (make-paragraphs (cdr lines) paragraphs))
	  ((#/^!{1,5}\s/ (car lines)) ; headline
	   (make-paragraphs (cdr lines)
			    (cons (car lines) paragraphs)))
	  (else
	   (let make-paragraph ((lines lines) (paragraph '()))
	     (cond ((or (null? lines)
			(string-null? (car lines))
			(#/^\s*$/ (car lines))
			(#/^!{1,5}\s/ (car lines))) ; not paragraph
		    (make-paragraphs lines
				     (cons (reverse paragraph) paragraphs)))
		    (else ; paragraph
		     (make-paragraph (cdr lines)
				     (cons (car lines) paragraph)))))))))
(define (headline/ p)
  (let* ((m (#/^(!{1,5})\s/ p))
	 (level (string-length (m 1))))
    ((list-ref `(_ ,h2/ ,h3/ ,h4/ ,h5/ ,h6/) level)
    (m 'after))))

(define (paragraphs->node/ paragraphs)
  (let loop ((paragraphs paragraphs)
	     (node '()))
    (if (null? paragraphs)
	(reverse node)
	(let1 paragraph (tree->string (car paragraphs))
	  (cond
	   ((#/^!{1,5}\s/ paragraph)
	    (loop (cdr paragraphs) (cons (p/ (headline/ paragraph)) node)))
	   (else
	    (loop (cdr paragraphs) (cons (p/ paragraph) node))))))))