# How @openmaic/importer Converts PPTX to OpenMAIC Slides: Complete Pipeline Explained

> Learn how @openmaic/importer converts PPTX to OpenMAIC slides. Explore the 10-stage pipeline that parses PPTX archives, extracts XML, and transforms content into OpenMAIC's native format.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: how-to-guide
- Published: 2026-09-02

---

**`@openmaic/importer` transforms PowerPoint files into structured JSON by parsing the PPTX zip archive, extracting slide XML, theme data, and media resources, then converting each element into OpenMAIC's native slide format through a 10-stage pipeline.**

The `@openmaic/importer` package is the official conversion engine for the OpenMAIC project (THU-MAIC/OpenMAIC). It reads binary `.pptx` files and outputs a JSON representation that the OpenMAIC renderer can display natively. This article breaks down the complete conversion pipeline implemented in `packages/@openmaic/importer/src1/pptxtojson.js`.

## Stage 1: Loading and Parsing the PPTX Archive

The entry point `parse` accepts an `ArrayBuffer` and initializes **JSZip** to read the zip-packed PPTX structure.

```javascript
import { parse } from '@openmaic/importer'

async function convertPptx(file) {
  const arrayBuffer = await file.arrayBuffer()
  const result = await parse(arrayBuffer, { mediaMode: 'base64' })
  return result
}

```

