Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

better defaults for nested ordered lists (distinguish sublist numerals from parent list numerals) #227

Closed
dkg opened this issue Apr 3, 2024 · 15 comments

Comments

@dkg
Copy link
Contributor

dkg commented Apr 3, 2024

When describing an ordered sequence of steps (e.g., in pseudocode in a draft), it's nice to present them as an ordered list (e.g. 1,2,3,4) rather than unordered (just bullets). However, if there are sub-steps in such a presentation, the natural way to present them is with a nested ordered list. But the nested list restarts with same numbering scheme as the outer list, which is pretty confusing.

For example, this text:

1. bar <- Retrieve config
1. foo <- baz(bar)
1. for qux in foo:
    1. Do thing A(qux)
    1. Do thing B(qux)
1. cleanup

renders as:

   1.  bar <- Retrieve config
   2.  foo <- baz(bar)
   3.  for qux in foo:
       1.  Do thing A(qux)
       2.  Do thing B(qux)
   4.  cleanup

Here are two better ways that it could render:

   1.  bar <- Retrieve config
   2.  foo <- baz(bar)
   3.  for qux in foo:
       3.1.  Do thing A(qux)
       3.2.  Do thing B(qux)
   4.  cleanup

or

   1.  bar <- Retrieve config
   2.  foo <- baz(bar)
   3.  for qux in foo:
       a.  Do thing A(qux)
       b.  Do thing B(qux)
   4.  cleanup
@cabo
Copy link
Owner

cabo commented Apr 4, 2024

The format of an ordered list can be specified by the type= attribute, please see RFC 7991: The "xml2rfc" Version 3 Vocabulary.

I think what you are asking is a way for the outer list to be parametrized to supply a type= attribute for any inner list, so it does not have to be repeated for each inner list. It would be easy to add something like type="a" (your second "better way"). Doing something for your first "better way" would require kramdown-rfc to generate the label on the outer list at each point an inner list is encountered (here: something like type="3.%d.", where the 3. is computed from the structure of the outer list, and values of type=, group=, and start=). Second-guessing xml2rfc to this extent is a bit beyond kramdown-rfc's remit. But I can certainly think about helping the second "better way" with pseudo-attributes of the form sub-type, sub-sub-type etc. that get inherited as type and sub-type to the next inner list.

@dkg
Copy link
Contributor Author

dkg commented Apr 18, 2024

@cabo if there is a way to do that from kramdown-rfc, that would be great. You mention it as a way to parameterize the outer list itself, which would definitely be useful. Even more useful (and simple, for my purposes) would be a document-wide setting that applies to all nested, ordered lists.

What i would like ideally is something in the YAML metadata block like:

nested-ordered-types: 1 a i A I

which would make the top-level ordered list type='1', and the next-level ordered list type='a', the third-level ordered list type='i', and so on.

@cabo
Copy link
Owner

cabo commented Apr 18, 2024

Will the code need to consider intervening unordered lists? Or can we start at 1 again if that happens?

1. one
2. two
   - two-left
      a. two-left-a
      b. two-left-b
   - two-right

@cabo
Copy link
Owner

cabo commented Apr 18, 2024

nested-ordered-types: 1 a i A I

Those types can contain spaces, so a space-separated list won't work too well. Probably needs to be

nested-ordered-types: ["1", a, i, A, I]

@dkg
Copy link
Contributor Author

dkg commented Apr 19, 2024

Will the code need to consider intervening unordered lists? Or can we start at 1 again if that happens?

I don't have much of an opinion here -- that seems pretty weird to me, if i'm doing nested ordered lists it's probably because i want to be able to refer to a particular sub-sub-*-item by its coordinates (e.g., "clause 3(b)iii", the way people talk about US legislation) , and i don't see how an intervening unordered list would fit in here.

I'd be fine with any of the following three choices:

  • an intervening unordered list is simply ignored. So with ["1",a,i] and an ordered,unordered,ordered nesting, the first ordered would be "1", and the second ordered would be "a"
  • an intervening unordered list silently consumes a level of the hierarchy. So with the same example, the first ordered would be "1" and the second ordered would be "i".
  • an intervening unordered list resets the rankings. So with the same example, the first ordered would be "1" and the second ordered would also be "1".

@cabo
Copy link
Owner

cabo commented Apr 19, 2024

OK, implementation-wise your number 1 (see what I did here :-) seems easiest.
It is also probably easiest to roll through the array, i.e., putting the shifted off current value back in at the end for the nested items.
Default then can simply be ["1"].

@paulehoffman
Copy link
Collaborator

Is there a reason why we're not trying to follow what would happen from CommonMark? CommonMark puts out HTML, but we can follow how it does levels and nesting instead of inventing our own way.

@cabo
Copy link
Owner

cabo commented Apr 19, 2024 via email

@cabo
Copy link
Owner

cabo commented Apr 20, 2024

I have written the code, but

ietf-tools/xml2rfc#1122

Will push this anyway after some more testing.

@cabo
Copy link
Owner

cabo commented Apr 20, 2024

Now in 1.7.9:

1.7.9 Add option nested_ol_types

Set globally in {::options nested_ol_types="1, i, a" /} (markdown, not YAML header)
or for a single <ol in an IAL {: nested_ol_types="1 (%i) A"}

The value needs to be an array of <ol type= values, expressed as one of:

  1. A YAML array
  2. A string that will be split on commas (with optional blank space following)
  3. A string that will be split on blank space

When testing this, an HTML rendering issue might cause some confusion:
ietf-tools/xml2rfc#1122

@cabo
Copy link
Owner

cabo commented Apr 21, 2024

1.7.10 now also takes nested_ol_types from YAML kramdown_options

As in

kramdown_options:
  nested_ol_types: 1, i, a

(overridden by ::options and by pseudo-attribute on <ol)

@cabo
Copy link
Owner

cabo commented Apr 21, 2024

1.7.11 now also takes an option ol_start_at_first_marker

As in

kramdown_options:
  ol_start_at_first_marker: true

Default: false (for kramdown-rfc backward compatibility)

If true, an ordered list (<ol) will use the number in its first
marker (1 for 1. etc.) as the default value of the start= attribute.

(This increases commonmark compatibility, see #227 (comment))

@cabo
Copy link
Owner

cabo commented Apr 21, 2024

I think the recent changes should address both the original observation and the discussion, so please close this if this works for you.
ietf-tools/xml2rfc#1122 remains though, for now.

@cabo
Copy link
Owner

cabo commented Apr 23, 2024

Nice -- a solution is on its way in ietf-tools/xml2rfc#1123
(If you don't need uppercase roman numerals, everything else appears to work.)

@dkg
Copy link
Contributor Author

dkg commented May 8, 2024

This works great. Thank you, @cabo! Much appreciated.

@dkg dkg closed this as completed May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants