python-pptx icon indicating copy to clipboard operation
python-pptx copied to clipboard

feature request: maths formula or Latex support

Open httassadar opened this issue 11 years ago • 8 comments

Writing maths is needed very frequently in scientific background. Powerpoint has built-in formula support, is it possible to have access to that?

At the moment, when I want some formula, I'll generate a picture and add_picture

r = requests.get( 'http://latex.codecogs.com/png.latex?\dpi{900} %s' % formula )
tmpfname = r"H:\tmpplots\pptx_formula.png"
f = open( tmpfname, 'wb' )
f.write( r.content )
f.close()

This is OK for occasional displayed maths, but for frequent use of Greeks, sub/super-scripts etc, I have to manually edit the file afterwards.

httassadar avatar Oct 24 '14 14:10 httassadar

+1

nilswagner avatar Oct 29 '15 10:10 nilswagner

+1

nhkhai avatar Dec 07 '20 01:12 nhkhai

+1

Dusty-Gannon avatar Mar 21 '25 19:03 Dusty-Gannon

What would that look like in XML terms?

MartinPacker avatar Mar 21 '25 19:03 MartinPacker

+1

mayurankv avatar Dec 24 '25 10:12 mayurankv

Two questions - of which one is where I'm repeating myself:

  1. Can someone post a fragment of XML that shows what a simple formula would look like? Euler's Equation has some complexity.

  2. Any thoughts on what could parse a formula in eg Latex syntax into a tree - to be converted to XML like that in Q1? This would have to be in python - unless something could be called externally that emitted eg JSON.

(On the second point - my md2pptx can call CairoSVG to do conversion.)

Note: I'm not advocating an external tool creating a bitmap; pptx format is better all round.

MartinPacker avatar Dec 24 '25 10:12 MartinPacker

Being able to request something like mathjax would be the dream but html is not possible in pptx iirc so I think there's two straightforward approaches:

  1. Use latex to unicode converters to have a semblance of math capabilities (this can likely be done on the user side though so may not be ideal for additional implementation)
  2. As you suggest parse latex or some python structure into a powerpoint math output

For point 1, see https://pypi.org/project/pylatexenc/

For point 2, these may be of interest:

  • Direct Conversion: https://tex.stackexchange.com/questions/25223/embed-latex-math-equations-into-microsoft-word
    • https://github.com/cyrildtm/latex2word/blob/master/latex2word.html - This is interesting as it suggests MathJax can do direct to MathML (I believe what microsoft math uses) which means users wouldn't necessarily need a LaTeX install
    • https://github.com/roniemartinez/latex2mathml - This is a pure python solution apparently which would be ideal - not sure what prereqs it has
      • Example application: https://github.com/maxwang967/Latex2WordFullConverter/blob/main/eq_converter_v1.py
    • Alternative approach: https://github.com/yeewantung/tex_math_to_word/blob/main/latex_to_word.py
  • LaTeX AST Tree: https://www.npmjs.com/package/@andstor/latex-math-parser

This is showing $e^{i\theta}=\cos{\theta}+i\sin{\theta}$ using the standard powerpoint maths tools:

<m:oMathPara xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math">
	<m:oMathParaPr>
		<m:jc m:val="centerGroup" />
	</m:oMathParaPr>
	<m:oMath>
		<m:sSup>
			<m:sSupPr>
				<m:ctrlPr>
					<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
				</m:ctrlPr>
			</m:sSupPr>
			<m:e>
				<m:r>
					<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
					<m:t>&#x1d452;</m:t>
				</m:r>
			</m:e>
			<m:sup>
				<m:r>
					<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
					<m:t>&#x1d456;</m:t>
				</m:r>
				<m:r>
					<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
						<a:ea typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
					<m:t>&#x1d703;</m:t>
				</m:r>
			</m:sup>
		</m:sSup>
		<m:r>
			<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
				<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
			</a:rPr>
			<m:t>=</m:t>
		</m:r>
		<m:func>
			<m:funcPr>
				<m:ctrlPr>
					<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
				</m:ctrlPr>
			</m:funcPr>
			<m:fName>
				<m:r>
					<m:rPr>
						<m:sty m:val="p" />
					</m:rPr>
					<a:rPr lang="en-GB" sz="3600" b="0" i="0" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
					<m:t>cos</m:t>
				</m:r>
			</m:fName>
			<m:e>
				<m:r>
					<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
						<a:ea typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
					<m:t>&#x1d703;</m:t>
				</m:r>
			</m:e>
		</m:func>
		<m:r>
			<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
				<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
			</a:rPr>
			<m:t>+</m:t>
		</m:r>
		<m:r>
			<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
				<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
			</a:rPr>
			<m:t>&#x1d456;</m:t>
		</m:r>
		<m:func>
			<m:funcPr>
				<m:ctrlPr>
					<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
				</m:ctrlPr>
			</m:funcPr>
			<m:fName>
				<m:r>
					<m:rPr>
						<m:sty m:val="p" />
					</m:rPr>
					<a:rPr lang="en-GB" sz="3600" b="0" i="0" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
					<m:t>sin</m:t>
				</m:r>
			</m:fName>
			<m:e>
				<m:r>
					<a:rPr lang="en-GB" sz="3600" b="0" i="1" smtClean="0">
						<a:latin typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
						<a:ea typeface="Cambria Math" panose="02040503050406030204" pitchFamily="18" charset="0" />
					</a:rPr>
					<m:t>&#x1d703;</m:t>
				</m:r>
			</m:e>
		</m:func>
	</m:oMath>
</m:oMathPara>

As an aside, if this is harder than I believe, then even an easier way to embed images of latex would be amazing!

mayurankv avatar Dec 24 '25 11:12 mayurankv

I will say, that https://github.com/roniemartinez/latex2mathml seems the obvious route imo but the above xml also seems pretty straightforward to parse

mayurankv avatar Dec 24 '25 11:12 mayurankv