Skip to content

RFC: Implementation of outline in HTML export #6148

@pure-chance

Description

@pure-chance

Proposal for the implementation of outline in HTML export

In the ongoing development of the HTML export, one of the elements that has yet to be fully implemented is the outline.

The outline is a crucial feature that helps users navigate through the document structure. It provides a visual representation of the hierarchy of headings and subheadings, making it easier for users to locate specific sections within the document. This issue presents a possible implementation of the outline feature.

In short, outlines should generally have the structure

<nav class="outline">
  <h2>Table of Contents</h2>
  <ol>
    <li><a href="#introduction">Introduction</a></li>
    <li>
        <a href="#background">Background</a>
        <ol>
            <li><a href="#history-of-...">History of ...</a></li>
            <li><a href="#current-research">current research</a></li>
        </ol>
    </li>
  </ol>
</nav>

<!-- -- snip -- -->

<h1 id="introduction">Introduction</h1>
<h2 id="background">Background</h2>
<h3 id="history-of-...">History of ...</h3>
<h3 id="current-research">current research</h3>

Semantic HTML5

Let's discuss semantics for a bit. Typst allows multiple outlines to be generated from a single document, so we cannot make outline a id. Instead it must be a class. Since we want to be able to differentiate between different outlines, we can use a unique class name for each outline. So the class name "outline" is used for all outlines, but each outline can have an additional unique class name for styling purposes.

Naturally, as outlines are a set of navigational elements, the outline should be wrapped in a <nav> element. As outlines can appear anywhere in a document, they should not be wrapped in a <header> element. I also don't believe that outlines should be wrapped in any <div> element, as there are no semantic or styling semantics that would justify it. Anything that you can do with a <div> element can be done with a <nav> element.

Linking

A foundational consideration of this layout is the ability to click on a section of the heading and jump to that section. This happens by linking the id attribute of the heading to the href attribute of the anchor tag. Note that this behaves quite similarly to the behavior of labels and links, and indeed these features will butt against each other in ways that must be carefully considered.

There are two possible paths to go:

The first is to slugify the heading name and use that as the id. If the heading has a label, then use the label as the id. (Since labels do not allow spaces, they should be valid identifiers.) The downside to this is that it makes it impossible to reverse engineer whether a given heading has a label or not.

The second method is to have some special id convention that can be used to identify headings that have labels. This convention could be something like label-<label>. This would allow tools like pandoc to take HTML generated by Typst and convert it back to Typst (provided that you didn't start a heading with label-. I do see the problems with having in hidden invariant like "headings must not start with label-" to ensure correctness when converting back and forth between Typst and HTML, but this is the best I can think of. I'm open to suggestions for an alternative approach.

Arguments

Outline has the following arguments: title, target, depth, indent.

  1. Naturally, title just specifies the text in the first element <h2> of the outline.

  2. target works equivalently to how it does for pdf documents, grabbing all elements that match the selector.

  3. depth works equivalently to how it does for pdf documents, filtering elements that are not within the specified depth.

  4. indent is a stylistic argument that is beyond the scope of this proposal, but should be brought back up when styling is seriously considered.

Outline entries have the following arguments: level, element, fill

  1. level overrides the default level of the outline, specifying which level some entry should go.

  2. element gives the content of some element that (1) is available through the location method, and (2) can be linked to. This implies that all elements that can be linked have to have some method that converts to an id.

All additional functions are stylistic.

Stylization

Fine, I will give my brief and incomplete thoughts on indent and stylization, but consider it separate from the rest of the proposal. Since Typst allows multiple outlines with exactly the same content, but different styles, we need a unique identifier for each outline to bind css to. My initial thought was to use the target, but again, two outlines can have the same target. To avoid this, we can keep track of outlines with the same target and just index them. Things like indented need to be keeping track of which outline(s) they belong to, and generate only css for those outline(s). There is tons more here but again, this is outside of the scope of this proposal.

Conclusion

That's all that I can think of for now. I hope this proposal is helpful in guiding the development of Typst's outline for HTML. I'm sure there are tons of things that I missed, so please leave a comment about your thoughts and suggestions. Thank you for your time and consideration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    htmlRelated to HTML export

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions