Skip to content

Commit ee467d3

Browse files
committed
Add: Section on multimethod approach to defblock
1 parent cde8c66 commit ee467d3

File tree

1 file changed

+70
-64
lines changed

1 file changed

+70
-64
lines changed

org-special-block-extras.org

Lines changed: 70 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pre.src-C:before { content: 'Org-mode Example!'; }
149149
;; Copyright (c) 2021 Musa Al-hassy
150150

151151
;; Author: Musa Al-hassy <[email protected]>
152-
;; Version: 4.1.0
152+
;; Version: 4.1.1
153153
;; Package-Requires: ((s "1.13.1") (dash "2.18.1") (emacs "27.1") (org "9.1") (lf "1.0") (dad-joke "1.4") (seq "2.0") (lolcat "0"))
154154
;; Keywords: org, blocks, colors, convenience
155155
;; URL: https://alhassy.github.io/org-special-block-extras
@@ -518,10 +518,7 @@ badge:Emacs|27|green|https://www.gnu.org/software/emacs|gnu-emacs
518518
badge:Org|9.4|blue|https://orgmode.org|gnu
519519

520520
#+html: <span>
521-
badge:org-special-block-extras|3.0|informational|https://github.com/alhassy/org-special-block-extras|Gnu-Emacs
522-
523-
#+html: <a href="https://melpa.org/#/org-special-block-extras"><img alt="MELPA" src="https://melpa.org/packages/org-special-block-extras-badge.svg"/></a>
524-
#+html: </span>
521+
melpa:org-special-block-extras
525522

526523
[[badge:license|GNU_3|informational|https://www.gnu.org/licenses/gpl-3.0.en.html|read-the-docs][gnu 3 license badge]]
527524
[[badge:docs|literate|success|https://github.com/alhassy/emacs.d#what-does-literate-programming-look-like|read-the-docs][read-the-docs badge]]
@@ -1808,7 +1805,7 @@ Three example uses:
18081805
,(org--create-defmethod-of-defblock name docstring (plist-get kwds :backend) kwds body)
18091806
;; ⇨ The link type support
18101807
(eval (backquote (org-deflink ,name
1811-
,(vconcat `[:help-echo (format "%s:%s\n\n%s" (quote ,name) o-label ,docstring)] (cdr (assoc name org--block--link-display)))
1808+
,(vconcat `[:help-echo (format "%s:%s\n\n%s" (quote ,name) o-label ,docstring)] (or link-display (cdr (assoc name org--block--link-display))))
18121809
;; s-replace-all `((,(format "@@%s:" backend) . "") ("#+end_export" . "") (,(format "#+begin_export %s" backend) . ""))
18131810
(s-replace-regexp "@@" ""
18141811
(,(intern (format "org-block/%s" name)) o-backend (or o-description o-label) o-label :o-link? t)))))))))
@@ -3195,7 +3192,7 @@ then:
31953192

31963193
Bye!
31973194
#+end_box
3198-
* Basic defblock test :relocate:noexport:
3195+
** Basic defblock test :relocate:noexport:
31993196
:PROPERTIES:
32003197
:CUSTOM_ID: Basic-defblock-test
32013198
:END:
@@ -3257,6 +3254,70 @@ post")
32573254
"<p>\npost"))
32583255
#+end_src
32593256

3257+
** Dispatch on =backend= ---open for extensibility
3258+
:PROPERTIES:
3259+
:CUSTOM_ID: Dispatch-on-backend-open-for-extensibility
3260+
:END:
3261+
3262+
Consider the source and how it exports ...
3263+
#+begin_org-demo
3264+
The link “ [[shout:me the author][hello to the world]] ” exports with bold in HTML and large in LaTeX.
3265+
#+end_org-demo
3266+
# C-c C-e h o ⇒ bold
3267+
# C-c C-e l o ⇒ large
3268+
3269+
This could be declared via ...
3270+
#+begin_src elisp :tangle no
3271+
;; Declare the new defblock, along with how it should be displayed as an org link
3272+
(org-defblock shout0 (speaker)
3273+
[:face '(:foreground "orange" :weight bold) :display 'full]
3274+
"Capitalise the contents! Seen in orange bold in Emacs!"
3275+
(pcase backend
3276+
('html (format "Yuck/%s: <strong>%s</strong>" speaker contents))
3277+
('latex (format "Yuck/%s: \\emph{\\LARGE %s}" speaker contents))
3278+
(t (error "org-block/shout: Unsupported backend “%s”" backend))))
3279+
#+end_src
3280+
3281+
Rather than defining it with a single defblock declaration and a condition on the backend, we can define it using three
3282+
defblock declarations: One to declare the block along with top-level documentation and display link information; the
3283+
second for the HTML export; the third for the LaTeX backend export. (Your favourite backend ℬ can easily be supported by
3284+
declaring a new defblock in /your own code/!)
3285+
3286+
#+name: startup-code
3287+
#+begin_src elisp :tangle no
3288+
;; Declare the new defblock, along with how it should be displayed as an org link
3289+
(org-defblock shout (speaker)
3290+
[:face '(:foreground "orange" :weight bold) :display 'full]
3291+
"Capitalise the contents! Seen in orange bold in Emacs!")
3292+
3293+
3294+
;; Specialise its definition for when we export to the HTML backend
3295+
(org-defblock shout (speaker nil :backend html)
3296+
"To shout is to be bold; i.e., strong."
3297+
(format "%s: <strong>%s</strong>" speaker contents))
3298+
3299+
3300+
;; Specialise its definition for when we export to the LaTeX backend
3301+
(org-defblock shout (speaker nil :backend latex)
3302+
"Shouting is a what LARGE brutes do"
3303+
(format "%s: \\emph{\\LARGE %s}" speaker contents))
3304+
#+end_src
3305+
3306+
Try kbd:C-h_o_org-defblock/shout and see two implementations.
3307+
- This means that users can always re-define an org special block, or extend it to support a new backend. Neato!
3308+
- Free user extensibility!
3309+
3310+
Such “open methods” are known as “multimethods”; e.g., see doc:cl-defgeneric and doc:cl-defmethod.
3311+
3312+
:Multimethod_invocation_examples_of_SHOUT:
3313+
#+begin_src elisp :tangle no
3314+
;; Example uses of the multimethods approach
3315+
(org-block/shout 'random-backend "hi") ;; should error!
3316+
(org-block/shout 'html "hi")
3317+
(org-block/shout 'latex "hi")
3318+
#+end_src
3319+
:End:
3320+
32603321
* Folded Details ---As well as boxed text and subtle colours
32613322
:PROPERTIES:
32623323
:CUSTOM_ID: Folded-Details
@@ -3332,61 +3393,6 @@ it may be prudent to expose more aspects as arguments.
33323393
</details>" background-color title-color title contents))))
33333394
#+end_src
33343395

3335-
#+RESULTS:
3336-
| :export | (lambda (label description backend) (s-replace-all `((#+end_export . ) (,(format #+begin_export %s backend) . )) (org--details backend (or description label) label))) | :help-echo | (lambda (window object position) (save-excursion (goto-char position) (-let* (((&plist :path :format :raw-link :contents-begin :contents-end) (cadr (org-element-context))) (description (when (equal format 'bracket) (copy-region-as-kill contents-begin contents-end) (substring-no-properties (car kill-ring))))) (format %s |
3337-
3338-
:HACK:Disabled:
3339-
Above is a lower-case ‘d’etails block, we now make a captial-case ‘D’etails
3340-
block, for the not-too-odd situation we want to have, right away, one details block
3341-
within another.
3342-
#+begin_src emacs-lisp :exports none
3343-
(org-defblock Details (title "Details"
3344-
background-color "#e5f5e5" title-color "green")
3345-
"Enclose contents in a folded up box, for HTML.
3346-
3347-
For LaTeX, this is just a boring, but centered, box.
3348-
3349-
By default, the TITLE of such blocks is “Details”
3350-
its TITLE-COLOR is green, and BACKGROUND-COLOR is “#e5f5e5”.
3351-
3352-
In HTML, we show folded, details, regions with a nice greenish colour.
3353-
3354-
In the future ---i.e., when I have time---
3355-
it may be prudent to expose more aspects as arguments.
3356-
"
3357-
(pcase backend
3358-
(`latex (concat (pcase (substring background-color 0 1)
3359-
("#" (format "\\definecolor{osbe-bg}{HTML}{%s}" (substring background-color 1)))
3360-
(_ (format "\\colorlet{osbe-bg}{%s}" background-color)))
3361-
(pcase (substring title-color 0 1)
3362-
("#" (format "\\definecolor{osbe-fg}{HTML}{%s}" (substring title-color 1)))
3363-
(_ (format "\\colorlet{osbe-fg}{%s}" title-color)))
3364-
(format "\\begin{quote}
3365-
\\begin{tcolorbox}[colback=osbe-bg,colframe=osbe-fg,title={%s},sharp corners,boxrule=0.4pt]
3366-
%s
3367-
\\end{tcolorbox}
3368-
\\end{quote}" title contents)))
3369-
(_ (format "<details class=\"code-details\"
3370-
style =\"padding: 1em;
3371-
background-color: %s;
3372-
border-radius: 15px;
3373-
color: hsl(157 75% 20%);
3374-
font-size: 0.9em;
3375-
box-shadow: 0.05em 0.1em 5px 0.01em #00000057;\">
3376-
<summary>
3377-
<strong>
3378-
<font face=\"Courier\" size=\"3\" color=\"%s\">
3379-
%s
3380-
</font>
3381-
</strong>
3382-
</summary>
3383-
%s
3384-
</details>" background-color title-color title contents))))
3385-
#+end_src
3386-
MA: TODO: The above should not be present, it should instead be factored out
3387-
into a defblock-alias function.
3388-
:End:
3389-
33903396
:Posterity_Older_implementation:
33913397
#+BEGIN_SRC emacs-lisp -n -r :tangle no
33923398
(defun org--details (backend contents)
@@ -6088,7 +6094,7 @@ wish to use; e.g., badge:|1d8348|1d8348
60886094
the LaTeX backend. {{{newline}}} [[remark:Author][That is why no examples are shown in the PDF]] It
60896095
may be useful to colour the =|=-separated fields of a badge link.
60906096
# This would make the interface more welcoming to new users.
6091-
* COMMENT Tooltips for Glossaries, Dictionaries, and Documentation
6097+
* Tooltips for Glossaries, Dictionaries, and Documentation
60926098
:PROPERTIES:
60936099
:CUSTOM_ID: Tooltips-for-Glossaries-Dictionaries-and-Documentation
60946100
:END:
@@ -7489,7 +7495,7 @@ block types; whereas they currently break the HTML export.
74897495
to its associated =#+begin_documentation= declaration block in the current
74907496
buffer, if possible.
74917497

7492-
* COMMENT Marginal, “one-off”, remarks
7498+
* Marginal, “one-off”, remarks
74937499
:PROPERTIES:
74947500
:CUSTOM_ID: Marginal-one-off-remarks
74957501
:END:

0 commit comments

Comments
 (0)