Skip to content

Commit

Permalink
pillar:0.3.1 (#1554)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mc-Zen authored Jan 13, 2025
1 parent a9b1167 commit 50237d1
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/preview/pillar/0.3.1/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024-2025 Mc-Zen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

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 OR COPYRIGHT HOLDERS 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.
187 changes: 187 additions & 0 deletions packages/preview/pillar/0.3.1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# Pillar

_Shorthand notations for table column specifications in [Typst](https://typst.app/)._


[![Typst Package](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FMc-Zen%2Fpillar%2Fv0.3.1%2Ftypst.toml&query=%24.package.version&prefix=v&logo=typst&label=package&color=239DAD)](https://typst.app/universe/package/pillar)
[![Test Status](https://github.com/Mc-Zen/pillar/actions/workflows/run_tests.yml/badge.svg)](https://github.com/Mc-Zen/pillar/actions/workflows/run_tests.yml)
[![MIT License](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Mc-Zen/pillar/blob/main/LICENSE)



- [Introduction](#introduction)
- [Column specification](#column-specification)
- [Number alignment](#number-alignment)
- [`pillar.cols()`](#pillarcols)
- [`pillar.table()`](#pillartable)
- [`vline` customization](#vline-customization)

## Introduction
With **pillar**, you can significantly simplify the column setup of tables by unifying the specification of the number, alignment, and separation of columns. This package is in particular designed for scientific tables, which typically have simple styling:


<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://github.com/user-attachments/assets/c0c60651-c682-4968-9ac9-0fa1e8d85dad">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/710ac89b-c03b-4975-8d46-90790ebcea9a">
<img alt="Table of some piano notes and their names and frequencies" src="https://github.com/user-attachments/assets/c0c60651-c682-4968-9ac9-0fa1e8d85dad">
</picture>
</p>

In order to prepare this table with just the built-in methods, some code like the following would be required.
```typ
#table(
columns: 5,
align: (center,) * 4 + (right,),
stroke: none,
[Piano Key], table.vline(), [MIDI Number], [Note Name], [Pitch Name], table.vline(), [$f$ in Hz],
..
)
```
Using **pillar**, the same can be achieved with
```typ
#import "@preview/pillar:0.3.1"
#table(
..pillar.cols("c|ccc|r"),
[Piano Key], [MIDI Number], [Note Name], [Pitch Name], [$f$ in Hz], ..
)
```
or alternatively
```typ
#pillar.table(
cols: "c|ccc|r",
[Piano Key], [MIDI Number], [Note Name], [Pitch Name], [$f$ in Hz], ..
)
```

**Pillar** is designed for interoperability. It uses the powerful standard tables and provides generated arguments for `table`'s `columns`, `align`, `stroke`, and for the specified vertical lines. This means that all features of the built-in tables (and also `show` and `set` rules) can be applied as usual.




## Column specification

This package works with _column specification strings_. Each column is described by its alignment which can be `l` (left), `c` (center), `r` (right), or `a` (auto).

The width of a column can optionally be specified by appending a (relative) length, or fraction in square brackets to the alignment specifier, e.g., `c[2cm]` or `r[1fr]`.

Vertical lines can be added between columns with a `|` character. Double lines can be produced with `||` (see [`vline` customization](#vline-customization)). The stroke of the vertical line can be changed by appending anything that is usually allowed as a stroke argument in square brackets, e.g., `|[2pt]`, `|[red]` or `|[(dash: \"dashed\")]`.

A column specification string may contain any number of spaces (e.g., to improve readability) — all spaces will be ignored.

_If you find yourself writing highly complex column specifications, consider not using this package and resort to the parameters that the built-in tables provide. This package is intended for quick and relatively simple column specifications._

## Number alignment

Choosing capital letters `L`, `C`, `R`, or `A` instead of lower-case letters activates number alignment at the decimal separator for a specific column (similar to the column type "S" of the LaTeX package [siunitx](https://github.com/josephwright/siunitx)). This feature is provided via the Typst package **Zero**. [Here](https://github.com/Mc-Zen/zero) you can read up on the configuration of number formatting.

```typ
#let percm = $"cm"^(-1)$
#pillar.table(
cols: "l|CCCC",
[], [$Δ ν_0$ in #percm], [$B'_ν$ in #percm], [$B''_ν$ in #percm], [$D'_ν$ in #percm],
table.hline(),
[Measurement], [14525.278], [1.41], [1.47], [1.5e-5],
[Uncertainty], [2], [0.3], [0.3], [4e-6],
[Ref. [2]], [14525,74856], [1.37316], [1.43777], [5.401e-6]
)
```


<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://github.com/user-attachments/assets/066cd34e-7043-48c7-b067-e3256e942f14">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/2f1cfd30-00e1-400b-968e-c6ae39939d28">
<img alt="Number alignment" src="https://github.com/user-attachments/assets/066cd34e-7043-48c7-b067-e3256e942f14">
</picture>
</p>


Non-number entries (e.g., in the header) are automatically recognized in some cases and will not be aligned. In ambiguous cases, adding a leading or trailing space tells Zero not to apply alignment to this cell, e.g., `[Voltage ]` instead of `[Voltage]`.


## `pillar.cols()`

This function produces an argument list that may contain arguments for `columns`, `align`, `stroke`, and `column-gutter` as well as instances of `table.vline()`. These arguments are intended to be expanded with the `..` syntax into the argument list of `table` as shown in the examples.

## `pillar.table()`

This is a thin wrapper that behaves just like the built-in `table`, except that it extracts the first positional argument if it is a string, and runs it through `pillar.cols()`.

## `vline` customization

In order to customize the default line setting, just use set rules on `table.vline`, e.g.,
```typ
#set table.vline(stroke: .7pt)
#table(..pillar.cols("c|cc"), ..)
```

Double lines are currently experimental and are realized through column gutters. They could also be realized through patterns, but this can produce artifacts with some renderers. As it currently is, double lines are not supported before the first and after the last column. On the other hand, with the current method, double lines are styled with set rules on `table.vline` which is nice and not achievable in the same way with patterns.

## Examples

### Double lines
The following example uses a double line for visually separating repeated table columns.
```typ
#pillar.table(
cols: "ccc ||[.7pt] ccc",
..([\#], [$α$ in °], [$β$ in °]) * 2,
table.hline(),
[1], [34.3], [11.1], [6], [34.0], [12.9],
[2], [34.2], [11.2], [7], [34.3], [12.8],
[3], [34.6], [11.4], [8], [33.9], [11.9],
[4], [34.7], [10.3], [9], [34.4], [11.8],
[5], [34.3], [11.1], [10], [34.4], [11.8],
)
```


<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://github.com/user-attachments/assets/e05e7bad-61b6-44f9-af34-5e558f338cdc">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/f1134ce3-dbd0-4a73-895d-544c3c9f2645">
<img alt="Demonstration example using double vertical lines" src="https://github.com/user-attachments/assets/e05e7bad-61b6-44f9-af34-5e558f338cdc">
</picture>
</p>

### Further customization

This example shows the codes of the first ten printable ASCII characters, demonstrating stroke and column width customization.

```typ
#pillar.table(
cols: "ccc|ccc|[1.8pt + blue] l[5cm]",
[Dec],[Hex],[Bin],[Symbol], [HTML code], [HTML name], [Description],
table.hline(),
[32], [20], [00100000], [&#32;], [], [SP], [Space],
[33], [21], [00100001], [&#33;], [&excl;], [!], [Exclamation mark],
[34], [22], [00100010], [&#34;], [&quot;], ["], [Double quotes],
[35], [23], [00100011], [&#35;], [&num;], [\#], [Number sign],
[36], [24], [00100100], [&#36;], [&dollar;], [\$], [Dollar sign],
[37], [25], [00100101], [&#37;], [&percnt;], [%], [Percent sign],
[38], [26], [00100110], [&#38;], [&amp;], [&], [Ampersand],
[39], [27], [00100111], [&#39;], [&apos;], ['], [Single quote],
[40], [28], [00101000], [&#40;], [&lparen;], [(], [Opening parenthesis],
[41], [29], [00101001], [&#41;], [&rparen;], [)], [Closing parenthesis],
)
```

<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://github.com/user-attachments/assets/9fae998e-033d-4d7e-9344-fe3778bbd9e6">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/e6c82d82-aa5e-4ea7-9517-a644b9f9355e">
<img alt="Demonstration example using double vertical lines" src="https://github.com/user-attachments/assets/9fae998e-033d-4d7e-9344-fe3778bbd9e6">
</picture>
</p>

## Tests
This package uses [typst-test](https://github.com/tingerrr/typst-test/) for running [tests](tests/).
95 changes: 95 additions & 0 deletions packages/preview/pillar/0.3.1/src/impl.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#import "@preview/zero:0.3.2": ztable

#let stdstroke = stroke
#let stdtable = table

#let cols(spec, stroke: auto, line-distance: 1.6pt) = {
assert(type(spec) == str, message: "expected a `str` argument, got `" + str(type(spec)) + "`")

let aligns = (r: right, c: center, l: left, a: auto)
let format = ()

let align = ()
let columns = ()
let vline-specs = ()

let i = 0
let col = 0
let count-vlines = 0

while i < spec.len() {
let c = spec.at(i)
if lower(c) in "lcra" {
align.push(aligns.at(lower(c)))
format.push(if lower(c) == c { none } else { auto })
columns.push(auto)
col += 1
count-vlines = 0
} else if c == "|" {
count-vlines += 1
vline-specs.push((col, count-vlines, stroke))
assert(count-vlines <= 2, message: "At most two consecutive `|` are supported. ")
} else if c == "[" {
let end = spec.slice(i).position("]")
if end == none {
assert(false, message: "Unmatched `[`")
}
let width = eval(spec.slice(i + 1, i + end))
if count-vlines == 0 {
assert(columns.len() > 0, message: "Unexpected width specification `" + spec.slice(i, i + end + 1) + "` at the beginning")
assert(width == auto or type(width) in (relative, length, fraction), message: "column width expects a relative length, fraction, or auto, found " + str(type(width)))
columns.last() = width
} else {
assert(width == none or type(width) in (length, color, gradient, pattern, dictionary, stdstroke), message: "vline stroke expects a length, color, gradient, pattern, dictionary, stroke, or none, found " + str(type(width)))
vline-specs.last().last() = width
}
i += end

} else if c == " " {

} else {
if c == "]" { assert(false, message: "Unexpected `]`") }
assert(false, message: "Unknown column type `" + c + "`")
}
i += 1
}
let vlines = ()
let column-gutter = (auto,) * columns.len()
for (col, num, stroke) in vline-specs {
let vline = table.vline
if stroke != auto { vline = vline.with(stroke: stroke) }
if num == 2 {
assert(col != 0 and col != columns.len(), message: "Double lines `||` are currently not supported before the first and after the last column. ")
vlines.push(vline(x: col - 1, position: end))
column-gutter.at(col - 1) = line-distance
}
vlines.push(vline(x: col))
}

if auto in format { format = (format: format) }
else { format = (:) }

arguments(
columns: columns,
align: align,
stroke: none,
column-gutter: column-gutter,
..vlines,
..format
)
}



#let table(..children) = {
let named = children.named()
if "cols" in named {
let colspec = named.cols
named.remove("cols")
return ztable(
..cols(colspec),
..named,
..children.pos()
)
} else { return stdtable(..children) }
}
1 change: 1 addition & 0 deletions packages/preview/pillar/0.3.1/src/pillar.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#import "impl.typ": cols, table
13 changes: 13 additions & 0 deletions packages/preview/pillar/0.3.1/typst.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "pillar"
version = "0.3.1"
entrypoint = "src/pillar.typ"
authors = ["Mc-Zen <https://github.com/Mc-Zen>"]
license = "MIT"
description = "Faster column specifications for tables."
compiler = "0.11.0"

repository = "https://github.com/Mc-Zen/pillar"
keywords = ["table", "tabular", "columns", "latex", "siunitx S column", "number alignment"]
categories = ["visualization", "layout"]
exclude = ["/docs/*"]

0 comments on commit 50237d1

Please sign in to comment.