diff --git a/org-special-block-extras.org b/org-special-block-extras.org index 0a64dbd..de3d4f1 100644 --- a/org-special-block-extras.org +++ b/org-special-block-extras.org @@ -3607,1353 +3607,1226 @@ In the future, it'd be nice to account for colours for LaTeX as well. ( E.g., src_latex[:exports code]{\color{blue}} is a nightmare. ) #+end_details -* DONE COMMENT Nice Keystroke Renditions: kbd:C-h_h +* COMMENT Colours :PROPERTIES: - :CUSTOM_ID: kbd:nice-keystroke-renditions + :CUSTOM_ID: Colours :END: - -Anyone who writes /about/ Emacs will likely want to mention keystrokes in an -aesthetically pleasing way, such as [[kbd:C-u 80 -]] to insert 80 dashes, -or kbd:C-c_C-e_h_o to export an Org-mode file to HTML, -or the useful . -- ~kbd:𝒳~ will show a tooltip defining 𝒳, as an Emacs Lisp function, if possible. - For example, ~kbd:C-h_h~ is kbd:C-h_h; and likewise == is (we need to use ~<...>~ since punctuation is not picked up as part of link - labels). In contrast, ~kbd:nope~ renders as kbd:nope /without/ a tooltip (nor a - red border). +Let's develop blocks for colouring text and link types for inline colouring; +e.g., [[doc:org-block/color][color]] and [[doc:org-block/teal][teal]]. + + E.g., ~[[brown: Hello, World!]]~ ⇒ [[brown: Hello, World!]] + + E.g., ~brown:Friends!~ + ⇒ brown:Friends! ( Note the ‘!’ is not coloured; use ~[[...]]~ ! ) - You can also supply explicit tooltip description: =[[kbd:key - sequence][description]]= will show as [[kbd:key sequence][description]]; i.e., - the key sequence in nice key font along with a tooltip explaining it. + #+begin_box :background-color custard + Use kbd:M-x_list-colors-display to see a list of defined colour names in Emacs + ---see [[http://muug.ca/mirror/ctan/macros/latex/contrib/xcolor/xcolor.pdf][xcolor]] for the LaTeX side and [[https://htmlcolorcodes.com/color-names/][htmlcolorcodes.com]] for the HTML side, or + just visit http://latexcolor.com/ for both. + # Use =M-: (defined-colors)= to see all colours that are supported on your Emacs. + #+end_box + #+html:
+ :Examples: + #+BEGIN_SRC emacs-lisp :results value :wrap no :tangle no +(s-join "\n\n" +(cl-loop for c in org-special-block-extras/colors + collect (format "#+begin_%s\n This text is %s!\n#+end_%s" c c c))) + #+END_SRC + :End: +#+begin_details A Picture and Block Examples -# To make a screenshot, add the following to the above :PROPERTIES: drawer. -# :UNNUMBERED: t -# -#+attr_html: :width 80% :height 80%s -[[file:./images/kbd.png]] + [[file:images/colours.jpg]] -#+begin_details Implementation + -------------------------------------------------------------------------------- -#+begin_src emacs-lisp -(org-deflink kbd - "Show keysequence O-LABEL in a nice grey button-like font, along with a tooltip of its documentation, if any. + #+begin_parallel + #+begin_black + This text is black! + #+end_black -Such links do not get folded in [[bracket]] style, and are rendered as buttons within Emacs. + #+begin_blue + This text is blue! + #+end_blue -Moreover, O-LABEL may use ‘_’ in-lieu of spaces or [[bracket]] link notation. + #+begin_brown + This text is brown! + #+end_brown -Examples: - [[kbd:C-x C-s]] - ≈ - ≈ kbd:C-x_C-s" - [:display 'full - :let (the-label (s-trim (s-replace "_" " " o-label)) - lisp-func (ignore-errors (cl-second (help--analyze-key (kbd the-label) the-label))) - tooltip (or o-description (ignore-errors (documentation lisp-func)) "") - tooltip? (not (equal tooltip "")) - style (if tooltip? "border-color: red" "") - keystrokes (format "%s" style the-label)) - ;; o-description is always nil when it comes to deciding the :face. - :face (list :inherit 'custom-button :box (if tooltip? "red" t)) - :help-echo (format "%s ∷ %s\n%s" the-label (or lisp-func "") tooltip)] - (if (equal o-backend 'latex) - (format "\\texttt{%s}" the-label) - (if tooltip? - ;; The style=⋯ is to remove the underlining caused by . - (format "%s\">%s" - the-label (or lisp-func "") (org-ospe-html-export-preserving-whitespace tooltip) - keystrokes) - keystrokes))) -#+end_src + # #+begin_cyan + # This text is cyan! + # #+end_cyan -The following styling rule is used to make the keystrokes displayed nicely. -#+begin_src emacs-lisp :noweb-ref enable-mode :tangle no - (defvar org--ospe-kbd-html-setup nil - "Has the necessary keyboard styling HTML beeen added?") + #+begin_darkgray + This text is darkgray! + #+end_darkgray - (unless org--ospe-kbd-html-setup - (setq org--ospe-kbd-html-setup t)) - (when org-special-block-add-html-extra - (setq org-html-head-extra - (concat org-html-head-extra - " - "))) -#+end_src + #+begin_green + This text is green! + #+end_green -Let's have some sanity tests... -#+begin_src emacs-lisp :tangle tests.el :comments link -(deftest "It becomes tags, but final symbol non-ascii *may* be ignored" - [kbd direct-org-links] - (⇝ (⟰ "kbd:C-u_80_-∀") "

\nC-u 80_-∀

")) + #+begin_lightgray + This text is lightgray! + #+end_lightgray -(deftest "[[It]] becomes tags" - [kbd square-org-links] - (⇝ (⟰ "[[kbd:C-u_80_-]]") "

\nC-u 80 -

")) + #+begin_lime + This text is lime! + #+end_lime -(deftest " becomes tags, and surrounding space is trimmed" - [kbd angle-org-links] - (⇝ (⟰ "") "

\nC-u 80 -

")) + #+begin_magenta + This text is magenta! + #+end_magenta -;; FIXME: uh-oh! -(when nil -(deftest "It has a tooltip documenting the underlying Lisp function, when possible" - [kbd tooltip] - (⇝ (⟰ "") + #+begin_olive + This text is olive! + #+end_olive - "Uses the - next face from ‘hi-lock-face-defaults’ without - prompting,
unless you use a prefix argument.
Uses - ‘find-tag-default-as-symbol-regexp’ to retrieve the symbol - at point.

