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

Add use-last parameter #19

Merged
merged 2 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/chapters/3-reference.typ
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Defines the candidates that have been found in a specific context.

```typc
(
primary: (prev: content | none, next: content | none),
primary: (prev: content | none, next: content | none, last: content | none),
ancestor: (prev: content | none, next: content | none),
)
```
Expand All @@ -61,6 +61,7 @@ displaying.
next-filter: (context, candidates) => bool,
display: (context, content) => content,
skip-starting: bool,
use-last: bool,
book: bool,
anchor: label | none,
anchor-loc: location,
Expand Down
Binary file modified doc/manual.pdf
Binary file not shown.
46 changes: 29 additions & 17 deletions src/core.typ
Original file line number Diff line number Diff line change
Expand Up @@ -84,43 +84,48 @@
#let get-candidates(ctx, scope-prev: true, scope-next: true) = {
let look-prev = selector(ctx.primary.target).before(ctx.anchor-loc)
let look-next = selector(ctx.primary.target).after(ctx.anchor-loc)
let look-last = look-next

let prev-ancestor = none
let next-ancestor = none

if ctx.ancestors != none {
let prev = query(selector(ctx.ancestors.target).before(ctx.anchor-loc))
let next = query(selector(ctx.ancestors.target).after(ctx.anchor-loc))
let prev-ancestors = query(selector(ctx.ancestors.target).before(ctx.anchor-loc))
let next-ancestors = query(selector(ctx.ancestors.target).after(ctx.anchor-loc))
tingerrr marked this conversation as resolved.
Show resolved Hide resolved

if ctx.ancestors.filter != none {
prev = prev.filter(x => (ctx.ancestors.filter)(ctx, x))
next = next.filter(x => (ctx.ancestors.filter)(ctx, x))
prev-ancestors = prev-ancestors.filter(x => (ctx.ancestors.filter)(ctx, x))
next-ancestors = next-ancestors.filter(x => (ctx.ancestors.filter)(ctx, x))
}

if scope-prev and prev != () {
prev-ancestor = prev.last()
if scope-prev and prev-ancestors != () {
prev-ancestor = prev-ancestors.last()
look-prev = look-prev.after(prev-ancestor.location())
}

if scope-next and next != () {
next-ancestor = next.first()
if scope-next and next-ancestors != () {
next-ancestor = next-ancestors.first()
look-next = look-next.before(next-ancestor.location())
}
}

let prev = query(look-prev)
let next = query(look-next)
let prev-targets = query(look-prev)
let next-targets = query(look-next)
let last-targets = query(look-last)

if ctx.primary.filter != none {
prev = prev.filter(x => (ctx.primary.filter)(ctx, x))
next = next.filter(x => (ctx.primary.filter)(ctx, x))
prev-targets = prev-targets.filter(x => (ctx.primary.filter)(ctx, x))
next-targets = next-targets.filter(x => (ctx.primary.filter)(ctx, x))
last-targets = last-targets.filter(x => (ctx.primary.filter)(ctx, x))
}
last-targets = last-targets.filter(x => x.location().page() == ctx.anchor-loc.page())

let prev = if prev != () { prev.last() }
let next = if next != () { next.first() }
let prev = if prev-targets != () { prev-targets.last() }
let next = if next-targets != () { next-targets.first() }
let last = if last-targets != () { last-targets.last() }

(
primary: (prev: prev, next: next),
primary: (prev: prev, next: next, last: last),
freundTech marked this conversation as resolved.
Show resolved Hide resolved
ancestor: (prev: prev-ancestor, next: next-ancestor),
)
}
Expand Down Expand Up @@ -231,11 +236,18 @@
let candidates = get-candidates(ctx)
let prev-eligible = candidates.primary.prev != none and (ctx.prev-filter)(ctx, candidates)
let next-eligible = candidates.primary.next != none and (ctx.next-filter)(ctx, candidates)
let last-eligible = candidates.primary.last != none and (ctx.next-filter)(ctx, candidates)
let active-redundant = is-active-redundant(ctx, candidates)

if prev-eligible and not active-redundant {
if active-redundant and ctx.skip-starting {
return
}

if ctx.use-last and last-eligible {
(ctx.display)(ctx, candidates.primary.last)
} else if prev-eligible and not active-redundant {
(ctx.display)(ctx, candidates.primary.prev)
} else if next-eligible and not ctx.skip-starting {
} else if next-eligible {
(ctx.display)(ctx, candidates.primary.next)
}
}
5 changes: 5 additions & 0 deletions src/lib.typ
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
/// display. If this is `auto`, the default implementaion will be used.
/// - skip-starting (bool): Whether `hydra` should show the current candidate even if it's on top of
/// the current page.
/// - use-last (bool): If hydra should show the name of the first or last candidate on the page.
// Defaults to false.
/// - dir (direction, auto): The reading direction of the document. If this is `auto`, the text
/// direction is used. Be cautious about leaving this option on `auto` if you switch text
/// direction mid-page and use hydra outside of footers or headers.
Expand All @@ -47,6 +49,7 @@
next-filter: auto,
display: auto,
skip-starting: true,
use-last: false,
dir: auto,
binding: auto,
book: false,
Expand All @@ -57,6 +60,7 @@
util.assert.types("next-filter", next-filter, function, auto)
util.assert.types("display", display, function, auto)
util.assert.types("skip-starting", skip-starting, bool)
util.assert.types("use-last", use-last, bool)
util.assert.enum("dir", dir, ltr, rtl, auto)
util.assert.enum("binding", binding, left, right, auto)
util.assert.types("book", book, bool)
Expand All @@ -78,6 +82,7 @@
next-filter: util.auto-or(next-filter, () => default-filter),
display: util.auto-or(display, () => core.display),
skip-starting: skip-starting,
use-last: use-last,
dir: dir,
binding: binding,
book: book,
Expand Down
1 change: 1 addition & 0 deletions tests/features/use-last/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# added by typst-test
Binary file added tests/features/use-last/basic/ref/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/features/use-last/basic/ref/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/features/use-last/basic/ref/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/features/use-last/basic/ref/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/features/use-last/basic/ref/5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/features/use-last/basic/ref/6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/features/use-last/basic/ref/7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions tests/features/use-last/basic/test.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Synopsis:
// - Setting use-last to true makes hydra use show the last candidate on a page instead of the first

#import "/src/lib.typ": hydra

#set page(
paper: "a7",
header: context hydra(use-last: true),
)
#set heading(numbering: "1.1")
#show heading.where(level: 1): it => pagebreak(weak: true) + it
#set par(justify: true)

= Introduction
#lorem(200)

= Content
== First Section
#lorem(50)
== Second Section
#lorem(100)
== Third section
#lorem(100)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions tests/features/use-last/multiple-ancestors/test.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Synopsis:
// - When there are multiple ancestors on one page hydra should still show the last heading

#import "/src/lib.typ": hydra

#set page(
paper: "a7",
header: context hydra(2, use-last: true),
)
#set heading(numbering: "1.1")
#set par(justify: true)


= Introduction
== First Section
#lorem(50)
== Second Section
#lorem(100)
== Third section
#lorem(50)

= Other
#lorem(10)
== test
#lorem(10)
= More
#lorem(5)
== more tests
#lorem(10)
Loading