Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add math styling module #20

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

Conversation

mkorje
Copy link
Collaborator

@mkorje mkorje commented Dec 16, 2024

This PR adds functions and the related infrastructure needed to take a character/string and a style in math (e.g. blackboard-bold, monospace), and return it in styled form. It is implemented under the feature styling, which I've added as a default.

Moving this to Codex was brought up briefly on Discord, and whilst it doesn't directly fall under "naming Unicode symbols", I think it still fits quite nicely in this crate. I may have jumped the gun a little on this, but it wasn't much work to do. Hopefully this PR starts some more thorough discussion of this idea. I also think that moving this outside of the main typst repo will be an improvement and make it more maintainable.

@mkorje mkorje added the meta Discussion about the structure of this repo label Dec 16, 2024
@MDLC01
Copy link
Collaborator

MDLC01 commented Dec 16, 2024

A bit more context: #5 (comment).

Comment on lines +201 to +247
'A'..='Z' => 0x1D3BF,
'a'..='z' => 0x1D3B9,
'Α'..='Ρ' => 0x1D317,
'ϴ' => 0x1D2C5,
'Σ'..='Ω' => 0x1D317,
'∇' => 0x1B4BA,
'α'..='ω' => 0x1D311,
'∂' => 0x1B4D9,
'ϵ' => 0x1D2E7,
'ϑ' => 0x1D30C,
'ϰ' => 0x1D2EE,
'ϕ' => 0x1D30A,
'ϱ' => 0x1D2EF,
'ϖ' => 0x1D30B,
'Ϝ' | 'ϝ' => 0x1D3EE,
'0'..='9' => 0x1D79E,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to somehow use characters (e.g., '𝐀') instead of codepoints on the right hand sides here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment the right hand side is just a delta to add to the original codepoint. I can't quite remember why exactly I did it this way instead of just mapping directly to the new codepoint, in which case we could use characters instead.

Copy link
Collaborator

@T0mstone T0mstone Feb 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The delta allows the pattern to be 'A'..='Z' instead of 26 individual ones.

Tho I guess it could be inlined to something like

'A'..='Z' => std::char::from_u32((c as u32) - ('A' as u32) + ('𝐀' as u32))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh of course, for some reason I thought 'A'..='Z' => '𝐀'..='𝐙' would work 😅.

@MDLC01
Copy link
Collaborator

MDLC01 commented Feb 12, 2025

Regarding the implementation, as well as having many to_{style} functions, there could also be a MathStyle::apply method to apply a style to a char.

@MDLC01
Copy link
Collaborator

MDLC01 commented Feb 12, 2025

Regardless of my above comments, @laurmaedje will have to approve moving those functions before we merge this PR.

@mkorje
Copy link
Collaborator Author

mkorje commented Feb 22, 2025

Regarding the implementation, as well as having many to_{style} functions, there could also be a MathStyle::apply method to apply a style to a char.

The issue I had with something like this is that some of the styles will output multiple characters.

I also considered implementing the MathStyling trait for EcoString, as EcoString is used in the Typst repo. Though I wasn't sure about adding that as a dependency; maybe instead it could be under a feature flag?

@MDLC01
Copy link
Collaborator

MDLC01 commented Feb 22, 2025

Regarding the implementation, as well as having many to_{style} functions, there could also be a MathStyle::apply method to apply a style to a char.

The issue I had with something like this is that some of the styles will output multiple characters.

Can you not return [char; 2] like the to_style function? Essentially, making to_style a method on MathStyle.

I also considered implementing the MathStyling trait for EcoString, as EcoString is used in the Typst repo. Though I wasn't sure about adding that as a dependency; maybe instead it could be under a feature flag?

Instead, maybe to_styled could be made generic over its return type T: Default + AddAssign<&str>. Or maybe I'm just overthinking, and we can just add the dependency behind a feature flag.

@MDLC01
Copy link
Collaborator

MDLC01 commented Feb 22, 2025

