Refine the code that constructs notes from entries.
This commit is contained in:
parent
38ef26aa01
commit
683c48dfec
1 changed files with 39 additions and 43 deletions
|
@ -309,32 +309,11 @@ The implementation is borrowed and simplified from ox-html."
|
||||||
(funcall oldfun link desc info)))
|
(funcall oldfun link desc info)))
|
||||||
|
|
||||||
|
|
||||||
;;; Utilities
|
|
||||||
|
|
||||||
(defun anki-editor--get-subheadings (heading)
|
|
||||||
"Get all the subheadings of HEADING."
|
|
||||||
(org-element-map (org-element-contents heading)
|
|
||||||
'headline 'identity nil nil 'headline))
|
|
||||||
|
|
||||||
|
|
||||||
;;; Core Functions
|
;;; Core Functions
|
||||||
|
|
||||||
(defun anki-editor--process-note-heading ()
|
(defun anki-editor--process-note-heading ()
|
||||||
"Process note heading at point."
|
"Process note heading at point."
|
||||||
(-->
|
(anki-editor--push-note (anki-editor-note-at-point)))
|
||||||
(org-element-at-point)
|
|
||||||
(let ((content (buffer-substring
|
|
||||||
(org-element-property :begin it)
|
|
||||||
;; in case the buffer is narrowed,
|
|
||||||
;; e.g. by `org-map-entries' when
|
|
||||||
;; scope is `tree'
|
|
||||||
(min (point-max) (org-element-property :end it)))))
|
|
||||||
(with-temp-buffer
|
|
||||||
(org-mode)
|
|
||||||
(insert content)
|
|
||||||
(car (org-element-contents (org-element-parse-buffer)))))
|
|
||||||
(anki-editor--heading-to-note it)
|
|
||||||
(anki-editor--save-note it)))
|
|
||||||
|
|
||||||
(defun anki-editor--insert-note-skeleton (prefix deck heading note-type fields)
|
(defun anki-editor--insert-note-skeleton (prefix deck heading note-type fields)
|
||||||
"Insert a note subtree (skeleton) with HEADING, NOTE-TYPE and FIELDS.
|
"Insert a note subtree (skeleton) with HEADING, NOTE-TYPE and FIELDS.
|
||||||
|
@ -358,7 +337,7 @@ Where the subtree is created depends on PREFIX."
|
||||||
(org-do-demote)
|
(org-do-demote)
|
||||||
(insert field))))
|
(insert field))))
|
||||||
|
|
||||||
(defun anki-editor--save-note (note)
|
(defun anki-editor--push-note (note)
|
||||||
"Request AnkiConnect for updating or creating NOTE."
|
"Request AnkiConnect for updating or creating NOTE."
|
||||||
(if (= (alist-get 'note-id note) -1)
|
(if (= (alist-get 'note-id note) -1)
|
||||||
(anki-editor--create-note note)
|
(anki-editor--create-note note)
|
||||||
|
@ -469,14 +448,14 @@ Do nothing when JUST-ALIGN is non-nil."
|
||||||
"Get note types from Anki."
|
"Get note types from Anki."
|
||||||
(anki-editor--anki-connect-invoke-result "modelNames"))
|
(anki-editor--anki-connect-invoke-result "modelNames"))
|
||||||
|
|
||||||
(defun anki-editor--heading-to-note (heading)
|
(defun anki-editor-note-at-point ()
|
||||||
"Construct an alist representing a note for HEADING."
|
"Construct an alist representing a note from current entry."
|
||||||
(let ((org-trust-scanner-tags t)
|
(let ((org-trust-scanner-tags t)
|
||||||
(deck (org-entry-get-with-inheritance anki-editor-prop-deck))
|
(deck (org-entry-get-with-inheritance anki-editor-prop-deck))
|
||||||
(note-id (org-entry-get nil anki-editor-prop-note-id))
|
(note-id (org-entry-get nil anki-editor-prop-note-id))
|
||||||
(note-type (org-entry-get nil anki-editor-prop-note-type))
|
(note-type (org-entry-get nil anki-editor-prop-note-type))
|
||||||
(tags (org-get-tags-at))
|
(tags (org-get-tags-at))
|
||||||
(fields (mapcar #'anki-editor--heading-to-note-field (anki-editor--get-subheadings heading))))
|
(fields (anki-editor--build-fields)))
|
||||||
|
|
||||||
(unless deck (error "No deck specified"))
|
(unless deck (error "No deck specified"))
|
||||||
(unless note-type (error "Missing note type"))
|
(unless note-type (error "Missing note type"))
|
||||||
|
@ -488,23 +467,38 @@ Do nothing when JUST-ALIGN is non-nil."
|
||||||
(tags . ,tags)
|
(tags . ,tags)
|
||||||
(fields . ,fields))))
|
(fields . ,fields))))
|
||||||
|
|
||||||
(defun anki-editor--heading-to-note-field (heading)
|
(defun anki-editor--build-fields ()
|
||||||
"Convert HEADING to field data, a cons cell, the car of which is the field name, the cdr of which is contens represented in HTML."
|
"Build a list of fields from subheadings of current heading, each element of which is a cons cell, the car of which is field name and the cdr of which is field content."
|
||||||
(let ((inhibit-message t) ;; suppress echo message from `org-babel-exp-src-block'
|
(save-excursion
|
||||||
(field-name (substring-no-properties
|
(let (fields
|
||||||
(org-element-property
|
(point-of-last-child (point)))
|
||||||
:raw-value
|
(when (org-goto-first-child)
|
||||||
heading)))
|
(while (/= point-of-last-child (point))
|
||||||
(contents (org-element-contents heading)))
|
(setq point-of-last-child (point))
|
||||||
|
(let* ((inhibit-message t) ;; suppress echo message from `org-babel-exp-src-block'
|
||||||
|
(field-heading (org-element-at-point))
|
||||||
|
(field-name (substring-no-properties
|
||||||
|
(org-element-property
|
||||||
|
:raw-value
|
||||||
|
field-heading))))
|
||||||
|
(push (cons field-name
|
||||||
|
(or (org-export-string-as
|
||||||
|
(buffer-substring
|
||||||
|
(org-element-property :contents-begin field-heading)
|
||||||
|
;; in case the buffer is narrowed,
|
||||||
|
;; e.g. by `org-map-entries' when
|
||||||
|
;; scope is `tree'
|
||||||
|
(min (point-max) (org-element-property :contents-end field-heading)))
|
||||||
|
anki-editor--ox-anki-html-backend t '(:with-toc nil))
|
||||||
|
|
||||||
`(,field-name . ,(or (org-export-string-as
|
;; 8.2.10 version of
|
||||||
(org-element-interpret-data contents)
|
;; `org-export-filter-apply-functions'
|
||||||
anki-editor--ox-anki-html-backend t)
|
;; returns nil for an input of empty string,
|
||||||
;; 8.2.10 version of
|
;; which will cause AnkiConnect to fail
|
||||||
;; `org-export-filter-apply-functions'
|
""))
|
||||||
;; returns nil for an input of empty string,
|
fields)
|
||||||
;; which will cause AnkiConnect to fail
|
(org-forward-heading-same-level nil t))))
|
||||||
""))))
|
(reverse fields))))
|
||||||
|
|
||||||
|
|
||||||
;;; Minor mode
|
;;; Minor mode
|
||||||
|
@ -566,6 +560,8 @@ of that heading."
|
||||||
(t nil))))
|
(t nil))))
|
||||||
(setq match (concat match "&" anki-editor-prop-note-type "<>\"\""))
|
(setq match (concat match "&" anki-editor-prop-note-type "<>\"\""))
|
||||||
|
|
||||||
|
;; disable property inheritance temporarily, or all subheadings of a
|
||||||
|
;; note heading will be counted as note headings as well
|
||||||
(let* ((org-use-property-inheritance nil)
|
(let* ((org-use-property-inheritance nil)
|
||||||
(total (progn
|
(total (progn
|
||||||
(message "Counting notes...")
|
(message "Counting notes...")
|
||||||
|
@ -640,7 +636,7 @@ same as how it is used by `M-RET'(org-insert-heading)."
|
||||||
(interactive)
|
(interactive)
|
||||||
(org-export-to-buffer
|
(org-export-to-buffer
|
||||||
anki-editor--ox-anki-html-backend
|
anki-editor--ox-anki-html-backend
|
||||||
anki-editor-buffer-html-output nil t nil t nil
|
anki-editor-buffer-html-output nil t nil t '(:with-toc nil)
|
||||||
#'html-mode))
|
#'html-mode))
|
||||||
|
|
||||||
(defun anki-editor-convert-region-to-html ()
|
(defun anki-editor-convert-region-to-html ()
|
||||||
|
|
Loading…
Reference in a new issue