mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Fix order of tags in text show rules matches (#5083)
This commit is contained in:
parent
f0ada7ba0c
commit
63e6150ca1
@ -1115,13 +1115,22 @@ fn visit_regex_match<'a>(
|
||||
elems: &[Pair<'a>],
|
||||
m: RegexMatch<'a>,
|
||||
) -> SourceResult<()> {
|
||||
let matched = m.offset..m.offset + m.text.len();
|
||||
let match_range = m.offset..m.offset + m.text.len();
|
||||
let piece = TextElem::packed(m.text);
|
||||
let context = Context::new(None, Some(m.styles));
|
||||
let output = m.recipe.apply(s.engine, context.track(), piece)?;
|
||||
|
||||
let mut output = Some(output);
|
||||
let mut cursor = 0;
|
||||
let mut output = Some(output);
|
||||
let mut visit_unconsumed_match = |s: &mut State<'a, '_, '_, '_>| -> SourceResult<()> {
|
||||
if let Some(output) = output.take() {
|
||||
let revocation = Style::Revocation(m.id).into();
|
||||
let outer = s.arenas.bump.alloc(m.styles);
|
||||
let chained = outer.chain(s.arenas.styles.alloc(revocation));
|
||||
visit(s, s.store(output), chained)?;
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
for &(content, styles) in elems {
|
||||
// Just forward tags.
|
||||
@ -1130,48 +1139,49 @@ fn visit_regex_match<'a>(
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine the range of the element.
|
||||
// At this point, we can have a `TextElem`, `SpaceElem`,
|
||||
// `LinebreakElem`, or `SmartQuoteElem`. We now determine the range of
|
||||
// the element.
|
||||
let len = content.to_packed::<TextElem>().map_or(1, |elem| elem.text.len());
|
||||
let subrange = cursor..cursor + len;
|
||||
let elem_range = cursor..cursor + len;
|
||||
|
||||
// If the element starts before the start of match, visit it fully or
|
||||
// sliced.
|
||||
if subrange.start < matched.start {
|
||||
if subrange.end <= matched.start {
|
||||
if elem_range.start < match_range.start {
|
||||
if elem_range.end <= match_range.start {
|
||||
visit(s, content, styles)?;
|
||||
} else {
|
||||
let mut elem = content.to_packed::<TextElem>().unwrap().clone();
|
||||
elem.text = elem.text[..matched.start - subrange.start].into();
|
||||
elem.text = elem.text[..match_range.start - elem_range.start].into();
|
||||
visit(s, s.store(elem.pack()), styles)?;
|
||||
}
|
||||
}
|
||||
|
||||
// When the match starts at or before this element ends, visit the
|
||||
// match.
|
||||
if matched.start <= subrange.end {
|
||||
if let Some(output) = output.take() {
|
||||
let revocation = Style::Revocation(m.id).into();
|
||||
let outer = s.arenas.bump.alloc(m.styles);
|
||||
let chained = outer.chain(s.arenas.styles.alloc(revocation));
|
||||
visit(s, s.store(output), chained)?;
|
||||
}
|
||||
// When the match starts before this element ends, visit it.
|
||||
if match_range.start < elem_range.end {
|
||||
visit_unconsumed_match(s)?;
|
||||
}
|
||||
|
||||
// If the element ends after the end of the match, visit if fully or
|
||||
// sliced.
|
||||
if subrange.end > matched.end {
|
||||
if subrange.start >= matched.end {
|
||||
if elem_range.end > match_range.end {
|
||||
if elem_range.start >= match_range.end {
|
||||
visit(s, content, styles)?;
|
||||
} else {
|
||||
let mut elem = content.to_packed::<TextElem>().unwrap().clone();
|
||||
elem.text = elem.text[matched.end - subrange.start..].into();
|
||||
elem.text = elem.text[match_range.end - elem_range.start..].into();
|
||||
visit(s, s.store(elem.pack()), styles)?;
|
||||
}
|
||||
}
|
||||
|
||||
cursor = subrange.end;
|
||||
cursor = elem_range.end;
|
||||
}
|
||||
|
||||
// If the match wasn't consumed yet, visit it. This shouldn't really happen
|
||||
// in practice (we'd need to have an empty match at the end), but it's an
|
||||
// extra fail-safe.
|
||||
visit_unconsumed_match(s)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
BIN
tests/ref/issue-5014-show-text-tags.png
Normal file
BIN
tests/ref/issue-5014-show-text-tags.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 184 B |
@ -199,3 +199,12 @@ $a^2 + b^2 = c^2$ is Pythagoras' theorem.
|
||||
a \ #h(0pt, weak: true)
|
||||
b \ #h(0pt, weak: true)
|
||||
$x$ c $y$
|
||||
|
||||
--- issue-5014-show-text-tags ---
|
||||
#{
|
||||
let c = counter("c")
|
||||
show "b": context c.get().first()
|
||||
[a]
|
||||
c.step()
|
||||
[bc]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user