this-month-in-org/2021-11-30-element.txt

371 lines
15 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

━━━━━━━━━━━━━━━━━━━━━━━━━
NOVEMBER 2021
Elementary improvements
TEC
━━━━━━━━━━━━━━━━━━━━━━━━━
2021-11-30
With a 9.5 release highlight post last month, and the month before
skipped, its now /three months/ since the last regular instalment of
TMIO. Lets get back up to date on some of the latest happenings with
Org.
Org as markup
═════════════
Looking at the wider ecosystem, it certainly appears that there is a
growing appetite for Org markup outside org-mode. More projects like
[Hugo] and [Logseq] seem to be interested in supporting Org markup,
and there has been a recent growth in editor extensions like Neovims
[orgmode.nvim] (started in March this year) and Sublime Texts
[OrgExtended] (started in June this year).
Interest in Org as a general-usage markup format can also be seen
within the Org project. Primarily lead by Nicolas Goaziou, there is an
ongoing attempt to codify the Org syntax in a formal specification in
the Worg document [Org Syntax (draft)]. Other members of the Org
mailing list have directed their effort to creating non-elisp parsers
for Org, both to help Org tools be created in other languages, and as
put in the README for Tom Gillespies [laundry] parser
The long term goal of this work is to provide a reference
that can be used to standardize Org syntax and behavior
and to specify various levels of compliance for an
implementation of Org mode.
Earlier this week Karl Voit, the author of the rather well-known
document [Org Mode Is One of the Most Reasonable Markup Languages to
Use for Text], surprised the mailing list by announcing his
independent creation of a multi-leveled standard for Org syntax
subsets called “Orgdown” (the name is a blend of “Org-mode” and
“markdown”, but the standard is only a subset of Org). Each level
defines a compliance score given by a mix of parsing and editing
support, with example compliance scores for the first (and currently
only) level of the standard given for common tools.
At this stage, it isnt clear exactly how the Org-outside-Emacs
landscape will evolve, but the swelling interest is very encouraging.
[Hugo] <https://gohugo.io/>
[Logseq] <https://logseq.com/>
[orgmode.nvim] <https://github.com/nvim-orgmode/orgmode/>
[OrgExtended] <https://packagecontrol.io/packages/OrgExtended>
[Org Syntax (draft)] <https://orgmode.org/worg/dev/org-syntax.html>
[laundry] <https://github.com/tgbugs/laundry>
[Org Mode Is One of the Most Reasonable Markup Languages to Use for
Text] <https://karl-voit.at/2017/09/23/orgmode-as-markup-only/>
An Org parser in Julia
══════════════════════
Speaking of parsers, I may be somewhat biased but Im quite happy that
a Org parser for [Julia] now exists 🎉.
//github.com/tecosaur/OrgMode.jl
OrgMode.jl is a parser, but also intended as a general-purpose Org
library for Julia. Its only been a week since development started,
but it currently supports most of the [Org Syntax] draft
specification, along with the rendering of a parsed Org AST to a TTY
or back to Org text. A few utility functions are also included, such
as `filtermap' which operates similarly to `org-element-map'.
[Julia] <https://julialang.org/>
[Org Syntax] <https://orgmode.org/worg/dev/org-syntax.html>
Autoloading citation backends
═════════════════════════════
One small but impactful change is autoloading of citation
backends. Until recently before say using the `csl' backend, one
needed to `(require 'oc-csl)' or face error messages.
Now, if you have a line like:
┌────
│ #+cite_export: FORMAT ...
└────
org-mode will try to load the file `oc-FORMAT' before trying to
process citations.
This should make getting started with citations in Org just a bit
easier.
A nicer `:tangle-mode' syntax
═════════════════════════════
The standard way of setting a `:tangle-mode' has typically been by
providing a closure that makes use of Elisps octal syntax, such as
`(identity #o755)'. This is unnecessarily verbose, and certainly
doesnt feel natural.
With the addition of a small mode-interpreting function
(`org-babel-interpret-file-mode') It is now possible to specify
`:tangle-mode' using three different forms of shorthand
octal
`o755' is equivalent to `(identity #o755)'
chmod
`chmod'-style inputs like `u+x' are now parsed to a file mode[1]
with the the base/default mode set by
`org-babel-tangle-default-file-mode'.
ls -l
strings of the form given by `ls -l' like `rwxr-xr-x' are also
accepted
This means the following forms are now all equivalent:
┌────
│ :tangle-mode (identity #o755)
│ :tangle-mode o755
│ :tangle-mode a=rx,u+w
│ :tangle-mode rwxr-xr-x
└────
It has also been noted on the mailing list that the `:tangle-mode
(identity #o755)' form works by being transformed to `:tangle-mode
493' during parsing. Similarly `:tangle-mode 755' is equivalent to
`:tangle-mode (identity #o1363)'. For some values the decimal and
octal interpretation are /both/ valid file modes. Due to the clear
potential for confusion, and since file permissions are an important
security consideration, it has been suggested on the mailing list that
these forms should be depreciated with a warning in future. No
decision has been made yet though.
Org element parser cache
════════════════════════
Ihor Radchenko has done some fantastic work over the past few months
by overhauling parts of `org-element.el' to introduce extensive
caching. `org-element' is /the/ Org markup parser inside
org-mode. This allows for a huge jump in speed, and also provides a
few functions which fetch information without updating the cache —
allowing for particularly speedy lookups with a small sacrifice to
correctness guarantees on one or two properties in particular cases.
Several org-mode APIs now make use of the cache to dramatically
improve speed. Aside from improvements to typically slow operations,
this is ideal for situations involving frequent buffer edits. Its no
understatement to say that this work is transformative.
One potential beneficiary from this work is actually fontification. It
has become increasingly apparent that the current regex-based method
for buffer fontification is imperfect, and can actually differ from
the true structure of the document as parsed (authoritatively) by
`org-element'. This has lead to the well-received suggestion on the
mailing list to rewrite the fontification code to be built on
`org-element' instead.
Inline source block fontification
═════════════════════════════════
I think [inline source code blocks] are an underappreciated feature of
Org. I dont think its helped that they have not been visually
treated at all differently from plain text. Now though, they have a
new dedicated face (`org-inline-src-block') /and/ in the same manner
as source blocks, based on `org-src-fontify-natively' can be fontified
using the languages major mode.
<file:figures/inline-src-block-fontified-vs-code.png>
If you arent familiar with inline source blocks, youre missing
out. They are very much the inline cousin of source blocks, and so
support all your favourite Babel features like code execution and
header arguments. This provides a fantastic capacity to inline
dynamically computed expressions, and optionally show the code that
produces them.
<file:figures/inline-src-block-julia-demo.png>
[inline source code blocks]
<https://orgmode.org/manual/Structure-of-Code-Blocks.html>
Functions as default heading arguments
══════════════════════════════════════
Matt Huszagh has contributed a patch that allows functions to be used
as values for default header arguments. This is great for arguments
where a sensible default can be provided by evaluating a function
on-the-fly.
Consider for example the arguments required to produce a simple image
using R with Babel:
┌────
│ #+begin_src R :results graphics file :file myimage.svg
│ library(ggplot2)
│ ggplot(mpg, aes(displ, hwy, colour = class)) + geom_point()
│ #+end_src
└────
In a Jupyter-style (`.ipynb') or throwaway document, we likely dont
care about the file name at all. With these new capabilities, we can
provide a file name dynamically as a default argument!
First we must write a function that when run at the source block will
give us a suitable file name, like so
┌────
│ (defun my/org-src-sha-to-image ()
│ (concat "generated-"
│ (substring
│ (sha1 (org-element-property :value (org-element-at-point)))
│ 0 8)
│ ".svg"))
└────
Lets also write a function to guess whether the source block produces
a plot by checking if theres a plot command on the last line.
┌────
│ (defun my/org-src-guess-results-type ()
│ (if (string-match-p "^ *\\(?:plot\\|ggplot\\)([^\n]+\n?\\'"
│ (org-element-property :value (org-element-at-point)))
│ "graphics file" "replace"))
└────
Then we can just use these function in place of a static value in the
default header arguments variable — thats all it takes.
┌────
│ (setq org-babel-default-header-args:R
│ '((:results . my/org-src-guess-results-type)
│ (:file . my/org-src-sha-to-image)))
└────
This means for most cases we can now get away without any header
arguments at all.
┌────
│ #+begin_src R
│ library(ggplot2)
│ ggplot(mpg, aes(displ, hwy, colour = class)) + geom_point()
│ #+end_src
└────
Its always lovely to see more ways of reducing boilerplate.
Proportional image widths
═════════════════════════
Previously, as long as `org-image-actual-width' was `nil' or a list of
the form `(default-value)', `org-mode' would display images according
to a `:width' attribute (e.g. `#+attr_html: :width 400px') by simply
looking for the first `#+attr_' affiliated keyword and reading the
numeric component of the `:width' as the number of pixels wide the
image should be.
This has now become somewhat fancier. The image-width determining
logic has been extracted to a new function
(`org-display-inline-image--width') which will now extract
floating-point values like `0.7' and interpret them as that portion of
the accessible text width in the buffer.
<file:figures/proportional-image-width.png>
This means that a width parameter like `#+attr_latex: :width
0.7\linewidth' the image will displayed as 70% of the buffer text
width. This also supports percentage value, like `#+attr_html: :width
80%' by dividing the number before the `%' by 100 as a floating-point
value. As always, if you dont like the way display width is inferred
here you can override it by putting a `#+attr_org: :width X' statement
first.
Support for proportional image widths extends to the `(default-value)'
form of `org-image-actual-width', as now if you set it to say `(0.9)'
which will cause images /without/ any width specification to be
displayed at 90% of the buffer text width.
If you want to have some images displayed as their actual width you
can use the new special width parameter `t' to set this on a per-image
basis with `#+attr_org: :width t'. Now all you need to do is remember
to put this first. Based on current discussions on the mailing list
though, soon `#+attr_org' will be prioritised when determining display
image width, no matter which order you put the attributes in. I do
like having one less thing to remember 🙂.
Other improvements
══════════════════
Allow citations immediately following an item bullet _TEC_
Allow citations immediately following a footnote definition _Nicolas
Goaziou_
Update some obsolete function references _Marco Wahl_
`ob-gnuplot' is now maintained by Ihor Radchenko
Improve makescript support for `ORGVERSION' in tag-less mirrors
_Nicholas Vollmer_
New `ob-julia', now maintained by Pedro Bruel
Allow for no indentation, but preserving current indentation by
setting `org-indent-indentation-per-level' to `0' _David Lukes_
Eliminate some byte-compile warnings _Nicholas Vollmer_ _Bastien_
Support Greek smart quotes _Juan Manuel Macías_
`org-mouse' support for intermediate-state checkboxes _Jim Porter_
Allow nested parenthesis in `org-compile-prefix-format' `%(sexp)'
expressions _Ihor Radchenko_
`oc-csl' / citeproc improvements _András Simonyi_
Move more unmaintained/overly niche `ob-*' files to the contrib
repo, reducing the maintainer burden _Bastien_
Allow use of a function for `org-agenda-overriding-header' for
dynamic headers _Christopher League_
Improve `org-protocol' URI decoding _Max Nikulin_
Remove some obsolete LaTeX packages from the default packages list
_TEC_
Add support for text and year citation styles to `oc-csl' _András
Simonyi_
Produce lower-case keywords in `ox-org' _TEC_
Improve `ob-gnuplot' argument processing _Ihor Radchenko_
A collection of `oc-*' improvements _Nicholas Goaziou_
Support bare author citations in `oc-csl' _TEC_
Add `:options' LaTeX attribute to tables _Juan Manuel Macías_
Fix display error with `ob-plantuml' and html export _Su Lin_
More tests! _Ihor Radchenko_
Documentation improvements! _Marco Wahl_ _Stefan Kangas_ _Daniel
Fleischer_ _Wiliam Denton_ _Thomas Dye_ _Bastien_ _Bruce DArcus_
_Kyle Meyer_ _Nicolas Goaziou_
Bugfixes
════════
Fix heading insertion in a case where point is before any heading
_Marco Wahl_
Prevent stringp error when tangling Org from an org-src edit buffer
_Mark Dawson_
Prevent `indent-tabs-mode' from messing with justification in ASCII
exports _Morgan Willcock_
Fix form of default Babel haskell header args _Ihor Radchenko_
No more duplicated logbook entries for repeated tasks _Ihor
Radchenko_
A headline fontification edge case _Sébastien Miquel_
Refactor code that needed Emacs 28 _Kyle Meyer_
Make sure a terminating emphasis marker cant be used as a beginning
emphasis marker in fontification _Ihor Radchenko_
Allow footnotes at footnote definition start _Nicholas Goaziou_
Footnotes
─────────
[1] This is performed easily thanks to
`file-modes-symbolic-to-number', which is used as the basis for both
the `chmod' and `ls -l' shorthand interpretations.