Skip to content

Commit bf8936f

Browse files
authored
single-sided mode
1 parent a4a560e commit bf8936f

7 files changed

Lines changed: 142 additions & 69 deletions

File tree

packages/preview/obelisk/0.2.0/README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,19 @@ Obelisk exposes its architectural engine through a centralized configuration dic
6969
### 1. Layout Configuration
7070

7171
```typst
72-
paper: (width, height),
72+
paper: (width, height, two-sided),
7373
margin: (s, e, t, f),
7474
side: (half-gutter, margin),
7575
texts: (size, ascender, step),
7676
```
7777

7878
* **`paper`**: Maps the absolute dimensions of the physical canvas.
7979
* `width` / `height`: Explicit length dimensions. Defaults to A4 size.
80+
* `two-sided`: whether to use a two-sided layout. Defaults to `true`.
8081

8182

8283
* **`margin`**: Uses logical binding scopes to handle alternating page layouts dynamically.
83-
* `s` / `e`: Spine (Inside) and Face (Outside) horizontal margins. The layout engine flips these on odd and even pages to maintain binding gutters.
84+
* `s` / `e`: Spine (Inside) and Face (Outside) horizontal margins. The layout engine flips these on odd and even pages to maintain binding gutters. In single-sided mode, they are right and left margins respectively.
8485
* `t` / `f`: Top and Foot (Bottom) vertical margins, defining the boundaries where the baseline grid activates and terminates.
8586

8687

@@ -127,4 +128,6 @@ headers: (h2: (sym, dy, size), h3: (sym, dy, size))
127128

128129
1. Inline math equations are aligned using a box to adjust its height. However, once it is wrapped inside a box, it becomes unbreakable, so inline long equations may fail to break lines. Also, it may break some packages that rely on the layout of the equation, like `fletcher`. Currently the workaround is that if there is no need to adjust its height, then don't wrap it in a box. This should work most of the time; for extra tall equations, manual adjusting might be needed.
129130

130-
2. Theorem blocks rely on measuring the height of the sidenote. However the current measuring mechanism is somewhat broken and sometimes returns the wrong height for very long paragraphs, a little less than the actual height. Manual adjusting might be needed; you can use `v-step(size)` (size being an integer) to insert spaces. This should not be needed for short texts.
131+
2. The Typst engine will try to automatically increase line height when a inline math equation is particularly tall or deep. This behaviour could sometimes cause the line to shift a little. To fix this, you can adjust the `texts.descender` field to a value such that tall equations are automatically handled by the template, rather than the Typst engine. The default value should be a descent estimate.
132+
133+
3. Theorem blocks rely on measuring the height of the sidenote. However the current measuring mechanism is somewhat broken and sometimes returns the wrong height for very long paragraphs, a little less than the actual height. Manual adjusting might be needed; you can use `v-step(size)` (size being an integer) to insert spaces. This should not be needed for short texts.

packages/preview/obelisk/0.2.0/default.typ

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Paper measures
22
#let width = 21cm
33
#let height = width * calc.sqrt(2)
4-
#let def-paper = (width: width, height: height)
4+
#let def-paper = (width: width, height: height, two-sided: true)
55

66
// Paper margins
77
#let t-margin = width / 9
@@ -25,7 +25,7 @@
2525

2626
// Text measures
2727
#let text-size = 12pt
28-
#let text-height = 9pt // Approximately the ascender height
28+
#let text-height = 10pt // Approximately the ascender height
2929

3030
// Baseline grid
3131
#let step = 16pt
@@ -136,6 +136,7 @@
136136
height: paper.height - margin.t - margin.f,
137137
)
138138
texts.step-num = calc.floor(body.height / texts.step)
139+
texts.descender = texts.step - texts.ascender
139140
margin.f = (
140141
paper.height - margin.t - texts.step-num * texts.step
141142
)

packages/preview/obelisk/0.2.0/headers.typ

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#import "default.typ": default-settings
2-
#import "layout.typ": place-node, blank-page
2+
#import "layout.typ": blank-page, place-node
33

44
#let show-headers(it) = context {
55
let (
6+
paper,
67
margin,
78
fonts,
89
texts,
@@ -23,31 +24,47 @@
2324

2425
show heading.where(level: 1): it => context {
2526
let step = texts.step
26-
blank-page(to: "odd", weak: true)
27+
let two-sided = paper.two-sided
28+
if two-sided {
29+
blank-page(to: "odd", weak: true)
30+
} else {
31+
blank-page(weak: true)
32+
}
2733
let h1 = counter(heading).at(here()).at(0)
28-
place(
29-
top + right,
30-
dx: margin.e + 10pt,
31-
dy: -margin.t - step - 10pt,
32-
box(
33-
stroke: 0.75pt + luma(180),
34-
fill: white,
35-
width: 7cm,
36-
height: 7cm,
37-
align(
38-
center + horizon,
39-
text(
40-
font: fonts.sans,
41-
size: 120pt,
42-
fill: white,
43-
top-edge: "bounds",
44-
bottom-edge: "bounds",
45-
stroke: 1.5pt + luma(180),
46-
[#h1],
47-
),
34+
let boxed = box(
35+
stroke: 0.75pt + luma(180),
36+
fill: white,
37+
width: 7cm,
38+
height: 7cm,
39+
align(
40+
center + horizon,
41+
text(
42+
font: fonts.sans,
43+
size: 120pt,
44+
fill: white,
45+
top-edge: "bounds",
46+
bottom-edge: "bounds",
47+
stroke: 1.5pt + luma(180),
48+
[#h1],
4849
),
4950
),
5051
)
52+
if two-sided {
53+
place(
54+
top + right,
55+
dx: margin.e + 10pt,
56+
dy: -margin.t - step - 10pt,
57+
boxed,
58+
)
59+
} else {
60+
place(
61+
top + left,
62+
dx: -margin.e - 10pt,
63+
dy: -margin.t - step - 10pt,
64+
boxed
65+
)
66+
}
67+
5168
v(step * 12)
5269
text(
5370
size: texts.size * 3.5,

packages/preview/obelisk/0.2.0/layout.typ

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,52 @@
99
#let bblock(it, ..args) = context {
1010
let def = default-settings.get()
1111
let step = def.texts.step
12+
let ascender = def.texts.ascender
1213

1314
set text(top-edge: "bounds", bottom-edge: "bounds")
1415
let height = measure({
1516
set text(top-edge: "bounds", bottom-edge: "bounds")
1617
it
1718
}).height
18-
let desired-height = calc.round(height / step)
19-
block(v(step * 2 / 3), spacing: 0pt, sticky: true)
19+
let desired-height = calc.round(height / step) + 1
2020
block(
2121
height: desired-height * step,
22+
inset: (top: (step - ascender) / 2),
2223
align(horizon, it),
23-
// stroke: 1pt,
2424
above: 0pt,
2525
below: step,
26-
sticky: true,
2726
..args,
2827
)
29-
block(v(step / 3), spacing: 0pt, sticky: true)
28+
}
29+
30+
31+
#let true-metrics(eq) = {
32+
let total = measure(text(
33+
top-edge: "bounds",
34+
bottom-edge: "bounds",
35+
eq,
36+
))
37+
let strut-height = 1000pt
38+
let strut = box(
39+
width: 0pt,
40+
height: strut-height,
41+
baseline: 0pt,
42+
)
43+
44+
let combined = measure(text(
45+
top-edge: "bounds",
46+
bottom-edge: "bounds",
47+
eq + strut,
48+
))
49+
50+
let descender = combined.height - strut-height
51+
let ascender = total.height - descender
52+
53+
return (
54+
height: total.height,
55+
ascender: ascender,
56+
descender: descender,
57+
)
3058
}
3159

3260
#let place-side(it, dx: 0pt, dy: 0pt, ..args) = context {
@@ -37,14 +65,15 @@
3765
let half-gutter = def.side.half-gutter
3866
let e-margin = def.margin.e
3967
let text-height = def.texts.ascender
68+
let two-sided = def.paper.two-sided
4069

4170
let page-num = here().page()
42-
let move = if calc.even(page-num) {
71+
let move = if calc.even(page-num) or not two-sided {
4372
-side-width - half-gutter + dx
4473
} else {
4574
t-width + half-gutter + dx
4675
}
47-
let flush = if calc.even(page-num) {
76+
let flush = if calc.even(page-num) or not two-sided {
4877
right
4978
} else {
5079
left
@@ -69,9 +98,10 @@
6998
#let place-node(sym, dy: 0pt) = context {
7099
let def = default-settings.get()
71100
let half-gutter = def.side.half-gutter
101+
let two-sided = def.paper.two-sided
72102
let page-num = here().page()
73103
let width = measure(sym).width
74-
let dx = if calc.even(page-num) {
104+
let dx = if calc.even(page-num) or not two-sided {
75105
half-gutter + width / 2
76106
} else {
77107
-half-gutter - width / 2
@@ -96,9 +126,10 @@
96126
let f-margin = def.margin.f
97127
let step = def.texts.step
98128
let ascender = def.texts.ascender
129+
let two-sided = def.paper.two-sided
99130

100131
let page-num = counter(page).get().first()
101-
let is-odd = calc.odd(page-num)
132+
let is-odd = calc.odd(page-num) and two-sided
102133

103134
// Get the total number of sblocks in the document
104135
let total-blocks = counter("__obelisk_sblock-id")
@@ -279,10 +310,11 @@
279310

280311
#let sidenote(it, dy: 0pt) = context {
281312
let def = default-settings.get()
313+
let two-sided = def.paper.two-sided
282314
let page-num = here().page()
283315
let posx = here().position().x
284316
sym.wj
285-
let dx = if calc.even(page-num) {
317+
let dx = if calc.even(page-num) or not two-sided {
286318
-posx + def.margin.e
287319
} else {
288320
-posx + def.margin.s

0 commit comments

Comments
 (0)