mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Remove Target
enum
This commit is contained in:
parent
ddb617390c
commit
c3895cbd66
@ -33,7 +33,7 @@ use typst::frame::Frame;
|
|||||||
use typst::geom::*;
|
use typst::geom::*;
|
||||||
use typst::model::{
|
use typst::model::{
|
||||||
capability, Content, Node, SequenceNode, Show, StyleChain, StyleEntry,
|
capability, Content, Node, SequenceNode, Show, StyleChain, StyleEntry,
|
||||||
StyleVecBuilder, StyledNode, Target,
|
StyleVecBuilder, StyledNode,
|
||||||
};
|
};
|
||||||
use typst::World;
|
use typst::World;
|
||||||
|
|
||||||
@ -312,8 +312,8 @@ impl<'a> Builder<'a> {
|
|||||||
content: &'a Content,
|
content: &'a Content,
|
||||||
styles: StyleChain<'a>,
|
styles: StyleChain<'a>,
|
||||||
) -> SourceResult<()> {
|
) -> SourceResult<()> {
|
||||||
if let Some(text) = content.downcast::<TextNode>() {
|
if content.is::<TextNode>() {
|
||||||
if let Some(realized) = styles.apply(self.world, Target::Text(&text.0))? {
|
if let Some(realized) = styles.apply(self.world, content)? {
|
||||||
let stored = self.scratch.content.alloc(realized);
|
let stored = self.scratch.content.alloc(realized);
|
||||||
return self.accept(stored, styles);
|
return self.accept(stored, styles);
|
||||||
}
|
}
|
||||||
@ -362,7 +362,7 @@ impl<'a> Builder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self, content: &Content, styles: StyleChain<'a>) -> SourceResult<bool> {
|
fn show(&mut self, content: &Content, styles: StyleChain<'a>) -> SourceResult<bool> {
|
||||||
let Some(realized) = styles.apply(self.world, Target::Node(content))? else {
|
let Some(realized) = styles.apply(self.world, content)? else {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ pub mod structure;
|
|||||||
pub mod text;
|
pub mod text;
|
||||||
|
|
||||||
use typst::geom::{Align, Color, Dir, GenAlign};
|
use typst::geom::{Align, Color, Dir, GenAlign};
|
||||||
use typst::model::{LangItems, Node, Scope, StyleMap};
|
use typst::model::{LangItems, Node, NodeId, Scope, StyleMap};
|
||||||
|
|
||||||
use self::layout::LayoutRoot;
|
use self::layout::LayoutRoot;
|
||||||
|
|
||||||
@ -160,6 +160,8 @@ pub fn items() -> LangItems {
|
|||||||
space: || text::SpaceNode.pack(),
|
space: || text::SpaceNode.pack(),
|
||||||
linebreak: |justify| text::LinebreakNode { justify }.pack(),
|
linebreak: |justify| text::LinebreakNode { justify }.pack(),
|
||||||
text: |text| text::TextNode(text).pack(),
|
text: |text| text::TextNode(text).pack(),
|
||||||
|
text_id: NodeId::of::<text::TextNode>(),
|
||||||
|
text_str: |content| Some(&content.downcast::<text::TextNode>()?.0),
|
||||||
smart_quote: |double| text::SmartQuoteNode { double }.pack(),
|
smart_quote: |double| text::SmartQuoteNode { double }.pack(),
|
||||||
parbreak: || text::ParbreakNode.pack(),
|
parbreak: || text::ParbreakNode.pack(),
|
||||||
strong: |body| text::StrongNode(body).pack(),
|
strong: |body| text::StrongNode(body).pack(),
|
||||||
|
@ -5,7 +5,7 @@ use std::num::NonZeroUsize;
|
|||||||
use comemo::Tracked;
|
use comemo::Tracked;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
use super::{Content, StyleChain};
|
use super::{Content, NodeId, StyleChain};
|
||||||
use crate::diag::SourceResult;
|
use crate::diag::SourceResult;
|
||||||
use crate::frame::Frame;
|
use crate::frame::Frame;
|
||||||
use crate::geom::{Abs, Dir};
|
use crate::geom::{Abs, Dir};
|
||||||
@ -54,6 +54,10 @@ pub struct LangItems {
|
|||||||
pub linebreak: fn(justify: bool) -> Content,
|
pub linebreak: fn(justify: bool) -> Content,
|
||||||
/// Plain text without markup.
|
/// Plain text without markup.
|
||||||
pub text: fn(text: EcoString) -> Content,
|
pub text: fn(text: EcoString) -> Content,
|
||||||
|
/// The id of the text node.
|
||||||
|
pub text_id: NodeId,
|
||||||
|
/// Get the string if this is a text node.
|
||||||
|
pub text_str: fn(&Content) -> Option<&str>,
|
||||||
/// A smart quote: `'` or `"`.
|
/// A smart quote: `'` or `"`.
|
||||||
pub smart_quote: fn(double: bool) -> Content,
|
pub smart_quote: fn(double: bool) -> Content,
|
||||||
/// A paragraph break.
|
/// A paragraph break.
|
||||||
|
@ -247,9 +247,7 @@ impl<'a> StyleChain<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the style chain has a matching recipe for the content.
|
/// Whether the style chain has a matching recipe for the content.
|
||||||
pub fn applicable(self, content: &Content) -> bool {
|
pub fn applicable(self, target: &Content) -> bool {
|
||||||
let target = Target::Node(content);
|
|
||||||
|
|
||||||
// Find out how many recipes there any and whether any of them match.
|
// Find out how many recipes there any and whether any of them match.
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
let mut any = true;
|
let mut any = true;
|
||||||
@ -278,7 +276,7 @@ impl<'a> StyleChain<'a> {
|
|||||||
pub fn apply(
|
pub fn apply(
|
||||||
self,
|
self,
|
||||||
world: Tracked<dyn World>,
|
world: Tracked<dyn World>,
|
||||||
target: Target,
|
target: &Content,
|
||||||
) -> SourceResult<Option<Content>> {
|
) -> SourceResult<Option<Content>> {
|
||||||
// Find out how many recipes there any and whether any of them match.
|
// Find out how many recipes there any and whether any of them match.
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
@ -306,16 +304,14 @@ impl<'a> StyleChain<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Target::Node(node) = target {
|
if let Some(showable) = target.to::<dyn Show>() {
|
||||||
// Realize if there was no matching recipe.
|
// Realize if there was no matching recipe.
|
||||||
if realized.is_none() {
|
if realized.is_none() {
|
||||||
let sel = RecipeId::Base(node.id());
|
let sel = RecipeId::Base(target.id());
|
||||||
if self.guarded(sel) {
|
if self.guarded(sel) {
|
||||||
guarded = true;
|
guarded = true;
|
||||||
} else {
|
} else {
|
||||||
let content = node
|
let content = showable
|
||||||
.to::<dyn Show>()
|
|
||||||
.unwrap()
|
|
||||||
.unguard_parts(sel)
|
.unguard_parts(sel)
|
||||||
.to::<dyn Show>()
|
.to::<dyn Show>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -327,7 +323,7 @@ impl<'a> StyleChain<'a> {
|
|||||||
|
|
||||||
// Finalize only if guarding didn't stop any recipe.
|
// Finalize only if guarding didn't stop any recipe.
|
||||||
if !guarded {
|
if !guarded {
|
||||||
if let Some(node) = node.to::<dyn Finalize>() {
|
if let Some(node) = target.to::<dyn Finalize>() {
|
||||||
if let Some(content) = realized {
|
if let Some(content) = realized {
|
||||||
realized = Some(node.finalize(world, self, content)?);
|
realized = Some(node.finalize(world, self, content)?);
|
||||||
}
|
}
|
||||||
@ -1006,7 +1002,7 @@ pub struct Recipe {
|
|||||||
|
|
||||||
impl Recipe {
|
impl Recipe {
|
||||||
/// Whether the recipe is applicable to the target.
|
/// Whether the recipe is applicable to the target.
|
||||||
pub fn applicable(&self, target: Target) -> bool {
|
pub fn applicable(&self, target: &Content) -> bool {
|
||||||
self.selector
|
self.selector
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(false, |selector| selector.matches(target))
|
.map_or(false, |selector| selector.matches(target))
|
||||||
@ -1017,16 +1013,24 @@ impl Recipe {
|
|||||||
&self,
|
&self,
|
||||||
world: Tracked<dyn World>,
|
world: Tracked<dyn World>,
|
||||||
sel: RecipeId,
|
sel: RecipeId,
|
||||||
target: Target,
|
target: &Content,
|
||||||
) -> SourceResult<Option<Content>> {
|
) -> SourceResult<Option<Content>> {
|
||||||
let content = match (target, &self.selector) {
|
let content = match &self.selector {
|
||||||
(Target::Node(node), Some(Selector::Node(id, _))) if node.id() == *id => {
|
Some(Selector::Node(id, _)) => {
|
||||||
|
if target.id() != *id {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
self.transform.apply(world, self.span, || {
|
self.transform.apply(world, self.span, || {
|
||||||
Value::Content(node.to::<dyn Show>().unwrap().unguard_parts(sel))
|
Value::Content(target.to::<dyn Show>().unwrap().unguard_parts(sel))
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
|
|
||||||
(Target::Text(text), Some(Selector::Regex(regex))) => {
|
Some(Selector::Regex(regex)) => {
|
||||||
|
let Some(text) = item!(text_str)(target) else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
let make = world.config().items.text;
|
let make = world.config().items.text;
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
let mut cursor = 0;
|
let mut cursor = 0;
|
||||||
@ -1055,7 +1059,7 @@ impl Recipe {
|
|||||||
Content::sequence(result)
|
Content::sequence(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => return Ok(None),
|
None => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(content.styled_with_entry(StyleEntry::Guard(sel))))
|
Ok(Some(content.styled_with_entry(StyleEntry::Guard(sel))))
|
||||||
@ -1095,17 +1099,16 @@ impl Selector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the selector matches for the target.
|
/// Whether the selector matches for the target.
|
||||||
pub fn matches(&self, target: Target) -> bool {
|
pub fn matches(&self, target: &Content) -> bool {
|
||||||
match (self, target) {
|
match self {
|
||||||
(Self::Node(id, dict), Target::Node(node)) => {
|
Self::Node(id, dict) => {
|
||||||
*id == node.id()
|
*id == target.id()
|
||||||
&& dict
|
&& dict
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|dict| dict.iter())
|
.flat_map(|dict| dict.iter())
|
||||||
.all(|(name, value)| node.field(name).as_ref() == Some(value))
|
.all(|(name, value)| target.field(name).as_ref() == Some(value))
|
||||||
}
|
}
|
||||||
(Self::Regex(_), Target::Text(_)) => true,
|
Self::Regex(_) => target.id() == item!(text_id),
|
||||||
_ => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1140,15 +1143,6 @@ impl Transform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A target for a show rule recipe.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
||||||
pub enum Target<'a> {
|
|
||||||
/// A showable node.
|
|
||||||
Node(&'a Content),
|
|
||||||
/// A slice of text.
|
|
||||||
Text(&'a str),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Identifies a show rule recipe.
|
/// Identifies a show rule recipe.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Hash)]
|
||||||
pub enum RecipeId {
|
pub enum RecipeId {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user