Skip to content

Commit

Permalink
gridlock:0.3.0 (#1826)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssotoen authored Feb 24, 2025
1 parent 89d41a5 commit 2cb29aa
Show file tree
Hide file tree
Showing 6 changed files with 308 additions and 0 deletions.
22 changes: 22 additions & 0 deletions packages/preview/gridlock/0.3.0/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Changelog

<!-- ## Added
## Removed
## Changed
## Migration Guide from v0.1.X -->

## v0.3.0 (2025-02-23)

Added option to indent all paragraphs

## v0.2.0 (2024-10-19)

- Added support for Typst 0.12’s new `par.spacing` property
- Replaced a deprecated `location` call with the new `context`

## v0.1.0 (2024-08-06)

Initial Release
24 changes: 24 additions & 0 deletions packages/preview/gridlock/0.3.0/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org/>
70 changes: 70 additions & 0 deletions packages/preview/gridlock/0.3.0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# The `gridlock` Package (v0.3.0)

Grid typesetting in Typst.
Use this package if you want to line up your body text across columns and pages.

## Example

![An example image showing a two-column page with headings, a block quote, a footnote, a figure, a display formula, and a bulleted list. All body text in both columns lines up.](docs/assets/example-lines.png)

## Getting Started

```typ
#import "@preview/gridlock:0.3.0": *
#show: gridlock.with()
#lock[= This is a heading]
#lorem(30)
#figure(
placement: auto,
caption: [a caption],
rect()
)
#lorem(30)
```

## Usage

Check out [the manual](docs/gridlock-manual.pdf) for a detailed description.

To get started, import the package into your document:

```typ
#import "@preview/gridlock:0.3.0": *
```

Set up the basic parameters:

```typ
#show: gridlock.with(
paper: "a4",
margin: (y: 76.445pt),
font-size: 11pt,
line-height: 13pt
)
```

You can now use the `lock()` function to align any block to the text grid.
Block quotes bulleted/numbered lists, and floating figures do _not_ need to be wrapped in `lock()`.
Their spacing is handled fully automatically.

```typ
#lock[= Heading]
#lorem(50)
#lock(figure(
rect(),
caption: [An example figure aligned to the grid.]
))
#lorem(50)
#lock[$ a^2 = b^2 + c^2 $]
#lorem(50)
```
Binary file not shown.
162 changes: 162 additions & 0 deletions packages/preview/gridlock/0.3.0/src/lib.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/// This function deals with the floating figures in your document.
/// You don’t need to call it manually.
///
/// Unfortunately we can’t use ```typc layout()``` here since that messes with the floating.
/// This means that figures wider than the line width are measured before they are shrunk down to fit,
/// which results in inaccurate measurements.
/// To solve this problem, the compiler will remind you to manually set the width of these figures.
///
/// -> content
#let float-adjustment(
/// The figure.
/// -> content
it
) = context {
let body-size = measure(it.body).height

if it.kind == image {
layout(size => {
let container-width = size.width
let body-width = measure(it.body).width

if body-width > container-width {
// TODO: v0.12 might introduce a warning function. could be more appropriate
panic("Make sure none your figures are wider than " + str(container-width/1pt) + "pt.")
}
})
}

let caption-size = measure(it.caption).height
let height = body-size

if it.caption != none {
height = body-size + figure.gap.to-absolute() + caption-size
}

let line-height = text.top-edge

let padding = line-height
while height > padding {
padding += line-height
}
set place(clearance: padding - height + line-height)

it
h(line-height)
}

/// Sets up the basic layout of the document.
/// If you want to change the line height, you need to adjust the vertical margins so that the text area is an exact multiple of the line height.
/// This is necessary because otherwise, floating figures won’t line up with the first/last line on the page.
///
/// To change an element’s line height, use its ```typ top-edge``` property: \
/// ```typ #show heading: set text(top-edge: 18pt)```.
///
/// Note that inline math is wrapped in a ```typc box()``` to ensure a consistent line height.
/// As a side effect, these formulas cannot be broken across lines.
///
/// -> content
#let gridlock(
/// The paper size.
/// -> string
paper: "a4",

