Projects About AlBasmala
build status

org-special-block-extras: The block and link types

Article image
  

Ξ  

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

1. Boxed Text —Calling out super duper info

﴾What You Write﴿
It can be useful to draw attention to some important text by
enclosing it in a [[doc:org-block/box][box]].

#+begin_box Uses of callout boxes
Such boxes often callout tips, warnings, cautionary info or
emphasises core information.
#+end_box
﴾What You Get﴿

It can be useful to draw attention to some important text by enclosing it in a box.

Uses of callout boxes

Such boxes often callout tips, warnings, cautionary info or emphasises core information.


﴾How It’s Implemented﴿
(org-defblock box (&optional (title "") &key background-color shadow frame-color title-background-color
                  &allow-other-keys :latex-head ("xcolor" "tcolorbox") :manual "#Boxed-Text"
                  &context backend raw-contents contents)
              "Enclose text in a box, possibly with a TITLE.

By default, the box's BACKGROUND-COLOR is green for HTML and red for LaTeX;
for LaTeX, there are also FRAME-COLOR and TITLE-BACKGROUND-COLOR.

SHADOW is an alternate style of boxing: It shows the contents in a centred
box with a shadow colour being the given non-nil value of SHADOW.
If SHADOW is a hexadecimal colour, it should be a string enclosed in double quotes.
More accurately, the following are all valid uses:

    #+begin_box title :shadow t
    #+begin_box title :shadow inset

    #+begin_box title :shadow \"pink\"
    #+begin_box title :shadow pink

    #+begin_box title :shadow (cyan pink orange yellow)
    #+begin_box title :shadow (cyan \"inset pink\" orange)
    #+begin_box title :shadow (:left cyan :right pink :deep-right orange :deep-left yellow)

Notice that prefixing colours with ‘inset’ causes the colour to be within the box,
rather than spread, with blur, around the box. The use of ‘inset’ swaps left and right.

The HTML export uses a padded div, whereas the LaTeX export
requires the tcolorbox package; Markdown, sans colours, gets a quote opening with TITLE in bold."
              (pcase (if (org-export-markdown-p) 'md backend)
                ('md (org-parse (format "#+begin_quote\n%s%s\n#+end_quote"
                                        (if (org-string-nw-p (format "%s" title)) (format "*%s*\n\n" title) "")
                                        raw-contents)))
                ;; Colours are named first, since tcolorbox options cannot take hex codes such as #CCFFCC.
                ('latex
                 (concat (org--latex-define-color "osbe-box-back" (or background-color "red!5!white"))
                         (org--latex-define-color "osbe-box-frame" (or frame-color "red!75!black"))
                         (org--latex-define-color "osbe-box-title" (or title-background-color "yellow!50!red"))
                         (format (concat "\\begin{tcolorbox}[title={%s},colback=osbe-box-back,colframe=osbe-box-frame,"
                                         "colbacktitle=osbe-box-title,coltitle=red!25!black, fonttitle=\\bfseries,"
                                         "subtitle style={boxrule=0.4pt, colback=yellow!50!red!25!white}]"
                                         "%s\\end{tcolorbox}")
                                 title contents)))
                (_ (format "<div style=\"%s\"> <h3>%s</h3> %s </div>"
                           (s-join ";" (list "padding: 1em"
                                             (format "background-color: %s" (org-subtle-colors (format "%s" (or background-color "green"))))
                                             "border-radius: 15px"
                                             "font-size: 0.9em"
                                             (org--box-shadow shadow)))
                           title contents))))

2. Folded Details —Let the user see stuff only if they're interested

﴾What You Write﴿
Sometimes there is a remark or a code snippet that is useful to
have, but not relevant to the discussion at hand and so we want to
/fold away such [[doc:org-block/details][details]]/.

#+begin_details Example use cases
+ ‘Conversation-style’ articles, where the author asks the reader questions
  whose answers are “folded away” so the reader can think about the exercise
  before seeing the answer.

+ Hiding boring but important code snippets, such as a list of import
  declarations or a tedious implementation.
#+end_details

Full syntax ~#+begin_details "title" :background-color "cyan" :title-color "green"~.
﴾What You Get﴿

Sometimes there is a remark or a code snippet that is useful to have, but not relevant to the discussion at hand and so we want to fold away such details.

Example use cases
  • ‘Conversation-style’ articles, where the author asks the reader questions whose answers are “folded away” so the reader can think about the exercise before seeing the answer.
  • Hiding boring but important code snippets, such as a list of import declarations or a tedious implementation.

Full syntax #+begin_details "title" :background-color "cyan" :title-color "green".


﴾How It’s Implemented﴿
(org-defblock details (&optional (title "Details") &key (background-color "#e5f5e5") (title-color "green")
                      &allow-other-keys :latex-head ("xcolor" "tcolorbox") :manual "#Folded-Details"
                      &context backend contents)
              "Enclose contents in a folded up box, for HTML.

For LaTeX, this is just a boring, but centered, box.

By default, the TITLE of such blocks is “Details”,
its TITLE-COLOR is green, and BACKGROUND-COLOR is “#e5f5e5”.

In HTML, we show folded, details, regions with a nice greenish colour."
              (pcase backend
                ('latex (concat (org--latex-define-color "osbe-bg" background-color)
                                (org--latex-define-color "osbe-fg" title-color)
                                (format (concat "\\begin{quote}\n"
                                                "\\begin{tcolorbox}[colback=osbe-bg,colframe=osbe-fg,title={%s},sharp corners,boxrule=0.4pt]\n"
                                                "%s\n"
                                                "\\end{tcolorbox}\n"
                                                "\\end{quote}")
                                        title contents)))
                (_ (format (concat "<details class=\"code-details\" style=\"padding: 1em; background-color: %s; "
                                   "border-radius: 15px; color: hsl(157 75%% 20%%); font-size: 0.9em; "
                                   "box-shadow: 0.05em 0.1em 5px 0.01em #00000057;\">\n"
                                   "<summary><strong><font face=\"Courier\" size=\"3\" color=\"%s\">%s</font></strong></summary>\n"
                                   "%s\n"
                                   "</details>")
                           background-color title-color title contents))))

Src blocks fold too: the header argument :folded t exports a src block, exactly as Org otherwise would, inside a details block titled by its language; :folded "TITLE" picks the title.

#+begin_src emacs-lisp :folded "How is it done?"
(org-defblock details …)
#+end_src

A page with many folded blocks may offer a button to unfold them all at once: [[toggle-details:][Show me everything]] is that button; pressed again, it folds them all. Without a description, it reads “Unfold all details”.

3. Nice Keystroke Renditions: C-h t

Anyone who writes about Emacs will likely want to mention keystrokes in an aesthetically pleasing way, such as C-u 80 - to insert 80 dashes, or C-c C-e h o to export an Org-mode file to HTML, or the useful M-s h ..

  • kbd:𝒳 will show a tooltip defining 𝒳, as an Emacs Lisp function, if possible. For example, kbd:C-h_t is C-h t; and likewise <kbd:M-s h .> is M-s h. (we need to use <...> since punctuation is not picked up as part of link labels). In contrast, kbd:nope renders as nope without a tooltip (nor a red border).

    You can also supply explicit tooltip description: [[kbd:key sequence][description]] will show as key sequence; i.e., the key sequence in nice key font along with a tooltip explaining it.

  • In Emacs itself, each of these displays as 〔C-x C-s〕: the kbd: markup becomes the brackets and each _ a space. Only the markup is displayed differently, so the keys stay editable as ever. Moreover, clicking one runs its keys —after asking, as elisp: links do— so readers may try them on the spot.

kbd.png

4. Remark —Inline footnotes, viz HTML tooltips and LaTeX notes in the margin

Sometimes you want to remark on details without drawing too much attention, and so a tooltip via remark suffices.

﴾What You Write﴿
It can be annoying to make readers jump to the bottom of the page to
read a footnote.  Instead, I prefer to write an /inline [[doc:org-block/tooltip][remark]]/
containing, say, references or additional explanation.

   /[[tooltip:Allah][The God of Abraham; known as Elohim in the Bible]] does not burden a
       soul beyond what it can bear./ --- Quran 2:286

Or, without specifying an explicit label:

   /Allah[[tooltip:][The God of Abraham; known as Elohim in the Bible]] does not
       burden a soul beyond what it can bear./ --- Quran 2:286
﴾What You Get﴿

It can be annoying to make readers jump to the bottom of the page to read a footnote. Instead, I prefer to write an inline remark containing, say, references or additional explanation.

Allah  does not burden a soul beyond what it can bear. — Quran 2:286

Or, without specifying an explicit label:

Allah°  does not burden a soul beyond what it can bear. — Quran 2:286

A tooltip opens when its word is hovered with a mouse, or tapped on a phone; it closes when we leave both, tap elsewhere, or press Escape. Its text is Org, exported as Org, so it may hold links —clickable, since moving into the tooltip keeps it open— and any other markup; an Elisp docstring is shown just as it is written. The machinery is tooltips.js, about eighty lines with no dependencies, in the look of tooltips.css; both are inlined into each exported page, which so fetches nothing for them.

Org's own footnotes are such remarks too: in HTML, each footnote's number is a tooltip of its definition, the footnotes section staying below, for print; in LaTeX, each is a margin note, as the margin block's are, numbered as footnotes are. All three of Org's spellings serve: an anonymous [fn::…], a named [fn:NAME] defined elsewhere, and a named inline [fn:NAME: …], which later [fn:NAME] references share.

﴾What You Write﴿
The Quran was revealed over 23 years[fn::From 610 to 632 CE, in Mecca then Medina.], and the
Torah[fn:-0-torah] and the Gospel[fn:-0-injil: /Injil/, given to Jesus.] are honoured in it as earlier
scriptures; the Gospel[fn:-0-injil] is named in it a dozen times.

