Mercurial > core / lisp/lib/organ/element/headline.lisp
changeset 698: |
96958d3eb5b0 |
parent: |
f6a340b92274
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; lib/organ/element/headline.lisp --- Org Headline 9 (define-org-element todo-keyword 10 ((todo-type :accessor todo-keyword-type :initarg :type :initform "" :type string))) 12 (define-org-parser (todo-keyword :from string) 13 (when-let ((kw (org-todo-keyword-p input))) 14 (org-create :todo-keyword :type kw))) 16 (define-org-element priority 17 ((level :accessor org-priority-level :initarg :level :type character))) 19 (define-org-parser (priority :from string) 20 (with-lexer-environment (input) 21 (when (and (char= #\[ (peek)) 25 (not (char= #\] (peek)))) 26 (when-let ((c (consume))) 27 (when (and (characterp (peek)) 28 (char= #\] (peek))) ;; kludge 29 (org-create :priority :level c)))))) 31 (defun org-parse-todo-keyword-and-priority (input) 32 "Parse INPUT returning the following values: 34 (TODO-KEYWORD PRIORITY REST)" 36 (multiple-value-bind (match subs) 37 ;; scan for todo-keyword 38 (scan-to-strings org-todo-keyword-rx input) 40 (let ((k (aref subs 0))) 41 (if-let ((%kw (org-parse :todo-keyword k))) 42 (let* ((next (aref subs 1)) 43 (prio? (org-parse :priority next))) 46 rest (if prio? (trim (subseq next 4)) next))) 47 (setq rest (trim match)))) 49 (let* ((next (trim input)) 50 (prio? (org-parse :priority next))) 51 (setq kw nil ;; kw always comes before priority. 52 prio (org-parse :priority next) 53 rest (if prio? (subseq next 4) next))))) 54 (values kw prio rest))) 56 (define-org-element tag 57 ((name :initform "" :initarg :name :type string))) 59 (define-org-parser (tag :from string) 60 (org-create type :name input)) 63 ;; when level=0, headline is uninitialized 64 (define-org-element headline 65 ((stars :initarg :stars :accessor hl-stars :initform 0) 66 (keyword :initarg :kw :accessor hl-kw :initform nil) 67 (priority :initarg :priority :accessor hl-priority :initform nil) 68 (title :initarg :title :accessor hl-title :initform "") 69 (tags :initarg :tags :accessor hl-tags :initform nil)) 70 :documentation "Org Headline object without connection to other 71 elements. This is a deviation from the org-element specification in 72 the name of utility. Properties, Logbook, and Body objects are 73 defined separately too, so a complete Heading object can be 74 summarized as a list of at most four elements: The headline, 75 properties, logbook and body.") 77 (defmethod org-parse ((type (eql :headline)) (input string)) 78 (let ((res (org-create type))) 79 (with-input-from-string (s input) 80 ;; first we parse 'just' the headline 81 (when (peek-char #\* s) 82 (let ((line (read-line s))) 83 (multiple-value-bind (start _ reg-start reg-end) 85 (cl-ppcre:scan org-headline-rx line) 88 (loop for rs across reg-start 93 (setf (hl-stars res) (- re rs)) 94 (multiple-value-bind (kw prio title) 95 (org-parse-todo-keyword-and-priority (subseq line rs)) 97 (hl-priority res) prio 98 (hl-title res) title)))))) 99 ;; scan for tags, modifies title slot 100 (let ((tag-str (cl-ppcre:scan-to-strings org-tag-rx (hl-title res)))) 102 (setf (hl-tags res) (apply #'vector (mapcar (lambda (x) (org-create :tag :name x)) (org-tag-split tag-str))) 103 ;; Q 2023-12-27: should we preserve whitespace here? 104 (hl-title res) (string-right-trim 106 (subseq (hl-title res) 0 (- (length (hl-title res)) 1 (length tag-str))))))))) 107 ;; TODO 2023-07-24: cookies,priority,comment,footnote,archive