Skip to content

Commit bad6081

Browse files
committed
Feat: book aware redundancy check
1 parent 33e07df commit bad6081

File tree

3 files changed

+46
-24
lines changed

3 files changed

+46
-24
lines changed

README.md

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,15 @@ headings is added.
4242
Changing the default behavior can be done using the vairous named parameters:
4343
```typst
4444
#let hydra(
45-
sel: heading, // the elements to consider
46-
prev-filter: (_, _, _) => true, // check if the last element is eligible
47-
next-filter: (_, _, _) => true, // check if the next element is eligible
48-
display: core.display, // displays the eligible element
49-
paper: "a4", // the paper size to use
50-
page-size: auto, // the smaller page size if set
51-
top-margin: auto, // the top margin is set
52-
loc: none, // a location from which to search
45+
sel: heading, // the elements to consider
46+
prev-filter: (ctx, p, n) => true, // check if the last element is eligible
47+
next-filter: (ctx, p, n) => true, // check if the next element is eligible
48+
display: core.display, // displays the eligible element
49+
is-book: false, // whether the redundancy check should be book aware
50+
paper: "a4", // the paper size to use
51+
page-size: auto, // the smaller page size if set
52+
top-margin: auto, // the top margin is set
53+
loc: none, // a location from which to search
5354
) = {
5455
...
5556
}
@@ -61,10 +62,15 @@ a complicated selector `(heading, h => h.level in (1, 2, 3))`. This function is
6162
matching element in your document.
6263

6364
`loc` can be used in contexts where location is already known, this avoids a call to `locate`,
64-
allowing you to inspect the result of `display` directly. `prev-filter` and `next-filter` are used
65-
to check if an element is eligible for being displayed. They receive the `context`, the previous and
66-
next element relative to the given `loc`, the element thast is checked for is not `none`, but the
67-
other may be.
65+
allowing you to inspect the result of `display` directly.
66+
67+
`prev-filter` and `next-filter` are used to check if an element is eligible for being displayed.
68+
They receive the `context`, the previous and next element relative to the given `loc`, the element
69+
that is checked for is not `none`, but the other may be. These fucntions are executed at most once.
70+
71+
If `is-book` is set to `true`, it will not display the element if it is visible on the previous
72+
open page. This means for a book with `left` binding, if hydra is used on the right page while the
73+
previous section is visible on the left page, it will display nothing.
6874

6975
Of `paper`, `page-size` and `top-margin` exactly one must be given. `paper` and `page-size` are for
7076
convenience aand will be used to calculate the `top-margin` for you. Use them as follows:

src/core.typ

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,19 @@
2020
(prev, next, ctx.loc)
2121
}
2222

23-
// check if the next heading is on the curent page
24-
#let is-redundant(ctx, element) = {
25-
(element.location().page() == ctx.loc.page()
26-
and element.location().position().y <= ctx.top-margin)
23+
// check if the next heading is on the current page
24+
#let is-redundant(ctx, prev, next) = {
25+
let is-next-on-top = (
26+
next.location().page() == ctx.loc.page()
27+
and next.location().position().y <= ctx.top-margin
28+
)
29+
30+
let is-prev-visible = (
31+
ctx.is-book
32+
and calc.odd(ctx.loc.page()) and prev.location().page() == ctx.loc.page() - 1
33+
)
34+
35+
is-next-on-top or is-prev-visible
2736
}
2837

2938
// display the heading as closely as it occured at the given loc

src/lib.typ

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55

66
#let hydra(
77
sel: heading,
8-
prev-filter: (_, _, _) => true,
9-
next-filter: (_, _, _) => true,
8+
prev-filter: (ctx, p, n) => true,
9+
next-filter: (ctx, p, n) => true,
1010
display: core.display,
1111
fallback-next: false,
12+
is-book: false,
1213
paper: "a4",
1314
page-size: auto,
1415
top-margin: auto,
@@ -32,19 +33,25 @@
3233

3334
let func = loc => {
3435
let ctx = (
36+
is-book: is-book,
3537
top-margin: top-margin,
3638
loc: loc,
3739
)
3840

39-
let (last, next, loc) = core.get-adjacent-from(ctx, sel, filter)
41+
let (prev, next, loc) = core.get-adjacent-from(ctx, sel, filter)
4042
ctx.loc = loc
4143

42-
let last-eligible = last != none and prev-filter(ctx, last, next)
43-
let next-eligible = next != none and next-filter(ctx, last, next)
44-
let last-redundant = next-eligible and ctx.top-margin != none and core.is-redundant(ctx, next)
44+
let prev-eligible = prev != none and prev-filter(ctx, prev, next)
45+
let next-eligible = next != none and next-filter(ctx, prev, next)
46+
let prev-redundant = (
47+
prev-eligible
48+
and next-eligible
49+
and ctx.top-margin != none
50+
and core.is-redundant(ctx, prev, next)
51+
)
4552

46-
if last-eligible and not last-redundant {
47-
display(ctx, last)
53+
if prev-eligible and not prev-redundant {
54+
display(ctx, prev)
4855
} else if fallback-next and next-eligible {
4956
display(ctx, next)
5057
}

0 commit comments

Comments
 (0)