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
