Repository: typst/typst
File: crates/typst/src/introspection/query.rs (Rust)

Code before:
use comemo::Tracked;

use crate::diag::HintedStrResult;
use crate::engine::Engine;
use crate::foundations::{func, Array, Context, LocatableSelector, Value};
use crate::introspection::Location;

/// Finds elements in the document.
///
/// The `query` functions lets you search your document for elements of a
/// particular type or with a particular label. To use it, you first need to
/// ensure that [context] is available.
///

/// # Finding elements
/// In the example below, we manually create a table of contents instead of
/// using the [`outline`] function.
///
/// To do this, we first query for all headings in the document at level 1 and
/// after the current location. Querying only for headings at level 1 ensures
/// that sub-headings are not included in the table of contents and after
/// `here()` ensures that the "Table of Contents" heading is not included.
///
/// Note that we open a `context` to be able to use the `query` function. The
/// code within the context block runs once per page.
///
/// ```example
/// >>> #set page(
/// >>>  width: 240pt,
/// >>>  height: 180pt,
/// >>>  margin: (top: 20pt, bottom: 35pt)
/// >>> )
/// #set page(numbering: "1")
///
/// = Table of Contents
/// \
/// #context {
///   let chapters = query(
///     selector(heading.where(level: 1)).after(here())
///   )
///   for chapter in chapters {
///     let page_number = chapter.location().page()
///     [#chapter.body #h(1fr) #page_number \ ]
///   }
/// }
///
/// #pagebreak()

Review comment (suggestion):
I think a more idiomatic approach would be to filter for `heading.outlined` and use `heading(outlined: false)[Table of Contents]`. Alternatively, the example could specifically be about a special kind of outline, that only outlines the headings before/after it. That way, we can demo before/after + `here()`.

Code after:
use comemo::Tracked;

use crate::diag::HintedStrResult;
use crate::engine::Engine;
use crate::foundations::{func, Array, Context, LocatableSelector, Value};
use crate::introspection::Location;

/// Finds elements in the document.
///
/// The `query` functions lets you search your document for elements of a
/// particular type or with a particular label. To use it, you first need to
/// ensure that [context] is available.
///

/// # Finding elements
/// In the example below, we manually create a table of contents instead of
/// using the [`outline`] function.
///
/// To do this, we first query for all headings in the document at level 1 and
/// where `outlined` is true. Querying only for headings at level 1 ensures
/// that, for the purpose of this example, sub-headings are not included in the
/// table of contents. The `outlined` field is used to exclude the "Table of
/// Contents" heading itself.
///
/// Note that we open a `context` to be able to use the `query` function.
///
/// ```example
/// >>> #set page(
/// >>>  width: 240pt,
/// >>>  height: 180pt,
/// >>>  margin: (top: 20pt, bottom: 35pt)
/// >>> )
/// #set page(numbering: "1")
///
/// #heading(outlined: false)[
///   Table of Contents
/// ]
/// #context {
///   let chapters = query(
///     heading.where(
///       level: 1,
///       outlined: true,
///     )
///   )
///   for chapter in chapters {
///     let loc = chapter.location()
///     let nr = numbering(