Never shrink lines in raw blocks (#3796)

This commit is contained in:
Ana Gelez 2024-04-02 14:16:00 +02:00 committed by Laurenz
parent cb24d10404
commit 444c8682ce
5 changed files with 51 additions and 8 deletions

View File

@ -73,7 +73,8 @@ pub(crate) fn layout_inline(
let lines = linebreak(&engine, &p, region.x - p.hang);
// Stack the lines into one frame per region.
finalize(&mut engine, &p, &lines, region, expand)
let shrink = ParElem::shrink_in(styles);
finalize(&mut engine, &p, &lines, region, expand, shrink)
}
let fragment = cached(
@ -1191,6 +1192,7 @@ fn finalize(
lines: &[Line],
region: Size,
expand: bool,
shrink: bool,
) -> SourceResult<Fragment> {
// Determine the paragraph's width: Full width of the region if we
// should expand or there's fractional spacing, fit-to-width otherwise.
@ -1207,7 +1209,7 @@ fn finalize(
// Stack the lines into one frame per region.
let mut frames: Vec<Frame> = lines
.iter()
.map(|line| commit(engine, p, line, width, region.y))
.map(|line| commit(engine, p, line, width, region.y, shrink))
.collect::<SourceResult<_>>()?;
// Prevent orphans.
@ -1243,6 +1245,7 @@ fn commit(
line: &Line,
width: Abs,
full: Abs,
shrink: bool,
) -> SourceResult<Frame> {
let mut remaining = width - line.width - p.hang;
let mut offset = Abs::zero();
@ -1289,12 +1292,12 @@ fn commit(
let mut justification_ratio = 0.0;
let mut extra_justification = Abs::zero();
let shrink = line.shrinkability();
let shrinkability = line.shrinkability();
let stretch = line.stretchability();
if remaining < Abs::zero() && shrink > Abs::zero() {
if remaining < Abs::zero() && shrinkability > Abs::zero() && shrink {
// Attempt to reduce the length of the line, using shrinkability.
justification_ratio = (remaining / shrink).max(-1.0);
remaining = (remaining + shrink).min(Abs::zero());
justification_ratio = (remaining / shrinkability).max(-1.0);
remaining = (remaining + shrinkability).min(Abs::zero());
} else if line.justify && fr.is_zero() {
// Attempt to increase the length of the line, using stretchability.
if stretch > Abs::zero() {

View File

@ -96,6 +96,15 @@ pub struct ParElem {
#[resolve]
pub hanging_indent: Length,
/// Indicates wheter an overflowing line should be shrunk.
///
/// This property is set to `false` on raw blocks, because shrinking a line
/// could visually break the indentation.
#[ghost]
#[internal]
#[default(true)]
pub shrink: bool,
/// The contents of the paragraph.
#[external]
#[required]

View File

@ -16,7 +16,7 @@ use crate::foundations::{
PlainText, Show, ShowSet, Smart, StyleChain, Styles, Synthesize, Value,
};
use crate::layout::{BlockElem, Em, HAlignment};
use crate::model::Figurable;
use crate::model::{Figurable, ParElem};
use crate::syntax::{split_newlines, LinkedNode, Span, Spanned};
use crate::text::{
FontFamily, FontList, Hyphenate, Lang, LinebreakElem, LocalName, Region,
@ -440,13 +440,16 @@ impl Show for Packed<RawElem> {
}
impl ShowSet for Packed<RawElem> {
fn show_set(&self, _: StyleChain) -> Styles {
fn show_set(&self, styles: StyleChain) -> Styles {
let mut out = Styles::new();
out.set(TextElem::set_overhang(false));
out.set(TextElem::set_hyphenate(Hyphenate(Smart::Custom(false))));
out.set(TextElem::set_size(TextSize(Em::new(0.8).into())));
out.set(TextElem::set_font(FontList(vec![FontFamily::new("DejaVu Sans Mono")])));
out.set(SmartQuoteElem::set_enabled(false));
if self.block(styles) {
out.set(ParElem::set_shrink(false));
}
out
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -0,0 +1,28 @@
// Spaces in raw blocks should not be shrunk
// as it would mess up the indentation of code
// https://github.com/typst/typst/issues/3191
---
#set par(justify: true)
#show raw.where(block: true): block.with(
fill: luma(240),
inset: 10pt,
)
#block(
width: 60%,
```py
for x in xs:
print("x=",x)
```
)
---
// In normal paragraphs, spaces should still be shrunk.
// The first line here serves as a reference, while the second
// uses non-breaking spaces to create an overflowing line
// (which should shrink).
~~~~No shrinking here
~~~~The~spaces~on~this~line~shrink