org-special-block-extras: demos that are tests, rather than docs

⭐ The code lives at github.com/alhassy/org-special-block-extras —star it, or discuss it there!
1. badge
﴾What You Write﴿
1. It works when all 5 arguments are provided
badge:Let_me_google_that|for_you!|orange|https://lmgtfy.app/?q=badge+shields.io&iie=1|Elixir
2. It works when we use [ [ link ] ] syntax with generous spaces and newlines
[[badge: Let me google that | for you! | orange |
https://lmgtfy.app/?q=badge+shields.io&iie=1|Elixir]]
3. It works when only the first 2 arguments are provided;
asterisks are passed unaltered into the first argument
badge:Let_me_*not*_google_that|for_you
4. It works sans a URL, yet with a logo; Org's own <<key>> beside it is a permalink to here
<<key>> badge:key|value|informational||Elixir
5. We can use spaces, commas, dashes, and percentage symbols in the first argument
badge:example_with_spaces,_-,_and_%|points_right_here|orange
6. It works when only first 2 arguments are given: Default colour & logo are green & no logo shown
badge:key|value
7. When only a key is provided, the value slot is shown as an empty green stub
badge:key
8. When only a value is provided, only the value is shown in a default green
---no stub for the missing key, yay
badge:|value
9. It's only a green stub when provided with an empty key and empty value
badge:||green
10. It's only a green stub when we use no options at all
[[badge:]] ﴾What You Get﴿
It works when all 5 arguments are provided
It works when we use [ [ link ] ] syntax with generous spaces and newlines
It works when only the first 2 arguments are provided; asterisks are passed unaltered into the first argument
It works sans a URL, yet with a logo; Org's own beside it is a permalink to here
We can use spaces, commas, dashes, and percentage symbols in the first argument
It works when only first 2 arguments are given: Default colour & logo are green & no logo shown
When only a key is provided, the value slot is shown as an empty green stub
When only a value is provided, only the value is shown in a default green —no stub for the missing key, yay
It's only a green stub when provided with an empty key and empty value
It's only a green stub when we use no options at all
﴾How It’s Implemented﴿
(org-make-badge "badge")
2. calc
﴾What You Write﴿
#+begin_math
x
={ Explanation of why $x \;=\; y$.
Actually, let me explain:
\[ x
={ hint 1 } x′
={ hint 2 } y \]
Words may follow a nested calculation.
}
y
≤{ Explanation of why $y \;\leq\; z$
# Explain it more; this comment is absent from the export ;-)
}
z
#+end_math ﴾What You Get﴿
\begin{align*} & x \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Explanation of why $x \;=\; y$.} \\ \text{Actually, let me explain:} \\ \begin{aligned}[t] & x \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{hint 1} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & x′ \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{hint 2} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & y \end{aligned} \\ \text{Words may follow a nested calculation.} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & y \\ ≤ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Explanation of why $y \;\leq\; z$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & z \end{align*}3. kbd
﴾What You Write﴿
1. It becomes <kbd> tags, but final symbol non-ascii *may* be ignored kbd:C-u_80_-∀ 2. [ [ It ] ] becomes <kbd> tags [[kbd:C-u_80_-]] 3. Using syntax <it> becomes <kbd> tags, and surrounding space is trimmed <kbd: C-u 80 - > 4. It has a tooltip documenting the underlying Lisp function, when possible <kbd: M-s h .>
﴾What You Get﴿
It becomes <kbd> tags, but final symbol non-ascii may be ignored
C-u 80 -∀
[ [ It ] ] becomes <kbd> tags
C-u 80 -
Using syntax <it> becomes <kbd> tags, and surrounding space is trimmed
C-u 80 -
It has a tooltip documenting the underlying Lisp function, when possible
M-s h .
M-s h . ∷ highlight-symbol-at-point Highlight each instance of the symbol at point. Uses the next face from ‘hi-lock-face-defaults’ without prompting, unless you use a prefix argument. Uses ‘find-tag-default-as-symbol-regexp’ to retrieve the symbol at point. If REGEXP contains upper case characters (excluding those preceded by ‘\’) and ‘search-upper-case’ is non-nil, the matching is case-sensitive. This uses Font lock mode if it is enabled; otherwise it uses overlays, in which case the highlighting will not update as you type. The Font Lock mode is considered "enabled" in a buffer if its ‘major-mode’ causes ‘font-lock-specified-p’ to return non-nil, which means the major mode specifies support for Font Lock.
﴾How It’s Implemented﴿
(org-deflink kbd (keys &optional description backend)
"Show keysequence KEYS in a nice grey button-like font, along with a tooltip of its documentation, if any.
Such links do not get folded in [[bracket]] style, and are rendered as buttons within Emacs; clicking one
runs its keys, so readers may try them out. Keys may run any command, so we first ask, as `elisp' links
do, via `org-link-elisp-confirm-function'.
Moreover, KEYS may use ‘_’ in-lieu of spaces or [[bracket]] link notation.
Examples:
[[kbd:C-x C-s]]
≈ <kbd: C-x C-s>
≈ kbd:C-x_C-s"
:display 'full
:manual "#nice-keystroke-renditions"
:let (the-label (s-trim (s-replace "_" " " keys))
lisp-func (ignore-errors (key-binding (kbd the-label)))
tooltip (or description (ignore-errors (documentation lisp-func)) "")
tooltip? (not (equal tooltip ""))
style (if tooltip? "border-color: red" "")
keystrokes (progn (org-html-head-require 'org--kbd-html-head)
(format "<kbd style=\"%s\">%s</kbd>" style the-label)))
;; The description is always nil when it comes to deciding the :face.
:face (list :inherit 'custom-button :box (if tooltip? "red" t))
:help-echo (format "%s ∷ %s\n%s\n\nClick to run these keys." the-label (or lisp-func "") tooltip)
:follow (org--kbd-run the-label)
:export (cond ((equal backend 'latex) (format "\\texttt{%s}" the-label))
;; The style is to remove the underlining caused by <abbr>.
(tooltip? (org--html-tooltip (format "%s ∷ %s\n%s" the-label (or lisp-func "") tooltip) keystrokes
:plain "border: none; text-decoration: none;"))
(t keystrokes)))
4. solution
﴾What You Write﴿
What is the name of Prophet Yusuf's father? Hint: The father's name also starts with `y`. #+begin_solution Yacoub #+end_solution
﴾What You Get﴿
What is the name of Prophet Yusuf's father?
Hint: The father's name also starts with `y`.
Solution
Did you actually try? Maybe see the ‘hints’ above!
Solution, for real
Yacoub
﴾How It’s Implemented﴿
(org-defblock solution
(&optional (title "Solution")
&key (reprimand "Did you actually try? Maybe see the ‘hints’ above!") (really "Solution, for real")
&allow-other-keys :manual "#Boxed-Text" &context raw-contents)
"Show the answers to a problem, but with a reprimand in case no attempt was made."
(org-thread-blockcall raw-contents
(details really :title-color "red")
(box reprimand :background-color "blue")
(details title)))
5. spoiler
﴾What You Write﴿
The ~spoiler~ block is for “fill in the blanks” or “guess, and hover to see the results” style of exposition. #+begin_spoiler ((Yusuf)) said to his father ((Yacoub)), /“O my father, indeed I have seen ((eleven stars)) and ((the sun and the moon)); I saw them prostrating to me.”/ #+end_spoiler There are also options for the left delimiter of a hidden item, the right delimiter, and the color of the hidden item. These default to ~grey, ((, ))~ respectively. #+begin_spoiler orange :left "[" :right "]" [Yusuf] said to his father [Yacoub], /“O my father, indeed I have seen [eleven stars] and [the sun and the moon]; I saw them prostrating to me.”/ #+end_spoiler
﴾What You Get﴿
The spoiler block is for “fill in the blanks” or “guess, and hover
to see the results” style of exposition.
Yusuf said to his father Yacoub , “O my father, indeed I have seen eleven stars and the sun and the moon ; I saw them prostrating to me.”
There are also options for the left delimiter of a hidden item, the right delimiter,
and the color of the hidden item. These default to grey, ((, )) respectively.
Yusuf said to his father Yacoub , “O my father, indeed I have seen eleven stars and the sun and the moon ; I saw them prostrating to me.”
﴾How It’s Implemented﴿
(org-defblock spoiler (&optional (color "grey") &key (left "((") (right "))") &allow-other-keys :manual "#Boxed-Text"
&context backend raw-contents contents)
"Hide text enclosed in double parens ((like this)) as if it were spoilers.
LEFT and RIGHT may be other kinds of delimiters.
The main argument, COLOR, indicates which color to use.
For LaTeX, this becomes “fill in the blanks”, with the answers
in the footnotes; for Markdown, whose renderers strip <style>, numbered
blanks with the answers folded away beneath them."
(cond
((org-export-markdown-p)
(let* ((answers nil)
(blanked (replace-regexp-in-string
(concat (regexp-quote left) "\\(.*?\\)" (regexp-quote right))
(lambda (it)
(push (match-string 1 it) answers)
(format "@@html:<ins> %s </ins>@@" (length answers)))
raw-contents t t)))
(org-parse (format "%s\n\n#+html: <details><summary>Answers</summary>\n\n%s\n\n#+html: </details>"
blanked
(s-join "\n" (--map-indexed (format "%s. %s" (1+ it-index) it) (reverse answers)))))))
((equal backend 'latex)
(s-replace-regexp
(concat (regexp-quote left) "\\(.*?\\)" (regexp-quote right))
"@@latex:\\\\fbox{\\\\phantom{\\1}}\\\\footnote{\\1}@@"
contents))
(t
;; The styling depends only on COLOR, so a class per colour serves every spoiler of that colour.
(-let [class (format "spoiler-%s" color)]
(concat
;; In HTML, a ‘style’ can be, technically, almost anywhere...
(format "<style> .%s {color: %s; background-color:%s;} .%s:hover {color: black; background-color:white;} </style>\n"
class color color class)
(s-replace-regexp
(concat (regexp-quote left) "\\(.*?\\)" (regexp-quote right))
(format "@@html:<span class=\"%s\"> \\1 </span>@@" class)
contents))))))
6. tree
﴾What You Write﴿
#+begin_box Programming ≈ Proving #+begin_tree + Function Application :: f(a) : B - a : A - f : A → B + Modus Ponens :: q - p - p ⇒ q #+end_tree #+end_box
﴾What You Get﴿
Programming ≈ Proving
\[\frac{\displaystyle a : A \qquad f : A → B }{f(a) : B}[\text{Function Application}]\]\[\frac{\displaystyle p \qquad p ⇒ q}{q}[\text{Modus Ponens}]\]﴾How It’s Implemented﴿
(org-defblock tree (&allow-other-keys :html-head (mathjax) :manual "#Aligned-equations" &context raw-contents)
"Write a proof tree using Org-lists.
To get
premises₀ … premisesₙ
────────────────────────────[ reason ]
conclusion
You type
#+begin_tree
+ reason :: conclusion
- premises₀
- premises₁
⋮
- premisesₙ
#+end_tree
Where each premisesᵢ may, recursively, also have named reasons
and (indented) child premises of its own.
If there are multiple trees, they are shown one after the other.
The text in this block should be considered LaTeX;
as such, Org markup is not recognised.
A proof tree, derivation, is then just a deeply nested
itemisation. For instance, assuming P = Q(X), X = Y, Q(Y) = R,
the following proves P = R.
#+begin_tree
+ Trans :: P = R
- P = Q(X)
+ ✓
- Trans :: Q(X) = R
+ Trans :: Q(X) = Q(Y)
- Refl :: Q(X) = Q(X)
+ ✓
- Leibniz :: Q(X) = Q(Y)
+ X = Y
- ✓
+ Sym :: Q(Y) = R
- R = Q(Y)
- ✓
#+end_tree
In Markdown, each tree is a $$…$$ display, since GitHub's maths knows no \\[…\\]."
(-let [md? (org-export-markdown-p)]
(mapconcat (lambda (it) (format (if md? "$$%s$$" "\\[%s\\]") (org--list-to-math it)))
(cdr (org--parse-plain-list raw-contents "tree"))
(if md? "\n\n" ""))))
Life & Computing Science by Musa Al-hassy is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License