anki-editor icon indicating copy to clipboard operation
anki-editor copied to clipboard

Inline images would be a major upgrade for this project

Open falematte opened this issue 6 years ago • 20 comments

I use quite a lot images in my anki notes and in my org headers. It would be great to be able to export images too from anki-editor.

falematte avatar Sep 20 '18 12:09 falematte

Link to local images like [[file:/path/to/whatever.png]] is already supported.

louietan avatar Sep 23 '18 19:09 louietan

If I insert a link an image like u indicated and I push the note I see a broken link in the respectively card. Any tips?

falematte avatar Sep 26 '18 13:09 falematte

What's the extension of the file name ?

louietan avatar Sep 28 '18 15:09 louietan

:+1: on this issue and thank you for creating/maintaining this package @louietan!

I think the problem @falematte is experiencing may be the same as me.

Linking the image as you described works perfectly fine on desktop anki; however, when I sync the content onto my android device, the image resource is not available and thus is a broken file link. Similarly, if I were to sync with any other device the same problem would manifest.

Do you know if there is anyway to embedded the image via latex or html tags? Since you export the code to html, I believe embedding via latex is not an option as it stands.

ejmg avatar Oct 02 '18 01:10 ejmg

@ejmg Normal HTML code can be embedded in Org by blocks like below

#+BEGIN_EXPORT html
<img src="http://url/to/whatever.png" />
#+END_EXPORT

but if you're going to link local images, embedding via HTML tags is either an option, since they will be exported as is and there's no way to upload the targets to Anki as media files.

To be able to reproduce and fix this issue, I have to know what is the path to your image file like.

louietan avatar Oct 05 '18 11:10 louietan

Thank you for the great work. I think most of the users are using anki web on their android device. A good way to solve this problem would be to couple this software with a sync mechanism, e.g. syncthing. If the path is handled correctly one could, in principle, export org headers with images with images inline into anki cards.

P.S: Why do you asked me for the file extension? Is this working also for jpg or only for png?

falematte avatar Oct 05 '18 11:10 falematte

I'm a bit confused, why do we need an external sync service ? Anki itself supports media files including images and audios, which are synced across devices. I personally use Anki desktop and AnkiDroid, linking to images works good for me. To be able to figure out why it doesn't work on your side and to avoid my misunderstanding of your description, I need more information about the Org doc you use.

There's a variable called org-export-default-inline-image-rule defined in Org, which is a regexp to match the file name for inline images, whose documentation says:

Default rule for link matching an inline image. This rule applies to links with no description. By default, it will be considered as an inline image if it targets a local file whose extension is either "png", "jpeg", "jpg", "gif", "tiff", "tif", "xbm", "xpm", "pbm", "pgm" or "ppm".

Then I was guessing if it's your image extension isn't included in this default rule.

louietan avatar Oct 06 '18 13:10 louietan

Thank you for the answer. Maybe I am a little bit confused. Here is the value of describing the variable:

org-export-default-inline-image-rule is a variable defined in ‘ox.el’.
Its value is
(("file" . "\\.\\(gif\\|jp\\(?:e?g\\)\\|p\\(?:bm\\|gm\\|ng\\|pm\\)\\|tiff?\\|x\\(?:[bp]m\\)\\)\\'"))

And here is an example of a note not working:


* Item
:PROPERTIES:
:ANKI_DECK: Importedfromorg
:ANKI_NOTE_TYPE: Basic
:ANKI_NOTE_ID: 1538838186536
:END:
** Front
Let's make a try
** Back


[[file:orgpic/Item/Selection_076_2018-10-06_17-02-55.jpg]]

If I export this note I get an "answer" with a broken link:

selection_077

falematte avatar Oct 06 '18 15:10 falematte

@louietan just wanted to say that your suggestion works perfectly! I now have anki cards that render correctly on desktop and on the android app via synchronization. Thank you so much for making such an awesome minor mode :smiley: :100: I can't emphasize how awesome your minor mode is.

@falematte I was always able to use the org-mode file url syntax without modifying any configuration variables. Assume your system configurations are fine, I'm betting it's a relative/absolute file URL issue.

Here's a real working example of what I had from an older version of my anki.org file:

* physics                                                              :deck:
<code snip>
** CH4: 2D Motion, Vectors
*** position vector                                                    :note:
    :PROPERTIES:
    :ANKI_NOTE_TYPE: Basic
    :ANKI_NOTE_ID: 1521658933042
    :END:
**** Front
     position vector, $\vec{r}$
**** Back
     $\vec{r} = x\hat{i} + y\hat{j}$
    
     [[file:position-vector.png][position vector]]

Notes that my file url is relative to the immediate directory of my anki.org file:

