Elilif / emacs-anki-helper

Manage your Anki cards in Emacs.
30 stars 3 forks source link

一些小疑问 #4

Closed czqhurricnae closed 8 months ago

czqhurricnae commented 11 months ago

一. ANKI_MATCH 的作用文档描述模糊不清

看了源码才知道什么意思。 在我的文档中需要设置成:

#+ANKI_MATCH: "tree"
#+ANKI_DECK: English
#+ANKI_NOTE_TYPE: Basic

而且以上三个变量,偏偏 ANKI_MATCH 需要加引号才能起作用,我尝试过三个变量,两种加和不加引号,各种组合,各种尝试才知道怎么能使它正常使用。 没有示例。 这对新手非常不友好。

二. ANKI_MATCH 的设置和它的结果表现不一致

根据源码中所述,ANKI_MATCH 可以设置 org-map-entriesSCOPE 参数的值?

我尝试将其设置为 #+ANKI_MATCH: "file"

我的预期是运行 anki-helper-entry-sync 后会将整个文档做成卡片。(当然,现在想想,anki-helper-entry-sync 这个函数是将 entry 作为正面,内容作为背面)。 但是根据 ANKI_MATCH 可以设置为 “file” 的行为,让人会误解为 anki-helper-entry-sync 函数可以做到我的预期,而实际上运行该函数,任何情况都没有发生,没有提示,没有任何反馈。

anki-helper-entry-sync-all 偏偏又把文档下所有的 entry 都做成卡片,这又和我的将《整个文档做成卡片》 的预期相反。

Elilif commented 11 months ago

抱歉,目前文档确实有些描述不清的地方,接下来的几次提交应该会进一步完善文档。

根据源码中所述,ANKI_MATCH 可以设置 org-map-entriesSCOPE 参数的值?

它设置的是 MATCH 参数的值(再次为不完善的文档抱歉)详见 Matching-tags-and-properties

偏偏 ANKI_MATCH 需要加引号才能起作用

都不需要加引号,举个例子

#+ANKI_MATCH: TODO="TODO"|+DATE="today"

将会匹配所有 TODO 状态为 TODODATE property 为 today 的 entries 。

Elilif commented 11 months ago

我的预期是运行 anki-helper-entry-sync 后会将整个文档做成卡片。(当然,现在想想,anki-helper-entry-sync 这个函数是将 entry 作为正面,内容作为背面)。

这需要您自己写一个同步函数,比如说

(defun my/anki-helper-file-sync ()
  "Create a notes for the current buffer.

Use the title of the current buffer as the front of the note, the
contents as the back side. e.g.:

#+TITLE: front

This is back side."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (search-forward-regexp org-keyword-regexp nil t))
    (let ((title (anki-helper--get-global-keyword "TITLE"))
          (contents (buffer-substring-no-properties (point) (point-max))))
      (anki-helper-request 'addNote
                           (anki-helper-create-note `(,title
                                                      ,(anki-helper--org2html
                                                        contents)))
                           (list :command 'my/anki-helper-file-sync
                                 :orig-info `(:pos ,(point-marker)))))))

(defun my/anki-helper-file-sync-callback (info result)
  "Callback for `my/anki-helper-file-sync'.

Set the note id."
  (with-current-buffer (marker-buffer (plist-get info :pos))
    (org-entry-put (point-min) anki-helper-prop-note-id
                   (number-to-string result))
    (message "Synchronizing...Done.")))

(add-to-list 'anki-helper-callback-alist '(my/anki-helper-file-sync . my/anki-helper-file-sync-callback))

当然您还需要设置更新和删除相关的函数。

Elilif commented 11 months ago

没有示例。

已增加示例,如果还有什么不足,请告诉我,我会尽快修改。

czqhurricane commented 8 months ago

我有文件内容如下:

# -*- eval: (setq org-download-image-dir (concat default-directory "./static/Python 线程基础/")); -*-
:PROPERTIES:
:ID:       2FCAD4B0-022B-4FE9-BF1F-977A8C6512C0
:END:
#+LATEX_CLASS: my-article
#+DATE: <2020-08-04 Tue 21:11>
#+TITLE: Python 线程基础
#+ANKI_MATCH: "tree"
#+ANKI_DECK: English
#+ANKI_NOTE_TYPE: Cloze