[fn:-0-torah] /Tawrat/, given to Moses; see [[https://en.wikipedia.org/wiki/Tawrat][Tawrat]].
﴾What You Get﴿

The Quran was revealed over 23 years1, and the Torah2 and the Gospel3 are honoured in it as earlier scriptures; the Gospel3 is named in it a dozen times.

Footnotes:

1

From 610 to 632 CE, in Mecca then Medina.

2

Tawrat, given to Moses; see Tawrat.

3

Injil, given to Jesus.

5. Glossaries —Define a term once, cite it with doc:𝒳

A doc:𝒳 link shows the documentation of 𝒳 as a tooltip in HTML, and as a glossary reference in LaTeX. Here 𝒳 is an Emacs Lisp function or variable, a word in the English dictionary —via WordNet's wn, should we have it— or, best of all, a term of our own.

﴾What You Write﴿
The ~doc~ link type can be used to show tooltips for Emacs Lisp commands such as

                         doc:thread-last
                         
However, it can also be used for your own definitions/glossary.
First define a term as follows, which does not render anything in the resulting HTML.

                 #+begin_documentation Category Theory :label cat
                 A theory of typed composition; e.g., typed monoids.
                 #+end_documentation

Then you can refer to it using the given :label, if any:

                             doc:cat
  
Or else refer to it with underscores in lieu of spaces:

                       doc:Category_Theory

Either approach renders the name of the term, not the way its referenced.
If you want to change what's rendered, provide a description:

                  [[doc:cat][abstract nonsense]]

Finally, if ~doc~ gets a label that is not an Emacs Lisp command, variable, nor a user-defined
definition via #+begin_documentation, then we try to look up its definition via the dictionary:

                          doc:happiness
﴾What You Get﴿

The doc link type can be used to show tooltips for Emacs Lisp commands such as

thread-last

However, it can also be used for your own definitions/glossary. First define a term as follows, which does not render anything in the resulting HTML.

Then you can refer to it using the given :label, if any:

Category Theory

Or else refer to it with underscores in lieu of spaces:

Category Theory

Either approach renders the name of the term, not the way its referenced. If you want to change what's rendered, provide a description:

abstract nonsense

Finally, if doc gets a label that is not an Emacs Lisp command, variable, nor a user-defined definition via #+begindocumentation, then we try to look up its definition via the dictionary:

happiness


﴾How It’s Implemented﴿
(org-deflink doc (label &optional description backend)
  "Export LABEL as itself, or as the provided DESCRIPTION,
 along with a tooltip that shows the user's
 documentation-glossary for LABEL and using that entry's name
 when no DESCRIPTION is provided."
  :let (entry (org-docs-get label)
        name (cl-first entry)
        docs (cl-second entry)
        display-name (or description name))
  :help-echo (format "[%s] %s :: %s" label name docs)
  :face '(custom-button)
  :manual "#Glossaries"
  :export (progn
            (add-to-list 'org--docs-actually-used (list label name docs))
            (pcase backend
              ('html (org--html-tooltip docs display-name (org--docs-plain-p label)))
              ;; Make the current word refer to its glossary entry, and declare the location
              ;; that the glossary should refer back to; see `org--docs-glossary'.
              ('latex (format "\\hyperref[o-glossary-%s]{%s}\\label{o-glossary-declaration-site-%s}"
                              label display-name label))
              (_ display-name))))

Our own terms are data in an Org file: an entry is either a documentation block, which exports nothing, or a heading tagged :documentation:, which exports as an ordinary section. The heading's title is the term's name, its :DOC_KEYS: property lists the labels by which we cite it, and its own text is the definition. Either way, the name with underscores in lieu of spaces is a label too; e.g., doc:Category_Theory. Moreover, as #+print_bibliography: lists the works a page cites, #+print_glossary: lists every term the page cites, wherever it sits.

Org's own radio targets are entries too, with no markup of ours at all: in “A <<<monoid>>> is a unital semigroup”, Org already links each later “monoid” to its definition; in HTML, each such mention is also a tooltip of the defining paragraph.

﴾What You Write﴿
Our glossary, listing every term this page cites ---even those cited further below:

#+print_glossary:

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

* Using our terms

A glossary entry may instead be a block, which exports nothing:

#+begin_documentation Monoid :label mon
A set with an associative binary operation that has a unit.
#+end_documentation

Then, doc:cat studies [[doc:mon][monoids]] and their kin.
﴾What You Get﴿

Our glossary, listing every term this page cites —even those cited further below:

Monoid Category Theory

Category Theory   documentation

A theory of typed composition; e.g., typed monoids.

Using our terms

A glossary entry may instead be a block, which exports nothing:

Then, Category Theory studies monoids and their kin.


﴾How It’s Implemented﴿
(org-defblock documentation
              (&optional (name (error "Documentation block: Name must be provided")) &key label show (color "green")
               &allow-other-keys
               ;; A heading tagged :documentation: is an entry in its own right; see `org--docs-read-buffer'.
               :tag nil :manual "#Glossaries" &context raw-contents)
              "A glossary entry: CONTENTS defines NAME, cited as doc:LABEL; a heading tagged :documentation: is one too.

The entries live in ‘org--docs’.

A documentation entry may have its LABEL, its primary identifier,
be:
1. Omitted
2. Given as a single symbol
3. Given as a many aliases '(lbl₀ lbl₁ … lblₙ)

The third case is for when there is no canonical label to refer to
an entry, or it is convenient to use multiple labels for the same
entry.

In all of the above cases, two additional labels are included:
The entry name with spaces replaced by underscores, and again but
all lower case.

Documentation blocks are not shown upon export;
unless SHOW is non-nil, in which case they are shown
using the ‘box’ block, with the provided COLOR passed to it.

Alternatively, a heading tagged :documentation: is an entry, which
exports as an ordinary section: its title is the NAME, its :DOC_KEYS:
property holds the labels, and its own text is the entry.

  * 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 they may be cited before
they are defined; see `org--docs-prepare'."
              (dolist (entry (org--docs-entries name label (substring-no-properties raw-contents)))
                (add-to-list 'org--docs entry))
              ;; Should the special block show something upon export?
              (if show (org--blockcall box name :background-color color raw-contents) ""))

Terms we cite across many files go in a library: a list of Org files in org-docs-libraries, whose entries —blocks and headings alike— every doc:𝒳 link may cite. The files are read, not exported, so loading them is quick; M-x org-docs-load-libraries reloads them after an edit, and M-x org-docs-insert inserts a doc:𝒳 link by searching all the terms we have.

A radio target is a term too: in A <<<monoid>>> is a set with an associative operation and a unit., the target names the term and its paragraph defines it; so doc:monoid cites it, in the same file or, from a library, in any other.

6. Parallel ---Place ideas side-by-side, possibly with a separator

﴾What You Write﴿
Reduce the amount of whitespace noise in your articles by using the
[[doc:org-block/parallel][parallel]] block to place ideas
side-by-side ---with up to 𝓃-many columns.

----------------------------------------------------------------------

#+begin_parallel 2
*“Soft Columns”:* Writing ~#+begin_parallel 𝓃 :bar BAR~ will produce
𝒏-many parallel columns, possibly separated by solid rules, or a
“bar”. /This style allows text to freely move between columns,
depending on the size of the browser, which may dynamically shrink
and grow./ The value ~BAR~ can either be ~t~, ~nil~, or any
(backend)-valid colour specification; such as ~red~ or ~green~.
#+end_parallel

----------------------------------------------------------------------

#+begin_parallel 25% 50% 25% :bar green

*“Hard Columns”:* Alternatively, /for non-uniform column widths, 𝓃 may
instead be a specification of the widths of the columns./

#+columnbreak:  
However, this extra flexibility comes at an additional cost: The
contents of the block must now contain /𝓃-1/ lines consisting of
~#+columnbreak:~, when the specification determines 𝓃-many columns.

#+columnbreak:
Goodbye (“God-be-with-ye”) to the right!

#+end_parallel

# In the Soft Columns style above, any ‘#+columnbreak:’ are merely ignored.

In summary, articles can get lengthy when vertical whitespace is
wasted on thin lines; instead, one could save space by using
/[[doc:org-block/parallel][parallel]] columns of text/.
﴾What You Get﴿

Reduce the amount of whitespace noise in your articles by using the parallel block to place ideas side-by-side —with up to 𝓃-many columns.


“Soft Columns”: Writing #+begin_parallel 𝓃 :bar BAR will produce 𝒏-many parallel columns, possibly separated by solid rules, or a “bar”. This style allows text to freely move between columns, depending on the size of the browser, which may dynamically shrink and grow. The value BAR can either be t, nil, or any (backend)-valid colour specification; such as red or green.


“Hard Columns”: Alternatively, for non-uniform column widths, 𝓃 may instead be a specification of the widths of the columns.

However, this extra flexibility comes at an additional cost: The contents of the block must now contain 𝓃-1 lines consisting of #+columnbreak:, when the specification determines 𝓃-many columns.

Goodbye (“God-be-with-ye”) to the right!

In summary, articles can get lengthy when vertical whitespace is wasted on thin lines; instead, one could save space by using parallel columns of text.


﴾How It’s Implemented﴿
(org-defblock parallel (&optional (cols "2") &key bar &allow-other-keys :latex-head ("multicol") :manual "#Parallel"
                       &context backend contents)
              "Place ideas side-by-side, possibly with a separator.

There are COLS many columns, and they may be separated by solid
vertical rules if BAR is a non-nil (colour) value.

+ COLS is either a number or a sequence of the shape: 10% 20% 30%.
+ BAR is either `t', `nil', or a colour such as `red' or `blue'.

----------------------------------------------------------------------

“Soft Columns”: Writing “#+begin_parallel 𝓃 :bar t” will produce
𝒏-many parallel columns, possibly separated by solid rules, or a
“bar”. This style allows text to freely move between columns,
depending on the size of the browser, which may dynamically
shrink and grow.  BAR can either be `t', `nil', or
any (backend)-valid colour specification; such as `red' or
`green'.

“Hard Columns”: Alternatively, for non-uniform column widths,
COLS may instead be a specification of the widths of the
columns. However, this extra flexibility comes at an additional
cost: The contents of the block must now contain 𝒏-1 lines
consisting of ‘#+columnbreak:’, when the specification determines
𝒏 columns, as shown in the following example.

   #+begin_parallel 20% 60% 20% :bar green
   Hello, to the left!

   #+columnbreak:
   A super duper wide middle margin!

   #+columnbreak:
   Goodbye (“God-be-with-ye”) to the right!
   #+end_parallel

The specification is 𝒏 measurements denoting widths; which may be
in any HTML recognisable units; e.g., “5em 20px 30%” is valid.
I personally advise only the use of percentage measurements.

In the Soft Columns style above, any ‘#+columnbreak:’ are merely ignored.
With LaTeX export, the use of ‘#+columnbreak:’ is used to request a column break."
              (let* ((widths (split-string cols))
                     ;; Hard columns have their widths given; e.g., 20% 60% 20%, or 5em 20px.
                     (hard? (--any? (not (string-match-p "\\`[0-9]+\\'" it)) widths))
                     (colour (if (equal (format "%s" bar) "t") "black" bar))
                     ;; A line of its own, so that mentions such as ~#+columnbreak:~ are left alone.
                     (column-break "^[ \t]*#\\+columnbreak:[ \t]*$"))
                (pcase backend
                  ('latex (format (concat "\\par \\setlength{\\columnseprule}{%s pt}\n"
                                          "\\begin{minipage}[t]{\\linewidth}\n"
                                          "\\begin{multicols}{%s}\n%s\n"
                                          "\\end{multicols}\\end{minipage}")
                                  (if bar 2 0)
                                  (if hard? (length widths) cols)
                                  (replace-regexp-in-string column-break "\\\\columnbreak" contents)))
                  ((guard (not hard?))
                   (format "<div style=\"column-count: %s;%s\">%s</div>"
                           cols (if bar (format " column-rule: 1px solid %s;" colour) "") contents))
                  ;; Each width begins a column, separated by a bar unless it is the last; CONTENTS is Org
                  ;; between export fences, so the columns after the first begin within @@html:…@@.
                  (_ (let ((columns (cl-loop for (width . more) on widths
                                             collect (format "<div style=\"width: %s; margin: 10px; border-right: %s;\">"
                                                             width (if (and bar more) (format "4px solid %s" colour) "none"))))
                           (chunks (split-string contents column-break)))
                       (format "<div style=\"display: flex; justify-content: space-between; align-items: flex-start;\">%s</div>"
                               (concat (car columns)
                                       (car chunks)
                                       (cl-loop for column in (cdr columns)
                                                for chunk in (cdr chunks)
                                                concat (format "@@html:</div>%s@@%s" column chunk))
                                       "</div>")))))))

7. Display maths ---#+begin_math, wherein red:𝒳 colours a symbol

To colour a formula, LaTeX —and MathJax, which typesets it in HTML— would have us write {\color{red} x}; yet our prose colours by red:x. A math block is display maths wherein our links are LaTeX's: red:ATOM colours a {group}, \left(…\right), a \command{with}{arguments}, a word, else one character; [[red:][a + b]] colours a + b. So too for color:#ff0066, highlight:, web links, and tooltip: and doc:, which hover in HTML; as does a footnote, x[fn::the current element], or x[fn:elt], whose [fn:elt] … definition sits elsewhere, as in prose —so one long tip serves many atoms. A tooltip in maths is as one in prose: the same box in HTML, and in LaTeX, a margin note, its number on x. Org's emphasis is read when its markers hug their text, as in prose: *f(a)* is bold, whereas a*b*c and a = b are left be.

A line that begins \def, \newcommand, …, begins a definition, through the line that closes its braces: declared, but not shown —in LaTeX, in the preamble; in HTML, hidden, whence MathJax knows it page-wide. A line # … is a comment. Below, the first block is only definitions, and so shows nothing.

﴾What You Write﴿
Hello, in this blog post I'd like to talk about quantifiers.

# First, I'll define some helpers that I use multiple times; they are declared, not shown.
#+begin_math
\def\Plus{teal:\bigoplus}
\def\plus{\;teal:\oplus\;}
\def\f#1{brown:f violet:{(#1)}}
\def\xstart{red:a}
\def\xend{cyan:b}
#+end_math

Anyhow, let's talk about quantifiers...
#+begin_math
\Plus_{violet:x = \xstart}^{\xend} \f{x} \; = \; \f{\xstart} \plus \f{a+1} \plus \f{a+2} \plus \cdots \plus \f{\xend}
#+end_math

The above “quantification” means [[teal:Loop sequentially with]]
[[brown:loop-bodies f(x)]] [[teal:fused using ⊕]], using [[violet:x as the
name of the current element]], [[red:starting at a]] and [[cyan:ending at b]].
﴾What You Get﴿

Hello, in this blog post I'd like to talk about quantifiers.

\[\def\Plus{{\color{teal}\bigoplus}} \def\plus{\;{\color{teal}\oplus}\;} \def\f#1{{\color{brown}f} {\color{violet}{(#1)}}} \def\xstart{{\color{red}a}} \def\xend{{\color{cyan}b}}\]

Anyhow, let's talk about quantifiers…

\[ \Plus_{{\color{violet}x} = \xstart}^{\xend} \f{x} \; = \; \f{\xstart} \plus \f{a+1} \plus \f{a+2} \plus \cdots \plus \f{\xend} \]

The above “quantification” means Loop sequentially with loop-bodies f(x) fused using ⊕, using x as the name of the current element, starting at a and ending at b.


﴾How It’s Implemented﴿
(org-defblock math (&key numbered (matrix "pmatrix") (hints 'between) environment
                         :link nil :latex-head ("amsmath" "xcolor" "cancel") :html-head (mathjax)
                         :edit-indirect-mode latex-mode :manual "#math"
                         :fontify [:language "latex" :keywords org--math-fontify-keywords]
                         &context backend raw-contents anchor)
  "Display maths, wherein our links ---e.g., red:x, [[doc:fold][f]]--- and Org's *markup* are LaTeX's.

  #+begin_math
  # The bounds, declared once; this line is a comment.
  \\def\\xstart{red:a}
  teal:\\bigoplus_{violet:x[fn::the current element] = \\xstart}^{cyan:b} brown:f(violet:x)   teal:<<Fold>>
  #+end_math

Then [[Fold]] cites the equation, as (Fold) in teal; [[Fold][these words]] link to it.

+ red:ATOM colours an ATOM: a {group}; \\left(…\\right); a \\command{with}{arguments}, or a sizer with its
  delimiter, \\big(; a word; else one character.  [[red:][a + b]] colours a + b.  So too for any colour,
  [[color:#ff0066][…]], highlight:, web links, and tooltip: and doc:, which hover in HTML; see `org-math-links'.
+ ATOM[fn::TIP], or ATOM[[tooltip:TIP]], is a tooltip, as [[tooltip:ATOM][TIP]] is, and as in prose: in HTML, TIP hovers over ATOM, by
  tooltips.js; in LaTeX, TIP is a margin note, its number on ATOM.  ATOM[fn:NAME]'s TIP is its “[fn:NAME] TIP”
  definition, elsewhere in the buffer; so one long tip may serve many atoms.
+ A section link, [[*Heading][f]], [[#custom-id][f]], or [[id:ID][f]], links f to that section, as a graph's node does.
+ *bold* /italic/ _underline_ +cancel+ =texttt= ~mathtt~, when the markers hug their text, as in Org's prose.
+ An Org table is a MATRIX, pmatrix by default; as in Org, a line that begins | is a table, so write \\lvert x \\rvert.
+ A description list, “- VALUE :: CONDITION” lines, is a cases environment; a CONDITION of mere words, such as
  otherwise, is prose.
+ A line ending “COLOUR:<<NAME>>”, Org's own target, is tagged NAME, in COLOUR, which [[NAME]] cites, as Org cites
  a target, and C-c C-o on it visits; sans COLOUR, “<<NAME>>” is plain.  NAME may hold maths, as \\meet, ⊑, or a
  subscript, as <<Base Case_1>>.  A hint's \\[ … \\] may be tagged too: “\\[ 0 + n = n teal:<<Base Case>> \\]”.
  NUMBERED numbers the rest.  A block's “#+name: NAME” labels its last line, so [[NAME]] cites it too; it is
  tagged NAME when unnumbered.
+ Lines with an & are aligned at it, as in LaTeX's align; else, lines that end in \\\\ are gathered, each centred on
  a line of its own.  Only the block's own & and \\\\ count, not those in a {group} or a \\begin{cases}…\\end{cases}.
+ “X ={ HINT } Y” states why the step holds, as in a calculational proof; so too for any relation, ≤{ … }, \\equiv{ … },
  … The { hugs the relation, and a space or newline follows it, so x ={a} is no hint; in Emacs, a hint shows as a
  comment does, so we see which {…} is one.  A step runs from its hint to the next, wherever the newlines fall, sans
  our writing \\\\.  A hint may span lines, and shows on those lines, a blank one a gap; within it, \\[ … \\] is a nested
  calculation.  TAB on a hint folds it, as a click does in HTML; M-q within it fills it alone, as prose, whereas M-q
  elsewhere in the block leaves the maths be.
+ HINTS sets each hint between the expressions it relates, maroon, after a bracket that opens it, lest it be mistaken
  for maths; beside, at its step's end, plain, as its column sets it apart; none, hidden from the export; or as a list,
  LAYOUT then FORMAT, LaTeX whose %s is the hint, or folded, or both ---e.g., (beside \"{\\color{teal} %s}\" folded).
  Folded hints start as [⋯] in HTML, so a reader clicks to see each, as a puzzle; LaTeX, sans clicks, shows them.
  To set hints beside throughout a file: #+property: header-args:math :hints beside.
+ ENVIRONMENT overrules the environment the lines imply, for a layout we infer not: e.g., multline* for one long
  equation, or alignat*{2} for columns of a set width.  Sans star, it is numbered; its #+name: labels it.
+ NUMBERED is t, to number each line; or once, to number the lines as one equation, split at their &s; its one tag,
  else its #+name:, labels it.
+ Inline maths, $red:x$ or \\(red:x\\), reads our links and Org's markup too.
+ Unicode, such as ∀ x ∈ ℕ, typesets in HTML, but in LaTeX only with #+latex_compiler: lualatex and
  #+latex_header: \\usepackage{unicode-math}; else, its symbols are dropped, silently.
+ A line “# …” is a comment.  A line that begins \\def, \\let, \\newcommand, \\renewcommand, or \\DeclareMathOperator
  begins a definition, through the line that closes its braces: declared, but not shown.  In LaTeX, it goes to the
  preamble; in HTML, MathJax reads it hidden, and then knows it page-wide.
+ In Markdown, the block is a fenced math block, its definitions within, since GitHub forgets them between blocks.
+ In Emacs, C-c C-c shows the maths as an image atop the block, until C-c C-c again, or an edit; C-c ' edits the
  block in `latex-mode', its hints, tags, and colours shown as in the Org buffer.  C-c C-x C-l, which shows Org's own maths as images, shows math blocks too."
  (pcase-let ((`(,layout ,format ,folded) (org--math-hints-switch hints)))
    (let ((org--math-tips nil) (org--math-hint-format format) (org--math-hint-folded folded))
      (pcase-let ((`(,definitions . ,shown)
                   (org--math-render raw-contents backend numbered matrix anchor layout environment)))
        (cond ((org-export-markdown-p)
               ;; A fenced math block is displayed already, so \[…\] would be one display too many.
               (let ((shown (and shown (string-remove-suffix "\n\\]" (string-remove-prefix "\\[\n" shown)))))
                 (format "```math\n%s\n```" (string-join (append definitions (and shown (list shown))) "\n"))))
              ((equal backend 'latex)
               (concat (when definitions
                         (org-parse (mapconcat (lambda (d) (replace-regexp-in-string "^" "#+latex_header: " d))
                                               definitions "\n")))
                       shown
                       ;; The margin notes of the maths' tooltips, after it, as maths holds no \marginpar.
                       (string-join (reverse org--math-tips))))
              ;; MathJax reads the page's text, wherein a < would begin an HTML tag.
              (t (when org--math-tips (org-html-head-require 'org--tooltip-html-head))
                 ;; Hints fold on a click, by their tip and script; see `org--math-hint-styled'.
                 (when (and shown (string-match-p "osbe-hint" shown))
                   (org-html-head-require 'org--tooltip-html-head)
                   (org-html-head-require 'org--math-hint-html-head))
                 (concat (when definitions
                           (format "<p style=\"display:none\">\\[%s\\]</p>\n"
                                   (org-html-encode-plain-text (string-join definitions "\n"))))
                         (and shown (org-html-encode-plain-text shown))
                         ;; The tips of the maths' tooltips, beside it, since MathJax keeps no <template>.
                         (mapconcat (lambda (tip) (concat "\n" tip)) (reverse org--math-tips) ""))))))))

The rest of Org's markup is read as one would hope:

  • An Org table is a matrix —a pmatrix, or whichever environment :matrix names— whose columns TAB aligns for us. As in Org, a line that begins | is a table; so we write \lvert x \rvert for an absolute value.
  • A line ending COLOUR:<<NAME>>, Org's own target, is tagged —see aligned equations— and [[NAME]] cites it; :numbered t numbers the rest. Org's own #+name: NAME labels the block's last line, so [[NAME]] cites a single equation sans a tag; unnumbered, it is tagged NAME.
  • A description list is a cases environment, each term a value and each description its condition —one of mere words, such as otherwise, is prose:

    #+begin_math
    n! =
    - 1 :: n = 0
    - n · (n-1)! :: otherwise
    #+end_math
    

    A line that begins - x, sans a ::, stays maths.

  • A section link ---[[*Heading][f]], [[#custom-id][f]], or [[id:ID][f]]— links its description to that section, as a graph's node does; sans description, the heading shows.
  • Lines with an & are aligned at it; else, lines that end in \\ are gathered, each centred on a line of its own. With :numbered once, the lines are one equation, with one number: split at their &, else gathered.
  • :environment names the environment ourselves, for a layout the lines don't imply: multline* for one long equation, broken over lines; alignat*{2} for columns of a set width. Sans star, it is numbered, and its #+name: labels it.
  • Inline maths, $red:x$ or \(red:x\), reads our links and Org's markup just as the block does.
  • In Emacs, the block looks as a #+begin_src latex block does, with each red:ATOM in red, as the maths reads it; C-c C-c shows the maths as an image atop the block, until C-c C-c again, or an edit; and C-c ' edits it in latex-mode, its hints, tags, and colours shown as in the Org buffer. Org's own C-c C-x C-l, and #+startup: latexpreview, show math blocks as images too.
  • With org-cdlatex-mode, a math block reads as maths, as $…$ does: _ and ^ open braces, `a is \alpha, and TAB expands cdlatex's templates; a hint's prose is prose, save its own $…$.
  • Unicode, such as ∀ x ∈ ℕ, typesets in HTML as is; in LaTeX, it needs #+latex_compiler: lualatex and #+latex_header: \usepackage{unicode-math}, else its symbols are dropped —silently, with only a “Missing character” in the log.
#+begin_math :numbered t :matrix bmatrix
R_{teal:\theta} =
| \cos teal:\theta | -\sin teal:\theta |
| \sin teal:\theta | \cos teal:\theta  |
#+end_math

8. Aligned equations ---& in a math block, cited by [[𝒳]]

A math block whose lines have an & is LaTeX's align: its lines line up at each &. As in LaTeX, a line ends in \\, unless it ends in a tag COLOUR:<<NAME>>, which is NAME in that colour, as red:x colours maths; <<NAME>> is plain. It is Org's own target, so NAME may hold spaces, and a _ is a subscript: <<Base Case_1>> is tagged “Base Case₁”. Its brackets delimit it, so a hint's nested calculation, \[ … \], may hold one too. We cite it as Org cites any named thing: [[NAME]] is its number, or name, as LaTeX's \eqref shows it; and [[NAME][these words]] links the words to it. C-c C-o on the link, in Emacs, visits the line; failing that, any \tag{…NAME…}. A NAME may hold maths, such as ⊑-Definition or Distributivity of \meet, which shows as maths in the tag, and is cited by the very same name. With :numbered t, the untagged lines are numbered too. Only the block's own & counts: one within a {group} or a \begin{cases}…\end{cases} belongs to it, so a piecewise definition is one equation, unless its line aligns at an & of its own. A hint, X ={ HINT } Y, aligns its line too —see calculational proofs. Shorthands are welcome too: the :let switch gives them, as below.

﴾What You Write﴿
A ~math~ block aligns its lines at each =&=; a line may end in a coloured tag,
which a link, =[[Golden Rule]]=, cites. Shorthands, such as =->= below, come from the =:let= switch every block has.

#+begin_math :let (-> "\\Rightarrow" == "\\equiv")
p -> q &== \neg p \lor q          blue:<<Implication>>
p \land q &== p == q == p \lor q  orange:<<Golden Rule>>
#+end_math

By [[Golden Rule]], conjunction is defined by equivalence and disjunction.
﴾What You Get﴿

A math block aligns its lines at each &; a line may end in a coloured tag, which a link, [[Golden Rule]], cites. Shorthands, such as -> below, come from the :let switch every block has.

\begin{align*} p \Rightarrow q &\equiv \neg p \lor q \tag{$\color{blue}{\text{Implication}}$} \label{Implication} \\ p \land q &\equiv p \equiv q \equiv p \lor q \tag{$\color{orange}{\text{Golden Rule}}$} \label{Golden Rule} \end{align*}

By \eqref{Golden Rule}, conjunction is defined by equivalence and disjunction.

To share shorthands among many blocks, name them once, in a table that need not itself export:

#+begin_math :let logic
p -> q &== \neg p \lor q
#+end_math

* Shorthands :noexport:
#+name: logic
| Variable | Value       |
|----------+-------------|
| ->       | \Rightarrow |
| ==       | \equiv      |

The rows above the rule are a header, and are skipped. A Lisp variable serves too, across documents: (setq logic '(-> "\\Rightarrow")) and then :let logic.

9. Calculational proofs ---REL{ HINT } in a math block, folded by TAB

A calculational proof states why each step holds. We write the hint right after the relation, X ={ HINT } Y, and it shows on a row of its own, between the two expressions it relates —as Feijen and Dijkstra set a calculation— in maroon, after a bracket that opens it, lest it be mistaken for maths. So too for any relation ---≤{ … }, \equiv{ … }, or a :let shorthand's. The { hugs the relation and a space or newline follows it, so LaTeX's own x ={a} and \frac{ a }{ b } are left be. So that we need not recall the rule, Emacs shows each hint as a comment, by the very reading the export makes; any other {…} is LaTeX's own.

A step runs from its hint to the next, wherever the newlines fall —we need not write \\, and may give each expression and hint a line of its own, in Dijkstra's style, or not.

#+begin_math :let (== "\\equiv")
p \land q =={ Golden Rule } p == q == p \lor q
           =={ by symmetry } q \land p
#+end_math

A hint may span lines, as a long reason does, and shows on those very lines —a blank one a gap between paragraphs. Within a hint, \[ … \] is a nested calculation, whose own hints are read alike, so they may nest in turn; one sans hints is a mere displayed formula.

  • TAB on a hint folds it away to {…}, and TAB again unfolds it —the proof's outline at a glance; so too in the block's C-c ' buffer. C-TAB within a block folds all its hints, unless all are folded, whence it unfolds them. In HTML, a click on a hint folds it, and a shift-click all hints of its proof, as its tooltip says. With point on a hint, the echo area says what it is, how to write it, and how to fold it.
  • M-q within a hint fills the paragraph at point alone, as prose, and so sets its lines; M-q elsewhere in the block, or within a nested calculation, leaves the maths be.
  • A line # … is a comment, even within a hint: say, an alternative reason, kept in the source yet absent from the export.
  • :hints says how hints show:

    :hints between On a row of their own, maroon and bracketed: the default.
    :hints beside At their step's end, plain, as their column sets them apart.
    :hints none Hidden from the export; the steps remain, a compact chain.
    :hints (beside "{\color{teal} \langle %s \rangle}") A layout, then a format of our own, LaTeX whose %s is the hint.
    :hints (between folded) Folded, so a page's reader clicks to see each —a puzzle!

    A format may join folded, as in (between "{\color{teal} %s}" folded). LaTeX, sans clicks, shows folded hints in full. Hints beside read well when the expressions are narrow; to have them so throughout a file, we say it once, as for any block's header arguments:

    #+property: header-args:math :hints beside
    

“Programming Comments ≈ Proof Hints”

Let's prove that \(x ≤ z\)…

Source:

#+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

Result:

\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*}

Let's calculate that \(a ⊆ e\)…

Source:

#+begin_math
  a
={ reason for the equality }
  b
⊆{ reason for the inclusion }
  c
={ reason for the equality }
  d
={ final justification }
  e
#+end_math


Result:

\begin{align*} & a \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{reason for the equality} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & b \\ ⊆ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{reason for the inclusion} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & c \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{reason for the equality} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & d \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{final justification} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & e \end{align*}

Examples below: “1 + 1 = 2”, calculating a train's length, Euler's Handshaking Lemma, and rational root equivales perfect power.

★ Proof of “1 + 1 = 2” with source

\[\def\suc{\mathsf{suc}\,} \def\zero{\mathsf{zero}}\]

\begin{align*} & 1 + 1 \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{“1” abbreviates “$\suc \zero$”} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \suc \zero + \suc \zero \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Addition is defined by moving the} \\ \text{$\suc$-s from the left argument to the} \\ \text{right.} \\ \\ \text{That is, we define $x + y$ by considering} \\ \text{the possible $shape$ of $x$, which could} \\ \text{only be a $\zero$ or a $\suc$-cessor.} \\ \\ \text{When $x$ is zero, there are no $\suc$-s} \\ \text{to move to the right, so we yield the} \\ \text{right:} \\ \begin{aligned}[t] \zero + n = n \qquad \cssId{mjx-eqn:Base_Case}{{\color{teal}\text{(Base Case)}}} \end{aligned} \\ \text{When $x$ is a $\suc$, we move the $\suc$} \\ \text{to the right, and continue to try adding:} \\ \begin{aligned}[t] \suc m + n = m + \suc n \qquad \cssId{mjx-eqn:Inductive_Step}{{\color{teal}\text{(Inductive Step)}}} \end{aligned} \\ \text{Since we're moving a $\suc$ at each step,} \\ \text{eventually we'll hit the $\href{#mjx-eqn%3ABase_Case}{\text{(Base Case)}}$ and be} \\ \text{done adding.} \\ \\ \text{For now, we apply the $\href{#mjx-eqn%3AInductive_Step}{\text{(Inductive Step)}}$.} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \zero + \suc (\suc \zero) \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Using the $\href{#mjx-eqn%3ABase_Case}{\text{(Base Case)}}$ of addition} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \suc (\suc \zero) \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Switching to ‘conventional’ notation} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & 2 \end{align*}

Source:

#+begin_math
\def\suc{\mathsf{suc}\,}
\def\zero{\mathsf{zero}}
  1 + 1
={ “1” abbreviates “$\suc \zero$” }
  \suc \zero + \suc \zero
={ Addition is defined by moving the
   $\suc$-s from the left argument to the
   right.

   That is, we define $x + y$ by considering
   the possible $shape$ of $x$, which could
   only be a $\zero$ or a $\suc$-cessor.

   When $x$ is zero, there are no $\suc$-s
   to move to the right, so we yield the
   right:
   \[ \zero + n = n   teal:<<Base Case>> \]
   When $x$ is a $\suc$, we move the $\suc$
   to the right, and continue to try adding:
   \[ \suc m + n = m + \suc n   teal:<<Inductive Step>> \]
   Since we're moving a $\suc$ at each step,
   eventually we'll hit the Base Case and be
   done adding.

   For now, we apply the Inductive Step.
 }
  \zero + \suc (\suc \zero)
={ Using the Base Case of addition }
  \suc (\suc \zero)
={ Switching to ‘conventional’ notation }
  2
#+end_math
“Calculating” the length of a train

Let us calculate the length of a train, that is travelling at a speed of 60 km/hr and, on its way, it crosses a pole in 9 seconds.

\[\def\meters{\,\mathsf{meters}\,} \def\seconds{\,\mathsf{seconds}\,}\]

\begin{align*} & \text{the length of the train} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Express length as a difference of distance} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \text{the distance from the end of the train to its front} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{distance = time × speed} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \left(\begin{aligned} &\text{difference in time from when the train's front} \\ &\text{crosses the pole until its back crosses the pole} \end{aligned}\right) \times \text{speed of the train} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Rephrase} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \text{how long it takes the train to cross the pole} \times \text{speed of the train} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{The train crosses the pole in 9 seconds;} \\ \text{and the train is travelling at the speed of 60km/hr.} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & 9 \text{ seconds } \times 60 \text{ km / hr} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Express things in common units, such as seconds; i.e.,} \\ \begin{aligned}[t] & 1 \text{ km / hr} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Be more explicit} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & 1 \text{ km } /\; 1 \text{ hr } \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{A kilometre is 1000 meters} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & 1000 \meters /\, 1 \text{ hr } \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Express hours in terms of seconds:} \\ \begin{aligned}[t] & 1 \text{ hr } \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Express in minutes} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & 60 \,\mathsf{minutes} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Be more explicit} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & 60 \,\times\, 1 \,\mathsf{minutes} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{A minute has 60 seconds} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & 60 \,\times\, 60 \,\seconds \end{aligned} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & 1000 \meters /\, (60 × 60) \seconds \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Collecting like-terms} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & (1000 / 60 × 60) \meters / \seconds \end{aligned} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & 9 \seconds \times 60 × (1000 / 60 × 60) \meters / \seconds \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Division cancels multiplication: $b × (a / b) = a$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & 9 \seconds \times (1000 / 60) \meters / \seconds \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Collect like-terms; i.e., commutativity of ×} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & (1000 / 60) × 9 \seconds × (\meters / \seconds) \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Division cancels multiplication: $b × (a / b) = a$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & (1000 / 60) × 9 \meters \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Arithmetic} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & 150 \meters \end{align*}
Euler's Handshaking Lemma

At a party of 7 people, is it possible that everybody knows exactly 3 other people?

We could consider all possible cases, which is not particularly enlightening; or we could calculate…

\[\def\even#1{\mathsf{even}\,\left(#1\right)} \def\odd#1{\mathsf{odd}\,\left(#1\right)}\]

\begin{align*} & \begin{array}{l} \text{“Obviously”, the sum of everyone's friendship count} \\ \text{is twice the total number of friendships} \end{array} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Formalise...} \\ \\ \text{Let $f(p)$ denote the number of friends that person $p$} \\ \text{has, which is 0 if $p$ has no friends.} \\ \\ \text{Let $F$ be the total number of friendships (between any 2 people).} \\ \\ \text{Since friendships are always between two people, we have} \\ \text{that $\sum_p f(p) = 2 × F$: Counting-up the number of} \\ \text{friends that everyone has will always be twice the total} \\ \text{number of relationships ---which is always an even number.} \\ \\ \text{Formally,} \\ \begin{aligned}[t] & \text{sum of everyone's friendship count} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Formalise, where $p$ ranges over people} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & \sum_p f(p) \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Definition of $f$: Let $𝑭𝒓_{p, r}$ be 1 exactly when $p$} \\ \text{participates in friendship/relationship $r$, and 0} \\ \text{otherwise, then $f(p) = \sum_r 𝑭𝒓_{p, r}$.} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & \sum_p \sum_r 𝑭𝒓_{p, r} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Quantifier interchange; i.e., Fubini's Principle} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & \sum_r \sum_p 𝑭𝒓_{p, r} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Every relationship $r$ is between 2 people;} \\ \text{i.e., $\sum_p 𝑭𝒓_{p, r} = 2$} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & \sum_r 2 \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Factoring} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & 2 × \sum_r 1 \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{The total number of friendships is $F$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & 2 × F \end{aligned} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & ∑_p f(p) = 2×F \\ ⇒ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Equals for equals; i.e., $if$ those numbers are equal} \\ \text{$then$ their parities are equal} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \even{∑_p f(p)} ≡ \even{2 × F} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{The right side is clearly true; (‘true’ is the identity of ‘$≡$’)} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \even{∑_p f(p)} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{$\even{-}$ distributes over sums turning them into equivalences ‘$≡$’} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & {\LARGE ≡}_p \;\even{f(p)} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{By definition, a chain of equivalences is true exactly when} \\ \text{it has an even number of false values} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \even{ ♯\{p ∣ ¬ \even{f(p)}\} } \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{A non-even number is precisely an odd number} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \even{ ♯\{p ∣ \odd{f(p)} \} } \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Un-formalise} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \text{an even number of people have an odd number of friends} \end{align*}

Back to the problem: At a party of 7 people, is it possible that everybody knows exactly 3 other people?

If such a party were possible, the number of people with an odd friend count must be even, but 7 is not even, and so no such party is possible. ( Alternatively, if such a party were possible, then by the Handshaking Lemma, \(F = {∑_p f(p) \over 2} = {7 × 3 \over 2} = 10.5\): This is absurd since there cannot be a ‘.5’ relationship! Hence, no such party is possible. )

  • Likewise, if exactly 5 people in a room each claim to have shaken 3 hands, then someone is lying.

( Rephrased: The sum of the degrees of the vertices of a (total) graph is twice the number of edges of the graph; moreover, an even number of vertices have an odd degree.

The party problem is then: Is there a graph of 7 nodes with each node being connected to exactly 3 other nodes? Apparently not, and we didn't need to draw any graphs at all to prove it.

For more on Graph Theory, here are some lecture notes. )

★ Rational root equivales perfect power

\[\def\exp#1#2{\mathsf{exp}_#1\,#2} \def\eq{\;=\;}\]

\begin{align*} & \sqrt[n]{k} \text{ is a rational number } \\ ⇔ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{A rational number is the fraction of two integers.} \\ \text{Let variables $a,\, b$ range over integer numbers.} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & ∃\, a, b •\; \sqrt[n]{k} = {a \over b} \\ ⇔ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Use arithmetic to eliminate the $n$-th root operator.} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & ∃\, a, b •\; k · b ^n = a ^n \\ ⇔ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Let $\exp{m} x$ be the number of times that $m$ divides $x$.} \\ \text{For example, $\exp{2} 48 \eq 4$ and $\exp{2} 49 \eq 0$.} \\ \\ \text{The numbers $p$ with $∀ m : ℤ⁺ \;•\; \exp{m}p \,≠\, 0 \,≡\, m \,=\, p$} \\ \text{are called $prime$ numbers. Let variable $p$ range over prime numbers.} \\ \\ \text{Fundamental theorem of arithmetic: Numbers are determined by} \\ \text{their prime powers. That is, for any $f$,} \\ \begin{aligned}[t] \big(∀ \,p\, •\;\; \exp{p} x \eq f(p)\big) \;\;≡\;\; x \eq \big(Π\, p\, •\; p^{f(p)}\big) \end{aligned} \\ \text{As such, every number is the product of its prime powers:} \\ \begin{aligned}[t] x \eq \big(Π \,p\, •\; p^{\exp{p} x}\big) \end{aligned} \\ \text{And so, any two numbers are the same precisely when they} \\ \text{have the same primes:} \\ \begin{aligned}[t] x \eq y \;\;≡\;\; \big(∀ p \,•\, \exp{p} x \eq \exp{p} y\big) \end{aligned} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & ∃\, a, b •\; ∀\, p •\; \exp{p}(k · b ^n) \eq \exp{p}(a ^n ) \\ ⇔ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{When $p$ is prime, $\exp{p}(x · y) \eq \exp{p} x \,+\, \exp{p} y$.} \\ \text{Aside: In general, $\exp{p}(Π \,i\, \,•\, x_i) \eq (Σ \,i\, \,•\, \exp{p} x_i)$.} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & ∃\, a, b •\; ∀\, p •\; \exp{p} k + n · \exp{p} b \eq n · \exp{p} a \\ ⇔ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Use arithmetic to collect similar terms.} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & ∃\, a, b •\; ∀\, p •\; \exp{p} k \eq n · \Big(\exp{p} a - \exp{p} b\Big) \\ ⇔ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{($⇒$) is the definition of multiplicity;} \\ \text{($⇐$) take $b \,≔\, 1$ and define $a$ by its prime powers:} \\ \begin{aligned}[t] ∀\, p \,•\, \exp{p} a \,≔\, {\exp{p} k \,/\, n} \end{aligned} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & ∀\, p •\; \exp{p} k \text{ is a multiple of } n \\ ⇔ & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Fundamental theorem of arithmetic and definition of ‘perfect’} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & k \text{ is a perfect $n$-th power; i.e., of the shape } x^n \end{align*}

Possibly Useful links:

★ What if I want to do this in LaTeX (e.g., for math.stackexchange.com)?

Copy-paste the following…

$
% set up \step command
\def\BEGINstep{ \left\langle }
\def\ENDstep{ \right\rangle }
\newcommand{\step}[2][=]{ \\ #1 \;\; & \qquad \color{maroon}{\BEGINstep\text{ #2 } \ENDstep} \\ & }
% multi-line step with many lines of text
\newcommand{\line}[1]{ \text{#1}\hfill\\ }
\newcommand{\stepmany}[2][=]{ \\ #1 \;\; & \qquad \color{maroon}{\BEGINstep \large\substack{ #2 } \ENDstep} \\ & }
% multi-line step with 4 lines of text
\newcommand{\stepfour}[5][=]{ \stepmany[#1]{\line{#2} \line{#3} \line{#4}
\line{#5}} }
\newenvironment{calc}{\begin{align*} & }{\end{align*}}
$

Then, use it as follows…

\begin{calc}
x
\step{reason for equality}
y
\step[\leq]{reason for inclusion}
z
\end{calc}

9.1. ★ Everything at once: the geometric series

A calculation enjoys all of a math block's maths. Below, we sum the first \(n\) powers of \(r\); read the key beneath, then hover, click, and TAB away.

\[\def\Sn{\mathcal{S}_n}\]

\begin{align*} & {\color{red}{(1 - r)}} · \class{tooltip osbe-tip-g540}{\Sn} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Definition of $\Sn$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & {\color{red}{(1 - r)}} · \sum_{i=0}^{n-1} r^i \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Distribute ${\color{red}{(1 - r)}}$ over the sum} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \sum_{i=0}^{n-1} r^i - {\color{teal}{\sum_{i=0}^{n-1} r^{i+1}}} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Shift the second sum's index:} \\ \begin{aligned}[t] & \sum_{i=0}^{n-1} r^{i+1} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Let $j = i + 1$, from $1$ to $n$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & \sum_{j=1}^{n} r^j \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Rename $j$ back to $i$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \\ & \sum_{i=1}^{n} r^i \end{aligned} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & \sum_{i=0}^{n-1} r^i - {\color{teal}{\sum_{i=1}^{n} r^i}} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \begin{array}{@{}l@{}} \text{Expand both sums: each of $r^1, …, r^{n-1}$ appears in} \\ \text{both, once added and once subtracted, and so cancels} \end{array} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & r^0 + \cancel{r^1} + ⋯ + \cancel{r^{n-1}} - \cancel{r^1} - ⋯ - \cancel{r^{n-1}} - r^n \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{Only the first and the last terms survive} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & {\color{violet}{r^0}} - {\color{violet}{r^n}} \\ = & \quad \class{tooltip osbe-tip-hint osbe-hint}{\class{osbe-hint-body}{{\color[RGB]{128,0,0} \left[ \text{$r^0 = 1$} \right.}}\class{osbe-hint-fold}{{\color[RGB]{128,0,0} [\,\cdots\,]}}} \notag \\ & 1 - r^n \tag{$\color{teal}{\text{Geometric}}$} \label{Geometric} \end{align*}

Hence, by \eqref{Geometric}, \(\Sn = {1 - r^n \over 1 - r}\) whenever \({\color{red}r} ≠ 1\).

  • Colour tells where to look: red, the factor a step distributes; teal, the sum it reindexes; violet, the two terms that survive. Inline maths is coloured alike: \({\color{red}r} ≠ 1\).
  • Org's +strike+ is LaTeX's \cancel, so the telescoping cancellation is drawn as one.
  • \Sn[fn::…] is a tooltip: hover over \(\mathcal{S}_n\) in the first line. \def\Sn names it once.
  • :let (Σ "\\sum_{i=0}^{n-1}") is a shorthand, so each line writes Σ r^i; it reaches the nested calculation too.
  • The index shift is a nested calculation, \[ … \], within its hint.
  • teal:<<Geometric>> tags the result, which [[Geometric]] then cites, as Org cites any named thing.
  • A line # … is a comment, kept in the source yet absent from the export.
  • For a puzzle, try :hints (between folded): the reader clicks each hint to see it —or shift-clicks, for all of them.

Source:

#+begin_math :let (Σ "\\sum_{i=0}^{n-1}")
# A comment, absent from the export: 𝒮ₙ is defined once.
\def\Sn{\mathcal{S}_n}
  red:{(1 - r)} · \Sn[fn::the first $n$ powers of $r$, summed]
={ Definition of $\Sn$ }
  red:{(1 - r)} · Σ r^i
={ Distribute $red:{(1 - r)}$ over the sum }
  Σ r^i - {Σ r^{i+1}}
={ Shift the second sum's index:
   \[   Σ r^{i+1}
      ={ Let $j = i + 1$, from $1$ to $n$ } \sum_{j=1}^{n} r^j
      ={ Rename $j$ back to $i$ } \sum_{i=1}^{n} r^i \] }
  Σ r^i - {\sum_{i=1}^{n} r^i}
={ Expand both sums: each of $r^1, …, r^{n-1}$ appears in
   both, once added and once subtracted, and so cancels }
  r^0 + +r^1+ + ⋯ + +r^{n-1}+ - +r^1+ - ⋯ - +r^{n-1}+ - r^n
={ Only the first and the last terms survive }
  {r^0} - {r^n}
={ $r^0 = 1$ }
  1 - r^n   teal:<<Geometric>>
#+end_math

10. Graphs ---Org lists, drawn by Graphviz

﴾What You Write﴿
Org lists are already trees, so the ~graph~ block draws them with Graphviz:
nesting makes an edge, and a two-column table styles the item above it.

#+begin_graph :file lambda-calculus.png
#+graph:
| rankdir | LR |

#+node:
| shape | box |

+ λ-calculus
  | shape | ellipse |
  + encodes :: Church encodings
  + <<combinators>> Combinators
    + S K I
+ Lisp
  + borrows :: [[combinators]]
    | :edge.style | dotted |
#+end_graph

Press =C-c C-c= inside the block to render it to a PNG; =C-u C-c C-c= shows the dot source instead.
﴾What You Get﴿

Org lists are already trees, so the graph block draws them with Graphviz: nesting makes an edge, and a two-column table styles the item above it.

λ-calculus Church encodings encodes Combinators S K I Lisp borrows

Press C-c C-c inside the block to render it to a PNG; C-u C-c C-c shows the dot source instead.


﴾How It’s Implemented﴿
(org-defblock graph (&optional title &key file svg &allow-other-keys :edit-indirect-mode org-graph-edit-mode
                    :manual "#Graphs" &context backend raw-contents args anchor)
  "Render an Org list + tables as a Graphviz dot graph.

TITLE is the graph's label.
The header's other keys are graph attributes, such as :rankdir LR; :node.KEY and :edge.KEY set node and edge defaults;
:directed nil makes an undirected graph; :wrap N fills labels to N characters a line; :unflatten N staggers
wide rows of leaves over N ranks; and :unknown-tags random-templates gives an unknown tag a made-up template,
rather than erring.  Pass :file foo.png on the
#+begin_graph line to fix the output filename; else a #+name: foo line above the block makes it foo.png, and the graph
a figure that [[foo]] reaches and #+caption: captions; otherwise the name is graph-HASH.png, HASH being that of the
dot source, so re-exporting an unchanged graph rewrites one file rather than adding another.

For HTML export: embeds an inline <svg> element, whose nodes' and arcs' tooltips hover as prose's do, by tooltips.js;
under :svg nil, an inline base64 PNG, sans tooltips.  Either fits the page's width, a click toggling its full size.
For Markdown, it writes the image file and links it, as for a named graph.
For other backends it emits a #+begin_src dot block.  In HTML, a node's [[*Section]] link leads to that section.

With :smartdiagram TYPE ---constellation, flow:horizontal, descriptive, and so on--- LaTeX's smartdiagram package
typesets the list instead, as `org--smartdiagram' says: the #+graph: rows are \\smartdiagramset's, and prose after the
list sits beneath the diagram.  It renders by pdflatex, at :dpi dots per inch, 300 by default; LaTeX export typesets it
in place, adding smartdiagram to the preamble.

Within the block body:

  #+graph: table  ↦ global graph[ ] attributes
  #+node:  table  ↦ default node[ ] attributes
  #+edge:  table  ↦ default edge[ ] attributes
  #+rank:  n1 n2  ↦ { rank=same; n1; n2 } for nodes without a common parent; ids may be [[links]]
  Under an item, #+graph:, #+node:, #+edge:, and #+rank: reach its whole subtree, as Org's inherited properties do.
  #+begin_cluster TITLE :KEY V … #+end_cluster  ↦ subgraph cluster_TITLE { … }; nests, and may sit in an item
  :NAME: … :END:  ↦ a drawer of any name, folding such directives away
  - :T: :: MEANING  ↦ at the top, a legend entry: a sample of template T, captioned MEANING

A #+name: table outside any graph is a template every graph in the buffer may use; the graph's own wins.
A section tagged :graph: exports as a graph of its text, its :PROPERTIES: drawer serving as the header line.

Each list item declares a node.  Nesting encodes edges (parent → child); ordered children, 1. 2. 3., share a rank
in the order written.  An item's text may hold a <<target>>, its id; [[TARGET]] or [[TARGET][LABEL]] links, extra arcs;
and *bold*, /italic/, _underline_, +strike+, =code=, or ~pre~, a braced x^{2} or H_{2}O, or a @@dot:…@@ snippet,
which make its label an HTML-like one; an entity, \\alpha, is its character.  A <<<radio target>>> is a node, every
item mentioning it having an arc to it.  Other Org syntax in a block, such as a headline or #+begin_quote, is an error.
A description tag, `+ L :: CHILD', labels the arc into CHILD; trailing `:T:' tags splice #+name: templates;
an inline footnote, [fn::NOTE], is the node's tooltip, as is a note: a paragraph past the item's first, or a
#+begin_note block ---with `#+begin_note :edge', the arc's---, shown beneath the label instead under :notes inline;
a web, file, or [[*Section]] link, its URL; an [[file:IMAGE.png]], its image;
a checkbox, [X], [-], or [ ], applies the template checked, partial, or unchecked, when one exists; and a `\\\\'
breaks the label's line ---in a table value or #+record: cell, too.
Org's {{{macros}}} expand, by the buffer's #+macro: lines.
A two-column inline table on a list item supplies node attributes.

  | key        | val    |  ↦ a Graphviz attribute of the node; values are quoted for you.
  | :id        | alias  |  ↦ cross-reference name for this node.
  | :edge.KEY  | val    |  ↦ attribute of the arc from the parent; a parallel arc is a second child item.
  | :edge[T].KEY | val  |  ↦ attribute of this item's arc to T, from a [[T]] link; \"rec::port\" reaches a record's port.
  | :inherit   | T₁ T₂  |  ↦ inherit the #+name: templates' rows; explicit rows win.  Also :edge.:inherit, and :T₁:T₂: tags:
                            after an item, its node's; after a reference, or a description term, its arc's.
  A child item that is a lone [[T]] link is a reference to T: an arc to it, styled by the child's :edge.KEY rows.
  | :children-rank | same | ↦ constrain immediate children to the same rank;
                            also accepts min, max, source, sink.
  | shape | cluster |      ↦ make this node an inline subgraph cluster_ID { … }.
  #+record: table       ↦ the node's <TABLE> label, as laid out: a cell's <<p>> is port p, its [[T]] an arc from there;
                            ^ or an empty cell spans, a <l>/<c>/<r> row aligns, and hlines rule.

Example:

  #+begin_graph :rankdir LR
  + A
    + calls :: B
      + returns :: C
  #+end_graph"
  (let* ((smart   (plist-get args :smartdiagram))
         (raw     (org--graph-expand-macros raw-contents))
         ;; HTML inlines a graph's <svg>, for its tooltips, unless told :svg nil; `svg' alone cannot tell nil from omitted.
         (inline-svg (and (eq backend 'html) (not anchor) (not (org-export-markdown-p))
                          (or svg (not (or smart (plist-member args :svg))))))
         (org--graph-tips (and inline-svg (make-hash-table :test #'equal)))
         (dot     (if smart (org--smartdiagram raw title args)
                    (org--graph-raw->dot raw title args)))
         (render  (if smart
                      (lambda (kind file) (org-graph--render-latex dot kind file (org-graph--dpi args)))
                    (lambda (kind file) (org-graph--render dot kind file))))
         ;; The header reads :file foo.png as the symbol foo.png; we want its name.
         (outfile (or (and file (format "%s" file)) (org-graph--named-file anchor svg)
                      (format "graph-%s.png" (substring (md5 dot) 0 12)))))
    (pcase backend
      ;; LaTeX typesets a smartdiagram itself: no image, and its packages join the preamble.
      ((guard (and smart (org-export-derived-backend-p backend 'latex)))
       (dolist (package org-graph-smartdiagram-latex-head) (cl-pushnew package org--latex-head-used :test #'equal))
       (format "\\begin{center}\n%s\n\\end{center}" dot))
      ;; A named graph is a figure: an image link, which the block's #+name: and #+caption: label, as with Babel's results.
      ;; Markdown gets one too, since its renderers strip the inline base64 <img> that HTML gets.
      ((guard (or anchor (org-export-markdown-p)))
       (funcall render (if (s-ends-with-p ".svg" outfile) "svg" "png") outfile)
       (org-parse (format "[[file:%s]]" outfile)))
      (`html
       (let ((tmp (make-temp-file "org-graph-" nil (if inline-svg ".svg" ".png"))))
         (unwind-protect
             ;; An inline <svg> keeps the tooltips; else, an inline base64 PNG.
             (or (when (funcall render (if inline-svg "svg" "png") tmp)
                   (-some-> (if inline-svg (-some--> (org-graph--svg-contents tmp) (org-graph--svg-tooltips it org--graph-tips))
                              (format "<img src=\"data:image/png;base64,%s\" alt=\"graph\" />" (org-graph--png-to-base64 tmp)))
                     org-graph--fit-width))
                 ;; dot unavailable, or its output sans <svg>: emit the raw dot source in a <pre>, its tooltips as text.
                 (format "<pre>%s</pre>" (s-replace "<" "&lt;" (if (and inline-svg (not smart))
                                                                    (let (org--graph-tips)
                                                                      (org--graph-raw->dot raw title args))
                                                                  dot))))
           (delete-file tmp))))
      (_
       ;; `org-parse' lets Org export the src block, rather than emit its raw syntax into the output.
       (org-parse (if smart (format "#+begin_src latex\n%s\n#+end_src" dot)
                    (format "#+begin_src dot :file %s\n%s\n#+end_src" outfile dot)))))))

The graph block is opt-in, so we load it separately with (require 'org-graph-block). Rendering needs the dot executable from Graphviz: HTML export embeds an inline SVG, whose tooltips hover as any other's do —or a PNG, sans tooltips, via :svg nil— whereas other backends receive the dot source. Inside the block, #+graph:, #+node: and #+edge: tables set Graphviz's defaults; C-h o org-block/graph documents every option.

﴾What You Write﴿
Some lists want a picture rather than a graph: a centre and what orbits it, or a flow of steps.
~:smartdiagram TYPE~ hands the very same list to LaTeX's smartdiagram package instead of Graphviz:

#+begin_graph One Org source, rich HTML and LaTeX :smartdiagram constellation
#+graph:
| planet color              | black!75        |
| planet font               | \bfseries       |
| planet text width         | 3cm             |
| satellite size            | 2.8cm           |
| satellite text width      | 2.6cm           |
| distance planet-satellite | 4.6cm           |
| font                      | \small\sffamily |

+ org-special-block-extras \\ define blocks & links
  | fontcolor | white |
  + =org-defblock= \\ custom blocks
  + =org-deflink= \\ custom links
  + =details= =parallel= \\ =proof= =margin=
  + =doc:= =kbd:= \\ =badge:= =fortune:=
  + HTML & LaTeX \\ one Org source
#+end_graph

Press =C-c C-c= inside the block to render it with =pdflatex=; LaTeX export typesets it in place.
﴾What You Get﴿

Some lists want a picture rather than a graph: a centre and what orbits it, or a flow of steps. :smartdiagram TYPE hands the very same list to LaTeX's smartdiagram package instead of Graphviz:

graph

Press C-c C-c inside the block to render it with pdflatex; LaTeX export typesets it in place.

Under :smartdiagram TYPE, the #+graph: rows are LaTeX's \smartdiagramset keys, and C-M-i completes those rather than Graphviz's; rendering needs pdflatex, with the smartdiagram package, and pdftoppm. Org's own markup ---#+macro:, ~code~, colour links, src blocks— replaces LaTeX's \newcommand, \texttt, \textcolor, and hand-tuned \hspace's; graphs-README.org sets the two side by side.

11. Switches for every block: :when, :let, :folded, …

Just as every src block understands :exports and :results, every block understands these header arguments —ours, those made with org-defblock, Org's own src, example, quote, verse, and center blocks, and any #+begin_𝒳 at all, no declaration needed:

Switch Effect upon export
:noexport t Nothing at all; e.g., notes to self
:when FORM Nothing at all, unless the Lisp FORM is non-nil; it may mention backend
:let (VAR VAL …) Each whole-word VAR, or operator such as ->, in the contents becomes its value, beforehand
:let NAME Likewise, for the VAR and VAL of each row of the table #+name: NAME, else of the variable NAME
:ignore t The contents, as plain Org; i.e., the block's own behaviour is bypassed
:boxed TITLE The result, within a box titled TITLE; t for untitled
:folded TITLE The result, folded within details titled TITLE; t for the block's name
:verbatim t The block as written, sans its switches, shown as Org source
:demo t That source, then what it exports to; and a test that it still does; see Demos
﴾What You Write﴿
#+begin_box Exercise :let (N 7)
What do the first N odd numbers sum to?
#+end_box

#+begin_box Answer :let (N 7 SUM (* N N)) :folded "Peek at the answer"
The first N odd numbers sum to N × N, which is SUM.
#+end_box

#+begin_remark :noexport t
Ask the class for a proof by induction next week.
#+end_remark

#+begin_parallel :when (eq backend 'html) :boxed "On the web only"
Columns suit wide screens.
#+columnbreak:
Print gets one column.
#+end_parallel
﴾What You Get﴿

Exercise

What do the first 7 odd numbers sum to?

Peek at the answer

Answer

The first 7 odd numbers sum to 7 × 7, which is 49.

On the web only

Columns suit wide screens.

Print gets one column.

A src block's :folded t is titled by its language, and its code is still exported by Org, as ever. Switches apply before Babel runs, so a src block's :let changes the code it runs, :noexport keeps it from running at all, and :folded folds away its results too. Other switches then apply to a :verbatim or :demo showing; e.g., :demo t :folded t folds away a block's source and rendering alike.

Moreover, :C-c_C-c ACTION gives a block an action in Emacs: pressing C-c C-c within it calls ACTION when it names a function, else evaluates it as a Lisp form; see C-c C-c for your own blocks.

Switches are inherited as a src block's header-args are; e.g., :header-args:red: :let (N 3) in a heading's drawer gives every red block of its subtree that :let.

A block that declares a keyword of the same name keeps it for itself; e.g., a block with its own folded argument receives :folded as usual. Since :when, :let and :C-c_C-c run Lisp written in the document, Emacs asks once before running each distinct form; org-defblock-evaluate-switches may instead allow them freely, or never.

12. Demos —a block, then what it exports to, and a test that it still does

Any block marked :demo t exports as ﴾What You Write﴿, the block as written sans its switches, then ﴾What You Get﴿, what it renders to. Pressing C-c C-c within it snapshots that rendering, along HTML and LaTeX ---org-demo-backends— in a #+RESULTS: drawer just after it, as Babel does a src block's results:

#+begin_box Title :demo t
Hi *there*
#+end_box

#+RESULTS[96978da579]:
:results:
#+begin_export html
<div style="padding: 1em;background-color: #CCFFCC; …"> <h3>Title</h3> <p> Hi <b>there</b> </p> </div>
#+end_export
#+begin_export latex
… \begin{tcolorbox}[title={Title}, …] Hi \textbf{there} \end{tcolorbox}
#+end_export
:end:

So a demo is three things at once:

  1. A demonstration, in the docs: the source, then its rendering; the snapshot is what is shown, so a reader sees what we saw, whatever build of ours renders the page.
  2. A test in the small, upon export: the block is rendered afresh and compared, sans whitespace and case, to its snapshot; a mismatch is a warning, or an error, or nothing, as org-demo-check says. The hash, [96978da579], tells the two failures apart: a source changed since its snapshot, or a rendering that changed for the same source —a regression, or an intended change, which another C-c C-c records.
  3. A test suite in the large: org-demo-failures checks every demo of a file, along every snapshotted backend; this manual's own are an ERT test,

    (ert-deftest manual ()
      (should-not (org-demo-failures "org-special-block-extras.org")))
    

M-x org-demo-refresh-buffer snapshots them all; C-u C-c C-c leaves C-c C-c to the block's own action, if any.

A demo's value says what else to show: :demo org-block/box folds away the definition of org-block/box, below the rendering; :demo (f v) those of the function f and the variable v, wherever they are defined —a library, or this very document. A live demo, :demo live, keeps no snapshot: its rendering varies by machine, say, so it renders afresh each export and checks nothing; so C-c C-c in it is the block's own, such as a graph's.

Its other switches apply as ever: :let to its source, :folded to the whole showing. With :ignore t, the block is bypassed, so the source is just its contents —the way to demonstrate plain Org, or several blocks at once; as in an example block, a line opening with * or #+ may be escaped by a comma, so a demo may hold headings.

﴾What You Write﴿
/italics/ and [[stutter:2][twice]]
﴾What You Get﴿

italics and twicetwice

13. Callouts —Note, tip, important, warning, caution

Five blocks, after GitHub's alerts, call out a paragraph with a coloured rule down its left under a titled heading; the title defaults to the block's name.

﴾What You Write﴿
#+begin_tip
=C-h k= followed by any key tells us what that key does.
#+end_tip

#+begin_warning Mind the gap
=C-x C-c= quits Emacs, unsaved buffers and all ---it asks first, though.
#+end_warning
﴾What You Get﴿

💡 Tip

C-h k followed by any key tells us what that key does.

⚠️ Mind the gap

C-x C-c quits Emacs, unsaved buffers and all —it asks first, though.

The colours, icons, and intended uses live in org-callouts. Since a heading tagged :note: is common enough to mean something else entirely, callouts claim neither tags nor link types.

Exported to Markdown (ox-md or ox-gfm), a callout becomes GitHub's own alert, > [!WARNING]; since alerts are untitled, a custom title becomes its bold first paragraph. See Markdown export for what the other blocks become.

15. Quotations, cited ---#+begin_quote KEY

Org's own quote block, given a bibliography key, cites it, at its pages —the key given as the main argument, or as :key:

#+begin_quote zermelo1908 :pages 20-22
Set theory is that branch of mathematics whose task is to investigate
the fundamental notions of number, order, and function.
#+end_quote

In LaTeX, and so in beamer, this is csquotes' \blockcquote[20-22]{zermelo1908}{…}, cited by our bibliography —biblatex's \addbibresource, BibTeX's \bibliography, or org-cite— which is ours to give; csquotes itself is loaded for us, unless we load it ourselves. In HTML, it is a <blockquote> closed by Org's own citation, [cite:@zermelo1908, 20-22], so #+print_bibliography: lists the work; in Markdown, a quote closed likewise. A quote sans arguments is Org's own, as ever.

The quoted text hugs its braces, \blockcquote[20-22]{zermelo1908}{Set theory …function.}, sans the stray spaces LaTeX would read from its newlines; so does the contents of any block of ours whose LaTeX wraps it in braces, say (format "\\textbf{%s}" contents).

An inline quotation needs nothing of ours: Org's own "to be" [cite:@shakespeare] serves, smart quotes and all. A section tagged :quote: is a quote of its text.

16. Highlights —Colour the background, not the text

Where red:𝒳 colours text, [[highlight:pink][𝒳]] colours its background; the colour defaults to yellow, and the link shows so highlighted in Emacs too.

﴾What You Write﴿
Skimming readers see [[highlight:yellow][the one sentence that matters]], and [[highlight:pink][the one to reread]].

#+begin_highlight #e5f5e5
A whole paragraph, gently set apart.
#+end_highlight
﴾What You Get﴿

Skimming readers see the one sentence that matters, and the one to reread.

A whole paragraph, gently set apart.


﴾How It’s Implemented﴿
(org-defblock highlight
              (&optional (color "yellow") &allow-other-keys :latex-head ("xcolor") :manual "#Highlights"
               :link [:face (list :background (or (org-string-nw-p label) "yellow"))]
               &context backend raw-contents contents link?)
              "Highlight text with a background of COLOR, which is yellow by default; as a link, it is so highlighted in Emacs too.

  [[highlight:pink][Read this twice.]]

For LaTeX, a hex COLOR such as #e5f5e5 needs no quotes; a block's text is a full-width paragraph box.
In Markdown, the text is <mark>ed, paragraph by paragraph, which GitHub shows yellow whatever COLOR is."
              (pcase (if (org-export-markdown-p) 'md backend)
                ('md (if link?
                         (format "<mark>%s</mark>" contents)
                       (org-parse (format "@@html:<mark>@@%s@@html:</mark>@@"
                                          (s-replace-regexp "\n\n+" "@@html:</mark>@@\n\n@@html:<mark>@@" (s-trim raw-contents))))))
                ('latex (concat (org--latex-define-color "osbe-highlight" color)
                                (if link?
                                    (format "\\colorbox{osbe-highlight}{%s}" contents)
                                  (format "\\colorbox{osbe-highlight}{\\parbox{\\dimexpr\\linewidth-2\\fboxsep}{%s}}" contents))))
                ;; A block's text is paragraphs, which a <span> may not hold.
                (_ (format (if link?
                               "<span style=\"background-color:%s;\">%s</span>"
                             "<div style=\"background-color:%s;\">%s</div>")
                           color contents))))

For the reader who would rather pick the page's background colour themself, [[palette:][Pick a background]] is a button that unfolds a palette of pale colours, org-palette-colors; clicking one makes it the background —try it: .

17. Markdown export —What survives GitHub, and how to change it

Exporting to Markdown, with ox-md or ox-gfm, our blocks see backend as html, since md derives from it; (org-export-markdown-p) tells the two apart. A Markdown renderer, such as GitHub's, keeps only some HTML: it strips every style, class, <style>, and <font>, yet keeps <details>, <kbd>, <mark>, <ins>, <abbr title>, <img>, and $$ maths.

Work as-is
badge, melpa, kbd, details, and solution export just as they do to HTML, and so render on GitHub —sans colours.
Markdown of their own

these blocks export to Markdown idioms, rather than HTML.

Block Markdown export
note, tip, … GitHub's own alert, > [!TIP]; a custom title is a bold line
box a quote, opening with its title in bold
remark a > [!NOTE] alert, titled by its editor
highlight <mark>, which GitHub shows yellow, whatever the colour
spoiler numbered blanks, with the answers folded away beneath
tree $$…$$ displays, as GitHub's maths knows no \[…\]
:demo the source as a code block, then its rendering
doc, tooltip, kbd <abbr> with a plain-text title, as there is no tooltipster
math a fenced math block, its definitions within
graph its image, written to its :file (else graph-HASH.png), linked
Plain HTML
every other block emits the HTML it always does, which a given Markdown renderer may not honour; e.g., on GitHub, colours ---red:𝒳, #+begin_color— and parallel's columns are stripped, leaving plain, stacked text. Then there are palette, #+html_export_style:, and toggle-details, which are HTML-only by design: they dress the page itself, and Markdown has no say over the page.

Dislike how a block B exports to Markdown? Advise org-block/B on your own machine; its result is Org, so the export makes of it whatever it does of any Org. By way of example, boxes between horizontal rules:

(advice-add 'org-block/box :around
            (lambda (box backend raw-contents &rest args)
              "In Markdown, a box is its bold title and text, between rules; elsewhere, as before."
              (if (org-export-markdown-p)
                  (format "-----\n*%s*\n\n%s\n-----" (car args) raw-contents)
                (apply box backend raw-contents args))))

18. PDF export —The LaTeX packages our blocks need, loaded for us

Each block names the LaTeX packages it needs —a box, xcolor and tcolorbox; a cited quote, csquotes— and a LaTeX export that uses the block, or its link, loads them just before \begin{document}. So we declare none ourselves; a package we do load, options and all, is left be. To see what a block needs, read the :latex-head of its definition, or evaluate (get 'org-block/box 'org-latex-head) ⇒ ("xcolor" "tcolorbox").

A test, tests/org-pdf-export-tests.el, keeps this honest: it compiles every example of this manual to a PDF, and to beamer slides, declaring no packages at all. It uses LuaLaTeX, which reads Unicode such as 𝒳 and ⇒ as is; pdflatex instead needs a \newunicodechar for each such character. Slides have no margins, so there our margin notes, tooltips, and Org's footnotes are beamer's own footnotes.


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