summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/layout/flow/compose.rs22
-rw-r--r--crates/typst/src/layout/flow/mod.rs28
-rw-r--r--crates/typst/src/model/par.rs35
-rw-r--r--tests/ref/line-numbers-default-alignment.pngbin1359 -> 1362 bytes
-rw-r--r--tests/ref/line-numbers-enable.pngbin929 -> 910 bytes
-rw-r--r--tests/ref/line-numbers-page-scope.pngbin2206 -> 1866 bytes
-rw-r--r--tests/ref/line-numbers-rtl.pngbin1369 -> 1365 bytes
-rw-r--r--tests/ref/line-numbers-start-alignment.pngbin470 -> 464 bytes
-rw-r--r--tests/suite/layout/line-numbers.typ10
9 files changed, 69 insertions, 26 deletions
diff --git a/crates/typst/src/layout/flow/compose.rs b/crates/typst/src/layout/flow/compose.rs
index 003e4e72..6f14618e 100644
--- a/crates/typst/src/layout/flow/compose.rs
+++ b/crates/typst/src/layout/flow/compose.rs
@@ -1,6 +1,8 @@
use std::num::NonZeroUsize;
-use super::{distribute, Config, FlowResult, PlacedChild, Skip, Stop, Work};
+use super::{
+ distribute, Config, FlowResult, LineNumberConfig, PlacedChild, Skip, Stop, Work,
+};
use crate::diag::SourceResult;
use crate::engine::Engine;
use crate::foundations::{Content, NativeElement, Packed, Resolve, Smart};
@@ -13,7 +15,7 @@ use crate::layout::{
OuterHAlignment, PlacementScope, Point, Region, Regions, Rel, Size,
};
use crate::model::{
- FootnoteElem, FootnoteEntry, LineNumberingScope, Numbering, ParLine, ParLineMarker,
+ FootnoteElem, FootnoteEntry, LineNumberingScope, Numbering, ParLineMarker,
};
use crate::syntax::Span;
use crate::utils::NonZeroExt;
@@ -198,10 +200,11 @@ impl<'a, 'b> Composer<'a, 'b, '_, '_> {
let mut output = insertions.finalize(self.work, self.config, inner);
// Lay out per-column line numbers.
- if self.config.root {
+ if let Some(line_config) = &self.config.line_numbers {
layout_line_numbers(
self.engine,
self.config,
+ line_config,
locator,
self.column,
&mut output,
@@ -647,6 +650,7 @@ impl<'a, 'b> Insertions<'a, 'b> {
fn layout_line_numbers(
engine: &mut Engine,
config: &Config,
+ line_config: &LineNumberConfig,
locator: Locator,
column: usize,
output: &mut Frame,
@@ -654,9 +658,7 @@ fn layout_line_numbers(
let mut locator = locator.split();
// Reset page-scoped line numbers if currently at the first column.
- if column == 0
- && ParLine::numbering_scope_in(config.shared) == LineNumberingScope::Page
- {
+ if column == 0 && line_config.scope == LineNumberingScope::Page {
let reset = layout_line_number_reset(engine, config, &mut locator)?;
output.push_frame(Point::zero(), reset);
}
@@ -711,9 +713,11 @@ fn layout_line_numbers(
.resolve(config.shared)
};
- // Compute the marker's horizontal position. Will be adjusted based on
- // the maximum number width later.
- let clearance = marker.number_clearance.resolve(config.shared);
+ // Determine how much space to leave between the column and the number.
+ let clearance = match marker.number_clearance {
+ Smart::Auto => line_config.default_clearance,
+ Smart::Custom(rel) => rel.resolve(config.shared),
+ };
// Compute the base X position.
let x = match margin {
diff --git a/crates/typst/src/layout/flow/mod.rs b/crates/typst/src/layout/flow/mod.rs
index 8a10b05d..5db70ecb 100644
--- a/crates/typst/src/layout/flow/mod.rs
+++ b/crates/typst/src/layout/flow/mod.rs
@@ -19,14 +19,14 @@ use self::compose::{compose, Composer};
use self::distribute::distribute;
use crate::diag::{bail, At, SourceDiagnostic, SourceResult};
use crate::engine::{Engine, Route, Sink, Traced};
-use crate::foundations::{Content, Packed, StyleChain};
+use crate::foundations::{Content, Packed, Resolve, StyleChain};
use crate::introspection::{
Introspector, Location, Locator, LocatorLink, SplitLocator, Tag,
};
use crate::layout::{
- Abs, Dir, Fragment, Frame, PlacementScope, Region, Regions, Rel, Size,
+ Abs, Dir, Em, Fragment, Frame, PageElem, PlacementScope, Region, Regions, Rel, Size,
};
-use crate::model::{FootnoteElem, FootnoteEntry};
+use crate::model::{FootnoteElem, FootnoteEntry, LineNumberingScope, ParLine};
use crate::realize::{realize, Arenas, Pair, RealizationKind};
use crate::text::TextElem;
use crate::utils::{NonZeroExt, Numeric};
@@ -187,6 +187,18 @@ pub(crate) fn layout_flow(
gap: FootnoteEntry::gap_in(shared),
expand: regions.expand.x,
},
+ line_numbers: root.then(|| LineNumberConfig {
+ scope: ParLine::numbering_scope_in(shared),
+ default_clearance: {
+ let width = if PageElem::flipped_in(shared) {
+ PageElem::height_in(shared)
+ } else {
+ PageElem::width_in(shared)
+ };
+ (0.026 * width.unwrap_or_default())
+ .clamp(Em::new(0.75).resolve(shared), Em::new(2.5).resolve(shared))
+ },
+ }),
};
// Collect the elements into pre-processed children. These are much easier
@@ -311,6 +323,8 @@ struct Config<'x> {
columns: ColumnConfig,
/// Settings for footnotes.
footnote: FootnoteConfig,
+ /// Settings for line numbers.
+ line_numbers: Option<LineNumberConfig>,
}
/// Configuration of footnotes.
@@ -338,6 +352,14 @@ struct ColumnConfig {
dir: Dir,
}
+/// Configuration of line numbers.
+struct LineNumberConfig {
+ /// Where line numbers are reset.
+ scope: LineNumberingScope,
+ /// The default clearance for `auto`.
+ default_clearance: Abs,
+}
+
/// The result type for flow layout.
///
/// The `Err(_)` variant incorporate control flow events for finishing and
diff --git a/crates/typst/src/model/par.rs b/crates/typst/src/model/par.rs
index 2e23bd74..b50fca8b 100644
--- a/crates/typst/src/model/par.rs
+++ b/crates/typst/src/model/par.rs
@@ -7,7 +7,7 @@ use crate::foundations::{
StyleVec, Unlabellable,
};
use crate::introspection::{Count, CounterUpdate, Locatable};
-use crate::layout::{Abs, Em, HAlignment, Length, OuterHAlignment};
+use crate::layout::{Em, HAlignment, Length, OuterHAlignment};
use crate::model::Numbering;
use crate::utils::singleton;
@@ -219,17 +219,27 @@ impl Unlabellable for Packed<ParbreakElem> {}
///
/// This element is exclusively used for line number configuration and cannot
/// be placed.
-#[elem(name = "line", title = "Paragraph Line", Construct, Locatable)]
+///
+/// ```example
+/// >>> #set page(margin: (left: 3em))
+/// #set par.line(numbering: "1")
+///
+/// Roses are red. \
+/// Violets are blue. \
+/// Typst is there for you.
+/// ```
+#[elem(name = "line", title = "Paragraph Line", keywords = ["line numbering"], Construct, Locatable)]
pub struct ParLine {
/// How to number each line. Accepts a
/// [numbering pattern or function]($numbering).
///
/// ```example
- /// #set par.line(numbering: "1")
+ /// >>> #set page(margin: (left: 3em))
+ /// #set par.line(numbering: "I")
///
/// Roses are red. \
/// Violets are blue. \
- /// Typst is awesome.
+ /// Typst is there for you.
/// ```
#[ghost]
pub numbering: Option<Numbering>,
@@ -241,6 +251,7 @@ pub struct ParLine {
/// the current text direction.
///
/// ```example
+ /// >>> #set page(margin: (left: 3em))
/// #set par.line(numbering: "I", number-align: left)
///
/// Hello world! \
@@ -253,6 +264,7 @@ pub struct ParLine {
/// The margin at which line numbers appear.
///
/// ```example
+ /// >>> #set page(margin: (right: 3em))
/// #set par.line(numbering: "1", number-margin: right)
///
/// = Report
@@ -265,10 +277,14 @@ pub struct ParLine {
/// The distance between line numbers and text.
///
+ /// The default value of `{auto}` results in a clearance that is adaptive to
+ /// the page width and yields reasonable results in most cases.
+ ///
/// ```example
+ /// >>> #set page(margin: (left: 3em))
/// #set par.line(
/// numbering: "1",
- /// number-clearance: 0.5pt
+ /// number-clearance: 4pt
/// )
///
/// Typesetting \
@@ -276,8 +292,8 @@ pub struct ParLine {
/// Layout
/// ```
#[ghost]
- #[default(Length::from(Abs::cm(1.0)))]
- pub number_clearance: Length,
+ #[default]
+ pub number_clearance: Smart<Length>,
/// Controls when to reset line numbering.
///
@@ -285,8 +301,9 @@ pub struct ParLine {
/// is never reset, or `"page"`, indicating it is reset on every page.
///
/// ```example
+ /// >>> #set page(margin: (left: 3em))
/// #set par.line(
- /// numbering: "1.",
+ /// numbering: "1",
/// numbering-scope: "page"
/// )
///
@@ -339,7 +356,7 @@ pub struct ParLineMarker {
#[internal]
#[required]
- pub number_clearance: Length,
+ pub number_clearance: Smart<Length>,
}
impl Construct for ParLineMarker {
diff --git a/tests/ref/line-numbers-default-alignment.png b/tests/ref/line-numbers-default-alignment.png
index 4445ddf3..c2e9f3d4 100644
--- a/tests/ref/line-numbers-default-alignment.png
+++ b/tests/ref/line-numbers-default-alignment.png
Binary files differ
diff --git a/tests/ref/line-numbers-enable.png b/tests/ref/line-numbers-enable.png
index 0437624e..95088f23 100644
--- a/tests/ref/line-numbers-enable.png
+++ b/tests/ref/line-numbers-enable.png
Binary files differ
diff --git a/tests/ref/line-numbers-page-scope.png b/tests/ref/line-numbers-page-scope.png
index 0cdffd28..4b29cd4b 100644
--- a/tests/ref/line-numbers-page-scope.png
+++ b/tests/ref/line-numbers-page-scope.png
Binary files differ
diff --git a/tests/ref/line-numbers-rtl.png b/tests/ref/line-numbers-rtl.png
index 6e0fef83..d4d9dc91 100644
--- a/tests/ref/line-numbers-rtl.png
+++ b/tests/ref/line-numbers-rtl.png
Binary files differ
diff --git a/tests/ref/line-numbers-start-alignment.png b/tests/ref/line-numbers-start-alignment.png
index 3f7a6523..9df2c6ef 100644
--- a/tests/ref/line-numbers-start-alignment.png
+++ b/tests/ref/line-numbers-start-alignment.png
Binary files differ
diff --git a/tests/suite/layout/line-numbers.typ b/tests/suite/layout/line-numbers.typ
index 5ee53e25..25f96d98 100644
--- a/tests/suite/layout/line-numbers.typ
+++ b/tests/suite/layout/line-numbers.typ
@@ -1,5 +1,5 @@
--- line-numbers-enable ---
-#set page(margin: (left: 1.5cm))
+#set page(margin: (left: 2.5em))
#set par.line(numbering: "1")
First line \
@@ -23,13 +23,13 @@ Second line \
Third line
--- line-numbers-default-alignment ---
-#set page(margin: (left: 2cm))
+#set page(margin: (left: 3em))
#set par.line(numbering: "1")
a
#([\ a] * 15)
--- line-numbers-start-alignment ---
-#set page(margin: (left: 2cm))
+#set page(margin: (left: 3em))
#set par.line(numbering: "i", number-align: start)
a \
a
@@ -47,7 +47,7 @@ Second line \
Third line
--- line-numbers-rtl ---
-#set page(margin: (right: 2cm))
+#set page(margin: (right: 3em))
#set text(dir: rtl)
#set par.line(numbering: "1")
a
@@ -120,7 +120,7 @@ In the \
Sky
--- line-numbers-page-scope ---
-#set page(margin: (left: 2cm))
+#set page(margin: (left: 2.5em))
#set par.line(numbering: "1", numbering-scope: "page")
First line \