This uses Font lock mode if it is enabled; - otherwise it uses overlays,
in which case the - highlighting will not update as you type. The - Font
Lock mode is considered ''enabled'' in a buffer if - its ‘major-mode’
causes ‘font-lock-specified-p’ to return - non-nil, which means
the major mode specifies support for - Font Lock." - (* anything) - "M-s h .
"))) -#+end_src + #+begin_orange + This text is orange! + #+end_orange -#+end_details + #+begin_pink + This text is pink! + #+end_pink -:Hide: -#+HTML: -#+HTML: -:End: -* DONE COMMENT Parallel ---/Place ideas side-by-side, possibly with a separator/ - :PROPERTIES: - :CUSTOM_ID: Parallel - :END: + #+begin_purple + This text is purple! + #+end_purple - osbe-example:~/org-special-block-extras/tests/parallel.yaml - -#+latex_header: \usepackage{multicol} -#+begin_src emacs-lisp -r -n :title Implementation :folded t -(org-defblock parallel (cols "2" bar nil) - "Place ideas side-by-side, possibly with a separator. + #+begin_red + This text is red! + #+end_red -There are COLS many columns, and they may be seperated by solid -vertical rules if BAR is a non-nil (colour) value. + #+begin_teal + This text is teal! + #+end_teal -+ 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'. + #+begin_violet + This text is violet! + #+end_violet ----------------------------------------------------------------------- + #+begin_white + This text is white! + #+end_white -“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'. + #+begin_yellow + This text is yellow! + #+end_yellow -“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. + #+end_parallel -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 ((rule (pcase backend - (`latex (if bar 2 0)) - (_ (format "%s %s" (if bar "solid" "none") (if (string= bar "t") "black" bar))))) - (contents′ (s-replace "#+columnbreak:" "\\columnbreak" contents))) - (pcase backend - (`latex (format "\\par \\setlength{\\columnseprule}{%s pt} - \\begin{minipage}[t]{\\linewidth} - \\begin{multicols}{%s} - %s - \\end{multicols}\\end{minipage}" rule cols contents′)) - (_ (if (not (s-contains-p "%" cols)) - (format "
%s
" - rule cols contents) - ;; Otherwise: cols ≈ "10% 40% 50%", for example. - (let ((spec (s-split " " (s-collapse-whitespace (s-trim cols)))) - (columnBreak (lambda (width omit-rule?) - (format "
" width - (if omit-rule? "none" rule)))) ) - (format "
%s%s%s
" - (funcall columnBreak (pop spec) nil) - (s-replace-regexp (regexp-quote "#+columnbreak:") - ;; ‘λ’ since we need the “pop” evaluated for each find-replace instance. - ;; We use “not spec” to omit the rule separator when there is NOT anymore elements in SPEC. - (lambda (_) (format "@@html:
%s@@" (funcall columnBreak (pop spec) (not spec)))) - contents) - (if (s-contains-p " " cols) "" "")))))))) -#+end_src + #+end_details -* COMMENT  :fire: HTML Export Styles as Links - :PROPERTIES: - :CUSTOM_ID: HTML-Export-Styles-as-Links - :END: + :Header: +#+BEGIN_SRC emacs-lisp +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Load support for 20 colour custom blocks and 20 colour link types + #+END_SRC + :End: + #+html:
+#+begin_details Implementation of numerous colour blocks/links + We declare a list of colors that should be available on most systems. Then + using this list, we evaluate the code necessary to produce the necessary + functions that format special blocks. - It's annoying to have to introduce HTML into your Org ---especially when - you don't know HTML and don't want to learn it just to have a pretty webpage. - - The annoyance stems from looking around for appropriate CSS files and then - dumping links to them into your Org. - - Ideally, you would use Org and /declaratively/ request a theme ---from a - pre-compiled list of themes, which you can add to. - - Now you can! Just write =html-export-style:𝑻𝑯𝑬𝑴𝑬= anywhere in your Org file. - + In Emacs, hover over this new link type to see a list of supported themes. - + By default, we ship themes: =stylish_white solarized_light solarized_dark= - =simple_gray retro_dark simple_whiteblue rethink_inline imagine_light= - =comfy_inline default bigblow readtheorg rose latexcss=. - # src_emacs-lisp[:exports results]{(mapcar #'car org-html-export-styles)}. + # - To add support for a colour =𝒞=, simply + # ~(push '𝒞 org--ospe-colors)~. + # # - #+begin_src emacs-lisp -(defvar org--html-export-style-choice "default" - "This variable holds the link label declared by users. - It is used in the hook to Org's reprocessing; `org--html-export-style-setup'.") + By default, Org uses the ~graphicx~ LaTeX package which let's us colour text + ---see its documentation [[http://ctan.mirror.rafal.ca/macros/latex/required/graphics/grfguide.pdf][here]]. For example, in an ~#+begin_export latex~ block, + the following produces blue coloured text. + #+begin_example latex +{ \color{blue} This is a sample text in blue. } + #+end_example + # Below, we format colour block types to essentially format block contents like + # this. -(defvar org-html-export-styles - `((default . "") - (bigblow . "#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-bigblow.setup") - (readtheorg . "#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup") - (rose . "#+HTML_HEAD: ") - (latexcss . "#+HTML_HEAD: ")) - "An alist of theme-to-setup pairs, symbols-to-strings, used by `org-link/html-export-style'. + #+BEGIN_SRC emacs-lisp +(defvar org--ospe-colors + '(black blue brown cyan darkgray gray green lightgray lime + magenta olive orange pink purple red teal violet white + yellow) + "Colours that should be available on all systems.") - For live examples of many of the themes, see - https://olmon.gitlab.io/org-themes/. +(cl-loop for colour in org--ospe-colors + do (eval `(org-defblock ,colour + (the-color "black") + (vector :face `(:foreground ,(format "%s" (quote ,colour)))) + ,(format "Show text in %s color." colour) + (let () + (format (pcase backend + (`latex "\\begingroup\\color{%s}%s\\endgroup\\,") + (_ "%s")) + (quote ,colour) contents))))) + #+END_SRC - In due time, I would like to add more, such as those linked from - the discussion https://news.ycombinator.com/item?id=23130104. - A nice, simple, opportunity for someone else to contribute.") -;; -;; Add a bunch more -(cl-loop for theme in '(comfy_inline imagine_light - rethink_inline simple_whiteblue - retro_dark simple_gray solarized_dark - solarized_light stylish_white) - do (push (cons theme (format "#+SETUPFILE: https://gitlab.com/OlMon/org-themes/-/raw/master/src/%s/%s.theme" theme theme)) org-html-export-styles)) + #+RESULTS: -(defun org--html-export-style-setup (_backend) - "Insert an HTML theme link setup, according to `org-html-export-styles'." - (save-excursion - (goto-char (point-min)) - (-> (or (assoc org--html-export-style-choice org-html-export-styles) - (error "Error: Unknown html-export-style ∷ %s ∉ '%s" - org--html-export-style-choice - (-cons* 'random 'default (mapcar 'car org-html-export-styles)))) - cdr - (format "\n %s \n") - insert))) +Let's have some sanity tests... +#+begin_src emacs-lisp :tangle tests.el :comments link +(deftest "It is an HTML span styled red that contains the user's text" + [color red block] + (⇝ (⟰ "#+begin_red + My cool thoughts... + ,#+end_red") + "" + (* anything) + "My cool thoughts" + (* anything) + "")) -(org-deflink html-export-style - "Add a dedicated style theme, from `org-html-export-styles'." - [:face '(:underline "green") - :keymap ("?" ;; Let use select new choice of style with the “?” key. - (-let [choice (completing-read - "New HTML style: " - (cons "random" (--map (pp-to-string (car it)) org-html-export-styles)))] - (save-excursion - (beginning-of-line) - (while (re-search-forward - (rx (seq "html-export-style:" (one-or-more word))) nil t) - (replace-match (concat "html-export-style:" choice)))))) - :help-echo (thread-last (cons "random" (--map (pp-to-string (car it)) org-html-export-styles)) - (-partition 4) - (--map (s-join " " it)) - (s-join "\n") - (format "Press “?” to change the theme. \n\n Supported themes include:\n\n%s")) - :let (whatdo (progn - (setq org--html-export-style-choice - (if (equal "random" o-label) - (seq-random-elt (mapcar 'car org-html-export-styles)) - (intern o-label))) - (pcase o-label - ;; TODO: Move this to when the mode is enabled/disabled? - ("default" (remove-hook 'org-export-before-processing-hook - 'org--html-export-style-setup)) - (_ (add-hook 'org-export-before-processing-hook - 'org--html-export-style-setup))))) - ] - ;; Result string, nothing. - "") +;; We have an HTML span styled with the user's color and it contains the user's text +(deftest "It works as expected" + [color pink block] + (⇝ (⟰ "#+begin_color pink + My cool thoughts... + ,#+end_color") + "" + (* anything) + "My cool thoughts" + (* anything) + "")) #+end_src -# html-export-style:solarized_light -* COMMENT Fortune Links: Smiles inside and outside of Emacs - :PROPERTIES: - :CUSTOM_ID: Fortune-Links-Smiles-inside-and-outside-of-Emacs - :END: - -Sometimes we need a smile, or a fortune, and want it with a nice graphic ---all -in Emacs. Enter ~fortune:𝒳~ links! -- These yield colourful graphics /both/ in Emacs and in HTML export. - + Click on the link to see it in action, in Emacs. -- Here is an example of ~fortune:joke~. fortune:joke - -# - An example usage in blog articles would be the ~[[fortune:ANIMAL][PHRASE]]~ -# syntax: -# [[fortune:cow][howdy buddo]] -# -# TODO: This is busted? Maybe make a Github Issue; looks like an easy thing for -# other new contributors. - -#+begin_src emacs-lisp -(org-deflink fortune - "Print an ASCII animal saying the given link's description, a fortune, or a joke. - -This is essentially a wrapper around the following command-line incantation - - fortune | cowsay | lolcat -f - -We show colourful sayings both in Emacs (when you click on the link) and in HTML export. - -This requires you have the command-line packages ‘fortune’, ‘cowsay’, ‘lolcat’, -and ‘aha’ for converting coloured terminal output into HTML. -On MacOS, all of these can be installed with `brew install 𝒳'; -better-yet use the Emacs Lisp `system-packages-install' package. - -The help-echo, hover tooltip, provides useful information on possibly link types and their effects. + :Old: + #+BEGIN_SRC emacs-lisp :tangle no +(defvar org--ospe-colors + '(black blue brown cyan darkgray gray green lightgray lime + magenta olive orange pink purple red teal violet white + yellow) + "Colours that should be available on all systems.") -Example uses: +(cl-loop for colour in org--ospe-colors + do (eval (read (format + "(defun org--%s (backend contents) + (format (pcase backend + (`latex \"\\\\begingroup\\\\color{%s}%%s\\\\endgroup\\\\,\") + (_ \"%%s\")) + contents))" + colour colour colour)))) + #+END_SRC + :End: - fortune:joke ;; Show a random animal saying a punny joke + #+end_details - fortune:random ;; Show a random animal saying a random fortune/phrase - fortune:dragon ;; Show a dragon saying a random fortune/phrase + #+html:
+ #+begin_details Implementation of ‘color’ + For faster experimentation between colours, we provide a generic =color= block + that consumes a color argument. - ;; Show a the given animal saying the given phrase - [[fortune:mutilated][Opps, I broke the thing!]] + #+begin_src emacs-lisp +(org-defblock color + (color black) + (vector :face (lambda (colour) `(:foreground ,(format "%s" colour)))) + "Format text according to a given COLOR, which is black by default." + (format (pcase backend + (`latex "\\begingroup\\color{%s}%s\\endgroup\\,") + (`html "%s")) + color contents)) + #+end_src - ;; The ‘fortune’ link grew out of the following link in my work journal - [[elisp:(dad-joke-get)][I wanna smile!]] +[Posterity] Old version which did /not/ allow ~wombo~ colour: + #+begin_src emacs-lisp :tangle no +(org-defblock color (color black :face (lambda (colour) + (if (member (intern colour) org--ospe-colors) + `(:foreground ,(format "%s" colour)) + `(:height 300 + :underline (:color "red" :style wave) + :overline "red" :strike-through "red")))) nil + "Format text according to a given COLOR, which is black by default." + (format (pcase backend + (`latex "\\begingroup\\color{%s}%s\\endgroup\\,") + (`html "%s")) + color contents)) + #+end_src -For HTML export, the resulting HTML element has class ‘org-fortune’, -to which users may adorn CSS styling. For instance, in an Org file: + #+RESULTS: - ,#+html: - # Chalkduster font-family is good for one-line sayings, phrases. + :Old: + #+begin_src emacs-lisp :tangle no +(defun org--color (backend contents) + "Format CONTENTS according to the ‘:color:’ they specify for BACKEND." + (-let* (((contents′ . (&alist 'color)) + (org--extract-arguments contents 'color)) + (block-coloring + (intern (format "org--%s" (s-trim color))))) + (if (member (intern (s-trim color)) org--ospe-colors) + (funcall block-coloring backend contents′) + (error "Error: “#+begin_color:%s” ⇒ Unsupported colour!" color)))) + #+end_src + :End: + #+end_details -We intentionally do not fold-up such links when they have associated descriptions. + Moreover, we have that the syntax =red:text= /renders/ ‘text’ with the colour red + in *both* the Emacs interface and in exported backends. -When you click, it takes a seconds to fetch jokes; so await a moment when hovering over joke fortunes." - [:display 'full - :face '(:box (:color "orange" :style released-button) :underline "green" :overline "green") - :let (animals '(blowfish bud-frogs cower default dragon - dragon-and-cow flaming-sheep ghostbusters - moose mutilated sheep stegosaurus turkey - turtle tux) - animal (if (string-equal "cow" (s-trim o-label)) - 'default - (seq-random-elt animals)) - animal₀ (if (equal 'default animal) 'cow animal) - _loads (progn (require 'dad-joke) (require 'seq) (require 'lolcat)) - saying (cond - (o-description (format "echo %s" (pp-to-string o-description))) - ((equal "joke" (s-trim o-label)) (format "echo %s" (pp-to-string (dad-joke-get)))) - (:otherwise "fortune")) - result (format "%s\t\t\t%s" - (shell-command-to-string (format "%s | cowsay -f %s" saying animal)) - animal₀) - buf-name (format "fortune:%s" animal₀)) - :follow (progn (display-message-or-buffer result) - (ignore-errors (kill-buffer buf-name)) - (switch-to-buffer-other-window "*Message*") - (rename-buffer buf-name) - (highlight-regexp (format "%s" animal₀) 'hi-green-b) - (lolcat-this-buffer) - (local-set-key "q" #'kill-buffer-and-window) - (message "“q” to kill buffer and window.")) - :help-echo (s-join "\n" (list "“fortune:𝒳” or “[[fortune:𝒳][description 𝒟]]” where 𝒳 is " - "⇢ joke ⟦A random animal that says a punny joke⟧" - "⇢ random ⟦A random animal that says 𝒟, or a random fortune phrase⟧" - "⇢ ⟦This animal says 𝒟, or a random fortune phrase⟧" - "\t cow, blowfish, bud-frogs, cower, dragon, dragon-and-cow," - "\t flaming-sheep, ghostbusters, moose, mutilated, sheep," - "\t stegosaurus, turkey, turtle tux" - "\n" - "\n" result)) - ] - (if (equal o-backend 'html) - (--> (shell-command-to-string (format "%s | cowsay -f %s | lolcat -f | aha -n" saying animal)) - (if (s-starts-with? "/System/Library" it) - (s-join "\n" (cdr (s-split "\n" it))) - it) - (format "%s\t\t\t%s" it animal₀) - (format "
 %s 
