Adjust line number clearance (#5093)

Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
PgBiel 2024-10-02 07:17:36 -03:00 committed by GitHub
parent fa623992c1
commit b791aede82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 69 additions and 26 deletions

View File

@ -1,6 +1,8 @@
use std::num::NonZeroUsize; 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::diag::SourceResult;
use crate::engine::Engine; use crate::engine::Engine;
use crate::foundations::{Content, NativeElement, Packed, Resolve, Smart}; use crate::foundations::{Content, NativeElement, Packed, Resolve, Smart};
@ -13,7 +15,7 @@ use crate::layout::{
OuterHAlignment, PlacementScope, Point, Region, Regions, Rel, Size, OuterHAlignment, PlacementScope, Point, Region, Regions, Rel, Size,
}; };
use crate::model::{ use crate::model::{
FootnoteElem, FootnoteEntry, LineNumberingScope, Numbering, ParLine, ParLineMarker, FootnoteElem, FootnoteEntry, LineNumberingScope, Numbering, ParLineMarker,
}; };
use crate::syntax::Span; use crate::syntax::Span;
use crate::utils::NonZeroExt; use crate::utils::NonZeroExt;
@ -198,10 +200,11 @@ impl<'a, 'b> Composer<'a, 'b, '_, '_> {
let mut output = insertions.finalize(self.work, self.config, inner); let mut output = insertions.finalize(self.work, self.config, inner);
// Lay out per-column line numbers. // Lay out per-column line numbers.
if self.config.root { if let Some(line_config) = &self.config.line_numbers {
layout_line_numbers( layout_line_numbers(
self.engine, self.engine,
self.config, self.config,
line_config,
locator, locator,
self.column, self.column,
&mut output, &mut output,
@ -647,6 +650,7 @@ impl<'a, 'b> Insertions<'a, 'b> {
fn layout_line_numbers( fn layout_line_numbers(
engine: &mut Engine, engine: &mut Engine,
config: &Config, config: &Config,
line_config: &LineNumberConfig,
locator: Locator, locator: Locator,
column: usize, column: usize,
output: &mut Frame, output: &mut Frame,
@ -654,9 +658,7 @@ fn layout_line_numbers(
let mut locator = locator.split(); let mut locator = locator.split();
// Reset page-scoped line numbers if currently at the first column. // Reset page-scoped line numbers if currently at the first column.
if column == 0 if column == 0 && line_config.scope == LineNumberingScope::Page {
&& ParLine::numbering_scope_in(config.shared) == LineNumberingScope::Page
{
let reset = layout_line_number_reset(engine, config, &mut locator)?; let reset = layout_line_number_reset(engine, config, &mut locator)?;
output.push_frame(Point::zero(), reset); output.push_frame(Point::zero(), reset);
} }
@ -711,9 +713,11 @@ fn layout_line_numbers(
.resolve(config.shared) .resolve(config.shared)
}; };
// Compute the marker's horizontal position. Will be adjusted based on // Determine how much space to leave between the column and the number.
// the maximum number width later. let clearance = match marker.number_clearance {
let clearance = marker.number_clearance.resolve(config.shared); Smart::Auto => line_config.default_clearance,
Smart::Custom(rel) => rel.resolve(config.shared),
};
// Compute the base X position. // Compute the base X position.
let x = match margin { let x = match margin {

View File

@ -19,14 +19,14 @@ use self::compose::{compose, Composer};
use self::distribute::distribute; use self::distribute::distribute;
use crate::diag::{bail, At, SourceDiagnostic, SourceResult}; use crate::diag::{bail, At, SourceDiagnostic, SourceResult};
use crate::engine::{Engine, Route, Sink, Traced}; use crate::engine::{Engine, Route, Sink, Traced};
use crate::foundations::{Content, Packed, StyleChain}; use crate::foundations::{Content, Packed, Resolve, StyleChain};
use crate::introspection::{ use crate::introspection::{
Introspector, Location, Locator, LocatorLink, SplitLocator, Tag, Introspector, Location, Locator, LocatorLink, SplitLocator, Tag,
}; };
use crate::layout::{ 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::realize::{realize, Arenas, Pair, RealizationKind};
use crate::text::TextElem; use crate::text::TextElem;
use crate::utils::{NonZeroExt, Numeric}; use crate::utils::{NonZeroExt, Numeric};
@ -187,6 +187,18 @@ pub(crate) fn layout_flow(
gap: FootnoteEntry::gap_in(shared), gap: FootnoteEntry::gap_in(shared),
expand: regions.expand.x, 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 // Collect the elements into pre-processed children. These are much easier
@ -311,6 +323,8 @@ struct Config<'x> {
columns: ColumnConfig, columns: ColumnConfig,
/// Settings for footnotes. /// Settings for footnotes.
footnote: FootnoteConfig, footnote: FootnoteConfig,
/// Settings for line numbers.
line_numbers: Option<LineNumberConfig>,
} }
/// Configuration of footnotes. /// Configuration of footnotes.
@ -338,6 +352,14 @@ struct ColumnConfig {
dir: Dir, 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 result type for flow layout.
/// ///
/// The `Err(_)` variant incorporate control flow events for finishing and /// The `Err(_)` variant incorporate control flow events for finishing and

View File

@ -7,7 +7,7 @@ use crate::foundations::{
StyleVec, Unlabellable, StyleVec, Unlabellable,
}; };
use crate::introspection::{Count, CounterUpdate, Locatable}; 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::model::Numbering;
use crate::utils::singleton; use crate::utils::singleton;
@ -219,17 +219,27 @@ impl Unlabellable for Packed<ParbreakElem> {}
/// ///
/// This element is exclusively used for line number configuration and cannot /// This element is exclusively used for line number configuration and cannot
/// be placed. /// 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 { pub struct ParLine {
/// How to number each line. Accepts a /// How to number each line. Accepts a
/// [numbering pattern or function]($numbering). /// [numbering pattern or function]($numbering).
/// ///
/// ```example /// ```example
/// #set par.line(numbering: "1") /// >>> #set page(margin: (left: 3em))
/// #set par.line(numbering: "I")
/// ///
/// Roses are red. \ /// Roses are red. \
/// Violets are blue. \ /// Violets are blue. \
/// Typst is awesome. /// Typst is there for you.
/// ``` /// ```
#[ghost] #[ghost]
pub numbering: Option<Numbering>, pub numbering: Option<Numbering>,
@ -241,6 +251,7 @@ pub struct ParLine {
/// the current text direction. /// the current text direction.
/// ///
/// ```example /// ```example
/// >>> #set page(margin: (left: 3em))
/// #set par.line(numbering: "I", number-align: left) /// #set par.line(numbering: "I", number-align: left)
/// ///
/// Hello world! \ /// Hello world! \
@ -253,6 +264,7 @@ pub struct ParLine {
/// The margin at which line numbers appear. /// The margin at which line numbers appear.
/// ///
/// ```example /// ```example
/// >>> #set page(margin: (right: 3em))
/// #set par.line(numbering: "1", number-margin: right) /// #set par.line(numbering: "1", number-margin: right)
/// ///
/// = Report /// = Report
@ -265,10 +277,14 @@ pub struct ParLine {
/// The distance between line numbers and text. /// 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 /// ```example
/// >>> #set page(margin: (left: 3em))
/// #set par.line( /// #set par.line(
/// numbering: "1", /// numbering: "1",
/// number-clearance: 0.5pt /// number-clearance: 4pt
/// ) /// )
/// ///
/// Typesetting \ /// Typesetting \
@ -276,8 +292,8 @@ pub struct ParLine {
/// Layout /// Layout
/// ``` /// ```
#[ghost] #[ghost]
#[default(Length::from(Abs::cm(1.0)))] #[default]
pub number_clearance: Length, pub number_clearance: Smart<Length>,
/// Controls when to reset line numbering. /// 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. /// is never reset, or `"page"`, indicating it is reset on every page.
/// ///
/// ```example /// ```example
/// >>> #set page(margin: (left: 3em))
/// #set par.line( /// #set par.line(
/// numbering: "1.", /// numbering: "1",
/// numbering-scope: "page" /// numbering-scope: "page"
/// ) /// )
/// ///
@ -339,7 +356,7 @@ pub struct ParLineMarker {
#[internal] #[internal]
#[required] #[required]
pub number_clearance: Length, pub number_clearance: Smart<Length>,
} }
impl Construct for ParLineMarker { impl Construct for ParLineMarker {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 464 B

View File

@ -1,5 +1,5 @@
--- line-numbers-enable --- --- line-numbers-enable ---
#set page(margin: (left: 1.5cm)) #set page(margin: (left: 2.5em))
#set par.line(numbering: "1") #set par.line(numbering: "1")
First line \ First line \
@ -23,13 +23,13 @@ Second line \
Third line Third line
--- line-numbers-default-alignment --- --- line-numbers-default-alignment ---
#set page(margin: (left: 2cm)) #set page(margin: (left: 3em))
#set par.line(numbering: "1") #set par.line(numbering: "1")
a a
#([\ a] * 15) #([\ a] * 15)
--- line-numbers-start-alignment --- --- line-numbers-start-alignment ---
#set page(margin: (left: 2cm)) #set page(margin: (left: 3em))
#set par.line(numbering: "i", number-align: start) #set par.line(numbering: "i", number-align: start)
a \ a \
a a
@ -47,7 +47,7 @@ Second line \
Third line Third line
--- line-numbers-rtl --- --- line-numbers-rtl ---
#set page(margin: (right: 2cm)) #set page(margin: (right: 3em))
#set text(dir: rtl) #set text(dir: rtl)
#set par.line(numbering: "1") #set par.line(numbering: "1")
a a
@ -120,7 +120,7 @@ In the \
Sky Sky
--- line-numbers-page-scope --- --- line-numbers-page-scope ---
#set page(margin: (left: 2cm)) #set page(margin: (left: 2.5em))
#set par.line(numbering: "1", numbering-scope: "page") #set par.line(numbering: "1", numbering-scope: "page")
First line \ First line \