Repository: typst/typst
File: docs/src/lib.rs (Rust)

Code before:
        let complete = |variant: codex::ModifierSet<&str>| {
            if variant.is_empty() {
                name.clone()
            } else {
                eco_format!("{}.{}", name, variant.as_str())
            }
        };

        for (variant, value, deprecation) in symbol.variants() {
            let value_char = value.parse::<char>().ok();

            let shorthand = |list: &[(&'static str, char)]| {
                value_char.and_then(|c| {
                    list.iter().copied().find(|&(_, x)| x == c).map(|(s, _)| s)
                })
            };

            let name = complete(variant);

            list.push(SymbolModel {
                name,
                markup_shorthand: shorthand(typst::syntax::ast::Shorthand::LIST),
                math_shorthand: shorthand(typst::syntax::ast::MathShorthand::LIST),
                math_class: value_char.and_then(|c| {
                    typst_utils::default_math_class(c).map(math_class_name)
                }),
                value: value.into(),
                accent: value_char
                    .is_some_and(|c| typst::math::Accent::combine(c).is_some()),
                alternates: symbol
                    .variants()
                    .filter(|(other, _, _)| other != &variant)
                    .map(|(other, _, _)| complete(other))
                    .collect(),
                deprecation: deprecation.or_else(|| binding.deprecation()),
            });
        }
    }

    SymbolsModel {
        name: group.name.clone(),
        title: group.title.clone(),
        details: Html::markdown(resolver, &group.details, Some(1)),
        list,
    }
}

/// Extract a module from another module.
#[track_caller]
fn get_module<'a>(parent: &'a Module, name: &str) -> StrResult<&'a Module> {
    match parent.scope().get(name).map(Binding::read) {

Review comment (suggestion):
We might want to be more subtle than that here. If `value` is the string `"⤴\u{FE0E}"` (U+2934, which is a Relation, followed by a text presentation selector), we want the math class to be that of the base character of the variation sequence.

Probably same for the `accent` below.

Code after:
        let Value::Symbol(symbol) = binding.read() else { continue };
        let complete = |variant: codex::ModifierSet<&str>| {
            if variant.is_empty() {
                name.clone()
            } else {
                eco_format!("{}.{}", name, variant.as_str())
            }
        };

        for (variant, value, deprecation_message) in symbol.variants() {
            let value_char = value.parse::<char>().ok();

            let shorthand = |list: &[(&'static str, char)]| {
                value_char.and_then(|c| {
                    list.iter().copied().find(|&(_, x)| x == c).map(|(s, _)| s)
                })
            };

            let name = complete(variant);

            list.push(SymbolModel {
                name,
                markup_shorthand: shorthand(typst::syntax::ast::Shorthand::LIST),
                math_shorthand: shorthand(typst::syntax::ast::MathShorthand::LIST),
                // Matches `typst_layout::math::GlyphFragment::new`
                math_class: value.chars().next().and_then(|c| {
                    typst_utils::default_math_class(c).map(math_class_name)
                }),
                value: value.into(),
                // Matches casting `Symbol` to `Accent`
                accent: value_char
                    .is_some_and(|c| typst::math::Accent::combine(c).is_some()),
                alternates: symbol
                    .variants()
                    .filter(|(other, _, _)| other != &variant)
                    .map(|(other, _, _)| complete(other))
                    .collect(),
                deprecation_message: deprecation_message
                    .or_else(|| binding.deprecation().map(Deprecation::message)),
                deprecation_until: binding.deprecation().and_then(Deprecation::until),
            });
        }
    }

    SymbolsModel {
        name: group.name.clone(),
        title: group.title.clone(),
        details: Html::markdown(resolver, &group.details, Some(1)),
        list,
    }
}