eyeinsky / org-anki

Sync org notes to Anki via AnkiConnect
BSD 3-Clause "New" or "Revised" License
180 stars 28 forks source link

implement fake decorators to refer to Anki fields #71

Open basaran opened 1 year ago

basaran commented 1 year ago

At the moment, we are able to refer to the Anki fields as nested org headings. But this approach ends up creating individual cards when you do a sync all. This could be desired for some use cases however. Perhaps, it would be more standard to use org-headings, when we want cards and use fake decorators when we want to refer to anki fields. It could provide a more predictable implementation.

Given that we have a new note defined in Anki, such as:

(use-package! org-anki
   :config
   (add-to-list 'org-anki-model-fields '("Typewriter" "Front" "Back", "Explain")))

image

--

But Why?

I understand this may seem unnecessary, but the issue I ran into was with Anki's {{FrontSide}} field, which is used with the {{type:Back}}. It allows you to do something like this:

image

If I had a note such as this:

image

Then the answer would look like this:

image

But, it would be preferable to have it look like this:

image

It could also be helpful to come up with a few additional conditions inside the --get-fields function, so we don't need to populate full structures like you would do with anki-editor. It is also possible this could be unnecessary. I was able to wrap the sync-all function as Ken did in his #66, for my use case to only sync a specific level of headings.

basaran commented 1 year ago

Hi, by the way, my wrapper redefined from #66 back fired on me due to promises) But I was able to use the skip function mechanism you thoughtfully included in org-map-entries.

In case someone else runs into this:

  (defun skipme ()
    (if (not (= 1 (org-element-property :level (org-element-at-point))))
        0))

  (setq org-anki-skip-function 'skipme)

This will skip creating flashcards from nested subheadings, and use the nice promise wrapper you already wrote.

basaran commented 1 year ago

I was also able to patch in an extra case for the Typed kind of decks to isolate the back of the card. And after going over the internals while doing so, I understand implementing these fake decorators might be unnecessarily complicated.

image

image

Combined with an additional clause, skip function is fine and produces predictable results. We can close this, what do you think?

eyeinsky commented 1 year ago

Right, so as I understand it, in this proposal, the note fields would have been taken from decorators, marked by the at-sign and a field name (@Explain). Are decorators themselves an org-mode feature? I think something like that is used in python, but haven't seen them in org-mode before.

basaran commented 1 year ago

Nope, as far as I know there are no decorators in elisp (but there are macros), hence the name "fake decorators: :)

The @ symbol or any symbol is arguably easier the manage and consistent, but that would differ from person to person. If we add that, then we would have to change most of the logic you already have in place for the parsing of fields (no more org-map-entries for instance)

I think if we add a clause for these Type:Back cards like I did, and make a reference in the documentation to the skip handler function, everything will be fine and functional.