From cfa0462972a45afd1135ce4814e0652ae68271f8 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 26 Aug 2024 03:58:43 +0300 Subject: packaging: Version 0.4.2-dev * Begin development 0.4.2-dev. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnosis.el b/gnosis.el index 3c04826..e0165e6 100644 --- a/gnosis.el +++ b/gnosis.el @@ -5,7 +5,7 @@ ;; Author: Thanos Apollo ;; Keywords: extensions ;; URL: https://thanosapollo.org/projects/gnosis -;; Version: 0.4.1 +;; Version: 0.4.2-dev ;; Package-Requires: ((emacs "27.2") (emacsql "4.0.0") (compat "29.1.4.2") (transient "0.7.2")) -- cgit v1.2.3 From 11e526b4965412c1632461eb3961b6ebb22d8ec9 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 26 Aug 2024 03:59:41 +0300 Subject: New module: gnosis-org: Use org-mode with gnosis. * This module will handle exports of decks as org files. * Sync of org files/deck exports with database. The main goal of incorporating org-mode is to promote collaboration of decks through git integration. --- gnosis-org.el | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 gnosis-org.el diff --git a/gnosis-org.el b/gnosis-org.el new file mode 100644 index 0000000..e194e88 --- /dev/null +++ b/gnosis-org.el @@ -0,0 +1,87 @@ +;;; gnosis-org.el --- Org module for Gnosis -*- lexical-binding: t; -*- + +;; Copyright (C) 2023-2024 Thanos Apollo + +;; Author: Thanos Apollo +;; 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 . + +;;; Commentary: + +;; Under development. + +;;; Code: + +(require 'cl-lib) +(require 'org) +(require 'org-element) + +(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)))) + +(cl-defun gnosis-org-insert-custom-heading (&key main id body type (buffer (current-buffer))) + "Insert an Org heading in BUFFER. + +- MAIN as the title. +- ID as CUSTOM_ID. +- BODY as the content. +- TYPE as the note type. + +If BUFFER is not specified, defaults to the current buffer." + (cl-assert (stringp main) nil "MAIN must be a string representing the heading title.") + (cl-assert (stringp id) nil "ID must be a string representing the CUSTOM_ID.") + (cl-assert (stringp body) nil "BODY must be a string representing the content.") + (cl-assert (stringp type) nil "TYPE must be a string representing the TYPE property.") + (with-current-buffer buffer + (goto-char (point-max)) ;; Ensure we're at the end of the buffer + (insert (format "* %s\n:PROPERTIES:\n:CUSTOM_ID: %s\n:TYPE: %s\n:END:\n%s\n" main id type body)) + (message "Inserted heading: %s with CUSTOM_ID %s and TYPE %s" main id type))) + +(provide 'gnosis-org) +;;; gnosis-org.el ends here. -- cgit v1.2.3 From 061633adca08d6978a694ad408cb42cda3b11697 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 26 Aug 2024 06:20:48 +0300 Subject: packaging: Require emacsql-4.0.1. * Require latest version of emacsql, supported by nongnu. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnosis.el b/gnosis.el index e0165e6..83fbb0a 100644 --- a/gnosis.el +++ b/gnosis.el @@ -7,7 +7,7 @@ ;; URL: https://thanosapollo.org/projects/gnosis ;; Version: 0.4.2-dev -;; Package-Requires: ((emacs "27.2") (emacsql "4.0.0") (compat "29.1.4.2") (transient "0.7.2")) +;; Package-Requires: ((emacs "27.2") (emacsql "4.0.1") (compat "29.1.4.2") (transient "0.7.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 -- cgit v1.2.3 From 487d903de1f3f7463206a52cd480d123331e4c7c Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 26 Aug 2024 06:27:44 +0300 Subject: New file: Add manifest.scm * Packages to run 'make'. --- manifest.scm | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 manifest.scm diff --git a/manifest.scm b/manifest.scm new file mode 100644 index 0000000..ce98337 --- /dev/null +++ b/manifest.scm @@ -0,0 +1,3 @@ +;; +(specifications->manifest + (list "make" "texinfo" "emacs" "emacs-org")) -- cgit v1.2.3 From 4d90489c5bb573ff547723b8caeb0a2b6cf7eb50 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 26 Aug 2024 06:28:35 +0300 Subject: elpaignore: Add manifest.scm --- .elpaignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.elpaignore b/.elpaignore index d8ed22f..9a93dad 100644 --- a/.elpaignore +++ b/.elpaignore @@ -1,3 +1,4 @@ CONTRIBUTING.org LICENSE Makefile +manifest.scm -- cgit v1.2.3 From 907308c45e8221fedb8c34596cd57497c2736c01 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 26 Aug 2024 06:31:06 +0300 Subject: makefile: Add tests & use quick (-Q) option. --- Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4ee28ad..9b1a262 100644 --- a/Makefile +++ b/Makefile @@ -6,15 +6,21 @@ EMACS = emacs ORG := doc/gnosis.org TEXI := doc/gnosis.texi INFO := doc/gnosis.info - +TEST_FILE := gnosis-test.el all: doc doc: $(ORG) $(EMACS) --batch \ + -Q \ --load org \ --eval "(with-current-buffer (find-file \"$(ORG)\") (org-texinfo-export-to-texinfo) (org-texinfo-export-to-info) (save-buffer))" \ --kill +test: + $(EMACS) --batch \ + --load $(TEST_FILE) \ + --eval "(ert-run-tests-batch-and-exit)" + clean: rm -f $(TEXI) $(INFO) -- cgit v1.2.3 From 48ca4aa6f2420676de468f3ce43608d4cab41fca Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 27 Aug 2024 02:14:35 +0300 Subject: [Refactor] Rewrite org-insert-heading * Adjust for list answers. * Use gnosis-id. --- gnosis-org.el | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/gnosis-org.el b/gnosis-org.el index e194e88..e977083 100644 --- a/gnosis-org.el +++ b/gnosis-org.el @@ -64,24 +64,29 @@ BUFFER defaults to the current buffer if not specified." (if results (reverse results) (message "No custom properties found for %s" property) nil)))) - -(cl-defun gnosis-org-insert-custom-heading (&key main id body type (buffer (current-buffer))) - "Insert an Org heading in BUFFER. +;; TODO: Add support for tags. +(cl-defun gnosis-org-insert-heading (&key main id answer type) + "Insert an Org heading in current buffer. - MAIN as the title. -- ID as CUSTOM_ID. -- BODY as the content. +- ID as GNOSIS_ID. +- ANSWER as the subheading. - TYPE as the note type. If BUFFER is not specified, defaults to the current buffer." (cl-assert (stringp main) nil "MAIN must be a string representing the heading title.") - (cl-assert (stringp id) nil "ID must be a string representing the CUSTOM_ID.") - (cl-assert (stringp body) nil "BODY must be a string representing the content.") + (cl-assert (stringp id) nil "ID must be a string representing the GNOSIS_ID.") (cl-assert (stringp type) nil "TYPE must be a string representing the TYPE property.") - (with-current-buffer buffer + (let ((main (if (string-match-p "\n" main) (replace-regexp-in-string "\n" "\\\\n" main) main)) + (answer (cond ((stringp answer) + answer) + ((numberp answer) + (number-to-string answer)) + (t (mapconcat 'identity answer ", "))))) (goto-char (point-max)) ;; Ensure we're at the end of the buffer - (insert (format "* %s\n:PROPERTIES:\n:CUSTOM_ID: %s\n:TYPE: %s\n:END:\n%s\n" main id type body)) - (message "Inserted heading: %s with CUSTOM_ID %s and TYPE %s" main id type))) + (insert (format "* %s\n:PROPERTIES:\n:GNOSIS_ID: %s\n:TYPE: %s\n:END:\n** %s\n" + main id type answer)) + (message "Inserted heading: %s with GNOSIS_ID %s and TYPE %s" main id type))) (provide 'gnosis-org) ;;; gnosis-org.el ends here. -- cgit v1.2.3 From bb1469aad5e488f1cf5ed1983feee3ee283a7152 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 27 Aug 2024 02:23:25 +0300 Subject: Update todos. * Update todos to work with magit-todos. --- gnosis.el | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gnosis.el b/gnosis.el index 83fbb0a..5476d52 100644 --- a/gnosis.el +++ b/gnosis.el @@ -217,7 +217,7 @@ When nil, review new notes last." (defvar gnosis-review-notes nil "Review notes.") -;; TODO: Make this as a defcustom +;; TODO: Make this as a defcustom. (defvar gnosis-custom-values '((:deck "demo" (:proto (0 1 3) :anagnosis 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.5 :lethe 3)) (:tag "demo" (:proto (1 2) :anagnosis 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.45 :lethe 3))) @@ -1269,7 +1269,7 @@ Optionally, add cusotm PROMPT." (cl-loop for tags in (gnosis-select 'tags 'notes '1=1 t) nconc tags into all-tags finally return (delete-dups all-tags))) -;; TODO: Rewrite this using `gnosis-get-tag-notes'. +;; TODO: Rewrite this using gnosis-get-tag-notes. (defun gnosis-select-by-tag (input-tags &optional due suspended-p) "Return note ID's for every note with INPUT-TAGS. @@ -1389,8 +1389,8 @@ provided, use it as the default value." ;; Collecting note ids -;; TODO: Rewrite. Tags should be an input of strings, interactive -;; handling should be done by "helper" funcs +;; TODO: Rewrite this! Tags should be an input of strings, +;; interactive handling should be done by "helper" funcs (cl-defun gnosis-collect-note-ids (&key (tags nil) (due nil) (deck nil) (query nil)) "Return list of note ids based on TAGS, DUE, DECKS, QUERY. @@ -1739,7 +1739,7 @@ NOTE-COUNT: The number of notes reviewed in the session to be commited." (error "Git not found, please install git")) (unless (file-exists-p (expand-file-name ".git" gnosis-dir)) (vc-create-repo 'Git)) - ;; TODO: Redo this using vc + ;; TODO: Redo this using vc. (unless gnosis-testing (shell-command (format "%s %s %s" git "add" (shell-quote-argument "gnosis.db"))) (shell-command (format "%s %s %s" git "commit -m" @@ -1834,7 +1834,7 @@ NOTE-COUNT: Total notes to be commited for session." (cl-incf note-count) (gnosis-review-actions success note note-count)) finally - ;; TODO: Add optional arg to repeat for specific deck/tag + ;; TODO: Add optional arg, repeat for specific deck/tag. ;; Repeat until there are no due notes (and due (gnosis-review-session (gnosis-collect-note-ids :due t) t note-count)))) (gnosis-dashboard) @@ -2251,7 +2251,7 @@ Defaults to current date." (let* ((date (or date (gnosis-algorithm-date))) (reviewed-new (or (car (gnosis-select 'reviewed-new 'activity-log `(= date ',date) t)) 0))) reviewed-new)) -;; TODO: Auto tag overdue tags +;; TODO: Auto tag overdue tags. (defun gnosis-tags--append (id tag) "Append TAG to the list of tags of note ID." (cl-assert (numberp id) nil "ID must be the note id number") -- cgit v1.2.3 From 56ed928045f20bb7e9a6840774d852599489a585 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 27 Aug 2024 02:24:21 +0300 Subject: export-deck: Add demo export. --- gnosis.el | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gnosis.el b/gnosis.el index 5476d52..2e8af51 100644 --- a/gnosis.el +++ b/gnosis.el @@ -50,6 +50,8 @@ (require 'gnosis-string-edit) (require 'gnosis-dashboard) +(require 'gnosis-org) + (require 'animate) (defgroup gnosis nil @@ -2509,6 +2511,19 @@ If STRING-SECTION is nil, apply FACE to the entire STRING." :tags note-tags)) (error "Demo deck already exists")))) +;; Export +;; This is a demo! +(defun gnosis-export-deck (&optional deck) + "Export contents of DECK." + (interactive (list (gnosis--get-deck-id))) + (with-current-buffer (get-buffer-create "*test*") + (insert (format "#+GNOSIS_DECK: %s\n\n" (gnosis--get-deck-name deck))) + (cl-loop for note in (gnosis-select '[main answer id type] 'notes `(= deck-id ,deck)) + do (gnosis-org-insert-heading :main (car note) + :answer (cadr note) + :id (number-to-string (caddr note)) + :type (cadddr note))))) + ;; Gnosis mode ;; ;;;;;;;;;;;;;;;;; -- cgit v1.2.3 From a783b56772fe44111395e3045cfebbf986259495 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 2 Sep 2024 09:31:23 +0300 Subject: New function: Add validate-custom-values. * Function to be used with a variable watcher to validate custom gnosis values. --- gnosis.el | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/gnosis.el b/gnosis.el index 2e8af51..61ab5db 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2017,6 +2017,35 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (gnosis-update 'notes `(= ,field ',value) `(= id ,id))) (t (gnosis-update 'notes `(= ,field ,value) `(= id ,id)))))) +(defun gnosis-validate-custom-values (new-value) + "Validate the structure and values of NEW-VALUE for gnosis-custom-values." + (unless (listp new-value) + (error "GNOSIS-CUSTOM-VALUES should be a list of entries")) + (dolist (entry new-value) + (unless (and (listp entry) (= (length entry) 3) + (memq (nth 0 entry) '(:deck :tag)) + (stringp (nth 1 entry)) + (listp (nth 2 entry))) ; Ensure the third element is a plist + (error "Each entry should a :deck or :tag keyword, a string, and a plist of custom values")) + (let ((nested-plist (nth 2 entry)) + (proto (plist-get (nth 2 entry) :proto)) + (anagnosis (plist-get (nth 2 entry) :anagnosis)) + (epignosis (plist-get (nth 2 entry) :epignosis)) + (agnoia (plist-get (nth 2 entry) :agnoia)) + (amnesia (plist-get (nth 2 entry) :amnesia)) + (lethe (plist-get (nth 2 entry) :lethe))) + (unless (listp proto) + (error "Proto must be a list of interval integer values")) + (unless (or (null anagnosis) (integerp anagnosis)) + (error "Anagnosis should be an integer")) + (unless (or (null epignosis) (numberp epignosis)) + (error "Epignosis should be a number")) + (unless (or (null agnoia) (numberp agnoia)) + (error "Agnoia should be a number")) + (unless (or (null amnesia) (and (numberp amnesia) (<= amnesia 1) (>= amnesia 0))) + (error "Amnesia should be a number between 0 and 1")) + (unless (or (null lethe) (and (integerp lethe) (> lethe 0))) + (error "Lethe should be an integer greater than 0"))))) (defun gnosis-get-custom-values--validate (plist valid-keywords) "Verify that PLIST consists of VALID-KEYWORDS." (let ((keys (let (ks) -- cgit v1.2.3 From 1e8e5fc529ad7dd1f1ca0fb8988cd309e3e24bd8 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 2 Sep 2024 09:32:18 +0300 Subject: New variable-watcher: custom-values-watcher. * Watch & validate new custom gnosis values. --- gnosis.el | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gnosis.el b/gnosis.el index 61ab5db..caef741 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2027,8 +2027,7 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (stringp (nth 1 entry)) (listp (nth 2 entry))) ; Ensure the third element is a plist (error "Each entry should a :deck or :tag keyword, a string, and a plist of custom values")) - (let ((nested-plist (nth 2 entry)) - (proto (plist-get (nth 2 entry) :proto)) + (let ((proto (plist-get (nth 2 entry) :proto)) (anagnosis (plist-get (nth 2 entry) :anagnosis)) (epignosis (plist-get (nth 2 entry) :epignosis)) (agnoia (plist-get (nth 2 entry) :agnoia)) @@ -2046,6 +2045,20 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (error "Amnesia should be a number between 0 and 1")) (unless (or (null lethe) (and (integerp lethe) (> lethe 0))) (error "Lethe should be an integer greater than 0"))))) + +(defun gnosis-custom-values-watcher (symbol new-value _operation _where) + "Watcher for gnosis custom values. + +SYMBOL to watch changes for. +NEW-VALUE is the new value set to the variable. +OPERATION is the type of operation being performed. +WHERE is the buffer or object where the change happens." + (when (eq symbol 'gnosis-custom-values) + (gnosis-validate-custom-values new-value))) + +(add-variable-watcher 'gnosis-custom-values 'gnosis-custom-values-watcher) + +;; Validate custom values during review process as well. (defun gnosis-get-custom-values--validate (plist valid-keywords) "Verify that PLIST consists of VALID-KEYWORDS." (let ((keys (let (ks) -- cgit v1.2.3 From 02a4e1352025e023d4345cd7dd71ae063d396538 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 2 Sep 2024 10:06:14 +0300 Subject: [fix] display-images: Display images only on graphical envs. * Fix issues for running gnosis on tty & termux. --- gnosis.el | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/gnosis.el b/gnosis.el index caef741..db5a6f4 100644 --- a/gnosis.el +++ b/gnosis.el @@ -484,19 +484,21 @@ or =extra-image'. Instead of using =extra-image' post review, prefer =gnosis-display-extra' which displays the =extra-image' as well. Refer to =gnosis-db-schema-extras' for informations on images stored." - (let* ((img (gnosis-get image 'extras `(= id ,id))) - (path-to-image (expand-file-name (or img "") (file-name-as-directory gnosis-images-dir))) - (image (create-image path-to-image 'png nil :width gnosis-image-width :height gnosis-image-height)) - (image-width (car (image-size image t))) - (frame-width (window-text-width))) ;; Width of the current window in columns - (cond ((or (not img) (string-empty-p img)) - (insert "\n\n")) - ((and img (file-exists-p path-to-image)) - (let* ((padding-cols (/ (- frame-width (floor (/ image-width (frame-char-width)))) 2)) - (padding (make-string (max 0 padding-cols) ?\s))) - (insert "\n\n" padding) ;; Insert padding before the image - (insert-image image) - (insert "\n\n")))))) + ;; Only display images on graphical env + (when (display-graphic-p) + (let* ((img (gnosis-get image 'extras `(= id ,id))) + (path-to-image (expand-file-name (or img "") (file-name-as-directory gnosis-images-dir))) + (image (create-image path-to-image 'png nil :width gnosis-image-width :height gnosis-image-height)) + (image-width (car (image-size image t))) + (frame-width (window-text-width))) ;; Width of the current window in columns + (cond ((or (not img) (string-empty-p img)) + (insert "\n\n")) + ((and img (file-exists-p path-to-image)) + (let* ((padding-cols (/ (- frame-width (floor (/ image-width (frame-char-width)))) 2)) + (padding (make-string (max 0 padding-cols) ?\s))) + (insert "\n\n" padding) ;; Insert padding before the image + (insert-image image) + (insert "\n\n"))))))) (defun gnosis-display-mcq-options (id) "Display answer options for mcq note ID." -- cgit v1.2.3 From 88a32f19180e36ce31f1819171ce9a9337c70568 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Thu, 5 Sep 2024 18:56:24 +0300 Subject: edit-update-note: Update assertions. * Update assertions, to avoid edits that will lead to bugs such as inserting numbers to the tags list. --- gnosis.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gnosis.el b/gnosis.el index db5a6f4..a722fe1 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1986,10 +1986,12 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" "Second-image must be a string, path to image file from `gnosis-images-dir', or nil") (cl-assert (or (stringp extra-notes) (null extra-notes)) nil "Extra-notes must be a string, or nil") - (cl-assert (listp tags) nil "Tags must be a list of strings") - (cl-assert (and (listp gnosis) (length= gnosis 3)) nil "gnosis must be a list of 3 floats") - (cl-assert (or (stringp options) (listp options)) nil "Options must be a string, or a list for MCQ") - (cl-assert (or (= suspend 0) (= suspend 1)) nil "Suspend must be either 0 or 1") + (cl-assert (and (listp tags) (cl-every #'stringp tags)) nil "Tags must be a list of strings") + (cl-assert (and (listp gnosis) (length= gnosis 3) (cl-every #'floatp gnosis)) + nil "gnosis must be a list of 3 floats") + (cl-assert (or (stringp options) (and (listp options) (cl-every #'stringp options))) + nil "Options must be a string or a list of strings") + (cl-assert (and (numberp suspend) (or (= suspend 0) (= suspend 1))) nil "Suspend must be either 0 or 1") (when (and (string= (gnosis-get-type id) "cloze") (not (stringp options))) (cl-assert (or (listp options) (stringp options)) nil "Options must be a list or a string.") -- cgit v1.2.3 From 8f0bb68c87843fee900b2bb10567fae96afe5186 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Thu, 5 Sep 2024 18:58:29 +0300 Subject: demo: Update formatting (aesthetics). * Adjust extras formatting of y-or-p exapmle to avoid breakage. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnosis.el b/gnosis.el index a722fe1..40e4061 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2548,7 +2548,7 @@ If STRING-SECTION is nil, apply FACE to the entire STRING." (gnosis-add-note--cloze :deck deck-name :note "GNU Emacs is an extensible editor created by {{c1::Richard}} {{c1::Stallman}} in {{c2::1984::year}}" :tags note-tags - :extra "Emacs was originally implemented in 1976 on the MIT AI Lab's Incompatible Timesharing System (ITS), as a collection of TECO macros. The name “Emacs” was originally chosen as an abbreviation of “Editor MACroS”. =This version of Emacs=, GNU Emacs, was originally *written in 1984*") + :extra "Emacs was originally implemented in 1976 on the MIT AI Lab's Incompatible Timesharing System (ITS), as a collection of TECO macros. The name “Emacs” was originally chosen as an abbreviation of “Editor MACroS”. This version of Emacs, =GNU= =Emacs=, was originally written in _1984_") (gnosis-add-note--y-or-n :deck deck-name :question "Is GNU Emacs the unparalleled pinnacle of all software creation?" :hint "Duh" -- cgit v1.2.3 From 52da178372d118875aa986ea455ef05e0430fbde Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Thu, 5 Sep 2024 19:00:12 +0300 Subject: Rewrite README as markdown * Rewrite README as markdown to work with nongnu elpa. --- README | 9 --------- README.md | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 README create mode 100644 README.md diff --git a/README b/README deleted file mode 100644 index 34e8089..0000000 --- a/README +++ /dev/null @@ -1,9 +0,0 @@ - -Gnosis (γνῶσις) -==== - -Gnosis (γνῶσις), pronounced "noh-sis", meaning knowledge in Greek, -is a Spaced Repetition System for note taking and self testing. - -- Project's Page: -- User Manual: diff --git a/README.md b/README.md new file mode 100644 index 0000000..8ed18df --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Γνῶσις | Gnosis + +## About + +Γνῶσις (gnosis), pronounced "GNU-sis", meaning knowledge in Greek, +is a GNU Emacs Spaced Repetition System for storing knowledge. + +- [Project's Page](https://thanosapollo.org/projects/gnosis/) +- [User Manual](https://elpa.nongnu.org/nongnu/doc/gnosis.html) -- cgit v1.2.3 From f9c6885cd56cd2e929992c1fa319b527f179a6cd Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Thu, 5 Sep 2024 19:23:39 +0300 Subject: doc: Update for new version. * Update manual entries. * Fix typos. * Adjust section for customizing note types. --- doc/gnosis.org | 60 ++++++++++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/doc/gnosis.org b/doc/gnosis.org index 15afc52..9d0efb9 100644 --- a/doc/gnosis.org +++ b/doc/gnosis.org @@ -4,8 +4,8 @@ #+language: en #+options: ':t toc:nil author:t email:t num:t #+startup: content -#+macro: stable-version 0.4.0 -#+macro: release-date 2024-08-7 +#+macro: stable-version 0.4.2 +#+macro: release-date 2024-09-5 #+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ #+macro: space @@texinfo:@: @@ #+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@ @@ -22,15 +22,16 @@ #+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:public@thanosapollo.org,contact the maintainer} -Gnosis is a customizable spaced repetition system designed to enhance +Gnosis (GNU-sis) is a customizable spaced repetition system designed to enhance memory retention through active recall. It allows users to set specific review intervals for note decks & tags, creating an optimal -learning environment tailored to each specific topic. +learning environment tailored to each specific topic/subject. #+texinfo: @noindent This manual is written for Gnosis version {{{stable-version}}}, released on {{{release-date}}}. -+ Official manual: ++ Official manual: + + + Git repositories: + @@ -260,7 +261,6 @@ name suggests, they rely on =vc= to work properly. Depending on your setup, =vc= might require an external package for the ssh passphrase dialog, such as ~x11-ssh-askpass~. - To automatically push changes after a review session, add this to your configuration: #+begin_src emacs-lisp (setf gnosis-vc-auto-push t) @@ -268,44 +268,30 @@ To automatically push changes after a review session, add this to your configura #+end_src * Configuring Note Types -** Adjust Current Types Entries +** Custom Note Types Each gnosis note type has an /interactive/ function, named -=gnosis-add-note-TYPE=. You can set default values for each entry by -hard coding specific values to their keywords. +=gnosis-add-note-TYPE= and a "hidden" function +named =gnosis-add-note--TYPE=. You can create your own custom interactive +functions to ignore or hard-code specific values by using already +defined hidden functions that handle all the logic. For example: #+begin_src emacs-lisp -(defun gnosis-add-note-basic (deck) - (gnosis-add-note--basic :deck deck - :question (gnosis-read-string-from-buffer "Question: " "") - :answer (read-string "Answer: ") - :hint (gnosis-hint-prompt gnosis-previous-note-hint) - :extra "" - :images nil - :tags (gnosis-prompt-tags--split gnosis-previous-note-tags))) + (defun gnosis-add-note-custombasic (deck) + (gnosis-add-note--basic :deck deck + :question (gnosis-read-string-from-buffer "Question: " "") + :answer (read-string "Answer: ") + :hint (gnosis-hint-prompt gnosis-previous-note-hint) + :extra "" + :images nil + :tags (gnosis-prompt-tags--split gnosis-previous-note-tags))) + ;; Add custom note type to gnosis-note-types + (add-to-list 'gnosis-note-types "custombasic") #+end_src -By evaluating the above code snippet, you won't be prompted to enter -anything for ~extra~ & ~images~. -** Creating Custom Note Types - -Creating custom note types for gnosis is a fairly simple thing to do - -+ First add your NEW-TYPE to =gnosis-note-types= - - #+begin_src emacs-lisp - (add-to-list 'gnosis-note-types "NEW-TYPE") - #+end_src -+ Create an interactive function - -Each note type has a =gnosis-add-note-TYPE= that is used interactively -& a "hidden function" =gnosis-add-note--TYPE= that handles all the -logic. You can use one of the =current gnosis-add-note--TYPE= -functions or create one of your own. - -Refer to =gnosis-add-note-basic= & =gnosis-add-note--basic= for a simple -example of how this is done, as well as =gnosis-add-note-double=. +Now ~custombasic~ is available as a note type, for which you won't be prompted to enter +anything for ~extra~ & ~images~. ** Development To make development and customization easier, gnosis comes with -- cgit v1.2.3 From d034335bde30c7873768bfbbae531a704d011245 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Thu, 5 Sep 2024 19:24:20 +0300 Subject: Packaging: Add version 0.4.2. * Comment out gnosis-org sections that are under development. * Fix display issues on non-grapical interface. * Add variable watchers for custom algorithm values. * Update assertions for editing notes This is a minor release with a few bug fixes. --- gnosis.el | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/gnosis.el b/gnosis.el index 40e4061..4619fa9 100644 --- a/gnosis.el +++ b/gnosis.el @@ -5,7 +5,7 @@ ;; Author: Thanos Apollo ;; Keywords: extensions ;; URL: https://thanosapollo.org/projects/gnosis -;; Version: 0.4.2-dev +;; Version: 0.4.2 ;; Package-Requires: ((emacs "27.2") (emacsql "4.0.1") (compat "29.1.4.2") (transient "0.7.2")) @@ -50,7 +50,7 @@ (require 'gnosis-string-edit) (require 'gnosis-dashboard) -(require 'gnosis-org) +;; (require 'gnosis-org) (require 'animate) @@ -2557,18 +2557,17 @@ If STRING-SECTION is nil, apply FACE to the entire STRING." :tags note-tags)) (error "Demo deck already exists")))) -;; Export -;; This is a demo! -(defun gnosis-export-deck (&optional deck) - "Export contents of DECK." - (interactive (list (gnosis--get-deck-id))) - (with-current-buffer (get-buffer-create "*test*") - (insert (format "#+GNOSIS_DECK: %s\n\n" (gnosis--get-deck-name deck))) - (cl-loop for note in (gnosis-select '[main answer id type] 'notes `(= deck-id ,deck)) - do (gnosis-org-insert-heading :main (car note) - :answer (cadr note) - :id (number-to-string (caddr note)) - :type (cadddr note))))) +;; TODO: Add Export funcs +;; (defun gnosis-export-deck (&optional deck) +;; "Export contents of DECK." +;; (interactive (list (gnosis--get-deck-id))) +;; (with-current-buffer (get-buffer-create "*test*") +;; (insert (format "#+GNOSIS_DECK: %s\n\n" (gnosis--get-deck-name deck))) +;; (cl-loop for note in (gnosis-select '[main answer id type] 'notes `(= deck-id ,deck)) +;; do (gnosis-org-insert-heading :main (car note) +;; :answer (cadr note) +;; :id (number-to-string (caddr note)) +;; :type (cadddr note))))) ;; Gnosis mode ;; ;;;;;;;;;;;;;;;;; -- cgit v1.2.3