In [[`pptxtojson.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/pptxtojson.js) lines 33-38](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/importer/src1/pptxtojson.js#L33-L38), the `parse` function creates the zip instance and begins the extraction process.

## Stage 2: Discovering Slide Files via Content Types

The `getContentTypes` helper parses `_rels/[Content_Types].xml` to locate all slide XML paths (`slides/slide*.xml`), layout files, and other document parts. This establishes the manifest of content to process.

## Stage 3: Extracting Global Slide Information

`getSlideInfo` reads [`ppt/presentation.xml`](https://github.com/THU-MAIC/OpenMAIC/blob/main/ppt/presentation.xml) to obtain:

- **Slide dimensions** — converted from EMUs (English Metric Units) to points
- **Default text style** — applied when no explicit formatting exists

## Stage 4: Loading the Theme

`getTheme` follows relationships in `presentation.xml.rels` to find the theme file, then builds an array of **accent colors** used throughout the presentation.

## Stage 5: Processing Each Individual Slide

For every slide file, `processSingleSlide` orchestrates resource resolution:

1. Reads the slide's `.rels` file to map images, charts, diagrams, notes, and master/layout references
2. Retrieves the corresponding **layout**, **master**, and **theme** resources
3. Builds a **warp object** containing all required data: `zip`, `slideResObj`, `layoutResObj`, `masterResObj`, `themeContent`, and more

## Stage 6: Background and Layout Elements

Two specialized functions prepare the slide canvas:

- **`getSlideBackgroundFill`** — creates the slide's background fill
- **`getLayoutElements`** — extracts non-placeholder shapes from layout and master that become part of the slide background

## Stage 7: Walking the Slide XML Tree

The slide's `spTree` node contains all visible objects. `processNodesInSlide` dispatches each node type to its specific handler:

| Node Type | Handler Function |
|-----------|----------------|
| `p:sp` (shape) | `processSpNode` |
| `p:cxnSp` (connector) | `processSpNode` |
| `p:pic` (picture) | `processPicNode` |
| `p:graphicFrame` (chart/table/diagram) | `processGraphicFrameNode` |
| `p:grpSp` (group) | `processNodesInSlide` (recursive) |

## Stage 8: Shape and Text Processing

`processSpNode` resolves **placeholder inheritance** (layout → master) and delegates to `genShape`. This function:

- Computes **geometry**: position, size, rotation, flips
- Extracts **fill/border** via [`fill.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/fill.js)
- Applies **shadow** effects via [`shadow.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/shadow.js)
- Processes **text content** via [`text.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/text.js)

The result is either a `shape` or `text` element in the OpenMAIC JSON schema.

## Stage 9: Media Extraction (Images, Video, Audio)

`processPicNode` handles embedded media:

```javascript
// Simplified flow from processPicNode
const mediaBuffer = await zip.file(mediaPath).async('arraybuffer')
const mimeType = getMimeType(mediaExtension)  // from utils.js
const dataUrl = buildDataUrl(mediaBuffer, mimeType, mediaMode)
// Returns: { type: 'image' | 'video' | 'audio', ... }

```

The `mediaMode` option controls whether media is embedded as **base64 data URLs** or **blob URLs**.

## Stage 10: Charts, Tables, Diagrams, and Math

`processGraphicFrameNode` inspects the `graphicData` URI and delegates to specialized parsers:

- **`genChart`** — parses chart XML, extracts series data, colors, and chart type
- **`genTable`** — converts tables to 2D JSON with cell spans, borders, and styling
- **`genDiagram`** — handles SmartArt diagrams with shape elements and fallback text
- **`processMathNode`** — parses OMML MathML, outputs LaTeX plus optional preview images

## Notes, Transitions, and Final Assembly

Per-slide metadata is extracted via:

- **`getNote`** — fetches speaker notes
- **`findTransitionNode`** and **`parseTransition`** — locate and interpret slide transition data

`processSingleSlide` returns a complete slide object:

```javascript
{
  fill,           // background fill
  elements,       // processed shapes, text, media
  layoutElements, // master/layout background elements
  note,           // speaker notes
  transition      // transition effect
}

```

The top-level `parse` function aggregates all slides and attaches **theme colors** and **presentation size**.

## Node.js Usage Example

```javascript
import fs from 'fs'
import { parse } from '@openmaic/importer'

async function run() {
  const buffer = fs.readFileSync('example.pptx')
  const { slides, themeColors, size } = await parse(buffer, { mediaMode: 'blob' })
  
  console.log(JSON.stringify({ slides, themeColors, size }, null, 2))
}
run()

```

## Key Source Files in the Pipeline

| File | Responsibility |
|------|--------------|
| [`src1/pptxtojson.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/pptxtojson.js) | Core orchestration pipeline |
| [`src1/readXmlFile.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/readXmlFile.js) | XML extraction via `fast-xml-parser` |
| [`src1/utils.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/utils.js) | EMU→point conversion, MIME lookup, base64 encoding |
| [`src1/shape.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/shape.js) | Geometry, custom shapes, fills/borders |
| [`src1/text.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/text.js) | PowerPoint text runs → HTML strings |
| [`src1/fill.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/fill.js) | Solid, picture, gradient, pattern fills |
| [`src1/chart.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/chart.js) | Chart parsing (series, types, colors) |
| [`src1/table.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/table.js) | Table structure with spans and styling |
| [`src1/diagram.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/diagram.js) | SmartArt diagram extraction |
| [`src1/math.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/math.js) | OMML MathML → LaTeX conversion |

## Summary

- **`@openmaic/importer`** converts PPTX to JSON through a 10-stage pipeline starting with zip extraction and ending with structured slide objects.

- **Resource resolution** follows PowerPoint's relationship files (`.rels`) to locate themes, layouts, masters, and embedded media.

- **Node dispatch** in `processNodesInSlide` routes shapes, pictures, charts, tables, diagrams, and math to specialized handlers.

- **Media handling** supports both base64 embedding and blob URL generation via the `mediaMode` option.

- **The output JSON** matches OpenMAIC's renderer schema exactly, enabling faithful reproduction of slides, shapes, text, media, charts, tables, diagrams, and formulas.

## Frequently Asked Questions

### What input formats does @openmaic/importer accept?

The `parse` function accepts an `ArrayBuffer` or `Buffer`. In browsers, use `file.arrayBuffer()` on a File object. In Node.js, read the file into a Buffer with `fs.readFileSync()`. The importer does not accept file paths directly.

### How are PowerPoint themes and colors preserved?

`getTheme` extracts accent colors from the theme XML referenced in `presentation.xml.rels`. These colors are aggregated into a `themeColors` array returned at the top level of the parse result, allowing the OpenMAIC renderer to apply consistent color schemes.

### What happens to embedded videos and audio files?

`processPicNode` detects media types by extension and MIME type lookup in [`utils.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/utils.js). The binary content is extracted from the zip and converted to either base64 data URLs or blob URLs depending on the `mediaMode` option. The resulting element specifies `type: 'video'` or `type: 'audio'` with the appropriate source reference.

### Can the importer handle complex SmartArt diagrams?

Yes. `processGraphicFrameNode` delegates SmartArt content to `genDiagram` in [`src1/diagram.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src1/diagram.js). This module extracts the hierarchical shape structure and fallback text from the diagram's data model, producing a JSON representation that preserves the visual arrangement.