mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Spruce up table docs (#3593)
This commit is contained in:
parent
639a8d0dc0
commit
15ac6c3166
@ -36,9 +36,19 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// There are multiple sizing modes for columns and rows that can be used to
|
||||
/// create complex layouts.
|
||||
///
|
||||
/// The sizing of the grid is determined by the track sizes specified in the
|
||||
/// arguments. Because each of the sizing parameters accepts the same values, we
|
||||
/// will explain them just once, here. Each sizing argument accepts an array of
|
||||
/// While the grid and table elements work very similarly, they are intended for
|
||||
/// different use cases and carry different semantics. The grid element is
|
||||
/// intended for presentational and layout purposes, while the
|
||||
/// [`{table}`]($table) element is intended for, in broad terms, presenting
|
||||
/// multiple related data points. In the future, Typst will annotate its output
|
||||
/// such that screenreaders will annouce content in `table` as tabular while a
|
||||
/// grid's content will be announced no different than multiple content blocks
|
||||
/// in the document flow. Set and show rules on one of these elements do not
|
||||
/// affect the other.
|
||||
///
|
||||
/// A grid's sizing is determined by the track sizes specified in the arguments.
|
||||
/// Because each of the sizing parameters accepts the same values, we will
|
||||
/// explain them just once, here. Each sizing argument accepts an array of
|
||||
/// individual track sizes. A track size is either:
|
||||
///
|
||||
/// - `{auto}`: The track will be sized to fit its contents. It will be at most
|
||||
@ -60,22 +70,10 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// instead of an array. For example, `columns:` `{3}` is equivalent to
|
||||
/// `columns:` `{(auto, auto, auto)}`.
|
||||
///
|
||||
/// # Styling the grid
|
||||
/// The grid's appearance can be customized through different parameters, such
|
||||
/// as `fill` to give all cells a background; `align` to change how cells are
|
||||
/// aligned; `inset` to optionally add internal padding to each cell; and
|
||||
/// `stroke` to optionally enable grid lines with a certain stroke.
|
||||
///
|
||||
/// If you need to override one of the above options for a single cell, you can
|
||||
/// use the [`grid.cell`]($grid.cell) element. Alternatively, if you need the
|
||||
/// appearance options to depend on a cell's position (column and row), you may
|
||||
/// specify a function to `fill` or `align` of the form
|
||||
/// `(column, row) => value`. You may also use a show rule on
|
||||
/// [`grid.cell`]($grid.cell) - see that element's examples or the examples
|
||||
/// below for more information.
|
||||
///
|
||||
/// # Examples
|
||||
/// The example below demonstrates the different track sizing options.
|
||||
/// The example below demonstrates the different track sizing options. It also
|
||||
/// shows how you can use [`grid.cell`]($grid.cell) in to make an individual
|
||||
/// cell span two grid tracks.
|
||||
///
|
||||
/// ```example
|
||||
/// // We use `rect` to emphasize the
|
||||
@ -94,8 +92,10 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// rect[1/3 of the remains],
|
||||
/// rect[2/3 of the remains],
|
||||
/// rect(height: 100%)[Fixed height],
|
||||
/// image("tiger.jpg", height: 100%),
|
||||
/// image("tiger.jpg", height: 100%),
|
||||
/// grid.cell(
|
||||
/// colspan: 2,
|
||||
/// image("tiger.jpg", width: 100%),
|
||||
/// ),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
@ -110,60 +110,42 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// Additionally, you can use [`grid.cell`]($grid.cell) in various ways to
|
||||
/// not only style each cell based on its position and other fields, but also
|
||||
/// to determine the cell's preferential position in the table.
|
||||
/// # Styling the grid
|
||||
/// The grid's appearance can be customized through different parameters. These
|
||||
/// are the most important ones:
|
||||
///
|
||||
/// ```example
|
||||
/// #set page(width: auto)
|
||||
/// #show grid.cell: it => {
|
||||
/// if it.y == 0 {
|
||||
/// // The first row's text must be white and bold.
|
||||
/// set text(white)
|
||||
/// strong(it)
|
||||
/// } else {
|
||||
/// // For the second row and beyond, we will show the day number for each
|
||||
/// // cell.
|
||||
/// - [`fill`]($grid.fill) to give all cells a background
|
||||
/// - [`align`]($grid.align) to change how cells are aligned
|
||||
/// - [`inset`]($grid.inset) to optionally add internal padding to each cell
|
||||
/// - [`stroke`]($grid.stroke) to optionally enable grid lines with a certain
|
||||
/// stroke
|
||||
///
|
||||
/// // In general, a cell's index is given by cell.x + columns * cell.y.
|
||||
/// // Days start in the second grid row, so we subtract 1 row.
|
||||
/// // But the first day is day 1, not day 0, so we add 1.
|
||||
/// let day = it.x + 7 * (it.y - 1) + 1
|
||||
/// if day <= 31 {
|
||||
/// // Place the day's number at the top left of the cell.
|
||||
/// // Only if the day is valid for this month (not 32 or higher).
|
||||
/// place(top + left, dx: 2pt, dy: 2pt, text(8pt, red.darken(40%))[#day])
|
||||
/// }
|
||||
/// it
|
||||
/// }
|
||||
/// }
|
||||
/// If you need to override one of the above options for a single cell, you can
|
||||
/// use the [`grid.cell`]($grid.cell) element. Likewise, you can override
|
||||
/// individual grid lines with the [`grid.hline`]($grid.hline) and
|
||||
/// [`grid.vline`]($grid.vline) elements.
|
||||
///
|
||||
/// #grid(
|
||||
/// fill: (x, y) => if y == 0 { gray.darken(50%) },
|
||||
/// columns: (30pt,) * 7,
|
||||
/// rows: (auto, 30pt),
|
||||
/// // Events will be written at the bottom of each day square.
|
||||
/// align: bottom,
|
||||
/// inset: 5pt,
|
||||
/// stroke: (thickness: 0.5pt, dash: "densely-dotted"),
|
||||
/// Alternatively, if you need the appearance options to depend on a cell's
|
||||
/// position (column and row), you may specify a function to `fill` or `align`
|
||||
/// of the form `(column, row) => value`. You may also use a show rule on
|
||||
/// [`grid.cell`]($grid.cell) - see that element's examples or the examples
|
||||
/// below for more information.
|
||||
///
|
||||
/// [Sun], [Mon], [Tue], [Wed], [Thu], [Fri], [Sat],
|
||||
/// Locating most of your styling in set and show rules is recommended, as it
|
||||
/// keeps the grid's or table's actual usages clean and easy to read. It also
|
||||
/// allows you to easily change the grid's appearance in one place.
|
||||
///
|
||||
/// // This event will occur on the first Friday (sixth column).
|
||||
/// grid.cell(x: 5, fill: yellow.darken(10%))[Call],
|
||||
/// ## Stroke styling precedence
|
||||
/// There are three ways to set the stroke of a grid cell: through
|
||||
/// [`{grid.cell}`'s `stroke` field]($grid.cell.stroke), by using
|
||||
/// [`{grid.hline}`]($grid.hline) and [`{grid.vline}`]($grid.vline), or by
|
||||
/// setting the [`{grid}`'s `stroke` field]($grid.stroke). When multiple of
|
||||
/// these settings are present and conflict, the `hline` and `vline` settings
|
||||
/// take the highest precedence, followed by the `cell` settings, and finally
|
||||
/// the `grid` settings.
|
||||
///
|
||||
/// // This event will occur every Monday (second column).
|
||||
/// // We have to repeat it 5 times so it occurs every week.
|
||||
/// ..(grid.cell(x: 1, fill: red.lighten(50%))[Meet],) * 5,
|
||||
///
|
||||
/// // This event will occur at day 19.
|
||||
/// grid.cell(x: 4, y: 3, fill: orange.lighten(25%))[Talk],
|
||||
///
|
||||
/// // These events will occur at the second week, where available.
|
||||
/// grid.cell(y: 2, fill: aqua)[Chat],
|
||||
/// grid.cell(y: 2, fill: aqua)[Walk],
|
||||
/// )
|
||||
/// ```
|
||||
/// Furthermore, strokes of a repeated grid header or footer will take
|
||||
/// precedence over regular cell strokes.
|
||||
#[elem(scope, LayoutMultiple)]
|
||||
pub struct GridElem {
|
||||
/// The column sizes.
|
||||
@ -209,13 +191,16 @@ pub struct GridElem {
|
||||
///
|
||||
/// ```example
|
||||
/// #grid(
|
||||
/// fill: (col, row) => if calc.even(col + row) { luma(240) } else { white },
|
||||
/// fill: (col, row) =>
|
||||
/// if calc.even(col + row) { luma(230) }
|
||||
/// else { white },
|
||||
/// align: center + horizon,
|
||||
/// columns: 4,
|
||||
/// inset: 2pt,
|
||||
/// [X], [O], [X], [O],
|
||||
/// [O], [X], [O], [X],
|
||||
/// [X], [O], [X], [O],
|
||||
/// [O], [X], [O], [X]
|
||||
/// [O], [X], [O], [X],
|
||||
/// )
|
||||
/// ```
|
||||
#[borrowed]
|
||||
@ -225,17 +210,11 @@ pub struct GridElem {
|
||||
///
|
||||
/// This can either be a single alignment, an array of alignments
|
||||
/// (corresponding to each column) or a function that returns an alignment.
|
||||
/// The function is passed the cells' column and row index, starting at zero.
|
||||
/// If set to `{auto}`, the outer alignment is used.
|
||||
/// The function is passed the cells' column and row index, starting at
|
||||
/// zero. If set to `{auto}`, the outer alignment is used.
|
||||
///
|
||||
/// ```example
|
||||
/// #grid(
|
||||
/// columns: 3,
|
||||
/// align: (x, y) => (left, center, right).at(x),
|
||||
/// [Hello], [Hello], [Hello],
|
||||
/// [A], [B], [C],
|
||||
/// )
|
||||
/// ```
|
||||
/// You can find an example for this argument at the
|
||||
/// [`table.align`]($table.align) parameter.
|
||||
#[borrowed]
|
||||
pub align: Celled<Smart<Alignment>>,
|
||||
|
||||
@ -249,31 +228,81 @@ pub struct GridElem {
|
||||
/// multiple specific cells, consider specifying one or more of
|
||||
/// [`grid.hline`]($grid.hline) and [`grid.vline`]($grid.vline) alongside
|
||||
/// your grid cells.
|
||||
///
|
||||
/// ```example
|
||||
/// #set page(height: 13em, width: 26em)
|
||||
///
|
||||
/// #let cv(..jobs) = grid(
|
||||
/// columns: 2,
|
||||
/// inset: 5pt,
|
||||
/// stroke: (x, y) => if x == 0 and y > 0 {
|
||||
/// (right: (
|
||||
/// paint: luma(180),
|
||||
/// thickness: 1.5pt,
|
||||
/// dash: "dotted"
|
||||
/// ))
|
||||
/// },
|
||||
/// grid.header(grid.cell(colspan: 2)[
|
||||
/// *Professional Experience*
|
||||
/// #box(width: 1fr, line(length: 100%, stroke: luma(180)))
|
||||
/// ]),
|
||||
/// ..{
|
||||
/// let last = none
|
||||
/// for job in jobs.pos() {
|
||||
/// (
|
||||
/// if job.year != last [*#job.year*],
|
||||
/// [
|
||||
/// *#job.company* - #job.role _(#job.timeframe)_ \
|
||||
/// #job.details
|
||||
/// ]
|
||||
/// )
|
||||
/// last = job.year
|
||||
/// }
|
||||
/// }
|
||||
/// )
|
||||
///
|
||||
/// #cv(
|
||||
/// (
|
||||
/// year: 2012,
|
||||
/// company: [Pear Seed & Co.],
|
||||
/// role: [Lead Engineer],
|
||||
/// timeframe: [Jul - Dec],
|
||||
/// details: [
|
||||
/// - Raised engineers from 3x to 10x
|
||||
/// - Did a great job
|
||||
/// ],
|
||||
/// ),
|
||||
/// (
|
||||
/// year: 2012,
|
||||
/// company: [Mega Corp.],
|
||||
/// role: [VP of Sales],
|
||||
/// timeframe: [Mar - Jun],
|
||||
/// details: [- Closed tons of customers],
|
||||
/// ),
|
||||
/// (
|
||||
/// year: 2013,
|
||||
/// company: [Tiny Co.],
|
||||
/// role: [CEO],
|
||||
/// timeframe: [Jan - Dec],
|
||||
/// details: [- Delivered 4x more shareholder value],
|
||||
/// ),
|
||||
/// (
|
||||
/// year: 2014,
|
||||
/// company: [Glorbocorp Ltd],
|
||||
/// role: [CTO],
|
||||
/// timeframe: [Jan - Mar],
|
||||
/// details: [- Drove containerization forward],
|
||||
/// ),
|
||||
/// )
|
||||
/// ```
|
||||
#[resolve]
|
||||
#[fold]
|
||||
pub stroke: Celled<Sides<Option<Option<Arc<Stroke>>>>>,
|
||||
|
||||
/// How much to pad the cells' content.
|
||||
///
|
||||
/// ```example
|
||||
/// #grid(
|
||||
/// inset: 10pt,
|
||||
/// fill: (_, row) => (red, blue).at(row),
|
||||
/// [Hello],
|
||||
/// [World],
|
||||
/// )
|
||||
///
|
||||
/// #grid(
|
||||
/// columns: 2,
|
||||
/// inset: (
|
||||
/// x: 20pt,
|
||||
/// y: 10pt,
|
||||
/// ),
|
||||
/// fill: (col, _) => (red, blue).at(col),
|
||||
/// [Hello],
|
||||
/// [World],
|
||||
/// )
|
||||
/// ```
|
||||
/// You can find an example for this argument at the
|
||||
/// [`table.inset`]($table.inset) parameter.
|
||||
#[fold]
|
||||
pub inset: Celled<Sides<Option<Rel<Length>>>>,
|
||||
|
||||
@ -508,6 +537,10 @@ impl TryFrom<Content> for GridItem {
|
||||
}
|
||||
|
||||
/// A repeatable grid header.
|
||||
///
|
||||
/// If `repeat` is set to `true`, the header will be repeated across pages. For
|
||||
/// an example, refer to the [`table.header`]($table.header) element and the
|
||||
/// [`grid.stroke`]($grid.stroke) parameter.
|
||||
#[elem(name = "header", title = "Grid Header")]
|
||||
pub struct GridHeader {
|
||||
/// Whether this header should be repeated across pages.
|
||||
@ -520,6 +553,11 @@ pub struct GridHeader {
|
||||
}
|
||||
|
||||
/// A repeatable grid footer.
|
||||
///
|
||||
/// Just like the [`grid.header`]($grid.header) element, the footer can repeat
|
||||
/// itself on every page of the table.
|
||||
///
|
||||
/// No other grid cells may be placed after the footer.
|
||||
#[elem(name = "footer", title = "Grid Footer")]
|
||||
pub struct GridFooter {
|
||||
/// Whether this footer should be repeated across pages.
|
||||
@ -533,9 +571,12 @@ pub struct GridFooter {
|
||||
|
||||
/// A horizontal line in the grid.
|
||||
///
|
||||
/// Overrides any per-cell stroke, including stroke specified through the
|
||||
/// grid's `stroke` field. Can cross spacing between cells created through
|
||||
/// the grid's `column-gutter` option.
|
||||
/// Overrides any per-cell stroke, including stroke specified through the grid's
|
||||
/// `stroke` field. Can cross spacing between cells created through the grid's
|
||||
/// `column-gutter` option.
|
||||
///
|
||||
/// An example for this function can be found at the
|
||||
/// [`table.hline`]($table.hline) element.
|
||||
#[elem(name = "hline", title = "Grid Horizontal Line")]
|
||||
pub struct GridHLine {
|
||||
/// The row above which the horizontal line is placed (zero-indexed).
|
||||
@ -644,53 +685,46 @@ pub struct GridVLine {
|
||||
pub position: OuterHAlignment,
|
||||
}
|
||||
|
||||
/// A cell in the grid. Use this to either override grid properties for a
|
||||
/// particular cell, or in show rules to apply certain styles to multiple cells
|
||||
/// at once.
|
||||
/// A cell in the grid. You can use this function in the argument list of a grid
|
||||
/// to override grid style properties for an individual cell or manually
|
||||
/// positioning it within the grid. You can also use this function in show rules
|
||||
/// to apply certain styles to multiple cells at once.
|
||||
///
|
||||
/// For example, you can override the fill, alignment or inset for a single
|
||||
/// cell:
|
||||
/// For example, you can override the position and stroke for a single cell:
|
||||
///
|
||||
/// ```example
|
||||
/// >>> #set page(width: auto)
|
||||
/// >>> #set text(15pt, font: "Noto Sans Symbols 2", bottom-edge: -.2em)
|
||||
/// <<< #set text(15pt, font: "Noto Sans Symbols 2")
|
||||
/// #show regex("[♚-♟︎]"): set text(fill: rgb("21212A"))
|
||||
/// #show regex("[♔-♙]"): set text(fill: rgb("111015"))
|
||||
///
|
||||
/// #grid(
|
||||
/// columns: 2,
|
||||
/// fill: red,
|
||||
/// align: left,
|
||||
/// inset: 5pt,
|
||||
/// [ABC], [ABC],
|
||||
/// grid.cell(fill: blue)[C], [D],
|
||||
/// grid.cell(align: center)[E], [F],
|
||||
/// [G], grid.cell(inset: 0pt)[H]
|
||||
/// fill: (x, y) => rgb(
|
||||
/// if calc.odd(x + y) { "EFF0F3" }
|
||||
/// else { "7F8396" }
|
||||
/// ),
|
||||
/// columns: (1em,) * 8,
|
||||
/// rows: 1em,
|
||||
/// align: center + horizon,
|
||||
///
|
||||
/// [♜], [♞], [♝], [♛], [♚], [♝], [♞], [♜],
|
||||
/// [♟], [♟], [♟], [♟], [], [♟], [♟], [♟],
|
||||
/// grid.cell(
|
||||
/// x: 4, y: 3,
|
||||
/// stroke: blue.transparentize(60%)
|
||||
/// )[♟],
|
||||
///
|
||||
/// ..(grid.cell(y: 6)[♙],) * 8,
|
||||
/// ..([♖], [♘], [♗], [♕], [♔], [♗], [♘], [♖])
|
||||
/// .map(grid.cell.with(y: 7)),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// You may also apply a show rule on `grid.cell` to style all cells at once,
|
||||
/// which allows you, for example, to apply styles based on a cell's position:
|
||||
///
|
||||
/// ```example
|
||||
/// #show grid.cell: it => {
|
||||
/// if it.y == 0 {
|
||||
/// // First row is bold
|
||||
/// strong(it)
|
||||
/// } else if it.x == 1 {
|
||||
/// // Second column is italicized
|
||||
/// // (except at the first row)
|
||||
/// emph(it)
|
||||
/// } else {
|
||||
/// // Remaining cells aren't changed
|
||||
/// it
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #grid(
|
||||
/// columns: 3,
|
||||
/// gutter: 3pt,
|
||||
/// [Name], [Age], [Info],
|
||||
/// [John], [52], [Nice],
|
||||
/// [Mary], [50], [Cool],
|
||||
/// [Jake], [49], [Epic]
|
||||
/// )
|
||||
/// ```
|
||||
/// which allows you, for example, to apply styles based on a cell's position.
|
||||
/// Refer to the examples of the [`table.cell`]($table.cell) element to learn
|
||||
/// more about this.
|
||||
#[elem(name = "cell", title = "Grid Cell", Show)]
|
||||
pub struct GridCell {
|
||||
/// The cell's body.
|
||||
@ -710,14 +744,21 @@ pub struct GridCell {
|
||||
/// position before cells with automatic positions).
|
||||
///
|
||||
/// ```example
|
||||
/// #let circ(c) = circle(
|
||||
/// fill: c, width: 5mm
|
||||
/// )
|
||||
///
|
||||
/// #grid(
|
||||
/// columns: 4,
|
||||
/// rows: 2.5em,
|
||||
/// fill: (x, y) => if calc.odd(x + y) { blue.lighten(50%) } else { blue.lighten(10%) },
|
||||
/// rows: 7mm,
|
||||
/// stroke: .5pt + blue,
|
||||
/// align: center + horizon,
|
||||
/// inset: 3pt,
|
||||
/// grid.cell(x: 2, y: 2)[3],
|
||||
/// [1], grid.cell(x: 3)[4], [2],
|
||||
/// inset: 1mm,
|
||||
///
|
||||
/// grid.cell(x: 2, y: 2, circ(aqua)),
|
||||
/// circ(yellow),
|
||||
/// grid.cell(x: 3, circ(green)),
|
||||
/// circ(black),
|
||||
/// )
|
||||
/// ```
|
||||
pub x: Smart<usize>,
|
||||
@ -732,11 +773,21 @@ pub struct GridCell {
|
||||
/// columns in the chosen row are already occupied, an error is raised.
|
||||
///
|
||||
/// ```example
|
||||
/// #let tri(c) = polygon.regular(
|
||||
/// fill: c,
|
||||
/// size: 5mm,
|
||||
/// vertices: 3,
|
||||
/// )
|
||||
///
|
||||
/// #grid(
|
||||
/// columns: 2,
|
||||
/// fill: (x, y) => if calc.odd(x + y) { gray.lighten(40%) },
|
||||
/// inset: 1pt,
|
||||
/// [A], grid.cell(y: 1)[B], grid.cell(y: 1)[C], grid.cell(y: 2)[D]
|
||||
/// stroke: blue,
|
||||
/// inset: 1mm,
|
||||
///
|
||||
/// tri(black),
|
||||
/// grid.cell(y: 1, tri(teal)),
|
||||
/// grid.cell(y: 1, tri(red)),
|
||||
/// grid.cell(y: 2, tri(orange))
|
||||
/// )
|
||||
/// ```
|
||||
pub y: Smart<usize>,
|
||||
@ -749,16 +800,16 @@ pub struct GridCell {
|
||||
#[default(NonZeroUsize::ONE)]
|
||||
pub rowspan: NonZeroUsize,
|
||||
|
||||
/// The cell's fill override.
|
||||
/// The cell's [fill]($grid.fill) override.
|
||||
pub fill: Smart<Option<Paint>>,
|
||||
|
||||
/// The cell's alignment override.
|
||||
/// The cell's [alignment]($grid.align) override.
|
||||
pub align: Smart<Alignment>,
|
||||
|
||||
/// The cell's inset override.
|
||||
/// The cell's [inset]($grid.inset) override.
|
||||
pub inset: Smart<Sides<Option<Rel<Length>>>>,
|
||||
|
||||
/// The cell's stroke override.
|
||||
/// The cell's [stroke]($grid.stroke) override.
|
||||
#[resolve]
|
||||
#[fold]
|
||||
pub stroke: Sides<Option<Option<Arc<Stroke>>>>,
|
||||
|
@ -25,14 +25,26 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// Tables are used to arrange content in cells. Cells can contain arbitrary
|
||||
/// content, including multiple paragraphs and are specified in row-major order.
|
||||
/// Because tables are just grids with different defaults for some cell
|
||||
/// properties (notably `stroke` and `inset`), refer to the
|
||||
/// [grid documentation]($grid) for more information on how to size the table
|
||||
/// tracks and specify the cell appearance properties.
|
||||
/// properties (notably `stroke` and `inset`), refer to the [grid
|
||||
/// documentation]($grid) for more information on how to size the table tracks
|
||||
/// and specify the cell appearance properties.
|
||||
///
|
||||
/// Note that, to override a particular cell's properties or apply show rules
|
||||
/// on table cells, you can use the [`table.cell`]($table.cell) element (but
|
||||
/// not `grid.cell`, which is exclusive to grids). See its documentation for
|
||||
/// more information.
|
||||
/// If you are unsure whether you should be using a table or a grid, consider
|
||||
/// whether the content you are arranging semantically belongs together as a set
|
||||
/// of related data points or similar or whether you are just want to enhance
|
||||
/// your presentation by arranging unrelated content in a grid. In the former
|
||||
/// case, a table is the right choice, while in the latter case, a grid is more
|
||||
/// appropriate. Furthermore, Typst will annotate its output in the future such
|
||||
/// that screenreaders will annouce content in `table` as tabular while a grid's
|
||||
/// content will be announced no different than multiple content blocks in the
|
||||
/// document flow.
|
||||
///
|
||||
/// Note that, to override a particular cell's properties or apply show rules on
|
||||
/// table cells, you can use the [`table.cell`]($table.cell) element. See its
|
||||
/// documentation for more information.
|
||||
///
|
||||
/// Although the `table` and the `grid` share most properties, set and show
|
||||
/// rules on one of them do not affect the other.
|
||||
///
|
||||
/// To give a table a caption and make it [referenceable]($ref), put it into a
|
||||
/// [figure].
|
||||
@ -45,7 +57,9 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// columns: (1fr, auto, auto),
|
||||
/// inset: 10pt,
|
||||
/// align: horizon,
|
||||
/// [], [*Area*], [*Parameters*],
|
||||
/// table.header(
|
||||
/// [], [*Area*], [*Parameters*],
|
||||
/// ),
|
||||
/// image("cylinder.svg"),
|
||||
/// $ pi h (D^2 - d^2) / 4 $,
|
||||
/// [
|
||||
@ -63,33 +77,44 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// the appearance and the position of each cell.
|
||||
///
|
||||
/// ```example
|
||||
/// #set page(width: auto)
|
||||
/// >>> #set page(width: auto)
|
||||
/// >>> #set text(font: "IBM Plex Sans")
|
||||
/// >>> #let gray = rgb("#565565")
|
||||
/// >>>
|
||||
/// #set table(
|
||||
/// stroke: none,
|
||||
/// gutter: 0.2em,
|
||||
/// fill: (x, y) =>
|
||||
/// if x == 0 or y == 0 { gray },
|
||||
/// inset: (right: 1.5em),
|
||||
/// )
|
||||
///
|
||||
/// #show table.cell: it => {
|
||||
/// if it.x == 0 or it.y == 0 {
|
||||
/// set text(white)
|
||||
/// strong(it)
|
||||
/// } else if it.body == [] {
|
||||
/// // Replace empty cells with 'N/A'
|
||||
/// pad(rest: it.inset)[_N/A_]
|
||||
/// pad(..it.inset)[_N/A_]
|
||||
/// } else {
|
||||
/// it
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #let a = table.cell(
|
||||
/// fill: green.lighten(60%),
|
||||
/// )[A]
|
||||
/// #let b = table.cell(
|
||||
/// fill: aqua.lighten(60%),
|
||||
/// )[B]
|
||||
///
|
||||
/// #table(
|
||||
/// fill: (x, y) => if x == 0 or y == 0 { gray.darken(50%) },
|
||||
/// columns: 4,
|
||||
/// [], [Exam 1], [Exam 2], [Exam 3],
|
||||
/// ..([John], [Mary], [Jake], [Robert]).map(table.cell.with(x: 0)),
|
||||
///
|
||||
/// // Mary got grade A on Exam 3.
|
||||
/// table.cell(x: 3, y: 2, fill: green)[A],
|
||||
///
|
||||
/// // Everyone got grade A on Exam 2.
|
||||
/// ..(table.cell(x: 2, fill: green)[A],) * 4,
|
||||
///
|
||||
/// // Robert got grade B on other exams.
|
||||
/// ..(table.cell(y: 4, fill: aqua)[B],) * 2,
|
||||
/// [John], [], a, [],
|
||||
/// [Mary], [], a, a,
|
||||
/// [Robert], b, a, b,
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(scope, LayoutMultiple, LocalName, Figurable)]
|
||||
@ -157,7 +182,7 @@ pub struct TableElem {
|
||||
/// ```example
|
||||
/// #table(
|
||||
/// columns: 3,
|
||||
/// align: (x, y) => (left, center, right).at(x),
|
||||
/// align: (left, center, right),
|
||||
/// [Hello], [Hello], [Hello],
|
||||
/// [A], [B], [C],
|
||||
/// )
|
||||
@ -172,10 +197,11 @@ pub struct TableElem {
|
||||
/// If it is necessary to place lines which can cross spacing between cells
|
||||
/// produced by the `gutter` option, or to override the stroke between
|
||||
/// multiple specific cells, consider specifying one or more of
|
||||
/// [`table.hline`]($table.hline) and [`table.vline`]($table.vline) alongside
|
||||
/// your table cells.
|
||||
/// [`table.hline`]($table.hline) and [`table.vline`]($table.vline)
|
||||
/// alongside your table cells.
|
||||
///
|
||||
/// See the [grid documentation]($grid) for more information on stroke.
|
||||
/// See the [grid documentation]($grid.stroke) for more information on
|
||||
/// strokes.
|
||||
#[resolve]
|
||||
#[fold]
|
||||
#[default(Celled::Value(Sides::splat(Some(Some(Arc::new(Stroke::default()))))))]
|
||||
@ -464,6 +490,49 @@ impl TryFrom<Content> for TableItem {
|
||||
}
|
||||
|
||||
/// A repeatable table header.
|
||||
///
|
||||
/// You should wrap your tables' heading rows in this function even if you do not
|
||||
/// plan to wrap your table across pages because Typst will use this function to
|
||||
/// attach accessibility metadata to tables in the future and ensure universal
|
||||
/// access to your document.
|
||||
///
|
||||
/// You can use the `repeat` parameter to control whether your table's header
|
||||
/// will be repeated across pages.
|
||||
///
|
||||
/// ```example
|
||||
/// #set page(height: 11.5em)
|
||||
/// #set table(
|
||||
/// fill: (x, y) =>
|
||||
/// if x == 0 or y == 0 {
|
||||
/// gray.lighten(40%)
|
||||
/// },
|
||||
/// align: right,
|
||||
/// )
|
||||
///
|
||||
/// #show table.cell.where(x: 0): strong
|
||||
/// #show table.cell.where(y: 0): strong
|
||||
///
|
||||
/// #table(
|
||||
/// columns: 4,
|
||||
/// table.header(
|
||||
/// [], [Blue chip],
|
||||
/// [Fresh IPO], [Penny st'k],
|
||||
/// ),
|
||||
/// table.cell(
|
||||
/// rowspan: 6,
|
||||
/// align: horizon,
|
||||
/// rotate(-90deg, reflow: true)[
|
||||
/// *USD / day*
|
||||
/// ],
|
||||
/// ),
|
||||
/// [0.20], [104], [5],
|
||||
/// [3.17], [108], [4],
|
||||
/// [1.59], [84], [1],
|
||||
/// [0.26], [98], [15],
|
||||
/// [0.01], [195], [4],
|
||||
/// [7.34], [57], [2],
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(name = "header", title = "Table Header")]
|
||||
pub struct TableHeader {
|
||||
/// Whether this header should be repeated across pages.
|
||||
@ -476,6 +545,13 @@ pub struct TableHeader {
|
||||
}
|
||||
|
||||
/// A repeatable table footer.
|
||||
///
|
||||
/// Just like the [`table.header`]($table.header) element, the footer can repeat
|
||||
/// itself on every page of the table. This is useful for improving legibility
|
||||
/// by adding the column labels in both the header and footer of a large table,
|
||||
/// totals, or other information that should be visible on every page.
|
||||
///
|
||||
/// No other table cells may be placed after the footer.
|
||||
#[elem(name = "footer", title = "Table Footer")]
|
||||
pub struct TableFooter {
|
||||
/// Whether this footer should be repeated across pages.
|
||||
@ -487,17 +563,42 @@ pub struct TableFooter {
|
||||
pub children: Vec<TableItem>,
|
||||
}
|
||||
|
||||
/// A horizontal line in the table. See the docs for
|
||||
/// [`grid.hline`]($grid.hline) for more information regarding how to use this
|
||||
/// element's fields.
|
||||
/// A horizontal line in the table.
|
||||
///
|
||||
/// Overrides any per-cell stroke, including stroke specified through the
|
||||
/// table's `stroke` field. Can cross spacing between cells created through
|
||||
/// the table's `column-gutter` option.
|
||||
/// table's `stroke` field. Can cross spacing between cells created through the
|
||||
/// table's [`column-gutter`]($table.column-gutter) option.
|
||||
///
|
||||
/// Use this function instead of the table's `stroke` field if you want to
|
||||
/// manually place a horizontal line at a specific position in a single table.
|
||||
/// Consider using [table's `stroke`]($table.stroke) field or [`table.cell`'s
|
||||
/// `stroke`]($table.cell.stroke) field instead if the line you want to place is
|
||||
/// part of all your tables' designs.
|
||||
///
|
||||
/// ```example
|
||||
/// #set table.hline(stroke: .6pt)
|
||||
///
|
||||
/// #table(
|
||||
/// stroke: none,
|
||||
/// columns: (auto, 1fr),
|
||||
/// [09:00], [Badge pick up],
|
||||
/// [09:45], [Opening Keynote],
|
||||
/// [10:30], [Talk: Typst's Future],
|
||||
/// [11:15], [Session: Good PRs],
|
||||
/// table.hline(start: 1),
|
||||
/// [Noon], [_Lunch break_],
|
||||
/// table.hline(start: 1),
|
||||
/// [14:00], [Talk: Tracked Layout],
|
||||
/// [15:00], [Talk: Automations],
|
||||
/// [16:00], [Workshop: Tables],
|
||||
/// table.hline(),
|
||||
/// [19:00], [Day 1 Attendee Mixer],
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(name = "hline", title = "Table Horizontal Line")]
|
||||
pub struct TableHLine {
|
||||
/// The row above which the horizontal line is placed (zero-indexed).
|
||||
/// Functions identically to the `y` field in [`grid.hline`]($grid.hline).
|
||||
/// Functions identically to the `y` field in [`grid.hline`]($grid.hline.y).
|
||||
pub y: Smart<usize>,
|
||||
|
||||
/// The column at which the horizontal line starts (zero-indexed, inclusive).
|
||||
@ -531,8 +632,14 @@ pub struct TableHLine {
|
||||
/// for more information regarding how to use this element's fields.
|
||||
///
|
||||
/// Overrides any per-cell stroke, including stroke specified through the
|
||||
/// table's `stroke` field. Can cross spacing between cells created through
|
||||
/// the table's `row-gutter` option.
|
||||
/// table's `stroke` field. Can cross spacing between cells created through the
|
||||
/// table's [`row-gutter`]($table.row-gutter) option.
|
||||
///
|
||||
/// Similar to [`table.hline`]($table.hline), use this function if you want to
|
||||
/// manually place a vertical line at a specific position in a single table and
|
||||
/// use the [table's `stroke`]($table.stroke) field or [`table.cell`'s
|
||||
/// `stroke`]($table.cell.stroke) field instead if the line you want to place is
|
||||
/// part of all your tables' designs.
|
||||
#[elem(name = "vline", title = "Table Vertical Line")]
|
||||
pub struct TableVLine {
|
||||
/// The column before which the horizontal line is placed (zero-indexed).
|
||||
@ -571,50 +678,85 @@ pub struct TableVLine {
|
||||
pub position: OuterHAlignment,
|
||||
}
|
||||
|
||||
/// A cell in the table. Use this to either override table properties for a
|
||||
/// particular cell, or in show rules to apply certain styles to multiple cells
|
||||
/// at once.
|
||||
/// A cell in the table. Use this to position a cell manually or to apply
|
||||
/// styling. To do the latter, you can either use the function to override the
|
||||
/// properties for a particular cell, or use it in show rules to apply certain
|
||||
/// styles to multiple cells at once.
|
||||
///
|
||||
/// Perhaps the most important use-case of `{table.cell}` is to make a cell span
|
||||
/// multiple columns or rows with the `colspan` and `rowspan` fields.
|
||||
///
|
||||
/// ```example
|
||||
/// >>> #set page(width: auto)
|
||||
/// >>> #show table.cell.where(y: 0): strong
|
||||
/// >>> #set table(
|
||||
/// >>> stroke: (x, y) => if y == 0 {
|
||||
/// >>> (bottom: 0.7pt + black)
|
||||
/// >>> },
|
||||
/// >>> align: (x, y) =>
|
||||
/// >>> if x > 0 { center }
|
||||
/// >>> else { left }
|
||||
/// >>> )
|
||||
/// #table(
|
||||
/// columns: 3,
|
||||
/// table.header(
|
||||
/// [Substance],
|
||||
/// [Subcritical °C],
|
||||
/// [Supercritical °C],
|
||||
/// ),
|
||||
/// [Hydrochloric Acid],
|
||||
/// [12.0], [92.1],
|
||||
/// [Sodium Myreth Sulfate],
|
||||
/// [16.6], [104],
|
||||
/// [Potassium Hydroxide],
|
||||
/// table.cell(colspan: 2)[24.7],
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// For example, you can override the fill, alignment or inset for a single
|
||||
/// cell:
|
||||
///
|
||||
/// ```example
|
||||
/// >>> #set page(width: auto)
|
||||
/// // You can also import those.
|
||||
/// #import table: cell, header
|
||||
///
|
||||
/// #table(
|
||||
/// columns: 2,
|
||||
/// fill: green,
|
||||
/// align: right,
|
||||
/// [*Name*], [*Data*],
|
||||
/// table.cell(fill: blue)[J.], [Organizer],
|
||||
/// table.cell(align: center)[K.], [Leader],
|
||||
/// [M.], table.cell(inset: 0pt)[Player]
|
||||
/// align: center,
|
||||
/// header(
|
||||
/// [*Trip progress*],
|
||||
/// [*Itinerary*],
|
||||
/// ),
|
||||
/// cell(
|
||||
/// align: right,
|
||||
/// fill: fuchsia.lighten(80%),
|
||||
/// [🚗],
|
||||
/// ),
|
||||
/// [Get in, folks!],
|
||||
/// [🚗], [Eat curbside hotdog],
|
||||
/// cell(align: left)[🌴🚗],
|
||||
/// cell(
|
||||
/// inset: 0.06em,
|
||||
/// text(1.62em)[🛖🌅🌊],
|
||||
/// ),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// You may also apply a show rule on `table.cell` to style all cells at once,
|
||||
/// which allows you, for example, to apply styles based on a cell's position:
|
||||
/// You may also apply a show rule on `table.cell` to style all cells at once.
|
||||
/// Combined with selectors, this allows you to apply styles based on a cell's
|
||||
/// position:
|
||||
///
|
||||
/// ```example
|
||||
/// #show table.cell: it => {
|
||||
/// if it.y == 0 {
|
||||
/// // First row is bold
|
||||
/// strong(it)
|
||||
/// } else if it.x == 1 {
|
||||
/// // Second column is italicized
|
||||
/// // (except at the first row)
|
||||
/// emph(it)
|
||||
/// } else {
|
||||
/// // Remaining cells aren't changed
|
||||
/// it
|
||||
/// }
|
||||
/// }
|
||||
/// #show table.cell.where(x: 0): strong
|
||||
///
|
||||
/// #table(
|
||||
/// columns: 3,
|
||||
/// gutter: 3pt,
|
||||
/// [Name], [Age], [Info],
|
||||
/// [John], [52], [Nice],
|
||||
/// [Mary], [50], [Cool],
|
||||
/// [Jake], [49], [Epic]
|
||||
/// [Name], [Age], [Strength],
|
||||
/// [Hannes], [36], [Grace],
|
||||
/// [Irma], [50], [Resourcefulness],
|
||||
/// [Vikram], [49], [Perseverance],
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(name = "cell", title = "Table Cell", Show)]
|
||||
@ -631,9 +773,6 @@ pub struct TableCell {
|
||||
/// Functions identically to the `y` field in [`grid.cell`]($grid.cell).
|
||||
pub y: Smart<usize>,
|
||||
|
||||
/// The cell's fill override.
|
||||
pub fill: Smart<Option<Paint>>,
|
||||
|
||||
/// The amount of columns spanned by this cell.
|
||||
#[default(NonZeroUsize::ONE)]
|
||||
pub colspan: NonZeroUsize,
|
||||
@ -642,13 +781,16 @@ pub struct TableCell {
|
||||
#[default(NonZeroUsize::ONE)]
|
||||
rowspan: NonZeroUsize,
|
||||
|
||||
/// The cell's alignment override.
|
||||
/// The cell's [fill]($table.fill) override.
|
||||
pub fill: Smart<Option<Paint>>,
|
||||
|
||||
/// The cell's [alignment]($table.align) override.
|
||||
pub align: Smart<Alignment>,
|
||||
|
||||
/// The cell's inset override.
|
||||
/// The cell's [inset]($table.inset) override.
|
||||
pub inset: Smart<Sides<Option<Rel<Length>>>>,
|
||||
|
||||
/// The cell's stroke override.
|
||||
/// The cell's [stroke]($table.stroke) override.
|
||||
#[resolve]
|
||||
#[fold]
|
||||
pub stroke: Sides<Option<Option<Arc<Stroke>>>>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user