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

First pass at a Table of Contents generator from markdown #8348

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

Levi-Lesches
Copy link

@Levi-Lesches Levi-Lesches commented Dec 2, 2024

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 #3657 (comment)

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;
}

  • 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.

Copy link
Member

@jonasfj jonasfj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@@ -53,6 +53,7 @@ dependencies:
ulid: '2.0.1'
tar: '2.0.0'
api_builder:
simple_mustache: ^2.1.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can't pull in arbitrary dependencies.

Copy link
Author

@Levi-Lesches Levi-Lesches Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not using this package for the parsing code, don't worry.

In the previous thread we decided not to focus on the UI elements of the parsing yet, so I didn't integrate this into the standard Pub package page, and instead make some quick-and-dirty HTML to show off the results. That's what this package is for and should not be used in the final site. For this PR, I'm just focusing on the parsing code itself

@isoos
Copy link
Collaborator

isoos commented Dec 3, 2024

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.

@Levi-Lesches
Copy link
Author

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

@parlough
Copy link
Member

parlough commented Dec 4, 2024

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.

@Levi-Lesches
Copy link
Author

Levi-Lesches commented Dec 4, 2024

@isoos See dart-lang/tools#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.

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

Successfully merging this pull request may close these issues.

4 participants