Skip to content

Commit

Permalink
Feat: book aware redundancy check
Browse files Browse the repository at this point in the history
  • Loading branch information
tingerrr committed Nov 24, 2023
1 parent 33e07df commit bad6081
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 24 deletions.
30 changes: 18 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ headings is added.
Changing the default behavior can be done using the vairous named parameters:
```typst
#let hydra(
sel: heading, // the elements to consider
prev-filter: (_, _, _) => true, // check if the last element is eligible
next-filter: (_, _, _) => true, // check if the next element is eligible
display: core.display, // displays the eligible element
paper: "a4", // the paper size to use
page-size: auto, // the smaller page size if set
top-margin: auto, // the top margin is set
loc: none, // a location from which to search
sel: heading, // the elements to consider
prev-filter: (ctx, p, n) => true, // check if the last element is eligible
next-filter: (ctx, p, n) => true, // check if the next element is eligible
display: core.display, // displays the eligible element
is-book: false, // whether the redundancy check should be book aware
paper: "a4", // the paper size to use
page-size: auto, // the smaller page size if set
top-margin: auto, // the top margin is set
loc: none, // a location from which to search
) = {
...
}
Expand All @@ -61,10 +62,15 @@ a complicated selector `(heading, h => h.level in (1, 2, 3))`. This function is
matching element in your document.

`loc` can be used in contexts where location is already known, this avoids a call to `locate`,
allowing you to inspect the result of `display` directly. `prev-filter` and `next-filter` are used
to check if an element is eligible for being displayed. They receive the `context`, the previous and
next element relative to the given `loc`, the element thast is checked for is not `none`, but the
other may be.
allowing you to inspect the result of `display` directly.

`prev-filter` and `next-filter` are used to check if an element is eligible for being displayed.
They receive the `context`, the previous and next element relative to the given `loc`, the element
that is checked for is not `none`, but the other may be. These fucntions are executed at most once.

If `is-book` is set to `true`, it will not display the element if it is visible on the previous
open page. This means for a book with `left` binding, if hydra is used on the right page while the
previous section is visible on the left page, it will display nothing.

Of `paper`, `page-size` and `top-margin` exactly one must be given. `paper` and `page-size` are for
convenience aand will be used to calculate the `top-margin` for you. Use them as follows:
Expand Down
17 changes: 13 additions & 4 deletions src/core.typ
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,19 @@
(prev, next, ctx.loc)
}

// check if the next heading is on the curent page
#let is-redundant(ctx, element) = {
(element.location().page() == ctx.loc.page()
and element.location().position().y <= ctx.top-margin)
// check if the next heading is on the current page
#let is-redundant(ctx, prev, next) = {
let is-next-on-top = (
next.location().page() == ctx.loc.page()
and next.location().position().y <= ctx.top-margin
)

let is-prev-visible = (
ctx.is-book
and calc.odd(ctx.loc.page()) and prev.location().page() == ctx.loc.page() - 1
)

is-next-on-top or is-prev-visible
}

// display the heading as closely as it occured at the given loc
Expand Down
23 changes: 15 additions & 8 deletions src/lib.typ
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

#let hydra(
sel: heading,
prev-filter: (_, _, _) => true,
next-filter: (_, _, _) => true,
prev-filter: (ctx, p, n) => true,
next-filter: (ctx, p, n) => true,
display: core.display,
fallback-next: false,
is-book: false,
paper: "a4",
page-size: auto,
top-margin: auto,
Expand All @@ -32,19 +33,25 @@

let func = loc => {
let ctx = (
is-book: is-book,
top-margin: top-margin,
loc: loc,
)

let (last, next, loc) = core.get-adjacent-from(ctx, sel, filter)
let (prev, next, loc) = core.get-adjacent-from(ctx, sel, filter)
ctx.loc = loc

let last-eligible = last != none and prev-filter(ctx, last, next)
let next-eligible = next != none and next-filter(ctx, last, next)
let last-redundant = next-eligible and ctx.top-margin != none and core.is-redundant(ctx, next)
let prev-eligible = prev != none and prev-filter(ctx, prev, next)
let next-eligible = next != none and next-filter(ctx, prev, next)
let prev-redundant = (
prev-eligible
and next-eligible
and ctx.top-margin != none
and core.is-redundant(ctx, prev, next)
)

if last-eligible and not last-redundant {
display(ctx, last)
if prev-eligible and not prev-redundant {
display(ctx, prev)
} else if fallback-next and next-eligible {
display(ctx, next)
}
Expand Down

0 comments on commit bad6081

Please sign in to comment.