Also, you can implement MathStyling for str instead, that way anything that derefs to str (such as String or EcoString) can benefit from to_styled.

@laurmaedje
Copy link
Member

Looks like there's quite a bit more going on here than in typst-layout/src/math/text.rs, e.g. the looped and chancery stuff. Would that somehow be exposed in Typst or is it for completeness?

@laurmaedje
Copy link
Member

Regarding EcoString: I wouldn't add a dependency on it here. Doesn't seem worth it to me.

src/styling.rs Outdated
/// assert_eq!(['ⅈ', '\0'], to_style('i', MathStyle::DoubleStruckItalic));
/// assert_eq!(['𝓴', '\u{fe01}'], to_style('k', MathStyle::RoundhandBold));
/// ```
pub fn to_style(c: char, style: MathStyle) -> [char; 2] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The [char: 2] approach where \0 has special meaning seems a bit easy to misuse to me. Maybe it could return a custom iterator type instead? Then to string impl would be trivial to do yourself (s.chars().flat_map(|c| to_style(c, style)).collect(). I would probably even remove the trait then.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree an iterator is much nicer. I've basically mimicked to_uppercase and ToUppercase from std. I also got rid of the trait.

@mkorje
Copy link
Collaborator Author

mkorje commented Feb 23, 2025

Looks like there's quite a bit more going on here than in typst-layout/src/math/text.rs, e.g. the looped and chancery stuff. Would that somehow be exposed in Typst or is it for completeness?

Yes, I plan to expose these in Typst as well. At this point in time it is just for completeness though.

For the Arabic ones I plan to add to Variants the functions inital, tailed, looped, and stretched, as well as isolated as an alias for serif. Though I should note I have no idea if these should even really have their names in English, or if shortened names like tail or loop would work. I'll try to figure this all out later.

As for the chancery/roundhand stuff, we'd add scr to join cal in Typst. But there is still some work to do before it can be added (see typst/typst#5853).

@mkorje mkorje force-pushed the math-alphabet-mappings branch from 224e505 to 9bc35ae Compare February 27, 2025 05:41
@mkorje
Copy link
Collaborator Author

mkorje commented Feb 27, 2025

I've changed the to_style function to return a custom iterator type and have removed the MathStyling trait for now (see #20 (comment))

Instead, maybe to_styled could be made generic over its return type T: Default + AddAssign<&str>. Or maybe I'm just overthinking, and we can just add the dependency behind a feature flag.

Also, you can implement MathStyling for str instead, that way anything that derefs to str (such as String or EcoString) can benefit from to_styled.

Since I've removed the trait for now, this no longer applies.

Regarding the implementation, as well as having many to_{style} functions, there could also be a MathStyle::apply method to apply a style to a char.

I think in my previous reply to this I misunderstood what you were saying, sorry. I've done that now.

Also, I was wondering whether to make the to_style function a method on char instead?

I also need to double check Arabic, as for the normal style the math symbols have separate codepoints (unlike latin where the upright serif for math is the same as the standard codepoints), I think.

@MDLC01
Copy link
Collaborator

MDLC01 commented Feb 28, 2025

Maybe I did not understand the purpose of ToStyle, but shouldn't all public functions return it instead of [char; 2]?

@laurmaedje
Copy link
Member

I agree that we shouldn't have [char; 2] in the public API. I don't think we need a public MathStyle::apply. I think we can inline its implementation into to_style.

@mkorje
Copy link
Collaborator Author

mkorje commented Mar 1, 2025

When you say not having [char; 2] in the public API, does that include the functions in mappings?

@laurmaedje
Copy link
Member

I hadn't seen that those are public. Feels slightly duplicate to me with the enum. It's nice to have have in the type that they return just one char. I guess it depends a bit on how you plan to use them in Typst.

But, even if we keep separate functions, I think it would make more sense for the ones that can return multiple chars to return ToStyle and the other ones just a single char.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
meta Discussion about the structure of this repo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants