math-text-transform 0.1.1

Transform greek letters, latin letters, or decimal digits into certain variants from the mathematical alphanumeric symbols Unicode block (U+1D400โ€“U+1D7FF). For example to bold, italic, script or double-struck.
Documentation
//! Transform text from standard alphanumerical characters to itโ€™s
//! unicode equivalents of a certain variant in the [mathematical
//! alphanumeric symbols block][1] (code block U+1D400โ€“U+1D7FF).
//!
//! ```rust
//! use math_text_transform::math_italic;
//! use math_text_transform::MathTextTransform;
//!
//! assert_eq!(math_italic('f'), Some('๐‘“'));
//! assert_eq!("Bold".to_math_bold(), "๐๐จ๐ฅ๐");
//! ```
//!
//! Supported variants are:
//!
//! * ๐›๐จ๐ฅ๐ (bold)
//! * ๐‘–๐‘ก๐‘Ž๐‘™๐‘–๐‘ (italic)
//! * ๐’ƒ๐’๐’๐’… ๐’Š๐’•๐’‚๐’๐’Š๐’„ (bold italic)
//! * ๐—Œ๐–บ๐—‡๐—Œ-๐—Œ๐–พ๐—‹๐—‚๐–ฟ (sans-serif)
//! * ๐˜€๐—ฎ๐—ป๐˜€-๐˜€๐—ฒ๐—ฟ๐—ถ๐—ณ ๐—ฏ๐—ผ๐—น๐—ฑ (sans-serif bold)
//! * ๐˜ด๐˜ข๐˜ฏ๐˜ด-๐˜ด๐˜ฆ๐˜ณ๐˜ช๐˜ง ๐˜ช๐˜ต๐˜ข๐˜ญ๐˜ช๐˜ค (sans-serif italic)
//! * ๐™จ๐™–๐™ฃ๐™จ-๐™จ๐™š๐™ง๐™ž๐™› ๐™—๐™ค๐™ก๐™™ ๐™ž๐™ฉ๐™–๐™ก๐™ž๐™˜ (sans-serif bold italic)
//! * ๐“ˆ๐’ธ๐“‡๐’พ๐“…๐“‰ (script)
//! * ๐“ซ๐“ธ๐“ต๐“ญ ๐“ผ๐“ฌ๐“ป๐“ฒ๐“น๐“ฝ (bold script)
//! * ๐”ฃ๐”ฏ๐”ž๐”จ๐”ฑ๐”ฒ๐”ฏ (fraktur)
//! * ๐–‡๐–”๐–‘๐–‰ ๐–‹๐–—๐–†๐–๐–™๐–š๐–— (bold fraktur)
//! * ๐š–๐š˜๐š—๐š˜๐šœ๐š™๐šŠ๐šŒ๐šŽ (monospace)
//! * ๐••๐• ๐•ฆ๐•“๐•๐•–-๐•ค๐•ฅ๐•ฃ๐•ฆ๐•”๐•œ (double-struck)
//!
//! ### References
//!
//! * https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
//!
//! [1]: https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols

mod variants;
pub use variants::*;

macro_rules! to_math_variant {
    ($to_math_variant:ident, $math_variant:expr) => {
        fn $to_math_variant(&self) -> String {
            self.chars()
                .map(|ch|
                     if let Some(variant) = $math_variant(ch) { variant }
                     else { ch })
                .collect()
        }
    }
}

/// Convenience trait that allows you to call the the transformation
/// straight on a string slice. If a variant doesn't exist for a given
/// character, it is left as is.
///
/// ### Examples
///
/// ```rust
/// use math_text_transform::MathTextTransform;
///
/// assert_eq!("Italฤฑc f(ฯ€)".to_math_italic(), "๐ผ๐‘ก๐‘Ž๐‘™๐šค๐‘ ๐‘“(๐œ‹)");
/// assert_eq!("Double-struck 123".to_math_double_struck(), "๐”ป๐• ๐•ฆ๐•“๐•๐•–-๐•ค๐•ฅ๐•ฃ๐•ฆ๐•”๐•œ ๐Ÿ™๐Ÿš๐Ÿ›");
/// ```
pub trait MathTextTransform<T> {
    /// Transform to ๐›๐จ๐ฅ๐ variant.
    fn to_math_bold(&self) -> T;

    /// Transform to ๐‘–๐‘ก๐‘Ž๐‘™๐‘–๐‘ variant.
    fn to_math_italic(&self) -> T;

    /// Transform to ๐’ƒ๐’๐’๐’… ๐’Š๐’•๐’‚๐’๐’Š๐’„ variant.
    fn to_math_bold_italic(&self) -> T;

    /// Transform to ๐—Œ๐–บ๐—‡๐—Œ-๐—Œ๐–พ๐—‹๐—‚๐–ฟ variant.
    fn to_math_sans_serif(&self) -> T;

    /// Transform to ๐˜€๐—ฎ๐—ป๐˜€-๐˜€๐—ฒ๐—ฟ๐—ถ๐—ณ ๐—ฏ๐—ผ๐—น๐—ฑ variant.
    fn to_math_sans_serif_bold(&self) -> T;

    /// Transform to ๐˜ด๐˜ข๐˜ฏ๐˜ด-๐˜ด๐˜ฆ๐˜ณ๐˜ช๐˜ง ๐˜ช๐˜ต๐˜ข๐˜ญ๐˜ช๐˜ค variant.
    fn to_math_sans_serif_italic(&self) -> T;

    /// Transform to ๐™จ๐™–๐™ฃ๐™จ-๐™จ๐™š๐™ง๐™ž๐™› ๐™—๐™ค๐™ก๐™™ ๐™ž๐™ฉ๐™–๐™ก๐™ž๐™˜ variant.
    fn to_math_sans_serif_bold_italic(&self) -> T;

    /// Transform to ๐“ˆ๐’ธ๐“‡๐’พ๐“…๐“‰ variant.
    fn to_math_script(&self) -> T;

    /// Transform to ๐“ซ๐“ธ๐“ต๐“ญ ๐“ผ๐“ฌ๐“ป๐“ฒ๐“น๐“ฝ variant.
    fn to_math_bold_script(&self) -> T;

    /// Transform to ๐”ฃ๐”ฏ๐”ž๐”จ๐”ฑ๐”ฒ๐”ฏ variant.
    fn to_math_fraktur(&self) -> T;

    /// Transform to ๐–‡๐–”๐–‘๐–‰ ๐–‹๐–—๐–†๐–๐–™๐–š๐–— variant.
    fn to_math_bold_fraktur(&self) -> T;

    /// Transform to ๐š–๐š˜๐š—๐š˜๐šœ๐š™๐šŠ๐šŒ๐šŽ variant.
    fn to_math_monospace(&self) -> T;

    /// Transform to ๐••๐• ๐•ฆ๐•“๐•๐•–-๐•ค๐•ฅ๐•ฃ๐•ฆ๐•”๐•œ variant.
    fn to_math_double_struck(&self) -> T;
}

impl MathTextTransform<String> for str {
    to_math_variant!(to_math_bold, math_bold);
    to_math_variant!(to_math_italic, math_italic);
    to_math_variant!(to_math_bold_italic, math_bold_italic);
    to_math_variant!(to_math_sans_serif, math_sans_serif);
    to_math_variant!(to_math_sans_serif_bold, math_sans_serif_bold);
    to_math_variant!(to_math_sans_serif_italic, math_sans_serif_italic);
    to_math_variant!(to_math_sans_serif_bold_italic, math_sans_serif_bold_italic);
    to_math_variant!(to_math_script, math_script);
    to_math_variant!(to_math_bold_script, math_bold_script);
    to_math_variant!(to_math_fraktur, math_fraktur);
    to_math_variant!(to_math_bold_fraktur, math_bold_fraktur);
    to_math_variant!(to_math_monospace, math_monospace);
    to_math_variant!(to_math_double_struck, math_double_struck);
}


#[cfg(test)]
mod tests {
    use super::MathTextTransform;

    #[test]
    fn to_math_bold() {
        assert_eq!("Bold 123".to_math_bold(), "๐๐จ๐ฅ๐ ๐Ÿ๐Ÿ๐Ÿ‘");
        assert_eq!("ฮ’ฮฟฮปฮด".to_math_bold(), "๐šฉ๐›๐›Œ๐›…");
    }

    #[test]
    fn to_math_italic() {
        assert_eq!("Italฤฑc 123".to_math_italic(), "๐ผ๐‘ก๐‘Ž๐‘™๐šค๐‘ 123");
        assert_eq!("ฮ™ฯ„ฮฑฮปฮนฮบ".to_math_italic(), "๐›ช๐œ๐›ผ๐œ†๐œ„๐œ…");
    }

