Clarify place documentation (#5031)

This commit is contained in:
Jeremie Knuesel 2024-09-26 15:17:28 +02:00 committed by GitHub
parent 5d8685e450
commit d1379d8bd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,26 +1,70 @@
use crate::foundations::{elem, scope, Cast, Content, Smart};
use crate::layout::{Alignment, Em, Length, Rel};
/// Places content at an absolute position.
/// Places content relatively to its parent container.
///
/// Placed content will not affect the position of other content. Place is
/// always relative to its parent container and will be in the foreground of all
/// other content in the container. Page margins will be respected.
/// Placed content can be either overlaid (the default) or floating. Overlaid
/// content is aligned with the parent container according to the given
/// [`alignment`]($place.alignment), and shown over any other content added so
/// far in the container. Floating content is placed at the top or bottom of
/// the container, displacing other content down or up respectively. In both
/// cases, the content position can be adjusted with [`dx`]($place.dx) and
/// [`dy`]($place.dy) offsets without affecting the layout.
///
/// The parent can be any container such as a [`block`], [`box`],
/// [`rect`], etc. A top level `place` call will place content directly
/// in the text area of the current page. This can be used for absolute
/// positioning on the page: with a `top + left`
/// [`alignment`]($place.alignment), the offsets `dx` and `dy` will set the
/// position of the element's top left corner relatively to the top left corner
/// of the text area. For absolute positioning on the full page including
/// margins, you can use `place` in [`page.foreground`]($page.foreground) or
/// [`page.background`]($page.background).
///
/// # Example
/// # Examples
/// ```example
/// #set page(height: 60pt)
/// Hello, world!
///
/// #rect(
/// width: 100%,
/// height: 2cm,
/// place(horizon + right, square()),
/// )
///
/// #place(
/// top + right,
/// square(
/// width: 20pt,
/// stroke: 2pt + blue
/// ),
/// top + left,
/// dx: -5pt,
/// square(size: 5pt, fill: red),
/// )
/// ```
///
/// # Effect on the position of other elements
///
/// Overlaid elements don't take space in the flow of content, but a `place`
/// call inserts an invisible block-level element in the flow. This can
/// affect the layout by breaking the current paragraph. To avoid this,
/// you can wrap the `place` call in a [`box`] when the call is made
/// in the middle of a paragraph. The alignment and offsets will then be
/// relative to this zero-size box. To make sure it doesn't interfere with
/// spacing, the box should be attached to a word using a zero-width joiner.
///
/// For example, the following defines a function for attaching an annotation
/// to the following word:
///
/// ```example
/// #let annotate(..args) = {
/// box(place(..args))
/// sym.zwj
/// h(0pt, weak: true)
/// }
///
/// A placed #annotate(square(), dy: 2pt)
/// square in my text.
/// ```
///
/// The zero-width weak spacing serves to discard spaces between the function
/// call and the next word in markup.
#[elem(scope)]
pub struct PlaceElem {
/// Relative to which position in the parent container to place the content.
@ -28,9 +72,8 @@ pub struct PlaceElem {
/// - If `float` is `{false}`, then this can be any alignment other than `{auto}`.
/// - If `float` is `{true}`, then this must be `{auto}`, `{top}`, or `{bottom}`.
///
/// When an axis of the page is `{auto}` sized, all alignments relative to
/// that axis will be ignored, instead, the item will be placed in the
/// origin of the axis.
/// When `float` is `{false}` and no vertical alignment is specified, the
/// content is placed at the current position on the vertical axis.
#[positional]
#[default(Smart::Custom(Alignment::START))]
pub alignment: Smart<Alignment>,
@ -73,7 +116,8 @@ pub struct PlaceElem {
/// ```
pub float: bool,
/// The amount of clearance the placed element has in a floating layout.
/// The spacing between the placed element and other elements in a floating
/// layout.
///
/// Has no effect if `float` is `{false}`.
#[default(Em::new(1.5).into())]