Projects About AlBasmala
build status

Tooltips for Glossaries, Dictionaries, and Documentation

Article image
  

Ξ  

⭐ The code lives at github.com/alhassy/org-special-block-extras —star it, or discuss it there!

Sometimes I want to use the same tooltip multiple times, so I write the tooltip content once in a documentation block and then reference it using the the doc link type.

Now I can reference this documentation entry using its label as in Category Theory or using its full entry name, with spaces replaced by underscores, as in Category Theory; finally, we can also use descriptions as in graphs + monoids.

The :label is optional; when not provided it defaults to the name of the entry with spaces replaced by ‘_’. For more, see org-block/documentation. Entry names do not need to be unique, but labels do! ( The labels are like the addresses used to look up a person's home. )

In this way, I can create a custom glossary.

An entry may also be a heading —an Org file as data— tagged :documentation:; its title is the name, its :DOC_KEYS: property holds space-separated labels, and its own text is the entry. Unlike the block, the heading exports as an ordinary section.

* Category Theory                                            :documentation:
:PROPERTIES:
:DOC_KEYS: cat cats
:END:
A theory of typed composition; e.g., typed monoids.

Entries are read afresh before each export, so #+print_glossary: lists every citation in a single export, wherever it sits; and the files in org-docs-libraries are read, not exported, so loading them is quick.

My personal documentation library can be seen here: or

Moreover, the doc link type lets me reference Emacs-documentation such as loop or thread-last, and English-dictionary entries such as happiness.

Finally, in Emacs, these links also have tooltips ☺️ As it stands, Emacs tooltips only appear after an export has happened: The export updates the dictionary variable which is used for the tooltips utility. TODO: Make a method docs-update to update the docs database, regardless of export. Low priority. THIS EXISTS AS (org-docs-load-libraries) ??

Notice how hovering over items makes them appear, but to make them disappear you should click on them or scroll away. This is ideal when one wants to have multiple ‘definitions’ visible ;-)


Eye-candy ---A gallery of images

tooltips_browser.png

Figure 1: Tooltips for documentation and glossary items –in the browser!

tooltips_emacs.png

Figure 2: Tooltips for documentation and glossary items –in Emacs!

tooltips_pdf.png

Figure 3: Tooltips for documentation and glossary items –in the PDF!

#+endquote

Below are the entries in my personal glossary ;-)

