pub-dev icon indicating copy to clipboard operation
pub-dev copied to clipboard

First pass at a Table of Contents generator from markdown

Open Levi-Lesches opened this issue 11 months ago • 4 comments

Related to #8347

This PR doesn't integrate with anything yet, just provides a new script in the app directory, dart run :toc. The script is heavily borrowed from @ramyak-mehra at https://github.com/dart-lang/pub-dev/issues/3657#issuecomment-826173573

This script generates a fake Pub page (couldn't get all the JS/CSS to load) based on flutter_local_notifications. Running the script generates a app/toc_experiment/index.html you can load in a localhost server. The generated page is the standard README plus a table of contents pinned to the side, with functioning links. This PR is not about the exact format of the page but rather about the parsing logic, all contained within app/bin/toc.dart.

To test, fill the content of app/toc_experiment/readme.md with whatever you like (now it has the notifications package), then:

cd app
dart run :toc
cd toc_experiment
dart pub global activate dhttpd
dhttpd --port 8888

Navigate to http://localhost:8888 in your browser, and there should be a functional table of contents!

image


Here's the new API:

/// 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.
  final String title;

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

  • [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR.
Contribution guidelines:

Note that many Dart repos have a weekly cadence for reviewing PRs - please allow for some latency before initial review feedback.

Levi-Lesches avatar Dec 02 '24 13:12 Levi-Lesches

Is TOC generation something we should consider adding to package:markdown directly?

Good point, I think besides the more users for the same feature, we could address the id generation (and customizations on conflicts for the same titles) better at the core library.

isoos avatar Dec 03 '24 14:12 isoos

Makes sense to me -- should I open a PR there instead?

Levi-Lesches avatar Dec 04 '24 01:12 Levi-Lesches

Makes sense to me -- should I open a PR there instead?

I think you should start with an issue there to discuss with its maintainers. I agree this tooling should be shared and accessible, but I'm not sure how much this makes sense in the core markdown package.

I think it might work best as a separate package and if the extension capabilities in package:markdown aren't enough, figuring out how to add them.

parlough avatar Dec 04 '24 03:12 parlough

@isoos See https://github.com/dart-lang/tools/issues/1456

@parlough there's the markdown_toc package which generates a toc as a header inside the markdown source. So it seems people are interested in having something like this, and having a first-party solution can be helpful.

Levi-Lesches avatar Dec 04 '24 04:12 Levi-Lesches

@isoos, thoughts as to the next steps here? https://github.com/dart-lang/tools/issues/1456 didn't get much discussion, but I can still open a PR on the markdown package if you feel that's the right direction.

Levi-Lesches avatar Sep 18 '25 00:09 Levi-Lesches