Skip to content

Latest commit

 

History

History
201 lines (149 loc) · 8.05 KB

README_CN.org

File metadata and controls

201 lines (149 loc) · 8.05 KB

Anki-helper

在 Emacs 中管理您的 Anki 卡片。

为什么用 Anki-helper

目前辅助 Anki 制卡的插件主要是 eyeinsky/org-ankilouietan/anki-editor

anki-editor 我只是很浅的用了一下,马上就被它的格式要求给劝退了: anki-editor 需要使用专门的标题行来标记卡片的正反面。这首先导致原有的笔记不能快速转化为卡片,需要自己转换;其次制作好的卡片几乎只能由 anki-editor 使用,无法融入到现有的工作流中,需要专门的文件来存放。

org-anki 比较好地解决了上述缺点,它使用当前的标题栏作为正面,笔记内容作为反面。这正好和我记笔记的方式吻合,原有的笔记马上就能拿来制卡,也不需要专门的文件。所以 org-anki 我用了很长一段时间,通过pdf-tools + org-note + org-anki 实践渐进式阅读,已经读了很多大部头的书。

org-anki 的缺点如下:

  1. 同步速度慢

    org-anki 同步笔记实在是太慢了。我经常需要修改卡片,对于卡片比较多的文件,同步简直是个噩梦。

    examples/headings.org 为例, org-anki 和 anki-helper 同步和删除所有卡片( 422张)的时间对比如下:

    (benchmark 1 ‘(xxx-sync-all))(benchmark 1 ‘(xxx-delete-all))
    org-anki123.855104s (35.423518s in 5 GCs)150.862886s (21.709634s in 8 GCs)
    anki-helper0.410945s0.098308s
  2. 仅支持 entry ,模板字段填充方式僵硬

    org-anki 的另外一个问题是它只适用于 entry ,没有提供 API 来添加自定义的卡片制做函数。一个 entry 一张卡片的好处一是可以保存卡片的信息,如卡片 ID,是否已经修改等,这样方便后续修改;二是可以对不同的 entry 进行不同操作。但是有些类型的卡片是不需要这类额外的信息的,一个常见的例子就是单词卡片。我需要只是收集生词,然后同步到 Anki ,后续几乎不会修改。显然一个单词一个 entry 是比较浪费的。

    org-anki 仅支持两种字段填充方式:一是标题行为卡片正面,内容为反面;二是使用子标题来区分字段。后一种做法又回到了 anki-editor。这里的问题是每个人的习惯是不一样的,自定义的模板也千奇百怪,所以必须要提供一套足够灵活的 API 来方便用户创建自己的字段填充函数。

  3. 缺乏多媒体内容处理

    org-anki 针对图片处理的 PR 还没有合并,其他多媒体内容也不支持。

    anki-helper 支持在卡片中包含图片和音频文件的链接,在制卡的过程中会将其复制到Anki 的媒体目录下。

我认为 anki-helper 比较好的解决了上述了个问题,同时增加了其他特点:

  1. 尽可能地保持原始文本内容不变

    对于 Cloze 类型的卡片来说,常规的做法是使用 {{c1:xxx}} 这种形式,但是这会破坏原有内容,不利于其他操作。这其实是一种变相的专有化。

    Anki-helper 使用 org-mode 内置的富文本标记来作为完形填空的标志,假设有以下文本:

    *Canberra* was founded in *1913*.
        

    在制卡的过程中,它会变成如下格式:

    {{c1::Canberra}} was founded in {{c2::1913}}.
        

    我认为这样是符合直觉的,因为你强调的部分往往是你想要记住的部分。

    注意: 此功能由变量 anki-helper-cloze-use-emphasis 控制,默认情况下关闭。同时不支持下述类型的转化:

    {{c1::Canberra}} was founded in {{c1::1913}}.
        

安装

依赖

  1. Anki
  2. FooSoft/anki-connect
  3. curl

使用 package.el 安装

M-x package-vc-install RET https://github.com/Elilif/emacs-anki-helper RET

手动安装

(add-to-list 'load-path "path-to-anki-helper")
(require 'anki-helper)

用法

使用方法和 org-anki 类似。

变量

全局变量

  1. anki-helper-cloze-use-emphasis

    是否将 org-emphasis-alist 中的标记视为 Cloze 的标记。该值如果是一个符号,如 ~bold~,则文本

    *Canberra* was founded in *1913*.
        

    在制卡的过程中会变成如下格式:

    {{c1::Canberra}} was founded in {{c2::1913}}.
        

    注意: 不支持下述类型的转化:

    {{c1::Canberra}} was founded in {{c1::1913}}.
        
  2. anki-helper-default-note-type

    默认的卡片模板类型

  3. anki-helper-default-deck

    默认的卡组名称

  4. anki-helper-default-tags

    默认的卡片标签

  5. anki-helper-default-match

    用于筛选满足条件的 entry ,详见变量文档。

  6. anki-helper-skip-function

    用于判断是否跳过某个 entry ,详见 org-map-entries

  7. anki-helper-inherit-tags

    是否继承父标题的标签

  8. anki-helper-media-directory

    Anki 保存多媒体文件的目录

  9. anki-helper-note-types

    模板名称及其对应的字段

file-local 的变量

  1. #+ANKI_DECK:
  2. #+ANKI_MATCH:
  3. #+ANKI_NOTE_TYPE:
  4. #+ANKI_TAGS:

上述关键字分别对应相应的全局变量。

比如说您有如下 org 文件:

#+ANKI_DECK: Default
#+ANKI_MATCH: TODO="TODO"|+DATE="today"
#+ANKI_NOTE_TYPE: Basic
#+ANKI_TAGS: test

* test note 1
back side
* TODO test note 2
back side
* test note 3
:PROPERTIES:
:DATE:     today
:END:
back side
* test note 4
back side

那么使用 anki-helper-entry-sync-all 只会创建两张卡片: test note 2test note 3

Properties

  1. ANKI_NOTE_TYPE
  2. ANKI_DECK

每个 entry 可以有各自的属性。上述变量的优先级为 Properties > file-local variables > global variables

entry 类型的卡片

anki-helper 默认提供了一系列函数来对 entry 类型的卡片进行操作(后续会增加更多操作):

函数

  1. anki-helper-entry-sync

    将光标位置下的 entry 制成卡片,如果已经是卡片则忽略。

  2. anki-helper-entry-sync-all

    将当前 buffer 中所有满足条件的 entries 制成卡片,如果已经是卡片则忽略。

  3. anki-helper-entry-delete

    如果光标下的 entry 是卡片且满足条件,则删除。

  4. anki-helper-entry-delete-all

    删除当前 buffer 中所有满足条件的卡片。

  5. anki-helper-entry-update

    如果光标下的 entry 是卡片且有过修改,则更新。

  6. anki-helper-entry-update-all

    更新当前 buffer 中所有修改过的卡片。

  7. anki-helper-entry-browse

    在 Anki 中浏览当前 entry

非 entry 类型的卡片

anki-helper 提供了几个 API :

  1. anki-helper-request
  2. anki-helper-create-note
  3. anki-helper-create-notes

具体用法详见函数文档。

作为参考,您可以查阅 anki-helper-set-front-regionanki-helper-make-two-sided-card 两个函数,它们提供了一种交互式制卡的方案。

具体效果: examples/make-card-interactively.gif

杂项

  1. anki-helper-find-notes

    在 Anki 中搜索指定 QUERY

修改默认的行为

修改模板字段填充方式

变量 anki-helper-fields-get-alist 设置了两个基本的字段获取函数:~anki-helper-fields-get-default~ 用于 Anki 默认的 Basic 模板,使用标题行为卡片正面,内容为卡片反面、~anki-helper-fields-get-cloze~ 用于 Anki 默认的 Cloze 模板,使用标题下的内容来填充 Text 字段,~Back Extra~ 字段为标题行。您可以定义自己的字段获取函数,详见 anki-helper-fields-get-alist 的文档。

修改回调函数

详见 anki-helper-callback-alist

更多自定义

在卡片中添加指向原文所在条目的链接

详见:GitHub - hwiorn/anki-open-org-note