From e25e1c98c9aaee9f60bc55c6cd650524e11b6775 Mon Sep 17 00:00:00 2001 From: Musa Al-hassy Date: Tue, 24 Dec 2024 15:38:29 -0500 Subject: [PATCH] Clean: parallel.yaml viz introducing osbe-example link type --- org-special-block-extras.org | 209 +++++++++-------------------------- tests/e2e.el | 38 ++++++- tests/osbe-example.yaml | 47 ++++++++ tests/parallel.yaml | 201 +++++++++------------------------ tests/rename.yaml | 2 +- 5 files changed, 185 insertions(+), 312 deletions(-) create mode 100644 tests/osbe-example.yaml diff --git a/org-special-block-extras.org b/org-special-block-extras.org index a55f260..5d8cc04 100644 --- a/org-special-block-extras.org +++ b/org-special-block-extras.org @@ -13,6 +13,28 @@ html-export-style:solarized_light + +#+RESULTS: +: kill-buffer-and-window + +#+name: startup-code +#+begin_src emacs-lisp :exports none :tangle no :exports none +(org-docs-load-libraries (list "~/org-special-block-extras/documentation.org")) +#+end_src + +# MA: TODO: Margin blocks produce extra newlines! + +# TODO: Make org-defblock looks almost the same as cl-defun, namely argslist has args being either pairs or singletons! + +# TODO: Since the implementation is a find-replace, nested blocks do not honor enclosing blocks. +# For example, try placing a `rename` block within an `example` block and see that it is expanded! + + Look: +# 1. osbe-example:~/org-special-block-extras/tests/doc.yaml +# 2. osbe-example:~/org-special-block-extras/tests/rename.yaml + +* COMMENT Run all /unit/ tests + # TODO C-c C-c ⇒ Run all tests, and see them printed with their descriptions nicely. #+begin_src emacs-lisp :exports none :tangle no ;; Press ‘q’ to kill the resulting buffer and window. @@ -37,16 +59,6 @@ html-export-style:solarized_light ) #+end_src -#+RESULTS: -: kill-buffer-and-window - -#+name: startup-code -#+begin_src emacs-lisp :exports none :tangle no :exports none -(org-docs-load-libraries (list "~/org-special-block-extras/documentation.org")) -#+end_src - -# MA: TODO: Margin blocks produce extra newlines! - * HTML & LaTeX Setup :ignore: :PROPERTIES: :CUSTOM_ID: HTML-LaTeX-Setup @@ -285,7 +297,7 @@ Disable this behaviour by setting `org-special-block-add-html-extra' to `nil'. # # # See https://github.com/alhassy/emacs.d#what-does-literate-programming-look-like -* Testing :noexport: +* COMMENT Testing :noexport: :PROPERTIES: :CUSTOM_ID: Testing :END: @@ -479,7 +491,7 @@ jobs: # Upload coverage - uses: codecov/codecov-action@v1 -* Test that this org file itself exports without problems :noexport: +* COMMENT Test that this org file itself exports without problems :noexport: :PROPERTIES: :CUSTOM_ID: Test-that-this-org-file-itself-exports-without-problems :END: @@ -506,7 +518,7 @@ jobs: (should (org-html-export-to-html))) #+end_src -* Abstract :ignore: +* COMMENT Abstract :ignore: :PROPERTIES: :CUSTOM_ID: Abstract :END: @@ -669,7 +681,7 @@ and the result looks nice. “Look ma, no HTML required!” #+caption: Write in Emacs using Org-mode, export beautifully to HTML or LaTeX [[file:images/minimal-working-example-multiforms.png]] -* org-tutorial :ignore: +* COMMENT org-tutorial :ignore: :PROPERTIES: :CUSTOM_ID: org-tutorial :END: @@ -691,7 +703,7 @@ Installation instructions are [[#Summary][below]]. #+end_quote #+latex: \newpage -* A unified interface for special blocks and links: ~defblock~ +* COMMENT A unified interface for special blocks and links: ~defblock~ :PROPERTIES: :CUSTOM_ID: A-unified-interface-for-special-blocks-and-links-defblock :END: @@ -1826,7 +1838,7 @@ Three example uses: (main-arg-value (cl-second kwds)) (kwds (cddr kwds))) ;; Unless we've already set the docs for the generic function, don't re-declare it. - `(if ,(null body) + `(progn ;; if ,(null body) (cl-defgeneric ,(intern (format "org-block/%s" name)) (backend raw-contents &rest _) ,docstring) @@ -3319,7 +3331,7 @@ Such “open methods” are known as “multimethods”; e.g., see doc:cl-defgen #+end_src :End: -* Folded Details ---As well as boxed text and subtle colours +* COMMENT Folded Details ---As well as boxed text and subtle colours :PROPERTIES: :CUSTOM_ID: Folded-Details :END: @@ -3705,21 +3717,18 @@ src_latex[:exports code]{\color{blue}} is a nightmare. ) It may be useful to /fuse/ the ~box~ and ~details~ concepts into one. Something for future me ---or another contributor--- to think about ;-) -* Parallel +* Parallel ---/Place ideas side-by-side, possibly with a separator/ :PROPERTIES: :CUSTOM_ID: Parallel :END: - Articles can get lengthy when vertical whitespace is wasted on thin lines; - instead, one could save space by using /[[doc:org--parallel][parallel]] columns of text/. - -#+latex_header: \usepackage{multicol} -#+begin_center -Requires: src_latex[:exports code]{#+latex_header: \usepackage{multicol}} -#+end_center +# (setq osbe-example-yaml-cache (make-hash-table :test 'equal)) + osbe-example:~/org-special-block-extras/tests/parallel.yaml + +#+latex_header: \usepackage{multicol} #+begin_details Implementation - #+begin_src emacs-lisp -r -n +#+begin_src emacs-lisp -r -n (org-defblock parallel (cols "2" bar nil) "Place ideas side-by-side, possibly with a separator. @@ -3780,134 +3789,17 @@ With LaTeX export, the use of ‘#+columnbreak:’ is used to request a column b (columnBreak (lambda (width omit-rule?) (format "
" width (if omit-rule? "none" rule)))) ) - (format "
%s%s
" + (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)))))))) -#+end_src - -Let's have some sanity tests... -#+begin_src emacs-lisp :tangle tests.el :comments link -(deftest "Parallel blocks work as expected - Defaults" - [parallel block] - (⇝ (⟰ "#+begin_parallel - Hello, to the left! - - ,#+columnbreak: - A super duper wide middle margin! - - - ,#+columnbreak: - Goodbye (“God-be-with-ye”) to the right! - - ,#+columnbreak: - woah - ,#+end_parallel") - - ;; The result is 2 columns with no rule between them and it contains the - ;; user's text, but ignores the “#+columnbreak”. - "
" - (* anything) - "Hello, to the left!" - (* anything) - "A super duper wide middle margin!" - (* anything) - "Goodbye (“God-be-with-ye”) to the right!" - (* anything) - "woah")) - - -(deftest "Parallel blocks work as expected - Soft Columns" - [parallel block] - (⇝ (⟰ "#+begin_parallel 2 :bar t - X - - ,#+columnbreak: - - Y - - Z - ,#+end_parallel") - - ;; The result is 2 columns with a solid BLACK rule between them and it - ;; contains the user's text, but ignores the “#+columnbreak”. - "
" - (* anything) - "X" - (* anything) - "Y" - (* anything) - "Z" - (* anything))) - - -(deftest "Parallel blocks work as expected - Hard Columns" - [parallel block] - (⇝ (⟰ "#+begin_parallel 20% 60% 20% :bar green - X - - ,#+columnbreak: - - Y - - ,#+columnbreak: - - Z - ,#+end_parallel") - - ;; The result is 3 columns with a solid GREEN rule between them and it - ;; contains the user's text along with the “#+columnbreak” evaluated at the - ;; expected positions. - "
" - (* anything) - "X" - (* anything) - "
" - (* anything) - "Y" - (* anything) - "
" - (* anything) - "Z")) + contents) + (if (s-contains-p " " cols) "
" "")))))))) #+end_src #+end_details -#+html:
-#+begin_box Example -_This_ -#+begin_src org :tangle no -,#+begin_parallel 2 :bar t -X - -,#+columnbreak: - -Y - -Z -,#+end_parallel -#+end_src - -_Yields_ - -#+begin_parallel 2 :bar t -X - -#+columnbreak: - -Y - -Z -#+end_parallel -#+end_box - -#+begin_center -( The [[https://www.gnu.org/software/emacs/manual/html_mono/eww.html][Emacs Web Wowser]], ~M-x eww~, does not display =parallel= environments as -desired. ) -#+end_center - ** COMMENT Older setup :Possibly_delete: :PROPERTIES: :CUSTOM_ID: COMMENT-Older-setup @@ -3981,7 +3873,7 @@ mode activation ---after such functions have been declared. (defalias 'org--parallelNB #'org--2parallelNB) #+END_SRC -*  :fire: HTML Export Styles as Links +* COMMENT  :fire: HTML Export Styles as Links :PROPERTIES: :CUSTOM_ID: HTML-Export-Styles-as-Links :END: @@ -4072,7 +3964,7 @@ mode activation ---after such functions have been declared. #+end_src # html-export-style:solarized_light -* Fortune Links: Smiles inside and outside of Emacs +* COMMENT Fortune Links: Smiles inside and outside of Emacs :PROPERTIES: :CUSTOM_ID: Fortune-Links-Smiles-inside-and-outside-of-Emacs :END: @@ -4177,7 +4069,7 @@ When you click, it takes a seconds to fetch jokes; so await a moment when hoveri result)) #+end_src -* Editor Comments +* COMMENT Editor Comments :PROPERTIES: :CUSTOM_ID: editor-comments :END: @@ -4574,7 +4466,7 @@ Completely lost one's train of thought… #+bind: org-hide-editor-comments nil -* Colours +* COMMENT Colours :PROPERTIES: :CUSTOM_ID: Colours :END: @@ -5082,7 +4974,7 @@ Let's have some sanity tests... generalisation would be when rendering text in multiple languages; e.g., use red and blue to interleave Arabic poetry with its English translation. -* Nice Keystroke Renditions: kbd:C-h_h +* COMMENT Nice Keystroke Renditions: kbd:C-h_h :PROPERTIES: :CUSTOM_ID: kbd:nice-keystroke-renditions :END: @@ -5250,7 +5142,7 @@ Let's have some sanity tests... #+HTML: #+HTML: :End: -*   /“Link Here!”/ & OctoIcons +* COMMENT   /“Link Here!”/ & OctoIcons :PROPERTIES: :CUSTOM_ID: Link-Here-OctoIcons :END: @@ -5388,7 +5280,7 @@ link-here:example-location (Click the icon and see the URL has changed!) #+end_src #+end_details -* Badge Links +* COMMENT Badge Links :PROPERTIES: :CUSTOM_ID: Badge-Links :END: @@ -6096,7 +5988,7 @@ wish to use; e.g., badge:|1d8348|1d8348 the LaTeX backend. {{{newline}}} [[remark:Author][That is why no examples are shown in the PDF]] It may be useful to colour the =|=-separated fields of a badge link. # This would make the interface more welcoming to new users. -* Tooltips for Glossaries, Dictionaries, and Documentation +* COMMENT Tooltips for Glossaries, Dictionaries, and Documentation :PROPERTIES: :CUSTOM_ID: Tooltips-for-Glossaries-Dictionaries-and-Documentation :END: @@ -6986,7 +6878,7 @@ and, finally, look for the documentation entry using `org-docs-fallback'." (cdr (or (assoc label org--docs) (assoc label org--docs-from-libraries) (funcall org-docs-fallback label) - (error "Error: No documentation-glossary entry for “%s”!" label)))) + (unless org-export-with-broken-links (error "Error: No documentation-glossary entry for “%s”!" label))))) (cl-defun org-docs-insert () "Insert a “doc:𝒳” link from user's documentation-glossary database. @@ -7497,7 +7389,7 @@ block types; whereas they currently break the HTML export. to its associated =#+begin_documentation= declaration block in the current buffer, if possible. -* Marginal, “one-off”, remarks +* COMMENT Marginal, “one-off”, remarks :PROPERTIES: :CUSTOM_ID: Marginal-one-off-remarks :END: @@ -7962,7 +7854,7 @@ from∘to m = {! try it! } #+end_margin exercise to show that ℕ is fixedpoint of ~Maybe~. -* Equational Proofs +* COMMENT Equational Proofs :PROPERTIES: :CUSTOM_ID: Equational-Proofs :END: @@ -8475,7 +8367,7 @@ z #+end_src #+end_details -* Case Studies +* COMMENT Case Studies ** In doubt, a block's main argument should be enclosed in quotes :PROPERTIES: :CUSTOM_ID: In-doubt-a-block's-main-argument-should-be-enclosed-in-quotes @@ -8536,7 +8428,6 @@ It is said that $e^{i \cdot \pi} + 1 = 0$ is the truth. - * TODO [#A] COMMENT Summary :PROPERTIES: :CUSTOM_ID: Summary diff --git a/tests/e2e.el b/tests/e2e.el index d5ae522..627effc 100644 --- a/tests/e2e.el +++ b/tests/e2e.el @@ -193,7 +193,7 @@ INDENT-LEVEL specifies the current indentation level, defaulting to 0." (let ((seed 0)) (cl-letf (((symbol-function 'gensym) (lambda () (format "g%s" (incf seed))))) - (list + (list (cons 'html (with-temp-buffer (org-special-block-extras-mode) @@ -216,5 +216,37 @@ INDENT-LEVEL specifies the current indentation level, defaulting to 0." (latex-mode) (format-all-buffer))) (s-trim (buffer-string))) (error (format "🚫 The LaTex backend is intentionally unmaintained.\n🫠 Whoops, there seems to be an error: \n %S" err))))))) - 'hash-table)) - +'hash-table)) + + +(defun my/hash-get-or-compute (hash key compute-fn) + "Retrieve or compute the value for KEY in HASH, and store it if computed." + (or (gethash key hash) + (let ((value (funcall compute-fn))) + (puthash key value hash) + value))) + +(defvar osbe-example-yaml-cache (make-hash-table :test 'equal) + "Cache to avoid time re-reading yaml files!") +(org-defblock osbe-example (file) + "Render the given FILE as both Org source and rendered HTML result. + +The source is the `input' key; the target is the `expectations.html' key. + +Workflow: Write the `input' in an Org buffer, and once the export is to +my liking, then move the `input' to the relevant yaml file." + (let* ((yaml (my/hash-get-or-compute osbe-example-yaml-cache + file + (lambda () (e2e--read-yaml-file file)))) + (input (map-elt yaml 'input)) + (src (s-trim input)) + (tgt (map-elt (map-elt yaml 'expectations) 'html)) + ;; "teal" "brown" "gray" "purple" "lime" "green" "blue" "orange" "peach" "pink" "yellow" "custard" + (src.color (org-subtle-colors "lime")) + (tgt.color (org-subtle-colors "peach"))) + (cl-letf* (((symbol-function 'make-title) (lambda (it) (format "
﴾%s﴿
" it))) + (src.title (make-title "What You Write")) + (tgt.title (make-title "What You Get"))) + (format "
%s
 %s 