~/org/anki (master)$ tree
.
├── anki.org
├── <output snip>
└── centripetal-force.png

Another possible reason is because you don't provide text to go along with the file url? If you look at my file, you'll note I have [position vector] immediately after the file url but still within the outside set of square brackets. When I use anki on desktop, it would result in me having a hyperlinked text that opened a separate window with the image. This is only another guess. Try those and let us know if it works.

ejmg avatar Oct 07 '18 21:10 ejmg

FYI, I just tried to see if I could include local files on my system using the HTML code snippet and the apparent answer is no, at least without editing some configurations I don't know about. This applies regardless if the file is specified by relative or absolute path, i.e. /home/user/file.png, ./file.png, and file.png all equally do not work. This doesn't really bother me as I can just throw images up on a gist and reference that or use images hosted on something like wikipedia, etc, but I'm sure someone else would appreciate knowing how to do that.

ejmg avatar Oct 07 '18 22:10 ejmg

@falematte Where's that image located and can it be previewed in Emacs with C-c C-x C-v ? And could you also provide me the HTML content of the back field, which you can get from the builtin Anki note editor by pressing Ctrl + Shift + x when the cursor is in the editing box.

louietan avatar Oct 08 '18 12:10 louietan

@louietan it is correctly displayed with C-c C-x C-v . The image is in

~/orgpic/Item/Selection_076_2018-10-06_17-02-55.jpg.

Here is the html. Thank you!

<div class="figure">
<p><img src="orgpic/Item/Selection_076_2018-10-06_17-02-55.jpg" alt="Selection_076_2018-10-06_17-02-55.jpg" />
</p>
</div>

falematte avatar Oct 09 '18 10:10 falematte

I am experiencing the same problems, with both Anki 2.0 and Anki 2.1.5 (under Linux). The cause of the problem is, I think, that the local images do not get copied to the ~/somepath/collection.media directory.

This is an example of an org file (yes, the png are visible when C-c C-x C-v):

with single "/"
[[file:/home/ramon/tmp/screenshot1.png][screenshot1.png]]

