mirror of
https://github.com/foo-dogsquared/wiki.git
synced 2025-02-07 06:19:03 +00:00
Update Org mode Babel note
This commit is contained in:
parent
0a244e1580
commit
439764ce63
@ -1,10 +1,9 @@
|
||||
((org-mode .
|
||||
((org-babel-default-header-args . ((:session . "none")
|
||||
(:results . "output")
|
||||
(:results . "replace output")
|
||||
(:exports . "both")
|
||||
(:cache . "yes")
|
||||
(:noweb . "no")
|
||||
(:hlines . "no")
|
||||
(:cache . "no")
|
||||
(:noweb . "yes")
|
||||
(:tangle . "no")))
|
||||
(org-babel-results-keyword . "results")
|
||||
(org-export-with-toc . t))))
|
||||
|
@ -1,71 +1,109 @@
|
||||
#+title: Org mode: Babel
|
||||
#+date: "2020-04-17 21:41:30 +08:00"
|
||||
#+date_modified: "2021-04-21 17:43:52 +08:00"
|
||||
#+date_modified: "2021-04-22 12:30:38 +08:00"
|
||||
#+language: en
|
||||
#+properties: header-args :session :exports both
|
||||
#+tags: research.reproducibility
|
||||
|
||||
|
||||
Org-babel is the framework that enables [[file:2020-04-20-16-51-40.org][Org mode]] to insert output of the code from programming languages.
|
||||
It is also the one thing that makes Org mode to be used as a tool for [[file:2020-04-12-11-20-53.org][Reproducible research]].
|
||||
As of 2020-06-08, [[https://orgmode.org/worg/org-contrib/babel/languages.html][Babel supports more than 50 languages]] with the possibility of adding of other languages that are not supported yet.
|
||||
Babel is the framework that enables [[file:2020-04-20-16-51-40.org][Org mode]] to be a [[file:2020-04-12-11-20-53.org][Reproducible research]] tool.
|
||||
It is what makes Org mode [[https://orgmode.org/manual/Working-with-Source-Code.html][works with source code blocks]].
|
||||
As of 2021-04-22, [[https://orgmode.org/worg/org-contrib/babel/languages/index.html][Babel supports more than 50 languages]] with the ability to support unsupported languages.
|
||||
Though, it does have its quirks with different languages.
|
||||
Your mileage may vary.
|
||||
|
||||
|
||||
|
||||
|
||||
* The fundamental concepts
|
||||
* Functional and scripting mode
|
||||
|
||||
Here's an example of a code block executed with the shell.
|
||||
Babel works in two modes: functional and scripting mode.
|
||||
|
||||
#+begin_src sh
|
||||
echo "HELLO WORLD"
|
||||
#+end_src
|
||||
- Functional mode returns a value either from the last statement or the return statement.
|
||||
The value can then be used in other source code blocks and appropriately converted into Org mode equivalents.
|
||||
If the return value is a vector type, it will be printed as tables in Org mode which will then be rendered as a vector when used in another source code block.
|
||||
|
||||
#+results:
|
||||
: HELLO WORLD
|
||||
- Scripting mode simply prints the output.
|
||||
Do keep in mind different languages have different ways of capturing the output.
|
||||
[fn:: Most of them involves capturing the stdout.]
|
||||
|
||||
To execute the code block, simply run ~org-babel-execute-src-block~ (by default, this is mapped in ~<C-c> <C-c>~).
|
||||
The results will be printed into a result block.
|
||||
The default mode is in functional mode but you can change it by setting ~:results~ header argument with the values from the [[https://orgmode.org/manual/Results-of-Evaluation.html][collection class]].
|
||||
|
||||
Each of the supported language may also have an exclusive option with each language suitable for certain processes.
|
||||
|
||||
For example, with Python 3, you can pretty print it in accordance to Org mode display.
|
||||
An array will create a table, for instance with ~:results value~ [[https://orgmode.org/manual/Using-Header-Arguments.html#Using-Header-Arguments][header argument]].
|
||||
|
||||
|
||||
* Functional mode values and passing them around
|
||||
|
||||
With functional mode, the value return will appear as an appropriate element in the Org mode buffer.
|
||||
Scalar values will appear as a string and vector values will appear as tables.
|
||||
The following examples are in [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-python.html][Python]].
|
||||
|
||||
#+begin_src python :results value
|
||||
[["Item", "Value"], ["Baseball bat", 123], ["Baseball glove", 25], ["Printed shirt", 42]]
|
||||
return "The quick brown fox jumps over the lazy dog."
|
||||
#+end_src
|
||||
|
||||
#+results:
|
||||
: None
|
||||
: The quick brown fox jumps over the lazy dog.
|
||||
|
||||
You can also export graphics with tools such as [[http://gnuplot.info/][Gnuplot]], [[https://www.gnu.org/software/octave/][GNU Octave]], [[https://www.r-project.org/][R]], and even [[https://www.latex-project.org/][LaTeX]].
|
||||
With it, you can export the graphics into a file (commonly with ~:file <PATH>~).
|
||||
#+name: data
|
||||
#+begin_src python :results value
|
||||
return [
|
||||
["Monty", 45],
|
||||
["Soup", 54],
|
||||
["Cabbages", 63]
|
||||
]
|
||||
#+end_src
|
||||
|
||||
#+begin_src gnuplot :exports both :file assets/2020-04-17-21-41-30/gnuplot-demo.png
|
||||
unset arrow
|
||||
unset label
|
||||
set grid
|
||||
splot x**2+y**2, x**2-y**2
|
||||
#+results: data
|
||||
| Monty | 45 |
|
||||
| Soup | 54 |
|
||||
| Cabbages | 63 |
|
||||
|
||||
To pass values between different code blocks, you have to give the blocks a name.
|
||||
The previous code block was given a name ~data~ and passed it to the next block.
|
||||
|
||||
#+begin_src python :results value :var o=data
|
||||
return o[0]
|
||||
#+end_src
|
||||
|
||||
#+results:
|
||||
[[file:assets/2020-04-17-21-41-30/gnuplot-demo.png]]
|
||||
| Monty | 45 |
|
||||
|
||||
With Org-babel, you can share either the output, the code used to generate the output, or both.
|
||||
This is commonly set with the ~:exports~ header argument.
|
||||
[fn:: Again, this varies whether export options are available for each Babel-supported lanaguages.]
|
||||
|
||||
Here's an example where I decided to show only the output with ~:exports results~.
|
||||
|
||||
#+begin_src gnuplot :exports results :file assets/2020-04-17-21-41-30/gnuplot-3d-demo.png
|
||||
set title "3D gnuplot demo"
|
||||
unset grid
|
||||
splot x*y with points
|
||||
|
||||
* Functions
|
||||
|
||||
With [[https://orgmode.org/worg/org-contrib/babel/intro.html][Babel]], you can call named code blocks anywhere from blocks to inline.
|
||||
This creates a "function" with Babel using different languages.
|
||||
The following block creates ~init~ function with a default value for its argument.
|
||||
|
||||
#+name: init
|
||||
#+header: :var name="world"
|
||||
#+begin_src python :results value silent :exports code
|
||||
return f"Hello {name}"
|
||||
#+end_src
|
||||
|
||||
You can then call the ~init~ function inline with ~call_init[${HEADER_ARGS}](${ARGS})~ which should contain "call_init[:results raw]() Hello world".
|
||||
For blocks, you can use the ~#+call~ block with a similar syntax to inline functions — i.e., ~#+call: init[${HEADER_ARGS}](${ARGS})~.
|
||||
|
||||
#+call: init[:results replace]()
|
||||
|
||||
#+results:
|
||||
[[file:assets/2020-04-17-21-41-30/gnuplot-3d-demo.png]]
|
||||
: Hello world
|
||||
|
||||
You can also use it inside of code blocks with ~<<init>>~ which makes it perfect for code blocks templates like configuring paper output for Lilypond blocks.
|
||||
Though, you have to set ~:noweb yes~ in the header arguments or configure it in ~org-babel-default-header-args~ as one of the default.
|
||||
|
||||
#+name: example
|
||||
#+begin_src shell
|
||||
echo -n <<init(name="Canavan")>>
|
||||
#+end_src
|
||||
|
||||
#+results: example
|
||||
: Hello Canavan
|
||||
|
||||
Babel functions are commonly used for inserting dynamic values.
|
||||
Very helpful in reducing places you need to edit (not to mention less prone to errors).
|
||||
|
||||
|
||||
|
||||
@ -73,84 +111,33 @@ splot x*y with points
|
||||
* Sessions
|
||||
|
||||
Each of the source code block runs on an individual session.
|
||||
However, you can connect source code blocks (with the supported languages) in the same session with ~:session <SESSION NAME>~.
|
||||
However, you can connect source code blocks in the same session with ~:session <SESSION NAME>~.
|
||||
|
||||
Let's start with a simple example where we want to demonstrate some Python shenanigans.
|
||||
Here's one Python code block.
|
||||
|
||||
#+begin_src python :results output :session python-example
|
||||
x = 35
|
||||
#+begin_src python :session python-example
|
||||
x = 30
|
||||
print(x)
|
||||
#+end_src
|
||||
|
||||
#+results:
|
||||
: 35
|
||||
: 30
|
||||
|
||||
Then here's another code block in the same session.
|
||||
|
||||
#+begin_src python :results output :session python-example
|
||||
#+begin_src python :session python-example
|
||||
for i in range(5):
|
||||
x += 5
|
||||
print(x)
|
||||
#+end_src
|
||||
|
||||
#+results:
|
||||
: 35
|
||||
: 40
|
||||
: 45
|
||||
: 50
|
||||
: 55
|
||||
: 60
|
||||
|
||||
In certain code where the output can still change (for example, try executing the previous code block again), this may not be the desired behavior.
|
||||
To correct this, simply execute ~org-babel-execute-buffer~.
|
||||
|
||||
|
||||
|
||||
|
||||
* Integrating between different programming languages
|
||||
|
||||
You can also pass Org mode variables (from ~#+NAME: <VAR>~) [fn:: Technically called an internal link (https://orgmode.org/org.html#Internal-Links).] into the source code blocks with the ~:var <NAMEC>=<DATA>~ (though, this may vary among Babel runtimes).
|
||||
|
||||
#+name: example_string
|
||||
This is the string.
|
||||
|
||||
#+begin_src python :var example=example_string :results value
|
||||
example
|
||||
#+end_src
|
||||
|
||||
#+results:
|
||||
: None
|
||||
|
||||
This is the source code from the document, for reference.
|
||||
|
||||
#+begin_src org :exports code :results silent
|
||||
,#+NAME: example_string
|
||||
This is the string.
|
||||
|
||||
,#+BEGIN_SRC python :var example=example_string :outputs value
|
||||
example
|
||||
,#+END_SRC
|
||||
|
||||
,#+RESULTS:
|
||||
,: This is the string.
|
||||
#+end_src
|
||||
|
||||
Org mode variables does capture an element as its input.
|
||||
This has a lot of implications of passing data between different sessions and even different languages.
|
||||
|
||||
For example, we could still capture the ~x~ variable from the previous Python code blocks.
|
||||
|
||||
#+name: var_from_other_lang
|
||||
#+begin_src python :results silent :session python-example :exports value
|
||||
x # Which should be 60 at this point.
|
||||
#+end_src
|
||||
|
||||
Then, pass it to some other Org mode blocks with the variable.
|
||||
(Since the captured variable are always going to be a string, we have to convert it into the appropriate type.)
|
||||
|
||||
#+begin_src R :results output :var python_var=var_from_other_lang
|
||||
as.numeric(python_var) + 2
|
||||
#+end_src
|
||||
|
||||
#+results:
|
||||
: [1] 62
|
||||
|
40
README.adoc
40
README.adoc
@ -7,13 +7,20 @@
|
||||
Keep taking notes and stop worrying about file organization!
|
||||
|
||||
Muh wiki.
|
||||
This documents the "infrastructure" of my notes because I like documenting.
|
||||
This documents the "infrastructure" of my notes because I like documenting and I always forget things.
|
||||
It primarily uses the link:https://zk.zettel.page/[Zettelkasten note-taking method] which means all of my notes are scattered in just one location.
|
||||
Fun.
|
||||
|
||||
NOTE: On another note, this supercedes my link:https://github.com/foo-dogsquared/personal-notes[personal notes].
|
||||
[NOTE]
|
||||
====
|
||||
On another note, this supersedes my link:https://github.com/foo-dogsquared/personal-notes[personal notes].
|
||||
I'm not going to import them because I want to start on a clean slate.
|
||||
|
||||
Also, not everything on this Git repo is here (at least yet).
|
||||
Some of them are private files and so I want them to not appear anywhere else.
|
||||
Fortunately for me, most of the private files are connected with each other (a separate org-roam instance would be better in this case).
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
@ -45,22 +52,27 @@ footnote:[You can enable the direnv module from the Doom Emacs config.]
|
||||
=== Setting up
|
||||
|
||||
Now with the pieces complete and assuming you've already have my wiki in your folder, fire up Emacs, open the wiki folder, and do your thing.
|
||||
This project has a link:./.dir-locals.el[local Emacs config] (see link:https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html[related section]).
|
||||
If you've set `enable-local-variables` to `:safe` or any value that makes Emacs to ignore them, you may want to configure related variables in a way either conditionally or simply replacing them.
|
||||
|
||||
If you have direnv installed, you can also enable automatic shell environments.
|
||||
How?
|
||||
Just add `.envrc`!
|
||||
|
||||
[source, shell]
|
||||
----
|
||||
echo "use nix" > .envrc && direnv allow
|
||||
----
|
||||
If you have direnv installed, you can also enable automatic shell environments by allowing `.entry` to set it up for you.
|
||||
Just run `direnv allow`!
|
||||
|
||||
If you have link:https://github.com/target/lorri[lorri] installed, you're better to go with the faster startup for the environment.
|
||||
|
||||
|
||||
|
||||
|
||||
== Conventions
|
||||
|
||||
* When create a link between notes, more specific notes should link general notes.
|
||||
This makes it easier to navigate a graph of back links.
|
||||
+
|
||||
IMPORTANT: This is a muddy subject leaning more into explicitly linking a subject without care.
|
||||
Besides, those are what backlinks are for.
|
||||
It's not an absolute rule to follow so don't worry about this, it's just a guideline at best.
|
||||
Otherwise, you'll go through analysis paralysis.
|
||||
|
||||
* Uses timestamp (at localtime) as the filename, it is unique enough (for personal purposes) and doesn't need to change.
|
||||
footnote:[If you use the title as the basis, that'll depend if you have tolerance for the misaligning relation between the filename and the title.]
|
||||
The format for the filename is equivalent to `$(date +%F-%H-%M-%S).org`.
|
||||
@ -118,16 +130,22 @@ For now, I'm not worrying to much on this one.
|
||||
I did create a publication script back then for a small org-mode-based for testing purposes but it is messy and life happened so I wasn't able to get back on it immediately.
|
||||
Here's a link:https://git.sr.ht/~brettgilio/website/[very good example of a org-mode-and-Emacs-powered site] complete with features and without JavaScript!
|
||||
footnote:[link:https://brettgilio.com/[Brett Gilio] is kind enough to answer my noob org-mode related questions back then so big thanks to him for the guidance. :)]
|
||||
The advantage is complete control and the disadvantage is starting from scratch.
|
||||
Still, you can start from already existing solutions.
|
||||
|
||||
** Convert the org documents to commonly-supported text formats like Markdown and use static site generators.
|
||||
Most of them supports Markdown and there is an "export to Markdown" option for org-mode.
|
||||
I could whip up an Elisp script and export it by batch then move them over to an SSG setup like Hugo.
|
||||
This is also how link:https://github.com/jethrokuan/braindump[Jethro Kuan's org-roam notes] are setup.
|
||||
|
||||
** Use a parser outside of Emacs.
|
||||
link:https://github.com/rasendubi/uniorg/tree/master/examples/org-braindump[uniorg] has a good example with Next.js as the site generator.
|
||||
It requires an external JavaScript-based setup but it can also be an advantage.
|
||||
|
||||
* Migrate the notes for link:https://org-roam.discourse.group/t/org-roam-major-redesign/1198[org-roam v2].
|
||||
Though I consider v1 to be feature-complete, I do like v2's reimagining of the plugin with the node (instead of files) as the new atomic unit.
|
||||
It is closer to its original inspiration (Roam Research).
|
||||
It also brings a few simplified options along the way such as choosing to only support `tags` property.
|
||||
It also brings a few simplified options along the way such as choosing to only support `tags` property as well as replacing IDs for linking instead of file links.
|
||||
Aaaand the primary maintainer said more performance so yay for me.
|
||||
|
||||
** Expect to change the links since it doesn't accept file links anymore.
|
||||
|
Loading…
Reference in New Issue
Block a user