" it)) - result)) -#+end_src + [[file:images/colour_links.png]] -* COMMENT Editor Comments - :PROPERTIES: - :CUSTOM_ID: editor-comments - :END: + :Old: + #+begin_src emacs-lisp :tangle no +;; [[𝒞:text₀][text₁]] ⇒ Colour ‘textₖ’ by 𝒞, where k is 1, if present, otherwise 0. +;; If text₁ is present, it is suggested to use ‘color:𝒞’, defined below. +(cl-loop for colour in org--ospe-colors + do (org-link-set-parameters + (format "%s" colour) + :follow `(lambda (path) (message "Colouring “%s” %s." path (quote ,colour))) + :export `(lambda (label description backend) + (-let [block-colouring + (intern (format "org--%s" (quote ,colour)))] + (funcall block-colouring backend (or description label)))) + :face `(:foreground ,(format "%s" colour)))) - “Editor Comments” are intended to be top-level first-class comments in an - article that are inline with the surrounding text and are delimited in such a - way that they are visible but drawing attention. I first learned about this - idea from Wolfram Kahl ---who introduced me to Emacs many years ago. We -# implement editor comments as special blocks named [[doc:org--remark][remark]]. +;; Generic ‘color’ link type [[color:𝒞][text]] ⇒ Colour ‘text’ by 𝒞. +;; If 𝒞 is an unsupported colour, ‘text’ is rendered in large font +;; and surrounded by red lines. +(org-link-set-parameters "color" + :follow (lambda (_)) + :face (lambda (colour) + (if (member (intern colour) org--ospe-colors) + `(:foreground ,(format "%s" colour)) + `(:height 300 + :underline (:color "red" :style wave) + :overline "red" :strike-through "red"))) + :help-echo (lambda (_ __ position) + (save-excursion + (goto-char position) + (-let* (((&plist :path) (cadr (org-element-context)))) + (if (member (intern path) org--ospe-colors) + "Colour links just colour the descriptive text" + (format "Error: “color:%s” ⇒ Unsupported colour!" path))))) + :export (lambda (colour description backend) + (-let [block-colouring + (intern (format "org-block/%s" colour))] + (if (member (intern colour) org--ospe-colors) + (funcall block-colouring backend description) + (error "Error: “color:%s” ⇒ Unsupported colour!" colour))))) + #+end_src + :End: -#+begin_box Example + #+begin_center + Observe: red:this green:is cyan:super teal:neato, purple:amigos! and [[color:brown][this is brown ‘color’ link]] and [[color:orange][this one is an orange ‘color’ link!]] -#+begin_parallel -_This_ + +Also: If we try to use an unsupported colour ‘wombo’, we render the+ + +descriptive text larger in Emacs along with a tooltip explaining why this is + the case; e.g., =[[color:wombo][hi]]=.+ -#+begin_src org :tangle no :tangle no - In LaTeX, a =remark= appears inline with the text surrounding it. - ,#+begin_remark Bobert - org-mode is dope, yo! - ,#+replacewith: - Org-mode is essentially a path toward enlightenment. - ,#+end_remark - Unfortunately, in the HTML rendition, the =remark= is its own paragraph and thus - separated by new lines from its surrounding text. -#+end_src + ~[[color:#fad][Using Hex colour code!]]~ ⇒ [[color:#fad][Using Hex colour code!]] ;-) + #+end_center -#+html:


+ #+latex: \vspace{1em} + [[color:orange][Moreover,]] it would be nice to extend the =color= block type to take multiple + arguments, say, =c₁ c₂ … cₙ= such that: -_Yields_ + | /n/ | Behaviour | + |---+------------------------------------------------------------------------------------| + | 0 | No colouring; likewise if no arguments altogether | + | 1 | Colour all entries using the given colour c₁ | + | /n/ | Paragraph --region separated by a new line-- =i= is coloured by =cₖ= where =k = i mod n= | - In LaTeX, an =remark= appears inline with the text surrounding it. - #+begin_remark Bobert - org-mode is dope, yo! - #+replacewith: - Org-mode is essentially a path toward enlightenment. - #+end_remark - Unfortunately, in the HTML rendition, the =remark= is its own paragraph and thus - separated by new lines from its surrounding text. -#+end_parallel -#+end_box + Besides having a colourful article, another usage I envision for this + generalisation would be when rendering text in multiple languages; e.g., use red + and blue to interleave Arabic poetry with its English translation. + +* DONE COMMENT   ~latex-definitions~ for hiding LaTeX declarations in HTML + :PROPERTIES: + :CUSTOM_ID: latex-definitions-for-hiding-LaTeX-declarations-in-HTML + :END: -:Pics_old: - #+caption: In order: Chrome, Emacs Web Wowser, Org source, PDF - [[file:images/edcomm.png]] -:End: + To present mathematical formulae in HTML export, we may use + LaTeX-style commands such as ~{\color{red} x}~ by enclosing them in + =$=-symbols to obtain ${\color{red}x}$. This is known as the MathJax + tool ---Emacs' default HTML export includes it. (Unfortunately, + MathJax does not directly support arbitrary HTML elements to occur + within the =$=-delimiters.) -# | /Any new ---possibly empty--- inner lines in the =remark= are desirably preserved/ | + #+latex: \vspace{1em} + It is common to declare LaTeX definitions for convenience, but such + declarations occur within ~$~-delimiters and thereby produce + undesirable extra whitespace. See the superflous vertical whitespace + in the =Result= side below. + + #+begin_org-demo :source-color "custard" :result-color "custard" + Hello, in this blog post I'd like to talk about quantifiers. + # First, I'll define some helpers that I use multiple times... + $$ + \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 [[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]]. + #+end_org-demo - #+begin_details "Implementing ‘remark’, from §ection 1, with more bells and whistles" :title-color pink - #+BEGIN_SRC emacs-lisp -(defvar org-hide-editor-comments nil - "Should editor comments be shown in the output or not.") + As such, we declare the [[doc:org-block/latex-definitions][latex-definitions]] block type which avoids + displaying such extra whitespace in the resulting HTML. -(org-defblock remark - (editor "Editor Remark" color "black" signoff "" strong nil) -; :inline-please__see_margin_block_for_a_similar_incantation ; ⇒ crashes! -[:face '(:foreground "red" :weight bold)] -"Format CONTENTS as an first-class editor comment according to BACKEND. + # (setq osbe-example-yaml-cache (make-hash-table :test 'equal)) + osbe-example:~/org-special-block-extras/tests/latex-definitions.yaml + + #+begin_src emacs-lisp :title "‘latex-definitions’ Implementation" :folded t +(org-defblock latex-definitions () + "Declare but do not display the CONTENTS according to the BACKEND." + (format (pcase backend + ('html "

\\[%s\\]