/// The margins.
/// To calculate the correct margins, find out how many lines fit on the page and multiply them with the line height.
/// That’s the height of the text area.
/// Subtract this from the page height (default: 841.89~pt) and you get the total height of the vertical margins.
/// Split this up between top and bottom as you like.
///
/// Example for Typst’s default settings (A4 paper, margins 2.5/21 × the page’s shorter edge) with a 13~pt line height:
/// $
/// "lines per page" &= ("page height" - 2 × "vertical margin") / "line height" \
/// &= (841.89 - 2 × 595.28 × 2.5 class("binary", slash) 21) / 13 \
/// &= 53.85… "pt" \ \ \
/// "new vertical margin" &= "page height" - "lines per page" × "line height" \
/// &= 841.89 - 53 × 13 \
/// &= 152.89 "pt"
/// $
///
/// For even margins, simply divide by 2 and you get 76.445~pt (the package’s default setting).
/// You could also, for example, make the bottom margin twice as high as the top margin by setting ```typc (bottom: 101.89pt, top: 51pt)```.
/// -> dictionary
margin: (y: 76.445pt),

///The font size of the body text.
/// -> length
font-size: 11pt,

/// The distance between lines of body text.
/// -> length
line-height: 13pt,

/// If all paragraphs should be indented, not just consecutive ones.
/// -> bool
indent-all: false,

body,
) = {
set page(
paper: paper,
margin: margin,
)

set text(
size: font-size,
top-edge: line-height,
)

set par(
leading: 0pt,
first-line-indent: (amount: line-height, all: indent-all),
justify: true,
spacing: 0pt,
)

set block(spacing: 0pt)
show quote.where(block: true): set block(spacing: line-height)

show heading: set text(top-edge: 1.2em)
show footnote.entry: set text(top-edge: 0.8em)
show math.equation.where(block: false): it => box(height: line-height, it)

show figure.where(placement: top): float-adjustment
show figure.where(placement: bottom): float-adjustment
show figure.where(placement: auto): float-adjustment

body
}

/// This function aligns blocks to the grid.
/// It measures the size of its argument, calculates the appropriate spacing,
/// and applies it using the ```typc pad()``` function.
///
/// Some elements are aligned automatically and do *not* need to be wrapped in ```typc lock()```:
/// / block quotes: These have their spacing set to the line height.
/// If you want to change the spacing, do ```typc #show quote.where(block: true): set block(spacing: 26pt)```.
/// / lists (numbered, bulleted, term): These simply have their spacing set to 0~pt.
/// If you want to change their spacing, use a show rule like with block quotes.
/// / figures with the `placement` argument (floating figures): These are handled automatically with a show rule.
/// Note that you *do* need to wrap non-floating figures in ```typc lock()```.
///
/// -> content
#let lock(
/// The block to be aligned.
/// -> content
body
) = context layout(size => {
let (height,) = measure( block(width: size.width, body), )
let line-height = text.top-edge
let padding = line-height

while height > padding {
padding += line-height
}

let pos = here().position().y
if pos == page.margin.top {
pad(bottom: (padding + line-height - height), body)
} else {
pad(y: (padding - height + (2 * line-height)) / 2, body)
}
})
30 changes: 30 additions & 0 deletions packages/preview/gridlock/0.3.0/typst.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# for a description of available keys, see https://github.com/typst/packages/?tab=readme-ov-file#package-format

[package]
name = "gridlock"
version = "0.3.0"
entrypoint = "src/lib.typ"
authors = ["ssotoen"]
license = "Unlicense"
description = "Grid typesetting in Typst"
repository = "https://github.com/ssotoen/gridlock"
keywords = ["grid"]
categories = ["layout"]
# disciplines = []
compiler = "0.13.0"
exclude = [
".github",
"docs",
"scripts",
"tests",
".typstignore",
"Justfile",
]

# [template]
# path = "template"
# entrypoint = "main.typ"
# thumbnail = "thumbnail.png"

# [tool.mytool]
# foo = "bar"

0 comments on commit 2cb29aa

Please sign in to comment.