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

Feature request: Generate a table of contents #1456

Open
Levi-Lesches opened this issue Dec 4, 2024 · 3 comments
Open

Feature request: Generate a table of contents #1456

Levi-Lesches opened this issue Dec 4, 2024 · 3 comments

Comments

@Levi-Lesches
Copy link

Levi-Lesches commented Dec 4, 2024

Something like this:

/// A section of the Table of Contents
class TocNode {
  /// What level heading this node is.
  ///
  /// This is not defined by what tag it is using, or how many `#` it has, but rather
  /// how many levels of nesting have occurred in the document so far. That is to say,
  ///
  /// ```md
  /// # Level 1
  /// ### Level 2
  /// ##### Level 3
  /// ```
  int level;

  /// The list of [TocNode] that are nested under this heading.
  List<TocNode> children;

  /// The title of the node, as a string.
  String title;

  /// The parent heading for this node.
  TocNode? parent;

  /// Renders this content to markdown
  List<Node> renderToMarkdown();
}

class Document { 
  /// Generates a Table of Contents for this document. 
  List<TocNode> generateToc();  // or generateTableOfContents()
}

I may be misunderstanding Document here -- its API does not include a List<Node>, so given the typical approach of:

final doc = Document()
final nodes = doc.parse(markdown);

would I need to make a TocNode generataeToc(List<Node> nodes) instead?

Code for parsing can be found at dart-lang/pub-dev#8348. See the discussion there for context, but the motivation is to eventually generate a ToC on the side of Pub package pages.

@Levi-Lesches
Copy link
Author

Levi-Lesches commented Dec 4, 2024

Also cc @hoylen, author of package:markdown_toc -- would an API like this help you? I see you're also using a syntax like 1.2.3 to represent nesting. That seems reasonable to me, maybe we can add that as an optional parameter here?

@hoylen
Copy link

hoylen commented Dec 10, 2024

author of package:markdown_toc -- would an API like this help you?

Not for me, because markdown_toc has already been written without using the markdown package since my utility produces Markdown (text) output rather than HTML output. Also because it needs to treat headings differently: it respects the heading level (i.e. the number of #'s is significant) rather than just nesting, and whether headings are represented using #'s versus underlining is significant.

This proposal assumes the Markdown file was written "correctly" and that definition of correctness goes beyond what the (unfortunately/deliberately loose) Markdown specification dictates. So I suspect different users will want to detect/handle "wrong" Markdown differently, and they have a different idea of what is wrong for them. For example, one user might want to treat bad level nesting as an error (e.g. a #### heading under a ## heading, when a ### heading is missing), but another might allow it.

It seems the markdown package works at the low level Abstract Syntax Tree (AST) level of a Markdown document, but this TocNode class is working at a higher level of abstraction for a Markdown document.

@Levi-Lesches
Copy link
Author

since my utility produces Markdown (text) output rather than HTML output

Just a note, this API's TocNode.renderToMarkdown() would render the node as markdown, not HTML. Either way, you can use the data in the TocNode itself to render in whatever format you'd like.

Also because it needs to treat headings differently: it respects the heading level (i.e. the number of #'s is significant) rather than just nesting, and whether headings are represented using #'s versus underlining is significant.

That could be a boolean option in Document.generateToc(). Normally I'd wonder if that was too specific, but it was also unclear whether this option should be enabled for the Pub.dev pages, so perhaps it should be left generalizable.

Thanks for your input

@mosuem mosuem transferred this issue from dart-lang/markdown Dec 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants