Skip to content
Open
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
2 changes: 2 additions & 0 deletions docs/user/text.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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::
Expand Down
2 changes: 2 additions & 0 deletions pptx/oxml/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
ST_TextSpacingPoint,
ST_TextTypeface,
ST_TextWrappingType,
BaseIntType,
XsdBoolean,
)
from pptx.oxml.xmlchemy import (
Expand Down Expand Up @@ -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):
Expand Down
26 changes: 26 additions & 0 deletions pptx/text/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down
60 changes: 60 additions & 0 deletions tests/text/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down