with triple "///"
[[file:///home/ramon/tmp/covr320.png][covr320.png]]

same directory
[[file:f1.png][f1.png]]

from org-attach-screenshot
[[file:../Downloads/sc2.png]]

org-attach screenshot, with figure under same directory as org file
[[file:sc3.png]]

And this is what Anki says (Ctrl + Shift + x):

<p>
with single "/"
<a href="file:///home/ramon/tmp/screenshot1.png">screenshot1.png</a>
</p>

<p>
with triple "<i>/</i>"
<a href="file:///home/ramon/tmp/covr320.png">covr320.png</a>
</p>

<p>
same directory
<a href="f1.png">f1.png</a>
</p>

<p>
from org-attach-screenshot 
<img src="../Downloads/sc2.png" alt="sc2.png">
</p>

<p>
org-attach screenshot, with figure under same directory as org file
<img src="sc3.png" alt="sc3.png">
</p>

Finally, these are two screen-captures of how it looks in Anki. From the browser: anki2 1_browser

And from the preview:

anki2 1_preview

Notice, however, that if we copy the files above to the Anki collection.media directory, then the last one (that specified as img src ="sc3.png", without a, path, i.e., located in the same directory as the org file) can be seen.

@ejmg mentions " Another possible reason is because you don't provide text to go along with the file url? " . But I find the opposite: adding, in the org link, the descriptive text after the filename (the [some name] before the closing brackets) actually hurts, because then the export produces a href to a file; in Anki we see

<a href="f1.png">f1.png</a>

instead of

<img src="f1.png" alt="f1.png">

So my solution for now is to use org-attach-screenshot, leave screenshots in the same directory as the org file, and then copy the files to collection.media. But it seems that @louietan and @ejmg do not need that?

rdiaz02 avatar Oct 20 '18 22:10 rdiaz02

Do we have any update on this?

falematte avatar Dec 07 '18 14:12 falematte

anki-editor should be sending the image to anki-connect and creating a media file within Anki for the card to use, so the path in the Anki card source shouldn't contain any directories, it should just be a file name.

Double check that you've enabled anki-editor-mode before trying to push. I think it's a bit confusing but enabling the mode wraps some exports with advice functions which properly handle image links.

If you're on a Mac (or possibly Windows) you may have issues with sha1sum and base64 not being available and if they are available I've found they don't behave the same as Linux versions which causes issues. I plan to open a PR with the following definition for anki-editor--anki-connect-store-media-file (and some more changes to remove checks that are no longer needed):

(defun anki-editor--anki-connect-store-media-file (path)
  "Store media file for PATH, which is an absolute file name.
The result is the path to the newly stored media file."
  (unless (-all? #'executable-find '("base64" "sha1sum"))
    (error "Please make sure `base64' and `sha1sum' are available from your shell, which are required for storing media files"))

  (let* ((hash (secure-hash 'sha1 path))
         (media-file-name (format "%s-%s%s"
                                  (file-name-base path)
                                  hash
                                  (file-name-extension path t)))
         content)
    (when (equal :json-false (anki-editor--anki-connect-invoke-result
                              "retrieveMediaFile"
                              `((filename . ,media-file-name))))
      (message "Storing media file to Anki for %s..." path)
      (setq content (string-trim
		     (base64-encode-string
		      (with-temp-buffer
			(insert-file-contents path)
			(buffer-string)))))
      (anki-editor--anki-connect-invoke-result
       "storeMediaFile"
       `((filename . ,media-file-name)
         (data . ,content))))
    media-file-name))

kevinjfoley avatar Dec 29 '18 03:12 kevinjfoley

anki-editor should be sending the image to anki-connect and creating a media file within Anki for the card to use, so the path in the Anki card source shouldn't contain any directories, it should just be a file name.

Double check that you've enabled anki-editor-mode before trying to push. I think it's a bit confusing but enabling the mode wraps some exports with advice functions which properly handle image links.

If you're on a Mac (or possibly Windows) you may have issues with sha1sum and base64 not being available and if they are available I've found they don't behave the same as Linux versions which causes issues. I plan to open a PR with the following definition for anki-editor--anki-connect-store-media-file (and some more changes to remove checks that are no longer needed):

(defun anki-editor--anki-connect-store-media-file (path)
  "Store media file for PATH, which is an absolute file name.
The result is the path to the newly stored media file."
  (unless (-all? #'executable-find '("base64" "sha1sum"))
    (error "Please make sure `base64' and `sha1sum' are available from your shell, which are required for storing media files"))

  (let* ((hash (secure-hash 'sha1 path))
         (media-file-name (format "%s-%s%s"
                                  (file-name-base path)
                                  hash
                                  (file-name-extension path t)))
         content)
    (when (equal :json-false (anki-editor--anki-connect-invoke-result
                              "retrieveMediaFile"
                              `((filename . ,media-file-name))))
      (message "Storing media file to Anki for %s..." path)
      (setq content (string-trim
		     (base64-encode-string
		      (with-temp-buffer
			(insert-file-contents path)
			(buffer-string)))))
      (anki-editor--anki-connect-invoke-result
       "storeMediaFile"
       `((filename . ,media-file-name)
         (data . ,content))))
    media-file-name))

This worked well thanks!

TomatoCream avatar Apr 11 '19 09:04 TomatoCream

@TomatoCream - glad it helped! The changes above have been merged into the package so you shouldn't need them other than the reminder to enable anki-editor-mode

kevinjfoley avatar Apr 11 '19 13:04 kevinjfoley

Hello guys, Is it possible now to export an anki card with an image inserted as a link to the file with an absolute path?

falematte avatar Apr 12 '19 12:04 falematte

Hi all, while this seems to work fine with "file:link.png" type links, it seems not to work with the "new" "attachment:link.png" type of link. I use org-download with the "org-download-method" set to "attach" and my images don't get exported to anki this way (seemingly since they produce "attachement:file.png"-type links), although images do successfully get exported with usual file-links.

g4v4g4i avatar Sep 07 '20 09:09 g4v4g4i

This really bugged me quite a lot so here is a function which goes through entire org file buffer looking for headlines with "ATTACH" tag and soft link each attachment into current file directory. Not ideal solution but better then nothing.

(defun +org-attach-link-every-attachment-to-current-dir ()
  "Got through current org buffer, check for attachments
and link them to the current directory so that there
aren't any issues with pushing images inserted by
org-download using attachment: link type into Anki.

Intended as workaround for `anki-editor--ox-html-link'.
"
;; uncomment following line if you want this fn as command in M-x menu
;; (interactive)
  (org-element-map (org-element-parse-buffer) 'headline
    (lambda (headline)
      (let ((tags (org-element-property :tags headline))
            (buffer-file-dir
             (directory-file-name
              (file-name-directory
               (buffer-file-name (org-base-buffer (current-buffer)))))))
        (if (cl-member "ATTACH" tags :test #'string-equal)
            (seq-map
             (lambda (file)
               (make-symbolic-link
                file
                (expand-file-name (file-name-nondirectory file) buffer-file-dir)
                'ok-if-already-exists))
             (directory-files-recursively
              (org-attach-dir-get-create) ".*" nil)))))))

execute this function before the command you are using to build and push anki cards.

AloisJanicek avatar Nov 05 '21 13:11 AloisJanicek