emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: "Tom Alexander" <tom@fizz.buzz>
To: emacs-orgmode@gnu.org
Subject: Clarification on blank lines following list items
Date: Sat, 19 Aug 2023 01:30:25 -0400	[thread overview]
Message-ID: <9372527e-3852-419e-936a-7b4dd38cc847@app.fastmail.com> (raw)

I am noticing the list items have some very context-sensitive specific behavior regarding ownership of the trailing blank lines. I was hoping to get some clarification on this (namely, are my observations correct, am I stumbling across a bug, or have I not dug deep enough to suss out the real rules?). The org-mode documentation states:

> With the exception of list items and footnote definitions blank lines belong to the preceding element with the narrowest possible scope

but it does not state who ends up owning those blank lines.

In a previous email the incredibly helpful Ihor Radchenko expanded on this further with:

> Also, in addition to list items, footnote-definitions do not extend their contents to the trailing blank lines.

which, I would interpret as the list items do not own their trailing blank lines but rather the list owns them. But that is not the behavior I am seeing. If I had to summarize the behavior I am seeing into words it would be:

> List items own their trailing blank lines unless they are both the final list item and not the final element of a non-final list item.

Below I have how I reached this conclusion, but before diving into the weeds I want to point two things out:

1. I have hastily thrown together a tool to help rapidly visualize the ownership of nodes in org-mode's AST. Before this tool, I was manually running org-element-parse-buffer and using M-g c to jump around to the various indices to see where nodes started/ended. With this tool, I can paste in my org-mode source and get a tree showing the contents of each node and I can click on the nodes to highlight the relevant characters in the org-mode source. It is available at https://github.com/tomalexander/org_mode_ast_investigation_tool .

2. I have flattened my analysis for plain-text consumption over email below, but if you'd prefer the original org-mode version of this investigation it is available at https://github.com/tomalexander/org_mode_ast_investigation_tool/blob/cba1d1e988be230f3104f5f63dfaeaaf5cd0d280/notes/plain_list_ownership_notes.org .

And now, here is how I reached that conclusion:

*** Test case 1
```
1. foo

   1. bar

   2. baz

2. lorem

ipsum
```
| Plain List *Item*      | Owns trailing blank lines |
|------------------------+---------------------------|
| foo (includes bar baz) | Yes                       |
| bar                    | Yes                       |
| baz                    | Yes                       |
| lorem                  | No                        |

In this test case, we see that the only list item that doesn't own its trailing blank lines is "lorem", the final list item of the outer-most list.


*** Test case 2
We add "cat" as a paragraph at the end of foo which makes "baz" lose its trailing blank lines
```
1. foo

   1. bar

   2. baz

   cat

2. lorem

ipsum
```
| Plain List *Item*             | Owns trailing blank lines |
|-------------------------------+---------------------------|
| foo -> cat (includes bar baz) | Yes                       |
| bar                           | Yes                       |
| baz                           | No                        |
| lorem                         | No                        |

In isolation, this implies that the final plain list item does not own its trailing blank lines, which conflicts with "baz" from test 1.

New theory: List items own their trailing blank lines unless they are both the final list item and not the final element of a list item.

Adding why to the table:
| Plain List *Item*             | Owns trailing blank lines | Why                                                       |
|-------------------------------+---------------------------+-----------------------------------------------------------|
| foo -> cat (includes bar baz) | Yes                       | Not the final list item                                   |
| bar                           | Yes                       | Not the final list item                                   |
| baz                           | No                        | Final item of bar->baz and not the final element of "foo" |
| lorem                         | No                        | Final item of foo->lorem and not contained in a list item |


*** Test case 3
So if that theory is true, taking the entire (foo -> lorem) list from test 1 and nesting it inside a list should coerce "lorem" to own its trailing blank lines since it would then be a final list item (of foo -> lorem) and the final element of the new list.
```
1. cat
   1. foo

      1. bar

      2. baz

   2. lorem

ipsum
```
| Plain List *Item*           | Owns trailing blank lines |
|-----------------------------+---------------------------|
| cat (includes foo -> lorem) | No                        |
| foo (includes bar baz)      | Yes                       |
| bar                         | Yes                       |
| baz                         | Yes                       |
| lorem                       | No                        |

Against expectations, we did not coerce lorem to consume its trailing blank lines. What is different between "baz" and "lorem"? Well, "baz" is contained within "foo" which has a "lorem" after it, whereas "lorem" is contained within "cat" which does not have any list items after it.

New theory: List items own their trailing blank lines unless they are both the final list item and not the final element of a non-final list item.
| Plain List *Item*           | Owns trailing blank lines | Why                                                  |
|-----------------------------+---------------------------+------------------------------------------------------|
| cat (includes foo -> lorem) | No                        | Final list item and not contained in a list item     |
| foo (includes bar baz)      | Yes                       | Not the final list item                              |
| bar                         | Yes                       | Not the final list item                              |
| baz                         | Yes                       | Final element of non-final list item                 |
| lorem                       | No                        | Final list item and final element of final list item |


*** Test case 4
So if that theory is true, then we should be able to coerce lorem to consume its trailing blank lines by adding a second item to the cat list.
```
1. cat
   1. foo

      1. bar

      2. baz

   2. lorem

2. dog

ipsum
```
| Plain List *Item*           | Owns trailing blank lines |
|-----------------------------+---------------------------|
| cat (includes foo -> lorem) | Yes                       |
| foo (includes bar baz)      | Yes                       |
| bar                         | Yes                       |
| baz                         | Yes                       |
| lorem                       | Yes                       |
| dog                         | No                        |

For the first time our expectations were met!

Enduring theory: List items own their trailing blank lines unless they are both the final list item and not the final element of a non-final list item.
| Plain List *Item*           | Owns trailing blank lines | Why                                              |
|-----------------------------+---------------------------+--------------------------------------------------|
| cat (includes foo -> lorem) | Yes                       | Not the final list item                          |
| foo (includes bar baz)      | Yes                       | Not the final list item                          |
| bar                         | Yes                       | Not the final list item                          |
| baz                         | Yes                       | Final element of non-final list item             |
| lorem                       | Yes                       | Final element of non-final list item             |
| dog                         | No                        | Final list item and not contained in a list item |


--
Tom Alexander


             reply	other threads:[~2023-08-19  5:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-19  5:30 Tom Alexander [this message]
2023-08-19  8:43 ` Clarification on blank lines following list items Ihor Radchenko
2023-08-21  1:56   ` Tom Alexander
2023-08-22  7:47     ` Ihor Radchenko
2023-08-22  8:26       ` Ihor Radchenko
2023-08-24 18:46         ` Tom Alexander
2023-09-16 11:26   ` Ihor Radchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9372527e-3852-419e-936a-7b4dd38cc847@app.fastmail.com \
    --to=tom@fizz.buzz \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).