%s %s
" + src.color src.title src + tgt.color tgt.title tgt)))) diff --git a/tests/osbe-example.yaml b/tests/osbe-example.yaml new file mode 100644 index 0000000..f9d6c45 --- /dev/null +++ b/tests/osbe-example.yaml @@ -0,0 +1,47 @@ +input: |- + Look: + + #+begin_osbe-example + hola + #+end_osbe-example +no-prettier: "t" +expectations: + expansion: |- + #+setupfile: https://gitlab.com/OlMon/org-themes/-/raw/master/src/solarized_light/solarized_light.theme + Look: + +
 The ~rename~ block is for Textual Substitution. For example, as a translation tool:
+
+    #+begin_rename "Allah to God, Yacoub to Jacob, Yusuf to Joseph"
+    Quran 12-4: *_Yusuf_* said to his father ( _*Yacoub*_ ), /“O my father,
+    indeed I have seen (in a dream) eleven stars and the sun and the
+    moon; I saw them prostrating to me.”/
+    #+end_rename
+
+    In the rendered result, the Arabic names are replaced with their English counterparts. 
+ html: |- +

+ Look: +

+ +
 The ~rename~ block is for Textual Substitution. For example, as a translation tool:
+
+    #+begin_rename "Allah to God, Yacoub to Jacob, Yusuf to Joseph"
+    Quran 12-4: *_Yusuf_* said to his father ( _*Yacoub*_ ), /“O my father,
+    indeed I have seen (in a dream) eleven stars and the sun and the
+    moon; I saw them prostrating to me.”/
+    #+end_rename
+
+    In the rendered result, the Arabic names are replaced with their English counterparts. 
+ latex: |- + Look: + +
 The ~rename~ block is for Textual Substitution. For example, as a translation tool:
+
+    #+begin_rename "Allah to God, Yacoub to Jacob, Yusuf to Joseph"
+    Quran 12-4: *_Yusuf_* said to his father ( _*Yacoub*_ ), /“O my father,
+    indeed I have seen (in a dream) eleven stars and the sun and the
+    moon; I saw them prostrating to me.”/
+    #+end_rename
+
+    In the rendered result, the Arabic names are replaced with their English counterparts. 
diff --git a/tests/parallel.yaml b/tests/parallel.yaml index bbf4cd6..1e15ef7 100644 --- a/tests/parallel.yaml +++ b/tests/parallel.yaml @@ -1,185 +1,88 @@ input: |- - In the HTML Export, The result is 2 columns with no rule between - them and it contains the user's text, but ignores the - “#+columnbreak”. - - #+begin_parallel - Hello, to the left! - - #+columnbreak: - A super duper wide middle margin! - - - #+columnbreak: - Goodbye (“God-be-with-ye”) to the right! - - #+columnbreak: - woah + 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/. + + ---------------------------------------------------------------------- + + #+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 + ---------------------------------------------------------------------- - [Soft Columns] Below, the result is 2 columns with a solid BLACK - rule between them and it contains the user's text, but ignores the - “#+columnbreak”. + #+begin_parallel 25% 50% 25% :bar green - #+begin_parallel 2 :bar t - X + *“Hard Columns”:* Alternatively, /for non-uniform column widths, 𝓃 may + instead be a specification of the widths of the columns./ - #+columnbreak: - - Y - - Z - #+end_parallel - - - [Hard Columns] The result is 3 columns with a solid GREEN rule - between them and it contains the user's text along with the - “#+columnbreak” evaluated at the expected positions. - #+begin_parallel 20% 60% 20% :bar green X + #+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! - Y + #+end_parallel - #+columnbreak: + # Moreover: + # → 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. + # \usepackage{multicol} - Z - #+end_parallel -no-prettier: t expectations: html: |-

