white-tiger/src/white-tiger.lisp

57 lines
1.6 KiB
Common Lisp

(defpackage white-tiger
(:use :cl)
(:export #:start))
(in-package white-tiger)
(defstruct node
(type)
(text-component "" :type string)
(preformat nil :type boolean))
(defun type-of-line (line)
(if (= (length line) 0)
:text
(case (char line 0)
;; Headers
(#\# (if (eq (char line 1) #\#) (if (eq (char line 2) #\#) :h3 :h2) :h1))
;; List item
(#\* :list)
;; Quote
(#\> :quote)
;; preformat toggle
(#\` (if (and (eql #\` (char line 2)) (eql #\` (char line 1))) :preformat :text))
;; Link
(#\= (if (eq #\> (char line 1)) :link :text))
(otherwise :text))))
(defun read-file (filename)
(uiop:read-file-lines filename))
(defun type-of-file (filename)
(map 'list #'type-of-line (read-file filename)))
(defun line-to-node (line type preformat)
(make-node
:preformat preformat
;; TODO: Split line on first whitespace; use cdr for text component
:type type
:text-component ""))
(defun parse-gemtext-file (line-list preformat-mode)
(if (= (length line-list) 0)
nil
;; Parse the line. If this line is a PREFORMAT, toggle the boolean moving forward.
(let ((line-type (type-of-line (car line-list))))
(cons (line-to-node (car line-list) line-type (if (eq line-type :preformat) nil preformat-mode))
(parse-gemtext-file (cdr line-list) (if (eq line-type :preformat) (not preformat-mode) preformat-mode))))))
(defun start-parse (filename)
(let ((file-contents (read-file filename)))
(parse-gemtext-file file-contents nil)))
;; entry point
(defun start ()
(let ((filename (car (cdr sb-ext:*posix-argv*))))
(format t "~a~%" (start-parse filename))))