diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-03 11:44:53 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-03 13:35:39 +0100 |
| commit | 37a7afddfaffd44cb9bc013c9506599267e08983 (patch) | |
| tree | 20e7d62d3c5418baff01a21d0406b91bf3096214 /src/library/text/raw.rs | |
| parent | 56342bd972a13ffe21beaf2b87ab7eb1597704b4 (diff) | |
Split crates
Diffstat (limited to 'src/library/text/raw.rs')
| -rw-r--r-- | src/library/text/raw.rs | 205 |
1 files changed, 0 insertions, 205 deletions
diff --git a/src/library/text/raw.rs b/src/library/text/raw.rs deleted file mode 100644 index 0c769636..00000000 --- a/src/library/text/raw.rs +++ /dev/null @@ -1,205 +0,0 @@ -use once_cell::sync::Lazy; -use syntect::easy::HighlightLines; -use syntect::highlighting::{ - Color, FontStyle, Style, StyleModifier, Theme, ThemeItem, ThemeSettings, -}; -use syntect::parsing::SyntaxSet; - -use super::{FontFamily, Hyphenate, LinebreakNode, TextNode}; -use crate::library::layout::{BlockNode, BlockSpacing}; -use crate::library::prelude::*; - -/// Monospaced text with optional syntax highlighting. -#[derive(Debug, Hash)] -pub struct RawNode { - /// The raw text. - pub text: EcoString, - /// Whether the node is block-level. - pub block: bool, -} - -#[node(Show)] -impl RawNode { - /// The language to syntax-highlight in. - #[property(referenced)] - pub const LANG: Option<EcoString> = None; - /// The raw text's font family. - #[property(referenced)] - pub const FAMILY: FontFamily = FontFamily::new("IBM Plex Mono"); - /// The spacing above block-level raw. - #[property(resolve, shorthand(around))] - pub const ABOVE: Option<BlockSpacing> = Some(Ratio::one().into()); - /// The spacing below block-level raw. - #[property(resolve, shorthand(around))] - pub const BELOW: Option<BlockSpacing> = Some(Ratio::one().into()); - - fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> { - Ok(Self { - text: args.expect("text")?, - block: args.named("block")?.unwrap_or(false), - } - .pack()) - } -} - -impl Show for RawNode { - fn unguard_parts(&self, _: Selector) -> Content { - Self { text: self.text.clone(), ..*self }.pack() - } - - fn field(&self, name: &str) -> Option<Value> { - match name { - "text" => Some(Value::Str(self.text.clone().into())), - "block" => Some(Value::Bool(self.block)), - _ => None, - } - } - - fn realize( - &self, - _: Tracked<dyn World>, - styles: StyleChain, - ) -> SourceResult<Content> { - let lang = styles.get(Self::LANG).as_ref().map(|s| s.to_lowercase()); - let foreground = THEME - .settings - .foreground - .map(Color::from) - .unwrap_or(Color::BLACK) - .into(); - - let mut realized = if matches!(lang.as_deref(), Some("typ" | "typst" | "typc")) { - let root = match lang.as_deref() { - Some("typc") => crate::syntax::parse_code(&self.text), - _ => crate::syntax::parse(&self.text), - }; - - let mut seq = vec![]; - crate::syntax::highlight::highlight_themed(&root, &THEME, |range, style| { - seq.push(styled(&self.text[range], foreground, style)); - }); - - Content::sequence(seq) - } else if let Some(syntax) = - lang.and_then(|token| SYNTAXES.find_syntax_by_token(&token)) - { - let mut seq = vec![]; - let mut highlighter = HighlightLines::new(syntax, &THEME); - for (i, line) in self.text.lines().enumerate() { - if i != 0 { - seq.push(LinebreakNode { justify: false }.pack()); - } - - for (style, piece) in - highlighter.highlight_line(line, &SYNTAXES).into_iter().flatten() - { - seq.push(styled(piece, foreground, style)); - } - } - - Content::sequence(seq) - } else { - TextNode(self.text.clone()).pack() - }; - - if self.block { - realized = BlockNode(realized).pack(); - } - - let mut map = StyleMap::new(); - map.set(TextNode::OVERHANG, false); - map.set(TextNode::HYPHENATE, Smart::Custom(Hyphenate(false))); - map.set(TextNode::SMART_QUOTES, false); - - Ok(realized.styled_with_map(map)) - } - - fn finalize( - &self, - _: Tracked<dyn World>, - styles: StyleChain, - mut realized: Content, - ) -> SourceResult<Content> { - let mut map = StyleMap::new(); - map.set_family(styles.get(Self::FAMILY).clone(), styles); - - if self.block { - realized = realized.spaced(styles.get(Self::ABOVE), styles.get(Self::BELOW)); - } - - Ok(realized.styled_with_map(map)) - } -} - -/// Style a piece of text with a syntect style. -fn styled(piece: &str, foreground: Paint, style: Style) -> Content { - let mut body = TextNode(piece.into()).pack(); - - let paint = style.foreground.into(); - if paint != foreground { - body = body.styled(TextNode::FILL, paint); - } - - if style.font_style.contains(FontStyle::BOLD) { - body = body.strong(); - } - - if style.font_style.contains(FontStyle::ITALIC) { - body = body.emph(); - } - - if style.font_style.contains(FontStyle::UNDERLINE) { - body = body.underlined(); - } - - body -} - -/// The syntect syntax definitions. -static SYNTAXES: Lazy<SyntaxSet> = Lazy::new(|| SyntaxSet::load_defaults_newlines()); - -/// The default theme used for syntax highlighting. -#[rustfmt::skip] -pub static THEME: Lazy<Theme> = Lazy::new(|| Theme { - name: Some("Typst Light".into()), - author: Some("The Typst Project Developers".into()), - settings: ThemeSettings::default(), - scopes: vec![ - item("comment", Some("#8a8a8a"), None), - item("constant.character.escape", Some("#1d6c76"), None), - item("constant.character.shortcut", Some("#1d6c76"), None), - item("markup.bold", None, Some(FontStyle::BOLD)), - item("markup.italic", None, Some(FontStyle::ITALIC)), - item("markup.underline", None, Some(FontStyle::UNDERLINE)), - item("markup.raw", Some("#818181"), None), - item("string.other.math.typst", None, None), - item("punctuation.definition.math", Some("#298e0d"), None), - item("keyword.operator.math", Some("#1d6c76"), None), - item("markup.heading, entity.name.section", None, Some(FontStyle::BOLD)), - item("markup.heading.typst", None, Some(FontStyle::BOLD | FontStyle::UNDERLINE)), - item("punctuation.definition.list", Some("#8b41b1"), None), - item("markup.list.term", None, Some(FontStyle::BOLD)), - item("entity.name.label, markup.other.reference", Some("#1d6c76"), None), - item("keyword, constant.language, variable.language", Some("#d73a49"), None), - item("storage.type, storage.modifier", Some("#d73a49"), None), - item("constant", Some("#b60157"), None), - item("string", Some("#298e0d"), None), - item("entity.name, variable.function, support", Some("#4b69c6"), None), - item("support.macro", Some("#16718d"), None), - item("meta.annotation", Some("#301414"), None), - item("entity.other, meta.interpolation", Some("#8b41b1"), None), - item("invalid", Some("#ff0000"), None), - ], -}); - -/// Create a syntect theme item. -fn item(scope: &str, color: Option<&str>, font_style: Option<FontStyle>) -> ThemeItem { - ThemeItem { - scope: scope.parse().unwrap(), - style: StyleModifier { - foreground: color.map(|s| s.parse::<RgbaColor>().unwrap().into()), - background: None, - font_style, - }, - } -} |
