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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ You can install python-pptx with

`pip3 install python-pptx`

Some optional features require additional packages:

* **Inline math** (`mathxsl` option): `pip3 install latex2mathml lxml`

(On a Raspberry Pi you might want to use `pip3` (or `python3 -m pip`) to install for Python 3.)

You will probably need to issue the following command from the directory where you install it:
Expand Down
36 changes: 36 additions & 0 deletions docs/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ As you can see in the [change log](#change-log), md2pptx is frequently updated -
* [Sample Macro To Remove The First Slide And Save As A .pptx File](#sample-macro-to-remove-the-first-slide-and-save-as-a-pptx-file)
* [HTML Comments](#html-comments)
* [Special Text Formatting](#special-text-formatting)
* [Inline Math](#inline-math)
* [Using HTML `<span>` Elements To Specify Text Effects](#using-html-<span>-elements-to-specify-text-effects)
* [Using HTML `<span>` Elements with `class`](#using-html-<span>-elements-with-class)
* [Using HTML `<span>` Elements with `style`](#using-html-<span>-elements-with-style)
Expand Down Expand Up @@ -97,6 +98,7 @@ As you can see in the [change log](#change-log), md2pptx is frequently updated -
* [Presentation Subtitle Size - `presSubtitleSize`](#presentation-subtitle-size-pressubtitlesize)
* [Page Title Alignment `pagetitlealign`](#page-title-alignment-pagetitlealign)
* [Monospace Font - `monoFont`](#monospace-font-monofont)
* [Inline Math - `mathxsl`](#inline-math-mathxsl)
* [Margin size - `marginBase` and `tableMargin`](#margin-size-marginbase-and-tablemargin)
* [Controlling Adjusting Title Positions And Sizes - `AdjustTitles`](#controlling-adjusting-title-positions-and-sizes-adjusttitles)
* [Associating A Class Name with A Background Colour With `style.bgcolor`](#associating-a-class-name-with-a-background-colour-with-stylebgcolor)
Expand Down Expand Up @@ -1659,6 +1661,15 @@ Some other HTML-originated text effects work - as Markdown allows you to embed H

**Note:** Superscript works by raising the text baseline. Subscript works by lowering it. This is how Powerpoint itself does it.

### Inline Math
<a id="inline-math"></a>

If you have configured the [`mathxsl`](#inline-math-mathxsl) metadata option, you can embed LaTeX inline math expressions by surrounding them with dollar signs:

* The Euler identity $e^{i\pi}+1=0$ is beautiful.

Each `$...$` expression is converted to a native PowerPoint math object (OMML). See [Inline Math - `mathxsl`](#inline-math-mathxsl) for setup instructions.

<a id="using-html-%3Cspan%3E-elements-to-specify-text-colours-and-underlining"></a>
### Using HTML `<span>` Elements To Specify Text Effects

Expand Down Expand Up @@ -2091,6 +2102,31 @@ Example:

The default is Courier.

#### Inline Math - `mathxsl`
<a id="inline-math-mathxsl"></a>

To render LaTeX inline math expressions as native PowerPoint math objects, specify the path to `MML2OMML.XSL` (supplied with Microsoft Office):

mathxsl: /path/to/MML2OMML.XSL

Once set, surround any LaTeX expression with dollar signs in your bullet text:

* The Euler identity $e^{i\pi}+1=0$ is beautiful.
* The quadratic formula $\frac{-b \pm \sqrt{b^2-4ac}}{2a}$ solves ax²+bx+c=0.

md2pptx converts each `$...$` expression to OMML (Office Math Markup Language) and embeds it directly in the slide XML, so the formula renders as a native PowerPoint equation object.

**Requirements:**

* `MML2OMML.XSL` — included with a local Microsoft Office installation (typically under `Office/root/`)
* `pip3 install latex2mathml lxml`

**Notes:**

* If `mathxsl` is not specified, `$...$` is left as-is in the output text.
* If conversion fails for a particular expression, md2pptx falls back to rendering the literal `$...$` text.
* `~` in the XSL path is expanded to the user's home directory.

#### Margin size - `marginBase` and `tableMargin`
<a id="margin-size-marginbase-and-tablemargin"></a>

Expand Down
16 changes: 16 additions & 0 deletions md2pptx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ from pptx.oxml import parse_xml
import uuid
import funnel
import runPython
import pptx_math
from card import Card
from rectangle import Rectangle
from colour import *
Expand Down Expand Up @@ -1579,6 +1580,10 @@ def handleRunPython(pythonType, prs, slide, renderingRectangle, codeLinesOrFile,
else:
r.runFromFile(codeLinesOrFile[0], prs, slide, renderingRectangle)

def handleMath(prs, slide, renderingRectangle, codeLines, codeType):
m = pptx_math.PptxMath()
m.run(prs, slide, renderingRectangle, codeLines, codeType)

def createCodeBlock(slideInfo, slide, renderingRectangle, codeBlockNumber):
monoFont = globals.processingOptions.getCurrentOption("monoFont")
baseTextSize = globals.processingOptions.getCurrentOption("baseTextSize")
Expand Down Expand Up @@ -1633,6 +1638,11 @@ def createCodeBlock(slideInfo, slide, renderingRectangle, codeBlockNumber):

return slide

elif codeType.startswith("math") or codeType.startswith("maths"):
handleMath(prs, slide, renderingRectangle, codeLines[1:-1], codeType)

return slide

else:
# Some other type with backticks
codeType = "backticks"
Expand Down Expand Up @@ -4675,6 +4685,7 @@ else:
print("\nInternal Dependencies:")
print(f"\n funnel: {funnel.version}")
print(f" runPython: {runPython.version}")
print(f" pptx_math: {pptx_math.version}")

input_file = []

Expand Down Expand Up @@ -4963,6 +4974,8 @@ globals.processingOptions.setOptionValuesArray(

globals.processingOptions.setOptionValues("monoFont", "Courier")

globals.processingOptions.setOptionValues("mathxsl", "")

topHeadingLevel = 1
titleLevel = topHeadingLevel
sectionLevel = titleLevel + 1
Expand Down Expand Up @@ -5648,6 +5661,9 @@ for line in metadata_lines:
applescriptPrologueFiles.append(prologFile)
globals.processingOptions.setOptionValues("applescriptprologue", applescriptPrologueFiles)

elif name == "mathxsl":
globals.processingOptions.setOptionValues(name, os.path.expanduser(value))

elif name in ["applescriptepilog", "applescriptepilogue"]:
if value[:1] == "!":
epilogFile = md2pptx_path + os.sep + "applescript" + os.sep + value[1:]
Expand Down
1 change: 1 addition & 0 deletions paragraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ def parseText(text):

fragment = ""
state = "fnref"

else:
fragment = fragment + c

Expand Down
Loading