Powering-up Special Blocks

A modular interface
for special blocks and links



Emacs-Conf-2020


Musa Al-hassy
Flattened View ; Press ? for Help ⟫

MELPA

Overview

With a bit of Lisp —and a lot of time— we obtain

  1. a uniform, and practical, syntax for both special blocks and link types


  2. reusing the Org src interface —including arguments for blocks and global header arguments for links


  3. “write once, generate many”: Write markup in Org and have it exported to other backends!


(•̀ᴗ•́) و
Idea Documentation Link only?
Colours latex-definitions, color  
Parallel parallel  
Editorial Remarks remark  
Folded Details details , box  
Keystrokes C-c C-e kbd
OctoIcons & Link Here octoicon, link-here
Documentation-Glossary documentation doc

Other fun stuff: solution, org-demo, stutter, rename, spoiler (─‿‿─)

Incidentally

😂 The setup joyously works for org-reveal 😹

🥰 🍭 🦄 😆

Motivation

See an aesthetically pleasing style online and seek to reproduce it …


⇄ The author wrote raw HTML

Obscures my source with styling information!

⇄ The author wraps the HTML in an {{{Org-macro}}}

Not useful if I want to export to PDF!

The author doesn't even provide the source!

Time to ‘View Page Source’ and do a lot of reading!

⇉ We want Org users to have numerous styles available and an extensible mechanism to add more! ⇇

Once upon a time

Three friends --- Amin , Sacha , and Corwin — were organising a conference

EmacsConf2020 !


Sacha wrote an Org file and wanted some feedback


Source for this slide!
#+ATTR_REVEAL: :frag (appear)
Three friends ---green:Amin, red:Sacha,
and blue:Corwin--- were organising a conference

#+ATTR_REVEAL: :frag (appear)
... orange:EmacsConf2020!

#+html: <br>
#+ATTR_REVEAL: :frag (appear)
Sacha wrote an Org file and wanted some feedback

What kind of feedback?

  • top-level remarks visible in the export

    … suggest replacement text

    … this is not possible, elegantly , with raw HTML!


  • translate in the export

    … everyone speaks different languages!

    … or suggest a rewrite, without altering the other person's text

    … this is not possible with raw HTML at all !

Example 💓 Text and Feedback

Sacha …

Writes

Let's begin at $\sqrt{3 + \sum_{i = 0}^{12} i}$ in the *morning*.\newline

Sees

Let's begin at \(\sqrt{3 + \sum_{i = 0}^{12} i}\) in the morning.

She gets feedback …

[Amin:

How about

(sqrt (apply '+ 3 (number-sequence 0 12))) ;-)

]


[Corwin:

C'mon guys, let's just say 9 am!

]

Amin ❤️ LaTeX

Amin likes to export to PDF, so he wrote top-level remarks using LaTeX

#+latex: {\color{green} \fbox{[Amin:}}
  Please change …
#+latex:  \fbox{]}

[Amin:

Please change …

]

Sacha 💔 PDF

But Sacha likes to look at the resulting HTML ! … not PDFs!

So, she may not see his top-level feedback and she may forgot to look at the Org source

Happily, she thinks things are all good …!

Amin 💢 HTML

Sacha may write top-level feedback …

#+html: <strong> [Sacha Speculates: </strong>

I think that maybe we could try …

#+html: <strong> End of speculations] </strong>

[Sacha Speculates:

I think that maybe we could try …

End of speculations ]

Now Amin exports to PDF; take a quick glance and not notice anything standing out; thinks it's all OK

💥 😧 💭 📖

Corwin actually reads an exported result, and is worried at what he sees.


Amin & Sacha agree to read up and make a uniform Org interface that exports to both HTML & PDF


They use Org “special blocks”!

How to set up special blocks?

They agree to figure out the necessary Lisp ,

hooks , advice , and macros needed to form a

special custom block that outputs both HTML and PDF,
but uses Org as interface.

So much work, but it's worth it!

…!?

Corwin 🥶 🤔 🥊 Terse!

Corwin likes to provide terse , right to the point, feedback and thinks blocks are overkill.

The team decides to incorporate an Org-link type

and —to avoid duplication of code!--- they have the link type reuse the core code of the block type.

The friends learn a lot!

  • defun, for making functions to format their blocks!
  • advice-add, for advising Emacs utilities to handle their new special blocks
  • -let, pattern matching / “destructuring lets”
  • extract-arguments, an ad-hoc mechanism to simulate arguments with special blocks
  • org-link-set-parameters, to make new link types

Of course to actually write the formatting function they need loop, s-replace, mapcar, or, s-match, and much more!

Such a pain!

⇒ It's probably not worth it!
“Just do enough to make it work!”
“We're in a rush!”

Goals

“Squad goals”

A modular and unified interface for producing new special blocks and link types, simultaneously , with roughly the same interface as a defun!


defblock

Solving the friend's trilemma

(defblock feedback (who) (color "red")
  "Top level (HTML & LaTeX) constructive feedback."
  (format (if (equal backend 'html)
            "<strong style=\"color: %s;\">⟦%s: %s⟧</strong>"
            "{\\color{%s}\\bfseries %s: %s}")
          color who contents))

Huh?

There are 3 main parts …

Line 1: Declare a block

1: (defblock feedback (who) (color "red")
2:   "Top level (HTML & LaTeX) constructive feedback."
3:   (format (if (equal backend 'html)
4:             "<strong style=\"color: %s;\">⟦%s: %s⟧</strong>"
5:             "{\\color{%s}\\bfseries %s: %s}")
6:           color who contents))

Line 1: def -ine a new block named feedback whose main argument is who wrote the feedback, and optionally a color —which is red by default.

Line 2: Document the block

1: (defblock feedback (who) (color "red")
2:   "Top level (HTML & LaTeX) constructive feedback."
3:   (format (if (equal backend 'html)
4:             "<strong style=\"color: %s;\">⟦%s: %s⟧</strong>"
5:             "{\\color{%s}\\bfseries %s: %s}")
6:           color who contents))

Line 2: Just as when you write a function, you write what it does.

Moreover, this documentation is used as a tooltip for the Org link form of feedback —for Corwin within Emacs!

Lines 3-6: Do the thing!

1: (defblock feedback (who) (color "red")
2:   "Top level (HTML & LaTeX) constructive feedback."
3:   (format (if (equal backend 'html)
4:             "<strong style=\"color: %s;\">⟦%s: %s⟧</strong>"
5:             "{\\color{%s}\\bfseries %s: %s}")
6:           color who contents))

Line 3: Depending on whether we're exporting to HTML —for Sacha — or to PDF —for Amin — we use HTML divs or LaTeX macros.

Anaphoric?

1: (defblock feedback (who) (color "red")
2:   "Top level (HTML & LaTeX) constructive feedback."
3:   (format (if (equal backend 'html)
4:             "<strong style=\"color: %s;\">⟦%s: %s⟧</strong>"
5:             "{\\color{%s}\\bfseries %s: %s}")
6:           color who contents))

Lines 3 and 6 let the user refer to the current export backend and to the contents of the special block / link.

How do the feedback?

Sacha 😍 Org/HTML

#+begin_feedback Sacha Speculates
I think we should do …
#+end_feedback

[Sacha Speculates:

I think we should do …

]

Amin 😻 Org/PDF

#+begin_feedback Amin :color green
I think we should do …
#+end_feedback

[Amin:

I think we should do …

]

Corwin 💌 Org/Terse

[[feedback:Corwin][Guys, let's wrap up already!]]


[Corwin: Guys, let's wrap up already! ]

More Blocks!

Using a few lines of Lisp …

  • write text in parallel columns

    … to save on vertical whitespace

  • hide away technical details for the interested reader only
  • enclose text in a pretty box
  • Educational material blocks: spolier, solution, and org-demo

Finally, blocks compose: They're building blocks for new and better ideas!

More details and examples at

https://alhassy.github.io/org-special-block-extras

Bye!

Thanks for listening in!