Category Theory Category Theory Category Theory Category Theory existential_angst Existential_Angst ex-angst existential_angsty Existential_Angsty nil nil hussain Hussain Karbala Cosmic_Tragedy hello Hello nil graph Graph nil expression Expression nil induction Induction nil textual_substitution Textual_Substitution nil inference_rule Inference_Rule nil logic Logic nil theorem Theorem nil metatheorem Metatheorem nil calculus Calculus Propositional_Calculus semantics Semantics temp temp calculational_proof Calculational_Proof nil programming Programming nil specification Specification nil proving_is_programming Proving_is_Programming nil algorithmic_problem_solving Algorithmic_Problem_Solving nil natural_transformation Natural_Transformation nat-trans polymorphism Category Theory Category Theory associative Associative nil identity Identity nil distributive Distributive nil commutative Commutative nil reflexive Reflexive nil transitive Transitive nil symmetric Symmetric nil antisymmetric Antisymmetric nil asymmetric Asymmetric nil preorder Preorder nil equivalence Equivalence nil linear Linear nil semilinear Semilinear nil univalent Univalent nil total Total nil map Map nil surjective Surjective nil injective Injective nil bijective Bijective nil iso Iso nil difunctional Difunctional nil nil hussain Hussain Karbala Cosmic_Tragedy hello Hello nil graph Graph nil expression Expression nil induction Induction nil textual_substitution Textual_Substitution nil inference_rule Inference_Rule nil logic Logic nil theorem Theorem nil metatheorem Metatheorem nil calculus Calculus Propositional_Calculus semantics Semantics temp temp calculational_proof Calculational_Proof nil programming Programming nil specification Specification nil proving_is_programming Proving_is_Programming nil algorithmic_problem_solving Algorithmic_Problem_Solving nil natural_transformation Natural_Transformation nat-trans polymorphism Category Theory Category Theory Category Theory associative Associative nil identity Identity nil distributive Distributive nil commutative Commutative nil reflexive Reflexive nil transitive Transitive nil symmetric Symmetric nil antisymmetric Antisymmetric nil asymmetric Asymmetric nil preorder Preorder nil equivalence Equivalence nil linear Linear nil semilinear Semilinear nil univalent Univalent nil total Total nil map Map nil surjective Surjective nil injective Injective nil bijective Bijective nil iso Iso nil difunctional Difunctional nil nil hussain Hussain Karbala Cosmic_Tragedy hello Hello nil graph Graph nil expression Expression nil induction Induction nil textual_substitution Textual_Substitution nil inference_rule Inference_Rule nil logic Logic nil theorem Theorem nil metatheorem Metatheorem nil calculus Calculus Propositional_Calculus semantics Semantics temp temp calculational_proof Calculational_Proof nil programming Programming nil specification Specification nil proving_is_programming Proving_is_Programming nil algorithmic_problem_solving Algorithmic_Problem_Solving nil natural_transformation Natural_Transformation nat-trans polymorphism Category Theory Category Theory Category Theory associative Associative nil identity Identity nil distributive Distributive nil commutative Commutative nil reflexive Reflexive nil transitive Transitive nil symmetric Symmetric nil antisymmetric Antisymmetric nil asymmetric Asymmetric nil preorder Preorder nil equivalence Equivalence nil linear Linear nil semilinear Semilinear nil univalent Univalent nil total Total nil map Map nil surjective Surjective nil injective Injective nil bijective Bijective nil iso Iso nil difunctional Difunctional nil Category Theory Category Theory Category Theory existential_angst Existential_Angst ex-angst existential_angsty Existential_Angsty nil nil hussain Hussain Karbala Cosmic_Tragedy hello Hello nil graph Graph nil expression Expression nil induction Induction nil textual_substitution Textual_Substitution nil inference_rule Inference_Rule nil logic Logic nil theorem Theorem nil metatheorem Metatheorem nil calculus Calculus Propositional_Calculus semantics Semantics temp temp calculational_proof Calculational_Proof nil programming Programming nil specification Specification nil proving_is_programming Proving_is_Programming nil algorithmic_problem_solving Algorithmic_Problem_Solving nil natural_transformation Natural_Transformation nat-trans polymorphism Category Theory Category Theory Category Theory associative Associative nil identity Identity nil distributive Distributive nil commutative Commutative nil reflexive Reflexive nil transitive Transitive nil symmetric Symmetric nil antisymmetric Antisymmetric nil asymmetric Asymmetric nil preorder Preorder nil equivalence Equivalence nil linear Linear nil semilinear Semilinear nil univalent Univalent nil total Total nil map Map nil surjective Surjective nil injective Injective nil bijective Bijective nil iso Iso nil difunctional Difunctional hussain Hussain Karbala Cosmic_Tragedy hello Hello nil graph Graph nil expression Expression nil induction Induction nil textual_substitution Textual_Substitution nil inference_rule Inference_Rule nil logic Logic nil theorem Theorem nil metatheorem Metatheorem nil calculus Calculus Propositional_Calculus semantics Semantics temp temp calculational_proof Calculational_Proof nil programming Programming nil specification Specification nil proving_is_programming Proving_is_Programming nil algorithmic_problem_solving Algorithmic_Problem_Solving nil natural_transformation Natural_Transformation nat-trans polymorphism Category Theory Category Theory Category Theory associative Associative nil identity Identity nil distributive Distributive nil commutative Commutative nil reflexive Reflexive nil transitive Transitive nil symmetric Symmetric nil antisymmetric Antisymmetric nil asymmetric Asymmetric nil preorder Preorder nil equivalence Equivalence nil linear Linear nil semilinear Semilinear nil univalent Univalent nil total Total nil map Map nil surjective Surjective nil injective Injective nil bijective Bijective nil iso Iso nil difunctional Difunctional nil

In the export, it looks like some names are repeated, but in the source one would notice that we have labels in both upper and lower cases and with underscores ;-) They just happen to be referring to the same named entry.

