Skip to content

feature: prefix section numbers to the headings e.g. 1. / 2.1. #286

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

Closed
WieeRd opened this issue Jan 6, 2025 · 3 comments
Closed

feature: prefix section numbers to the headings e.g. 1. / 2.1. #286

WieeRd opened this issue Jan 6, 2025 · 3 comments
Labels
enhancement New feature or request

Comments

@WieeRd
Copy link

WieeRd commented Jan 6, 2025

Is your feature request related to a problem? Please describe.

I wanted an easier way to distinguish nested levels of the headings.
While giving headings different colors makes it very clear, it was too distracting for me.

Describe the solution you'd like

I suggest an opt-in feature for headings: Section numbering via virtual texts.

# Foo
# Bar
## Baz
1. Foo
2. Bar
2.1. Baz

Section numbers make it easier to see the nested levels of the heading compared to counting the number of #. They also give you an intuitive hint of the structure of the document.

Describe alternatives you've considered

I could obviously add the numbers by myself in the document. But then I need to update the numbers by myself whenever moving or adding new sections. For this reason, I prefer to have the section numbers generated by the tools that render markdown. And rendering is what this plugin does, isn't it?

Additional information

There are 2 concerns about the section numbering.

  1. Preference for top level heading varies (# vs ##)

Some people and conventions prefer to use # at the top of the document only, as a title of the document itself. The rest of the document are nested under it and the actual sections use ## and below.

# Document
## Foo
### Bar
### Baz
## Lorem

Prefixing every heading with 1. is not going to be very helpful in this case. Preferably, the title at the top should not be given numbers and 1. should start at the first ##.

Document
1. Foo
1.1. Bar
1.2. Baz
2. Lorem

It should be fairly easy to detect this since all we need to is to count the number of # headings and make an exception when there is only 1 or 0.

  1. Skipping the intermediate heading levels

Sometimes smaller headings are used without intermediate level headings above them. Could be a mistake from the author, or intentional use to place some notice at the top of the document. Maybe just to get the desired font size.

## Notice
# Section A
### Note
# Section B

My suggestion is to simply use 0 as their (sub)section numbers.

0.1. Notice
1. Section A
1.0.1. Note
2. Section B

This makes it clear that the intermediate levels has been skipped.

@WieeRd WieeRd added the enhancement New feature or request label Jan 6, 2025
MeanderingProgrammer added a commit that referenced this issue Jan 6, 2025
…s input

## Details

Request: #286

This change allows `heading.icons` to be a function which returns a
`string` that will be used as the icon. The input to the function is an
`integer[]` which describes the nesting level of the current heading at
all parent levels.

An example configuration would look like:

```lua
require('render-markdown').setup({
    heading = {
        icons = function(sections)
            return table.concat(sections, '.') .. '. '
        end,
    },
})
```

Which when rendering:

```
# Foo
# Bar
## Baz
```

Results in:

```
1. Foo
2. Bar
2.1. Baz
```
@MeanderingProgrammer
Copy link
Owner

I've implemented a way to do this here: bab0663

The heading icons value can now be a function. The input to the function is the nesting level of the heading through all parent sections. For your basic example you can achieve the desired functionality with:

require('render-markdown').setup({
    heading = {
        icons = function(sections)
            return table.concat(sections, '.') .. '. '
        end,
    },
})

This also lets users use whatever format they want for the label, whether it's period separated, has an ending period, etc.

What I'm not going to handle is all the edge cases with all the ways headings can be nested and make assumptions about the desired functionality.

For users that always have a root at level 1 and don't want that included in the icons they can do something like:

require('render-markdown').setup({
    heading = {
        icons = function(sections)
            table.remove(sections, 1)
            if #sections > 0 then
                return table.concat(sections, '.') .. '. '
            end
        end,
    },
})

Sometimes smaller headings are used without intermediate level headings above them.

Given your example, here is what the input to the function would be given the current implementation:

## Notice -> { 1 }
# Section A -> { 2 }
### Note -> { 2, 1 }
# Section B -> { 3 }

Users can handle this as they would like though I think the result of the simple concatenation is reasonable given the input:

1. Notice
2. Section A
2.1. Note
3. Section B

@greyHairChooseLife
Copy link

Great feature request, best reactive developer. I'd really like to become someone like this person, one day in the future.

I'm leaving a comment to share my config related to this new feature. Honestly, I'm just trying to cheer up these guys, but I hope this might be also helpful for anyone not familiar with Lua, like me.

Adding some icons for level 3 headers
icons = function(sections)
  table.remove(sections, 1)
  if #sections > 0 then
    if #sections == 3 then
      return " "  -- this is font-icon
        .. table.concat(sections, ".")
        .. ". "
    end
    return table.concat(sections, ".") .. ". "
  end
end,

-- as a result

result

@MeanderingProgrammer
Copy link
Owner

Thank you for the kind words :)

I did end up updating the sections calculation logic here: cfe5746

It fills in missing levels with 0 and only counts nesting when the section is at the same level. This ends up producing the result suggested in the issue, i.e.,

0.1. Notice
1. Section A
1.0.1. Note
2. Section B

It also means you can get the level for a heading by using #sections and it will always be correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants