#lang racket/base (require racket/list racket/string) (provide extract-todos) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; goal : Extract wiki todo(...) markers from Markdown source. ; pre : markdown is a string. ; post : Fenced code blocks are ignored and source is unchanged. ; result : A list of hashes containing item number, line number and text. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (extract-todos markdown) (define lines (string-split markdown "\n" #:trim? #f)) (define in-fence? #f) (define item-number 0) (define result '()) (for ((line (in-list lines)) (line-number (in-naturals 1))) (define trimmed (string-trim line)) (cond ((regexp-match? #px"^(```|~~~)" trimmed) (set! in-fence? (not in-fence?))) ((not in-fence?) (for ((match (in-list (regexp-match* #px"todo\\([^()]+\\)" line)))) (define text (string-trim (substring match 5 (- (string-length match) 1)))) (when (not (string=? text "")) (set! item-number (+ item-number 1)) (set! result (cons (hash 'number item-number 'line line-number 'text text) result))))))) (reverse result))