tmalsburg / helm-bibtex

Search and manage bibliographies in Emacs
GNU General Public License v2.0
465 stars 74 forks source link

light formatting of candidates #393

Open jkitchin opened 3 years ago

jkitchin commented 3 years ago

Is there a way to add faces to parts of the candidates, e.g. make the authors be italicized, or add colors to the journal name, etc. this could make it easier to see different parts of the candidates.

update: I have used an ivy transformer to fontify optional org-syntax in bibtex-completion-display-formats. I guess you could also do something similar with html markup in these. This can be handled outside of bibtex-completion, but I still wonder if you have any ideas other than these.

tmalsburg commented 3 years ago

There's currently nothing that supports faces in bibex-completion. There was recently an issue about this about, but (I think) but there was no proposal for a clean (and easy to configure and maintain) solution. I think the Emacs ecosystem is in desperate need of an api for formatting tables. It's so silly that a million of helm sources (also mu4e, etc.) have to solve this problem over and over again but there is no general solution for that.

jkitchin commented 3 years ago

ok. Thanks for the update. I have hacked something that supports org-syntax in bibtex-completion-display-formats. It is not super fancy, and doesn't really support colors, but gets me bold, italics and underlining. That is pretty lightweight. I guess two other options could include html formatting (I am not sure how these would be fontified exactly), or maybe with ansi color codes?

With a little work, I could get this format (not sure the ansi codes will show right)

(article       . "${=has-pdf=:1}${=has-note=:1}${year:4} /${author}/ _${title}_, /${journal}/ ${keywords}")

to look like this with the ivy-transformer (guess it could be pushed in to bibtex-completions if you were interested in it.

image

I did have to hack ansi-color-apply to use the 'face property instead of 'font-lock-face, but otherwise it doesn't seem too bad. This is just a POC to see what can be done, I am not sure I want to keep this specific format for myself.

tmalsburg commented 3 years ago

Neat! But Ansi color codes is perhaps not something that the average user is familiar with.

jkitchin commented 3 years ago

That is fair, I was just looking for some options.

Here is another approach that I am not sure is better with an ivy-transformer. The format of the entry is a list of pieces and properties that get put together.

(defun jk (candidate)
  (let* ((width (- (frame-width) 2))
     (idx (get-text-property 1 'idx candidate))
     (entry (cdr (nth idx (ivy-state-collection ivy-last))))
     (fill-column (- width 7)))
    (with-temp-buffer
      (insert
       (mapconcat (lambda (x)
            (apply
             #'propertize
             (s-format (car x)
                   (lambda (key data)
                 (pcase key
                   ("=has-pdf=" (or (cdr (assoc key data)) "  "))
                   ("=has-note=" (or (cdr (assoc key data)) "  "))
                   ("keywords" (let ((keys (cdr (assoc key data))))
                         (if (stringp keys) 
                             (format ", (%s)" keys)
                           "")))
                   (_ (or (cdr (assoc key data)) "")))
                 )
                   entry)
             (cdr x)))
          '(("${=has-pdf=}${=has-note=} ${year} ")
            ("${author}" face (:foreground "DodgerBlue3"))
            (", ")
            ("${title}" face italic)
            (", ")
            ("${journal}") 
            ("${keywords}" face bold))
          ""))
      (fill-region (point-min) (point-max))
      (goto-char (point-min))
      (cond
       ((looking-at bibtex-completion-pdf-symbol)
    nil)
       ((looking-at " ✎")
    nil)
       (t
    (skip-chars-forward " ")
    (setf (buffer-substring (point-min) (point)) "  ")))
      (forward-line)
      (indent-region (point) (point-max) 7)

      (buffer-string))))

(ivy-configure 'org-ref-cite-insert-ivy :display-transformer-fn 'jk)

this ends up like this:

image

this works well on ~3K bibtex entries. It still needs some work, but seems to have some potential perhaps.

tmalsburg commented 3 years ago

This looks really nice! I think the current system for configuring the presentation has served us pretty well so far but it's reaching its limits. I think we need some way to configure the presentation that's more idiomatic in Elisp and that doesn't rely on a custom DSL. Not saying that I will work on this anytime soon, but this issue here is really helpful in developing some ideas.

jkitchin commented 3 years ago

I am converging on a good way to do this I think. Here I use the shr library to render html in the format strings.

(article       . "${=has-pdf=:1}${=has-note=:1} <b>${year:4}</b> <i>${author}</i>, <font color=\"RoyalBlue\">${title}</font>, ${journal}. ${keywords}")

renders like this

image

It is still not perfect, e.g. you can't conditionally add a comma at the end if there are keywords, but not if there are not. Also it seems to do the wrapping for you, I guess that could be changed perhaps. Maybe there are some alignment issues to work out. I guess getting it "just so" will require some kind of DSL though.

tmalsburg commented 3 years ago

Good idea to use shr. Some DSL that could also be used elsewhere would be nice.

bdarcus commented 2 years ago

375 is likely relevant.