diff --git a/docs/user/text.rst b/docs/user/text.rst index 1f59c8fa3..7d9bb2ca3 100644 --- a/docs/user/text.rst +++ b/docs/user/text.rst @@ -168,6 +168,8 @@ the theme color Accent 1. font.bold = True font.italic = None # cause value to be inherited from theme font.color.theme_color = MSO_THEME_COLOR.ACCENT_1 + font.superscript = True # sets superscript (baseline 30000) + font.subscript = True # sets subscript (baseline -25000), removes superscript (only 1 allowed at a time) If you prefer, you can set the font color to an absolute RGB value. Note that this will not change color when the theme is changed:: diff --git a/pptx/oxml/text.py b/pptx/oxml/text.py index cf99dd0da..1e416bde0 100644 --- a/pptx/oxml/text.py +++ b/pptx/oxml/text.py @@ -27,6 +27,7 @@ ST_TextSpacingPoint, ST_TextTypeface, ST_TextWrappingType, + BaseIntType, XsdBoolean, ) from pptx.oxml.xmlchemy import ( @@ -305,6 +306,7 @@ class CT_TextCharacterProperties(BaseOxmlElement): sz = OptionalAttribute("sz", ST_TextFontSize) b = OptionalAttribute("b", XsdBoolean) i = OptionalAttribute("i", XsdBoolean) + baseline = OptionalAttribute("baseline", BaseIntType) u = OptionalAttribute("u", MSO_TEXT_UNDERLINE_TYPE) def _new_gradFill(self): diff --git a/pptx/text/text.py b/pptx/text/text.py index b880cf4ec..5640015b6 100644 --- a/pptx/text/text.py +++ b/pptx/text/text.py @@ -339,6 +339,32 @@ def italic(self): def italic(self, value): self._rPr.i = value + @property + def superscript(self): + # baseline of 30000 means superscript + if self._rPr.baseline == 30000: + return True + return False + + @superscript.setter + def superscript(self, value): + self._rPr.baseline = 0 + if value: + self._rPr.baseline = 30000 + + @property + def subscript(self): + # baseline of -25000 means subscript + if self._rPr.baseline == -25000: + return True + return False + + @subscript.setter + def subscript(self, value): + self._rPr.baseline = 0 + if value: + self._rPr.baseline = -25000 + @property def language_id(self): """ diff --git a/tests/text/test_text.py b/tests/text/test_text.py index 8e0f0f5b3..67c394ceb 100644 --- a/tests/text/test_text.py +++ b/tests/text/test_text.py @@ -499,6 +499,24 @@ def it_can_change_its_italic_setting(self, italic_set_fixture): font.italic = new_value assert font._element.xml == expected_xml + def it_knows_its_superscript_setting(self, superscript_get_fixture): + font, expected_value = superscript_get_fixture + assert font.superscript == expected_value + + def it_can_change_its_superscript_setting(self, superscript_set_fixture): + font, new_value, expected_xml = superscript_set_fixture + font.superscript = new_value + assert font._element.xml == expected_xml + + def it_knows_its_subscript_setting(self, subscript_get_fixture): + font, expected_value = subscript_get_fixture + assert font.subscript == expected_value + + def it_can_change_its_subscript_setting(self, subscript_set_fixture): + font, new_value, expected_xml = subscript_set_fixture + font.subscript = new_value + assert font._element.xml == expected_xml + def it_knows_its_language_id(self, language_id_get_fixture): font, expected_value = language_id_get_fixture assert font.language_id == expected_value @@ -585,6 +603,48 @@ def italic_set_fixture(self, request): expected_xml = xml(expected_rPr_cxml) return font, new_value, expected_xml + @pytest.fixture( + params=[("a:rPr{baseline=30000}", True), ("a:rPr{baseline=0}", False)] + ) + def superscript_get_fixture(self, request): + rPr_cxml, expected_value = request.param + font = Font(element(rPr_cxml)) + return font, expected_value + + @pytest.fixture( + params=[ + ("a:rPr", True, "a:rPr{baseline=30000}"), + ("a:rPr{baseline=30000}", False, "a:rPr{baseline=0}"), + ("a:rPr{baseline=-25000}", False, "a:rPr{baseline=0}"), + ] + ) + def superscript_set_fixture(self, request): + rPr_cxml, new_value, expected_rPr_cxml = request.param + font = Font(element(rPr_cxml)) + expected_xml = xml(expected_rPr_cxml) + return font, new_value, expected_xml + + @pytest.fixture( + params=[("a:rPr{baseline=-25000}", True), ("a:rPr{baseline=0}", False)] + ) + def subscript_get_fixture(self, request): + rPr_cxml, expected_value = request.param + font = Font(element(rPr_cxml)) + return font, expected_value + + @pytest.fixture( + params=[ + ("a:rPr", True, "a:rPr{baseline=-25000}"), + ("a:rPr{baseline=30000}", False, "a:rPr{baseline=0}"), + ("a:rPr{baseline=-25000}", False, "a:rPr{baseline=0}"), + ] + ) + def subscript_set_fixture(self, request): + rPr_cxml, new_value, expected_rPr_cxml = request.param + font = Font(element(rPr_cxml)) + expected_xml = xml(expected_rPr_cxml) + return font, new_value, expected_xml + @pytest.fixture( params=[ ("a:rPr", MSO_LANGUAGE_ID.NONE),