    #[test]
    fn to_math_bold_italic() {
        assert_eq!("Bold-Italic 123".to_math_bold_italic(), "๐‘ฉ๐’๐’๐’…-๐‘ฐ๐’•๐’‚๐’๐’Š๐’„ 123");
        assert_eq!("ฮ’ฮฟฮปฮด-ฮ™ฯ„ฮฑฮปฮนฮบ".to_math_bold_italic(), "๐œ๐„๐€๐œน-๐œค๐‰๐œถ๐€๐œพ๐œฟ");
    }

    #[test]
    fn to_math_sans_serif() {
        assert_eq!("Sans-Serif 123".to_math_sans_serif(), "๐–ฒ๐–บ๐—‡๐—Œ-๐–ฒ๐–พ๐—‹๐—‚๐–ฟ ๐Ÿ๐Ÿ๐Ÿ‘");
    }

    #[test]
    fn to_math_sans_serif_bold() {
        assert_eq!("Sans-Serif-Bold 123".to_math_sans_serif_bold(), "๐—ฆ๐—ฎ๐—ป๐˜€-๐—ฆ๐—ฒ๐—ฟ๐—ถ๐—ณ-๐—•๐—ผ๐—น๐—ฑ ๐Ÿญ๐Ÿฎ๐Ÿฏ");
        assert_eq!("ฮฃฮฑฮฝฯƒ-ฮฃฮตฯฮนฯ†-ฮ’ฮฟฮปฮด".to_math_sans_serif_bold(), "๐จ๐ฐ๐ผ๐ž‚-๐จ๐ด๐ž€๐ธ๐ž…-๐—๐พ๐บ๐ณ");
    }

    #[test]
    fn to_math_sans_serif_italic() {
        assert_eq!("Sans-Serif-Italic 123".to_math_sans_serif_italic(), "๐˜š๐˜ข๐˜ฏ๐˜ด-๐˜š๐˜ฆ๐˜ณ๐˜ช๐˜ง-๐˜๐˜ต๐˜ข๐˜ญ๐˜ช๐˜ค 123");
    }

    #[test]
    fn to_math_sans_serif_bold_italic() {
        assert_eq!("Sans-Serif-Bold-Italic 123".to_math_sans_serif_bold_italic(), "๐™Ž๐™–๐™ฃ๐™จ-๐™Ž๐™š๐™ง๐™ž๐™›-๐˜ฝ๐™ค๐™ก๐™™-๐™„๐™ฉ๐™–๐™ก๐™ž๐™˜ 123");
        assert_eq!("ฮฃฮฑฮฝฯƒ-ฮฃฮตฯฮนฯ†-ฮ’ฮฟฮปฮด-ฮ™ฯ„ฮฑฮปฮนฮบ".to_math_sans_serif_bold_italic(), "๐žข๐žช๐žถ๐žผ-๐žข๐žฎ๐žบ๐žฒ๐žฟ-๐ž‘๐žธ๐žด๐žญ-๐ž˜๐žฝ๐žช๐žด๐žฒ๐žณ");
    }

    #[test]
    fn to_math_script() {
        assert_eq!("Script 123".to_math_script(), "๐’ฎ๐’ธ๐“‡๐’พ๐“…๐“‰ 123");
    }

    #[test]
    fn to_math_bold_script() {
        assert_eq!("Bold-Script 123".to_math_bold_script(), "๐“‘๐“ธ๐“ต๐“ญ-๐“ข๐“ฌ๐“ป๐“ฒ๐“น๐“ฝ 123");
    }

    #[test]
    fn to_math_fraktur() {
        assert_eq!("Fraktur 123".to_math_fraktur(), "๐”‰๐”ฏ๐”ž๐”จ๐”ฑ๐”ฒ๐”ฏ 123");
    }

    #[test]
    fn to_math_bold_fraktur() {
        assert_eq!("Bold-Fraktur 123".to_math_bold_fraktur(), "๐•ญ๐–”๐–‘๐–‰-๐•ฑ๐–—๐–†๐–๐–™๐–š๐–— 123");
    }

    #[test]
    fn to_math_monospace() {
        assert_eq!("Monospace 123".to_math_monospace(), "๐™ผ๐š˜๐š—๐š˜๐šœ๐š™๐šŠ๐šŒ๐šŽ ๐Ÿท๐Ÿธ๐Ÿน");
    }

    #[test]
    fn to_math_double_struck() {
        assert_eq!("Double-Struck 123".to_math_double_struck(), "๐”ป๐• ๐•ฆ๐•“๐•๐•–-๐•Š๐•ฅ๐•ฃ๐•ฆ๐•”๐•œ ๐Ÿ™๐Ÿš๐Ÿ›");
    }
}