#+enddetails

Tests
(deftest "It gives a tooltip whose title is the Lisp docs of APPLY"
  [doc]
  (⇝ (⟰ "doc:apply")
     "<abbr class=\"tooltip\" title=\""
     (literal (s-replace "\n" "<br>" (documentation #'apply)))
     "\">apply</abbr>"))

(setq angst
      (⟰ "#+begin_documentation Existential Angst :label \"ex-angst\"
                       A negative feeling arising from freedom and responsibility.

                       Also known as
                       1. /Existential Dread/, and
                       2. *Existential Anxiety*.

                       Perhaps a distraction, such as [[https://www.w3schools.com][visiting W3Schools]], may help ;-)

                       Then again, ~coding~ can be frustrating at times, maybe have
                       a slice of pie with maths by reading “$e^{i×π} + 1 = 0$” as a poem ;-)
                       #+end_documentation

                       We now use this as doc:ex-angst."))

(deftest "Documentation blocks are not exported; they produce a new osbe--docs entry"
  [doc documentation o--name&doc]
    (should (org-docs-get "ex-angst")))

;; Upon export, the #+begin_documentation is /not/ present.
;; We have the text outside that block only.
;; Along, with a htmlified tooltip of the new entry.
(deftest "The osbe--docs entry of the documentation block appears within a tooltip"
    [doc documentation o--name&doc]
    (⇝ angst " <p> We now use this as <abbr class=\"tooltip\" title=\""
             (literal (org-osbe-html-export-preserving-whitespace
                       (cl-second (org-docs-get "ex-angst"))))
                    "\">Existential Angst</abbr>.</p> "))

2. Wait, what about the LaTeX?

A PDF is essentially a fancy piece of paper, so tooltips will take on the form of glossary entries: Using doc:𝒳 will result in the word 𝒳 being printed as a hyperlink to a glossary entry, which you the user will eventually declare using #+print_glossary:, as #+print_bibliography: lists cited works; moreover, the glossary entry will also have a link back to where the doc:𝒳 was declared. E.g., defmacro and lambda.

For example, here is a word whose documentation is obtained from Emacs rather than me writing it: thread-last. If you click on it, in the LaTeX output, you will be directed to the glossary at the end of this article —glossaries are not printed in HTML rendering.

Neato! The whitespace in the documentation is preserved in the LaTeX output as is the case for HTML.

If we decide to erase a doc:𝒳, then it should not longer appear in the printed glossary listing. Likewise, a documentation block has its Org markup exported according to the backend being exported to, hence if we decide to switch between different backends then only the first rendition will be used unless we erase the database each time after export.

(defvar org--docs-empty! (list nil t)
  "An indicator of when glossary entries should be erased.

We erase the glossary not on the first export, but on the second export.
The first export collects all citations, which are used in the second export.")
(setcdr (last org--docs-empty!) org--docs-empty!) ;; It's an infinite cyclic list.

;; Actual used glossary entries depends on the buffer; so clean up after each export
(advice-add #'org-export-dispatch
  :after (lambda (&rest _)
  (when (pop org--docs-empty!)
      (setq org--docs-actually-used nil ;; The 𝒳 of each “doc:𝒳” that appears in the current buffer.
            org--docs nil))))           ;; The “#+begin_documentation ⋯ :label 𝒳” of the current buffer.

3. Next Steps

Going forward, it'd be nice to have URLs work well upon export for documentation block types; whereas they currently break the HTML export.

  • If an entry is referenced multiple times, such as Category Theory, then it would be nice if the glossary referred to the pages of all such locations rather than just the final one.
  • The glossary current prints in order of appearance; we may want to have the option to print it in a sorted fashion.
  • Perhaps use the line activation feature to provide link tooltips immediately rather than rely on exportation.
  • The show link type could accept an arbitrary Lisp expression as a bracketed link. It does ;-)
  • When one clicks on a doc documentation link, it would be nice to ‘jump’ to its associated #+begin_documentation declaration block in the current buffer, if possible.

Generated by Emacs and Org-mode (•̀ᴗ•́)و
Creative Commons License
Life & Computing Science by Musa Al-hassy is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License