protesilaos / denote

Simple notes for Emacs with an efficient file-naming scheme
https://protesilaos.com/emacs/denote
GNU General Public License v3.0
520 stars 55 forks source link

Is there an equivalent `denote-org-extras-convert-links-to-file-type ` for markdown files? #327

Open maikol-solis opened 5 months ago

maikol-solis commented 5 months ago

Hi Prot! How are you!

My question is basically the title. Today I installed denote, and I want to have something like denote-org-extras-convert-links-to-file-type basically for exporting some links in quarto (markdown) files.

Any help is appreciated.

Best.

Edit: I wrote the correct function denote-org-extras-convert-links-to-file-type

maikol-solis commented 5 months ago

I tried to create new functions based on the already existing for org, but it doesn't work for me.

Maybe I just did a silly thing.


(defun denote-markdown-extras--get-link-type-regexp (type)
  "Return regexp for Markdown link TYPE.
TYPE is a symbol of either `file' or `denote'.

The regexp consists of four groups. Group 1 is the description,
Group 2 is the link type with colon, Group 3 is the target,
and Group 4 is the target's search terms (optional)."
  (let ((group-2))
    (pcase type
      ('denote (setq group-2 "denote:"))
      ('file (setq group-2 "file:"))
      (_ (error "`%s' is an unknown link type" type)))
    (format "\\[\\(?1:.*?\\)\\](\\(?2:%s\\)\\(?3:[^:]*?\\)\\(?4::[^)]*?\\)?\\)" group-2)))

  (defun denote-markdown-extras-convert-links-to-file-type ()
    "Convert denote: links to file: links in the current Org buffer.
Ignore all other link types.  Also ignore links that do not
resolve to a file in the variable `denote-directory'."
    (interactive nil markdown-mode)
    (if (derived-mode-p 'markdown-mode)
        (progn
          (goto-char (point-min))
          (while (re-search-forward (denote-markdown-extras--get-link-type-regexp 'denote) nil :no-error)
            (let* ((id (match-string-no-properties 2))
                   (search (or (match-string-no-properties 3) ""))
                   (desc (or (match-string-no-properties 4) ""))
                   (file (save-match-data (denote-get-path-by-id id))))
              (when id
                (let ((new-text (if desc
                                    (format "[%s](%s%s)" desc file search )
                                  (format "<%s%s>" file search))))
                  (replace-match new-text :fixed-case :literal)))))
          ;; TODO 2024-02-28: notify how many changed.
          (message "Converted `denote:' links to `file:' links"))
      (user-error "The current file is not using markdown mode")))
protesilaos commented 5 months ago

Hello @maikol-solis!

I am happy to help but I do not know what the converted links should look like. What you have here looks promising. Are the regular expressions/formats the desired ones?

Note that the second functions includes a search but we do not have something like that for Markdown links, so this part could be simplified.

maikol-solis commented 5 months ago

Hi!

Thanks for the reply.

I'm following the convention for Quarto files (https://quarto.org/docs/authoring/markdown-basics.html#links-images), and I think it covers the 99% of the cases.

A regular link with signature, title and name of the file should be like

[SIGNATURE TITLE](NAME-OF-FILE)

Best.

maikol-solis commented 5 months ago

After tweaking the regexp a bit, this works for me.

Please check if it's useful to you.

  (defun denote-markdown-extras--get-link-type-regexp (type)
    "Return regexp for Markdown link TYPE.
TYPE is a symbol of either `file' or `denote'.

The regexp consists of four groups. Group 1 is the description,
Group 2 is the link type with colon, Group 3 is the target,
and Group 4 is the target's search terms (optional)."
    (let ((group-2))
      (pcase type
        ('denote (setq group-2 "denote:"))
        ('file (setq group-2 "file:"))
        (_ (error "`%s' is an unknown link type" type)))
      (format "\\[\\(?3:.*?\\)\\](\\(?1:%s\\)\\(?2:.*?\\))" group-2)))

  (defun denote-markdown-extras-convert-links-to-file-type ()
    "Convert denote: links to file: links in the current Org buffer.
Ignore all other link types.  Also ignore links that do not
resolve to a file in the variable `denote-directory'."
    (interactive nil markdown-mode)
    (if (derived-mode-p 'markdown-mode)
        (progn
          (goto-char (point-min))
          (while (re-search-forward (denote-markdown-extras--get-link-type-regexp 'denote) nil :no-error)
            (let* ((id (match-string-no-properties 2))
                   (desc (or (match-string-no-properties 3) ""))
                   (file (save-match-data (file-name-nondirectory (denote-get-path-by-id id)))))
              (when id
                (let ((new-text (if desc
                                    (format "[%s](%s)" desc file )
                                  (format "<%s>" file ))))
                  (replace-match new-text :fixed-case :literal)))))
          ;; TODO 2024-02-28: notify how many changed.
          (message "Converted `denote:' links to `file:' links"))