Synopsis
As Extractly is used by Earmark and potentially by EarmarkParser parsing the markdown is not an option (and probably total overkill anyway).
Therefore scanning for lines matching ~r{\A \s{0,3} (#{1,7}) \s+ (.*)}x shall deliver the necessary information.
Sketch
With that in mind such a list shall be obtained by the following pseudo code
lines
|> Enum.map(&Regex.run(~r{\A \s{0,3} (#{1,7}) \s+ (.*)}x, &1)
|> Enum.filter(& &1)
|> Enum.map(fn [_, header, title] -> {String.length(header), title} end)
yielding, e.g. ...
[{1, "Main"}, {2, "Sub 1"}, {2, "Sub 2"}, {3, "SubSub"}, {1, "Epilogue"}]
which than, depending on some options shall yield markdown, e.g.
1. Main
1. Sub 1
1. Sub 2
1. SubSub
1. Epilogue
Options
numbered: 1 value for starting position, nil for unnumbered lists
levels: 7 maximum level of headers taken into account
output: :markdown alternatives like :ast, :html or :json might be a nice enhancement
Limitations
Setext headers are not taken into account, as I do not have a use case for now
Synopsis
As Extractly is used by
Earmarkand potentially byEarmarkParserparsing the markdown is not an option (and probably total overkill anyway).Therefore scanning for lines matching
~r{\A \s{0,3} (#{1,7}) \s+ (.*)}xshall deliver the necessary information.Sketch
With that in mind such a list shall be obtained by the following pseudo code
yielding, e.g. ...
which than, depending on some options shall yield markdown, e.g.
Options
numbered: 1value for starting position,nilfor unnumbered listslevels: 7maximum level of headers taken into accountoutput: :markdownalternatives like:ast,:htmlor:jsonmight be a nice enhancementLimitations
Setext headers are not taken into account, as I do not have a use case for now