Fix styling of text operators

This commit is contained in:
Laurenz 2023-03-29 19:21:01 +02:00
parent e13fc04c3e
commit 24e26b8c77
6 changed files with 25 additions and 16 deletions

View File

@ -124,11 +124,11 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
.into_frame()) .into_frame())
} }
pub fn layout_text(&mut self, elem: &TextElem) -> SourceResult<()> { pub fn layout_text(&mut self, elem: &TextElem) -> SourceResult<MathFragment> {
let text = elem.text(); let text = elem.text();
let span = elem.span(); let span = elem.span();
let mut chars = text.chars(); let mut chars = text.chars();
if let Some(glyph) = chars let fragment = if let Some(glyph) = chars
.next() .next()
.filter(|_| chars.next().is_none()) .filter(|_| chars.next().is_none())
.map(|c| self.style.styled_char(c)) .map(|c| self.style.styled_char(c))
@ -139,9 +139,9 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
&& glyph.class == Some(MathClass::Large) && glyph.class == Some(MathClass::Large)
{ {
let height = scaled!(self, display_operator_min_height); let height = scaled!(self, display_operator_min_height);
self.push(glyph.stretch_vertical(self, height, Abs::zero())); glyph.stretch_vertical(self, height, Abs::zero()).into()
} else { } else {
self.push(glyph); glyph.into()
} }
} else if text.chars().all(|c| c.is_ascii_digit()) { } else if text.chars().all(|c| c.is_ascii_digit()) {
// Numbers aren't that difficult. // Numbers aren't that difficult.
@ -151,7 +151,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
fragments.push(GlyphFragment::new(self, c, span).into()); fragments.push(GlyphFragment::new(self, c, span).into());
} }
let frame = MathRow::new(fragments).to_frame(self); let frame = MathRow::new(fragments).to_frame(self);
self.push(FrameFragment::new(self, frame)); FrameFragment::new(self, frame).into()
} else { } else {
// Anything else is handled by Typst's standard text layout. // Anything else is handled by Typst's standard text layout.
let spaced = text.graphemes(true).count() > 1; let spaced = text.graphemes(true).count() > 1;
@ -161,14 +161,12 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
} }
let text: EcoString = text.chars().map(|c| style.styled_char(c)).collect(); let text: EcoString = text.chars().map(|c| style.styled_char(c)).collect();
let frame = self.layout_content(&TextElem::packed(text).spanned(span))?; let frame = self.layout_content(&TextElem::packed(text).spanned(span))?;
self.push(
FrameFragment::new(self, frame) FrameFragment::new(self, frame)
.with_class(MathClass::Alphabetic) .with_class(MathClass::Alphabetic)
.with_spaced(spaced), .with_spaced(spaced)
); .into()
} };
Ok(fragment)
Ok(())
} }
pub fn styles(&self) -> StyleChain { pub fn styles(&self) -> StyleChain {

View File

@ -331,7 +331,8 @@ impl LayoutMath for Content {
} }
if let Some(elem) = self.to::<TextElem>() { if let Some(elem) = self.to::<TextElem>() {
ctx.layout_text(elem)?; let fragment = ctx.layout_text(elem)?;
ctx.push(fragment);
return Ok(()); return Ok(());
} }

View File

@ -35,9 +35,10 @@ pub struct OpElem {
impl LayoutMath for OpElem { impl LayoutMath for OpElem {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let frame = ctx.layout_content(&TextElem::packed(self.text()))?; let fragment =
ctx.layout_text(&TextElem::new(self.text()).spanned(self.span()))?;
ctx.push( ctx.push(
FrameFragment::new(ctx, frame) FrameFragment::new(ctx, fragment.to_frame())
.with_class(MathClass::Large) .with_class(MathClass::Large)
.with_limits(self.limits(ctx.styles())), .with_limits(self.limits(ctx.styles())),
); );

View File

@ -204,6 +204,11 @@ fn create(element: &Elem) -> TokenStream {
pub fn span(&self) -> ::typst::syntax::Span { pub fn span(&self) -> ::typst::syntax::Span {
self.0.span() self.0.span()
} }
/// Set the element's span.
pub fn spanned(self, span: ::typst::syntax::Span) -> Self {
Self(self.0.spanned(span))
}
} }
#element_impl #element_impl

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -19,3 +19,7 @@ $ lim_(n->infinity) 1/n = 0 $
// Test custom operator. // Test custom operator.
$ op("myop", limits: #false)_(x:=1) x \ $ op("myop", limits: #false)_(x:=1) x \
op("myop", limits: #true)_(x:=1) x $ op("myop", limits: #true)_(x:=1) x $
---
// Test styled operator.
$ bold(op("bold", limits: #true))_x y $