change the font size of headings to 40 and the below information to 26 in all slides

Reading File
Reading File
Browsing Directory

~/

Reading File
Browsing Directory

~/attachments/fe357a1c-5b51-4c08-918f-5a6e21862651

Running Command

mkdir -p "/tmp/workspace/pancreatic-cancer-font-update/output" && python -c "from pptx import Presentation; p=Presentation('/tmp/workspace/attachments/fe357a1c-5b51-4c08-918f-5a6e21862651/pancreatic cancer.pptx'); print('slides',len(p.slides));\nfor i,s in enumerate(p.slides,1):\n print('SLIDE',i);\n for j,sh in enumerate(s.shapes,1):\n if getattr(sh,'has_text_frame',False) and sh.text_frame.text.strip():\n print(j,repr(sh.name),repr(sh.text_frame.text[:100]),'pos',round(sh.top/914400,2),'size',round(sh.height/914400,2))"

Running Command

python -c "from pptx import Presentation; p=Presentation('/tmp/workspace/attachments/fe357a1c-5b51-4c08-918f-5a6e21862651/pancreatic cancer.pptx'); print('slides',len(p.slides)); [print('S',i,'shape',j,repr(sh.name),repr(sh.text_frame.text[:100]),'top',round(sh.top/914400,2),'h',round(sh.height/914400,2),'placeholder',sh.is_placeholder,('type '+str(sh.placeholder_format.type) if sh.is_placeholder else '')) for i,s in enumerate(p.slides,1) for j,sh in enumerate(s.shapes,1) if getattr(sh,'has_text_frame',False) and sh.text_frame.text.strip()]"

Writing File

~/pancreatic-cancer-font-update/update_fonts.py

from copy import copy
from pathlib import Path
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pptx.util import Pt

SOURCE = Path('/tmp/workspace/attachments/fe357a1c-5b51-4c08-918f-5a6e21862651/pancreatic cancer.pptx')
OUTPUT = Path('/tmp/workspace/pancreatic-cancer-font-update/output/pancreatic cancer_font-updated.pptx')

TITLE_SIZE = Pt(40)
BODY_SIZE = Pt(26)


def iter_text_shapes(shapes):
    for shape in shapes:
        if shape.shape_type == MSO_SHAPE_TYPE.GROUP:
            yield from iter_text_shapes(shape.shapes)
        elif getattr(shape, 'has_text_frame', False) and shape.text_frame.text.strip():
            yield shape


def set_text_size(shape, size):
    for para in shape.text_frame.paragraphs:
        for run in para.runs:
            run.font.size = size
        # Paragraphs with no runs can still carry default text properties.
        para.font.size = size


def is_footer(shape):
    text = shape.text_frame.text.strip()
    return (
        'Pancreatic Cancer | Dept. of General Surgery' in text
        or text == 'Original schematic for teaching purposes'
        or text.isdigit()
    )

prs = Presentation(SOURCE)
changed = []
for slide_number, slide in enumerate(prs.slides, start=1):
    text_shapes = list(iter_text_shapes(slide.shapes))
    non_footer_shapes = [shape for shape in text_shapes if not is_footer(shape)]
    if not non_footer_shapes:
        continue

    # The uppermost main text box is the slide heading. The title slide is also
    # handled correctly: its first two institutional lines are introductory text,
    # and the actual presentation title is identified explicitly below.
    if slide_number == 1:
        title_shape = next(
            (shape for shape in non_footer_shapes if shape.text_frame.text.strip() == 'Pancreatic Cancer'),
            non_footer_shapes[0],
        )
    else:
        title_shape = min(non_footer_shapes, key=lambda shape: (shape.top, shape.left))

    set_text_size(title_shape, TITLE_SIZE)
    changed.append((slide_number, title_shape.text_frame.text.strip(), 40))

    for shape in non_footer_shapes:
        if shape is title_shape:
            continue
        set_text_size(shape, BODY_SIZE)
        changed.append((slide_number, shape.text_frame.text.strip(), 26))

OUTPUT.parent.mkdir(parents=True, exist_ok=True)
prs.save(OUTPUT)
print(f'Saved {OUTPUT}')
print(f'Updated {len(changed)} text boxes across {len(prs.slides)} slides')
Running Command

python "/tmp/workspace/pancreatic-cancer-font-update/update_fonts.py" && python -c "from pptx import Presentation; from collections import Counter; p=Presentation('/tmp/workspace/pancreatic-cancer-font-update/output/pancreatic cancer_font-updated.pptx'); c=Counter();\nfor s in p.slides:\n for sh in s.shapes:\n if getattr(sh,'has_text_frame',False) and sh.text_frame.text.strip():\n for para in sh.text_frame.paragraphs:\n for r in para.runs:\n if r.font.size: c[round(r.font.size.pt,2)]+=1\nprint('slides',len(p.slides),'font_sizes',sorted(c.items()))"

Writing File

~/pancreatic-cancer-font-update/verify_fonts.py

from pathlib import Path
from pptx import Presentation

path = Path('/tmp/workspace/pancreatic-cancer-font-update/output/pancreatic cancer_font-updated.pptx')
prs = Presentation(path)
assert len(prs.slides) == 35

# Verify all expected heading and content boxes received their intended sizes.
issues = []
checked = 0
for si, slide in enumerate(prs.slides, 1):
    for shape in slide.shapes:
        if not getattr(shape, 'has_text_frame', False) or not shape.text_frame.text.strip():
            continue
        txt = shape.text_frame.text.strip()
        if 'Pancreatic Cancer | Dept. of General Surgery' in txt or txt == 'Original schematic for teaching purposes' or txt.isdigit():
            continue
        expected = 40 if (si != 1 and shape.top == min(s.top for s in slide.shapes if getattr(s, 'has_text_frame', False) and s.text_frame.text.strip() and 'Pancreatic Cancer | Dept. of General Surgery' not in s.text_frame.text and s.text_frame.text.strip() != 'Original schematic for teaching purposes' and not s.text_frame.text.strip().isdigit())) or (si == 1 and txt == 'Pancreatic Cancer') else 26
        for para in shape.text_frame.paragraphs:
            for run in para.runs:
                if run.font.size is None or abs(run.font.size.pt - expected) > 0.01:
                    issues.append((si, txt[:30], expected, None if run.font.size is None else run.font.size.pt))
        checked += 1
print(f'Verified {checked} heading/content text boxes in {len(prs.slides)} slides.')
if issues:
    raise RuntimeError(f'Font verification failed: {issues[:10]}')
print('All expected heading boxes are 40 pt and all other main information boxes are 26 pt.')
Running Command

python "/tmp/workspace/pancreatic-cancer-font-update/verify_fonts.py" && ls -lh "/tmp/workspace/pancreatic-cancer-font-update/output/pancreatic cancer_font-updated.pptx"

Updated all 35 slides:
  • Headings: 40 pt
  • Main information/content: 26 pt
  • Footer text and slide numbers were left unchanged.
This is a shared conversation. Sign in to Orris to start your own chat.