") + (_ "%s")) + raw-contents)) + #+end_src -The CONTENTS string has an optional switch: If it contains a line -with having only ‘#+replacewith:’, then the text preceding this -clause should be replaced by the text after it; i.e., this is -what the EDITOR (the person editing) intends and so we fromat the -replacement instruction (to the authour) as such. +* DONE COMMENT Nice Keystroke Renditions: kbd:C-h_h + :PROPERTIES: + :CUSTOM_ID: kbd:nice-keystroke-renditions + :END: + +Anyone who writes /about/ Emacs will likely want to mention keystrokes in an +aesthetically pleasing way, such as [[kbd:C-u 80 -]] to insert 80 dashes, +or kbd:C-c_C-e_h_o to export an Org-mode file to HTML, +or the useful . -In Emacs, as links, editor remarks are shown with a bold red; but -the exported COLOR of a remark is black by default and it is not -STRONG ---i.e., bold---. There is an optional SIGNOFF message -that is appended to the remark. -" - (-let* (;; Are we in the html backend? - (tex? (equal backend 'latex)) +- ~kbd:𝒳~ will show a tooltip defining 𝒳, as an Emacs Lisp function, if possible. + For example, ~kbd:C-h_h~ is kbd:C-h_h; and likewise == is (we need to use ~<...>~ since punctuation is not picked up as part of link + labels). In contrast, ~kbd:nope~ renders as kbd:nope /without/ a tooltip (nor a + red border). - ;; fancy display style - (boxed (lambda (x) - (if tex? - (concat "\\fbox{\\bf " x "}") - (concat "" - "" x "")))) + You can also supply explicit tooltip description: =[[kbd:key + sequence][description]]= will show as [[kbd:key sequence][description]]; i.e., + the key sequence in nice key font along with a tooltip explaining it. - ;; Is this a replacement clause? - ((this that) (s-split "\\#\\+replacewith:" contents)) - (replacement-clause? that) ;; There is a ‘that’ - (replace-keyword (if tex? - "\\underline{Replace:}" " Replace:")) - (with-keyword (if tex? "\\underline{With:}" "With:" - )) - (editor (format "[%s:%s" editor - (if replacement-clause? - replace-keyword - ""))) - (contents′ (if replacement-clause? - (format "%s %s %s" this - (org-export (funcall boxed with-keyword)) - that) - contents)) - ;; “[Editor Comment:” - (edcomm-begin (funcall boxed editor)) - ;; “]” - (edcomm-end (funcall boxed "]"))) +# To make a screenshot, add the following to the above :PROPERTIES: drawer. +# :UNNUMBERED: t +# +#+attr_html: :width 80% :height 80%s +[[file:./images/kbd.png]] - (setq org-export-allow-bind-keywords t) ;; So users can use “#+bind” immediately - (if org-hide-editor-comments - "" - (format (pcase backend - ('latex (format "{\\color{%%s}%s %%s %%s %%s %%s}" (if strong "\\bfseries" ""))) - (_ (format "<%s style=\"color: %%s;\">%%s %%s %%s %%s" (if strong "strong" "p") (if strong "strong" "p")))) - color edcomm-begin contents′ signoff edcomm-end)))) - #+END_SRC +#+begin_details Implementation - #+RESULTS: - | :face | (:foreground red :weight bold) | :export | (lambda (label description backend) (s-replace-all `((@@ . )) (org--remark backend (or description label) label :o-link? t))) | :help-echo | (lambda (window object position) (save-excursion (goto-char position) (-let* (((&plist :path :format :raw-link :contents-begin :contents-end) (cadr (org-element-context))) (description (when (equal format 'bracket) (copy-region-as-kill contents-begin contents-end) (substring-no-properties (car kill-ring))))) (format %s | +#+begin_src emacs-lisp +(org-deflink kbd + "Show keysequence O-LABEL in a nice grey button-like font, along with a tooltip of its documentation, if any. +Such links do not get folded in [[bracket]] style, and are rendered as buttons within Emacs. +Moreover, O-LABEL may use ‘_’ in-lieu of spaces or [[bracket]] link notation. - :Older_version: - #+BEGIN_SRC emacs-lisp :tangle no -(defvar org-hide-editor-comments nil - "Should editor comments be shown in the output or not.") +Examples: + [[kbd:C-x C-s]] + ≈ + ≈ kbd:C-x_C-s" + [:display 'full + :let (the-label (s-trim (s-replace "_" " " o-label)) + lisp-func (ignore-errors (cl-second (help--analyze-key (kbd the-label) the-label))) + tooltip (or o-description (ignore-errors (documentation lisp-func)) "") + tooltip? (not (equal tooltip "")) + style (if tooltip? "border-color: red" "") + keystrokes (format "%s" style the-label)) + ;; o-description is always nil when it comes to deciding the :face. + :face (list :inherit 'custom-button :box (if tooltip? "red" t)) + :help-echo (format "%s ∷ %s\n%s" the-label (or lisp-func "") tooltip)] + (if (equal o-backend 'latex) + (format "\\texttt{%s}" the-label) + (if tooltip? + ;; The style=⋯ is to remove the underlining caused by . + (format "%s\">%s" + the-label (or lisp-func "") (org-ospe-html-export-preserving-whitespace tooltip) + keystrokes) + keystrokes))) +#+end_src -(defun org--edcomm (backend contents) -"Format CONTENTS as an first-class editor comment according to BACKEND. +The following styling rule is used to make the keystrokes displayed nicely. +#+begin_src emacs-lisp :noweb-ref enable-mode :tangle no + (defvar org--ospe-kbd-html-setup nil + "Has the necessary keyboard styling HTML beeen added?") -The CONTENTS string has two optional argument switches: -1. :ed: ⇒ To declare an editor of the comment. -2. :replacewith: ⇒ [Nullary] The text preceding this clause - should be replaced by the text after it." - (-let* ( - ;; Get arguments - ((contents₁ . (&alist 'ed)) - (org--extract-arguments contents 'ed)) + (unless org--ospe-kbd-html-setup + (setq org--ospe-kbd-html-setup t)) + (when org-special-block-add-html-extra + (setq org-html-head-extra + (concat org-html-head-extra + " + "))) +#+end_src - ;; Are we in the html backend? - (html? (equal backend 'html)) +Let's have some sanity tests... +#+begin_src emacs-lisp :tangle tests.el :comments link +(deftest "It becomes tags, but final symbol non-ascii *may* be ignored" + [kbd direct-org-links] + (⇝ (⟰ "kbd:C-u_80_-∀") "

\nC-u 80_-∀

")) - ;; fancy display style - (boxed (lambda (x) - (if html? - (concat "" - "" x "") - (concat "\\fbox{\\bf " x "}")))) +(deftest "[[It]] becomes tags" + [kbd square-org-links] + (⇝ (⟰ "[[kbd:C-u_80_-]]") "

\nC-u 80 -

")) - ;; Is this a replacement clause? - ((this that) (s-split ":replacewith:" contents₁)) - (replacement-clause? that) ;; There is a ‘that’ - (replace-keyword (if html? " Replace:" - "\\underline{Replace:}")) - (with-keyword (if html? "With:" - "\\underline{With:}")) - (editor (format "[%s:%s" - (if (s-blank? ed) "Editor Comment" ed) - (if replacement-clause? - replace-keyword - ""))) - (contents₂ (if replacement-clause? - (format "%s %s %s" this - (funcall boxed with-keyword) - that) - contents₁)) +(deftest " becomes tags, and surrounding space is trimmed" + [kbd angle-org-links] + (⇝ (⟰ "") "

\nC-u 80 -

")) - ;; “[Editor Comment:” - (edcomm-begin (funcall boxed editor)) - ;; “]” - (edcomm-end (funcall boxed "]"))) +;; FIXME: uh-oh! +(when nil +(deftest "It has a tooltip documenting the underlying Lisp function, when possible" + [kbd tooltip] + (⇝ (⟰ "") - (setq org-export-allow-bind-keywords t) ;; So users can use “#+bind” immediately - (if org-hide-editor-comments - "" - (format (pcase backend - ('latex "%s %s %s") - (_ "

%s %s %s

")) - edcomm-begin contents₂ edcomm-end)))) - #+END_SRC -:End: + "Uses the + next face from ‘hi-lock-face-defaults’ without + prompting,
unless you use a prefix argument.
Uses + ‘find-tag-default-as-symbol-regexp’ to retrieve the symbol + at point.

This uses Font lock mode if it is enabled; + otherwise it uses overlays,
in which case the + highlighting will not update as you type. The + Font
Lock mode is considered ''enabled'' in a buffer if + its ‘major-mode’
causes ‘font-lock-specified-p’ to return + non-nil, which means
the major mode specifies support for + Font Lock." + (* anything) + "M-s h .
"))) +#+end_src - In the HTML export, the =edcomm= special block is /not/ in-line with the text - surrounding it ---ideally, it would be inline so that existing paragraphs are - not split into multiple paragraphs but instead have an editor's comment - indicating suggested alterations. +#+end_details +:Hide: +#+HTML: +#+HTML: +:End: +* DONE COMMENT Parallel ---/Place ideas side-by-side, possibly with a separator/ + :PROPERTIES: + :CUSTOM_ID: Parallel + :END: + osbe-example:~/org-special-block-extras/tests/parallel.yaml + +#+latex_header: \usepackage{multicol} +#+begin_src emacs-lisp -r -n :title Implementation :folded t +(org-defblock parallel (cols "2" bar nil) + "Place ideas side-by-side, possibly with a separator. -Let's have some sanity tests... -#+begin_src emacs-lisp :tangle tests.el :comments link -(deftest "The user's remark is enclosed in the default delimiters" - [remark] - (⇝ (⟰ "#+begin_remark - Here is some meta-commentary... - ,#+end_remark") - (* anything) "[Editor Remark:" - (* anything) "Here is some meta-commentary" - (* anything) "]")) +There are COLS many columns, and they may be seperated by solid +vertical rules if BAR is a non-nil (colour) value. -;; The other features of remark blocks should be tested; -;; but this is not a pressing, nor interesting, concern. -#+end_src ++ 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'. - #+end_details +---------------------------------------------------------------------- --------------------------------------------------------------------------------- +“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'. -#+begin_details Example: No optional arguments - #+begin_remark - /Please/ *change* _this_ section to be more, ya know, professional. - #+end_remark +“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. --------------------------------------------------------------------------------- -*Source:* -#+begin_src org :tangle no - ,#+begin_remark - /Please/ *change* _this_ section to be more, ya know, professional. - ,#+end_remark -#+end_src -#+end_details -#+begin_details "Example: Only providing a main argument ---i.e., the remark author, the editor" - #+begin_remark Bobert - /Please/ *change* _this_ section to be more, ya know, professional. - #+end_remark + ,#+begin_parallel 20% 60% 20% :bar green + Hello, to the left! - #+latex: \vspace{1em}\noindent --------------------------------------------------------------------------------- -*Source:* -#+begin_src org :tangle no - ,#+begin_remark Bobert - /Please/ *change* _this_ section to be more, ya know, professional. - ,#+end_remark -#+end_src + ,#+columnbreak: + A super duper wide middle margin! -#+end_details -#+begin_details Example: Possibly with no contents: - #+begin_remark Bobert - #+end_remark --------------------------------------------------------------------------------- -*Source:* -#+begin_src org :tangle no - ,#+begin_remark Bobert - ,#+end_remark -#+end_src -#+end_details -#+begin_details "Example: Empty contents, no authour, nothing" - #+begin_remark - #+end_remark - -------------------------------------------------------------------------------- -*Source:* -#+begin_src org :tangle no - ,#+begin_remark - ,#+end_remark -#+end_src -#+end_details -#+latex: \vspace{1em}\noindent -#+begin_details Example: Possibly with an empty new line - #+begin_remark + ,#+columnbreak: + Goodbye (“God-be-with-ye”) to the right! + ,#+end_parallel - #+end_remark --------------------------------------------------------------------------------- -*Source:* -#+begin_src org :tangle no - ,#+begin_remark +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. - ,#+end_remark -#+end_src -#+end_details -#+latex: \iffalse -#+begin_details "Example: With a “#+replacewith:” clause" - #+begin_remark - The two-dimensional notation; e.g., $\sum_{i = 0}^n i^2$ - #+replacewith: - A linear one-dimensional notation; e.g., - $(\Sigma i : 0..n \;\bullet\; i^2)$ - #+end_remark --------------------------------------------------------------------------------- -*Source:* -#+begin_src org :tangle no - ,#+begin_remark - The two-dimensional notation; e.g., $\sum_{i = 0}^n i^2$ - ,#+replacewith: - A linear one-dimensional notation; e.g., - $(\Sigma i : 0..n \;\bullet\; i^2)$ - ,#+end_remark +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 ((rule (pcase backend + (`latex (if bar 2 0)) + (_ (format "%s %s" (if bar "solid" "none") (if (string= bar "t") "black" bar))))) + (contents′ (s-replace "#+columnbreak:" "\\columnbreak" contents))) + (pcase backend + (`latex (format "\\par \\setlength{\\columnseprule}{%s pt} + \\begin{minipage}[t]{\\linewidth} + \\begin{multicols}{%s} + %s + \\end{multicols}\\end{minipage}" rule cols contents′)) + (_ (if (not (s-contains-p "%" cols)) + (format "
%s
" + rule cols contents) + ;; Otherwise: cols ≈ "10% 40% 50%", for example. + (let ((spec (s-split " " (s-collapse-whitespace (s-trim cols)))) + (columnBreak (lambda (width omit-rule?) + (format "
" width + (if omit-rule? "none" rule)))) ) + (format "
%s%s%s
" + (funcall columnBreak (pop spec) nil) + (s-replace-regexp (regexp-quote "#+columnbreak:") + ;; ‘λ’ since we need the “pop” evaluated for each find-replace instance. + ;; We use “not spec” to omit the rule separator when there is NOT anymore elements in SPEC. + (lambda (_) (format "@@html:
%s@@" (funcall columnBreak (pop spec) (not spec)))) + contents) + (if (s-contains-p " " cols) "" "")))))))) #+end_src -#+end_details -#+latex: \fi -#+latex: \vspace{1em}\noindent -#+begin_details Example: Possibly “malformed” replacement clauses - -Forgot the thing to be replaced… -#+begin_remark -#+replacewith: -A linear one-dimensional notation; e.g., -$(\Sigma i : 0..n \;\bullet\; i^2)$ -#+end_remark +* COMMENT  :fire: HTML Export Styles as Links + :PROPERTIES: + :CUSTOM_ID: HTML-Export-Styles-as-Links + :END: --------------------------------------------------------------------------------- + It's annoying to have to introduce HTML into your Org ---especially when + you don't know HTML and don't want to learn it just to have a pretty webpage. + - The annoyance stems from looking around for appropriate CSS files and then + dumping links to them into your Org. + - Ideally, you would use Org and /declaratively/ request a theme ---from a + pre-compiled list of themes, which you can add to. + - Now you can! Just write =html-export-style:𝑻𝑯𝑬𝑴𝑬= anywhere in your Org file. + + In Emacs, hover over this new link type to see a list of supported themes. + + By default, we ship themes: =stylish_white solarized_light solarized_dark= + =simple_gray retro_dark simple_whiteblue rethink_inline imagine_light= + =comfy_inline default bigblow readtheorg rose latexcss=. + # src_emacs-lisp[:exports results]{(mapcar #'car org-html-export-styles)}. -Forgot the new replacement thing… + #+begin_src emacs-lisp +(defvar org--html-export-style-choice "default" + "This variable holds the link label declared by users. + It is used in the hook to Org's reprocessing; `org--html-export-style-setup'.") -#+begin_remark - The two-dimensional notation; e.g., $\sum_{i = 0}^n i^2$ - #+replacewith: -#+end_remark +(defvar org-html-export-styles + `((default . "") + (bigblow . "#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-bigblow.setup") + (readtheorg . "#+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup") + (rose . "#+HTML_HEAD: ") + (latexcss . "#+HTML_HEAD: ")) + "An alist of theme-to-setup pairs, symbols-to-strings, used by `org-link/html-export-style'. --------------------------------------------------------------------------------- + For live examples of many of the themes, see + https://olmon.gitlab.io/org-themes/. -Completely lost one's train of thought… -#+begin_parallel - #+begin_remark - #+replacewith: - #+end_remark + In due time, I would like to add more, such as those linked from + the discussion https://news.ycombinator.com/item?id=23130104. + A nice, simple, opportunity for someone else to contribute.") +;; +;; Add a bunch more +(cl-loop for theme in '(comfy_inline imagine_light + rethink_inline simple_whiteblue + retro_dark simple_gray solarized_dark + solarized_light stylish_white) + do (push (cons theme (format "#+SETUPFILE: https://gitlab.com/OlMon/org-themes/-/raw/master/src/%s/%s.theme" theme theme)) org-html-export-styles)) -#+columnbreak: -*Source:* +(defun org--html-export-style-setup (_backend) + "Insert an HTML theme link setup, according to `org-html-export-styles'." + (save-excursion + (goto-char (point-min)) + (-> (or (assoc org--html-export-style-choice org-html-export-styles) + (error "Error: Unknown html-export-style ∷ %s ∉ '%s" + org--html-export-style-choice + (-cons* 'random 'default (mapcar 'car org-html-export-styles)))) + cdr + (format "\n %s \n") + insert))) -#+begin_src org :tangle no - ,#+begin_remark - ,#+replacewith: - ,#+end_remark +(org-deflink html-export-style + "Add a dedicated style theme, from `org-html-export-styles'." + [:face '(:underline "green") + :keymap ("?" ;; Let use select new choice of style with the “?” key. + (-let [choice (completing-read + "New HTML style: " + (cons "random" (--map (pp-to-string (car it)) org-html-export-styles)))] + (save-excursion + (beginning-of-line) + (while (re-search-forward + (rx (seq "html-export-style:" (one-or-more word))) nil t) + (replace-match (concat "html-export-style:" choice)))))) + :help-echo (thread-last (cons "random" (--map (pp-to-string (car it)) org-html-export-styles)) + (-partition 4) + (--map (s-join " " it)) + (s-join "\n") + (format "Press “?” to change the theme. \n\n Supported themes include:\n\n%s")) + :let (whatdo (progn + (setq org--html-export-style-choice + (if (equal "random" o-label) + (seq-random-elt (mapcar 'car org-html-export-styles)) + (intern o-label))) + (pcase o-label + ;; TODO: Move this to when the mode is enabled/disabled? + ("default" (remove-hook 'org-export-before-processing-hook + 'org--html-export-style-setup)) + (_ (add-hook 'org-export-before-processing-hook + 'org--html-export-style-setup))))) + ] + ;; Result string, nothing. + "") #+end_src -#+end_parallel - -#+end_details - --------------------------------------------------------------------------------- - - A block to make an editorial comment could be overkill in some cases; luckily - [[doc:org-defblock][defblock]] automatically provides an associated link type for the declared - special blocks. - - Syntax: =[[remark:person_name][editorial remark]]=. - - This link type exports the same as the =remark= block type; - however, in Emacs it is shown with an ‘angry’ ---bold--- red face. +# html-export-style:solarized_light +* COMMENT Fortune Links: Smiles inside and outside of Emacs + :PROPERTIES: + :CUSTOM_ID: Fortune-Links-Smiles-inside-and-outside-of-Emacs + :END: -:Old_unnecessary_implementaiton: - #+begin_src emacs-lisp -n -r -(org-link-set-parameters - "edcomm" - :follow (lambda (_)) - :export (lambda (label description backend) - (org--edcomm - backend - (format ":ed:%s\n%s" label description))) - :help-echo (lambda (_ __ position) - (save-excursion - (goto-char position) - (-let [(&plist :path) (cadr (org-element-context))] - (format "%s made this remark" (s-upcase path))))) - :face '(:foreground "red" :weight bold)) - #+end_src -:End: +Sometimes we need a smile, or a fortune, and want it with a nice graphic ---all +in Emacs. Enter ~fortune:𝒳~ links! +- These yield colourful graphics /both/ in Emacs and in HTML export. + + Click on the link to see it in action, in Emacs. +- Here is an example of ~fortune:joke~. fortune:joke -#+begin_box Example: Terse remarks via links +# - An example usage in blog articles would be the ~[[fortune:ANIMAL][PHRASE]]~ +# syntax: +# [[fortune:cow][howdy buddo]] +# +# TODO: This is busted? Maybe make a Github Issue; looks like an easy thing for +# other new contributors. -#+begin_parallel :bar t -~[[edcomm:Jasim][Hello, where are you?]]~ +#+begin_src emacs-lisp +(org-deflink fortune + "Print an ASCII animal saying the given link's description, a fortune, or a joke. -# +html:
-[[remark:Jasim][Hello, where are you?]] -#+end_parallel -------- -#+begin_parallel :bar t - The =#+replacewith:= switch ---and usual Org markup--- also works with these - links: @@html:
@@ ~[[remark:Qasim][/‘j’/ #+replacewith: /‘q’/]]~ +This is essentially a wrapper around the following command-line incantation -#+html:
- [[remark:Qasim][/‘j’/ #+replacewith: /‘q’/]] -#+end_parallel + fortune | cowsay | lolcat -f -#+end_box +We show colourful sayings both in Emacs (when you click on the link) and in HTML export. --------------------------------------------------------------------------------- +This requires you have the command-line packages ‘fortune’, ‘cowsay’, ‘lolcat’, +and ‘aha’ for converting coloured terminal output into HTML. +On MacOS, all of these can be installed with `brew install 𝒳'; +better-yet use the Emacs Lisp `system-packages-install' package. - All editor comments, remarks, are disabled by declaring, in your Org file: - #+begin_example org -,#+bind: org-hide-editor-comments t - #+end_example - The =#+bind:= keyword makes Emacs variables buffer-local during export - ---it is evaluated /after/ any =src= blocks. To use it, one must declare in - their Emacs init file the following line, which our mode - ensures is true. - #+BEGIN_SRC emacs-lisp :tangle no :noweb-ref enable-mode -(setq org-export-allow-bind-keywords t) - #+END_SRC +The help-echo, hover tooltip, provides useful information on possibly link types and their effects. - | ( Remember to =C-c C-c= the =#+bind= to activate it, the first time it is written. ) | +Example uses: - #+bind: org-hide-editor-comments nil + fortune:joke ;; Show a random animal saying a punny joke -* COMMENT Colours - :PROPERTIES: - :CUSTOM_ID: Colours - :END: + fortune:random ;; Show a random animal saying a random fortune/phrase -Let's develop blocks for colouring text and link types for inline colouring; -e.g., [[doc:org--color][color]] and [[doc:org--teal][teal]]. - + E.g., ~[[brown: Hello, World!]]~ ⇒ [[brown: Hello, World!]] - + E.g., ~brown:Friends!~ - ⇒ brown:Friends! ( Note the ‘!’ is not coloured; use ~[[...]]~ ! ) + fortune:dragon ;; Show a dragon saying a random fortune/phrase - #+begin_box :background-color custard - Use kbd:M-x_list-colors-display to see a list of defined colour names in Emacs - ---see [[http://muug.ca/mirror/ctan/macros/latex/contrib/xcolor/xcolor.pdf][xcolor]] for the LaTeX side and [[https://htmlcolorcodes.com/color-names/][htmlcolorcodes.com]] for the HTML side, or - just visit http://latexcolor.com/ for both. - # Use =M-: (defined-colors)= to see all colours that are supported on your Emacs. - #+end_box + ;; Show a the given animal saying the given phrase + [[fortune:mutilated][Opps, I broke the thing!]] - #+html:
- :Examples: - #+BEGIN_SRC emacs-lisp :results value :wrap no :tangle no -(s-join "\n\n" -(cl-loop for c in org-special-block-extras/colors - collect (format "#+begin_%s\n This text is %s!\n#+end_%s" c c c))) - #+END_SRC - :End: -#+begin_details A Picture and Block Examples + ;; The ‘fortune’ link grew out of the following link in my work journal + [[elisp:(dad-joke-get)][I wanna smile!]] - [[file:images/colours.jpg]] +For HTML export, the resulting HTML element has class ‘org-fortune’, +to which users may adorn CSS styling. For instance, in an Org file: - -------------------------------------------------------------------------------- + ,#+html: + # Chalkduster font-family is good for one-line sayings, phrases. - #+begin_parallel - #+begin_black - This text is black! - #+end_black +We intentionally do not fold-up such links when they have associated descriptions. - #+begin_blue - This text is blue! - #+end_blue +When you click, it takes a seconds to fetch jokes; so await a moment when hovering over joke fortunes." + [:display 'full + :face '(:box (:color "orange" :style released-button) :underline "green" :overline "green") + :let (animals '(blowfish bud-frogs cower default dragon + dragon-and-cow flaming-sheep ghostbusters + moose mutilated sheep stegosaurus turkey + turtle tux) + animal (if (string-equal "cow" (s-trim o-label)) + 'default + (seq-random-elt animals)) + animal₀ (if (equal 'default animal) 'cow animal) + _loads (progn (require 'dad-joke) (require 'seq) (require 'lolcat)) + saying (cond + (o-description (format "echo %s" (pp-to-string o-description))) + ((equal "joke" (s-trim o-label)) (format "echo %s" (pp-to-string (dad-joke-get)))) + (:otherwise "fortune")) + result (format "%s\t\t\t%s" + (shell-command-to-string (format "%s | cowsay -f %s" saying animal)) + animal₀) + buf-name (format "fortune:%s" animal₀)) + :follow (progn (display-message-or-buffer result) + (ignore-errors (kill-buffer buf-name)) + (switch-to-buffer-other-window "*Message*") + (rename-buffer buf-name) + (highlight-regexp (format "%s" animal₀) 'hi-green-b) + (lolcat-this-buffer) + (local-set-key "q" #'kill-buffer-and-window) + (message "“q” to kill buffer and window.")) + :help-echo (s-join "\n" (list "“fortune:𝒳” or “[[fortune:𝒳][description 𝒟]]” where 𝒳 is " + "⇢ joke ⟦A random animal that says a punny joke⟧" + "⇢ random ⟦A random animal that says 𝒟, or a random fortune phrase⟧" + "⇢ ⟦This animal says 𝒟, or a random fortune phrase⟧" + "\t cow, blowfish, bud-frogs, cower, dragon, dragon-and-cow," + "\t flaming-sheep, ghostbusters, moose, mutilated, sheep," + "\t stegosaurus, turkey, turtle tux" + "\n" + "\n" result)) + ] + (if (equal o-backend 'html) + (--> (shell-command-to-string (format "%s | cowsay -f %s | lolcat -f | aha -n" saying animal)) + (if (s-starts-with? "/System/Library" it) + (s-join "\n" (cdr (s-split "\n" it))) + it) + (format "%s\t\t\t%s" it animal₀) + (format "
 %s 
" it)) + result)) +#+end_src - #+begin_brown - This text is brown! - #+end_brown +* COMMENT Editor Comments + :PROPERTIES: + :CUSTOM_ID: editor-comments + :END: - # #+begin_cyan - # This text is cyan! - # #+end_cyan + “Editor Comments” are intended to be top-level first-class comments in an + article that are inline with the surrounding text and are delimited in such a + way that they are visible but drawing attention. I first learned about this + idea from Wolfram Kahl ---who introduced me to Emacs many years ago. We +# implement editor comments as special blocks named [[doc:org--remark][remark]]. - #+begin_darkgray - This text is darkgray! - #+end_darkgray +#+begin_box Example - #+begin_gray - This text is gray! - #+end_gray +#+begin_parallel +_This_ - #+begin_green - This text is green! - #+end_green +#+begin_src org :tangle no :tangle no + In LaTeX, a =remark= appears inline with the text surrounding it. + ,#+begin_remark Bobert + org-mode is dope, yo! + ,#+replacewith: + Org-mode is essentially a path toward enlightenment. + ,#+end_remark + Unfortunately, in the HTML rendition, the =remark= is its own paragraph and thus + separated by new lines from its surrounding text. +#+end_src - #+begin_lightgray - This text is lightgray! - #+end_lightgray +#+html:


- #+begin_lime - This text is lime! - #+end_lime +_Yields_ - #+begin_magenta - This text is magenta! - #+end_magenta + In LaTeX, an =remark= appears inline with the text surrounding it. + #+begin_remark Bobert + org-mode is dope, yo! + #+replacewith: + Org-mode is essentially a path toward enlightenment. + #+end_remark + Unfortunately, in the HTML rendition, the =remark= is its own paragraph and thus + separated by new lines from its surrounding text. +#+end_parallel +#+end_box - #+begin_olive - This text is olive! - #+end_olive +:Pics_old: + #+caption: In order: Chrome, Emacs Web Wowser, Org source, PDF + [[file:images/edcomm.png]] +:End: - #+begin_orange - This text is orange! - #+end_orange +# | /Any new ---possibly empty--- inner lines in the =remark= are desirably preserved/ | - #+begin_pink - This text is pink! - #+end_pink +-------------------------------------------------------------------------------- - #+begin_purple - This text is purple! - #+end_purple + #+begin_details "Implementing ‘remark’, from §ection 1, with more bells and whistles" :title-color pink + #+BEGIN_SRC emacs-lisp +(defvar org-hide-editor-comments nil + "Should editor comments be shown in the output or not.") - #+begin_red - This text is red! - #+end_red +(org-defblock remark + (editor "Editor Remark" color "black" signoff "" strong nil) +; :inline-please__see_margin_block_for_a_similar_incantation ; ⇒ crashes! +[:face '(:foreground "red" :weight bold)] +"Format CONTENTS as an first-class editor comment according to BACKEND. - #+begin_teal - This text is teal! - #+end_teal +The CONTENTS string has an optional switch: If it contains a line +with having only ‘#+replacewith:’, then the text preceding this +clause should be replaced by the text after it; i.e., this is +what the EDITOR (the person editing) intends and so we fromat the +replacement instruction (to the authour) as such. - #+begin_violet - This text is violet! - #+end_violet +In Emacs, as links, editor remarks are shown with a bold red; but +the exported COLOR of a remark is black by default and it is not +STRONG ---i.e., bold---. There is an optional SIGNOFF message +that is appended to the remark. +" + (-let* (;; Are we in the html backend? + (tex? (equal backend 'latex)) - #+begin_white - This text is white! - #+end_white + ;; fancy display style + (boxed (lambda (x) + (if tex? + (concat "\\fbox{\\bf " x "}") + (concat "" + "" x "")))) - #+begin_yellow - This text is yellow! - #+end_yellow + ;; Is this a replacement clause? + ((this that) (s-split "\\#\\+replacewith:" contents)) + (replacement-clause? that) ;; There is a ‘that’ + (replace-keyword (if tex? + "\\underline{Replace:}" " Replace:")) + (with-keyword (if tex? "\\underline{With:}" "With:" + )) + (editor (format "[%s:%s" editor + (if replacement-clause? + replace-keyword + ""))) + (contents′ (if replacement-clause? + (format "%s %s %s" this + (org-export (funcall boxed with-keyword)) + that) + contents)) - #+end_parallel + ;; “[Editor Comment:” + (edcomm-begin (funcall boxed editor)) + ;; “]” + (edcomm-end (funcall boxed "]"))) - #+end_details + (setq org-export-allow-bind-keywords t) ;; So users can use “#+bind” immediately + (if org-hide-editor-comments + "" + (format (pcase backend + ('latex (format "{\\color{%%s}%s %%s %%s %%s %%s}" (if strong "\\bfseries" ""))) + (_ (format "<%s style=\"color: %%s;\">%%s %%s %%s %%s" (if strong "strong" "p") (if strong "strong" "p")))) + color edcomm-begin contents′ signoff edcomm-end)))) + #+END_SRC - :Header: -#+BEGIN_SRC emacs-lisp -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Load support for 20 colour custom blocks and 20 colour link types - #+END_SRC - :End: - #+html:
-#+begin_details Implementation of numerous colour blocks/links - We declare a list of colors that should be available on most systems. Then - using this list, we evaluate the code necessary to produce the necessary - functions that format special blocks. + #+RESULTS: + | :face | (:foreground red :weight bold) | :export | (lambda (label description backend) (s-replace-all `((@@ . )) (org--remark backend (or description label) label :o-link? t))) | :help-echo | (lambda (window object position) (save-excursion (goto-char position) (-let* (((&plist :path :format :raw-link :contents-begin :contents-end) (cadr (org-element-context))) (description (when (equal format 'bracket) (copy-region-as-kill contents-begin contents-end) (substring-no-properties (car kill-ring))))) (format %s | - # - To add support for a colour =𝒞=, simply - # ~(push '𝒞 org--ospe-colors)~. - # # - By default, Org uses the ~graphicx~ LaTeX package which let's us colour text - ---see its documentation [[http://ctan.mirror.rafal.ca/macros/latex/required/graphics/grfguide.pdf][here]]. For example, in an ~#+begin_export latex~ block, - the following produces blue coloured text. - #+begin_example latex -{ \color{blue} This is a sample text in blue. } - #+end_example - # Below, we format colour block types to essentially format block contents like - # this. - #+BEGIN_SRC emacs-lisp -(defvar org--ospe-colors - '(black blue brown cyan darkgray gray green lightgray lime - magenta olive orange pink purple red teal violet white - yellow) - "Colours that should be available on all systems.") + :Older_version: + #+BEGIN_SRC emacs-lisp :tangle no +(defvar org-hide-editor-comments nil + "Should editor comments be shown in the output or not.") -(cl-loop for colour in org--ospe-colors - do (eval `(org-defblock ,colour - (the-color "black") - (vector :face `(:foreground ,(format "%s" (quote ,colour)))) - ,(format "Show text in %s color." colour) - (let () - (format (pcase backend - (`latex "\\begingroup\\color{%s}%s\\endgroup\\,") - (_ "%s")) - (quote ,colour) contents))))) - #+END_SRC +(defun org--edcomm (backend contents) +"Format CONTENTS as an first-class editor comment according to BACKEND. - #+RESULTS: +The CONTENTS string has two optional argument switches: +1. :ed: ⇒ To declare an editor of the comment. +2. :replacewith: ⇒ [Nullary] The text preceding this clause + should be replaced by the text after it." + (-let* ( + ;; Get arguments + ((contents₁ . (&alist 'ed)) + (org--extract-arguments contents 'ed)) -Let's have some sanity tests... -#+begin_src emacs-lisp :tangle tests.el :comments link -(deftest "It is an HTML span styled red that contains the user's text" - [color red block] - (⇝ (⟰ "#+begin_red - My cool thoughts... - ,#+end_red") - "" - (* anything) - "My cool thoughts" - (* anything) - "")) + ;; Strip out any

tags + (_ (setq contents₁ (s-replace-regexp "

" "" contents₁))) + (_ (setq contents₁ (s-replace-regexp "

" "" contents₁))) -;; We have an HTML span styled with the user's color and it contains the user's text -(deftest "It works as expected" - [color pink block] - (⇝ (⟰ "#+begin_color pink - My cool thoughts... - ,#+end_color") - "" - (* anything) - "My cool thoughts" - (* anything) - "")) -#+end_src + ;; Are we in the html backend? + (html? (equal backend 'html)) - :Old: - #+BEGIN_SRC emacs-lisp :tangle no -(defvar org--ospe-colors - '(black blue brown cyan darkgray gray green lightgray lime - magenta olive orange pink purple red teal violet white - yellow) - "Colours that should be available on all systems.") + ;; fancy display style + (boxed (lambda (x) + (if html? + (concat "" + "" x "") + (concat "\\fbox{\\bf " x "}")))) -(cl-loop for colour in org--ospe-colors - do (eval (read (format - "(defun org--%s (backend contents) - (format (pcase backend - (`latex \"\\\\begingroup\\\\color{%s}%%s\\\\endgroup\\\\,\") - (_ \"%%s\")) - contents))" - colour colour colour)))) - #+END_SRC - :End: + ;; Is this a replacement clause? + ((this that) (s-split ":replacewith:" contents₁)) + (replacement-clause? that) ;; There is a ‘that’ + (replace-keyword (if html? " Replace:" + "\\underline{Replace:}")) + (with-keyword (if html? "With:" + "\\underline{With:}")) + (editor (format "[%s:%s" + (if (s-blank? ed) "Editor Comment" ed) + (if replacement-clause? + replace-keyword + ""))) + (contents₂ (if replacement-clause? + (format "%s %s %s" this + (funcall boxed with-keyword) + that) + contents₁)) - #+end_details + ;; “[Editor Comment:” + (edcomm-begin (funcall boxed editor)) + ;; “]” + (edcomm-end (funcall boxed "]"))) + (setq org-export-allow-bind-keywords t) ;; So users can use “#+bind” immediately + (if org-hide-editor-comments + "" + (format (pcase backend + ('latex "%s %s %s") + (_ "

%s %s %s

")) + edcomm-begin contents₂ edcomm-end)))) + #+END_SRC +:End: - #+html:
- #+begin_details Implementation of ‘color’ - For faster experimentation between colours, we provide a generic =color= block - that consumes a color argument. + In the HTML export, the =edcomm= special block is /not/ in-line with the text + surrounding it ---ideally, it would be inline so that existing paragraphs are + not split into multiple paragraphs but instead have an editor's comment + indicating suggested alterations. - #+begin_src emacs-lisp -(org-defblock color - (color black) - (vector :face (lambda (colour) `(:foreground ,(format "%s" colour)))) - "Format text according to a given COLOR, which is black by default." - (format (pcase backend - (`latex "\\begingroup\\color{%s}%s\\endgroup\\,") - (`html "%s")) - color contents)) - #+end_src -[Posterity] Old version which did /not/ allow ~wombo~ colour: - #+begin_src emacs-lisp :tangle no -(org-defblock color (color black :face (lambda (colour) - (if (member (intern colour) org--ospe-colors) - `(:foreground ,(format "%s" colour)) - `(:height 300 - :underline (:color "red" :style wave) - :overline "red" :strike-through "red")))) nil - "Format text according to a given COLOR, which is black by default." - (format (pcase backend - (`latex "\\begingroup\\color{%s}%s\\endgroup\\,") - (`html "%s")) - color contents)) - #+end_src - #+RESULTS: +Let's have some sanity tests... +#+begin_src emacs-lisp :tangle tests.el :comments link +(deftest "The user's remark is enclosed in the default delimiters" + [remark] + (⇝ (⟰ "#+begin_remark + Here is some meta-commentary... + ,#+end_remark") + (* anything) "[Editor Remark:" + (* anything) "Here is some meta-commentary" + (* anything) "]")) - :Old: - #+begin_src emacs-lisp :tangle no -(defun org--color (backend contents) - "Format CONTENTS according to the ‘:color:’ they specify for BACKEND." - (-let* (((contents′ . (&alist 'color)) - (org--extract-arguments contents 'color)) - (block-coloring - (intern (format "org--%s" (s-trim color))))) - (if (member (intern (s-trim color)) org--ospe-colors) - (funcall block-coloring backend contents′) - (error "Error: “#+begin_color:%s” ⇒ Unsupported colour!" color)))) - #+end_src - :End: - #+end_details +;; The other features of remark blocks should be tested; +;; but this is not a pressing, nor interesting, concern. +#+end_src - Moreover, we have that the syntax =red:text= /renders/ ‘text’ with the colour red - in *both* the Emacs interface and in exported backends. + #+end_details - [[file:images/colour_links.png]] +-------------------------------------------------------------------------------- - :Old: - #+begin_src emacs-lisp :tangle no -;; [[𝒞:text₀][text₁]] ⇒ Colour ‘textₖ’ by 𝒞, where k is 1, if present, otherwise 0. -;; If text₁ is present, it is suggested to use ‘color:𝒞’, defined below. -(cl-loop for colour in org--ospe-colors - do (org-link-set-parameters - (format "%s" colour) - :follow `(lambda (path) (message "Colouring “%s” %s." path (quote ,colour))) - :export `(lambda (label description backend) - (-let [block-colouring - (intern (format "org--%s" (quote ,colour)))] - (funcall block-colouring backend (or description label)))) - :face `(:foreground ,(format "%s" colour)))) +#+begin_details Example: No optional arguments + #+begin_remark + /Please/ *change* _this_ section to be more, ya know, professional. + #+end_remark -;; Generic ‘color’ link type [[color:𝒞][text]] ⇒ Colour ‘text’ by 𝒞. -;; If 𝒞 is an unsupported colour, ‘text’ is rendered in large font -;; and surrounded by red lines. -(org-link-set-parameters "color" - :follow (lambda (_)) - :face (lambda (colour) - (if (member (intern colour) org--ospe-colors) - `(:foreground ,(format "%s" colour)) - `(:height 300 - :underline (:color "red" :style wave) - :overline "red" :strike-through "red"))) - :help-echo (lambda (_ __ position) - (save-excursion - (goto-char position) - (-let* (((&plist :path) (cadr (org-element-context)))) - (if (member (intern path) org--ospe-colors) - "Colour links just colour the descriptive text" - (format "Error: “color:%s” ⇒ Unsupported colour!" path))))) - :export (lambda (colour description backend) - (-let [block-colouring - (intern (format "org-block/%s" colour))] - (if (member (intern colour) org--ospe-colors) - (funcall block-colouring backend description) - (error "Error: “color:%s” ⇒ Unsupported colour!" colour))))) - #+end_src - :End: +-------------------------------------------------------------------------------- +*Source:* +#+begin_src org :tangle no + ,#+begin_remark + /Please/ *change* _this_ section to be more, ya know, professional. + ,#+end_remark +#+end_src +#+end_details +#+begin_details "Example: Only providing a main argument ---i.e., the remark author, the editor" + #+begin_remark Bobert + /Please/ *change* _this_ section to be more, ya know, professional. + #+end_remark - #+begin_center - Observe: red:this green:is cyan:super teal:neato, purple:amigos! and [[color:brown][this is brown ‘color’ link]] and [[color:orange][this one is an orange ‘color’ link!]] + #+latex: \vspace{1em}\noindent +-------------------------------------------------------------------------------- +*Source:* +#+begin_src org :tangle no + ,#+begin_remark Bobert + /Please/ *change* _this_ section to be more, ya know, professional. + ,#+end_remark +#+end_src - +Also: If we try to use an unsupported colour ‘wombo’, we render the+ - +descriptive text larger in Emacs along with a tooltip explaining why this is - the case; e.g., =[[color:wombo][hi]]=.+ +#+end_details +#+begin_details Example: Possibly with no contents: + #+begin_remark Bobert + #+end_remark +-------------------------------------------------------------------------------- +*Source:* +#+begin_src org :tangle no + ,#+begin_remark Bobert + ,#+end_remark +#+end_src +#+end_details +#+begin_details "Example: Empty contents, no authour, nothing" + #+begin_remark + #+end_remark + -------------------------------------------------------------------------------- +*Source:* +#+begin_src org :tangle no + ,#+begin_remark + ,#+end_remark +#+end_src +#+end_details +#+latex: \vspace{1em}\noindent +#+begin_details Example: Possibly with an empty new line + #+begin_remark - ~[[color:#fad][Using Hex colour code!]]~ ⇒ [[color:#fad][Using Hex colour code!]] ;-) - #+end_center + #+end_remark +-------------------------------------------------------------------------------- +*Source:* +#+begin_src org :tangle no + ,#+begin_remark - ( Markdown does not support colour; go look at the HTML or PDF! ) -**   ~latex-definitions~ for hiding LaTeX declarations in HTML - :PROPERTIES: - :CUSTOM_ID: latex-definitions-for-hiding-LaTeX-declarations-in-HTML - :END: - :Fails_idea: - Larger example: - #+begin_mathjax - red:\Sigma + ,#+end_remark +#+end_src +#+end_details +#+latex: \iffalse +#+begin_details "Example: With a “#+replacewith:” clause" + #+begin_remark + The two-dimensional notation; e.g., $\sum_{i = 0}^n i^2$ + #+replacewith: + A linear one-dimensional notation; e.g., + $(\Sigma i : 0..n \;\bullet\; i^2)$ + #+end_remark +-------------------------------------------------------------------------------- +*Source:* +#+begin_src org :tangle no + ,#+begin_remark + The two-dimensional notation; e.g., $\sum_{i = 0}^n i^2$ + ,#+replacewith: + A linear one-dimensional notation; e.g., + $(\Sigma i : 0..n \;\bullet\; i^2)$ + ,#+end_remark +#+end_src +#+end_details +#+latex: \fi +#+latex: \vspace{1em}\noindent +#+begin_details Example: Possibly “malformed” replacement clauses - #+end_mathjax - :End: +Forgot the thing to be replaced… - Before indicating desirable next steps, let us produce an incidentally useful - special block type. +#+begin_remark +#+replacewith: +A linear one-dimensional notation; e.g., +$(\Sigma i : 0..n \;\bullet\; i^2)$ +#+end_remark - #+latex: \vspace{1em} - We may use LaTeX-style commands such as ~{\color{red} x}~ by enclosing them in - =$=-symbols to obtain ${\color{red}x}$ and other commands to present mathematical - formulae in HTML. This is known as the MathJax tool ---Emacs' default HTML - export includes it. +-------------------------------------------------------------------------------- - #+latex: \vspace{1em} - It is common to declare LaTeX definitions for convenience, but such - declarations occur within ~$~-delimiters and thereby produce undesirable extra - whitespace. We declare the ~latex_definitions~ block type which avoids - displaying such extra whitespace in the resulting HTML. +Forgot the new replacement thing… - #+begin_details ‘latex-definitions’ Implementation - #+begin_src emacs-lisp -(org-defblock latex-definitions nil - "Declare but do not display the CONTENTS according to the BACKEND." - (format (pcase backend - ('html "

\\[%s\\]

") - (_ "%s")) - raw-contents)) - #+end_src +#+begin_remark + The two-dimensional notation; e.g., $\sum_{i = 0}^n i^2$ + #+replacewith: +#+end_remark - #+RESULTS: +-------------------------------------------------------------------------------- - :OLD: - #+begin_src emacs-lisp :tangle no -(defun org--latex-definitions (backend contents) - "Declare but do not display the CONTENTS according to the BACKEND." - (cl-loop for (this that) in (-partition 2 '("

" "" - "

" "" - "\\{" "{" - "\\}" "}")) - do (setq contents (s-replace this that contents))) - (format (pcase backend - ('html "

\\[%s\\]

") - (_ "%s")) - contents)) - #+end_src +Completely lost one's train of thought… +#+begin_parallel + #+begin_remark + #+replacewith: + #+end_remark - - Org escapes ~{,}~ in LaTeX export, so we need to ‘unescape’ them. - This is clearly a hack. - :End: - #+end_details +#+columnbreak: +*Source:* - #+latex: \iffalse +#+begin_src org :tangle no + ,#+begin_remark + ,#+replacewith: + ,#+end_remark +#+end_src +#+end_parallel - Here ---which you cannot see, as /desired/---is an example usage, where we - declare ~\LL~ to produce a violet left parenthesis. We then use these to produce - an example of quantification notation. - #+begin_latex-definitions - \def\LL{\color{violet}(} - \def\RR{\color{violet})} - #+end_latex-definitions +#+end_details - # +begin_org-demo :source-color white :result-color white - $$ - {\color{teal}\bigoplus} - _{ {\color{violet} x} - = {\color{red} a}} - ^{\color{cyan} b} - {\color{brown}{\,f\, x}} - \quad=\quad - {\color{brown}{f\,\LL {\color{red} a} \RR}} - \;{\color{teal}\oplus}\; {\color{brown}{f \, \LL a + 1 \RR }} - \;{\color{teal}\oplus}\; {\color{brown}{f \, \LL a + 2 \RR }} - \;{\color{teal}\oplus}\; \cdots - \;{\color{teal}\oplus}\; {\color{brown}{f \, \LL {\color{cyan} b} \RR}} - $$ +-------------------------------------------------------------------------------- - | [[teal:⊕]] | /Loop sequentially with loop-bodies fused using [[teal:⊕][⊕]]/ | - | /[[violet:x]]/ | /Use [[violet:x][x]] as the name of the current element/ | - | /[[red:a]]/ | /Start with [[violet:x][x]] being [[red:a][a]]/ | - | /[[cyan:b]]/ | /End with [[violet:x][x]] being [[cyan:b][b]]/ | - | /[[color:brown][f x]]/ | /At each [[violet:x][x]] value, compute [[color:brown][f x]]/ | + A block to make an editorial comment could be overkill in some cases; luckily + [[doc:org-defblock][defblock]] automatically provides an associated link type for the declared + special blocks. - # Note that /[[color:brown][f x]]/ is obtained by =/[[color:brown][f x]]/.= - # +end_org-demo + - Syntax: =[[remark:person_name][editorial remark]]=. + - This link type exports the same as the =remark= block type; + however, in Emacs it is shown with an ‘angry’ ---bold--- red face. - ( Markdown does not support MathJax; go look at the HTML or PDF! ) +:Old_unnecessary_implementaiton: + #+begin_src emacs-lisp -n -r +(org-link-set-parameters + "edcomm" + :follow (lambda (_)) + :export (lambda (label description backend) + (org--edcomm + backend + (format ":ed:%s\n%s" label description))) + :help-echo (lambda (_ __ position) + (save-excursion + (goto-char position) + (-let [(&plist :path) (cadr (org-element-context))] + (format "%s made this remark" (s-upcase path))))) + :face '(:foreground "red" :weight bold)) + #+end_src +:End: - #+latex: \fi +#+begin_box Example: Terse remarks via links - -------------------------------------------------------------------------------- +#+begin_parallel :bar t +~[[edcomm:Jasim][Hello, where are you?]]~ - Unfortunately, MathJax does not easily support arbitrary HTML elements to occur - within the =$=-delimiters ---see [[https://stackoverflow.com/questions/58883048/mathjax-or-similar-render-arbitrary-html-element-inside-expression][this]] and [[https://github.com/mathjax/MathJax/issues/1707][this]] for ‘workarounds’. As such, the - MathJax producing the above example is rather ugly whereas its subsequent - explanatory table is prettier on the writer's side. +# +html:
+[[remark:Jasim][Hello, where are you?]] +#+end_parallel +------- +#+begin_parallel :bar t + The =#+replacewith:= switch ---and usual Org markup--- also works with these + links: @@html:
@@ ~[[remark:Qasim][/‘j’/ #+replacewith: /‘q’/]]~ - :Verbatim_pasted_from_the_above_THIS_link: - MathJax will not process math that contains HTML tags (other than a select few), - so you will not be able to do the kind of replacements inside an expression like - you are attempting to do here. +#+html:
+ [[remark:Qasim][/‘j’/ #+replacewith: /‘q’/]] +#+end_parallel - #+begin_export html - - - -
- $$x + \left(\,\insertHTML{}\,\right) + y$$ -
- - - $$x+\left(\insertHTML{}\right)+y$$ - #+end_export - :End: +#+end_box - #+latex: \vspace{1em} - [[color:orange][Going forward,]] it would be nice to easily have our colour links work within - a mathematical special block. +-------------------------------------------------------------------------------- - #+latex: \vspace{1em} - [[color:orange][Moreover,]] it would be nice to extend the =color= block type to take multiple - arguments, say, =c₁ c₂ … cₙ= such that: + All editor comments, remarks, are disabled by declaring, in your Org file: + #+begin_example org +,#+bind: org-hide-editor-comments t + #+end_example + The =#+bind:= keyword makes Emacs variables buffer-local during export + ---it is evaluated /after/ any =src= blocks. To use it, one must declare in + their Emacs init file the following line, which our mode + ensures is true. + #+BEGIN_SRC emacs-lisp :tangle no :noweb-ref enable-mode +(setq org-export-allow-bind-keywords t) + #+END_SRC - | /n/ | Behaviour | - |---+------------------------------------------------------------------------------------| - | 0 | No colouring; likewise if no arguments altogether | - | 1 | Colour all entries using the given colour c₁ | - | /n/ | Paragraph --region separated by a new line-- =i= is coloured by =cₖ= where =k = i mod n= | + | ( Remember to =C-c C-c= the =#+bind= to activate it, the first time it is written. ) | - Besides having a colourful article, another usage I envision for this - generalisation would be when rendering text in multiple languages; e.g., use red - and blue to interleave Arabic poetry with its English translation. + #+bind: org-hide-editor-comments nil * COMMENT   /“Link Here!”/ & OctoIcons :PROPERTIES: @@ -8193,6 +8066,8 @@ since otherwise things don't look as nice in a markdown readme file. #+caption: Visually hiding, folding away, details [[file:images/details.png]] + + ( Markdown does not support colour; go look at the HTML or PDF! ) * COMMENT Case Studies ** In doubt, a block's main argument should be enclosed in quotes :PROPERTIES: diff --git a/tests/latex-definitions.yaml b/tests/latex-definitions.yaml new file mode 100644 index 0000000..2d398fb --- /dev/null +++ b/tests/latex-definitions.yaml @@ -0,0 +1,66 @@ +input: |- + Hello, in this blog post I'd like to talk about quantifiers. + + # First, I'll define some helpers that I use multiple times... + #+begin_latex-definitions + \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} + #+end_latex-definitions + + 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 [[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]]. + +expectations: + html: |- +

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

+ latex: |- + 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\ldots{} + $$ + \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 \begingroup\color{teal}Loop sequentially with\endgroup\, + \begingroup\color{brown}loop-bodies f(x)\endgroup\, \begingroup\color{teal}fused using ⊕\endgroup\,, using \begingroup\color{violet}x as the name of the current element\endgroup\,, \begingroup\color{red}starting at a\endgroup\, and \begingroup\color{cyan}ending at b\endgroup\,.