- In the HTML Export, The result is 2 columns with no rule between - them and it contains the user's text, but ignores the - “#+columnbreak”. -

- -
-

- Hello, to the left! -

- -

- A super duper wide middle margin! -

- - -

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

- -

- woah -

- -
- - -

- [Soft Columns] Below, the result is 2 columns with a solid BLACK - rule between them and it contains the user's text, but ignores the - “#+columnbreak”. -

- -
-

- X + Articles can get lengthy when vertical whitespace is wasted on thin + lines; instead, one could save space by using + parallel columns of text.

-

- Y -

+
+

- Z + “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] The result is 3 columns with a solid GREEN rule - between them and it contains the user's text along with the - “#+columnbreak” evaluated at the expected positions. -

-
+

-

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

- Y +

+ However, this extra flexibility comes at an additional cost: The + contents of the block must now contain 𝓃-1 lines consisting of + @@html:</div><div style="width: 25%; margin: 10px; border-right:4px none; float: left;">@@, when the specification determines 𝓃-many columns.

-

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

-

- Z -

-
+
latex: |- - In the HTML Export, The result is 2 columns with no rule between - them and it contains the user's text, but ignores the - “\#+columnbreak”. - - \par \setlength{\columnseprule}{0 pt} - \begin{minipage}[t]{\linewidth} - \begin{multicols}{2} - Hello, to the left! - - \columnbreak - A super duper wide middle margin! - - - \columnbreak - Goodbye (“God-be-with-ye”) to the right! - - \columnbreak - woah - - - \end{multicols}\end{minipage} - - - {[}Soft Columns] Below, the result is 2 columns with a solid BLACK - rule between them and it contains the user's text, but ignores the - “\#+columnbreak”. - - \par \setlength{\columnseprule}{2 pt} - \begin{minipage}[t]{\linewidth} - \begin{multicols}{2} - X - - \columnbreak - - Y - - Z - - - \end{multicols}\end{minipage} - - - {[}Hard Columns] The result is 3 columns with a solid GREEN rule - between them and it contains the user's text along with the - “\#+columnbreak” evaluated at the expected positions. - \par \setlength{\columnseprule}{2 pt} - \begin{minipage}[t]{\linewidth} - \begin{multicols}{20% 60% 20%} - - \columnbreak - - Y - - \columnbreak - - Z - - - \end{multicols}\end{minipage} + 🚫 The LaTex backend is intentionally unmaintained. + 🫠 Whoops, there seems to be an error: + (void-variable label) diff --git a/tests/rename.yaml b/tests/rename.yaml index 110453f..434c3cb 100644 --- a/tests/rename.yaml +++ b/tests/rename.yaml @@ -7,7 +7,7 @@ input: |- moon; I saw them prostrating to me.”/ #+end_rename - In the rendered result, the Arabic names are replaed with their English counterparts. + In the rendered result, the Arabic names are replaced with their English counterparts. expectations: html: |-