html-export-style:solarized_light
#
#
#
;;; org-special-block-extras.el --- 30 new custom blocks & 34 link types for Org-mode -*- lexical-binding: t; -*-
;; Copyright (c) 2021 Musa Al-hassy
;; Author: Musa Al-hassy <alhassy@gmail.com>
;; Version: 4.1.1
;; 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"))
;; Keywords: org, blocks, colors, convenience
;; URL: https://alhassy.github.io/org-special-block-extras
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; This library provides common desirable features using the Org interface for
;; blocks and links:
;;
;; 0. A unified interface, the ‘defblock’ macro, for making new block and link types.
;;
;; 1. Colours: Regions of text and inline text can be coloured using 19 colours;
;; easily extendable; below is an example.
;;
;; #+begin_red org
;; /This/
;; *text*
;; _is_
;; red!
;; #+end_red
;;
;; 2. Multiple columns: Regions of text are exported into multiple side-by-side
;; columns
;;
;; 3. Remarks: First-class visible editor comments
;;
;; 4. Details: Regions of text can be folded away in HTML
;;
;; 5. Badges: SVG badges have the pleasant syntax
;; badge:key|value|colour|url|logo; only the first two are necessary.
;;
;; 6. Tooltips: Full access to Lisp documentation as tooltips, or any other
;; documentation-backend, including user-defined entries; e.g., doc:thread-first
;; retrives the documentation for thread-first and attachs it as a tooltip to
;; the text in the HTML export and as a glossary entry in the LaTeX export
;;
;; 7. Various other blocks: Solution, org-demo, spoiler (“fill in the blanks”).
;;
;; This file has been tangled from a literate, org-mode, file; and so contains
;; further examples demonstrating the special blocks it introduces.
;;
;; Full documentation can be found at
;; https://alhassy.github.io/org-special-block-extras
;;; Code:
;; String and list manipulation libraries
;; https://github.com/magnars/dash.el
;; https://github.com/magnars/s.el
(require 's) ;; “The long lost Emacs string manipulation library”
(require 'dash) ;; “A modern list library for Emacs”
(require 'subr-x) ;; Extra Lisp functions; e.g., ‘when-let’.
(require 'cl-lib) ;; New Common Lisp library; ‘cl-???’ forms.
(require 'cus-edit) ;; To get the custom-* faces
(require 'org)
(require 'ox-latex)
(require 'ox-html)
(require 'seq)
(require 'lf)
(defconst org-special-block-extras-version (package-get-version))
(defun org-special-block-extras-version ()
"Print the current version of the package in the minibuffer."
(interactive)
(message org-special-block-extras-version))
<<forward-decls>>
#
(defcustom org-special-block-add-html-extra t
"Whether to let `org-special-block-extras' to add content to the `ox-html' head tag.
The `org-special-block-extras' mode adds a lot of extra HTML/JS code that
1. [Bloat] may not be needed by everyone using this package,
2. [Security Threat] loads stuff from foreign websites.
Since the extra stuff is for beautiful tooltips or styles,
for ease of use, the default behaviour is to use such
“untrusted data from untrusted websites”.
To avoid such behaviour, set this variable to `nil'.")
;;;###autoload
(define-minor-mode org-special-block-extras-mode
"Provide 30 new custom blocks & 34 link types for Org-mode.
All relevant Lisp functions are prefixed ‘org-’; e.g., `org-docs-insert'.
This minor mode uses “untrusted data from untrusted websites” when exporting
to HTML, this is done for beautiful tooltips or styles.
Disable this behaviour by setting `org-special-block-add-html-extra' to `nil'.
"
:lighter " OSPE"
(if org-special-block-extras-mode
(progn
<<enable-mode>>
) ;; Must be on a new line; I'm using noweb-refs
<<disable-mode>>
)) ;; Must be on a new line; I'm using noweb-refs
osbe-example:~/org-special-block-extras/tests/details.yaml
The implementation of details
above is hidden away, and this is a
concrete example of hiding a boring, but important, code snippet.
Below is a concrete example of a ‘conversation-style’ usage of the
details
block:
We have thus found the above Lisp program to compute the inverse factorial of 𝓃;
i.e.,
Neato, let’s do more super cool stuff ^_^
summary:hover {background:pink;}
Sometimes you want to remark on details without drawing too much attention, and so a tooltip via tooltip suffices.
Sometimes you want to remark on details without drawing too much attention, and so a tooltip via remark suffices.
osbe-example:~/org-special-block-extras/tests/tooltip.yaml
It is pronounced “mar key”.
is a scrolling piece of text.
Source:
An HTML “marquee”
♯+begin_tooltip
An example is best:
♯+begin_export html
<marquee>Catch me if you can!</marquee>
♯+end_export
It is pronounced “mar key”.
♯+end_tooltip
is a scrolling piece of text.
The rest is an arduous exercise if you don’t know what’s going on.
exercise to show that ℕ is fixedpoint of Maybe
.
Source:
It's a
#+begin_tooltip simple
/Proof Sketch:/ “Squint” your eyes to see ~zero : ℕ~ and ~nothing : Maybe ℕ~ as
essentially the same, and “squint” your eyes to see that ~suc~ is essentially the
same as ~just~.
More formally, here's one direction:
#+begin_src haskell :tangle no
to : Maybe ℕ → ℕ
to nothing = zero
to (just n) = suc n
#+end_src
The rest is an arduous exercise if you don't know what's going on.
#+end_tooltip
exercise to show that ℕ is fixedpoint of ~Maybe~.
We can show Maybe ℕ ≅ ℕ
by writing two functions…
to : Maybe ℕ → ℕ
to nothing = zero
to (just n) = suc n
from : ℕ → Maybe ℕ
from zero = nothing
from (suc n) = just n
…and, finally, checking that the two functions undo each other…
to∘from : ∀ {n} → to (from n) ≡ n
to∘from n = {! try it! }
from∘to : ∀ {m} → from (to m) ≡ m
from∘to m = {! try it! }
This is “simple”, but involved!
exercise to show that ℕ is fixedpoint of Maybe
.
Source:
It's a
#+begin_tooltip simple
We show that there is an /isomorphism/; i.e., a non-lossy protocol between ~Maybe ℕ~
and ~ℕ~ in stages.
First, let's recall the definitions ... in Agda ...
#+begin_src haskell :tangle no :tangle no
data Maybe (A : Set) : Set₁ where
nothing : Maybe A
just : A → Maybe A
data ℕ : Set where
zero : ℕ
suc : ℕ → ℕ
#+end_src
We can show ~Maybe ℕ ≅ ℕ~ by writing two functions...
#+begin_src haskell :tangle no
to : Maybe ℕ → ℕ
to nothing = zero
to (just n) = suc n
from : ℕ → Maybe ℕ
from zero = nothing
from (suc n) = just n
#+end_src
...and, finally, checking that the two functions undo each other...
#+begin_src emacs-lisp
to∘from : ∀ {n} → to (from n) ≡ n
to∘from n = {! try it! }
from∘to : ∀ {m} → from (to m) ≡ m
from∘to m = {! try it! }
#+end_src
This is “simple”, but involved!
#+end_tooltip
exercise to show that ℕ is fixedpoint of ~Maybe~.
pre.tooltip {color: black; background-color:Snow;}
For the tooltips containing code snippets, I’ve declared the following to make the code look nice.
#+html: <style> pre.tooltip {color: black; background-color:Snow;} </style>
osbe-example:~/org-special-block-extras/tests/box.yaml
Or, with just the header option :shadow t
…
Or, with the header option :shadow (:left "inset cyan" :right "inset pink"
:deep-right orange)
…
For further header options, see the documentation of box.
In the first example above, how did we get that nice light blue? What
is its HTML code? That’s not something I care to remember, so let’s
make a handy dandy utility … Now when users request a colour to box
their text, it will be a ‘subtle colour’ ;-)
To use these colour names, you will need the following incantations in your Org file.
#+latex_header: \usepackage{xcolor}
#+latex_header: \definecolor{teal} {HTML}{99FFCC}
#+latex_header: \definecolor{brown} {HTML}{CCCC99}
#+latex_header: \definecolor{gray} {HTML}{CCCCCC}
#+latex_header: \definecolor{purple} {HTML}{CCCCFF}
#+latex_header: \definecolor{lime} {HTML}{CCFF99}
#+latex_header: \definecolor{green} {HTML}{CCFFCC}
#+latex_header: \definecolor{blue} {HTML}{CCFFFF}
#+latex_header: \definecolor{orange} {HTML}{FFCC99}
#+latex_header: \definecolor{peach} {HTML}{FFCCCC}
#+latex_header: \definecolor{pink}{HTML}{FFCCFF}
#+latex_header: \definecolor{yellow} {HTML}{FFFF99}
#+latex_header: \definecolor{custard}{HTML}{FFFFCC}
#+latex_header: \definecolor{cyan}{HTML}{00FFFF}
In the future, it’d be nice to account for colours for LaTeX as well. ( E.g., src_latex[:exports code]{\color{blue}} is a nightmare. )
To present mathematical formulae in HTML export, we may use
LaTeX-style commands such as {\color{red} x}
by enclosing them in
$
-symbols to obtain $
-delimiters.)
It is common to declare LaTeX definitions for convenience, but such
declarations occur within $
-delimiters and thereby produce
undesirable extra whitespace. See the superflous vertical whitespace
in the Result
side below.
As such, we declare the latex-definitions block type which avoids displaying such extra whitespace in the resulting HTML.
osbe-example:~/org-special-block-extras/tests/latex-definitions.yaml
Anyone who writes about Emacs will likely want to mention keystrokes in an aesthetically pleasing way, such as kbd:C-u 80 - to insert 80 dashes, or kbd:C-c_C-e_h_o to export an Org-mode file to HTML, or the useful <kbd:M-s h .>.
kbd:𝒳
will show a tooltip defining 𝒳, as an Emacs Lisp function, if possible. For example,kbd:C-h_h
is kbd:C-h_h; and likewise<kbd:M-s h .>
is <kbd:M-s h .> (we need to use<...>
since punctuation is not picked up as part of link labels). In contrast,kbd:nope
renders as kbd:nope without a tooltip (nor a red border).You can also supply explicit tooltip description:
[[kbd:key sequence][description]]
will show as description; i.e., the key sequence in nice key font along with a tooltip explaining it.
#
The following styling rule is used to make the keystrokes displayed nicely.
(defvar org--ospe-kbd-html-setup nil
"Has the necessary keyboard styling HTML beeen added?")
(unless org--ospe-kbd-html-setup
(setq org--ospe-kbd-html-setup t))
(when org-special-block-add-html-extra
(setq org-html-head-extra
(concat org-html-head-extra
"
<style>
/* From: https://endlessparentheses.com/public/css/endless.css */
/* See also: https://meta.superuser.com/questions/4788/css-for-the-new-kbd-style */
kbd
{
-moz-border-radius: 6px;
-moz-box-shadow: 0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
-webkit-border-radius: 6px;
-webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
background-color: #f7f7f7;
border: 1px solid #ccc;
border-radius: 6px;
box-shadow: 0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
color: #333;
display: inline-block;
font-family: 'Droid Sans Mono', monospace;
font-size: 80%;
font-weight: normal;
line-height: inherit;
margin: 0 .1em;
padding: .08em .4em;
text-shadow: 0 1px 0 #fff;
word-spacing: -4px;
box-shadow: 2px 2px 2px #222; /* MA: An extra I've added. */
}
</style>")))
Let’s have some sanity tests…
(deftest "It becomes <kbd> tags, but final symbol non-ascii *may* be ignored"
[kbd direct-org-links]
(⇝ (⟰ "kbd:C-u_80_-∀") "<p>\n<kbd style=\"\">C-u 80</kbd>_-∀</p>"))
(deftest "[[It]] becomes <kbd> tags"
[kbd square-org-links]
(⇝ (⟰ "[[kbd:C-u_80_-]]") "<p>\n<kbd style=\"\">C-u 80 -</kbd></p>"))
(deftest "<It> becomes <kbd> tags, and surrounding space is trimmed"
[kbd angle-org-links]
(⇝ (⟰ "<kbd: C-u 80 - >") "<p>\n<kbd style=\"\">C-u 80 -</kbd></p>"))
;; FIXME: uh-oh!
(when nil
(deftest "It has a tooltip documenting the underlying Lisp function, when possible"
[kbd tooltip]
(⇝ (⟰ "<kbd: M-s h .>")
"<abbr class=\"tooltip\""
(* anything)
"Highlight each instance of the symbol at point.<br>Uses the
next face from ‘hi-lock-face-defaults’ without
prompting,<br>unless you use a prefix argument.<br>Uses
‘find-tag-default-as-symbol-regexp’ to retrieve the symbol
at point.<br><br>This uses Font lock mode if it is enabled;
otherwise it uses overlays,<br>in which case the
highlighting will not update as you type. The
Font<br>Lock mode is considered ''enabled'' in a buffer if
its ‘major-mode’<br>causes ‘font-lock-specified-p’ to return
non-nil, which means<br>the major mode specifies support for
Font Lock."
(* anything)
"<kbd style=\"border-color: red\">M-s h .</kbd></abbr>")))
osbe-example:~/org-special-block-extras/tests/parallel.yaml
Add images for the “osbe-example” results and link to the html, since otherwise things don’t look as nice in a markdown readme file.
( Markdown does not support colour; go look at the HTML or PDF! )
The full article may be read as a PDF or as HTML —or visit the repo.
link-here:summary
Let 𝒞
be any of the following: black
, blue
, brown
, cyan
, darkgray
, gray
, green
,
lightgray
, lime
, magenta
, olive orange
, pink
, purple
, red
, teal
, violet
, white
,
yellow
.
Idea | Documentation | Link only? |
---|---|---|
Colours | 𝒞 , latex-definitions, color | |
Parallel | parallel | |
Editorial Comments | remark | |
Folded Details | details , box | |
Keystrokes | kbd | |
OctoIcons & Link Here | octoicon , link-here | |
Documentation-Glossary | documentation | doc |
Marginal remarks | margin | |
Badges | badge | |
Equational proofs | calc |
Other fun stuff: solution, org-demo, stutter, rename, spoiler, tree 😁
There are also the social badge links:
reddit-subscribe-to
, github-followers
, github-forks
, github-stars, github-watchers
, twitter-follow
, and tweet
.
Manually or using quelpa:
;; ⟨0⟩ Download the org-special-block-extras.el file manually or using quelpa
(quelpa '(org-special-block-extras :fetcher github :repo
"alhassy/org-special-block-extras"))
;; ⟨1⟩ Have this always active in Org buffers
(add-hook #'org-mode-hook #'org-special-block-extras-mode)
;; ⟨1′⟩ Or use: “M-x org-special-block-extras-mode” to turn it on/off
Or with use-package:
(use-package org-special-block-extras
:ensure t
:hook (org-mode . org-special-block-extras-mode)
:custom
;; The places where I keep my ‘#+documentation’
(org-docs-libraries
'("~/org-special-block-extras/documentation.org"))
;; Details heading “flash pink” whenever the user hovers over them?
(org-html-head-extra (concat org-html-head-extra "<style> summary:hover {background:pink;} </style>"))
;; For the “doc:𝒳” link type
;;;; Nearly instantaneous display of tooltips.
(setq tooltip-delay 0)
;;;;; Give user 30 seconds before tooltip automatically disappears.
(setq tooltip-hide-delay 300)
;; The message prefixing a ‘tweet:url’ badge
(org-link-twitter-excitement
"This looks super neat (•̀ᴗ•́)و:")
:config
;; For use with the “fortune” links, if you want to use them.
(system-packages-ensure "cowsay") ;; ≈ brew install cowsay
(system-packages-ensure "fortune") ;; ≈ brew install fortune
(system-packages-ensure "aha")) ;; ≈ brew install aha
Then, provide support for a new type of special block, say re-using the src
blocks that, say, folds up all such blocks in HTML export, by declaring the
following.
(org-defblock src (lang nil title nil exports nil file nil)
"Fold-away all ‘src’ blocks as ‘<details>’ HTML export.
If a block has a ‘:title’, use that to title the ‘<details>’."
(format "<details> <summary> %s </summary> <pre> %s </pre></details>"
(or title (concat "Details; " lang))
raw-contents))
- https://emacs.stackexchange.com/questions/44958/can-i-insert-a-prefix-to-org-babel-source-code-lines-on-export
- https://stackoverflow.com/questions/38857751/show-tangled-file-name-in-org-mode-code-block-export
- http://kitchingroup.cheme.cmu.edu/blog/2014/09/22/Showing-what-data-went-into-a-code-block-on-export/
- https://lists.gnu.org/archive/html/emacs-orgmode/2016-10/msg00282.html
- https://thibaultmarin.github.io/blog/posts/2016-11-13-Personal_website_in_org.html#org306eaa4
Especially the last link were this seems to have been implemented. However it does not use “hooks” but rather define a new export back-end.
I’ll let you know if I can combine different thing I can find to make something that works.
Cheers
The following example showcases the prominent features of this library.
#+begin_parallel [[color:orange][Are you excited to learn some Lisp?]] [[blue:Yes!]] Pop-quiz: How does doc:apply work? #+end_parallel #+begin_details Answer link-here:solution Syntactically, ~(apply f '(x0 ... xN)) = (f x0 ... xN)~. [[remark:Musa][Ain't that cool?]] #+begin_spoiler aqua That is, [[color:magenta][we can ((apply)) a function to a list of arguments!]] #+end_spoiler #+end_details #+html: <br> #+begin_box octoicon:report Note that kbd:C-x_C-e evaluates a Lisp form! #+end_box /Allah[[margin:][The God of Abraham; known as Elohim in the Bible]] does not burden a soul beyond what it can bear./ --- Quran 2:286 #+LATEX_HEADER: \usepackage{multicol} #+LATEX_HEADER: \usepackage{tcolorbox} #+latex: In the LaTeX output, we have a glossary. show:GLOSSARY badge:Thanks|for_reading tweet:https://github.com/alhassy/org-special-block-extras badge:|buy_me_a coffee|gray|https://www.buymeacoffee.com/alhassy|buy-me-a-coffee
Here is what it looks like as HTML (left) and LaTeX (right):
The above section, ‘practice problems’, presents a few puzzles to get you
comfortable with defblock
;-)
Other cool stuff…
badge:thanks|for_reading tweet:https://github.com/alhassy/org-special-block-extras badge:|buy_me_a coffee|gray|https://www.buymeacoffee.com/alhassy|buy-me-a-coffee
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide 'org-special-block-extras)
;;; org-special-block-extras.el ends here
show:GLOSSARY
[fn:1] See /A tutorial on the universality and expressiveness of fold/ and /Unifying Structured Recursion Schemes/