-
Notifications
You must be signed in to change notification settings - Fork 778
progressive-layout:1.0.0 #3361
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
Open
eusebe
wants to merge
6
commits into
typst:main
Choose a base branch
from
eusebe:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
progressive-layout:1.0.0 #3361
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
1f8d3bf
Add progressive-layout v1.0.0
eusebe cdb7abd
Add LICENSE file and update .gitignore in package
eusebe a1340c6
Remove generated PDF files from package submission
eusebe ed0dfad
Exclude example.typ and demo.typ from package bundle
eusebe 5e39904
Remove [source] section from typst.toml as it's not a valid field for…
eusebe 0a91fc7
Update the README file with correct links to examples
eusebe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| .DS_Store | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| MIT License | ||
|
|
||
| Copyright (c) 2025 David Hajage | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| # progressive-outline | ||
|
|
||
| This package provides a Typst function, `progressive-outline`, to generate a dynamic table of contents, similar to what is found in some LaTeX's Beamer presentations. | ||
|
|
||
| ## Context and Ultimate Goal | ||
|
|
||
| This function was developed to meet a need within the Typst community for displaying partial or progressive outlines, especially in presentations. It is inspired by the following discussions: | ||
|
|
||
| - [GitHub Issue (touying)](https://github.com/touying-typ/touying/issues/137) | ||
| - [Typst Forum](https://forum.typst.app/t/how-to-display-partial-outlines-with-touying/5526) | ||
|
|
||
| The ultimate goal would be to integrate this functionality directly into a presentation package like **[`polylux`](https://typst.app/universe/package/polylux/)**, **[`touying`](https://typst.app/universe/package/touying/)**, or **[`presentate`](https://typst.app/universe/package/presentate/)**. This would allow for the creation of "Beamer-like" presentations where the outline unfolds flexibly as you progress through the slides. Feel free to draw inspiration from this code to contribute to these projects! | ||
|
|
||
| ## Function Usage | ||
|
|
||
| To use the function, import the package and call `progressive-outline` where you want the outline to appear. | ||
|
|
||
| ```typst | ||
| #import "@preview/progressive-layout:1.0.0": progressive-outline | ||
|
|
||
| #progressive-outline( | ||
| h1-style: "all", | ||
| h2-style: "current-and-grayed", | ||
| h3-style: "current", | ||
| show-numbering: true, | ||
| ) | ||
| ``` | ||
|
|
||
| ## Example: The `progressive-layout` Template | ||
|
|
||
| This package also contains a simple template, `progressive-layout`, which shows an example of how to use the function. Here is a minimal code example to test it: | ||
|
|
||
| ```typst | ||
| // Import the template | ||
| #import "@preview/progressive-layout:1.0.0": progressive-layout, progressive-outline | ||
|
|
||
| // Apply the template to your document | ||
| #show: doc => progressive-layout(doc) | ||
|
|
||
| // Your headings... | ||
| = Chapter 1 | ||
| == Section 1.1 | ||
| = Chapter 2 | ||
| ``` | ||
|
|
||
| ## Examples | ||
|
|
||
| This package includes two files to demonstrate its usage: | ||
|
|
||
| - [`example.typ`](https://github.com/eusebe/progressive-layout/blob/main/example.typ): This file shows how the `progressive-outline` function works with different options. | ||
| - [`demo.typ`](https://github.com/eusebe/progressive-layout/blob/main/demo.typ): This file provides an example of how to use the `progressive-layout` template. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would either:
|
||
|
|
||
| ## `progressive-outline` Parameters | ||
|
|
||
| | Parameter | Description | Options | Default | | ||
| | :--- | :--- | :--- | :--- | | ||
| | `h1-style` | Controls the display of level 1 headings. | `"all"`, `"current"`, `"current-and-grayed"`, `"none"` | `"all"` | | ||
| | `h2-style` | Controls the display of level 2 headings. | `"all"`, `"current"`, `"current-and-grayed"`, `"none"` | `"all"` | | ||
| | `h3-style` | Controls the display of level 3 headings. | `"all"`, `"current"`, `"current-and-grayed"`, `"none"` | `"all"` | | ||
| | `scope-h2` | Restricts the display of level 2 headings. | `"all"`, `"current-h1"` | `"current-h1"` | | ||
| | `scope-h3` | Restricts the display of level 3 headings. | `"all"`, `"current-h2"` | `"current-h2"` | | ||
| | `show-numbering` | Shows or hides the numbering of headings. | `true`, `false` | `true` | | ||
|
|
||
| --- | ||
|
|
||
| ## Note on Code Generation | ||
|
|
||
| This package was initially generated with the help of a Large Language Model (LLM). It is a demonstration of what I would like to see one day included in a typst package dedicated to creating presentations, but I am unable to integrate such a feature into the packages I mentioned above in the readme. While functional, it may contain errors, inefficiencies, or programming practices that could be improved. Please use it with discretion and feel free to suggest improvements! | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| // Import the layout function from the local template | ||
| #import "@preview/progressive-layout:1.0.0": progressive-layout, progressive-outline | ||
| // #import "lib.typ": progressive-layout, progressive-outline | ||
|
|
||
| // Apply the layout to the entire document | ||
| #show: doc => progressive-layout(doc, show-numbering: true) | ||
|
|
||
| = First Section : General Introduction | ||
|
|
||
| == Project Context | ||
|
|
||
| #lorem(20) | ||
|
|
||
| == Objectives | ||
|
|
||
| #lorem(20) | ||
|
|
||
| = Second Section : Detailed Analysis | ||
|
|
||
| == Analysis of User's Need | ||
|
|
||
| #lorem(20) | ||
|
|
||
| == Proposed Solutions | ||
|
|
||
| === Solution A | ||
|
|
||
| #lorem(20) | ||
|
|
||
| === Solution B | ||
|
|
||
| #lorem(20) | ||
|
|
||
| = Third Section : Conclusion | ||
|
|
||
| == Appraisal | ||
|
|
||
| #lorem(20) | ||
|
|
||
| == Perspectives | ||
|
|
||
| #lorem(20) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| #import "@preview/progressive-layout:1.0.0": progressive-outline | ||
| // #import "lib.typ": progressive-outline | ||
|
|
||
| #progressive-outline( | ||
| h1-style: "all", | ||
| h2-style: "all", | ||
| h3-style: "all", | ||
| show-numbering: false | ||
| ) | ||
|
|
||
| = Title 1 | ||
|
|
||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. | ||
|
|
||
| #progressive-outline( | ||
| h1-style: "current-and-grayed", | ||
| h2-style: "none", | ||
| h3-style: "none", | ||
| show-numbering: false | ||
| ) | ||
|
|
||
| == Subtitle 1.1 | ||
|
|
||
| Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | ||
|
|
||
| #progressive-outline( | ||
| h1-style: "none", | ||
| h2-style: "current-and-grayed", | ||
| h3-style: "none", | ||
| show-numbering: false | ||
| ) | ||
|
|
||
| === Sub-subtitle 1.1.1 | ||
|
|
||
| Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. | ||
|
|
||
| #progressive-outline( | ||
| h1-style: "none", | ||
| h2-style: "none", | ||
| h3-style: "current-and-grayed", | ||
| show-numbering: false | ||
| ) | ||
|
|
||
| === Sub-subtitle 1.1.2 | ||
|
|
||
| Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. | ||
|
|
||
| #progressive-outline( | ||
| h1-style: "none", | ||
| h2-style: "current", | ||
| h3-style: "current-and-grayed", | ||
| show-numbering: false | ||
| ) | ||
|
|
||
| == Subtitle 1.2 | ||
|
|
||
| Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. | ||
|
|
||
| = Title 2 | ||
|
|
||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. | ||
|
|
||
| #progressive-outline( | ||
| h1-style: "current-and-grayed", | ||
| h2-style: "none", | ||
| h3-style: "none", | ||
| show-numbering: false | ||
| ) | ||
|
|
||
| == Subtitle 2.1 | ||
|
|
||
| Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | ||
|
|
||
| #progressive-outline( | ||
| h1-style: "current", | ||
| h2-style: "current-and-grayed", | ||
| h3-style: "none", | ||
| show-numbering: false | ||
| ) | ||
|
|
||
| == Subtitle 2.2 | ||
|
|
||
| Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. | ||
|
|
||
| = Title 3 | ||
|
|
||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. | ||
|
|
||
| == Subtitle 3.1 | ||
|
|
||
| Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | ||
|
|
||
| == Subtitle 3.2 | ||
|
|
||
| Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| #let progressive-outline( | ||
| h1-style: "all", | ||
| h2-style: "all", | ||
| h3-style: "all", | ||
| scope-h2: "current-h1", | ||
| scope-h3: "current-h2", | ||
| show-numbering: true, | ||
| ) = { | ||
| context { | ||
| let loc = here() | ||
| let all-headings = query(heading.where(outlined: true)) | ||
|
|
||
| let is-before(loc1, loc2) = { | ||
| if loc1.page() < loc2.page() { | ||
| return true | ||
| } | ||
| if loc1.page() == loc2.page() and loc1.position().y < loc2.position().y { | ||
| return true | ||
| } | ||
| return false | ||
| } | ||
|
|
||
| let current-h1 = if query(heading.where(outlined: true, level: 1).before(loc)).len() > 0 { | ||
| query(heading.where(outlined: true, level: 1).before(loc)).last() | ||
| } else { none } | ||
|
|
||
| let current-h2 = if query(heading.where(outlined: true, level: 2).before(loc)).len() > 0 { | ||
| query(heading.where(outlined: true, level: 2).before(loc)).last() | ||
| } else { none } | ||
|
|
||
| let current-h3 = if query(heading.where(outlined: true, level: 3).before(loc)).len() > 0 { | ||
| query(heading.where(outlined: true, level: 3).before(loc)).last() | ||
| } else { none } | ||
|
|
||
| let style-heading(heading, style, current) = { | ||
| let content = if show-numbering { | ||
| numbering("1.1.1", ..counter(heading.func()).at(heading.location())) + " " + heading.body | ||
| } else { | ||
| heading.body | ||
| } | ||
| if style == "all" { | ||
| return content | ||
| } else if style == "current" { | ||
| if heading == current { | ||
| return content | ||
| } else { | ||
| return none | ||
| } | ||
| } else if style == "current-and-grayed" { | ||
| if heading == current { | ||
| return content | ||
| } else { | ||
| return text(fill: gray, content) | ||
| } | ||
| } else if style == "none" { | ||
| return none | ||
| } else { | ||
| return content | ||
| } | ||
| } | ||
|
|
||
| for heading in all-headings { | ||
| let styled-heading = if heading.level == 1 { | ||
| style-heading(heading, h1-style, current-h1) | ||
| } else if heading.level == 2 { | ||
| if scope-h2 == "current-h1" and current-h1 != none { | ||
| let parent-h1 = all-headings.rev().find(h => h.level == 1 and is-before(h.location(), heading.location())) | ||
| if parent-h1 != current-h1 { | ||
| continue | ||
| } | ||
| } | ||
| style-heading(heading, h2-style, current-h2) | ||
| } else if heading.level == 3 { | ||
| if scope-h3 == "current-h2" and current-h2 != none { | ||
| let parent-h2 = all-headings.rev().find(h => h.level == 2 and is-before(h.location(), heading.location())) | ||
| if parent-h2 != current-h2 { | ||
| continue | ||
| } | ||
| } | ||
| style-heading(heading, h3-style, current-h3) | ||
| } else { | ||
| heading.body | ||
| } | ||
|
|
||
| if styled-heading != none { | ||
| let indent = 2em * (heading.level - 1) | ||
| block(pad(left: indent, styled-heading)) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Applies dynamic layout with outlines. | ||
| #let progressive-layout(doc, show-numbering: true) = { | ||
| // --- Base styles --- | ||
| set text(font: "Arial", size: 22pt) | ||
| set page( | ||
| paper: "presentation-16-9", | ||
| margin: (top: 2cm, bottom: 2cm, x: 2cm), | ||
| ) | ||
| set heading(numbering: "1.1.1") | ||
|
|
||
| // --- Display logic --- | ||
|
|
||
| // At the beginning of the document, display the full table of contents. | ||
| outline() | ||
|
|
||
| // For each level 1 heading, display the list of level 2 sub-sections. | ||
| show heading.where(level: 1): it => { | ||
| pagebreak(weak: true) // Each section 1 starts on a new page | ||
| // Display the progressive outline for the current H1, without the heading text itself. | ||
| set text(size: 22pt) // Homogenize font size for the outline | ||
| progressive-outline(h1-style: "current", h2-style: "all", h3-style: "none", show-numbering: show-numbering) | ||
| pagebreak(weak: true) // Start the actual content on a new page | ||
| } | ||
|
|
||
| // For each level 2 heading, display the list of *all* H2s, | ||
| // with the current H2 highlighted. | ||
| show heading.where(level: 2): it => { | ||
| pagebreak(weak: true) // Each H2 starts on a new page | ||
| // Display the progressive outline for the current H2, without the heading text itself. | ||
| set text(size: 22pt) // Homogenize font size for the outline | ||
| progressive-outline(h1-style: "current", h2-style: "current-and-grayed", h3-style: "none", show-numbering: show-numbering) | ||
| pagebreak(weak: true) // Start the actual content on a new page | ||
| } | ||
| // For each level 3 heading, display the list of *all* H3s, | ||
| // with the current H3 highlighted. | ||
| show heading.where(level: 3): it => { | ||
| pagebreak(weak: true) // Each H3 starts on a new page | ||
| // Display the progressive outline for the current H3, without the heading text itself. | ||
| set text(size: 22pt) // Homogenize font size for the outline | ||
| progressive-outline(h1-style: "current", h2-style: "current-and-grayed", h3-style: "current-and-grayed", show-numbering: show-numbering) | ||
| pagebreak(weak: true) // Start the actual content on a new page | ||
| } | ||
|
|
||
| // --- Document content --- | ||
| doc | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| [package] | ||
| name = "progressive-layout" | ||
| version = "1.0.0" | ||
| entrypoint = "lib.typ" | ||
| authors = ["David Hajage <[email protected]>"] | ||
| description = "A Typst function to display a dynamic table of contents, inspired by LaTeX's Beamer class." | ||
| license = "MIT" | ||
| keywords = ["outline", "table of contents", "presentation", "dynamic"] | ||
| compiler = "0.11.0" | ||
| exclude = ["example.typ", "demo.typ"] | ||
| repository = "https://github.com/eusebe/progressive-layout" | ||
|
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is more idiomatic to write
#show doc: progressive-layout, can you please update the example here (and other example files, using.with(...)in case you need to supply other arguments)?