branch: elpa/gnosis
commit c104fed6d91e8212838249028cad0ec51c7bdbdb
Author: Thanos Apollo <pub...@thanosapollo.org>
Commit: Thanos Apollo <pub...@thanosapollo.org>

    [Refactor] Remove gnosis-org module
    
    + Rewrite gnosis-org module as gnosis-export functions inside gnosis.el
---
 gnosis-org.el | 201 ----------------------------------------------------------
 gnosis.el     | 150 +++++++++++++++++++++++++++++++++++--------
 2 files changed, 125 insertions(+), 226 deletions(-)

diff --git a/gnosis-org.el b/gnosis-org.el
deleted file mode 100644
index f55093e197..0000000000
--- a/gnosis-org.el
+++ /dev/null
@@ -1,201 +0,0 @@
-;;; gnosis-org.el --- Org module for Gnosis  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2023-2024  Thanos Apollo
-
-;; Author: Thanos Apollo <pub...@thanosapollo.org>
-;; Keywords: extensions
-;; URL: https://git.thanosapollo.org/gnosis
-;; Version: 0.0.1
-
-;; Package-Requires: ((emacs "27.2") (compat "29.1.4.2"))
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This module provides parsing of org-mode buffers for gnosis.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'org)
-(require 'org-element)
-
-(defvar gnosis-org-separator "\n- ")
-
-(defun gnosis-org--global-props (name &optional buffer)
-  "Get the plists of global org properties by NAME in BUFFER.
-
-NAME is a string representing the property name to search for.
-BUFFER defaults to the current buffer if not specified."
-  (cl-assert (stringp name) nil "NAME must be a string.")
-  (with-current-buffer (or buffer (current-buffer))
-    (let ((elements (org-element-map (org-element-parse-buffer) 'keyword
-                      (lambda (el)
-                        (when (string= (org-element-property :key el) name)
-                          el))
-                      nil t)))
-      (if elements elements
-        (message "No properties found for %s" name)
-        nil))))
-
-(defun gnosis-org--heading-props (property &optional buffer)
-  "Get the values of a custom PROPERTY from all headings in BUFFER.
-
-PROPERTY is a string representing the property name to search for.
-BUFFER defaults to the current buffer if not specified."
-  (cl-assert (stringp property) nil "PROPERTY must be a string.")
-  (with-current-buffer (or buffer (current-buffer))
-    (let ((results nil))
-      (org-element-map (org-element-parse-buffer) 'headline
-        (lambda (headline)
-          (let ((prop (org-element-property (intern (concat ":" property)) 
headline)))
-            (when prop
-              (push prop results)))))
-      (if results (reverse results)
-        (message "No custom properties found for %s" property)
-        nil))))
-
-(defun gnosis-org--insert-read-only (string)
-  "Insert STRING as read-only."
-  (let ((start (point)))
-    (insert string)
-    ;; Set the just inserted string as read-only
-    (add-text-properties start (point) '(read-only t))
-    ;; Since the space is inserted outside of the read-only region, it's 
editable
-    (let ((inhibit-read-only t))
-      (insert " "))))
-
-(defun gnosis-org-make-read-only (&rest values)
-  "Make the provided VALUES read-only in the whole buffer."
-  (goto-char (point-min))
-  (dolist (value values)
-    (while (search-forward value nil t)
-      (put-text-property (match-beginning 0) (match-end 0) 'read-only t)))
-  (goto-char (point-min)))
-
-(cl-defun gnosis-org--insert-note (id type &optional keimenon hypothesis 
answer parathema tags example)
-  "Insert note for note ID.
-
-TYPE: Note type, refer to `gnosis-note-types'
-KEIMENON: Text user is first presented with.
-HYPOTHESIS: Hypothesis for what the ANSWER is
-ANSWER: The revelation after KEIMENON
-PARATHEMA: The text where NOTE is derived from.
-TAGS: List of NOTE tags
-EXAMPLE: Boolean value, if non-nil do not add properties for note."
-  (let ((components `(("** Keimenon" . ,keimenon)
-                      ("** Hypothesis" . ,hypothesis)
-                      ("** Answer" . ,answer)
-                      ("** Parathema" . ,parathema))))
-    (insert "\n* Thema")
-    (org-set-tags tags)
-    (unless example
-      (org-set-property "GNOSIS_ID" id)
-      (org-set-property "GNOSIS_TYPE" type)
-      (gnosis-org-make-read-only ":PROPERTIES:"
-                                (format "GNOSIS_ID: %s" id)
-                                (format "GNOSIS_TYPE: %s" type)
-                                ":END:"))
-    (dolist (comp components)
-      (goto-char (point-max))
-      (gnosis-org--insert-read-only (car comp))
-      (insert "\n" (or (cdr comp) "") "\n\n"))))
-
-(defun gnosis-org-parse--deck-name (&optional parsed-data)
-  "Retrieve deck name from PARSED-DATA."
-  (let* ((parsed-data (or parsed-data (org-element-parse-buffer)))
-        (title (org-element-map parsed-data 'keyword
-                 (lambda (kw)
-                   (when (string= (org-element-property :key kw) "DECK")
-                      (org-element-property :value kw)))
-                 nil t)))
-    title))
-
-(defun gnosis-org-parse-notes (&optional separator)
-  "Extract content for each level-2 heading for note headings with a GNOSIS_ID.
-
-Split content of Hypothesis and Answer headings using SEPARATOR."
-  (let ((sep (or separator gnosis-org-separator))
-        results)
-    (org-element-map (org-element-parse-buffer) 'headline
-      (lambda (headline)
-        (let* ((level (org-element-property :level headline))
-               (gnosis-id (org-element-property :GNOSIS_ID headline))
-               (gnosis-type (org-element-property :GNOSIS_TYPE headline))
-               (tags (org-element-property :tags headline)))
-          (when (and (= level 1) gnosis-id gnosis-type)
-            (let (entry)
-              (push gnosis-id entry)
-              (push gnosis-type entry)
-              (dolist (child (org-element-contents headline))
-                (when (eq 'headline (org-element-type child))
-                  (let* ((child-title (org-element-property :raw-value child))
-                         (child-text (substring-no-properties
-                                    (string-trim
-                                     (org-element-interpret-data
-                                      (org-element-contents child)))))
-                         (processed-text
-                          (cond
-                           ((and (member child-title '("Hypothesis" "Answer"))
-                                 (not (string-empty-p child-text)))
-                            (mapcar (lambda (s)
-                                    (string-trim
-                                     (string-remove-prefix "-"
-                                      (string-remove-prefix sep s))))
-                                  (split-string child-text sep t "[ \t\n]+")))
-                           ((string-empty-p child-text) nil)
-                           (t child-text))))
-                    (push processed-text entry))))
-              (push tags entry)
-              (push (nreverse entry) results)))))
-      nil nil)
-    results))
-
-;;;; TODO: Rewrite function that export deck without read-only values.
-;;;; Make them only with built-in to work with async.el
-;; (defun gnosis-org-export-deck (deck)
-;;   "Export DECK in an org file."
-;;   (interactive (list (gnosis--get-deck-id)))
-;;   ;; (find-file (read-file-name "File: "))
-;;   ;; TODO: Retrieve all values instead of just ids and then insert them 
async
-;;   (let* ((notes (append (gnosis-select '[type keimenon hypothesis answer 
tags] 'notes `(= deck-id ,deck))
-;;                     ;; (gnosis-select 'parathema 'extras `(= deck-id ,deck) 
t)
-;;                     nil))
-;;      (deck-name (car (gnosis-select 'name 'decks `(= id ,deck) t))))
-;;     (async-start
-;;      (lambda () (let ((inhibit-read-only 1))
-;;          (find-file (format "/tmp/%s.org" (downcase deck-name)))
-;;          (erase-buffer)
-;;          (org-mode)
-;;          (insert "#+DECK: " deck-name "\n\n")
-;;          (cl-loop for note in notes
-;;                   do
-;;                   (insert "\n* Thema")
-;;                   (insert "\n** Keimenon\n")
-;;                   (insert (format "\n%s\n" (nth 1 note))))
-;;          (save-buffer)))
-;;     ;; (let ((inhibit-read-only 1))
-;;     ;;   (erase-buffer))
-;;     ;; (org-mode)
-;;     ;; (insert "#+DECK: " deck-name)
-;;     ;; (org-set-property "GNOSIS_DECK" (number-to-string deck))
-;;     ;; (goto-char (point-max))
-;;     ;; (cl-loop for note in notes
-;;     ;;           do (gnosis-export-note note))
-;;     ;; (save-buffer)
-;;     )))
-
-(provide 'gnosis-org)
-;;; gnosis-org.el ends here.
diff --git a/gnosis.el b/gnosis.el
index 11e581411d..d92a4385e0 100644
--- a/gnosis.el
+++ b/gnosis.el
@@ -50,7 +50,6 @@
 (require 'animate)
 
 (require 'gnosis-algorithm)
-(require 'gnosis-org)
 
 (defgroup gnosis nil
   "Spaced Repetition System For Note Taking & Self Testing."
@@ -193,6 +192,8 @@ Avoid using an increased height value as this messes up with
 (defvar gnosis-review-notes nil
   "Review notes.")
 
+(defvar gnosis-separator "\n- ")
+
 ;; TODO: Make this as a defcustom.
 (defvar gnosis-custom-values
   '((:deck "demo" (:proto (0 1 3) :anagnosis 3 :epignosis 0.5 :agnoia 0.3
@@ -387,7 +388,7 @@ This will not be applied to sentences that start with 
double space."
                           (delete-region end (match-end 0))
                           (delete-region (match-beginning 0) start)))))))))))
 
