ntjess / typst-drafting

Some common drafting utilities for the `typst` document typesetter
The Unlicense
52 stars 2 forks source link

Allow usage of inside/outside #3

Open beingalink opened 9 months ago

beingalink commented 9 months ago

Typst now allows defining margins for inside/outside for bound documents. Would be nice if I could use this package like this, too.

Also, making it possible to define different text alignments depending on if the outside margin is on a left or a right side of a page.

Thanks for this very useful package!

ntjess commented 9 months ago

I am not yet inclined to support this by default since it would greatly increase some of the complexity, but does this work for you?

#import "@preview/drafting:0.1.1": *

#import "utils.typ": *

#let (in-margin, out-margin) = (3in, 0.8in)
#let my-note(..args) = {
  locate(loc => {
    let (l, r) = (out-margin, in-margin)
    if calc.odd(counter(page).at(loc).last()) {
      (l, r) = (r, l)
    }
    margin-note(margin-left: l, margin-right: r, ..args)
  })
}

#set page(
  margin: (inside: in-margin, outside: out-margin),
  paper: "us-letter",
  height: auto,
)
#set-page-properties()

#lorem(50)
#my-note[A right note]
#my-note(side: left)[A left note]
#lorem(50)
#pagebreak()
#lorem(50)
#my-note[A right note]
#my-note(side: left)[A left note]
#lorem(50)

image

beingalink commented 9 months ago

Thank you! That works. I modified the function to automatically do what I want:

#let (in-margin, out-margin) = (3in, 0.8in)
#let my-note(..args) = {
  locate(loc => {
    let (l, r) = (out-margin, in-margin)
    if calc.odd(counter(page).at(loc).last()) {
      (l, r) = (r, l)
      margin-note(margin-left: l, margin-right: r, side: left, ..args)
    } else {
      margin-note(margin-left: l, margin-right: r, side: right, ..args)
    }
  })
}

Would be nice if something like this could be included in the package, but of course it is your decision if the use case fits your conception.

ntjess commented 9 months ago

The reason I'm hesitant is it almost doubles the number of parameters the user must pass to set-page-properties to get things working properly (inside/outside change meanings depending on whether text is ltr or rtl, I'm not sure if odd/even pages will guarantee which margin to use, etc.). I think once #2 is possible (waiting on fundamental typst improvements), this becomes much more doable

ntjess commented 9 months ago

I am inspired by your solution to set the default side to auto, and using whichever margin is larger when unspecified. Then, you don't have to explicitly swap sides when the margin changes

beingalink commented 9 months ago

I am inspired by your solution to set the default side to auto, and using whichever margin is larger when unspecified. Then, you don't have to explicitly swap sides when the margin changes

That would already help tremendously and actually be as well of a solution! :) 👍

fredguth commented 9 months ago

It was not working for me, so I sent a PR with the page oddity check.

mareikep commented 7 months ago

let (in-margin, out-margin) = (3in, 0.8in)

let my-note(..args) = {

locate(loc => { let (l, r) = (out-margin, in-margin) if calc.odd(counter(page).at(loc).last()) { (l, r) = (r, l) margin-note(margin-left: l, margin-right: r, side: left, ..args) } else { margin-note(margin-left: l, margin-right: r, side: right, ..args) } }) }

I came across this when I ran into compiler warnings trying to solve the same issue (switching left/right with different margins depending on odd/even pages). I had found a similar solution and it seemed to work (visually, it produced the desired output), but it throws a warning, that the layout did not converge within 5 attempts. So I tried this solution, which is very similar to mine, and I am getting the very same warning. Has anyone experienced this as well?

ntjess commented 7 months ago

@mareikep thanks for reporting, are you able to share the full source code for your document that generates warnings? It will be much easier for me to identify the cause in that case.

Generally, the only time compiler warnings are unavoidable is when you have >= 4 overlapping notes

mareikep commented 7 months ago

@mareikep thanks for reporting, are you able to share the full source code for your document that generates warnings? It will be much easier for me to identify the cause in that case.

Generally, the only time compiler warnings are unavoidable is when you have >= 4 overlapping notes

Sure, I decided to just create a link to share the source in the Typst app, so it's easiest to reproduce. In this example, commenting out the last margin-note will remove the warning. I have played around with it a lot, depending on how much text is in between two margin-notes and whether it's the left page or not, but haven't figured out yet, what exactly seems to cause the warning.

Hope, you have some fresh ideas :)

ntjess commented 7 months ago

@mareikep the problem is you have locate nested 3 times: hint calls locate, margin-note calls locate (internally), and sticky-hint calls locate. This is what prevents the function from converging. It is instead better to allow your subfunctions to accept loc as an additional argument. I created an additional file called fixed.typ in your code that directly calls margin-note so there is only one nesting of locate and the warning goes away.

mareikep commented 7 months ago

@mareikep the problem is you have locate nested 3 times: hint calls locate, margin-note calls locate (internally), and sticky-hint calls locate. This is what prevents the function from converging. It is instead better to allow your subfunctions to accept loc as an additional argument. I created an additional file called fixed.typ in your code that directly calls margin-note so there is only one nesting of locate and the warning goes away.

Thanks for the hint, unfortunately the drafting package does not pass theloc to the subfunctions, so I had to update the drafting.typ file manually and then import it locally. Works now and - so far - no warnings or errors.