Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add support for more accents in mathtext #23189

New issue

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

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

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 39 additions & 15 deletions lib/matplotlib/_mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def _get_info(self, fontname, font_class, sym, fontsize, dpi):
if bunch is not None:
return bunch

font, num, slanted = self._get_glyph(
font, num, slanted, substituted_glyph = self._get_glyph(
fontname, font_class, sym, fontsize)

font.set_size(fontsize, dpi)
Expand All @@ -239,7 +239,8 @@ def _get_info(self, fontname, font_class, sym, fontsize, dpi):
ymax = ymax+offset,
# iceberg is the equivalent of TeX's "height"
iceberg = glyph.horiBearingY/64.0 + offset,
slanted = slanted
slanted = slanted,
substituted_glyph = substituted_glyph
)

result = self.glyphd[key] = types.SimpleNamespace(
Expand Down Expand Up @@ -323,7 +324,7 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):
if font is not None:
num = ord(sym)
if font is not None and font.get_char_index(num) != 0:
return font, num, slanted
return font, num, slanted, False
else:
return self._stix_fallback._get_glyph(
fontname, font_class, sym, fontsize)
Expand Down Expand Up @@ -448,6 +449,8 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):
found_symbol = False
_log.warning("No TeX to Unicode mapping for {!a}.".format(sym))

substituted_glyph = False

fontname, uniindex = self._map_virtual_font(
fontname, font_class, uniindex)

Expand Down Expand Up @@ -499,8 +502,9 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):
font = self._get_font('rm')
uniindex = 0xA4 # currency char, for lack of anything better
slanted = False
substituted_glyph = True

return font, uniindex, slanted
return font, uniindex, slanted, substituted_glyph

def get_sized_alternatives_for_symbol(self, fontname, sym):
if self._fallback_font:
Expand Down Expand Up @@ -935,6 +939,9 @@ def _update_metrics(self):
def is_slanted(self):
return self._metrics.slanted

def is_substituted(self):
return self._metrics.substituted_glyph

def get_kerning(self, next):
"""
Return the amount of kerning between this and the given character.
Expand Down Expand Up @@ -2011,7 +2018,7 @@ def unknown_symbol(self, s, loc, toks):
raise ParseFatalException(s, loc, f"Unknown symbol: {toks['name']}")

_accent_map = {
r'hat': r'\circumflexaccent',
r'hat': r'\combiningcircumflexaccent',
r'breve': r'\combiningbreve',
r'bar': r'\combiningoverline',
r'grave': r'\combininggraveaccent',
Expand All @@ -2027,10 +2034,13 @@ def unknown_symbol(self, s, loc, toks):
r"'": r'\combiningacuteaccent',
r'~': r'\combiningtilde',
r'.': r'\combiningdotabove',
r'^': r'\circumflexaccent',
r'overrightarrow': r'\rightarrow',
r'overleftarrow': r'\leftarrow',
r'mathring': r'\circ',
r'^': r'\combiningcircumflexaccent',
r'overrightarrow': r'\combiningrightarrowabove',
r'overleftarrow': r'\combiningleftarrowabove',
r'mathring': r'\combiningringabove',
r'=': r'\combiningmacron',
r'H': r'\combiningdoubleacuteaccent',
r'check': r'\combiningcaron',
}

_wide_accents = set(r"widehat widetilde widebar".split())
Expand All @@ -2050,10 +2060,27 @@ def accent(self, s, loc, toks):
accent_box = AutoWidthChar(
'\\' + accent, sym.width, state, char_class=Accent)
else:
# Check if accent and character can be combined
Copy link
Member Author

Choose a reason for hiding this comment

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

One can possibly consider splitting the accents into those that may have precomposed characters and those that may not.
https://en.wikipedia.org/wiki/List_of_precomposed_Latin_characters_in_Unicode

Possibly one should check that the character is one of the standard latin characters as well, although that may lead to that those precomposed with two accents may not work (which should be checked if they even do to start with...).

a = get_unicode_index(self._accent_map[accent])
if isinstance(sym, Char):
c = sym.c
else:
c = sym.children[0].c
if c == chr(305): # Dotless i, but normal i combines
c = 'i'
comb = unicodedata.normalize('NFC', c + chr(a))
if len(comb) == 1: # Check that they did combine
newsym = Char(comb, state)
# Check that glyph exists
if not newsym.is_substituted():
return newsym
if c == 'i': # Turn i into dotless i
sym = Char(chr(305), state)
if sym.is_substituted():
# Dotless i does not exist
sym = Char('i', state)
# Cannot be combined
accent_box = Accent(self._accent_map[accent], state)
if accent == 'mathring':
accent_box.shrink()
accent_box.shrink()
centered = HCentered([Hbox(sym.width / 4.0), accent_box])
centered.hpack(sym.width, 'exactly')
return Vlist([
Expand Down Expand Up @@ -2137,9 +2164,6 @@ def is_slanted(self, nucleus):
return nucleus.is_slanted()
return False

def is_between_brackets(self, s, loc):
return False

def subsuper(self, s, loc, toks):
nucleus = toks.get("nucleus", Hbox(0))
subsuper = toks.get("subsuper", [])
Expand Down
11 changes: 11 additions & 0 deletions lib/matplotlib/_mathtext_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,18 @@
'\\Upsilon' : ('cmr10', 0xa8),
'\\Xi' : ('cmr10', 0xa5),
'\\circumflexaccent' : ('cmr10', 0x5e),
'\\combiningcircumflexaccent' : ('cmr10', 0x5e),
'\\combiningacuteaccent' : ('cmr10', 0xb6),
'\\combiningbreve' : ('cmr10', 0xb8),
'\\combiningdiaeresis' : ('cmr10', 0xc4),
'\\combiningdotabove' : ('cmr10', 0x5f),
'\\combininggraveaccent' : ('cmr10', 0xb5),
'\\combiningoverline' : ('cmr10', 0xb9),
'\\combiningmacron' : ('cmr10', 0x16),
'\\combiningringabove' : ('cmr10', 0x15),
'\\combiningcaron' : ('cmr10', 0x14),
'\\combiningtilde' : ('cmr10', 0x7e),
'\\combiningdoubleacuteaccent' : ('cmr10', 0x7d),
'\\leftbracket' : ('cmr10', 0x5b),
'\\leftparen' : ('cmr10', 0x28),
'\\rightbracket' : ('cmr10', 0x5d),
Expand Down Expand Up @@ -994,14 +999,20 @@
'circumflexaccent' : 770,
'combiningbreve' : 774,
'combiningoverline' : 772,
'combiningmacron' : 773,
'combininggraveaccent' : 768,
'combiningacuteaccent' : 769,
'combiningdiaeresis' : 776,
'combiningtilde' : 771,
'combiningrightarrowabove' : 8407,
'combiningleftarrowabove' : 8406,
'combiningdotabove' : 775,
'combiningringabove' : 778,
'combiningthreedotsabove' : 8411,
'combiningfourdotsabove' : 8412,
'combiningdoubleacuteaccent' : 779,
'combiningcaron' : 780,
'combiningcircumflexaccent' : 770,
'to' : 8594,
'succeq' : 8829,
'emptyset' : 8709,
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading