andras-simonyi / citeproc-org

Renders Org-mode citations in CSL styles using citeproc-el.
GNU General Public License v3.0
69 stars 2 forks source link

Help Request: Is there a way to dynamically modify a links description? #21

Closed mohkale closed 3 years ago

mohkale commented 3 years ago

Hi.

I've been using a custom org link type I call pdfbib that works just like the org-ref cite link except it also stores the slide/page-number in the corresponding pdf so I can automatically jump to that page when opening the link. This works by storing the slide number after the bibtex entry key. For example a path of foo::2 links to the second page of the pdf for the bibtex entry foo. I've recently started using this package as well through org-ref and I had to advice some stuff to get the export working properly.

(advice-add #'citeproc-org--cites-and-notes :filter-return
              (defun citeproc-fix-pdfbib+ (res)
                (dolist (link (car res))
                  (when (string-equal (org-element-property :type link) "pdfbib")
                    (let ((path (org-element-property :path link)))

                      (save-match-data
                        (if (not (string-match +org-pdf-bib-regex path))
                            (warn "Failed to parse pdfbib link: %s" path)
                          ;; Strip the page number suffix to make sure org-ref works.
                          (org-element-put-property link :path (match-string 1 path)))))))
                res))

This works well enough, now the page number isn't misinterpreted by citreproc-org and org-ref as part of the bib key. However I can't seem to find a way to modify the description of the link to include the page that was stored in the link path. I discovered the link structure keeps a reference to the link text in the 3rd of entry of the link list, so I can do (setcdr (nthcdr 1 link) (cons "hello world friend." (nthcdr 2 link))) to modify it however this has no effect on the export so I don't believe it's relevent.

The link itself seems to store point markers to the start and end position of the link description but I'm not sure modifying the buffer in place is an effective approach for this. Is there some way I can modify the description of a link before citeproc-org gets to it?

mohkale commented 3 years ago

I've ended up adding a hook to org-export-before-parsing-hook that uses a regexp to replace any pdfbib links with cite links. It works well enough so this issue can be closed.

(add-hook 'org-export-before-parsing-hook
            (defun citeproc-fix-pdfbib+ (_backend)
              "Replace pdfbib links with their equivalent org-ref variants in citeproc style."
              (save-excursion
                (goto-char (point-min))

                (replace-regexp (rx "["
                                    "[pdfbib:" (group (minimal-match (one-or-more any))) (optional "::" (group (one-or-more digit))) "]"
                                    (optional (group "[" (minimal-match (one-or-more any)) "]"))
                                    "]")
                                (query-replace-compile-replacement
                                 "[[cite:\\1][see page \\2\\,(if \\3 (concat \", \" \\3) \"\")]]"
                                 t)))))