What it does
- Turns every page of your deck into a slide in a clean HTML player.
- Plays the narration you provide, one audio file per slide, and can require learners to hear it before moving on.
- Puts multiple-choice questions over the slides you choose, scores them, and reports passed or failed to your LMS.
- Saves progress, so a learner who closes the window resumes where they left off.
- Checks your settings against the deck before it builds anything, so a typo shows up at your desk, not in front of a learner.
The demo course was built by the converter from an eight-page PDF. It has two questions, so you can see how scoring works. Opened outside an LMS, it runs in preview mode and records nothing.
What it doesn't do
It doesn't write your slides or your narration. We draft course content and generate voiceover with AI tools, then review both and hand the results to the converter. Use whatever tools you like for that part. The converter packages what you give it.
It makes SCORM 1.2 packages, the format nearly every LMS accepts. It doesn't make SCORM 2004 or xAPI. Slides are images, so their text isn't readable by screen readers; if you need that, narrate the slides or provide a transcript.
Get started
You need Python 3.8 or later and Poppler, which provides the pdftoppm program. On a Mac that's brew install poppler; on Ubuntu or Debian, sudo apt install poppler-utils. LibreOffice is needed only if you hand the converter a .pptx instead of a PDF.
Download the converter, unzip it, and build the example course:
cd pptx-to-scorm
python pptx_to_scorm.py example
That produces example_scorm.zip, ready to upload. To make your own course:
- Export your deck to PDF and check every page. What you see is what learners see.
- Put the PDF in a folder, with an
audiofolder for narration if you have it. - Add a
course.jsonwith your title, passing score and questions. - Run
python pptx_to_scorm.py my_courseand upload the zip to your LMS.
Describe the course in course.json
Every field is optional. Slide numbers are page numbers in your PDF, and correct counts from zero, so 0 is the first choice.
{
"title": "Shop Safety Briefing",
"passing_score": 80,
"require_audio_completion": false,
"slides": {
"1": { "audio": "audio/slide_01.mp3" },
"4": {
"audio": "audio/slide_04.mp3",
"quiz": {
"question": "Where are the eye-wash stations?",
"choices": ["By the exits", "At every bench", "In the break room"],
"correct": 0,
"explanation": "Both eye-wash stations are next to the exits."
}
}
}
}
The README in the download covers every field, including identifier, which keeps re-uploads tied to the same course, and accent_color, which sets the player's color to match your brand.
What your LMS receives
| SCORM field | Value |
|---|---|
| Lesson status | incomplete on first launch, then passed or failed |
| Score | percent of questions answered correctly |
| Location and suspend data | current slide and answers so far, for resuming |
| Session time | time spent in each sitting |
| Mastery score | your passing score, written into the manifest |
Tested against a simulated SCORM 1.2 LMS for launch, quiz scoring, resume, retry and exit. Preview each course in your own LMS before you assign it.
License
MIT. Use it, change it and share it, including at work and in products you sell. The copyright notice stays with the code. You can also download the script on its own.
I wrote about why we built this instead of buying in Four tools we built instead of buying. If you're weighing build versus buy on a tool of your own, or this converter needs to do something it doesn't, email me.