Hi,

Ihor Radchenko <[email protected]> writes:
> Christian Moe <[email protected]> writes:
>>> Let's think about it more generally. What if we talk about something
>>> like drawer rather than dynamic block. What would be the most sensible
>>> way to include drawer contents?
>>
>> This patch supports multiple elements, and drawers as well as dblocks.
>
> Hmm. What about other greater elements?

Plain lists and their items are already supported, as are tables, and
they can be indexed into. Dynamic blocks are addressed in the patch.
That leaves

- greater blocks (center, quote, and special blocks) ::

  These are all already supported: they can be referenced by NAME, and
  the full text content is passed. One cannot index into them, but they
  can contain NAMEd contents, which can be referenced from Babel.

- drawers :: Also addressed in my last patch, but I now think that
  approach was wrong, and that they should be handled like greater
  blocks: full text only. If one wants to reference a specific element
  inside a drawer, one can NAME it. Crucially, turning drawer export off
  with the =d:nil= option does not make a drawer's contents invisible to
  Babel.

- footnote definitions :: Could be handled, but why would a Babel user
  want to use a footnote as data? I suppose someone would sometimes put
  a table or list into a footnote, but then, again, those elements can
  themselves be NAMEd.

- inlinetasks :: Semantically, even less reason why they should be used
  for Babel data sources. But if they should be handled, I guess they
  should treated like other entries. (Confusingly, in my testing, if I
  set a =CUSTOM_ID= on an inline task, then =:var x=inlinetask= returns the
  text of the whole parent entry, not just the inline task.)

- property drawers :: These are tightly connected with the entries they
  belong to and the other planning metadata that is also available as
  properties of the entry. Maybe we don't need to handle property
  drawers specifically (though something would need to be done for
  zeroth-section property drawers). Since metadata can be collected via
  columnview we don't strictly need to handle it directly at all. But
  for an idea on how to reference entry metadata from Babel more
  generally, see below.

Dynamic blocks, uniquely, require a different approach and can benefit
from indexing into their elements: because any NAME the user adds will
be overwritten, because the built-in dynamic blocks write un-named
tables, and because there is a case (clocktable with =:step=) that writes
more than one table.

In summary, I now think drawers should be handled like greater blocks.
Dynamic blocks are the only greater elements we need to index into
(unless we add support for property drawers, below). Other greater
elements do not need to be indexed into, and some probably don't need to
be passed to Babel blocks in the first place.

>> However, unlike my previous patch, they still have to add 0 as the first
>> dimension if they /want/ to index into the clocktable via the variable
>> reference, the clocktable will have a 3D index. We might want to make it
>> more intuitive still by making the value an element if there's only one,
>> and a list if there are several, so that indexing into the clocktable
>> with a 2D index works as one might expect. (But I only thought of that
>> after preparing everything for this mail, so I leave that for another
>> iteration.) WDYT?
>
> Sounds excessive. I'd rather keep things simple in the code and only add
> features if people request such additional simplification.

Sounds good to me. If you want the first column of the columnview named
"cv", then,

: :var x=cv[0,,0] - not [,0] as when referencing a table directly.

>> About whether or not to update the referenced dblock:
>>
>>>> Maybe block_name(:eval yes), block_name(:eval no),
>>>> block_name(:eval auto) == block_name
>>
>> I'm not sure it's a good idea to use the :eval header. What about
>> wanting a buffer-wide :eval setting, but wanting src blocks and dblocks
>> to behave differently?
[...]
> Buffer-wide settings do not affect reference resolution, AFAIU. Or do I
> miss something?

No, I think that was my misunderstanding. But if 'block_name(:eval yes)'
means e.g.:

: #+begin_src elisp :var x=block_name(:eval yes)[0]

I think you mean:

: #+begin_src elisp :var x=block_name[:eval yes]()[0]

Otherwise org-babel-ref-resolve won't parse it correctly, will it?

And yes, I suppose using =:eval= here specifically for updating dblocks
would not interfere with any other :eval settings, whether buffer-wide
or local. E.g.,

: #+begin_src elisp :eval never-export :var x=block_name[:eval yes]()[0]

would mean the source block is never updated on export, but we can
handle it so the referenced dblock 'block-name' is updated.

This raises the question whether a buffer- or tree-wide :eval setting
with a header-arg property should apply to updating dblocks if the
dblock reference does not specify an :eval setting itself. I think not;
since dblocks are not src blocks, there might be some user confusion
either way, but this way would be worse.

For the same reason, the approach in my last patch, of setting an
:update argument on the referencing src block, was misguided. Yours is
better.

For clarity, though, it might still be worth giving the argument a
different name (=:update= or =:update-dblock=) from existing Babel args
like =:eval= or =:cache=.

>>> As another data point, :var x=heading-id will return all the text past
>>> metadata (`org-babel-ref-headline-body').
>>
>> While we're at it, we might want to consider whether it should also read
>> the metadata (and we could do all of the above in one big
>> org-babel-ref-greater-element function). :) OTOH, people can get the
>> metadata via a dblock, which they can now access with this patch.
>
> Do you mean including metadata verbatim? Or via index, akin to what you
> do for dynamic blocks? I guess that points to handling other greater
> elements.

Does it? I think entry metadata are a specific case, including both
planning information and property drawers, all available as properties,
and we may be interested in all of them, not the property drawer
specifically. Idea for a feature: A specific bracket syntax for
accessing entry properties or lists of properties, with property names
as keys rather than a numeric index, e.g.:

  :var x=entry_id - As now: full text after metadata
  :var x=entry_id[CATEGORY] - a named property
  :var x=entry_id[CUSTOM_ID,CATEGORY,TAGS,DEADLINE] - multiple
  maybe: :var x=entry_id["CATEGORY"] - would we need quotes?
  maybe: :var x=entry_id[*] - all properties
  maybe: :var x=entry_od[ ] - full text including metadata
  
I can see this being occasionally useful, though more for doing fun
things with Org documents than for working with data.

But I don't think it's /necessary/. For Babel purposes, once we are able
to reference a columnview table, we will already be able to reference
entry properties, and planning data can be referenced indirectly via
columnviews.

Again, though, the zeroth-section property drawer would need some
special handling.

> This reminds me that lists are special when reading - only the top level
> is considered. (which is awkward, but intentional)

Yes, why was that, actually? I didn't follow discussions at the time.

It would actually be nice to be able to use an Org list as a convenient
tree structure. Babel does already pass data of arbitrary many
dimensions, and index into it. Maybe it gets complicated if we want to
keep unnumbered/numbered/dictionary distinctions, but it would still be
useful if that information is lost.

Anyway, it's not something I propose to address here.


Regards,
Christian

Reply via email to