diff --git a/crates/typst-library/src/visualize/color.rs b/crates/typst-library/src/visualize/color.rs index 5c657b4e2..dd0287d4b 100644 --- a/crates/typst-library/src/visualize/color.rs +++ b/crates/typst-library/src/visualize/color.rs @@ -797,7 +797,9 @@ impl Color { components } - /// Returns the constructor function for this color's space: + /// Returns the constructor function for this color's space. + /// + /// Returns one of: /// - [`luma`]($color.luma) /// - [`oklab`]($color.oklab) /// - [`oklch`]($color.oklch) diff --git a/docs/src/lib.rs b/docs/src/lib.rs index e3eb21f98..155ffb827 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -242,7 +242,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel { items.push(CategoryItem { name: group.name.clone(), route: subpage.route.clone(), - oneliner: oneliner(docs).into(), + oneliner: oneliner(docs), code: true, }); children.push(subpage); @@ -296,7 +296,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel { items.push(CategoryItem { name: name.into(), route: subpage.route.clone(), - oneliner: oneliner(func.docs().unwrap_or_default()).into(), + oneliner: oneliner(func.docs().unwrap_or_default()), code: true, }); children.push(subpage); @@ -306,7 +306,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel { items.push(CategoryItem { name: ty.short_name().into(), route: subpage.route.clone(), - oneliner: oneliner(ty.docs()).into(), + oneliner: oneliner(ty.docs()), code: true, }); children.push(subpage); @@ -637,7 +637,7 @@ fn group_page( let item = CategoryItem { name: group.name.clone(), route: model.route.clone(), - oneliner: oneliner(&group.details).into(), + oneliner: oneliner(&group.details), code: false, }; @@ -772,8 +772,24 @@ pub fn urlify(title: &str) -> EcoString { } /// Extract the first line of documentation. -fn oneliner(docs: &str) -> &str { - docs.lines().next().unwrap_or_default() +fn oneliner(docs: &str) -> EcoString { + let paragraph = docs.split("\n\n").next().unwrap_or_default(); + let mut depth = 0; + let mut period = false; + let mut end = paragraph.len(); + for (i, c) in paragraph.char_indices() { + match c { + '(' | '[' | '{' => depth += 1, + ')' | ']' | '}' => depth -= 1, + '.' if depth == 0 => period = true, + c if period && c.is_whitespace() && !docs[..i].ends_with("e.g.") => { + end = i; + break; + } + _ => period = false, + } + } + EcoString::from(&docs[..end]).replace("\r\n", " ").replace("\n", " ") } /// The order of types in the documentation. diff --git a/docs/src/model.rs b/docs/src/model.rs index 801c60c7f..e3b15e377 100644 --- a/docs/src/model.rs +++ b/docs/src/model.rs @@ -86,7 +86,7 @@ pub struct FuncModel { pub name: EcoString, pub title: &'static str, pub keywords: &'static [&'static str], - pub oneliner: &'static str, + pub oneliner: EcoString, pub element: bool, pub contextual: bool, pub deprecation: Option<&'static str>, @@ -139,7 +139,7 @@ pub struct TypeModel { pub name: &'static str, pub title: &'static str, pub keywords: &'static [&'static str], - pub oneliner: &'static str, + pub oneliner: EcoString, pub details: Html, pub constructor: Option, pub scope: Vec,