* 线程同步锁
考虑这样一种情况:一个列表里所有元素都是 0,线程 “set” 从后向前把所有元素改成 1,而线程 “print” 负责从前往后读取列表并打印。
那么,可能线程 “set” 开始改的时候,线程 “print” 便来打印列表了,输出就成了一半 0 一半 1,这就是数据的不同步。
为了避免这种情况,引入了 *锁* 的概念。
锁的两种状态: *锁定* , *未锁定* 。
线程与锁的交互如下图所示:

打算将 * 标记的内容挖空,所以设置为 #+ANKI_NOTE_TYPE: Cloze

但是在 entry * 线程同步锁 上调用函数 anki-helper-entry-sync。抛出错误:

Debugger entered--Lisp error: (wrong-number-of-arguments #<subr mapconcat> 2)
  mapconcat(#f(compiled-function (elt) #<bytecode -0x1f5a45abe888485f>) (#("考虑这样一种情况:一个列表里所有元素都是 0,线程 “set” 从后向前把所有元素改成 1,而线程 ..." 0 234 (:parent #2))))
  anki-helper--make-cloze("考虑这样一种情况:一个列表里所有元素都是 0,线程 “set” 从后向前把所有元素改成 1,而线程 ...")
  anki-helper-fields-get-cloze()
  anki-helper--entry-get-fields("Cloze")
  anki-helper--entry-get-content()
  org-scan-tags(anki-helper--entry-get-content (lambda (todo tags-list level) (progn (setq org-cached-props nil) (or (and (not (string-match #(".+" 0 2 ...) (or ... ""))))))) nil nil)
  org-map-entries(anki-helper--entry-get-content #("-ANKI_NOTE_ID={.+}\"tree\"" 14 18 (regexp t)) nil nil)
  anki-helper--entry-get-all(#("-ANKI_NOTE_ID={.+}\"tree\"" 14 18 (regexp t)))
  anki-helper-entry-sync-all()
  anki-helper-entry-sync()
  funcall-interactively(anki-helper-entry-sync)
  call-interactively(anki-helper-entry-sync record nil)
  command-execute(anki-helper-entry-sync record)
  counsel-M-x-action("anki-helper-entry-sync")
  ivy-call()
  ivy-read("M-x " ("anki-helper-entry-sync" "anki-helper-make-two-sided-card" "anki-helper-set-front-region" "evil-surround-delete" "toggle-debug-on-error" "anki-helper-entry-browse" "anki-helper-sync" "eval-region" "anki-helper-entry-sync-all" "org-noter-enable-org-roam-integration" "emacs-azure-tts" "eaf-restart-process" "reverso-context" "erase-buffer" "reverso" "reverso-synonyms" "youdao-dictionary-search" "youdao-dictionary-search-at-point+" "hurricane/youdao-search-at-point" "python-bridge-restart-process" "popweb-restart-process" "hurricane/insert-chrome-current-tab-url" "icloud-download" "hurricane/iterm-shell-command" "chmod" "find-lisp-find-dired" "web-mode" "hurricane/dired-duplicate-this-file" "xml-mode" "ediff-buffers" "ediff" "hurricane/open-link-in-chrome" "blink-search" "popweb-anki-review-show" "eaf-open-pdf-from-history" "popweb-dict-eudic-dicts-input" "hurricane/ivy-you-get" "xah-cycle-hyphen-lowline-space" "hurricane/now" "hurricane/reveal-cut-video" "org-id-get-create" "anki-editor-find-notes" "org-roam-db-sync" "eval-buffer" "popweb-dict-eudic-liju-input" "org-gtd-engage" "popweb-dict-youglish-pointer" "popweb-dict-youdao-input" "hurricane/goldendict-find" "blink-search-restart-process" ...) :predicate counsel--M-x-externs-predicate :require-match t :history counsel-M-x-history :action counsel-M-x-action :keymap (keymap (C-M-left . backward-sexp) (C-M-right . forward-sexp) (67108908 . counsel--info-lookup-symbol) (67108910 . counsel-find-symbol)) :initial-input nil :caller counsel-M-x)
  counsel-M-x()
  funcall-interactively(counsel-M-x)
  call-interactively(counsel-M-x nil nil)
  command-execute(counsel-M-x)
Elilif commented 8 months ago

@czqhurricnae anki-helper-cloze-use-emphasis 的设置是什么呢?按照您的情况应该是 bold ,详见 https://github.com/Elilif/emacs-anki-helper?tab=readme-ov-file#global-variables

czqhurricane commented 8 months ago

是我理解错误了,当时我看到

anki-helper-cloze-use-emphasis
是否将 org-emphasis-alist 中的标记视为 Cloze 的标记。

这句话时,把 anki-helper-cloze-use-emphasis 理解为是 bool 值,把它设置成了 t ,还以为这样后 anki-helper 会自动把 bold,下滑线,~ 等等都挖空呢。

感谢指正。

czqhurricane commented 8 months ago

我按照你的指导进行设置,


(use-package anki-helper
    :custom
    (anki-helper-media-directory Anki-media-dir)
    (anki-helper-cloze-use-emphasis 'bold))

可是,还是出现相同错误。

image

Elilif commented 8 months ago

@czqhurricnae 我在 emacs -Q 下用您的文本是可以的,请排除其他配置的影响。 Peek 2024-02-24 15-45

czqhurricane commented 8 months ago

发现问题了,是 mapconcat 的参数数量不对。不知道为啥你的不会报错,我的 Emacs 是 28.3。

其中,共有两处的 mapconcat 的第三个参数欠缺。

一,anki-helper--make-cloze 我的修改:

(defun anki-helper--make-cloze (string)
  (let ((data (org-element-parse-secondary-string string `(,anki-helper-cloze-use-emphasis)))
        (anki-helper--cloze-counter 0))
    (mapconcat (lambda (elt)
                 (if (stringp elt)
                     elt
                   (concat (format "{{c%d::%s}}"
                                   (cl-incf anki-helper--cloze-counter)
                                   (if (eq anki-helper-cloze-use-emphasis 'verbatim)
                                       (org-element-property :value elt)
                                     (if-let* ((content (car (org-element-contents elt)))
                                               ((stringp content)))
                                         content
                                       (org-element-property :value content))))
                           (make-string (org-element-property :post-blank elt)
                                        32))))
               data "\n")))

二,anki-helper--get-note-hash

我随手改成:


(defun anki-helper--get-note-hash ()
  (let* ((note-type (anki-helper--find-prop
                     anki-helper-note-type
                     anki-helper-default-note-type))
         (fields (anki-helper--entry-get-fields note-type))
         (fields-string (anki-helper--filelds2string fields ""))
         (tags (anki-helper--get-tags)))
    (md5 (mapconcat #'identity (push fields-string tags) ""))))

此后可以成功生成 ANKI 卡片。

因为不知道第三个参数分别用什么补充合适,我就不提 PR 了。作者看看如何修改合适?

Elilif commented 8 months ago

@czqhurricane

(mapconcat FUNCTION SEQUENCE &optional SEPARATOR)

mapconcat 的第三个参数是 optional 的,少了是不会报错的,应该不是这个问题。您在 emacs -Q 试过了吗?能提供下 emacs -Q 下的报错信息吗?

czqhurricane commented 8 months ago

在我这里不是 optional 的,

(mapconcat FUNCTION SEQUENCE SEPARATOR)
  Other relevant functions are documented in the list and string groups.
  Probably introduced at or before Emacs version 21.1.
Elilif commented 8 months ago

@czqhurricnae 原来是这样,这个包的 emacs 版本要求是 29.1 ,我看到你 fork 后改成了 28 ,可能这就是问题的来源吧。我正在编译 emacs 28.3 。等我测试完吧,之后会修改版本要求。

Elilif commented 8 months ago

@czqhurricnae 现在应该没问题了,如果还有其他方面的问题,请新开一个 issue 继续讨论。