From: Frank Duncan Date: Thu, 6 Jan 2022 22:27:08 +0000 (-0600) Subject: Add code fences X-Git-Tag: 0.1~3 X-Git-Url: https://code.consxy.com/gitweb/gitweb.cgi?a=commitdiff_plain;h=c4a9ac2;p=honey Add code fences --- diff --git a/src/main/parse.lisp b/src/main/parse.lisp index b64cb22..af3fca9 100644 --- a/src/main/parse.lisp +++ b/src/main/parse.lisp @@ -32,10 +32,23 @@ DESCRIPTION: ((line (car lines)) (parser (getf (cadr (find-if #1'(funcall (getf $1 :checker) line) (reverse *line-parsers*) :key #'cadr)) :parser))) (when (not parser) (error "Weird! Couldn't find a match for ~A" line)) - (multiple-value-bind (parsed-line squash-prev) (funcall (funcall parser line) prev) - (if squash-prev - (parse-lines (cdr lines) parsed-line) - (cons prev (parse-lines (cdr lines) parsed-line))))))) + (multiple-value-bind (parsed-line squash-prev suspension) (funcall (funcall parser line) prev) + (cond + (squash-prev (parse-lines (cdr lines) parsed-line)) + (suspension + (let* + ((regex-to-find (car suspension)) + (function-to-call (cadr suspension)) + (pos + (position-if + (lambda (line) (cl-ppcre:scan regex-to-find line)) + (cdr lines)))) + (append + (list + prev + (funcall function-to-call (subseq (cdr lines) 0 (or pos (length lines))))) + (parse-lines (nthcdr (1+ pos) (cdr lines)))))) + (t (cons prev (parse-lines (cdr lines) parsed-line)))))))) (defun parse-texts (line) (cond @@ -77,10 +90,14 @@ DESCRIPTION: #'parse-inline (coerce (second (multiple-value-list (cl-ppcre:scan-to-strings ,regex str))) 'list))))))))) -; each parser function needs to return a function that takes the previous line and returns either +; each parser function needs to return a function that takes the previous line and returns ; -; a single element being the new element, and optionally a second values option about whether -; the previous line should be consumed +; the values: +; the new element +; whether the previous line should be consumed (optional) +; an optional list with two items, which suspends parsing until regex is found +; - the regex to end the suspension +; - the function to call with the list of lines (defun prev-h2 () (lambda (prev) @@ -90,6 +107,12 @@ DESCRIPTION: (lambda (prev) (if (textp prev) (values (h1 prev) t) (hr)))) +(defun inline-h1 (text) (lambda (prev) (h1 text))) +(defun inline-h2 (text) (lambda (prev) (h2 text))) +(defun inline-h3 (text) (lambda (prev) (h3 text))) +(defun inline-h4 (text) (lambda (prev) (h4 text))) +(defun inline-h5 (text) (lambda (prev) (h5 text))) + (defun list-item (text) (lambda (prev) (let @@ -106,8 +129,29 @@ DESCRIPTION: (defun default (text) (lambda (prev) (declare (ignore prev)) text)) +(defun codefence (codetype) + (lambda (prev) + (declare (ignore prev)) + (values + nil + nil + (list + "^```$" + (lambda (lines) + (pre + (code + (format nil "~{~A~%~}" lines)))))))) + (defline-parser "-+" prev-h2) (defline-parser "=+" prev-h1) + +; These need to be in reverse order so they match correctly +(defline-parser "##### *(.*)" inline-h5) +(defline-parser "#### *(.*)" inline-h4) +(defline-parser "### *(.*)" inline-h3) +(defline-parser "## *(.*)" inline-h2) +(defline-parser "# *(.*)" inline-h1) +(defline-parser "```(.*)" codefence) (defline-parser " *\\* *(.*)" list-item) (defline-parser " *" emptiness) (defline-parser "(.*)" default)