-(defun gnosis-display-keimenon (str &optional fill-paragraph-p)
+(defun gnosis-display-keimenon (str)
   "Display STR as keimenon.
 
 If FILL-PARAGRAPH-P, insert question using `fill-paragraph'."
@@ -1748,6 +1749,120 @@ LINKS: List of id links in PARATHEMA."
                              answer parathema tags suspend links)
     (gnosis-update-note id keimenon hypothesis answer parathema tags links)))
 
+(defun gnosis-export--insert-read-only (string)
+  "Insert STRING as read-only."
+  (let ((start (point)))
+    (insert string)
+    ;; Set the just inserted string as read-only
+    (add-text-properties start (point) '(read-only t))
+    ;; Since the space is inserted outside of the read-only region, it's 
editable
+    (let ((inhibit-read-only t))
+      (insert " "))))
+
+(defun gnosis-export-make-read-only (&rest values)
+  "Make the provided VALUES read-only in the whole buffer."
+  (goto-char (point-min))
+  (dolist (value values)
+    (while (search-forward value nil t)
+      (put-text-property (match-beginning 0) (match-end 0) 'read-only t)))
+  (goto-char (point-min)))
+
+(cl-defun gnosis-export--insert-note (id type &optional keimenon hypothesis
+                                     answer parathema tags example)
+  "Insert note for note ID.
+
+TYPE: Note type, refer to `gnosis-note-types'
+KEIMENON: Text user is first presented with.
+HYPOTHESIS: Hypothesis for what the ANSWER is
+ANSWER: The revelation after KEIMENON
+PARATHEMA: The text where NOTE is derived from.
+TAGS: List of NOTE tags
+EXAMPLE: Boolean value, if non-nil do not add properties for note."
+  (let ((components `(("** Keimenon" . ,keimenon)
+                      ("** Hypothesis" . ,hypothesis)
+                      ("** Answer" . ,answer)
+                      ("** Parathema" . ,parathema))))
+    (insert "\n* Thema")
+    (org-set-tags tags)
+    (unless example
+      (org-set-property "GNOSIS_ID" id)
+      (org-set-property "GNOSIS_TYPE" type)
+      (gnosis-export-make-read-only ":PROPERTIES:"
+                                (format "GNOSIS_ID: %s" id)
+                                (format "GNOSIS_TYPE: %s" type)
+                                ":END:"))
+    (dolist (comp components)
+      (goto-char (point-max))
+      (gnosis-export--insert-read-only (car comp))
+      (insert "\n" (or (cdr comp) "") "\n\n"))))
+
+(defun gnosis-export-parse--deck-name (&optional parsed-data)
+  "Retrieve deck name from PARSED-DATA."
+  (let* ((parsed-data (or parsed-data (org-element-parse-buffer)))
+        (title (org-element-map parsed-data 'keyword
+                 (lambda (kw)
+                   (when (string= (org-element-property :key kw) "DECK")
+                      (org-element-property :value kw)))
+                 nil t)))
+    title))
+
+(defun gnosis-export-parse-notes (&optional separator)
+  "Extract content for each level-2 heading for note headings with a GNOSIS_ID.
+
+Split content of Hypothesis and Answer headings using SEPARATOR."
+  (let ((sep (or separator gnosis-separator))
+        results)
+    (org-element-map (org-element-parse-buffer) 'headline
+      (lambda (headline)
+        (let* ((level (org-element-property :level headline))
+               (gnosis-id (org-element-property :GNOSIS_ID headline))
+               (gnosis-type (org-element-property :GNOSIS_TYPE headline))
+               (tags (org-element-property :tags headline)))
+          (when (and (= level 1) gnosis-id gnosis-type)
+            (let (entry)
+              (push gnosis-id entry)
+              (push gnosis-type entry)
+              (dolist (child (org-element-contents headline))
+                (when (eq 'headline (org-element-type child))
+                  (let* ((child-title (org-element-property :raw-value child))
+                         (child-text (substring-no-properties
+                                    (string-trim
+                                     (org-element-interpret-data
+                                      (org-element-contents child)))))
+                         (processed-text
+                          (cond
+                           ((and (member child-title '("Hypothesis" "Answer"))
+                                 (not (string-empty-p child-text)))
+                            (mapcar (lambda (s)
+                                    (string-trim
+                                     (string-remove-prefix "-"
+                                      (string-remove-prefix sep s))))
+                                  (split-string child-text sep t "[ \t\n]+")))
+                           ((string-empty-p child-text) nil)
+                           (t child-text))))
+                    (push processed-text entry))))
+              (push tags entry)
+              (push (nreverse entry) results)))))
+      nil nil)
+    results))
+
+(defun gnosis-export-note (id)
+  "Export note with ID."
+  (let ((note-data (append (gnosis-select '[type keimenon hypothesis answer 
tags]
+                                         'notes `(= id ,id) t)
+                          (gnosis-select 'parathema 'extras `(= id ,id) t))))
+    (gnosis-export--insert-note (number-to-string id)
+                            (nth 0 note-data)
+                            (nth 1 note-data)
+                            (concat (string-remove-prefix "\n" 
gnosis-export-separator)
+                                    (mapconcat 'identity (nth 2 note-data)
+                                               gnosis-export-separator))
+                            (concat (string-remove-prefix "\n" 
gnosis-export-separator)
+                                    (mapconcat 'identity (nth 3 note-data)
+                                               gnosis-export-separator))
+                            (nth 5 note-data)
+                            (nth 4 note-data))))
+
 (defun gnosis-save-note (note deck)
   "Save NOTE for DECK."
   (let* ((id (nth 0 note))
@@ -1778,28 +1893,11 @@ LINKS: List of id links in PARATHEMA."
       (erase-buffer))
     (insert "#+DECK: " deck)
     (gnosis-edit-mode)
-    (gnosis-org--insert-note "NEW" type keimenon hypothesis
+    (gnosis-export--insert-note "NEW" type keimenon hypothesis
                              answer parathema tags example))
   (search-backward "keimenon")
   (forward-line))
 
-(defun gnosis-export-note (id)
-  "Export note with ID."
-  (let ((note-data (append (gnosis-select '[type keimenon hypothesis answer 
tags]
-                                         'notes `(= id ,id) t)
-                          (gnosis-select 'parathema 'extras `(= id ,id) t))))
-    (gnosis-org--insert-note (number-to-string id)
-                            (nth 0 note-data)
-                            (nth 1 note-data)
-                            (concat (string-remove-prefix "\n" 
gnosis-org-separator)
-                                    (mapconcat 'identity (nth 2 note-data)
-                                               gnosis-org-separator))
-                            (concat (string-remove-prefix "\n" 
gnosis-org-separator)
-                                    (mapconcat 'identity (nth 3 note-data)
-                                               gnosis-org-separator))
-                            (nth 5 note-data)
-                            (nth 4 note-data))))
-
 (defun gnosis-edit-note (id)
   "Edit note with ID."
   (window-configuration-to-register :gnosis-edit)
@@ -1817,8 +1915,8 @@ LINKS: List of id links in PARATHEMA."
 (defun gnosis-save ()
   "Save notes in current buffer."
   (interactive)
-  (let ((notes (gnosis-org-parse-notes))
-       (deck (gnosis--get-deck-id (gnosis-org-parse--deck-name))))
+  (let ((notes (gnosis-export-parse-notes))
+       (deck (gnosis--get-deck-id (gnosis-export-parse--deck-name))))
     (cl-loop for note in notes
             do (gnosis-save-note note deck))
     (gnosis-edit-quit)))
@@ -1927,7 +2025,8 @@ VALUES: Defaults to `gnosis-custom-values'."
     (cl-loop for tag in tags
             ;; Only collect non-nil values
             when (plist-get (gnosis-get-custom-values :tag tag custom-values) 
keyword)
-            collect (plist-get (gnosis-get-custom-values :tag tag 
custom-values) keyword))))
+            collect (plist-get (gnosis-get-custom-values :tag tag 
custom-values)
+                               keyword))))
 
 (defun gnosis-get-note-tag-amnesia (id &optional custom-tags custom-values)
   "Return tag MINIMUM amnesia for note ID.
@@ -1937,7 +2036,8 @@ amnesia i.e next interval to be 0.
 
 CUSTOM-TAGS: Specify tags for note id.
 CUSTOM-VALUES: Specify values for tags."
-  (let ((amnesia-values (gnosis-get-custom-tag-values id :amnesia custom-tags 
custom-values)))
+  (let ((amnesia-values (gnosis-get-custom-tag-values id :amnesia
+                                                     custom-tags 
custom-values)))
     (and amnesia-values (apply #'max amnesia-values))))
 
 (defun gnosis-get-note-deck-amnesia (id &optional custom-deck custom-values)
@@ -2382,7 +2482,7 @@ If STRING-SECTION is nil, apply FACE to the entire 
STRING."
     (insert (format "#+GNOSIS_DECK: %s\n\n" (gnosis--get-deck-name deck)))
     (cl-loop for note in (gnosis-select '[keimenon type answer id]
                                        'notes `(= deck-id ,deck))
-            do (gnosis-org--insert-note (number-to-string (car (last note)))
+            do (gnosis-export--insert-note (number-to-string (car (last note)))
                                          (cadr note)
                                          (car note)
                                          "hypo"

Reply via email to