diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-09-26 17:12:18 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-09-26 17:12:18 +0200 |
| commit | d7928a8ea347df89f501e5b3ecbb52402cae8edb (patch) | |
| tree | 0c63d98a96e1e3762d0fec94c7cda3d16817da64 /crates/typst-ide/src/lib.rs | |
| parent | 0d39fa021f2aa84c3302242082ea3bf23cc7f99d (diff) | |
Extract IDE crate
Diffstat (limited to 'crates/typst-ide/src/lib.rs')
| -rw-r--r-- | crates/typst-ide/src/lib.rs | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/crates/typst-ide/src/lib.rs b/crates/typst-ide/src/lib.rs new file mode 100644 index 00000000..3ab367dc --- /dev/null +++ b/crates/typst-ide/src/lib.rs @@ -0,0 +1,94 @@ +//! Capabilities for IDE support. + +mod analyze; +mod complete; +mod jump; +mod tooltip; + +pub use self::analyze::analyze_labels; +pub use self::complete::{autocomplete, Completion, CompletionKind}; +pub use self::jump::{jump_from_click, jump_from_cursor, Jump}; +pub use self::tooltip::{tooltip, Tooltip}; + +use std::fmt::Write; + +use ecow::{eco_format, EcoString}; +use typst::font::{FontInfo, FontStyle}; + +use self::analyze::*; + +/// Extract the first sentence of plain text of a piece of documentation. +/// +/// Removes Markdown formatting. +fn plain_docs_sentence(docs: &str) -> EcoString { + let mut s = unscanny::Scanner::new(docs); + let mut output = EcoString::new(); + let mut link = false; + while let Some(c) = s.eat() { + match c { + '`' => { + let mut raw = s.eat_until('`'); + if (raw.starts_with('{') && raw.ends_with('}')) + || (raw.starts_with('[') && raw.ends_with(']')) + { + raw = &raw[1..raw.len() - 1]; + } + + s.eat(); + output.push('`'); + output.push_str(raw); + output.push('`'); + } + '[' => link = true, + ']' if link => { + if s.eat_if('(') { + s.eat_until(')'); + s.eat(); + } else if s.eat_if('[') { + s.eat_until(']'); + s.eat(); + } + link = false + } + '*' | '_' => {} + '.' => { + output.push('.'); + break; + } + _ => output.push(c), + } + } + + output +} + +/// Create a short description of a font family. +fn summarize_font_family<'a>(variants: impl Iterator<Item = &'a FontInfo>) -> EcoString { + let mut infos: Vec<_> = variants.collect(); + infos.sort_by_key(|info| info.variant); + + let mut has_italic = false; + let mut min_weight = u16::MAX; + let mut max_weight = 0; + for info in &infos { + let weight = info.variant.weight.to_number(); + has_italic |= info.variant.style == FontStyle::Italic; + min_weight = min_weight.min(weight); + max_weight = min_weight.max(weight); + } + + let count = infos.len(); + let mut detail = eco_format!("{count} variant{}.", if count == 1 { "" } else { "s" }); + + if min_weight == max_weight { + write!(detail, " Weight {min_weight}.").unwrap(); + } else { + write!(detail, " Weights {min_weight}–{max_weight}.").unwrap(); + } + + if has_italic { + detail.push_str(" Has italics."); + } + + detail +} |
