[Ipe-discuss] Ipe presentation to reveal.js

Simon Dominik Fink sfink at ac.tuwien.ac.at
Mon Feb 10 15:42:07 CET 2025


> 
Hey Fabian,

I currently have a bachelor student working on a tool that translates
ipe objects to manim objects and that should allow to mostly faithfully
render ipe slides to video via manim or to HTML via manim-slides +
reveal.js. This should allow creating animations for all ipe-drawn
objects and also all the other fancy things manim can do.
Instead of statically doing the translation from ipe as a one-shot
process that makes it hard to edit your ipe file once you started
adding animations in manim, the idea is to have an ipe file and some
annotating python file with the manim animations side-by-side and only
do the translation at render time, so you can edit both files
simultaneously.
While I cannot share a public link just yet, the thesis should be
handed in by the end of this month and I hope to be able to share more
information shortly thereafter.

Cheers,
Niko from TU Wien

> > Date: Sun, 9 Feb 2025 15:47:14 +0200
> > From: Fabien Lafont <lafont.fabien at gmail.com>
> > To: Ipe-discuss <ipe-discuss at lists.science.uu.nl>
> > Subject: [Ipe-discuss]  Ipe presentation to reveal.js
> > Message-ID:
> > 	<CAC9H_cgx9R=CJx22ZqOjP5K0Hb_HLKxq7-
> > Ay19c7u+1Ury5f0Q at mail.gmail.com>
> > Content-Type: text/plain; charset="utf-8"
> > 
> > Hello everyone,
> > 
> > I have been using IPE to make my presentation for many years now
> > but I find
> > it sometimes a bit limited when I want to include videos (or
> > background
> > animations made with manim:
> > https://docs.manim.community/en/stable/tutorials/quickstart.html).
> > I
> > therefore tried to switch to reveal.js paired with quarto (
> > https://quarto.org/docs/presentations/revealjs/).
> > On the positive side it looks really good and it is pretty easy to
> > create
> > basic slides but, as often with such a solution, it is very rigid
> > when it
> > comes to add drawings or plots.
> > 
> > I did, with a lot of help from chatGPT, a small script to convert
> > slides
> > made with IPE to svg images that are then loaded in a quarto file.
> > It is
> > working ok but I wanted to know if other people did similar things
> > here and
> > probably in a better way I did. For example now I save each slide
> > separately in a SVG format which is a bit stupid when often each of
> > these
> > slides have 90% similar content.
> > 
> > Here is my code:
> > 
> > import os
> > import subprocess
> > import xml.etree.ElementTree as ET
> > 
> > # ==============================
> > # ? User Configuration ?
> > # ==============================
> > 
> > # Path to your Ipe presentation file (.ipe)
> > IPE_FILE = "your_presentation.ipe"  # Change this to your actual
> > file
> > 
> > # Output folder for generated SVGs and markdown
> > OUTPUT_FOLDER = "output"
> > 
> > # Name of the output Quarto markdown file
> > MARKDOWN_FILE = "slides.qmd"
> > 
> > # Path to the Ipe rendering tool (iperender)
> > IPE_RENDER_PATH = "C:/path/to/iperender.exe"  # Change this to your
> > actual
> > iperender path
> > 
> > # ==============================
> > # ? Script Execution Begins
> > # ==============================
> > 
> > # Step 1: Verify the IPE file exists
> > if not os.path.exists(IPE_FILE):
> >     print(f"? ERROR: IPE file not found: {IPE_FILE}")
> >     exit(1)
> > 
> > # Step 2: Create output directory
> > os.makedirs(OUTPUT_FOLDER, exist_ok=True)
> > 
> > # Step 3: Parse the IPE XML file to get pages (slides) and their
> > views
> > print(f"? Extracting pages and views from {IPE_FILE}...")
> > 
> > tree = ET.parse(IPE_FILE)
> > root = tree.getroot()
> > 
> > slide_views = []  # List to store all slide titles and their views
> > 
> > for page_idx, page in enumerate(root.findall(".//page"), start=1):
> >     # Get the slide title (default: "Slide X")
> >     title_element = page.find("title")
> >     slide_title = title_element.text.strip() if title_element is
> > not None
> > else f"Slide {page_idx}"
> > 
> >     views = []
> >     for view_idx, view in enumerate(page.findall("view"), start=1):
> >         layers = view.attrib.get("layers", "").split()
> >         if layers:
> >             views.append((view_idx, layers))
> > 
> >     if views:
> >         slide_views.append((slide_title, page_idx, views))
> > 
> > print(f"? Found {len(slide_views)} slides with views.")
> > 
> > # Step 4: Render each view of each slide
> > svg_files = []
> > 
> > for slide_title, page_idx, views in slide_views:
> >     for view_idx, (view_number, layers) in enumerate(views,
> > start=1):
> >         output_svg = os.path.join(OUTPUT_FOLDER,
> > f"{slide_title.replace('
> > ', '_')}_view_{view_idx}.svg")
> >         output_svg = output_svg.replace("\\", "/")  # Ensure cross-
> > platform
> > compatibility
> > 
> >         print(f"? Rendering {slide_title} (Page {page_idx}, View
> > {view_idx}) -> {output_svg}...")
> > 
> >         # Render the slide view directly from the IPE file
> >         render_cmd = [IPE_RENDER_PATH, "-svg", "-page",
> > str(page_idx),
> > "-view", str(view_number), IPE_FILE, output_svg]
> >         result = subprocess.run(render_cmd, capture_output=True,
> > text=True)
> > 
> >         if result.returncode != 0 or not
> > os.path.exists(output_svg):
> >             print(f"? ERROR: Failed to render {slide_title} (Page
> > {page_idx}, View {view_idx}). Message:\n{result.stderr}")
> >             continue
> > 
> >         svg_files.append((slide_title, output_svg))
> > 
> > # Step 5: Check if any SVGs were generated
> > if not svg_files:
> >     print("? ERROR: No slides generated. Check iperender and
> > views.")
> >     exit(1)
> > 
> > print(f"? Generated {len(svg_files)} slides.")
> > 
> > # Step 6: Generate Quarto/Reveal.js Markdown file with the "clean"
> > theme
> > with open(MARKDOWN_FILE, "w") as f:
> >     f.write(
> >         """---
> > title: "My Presentation"
> > format: revealjs
> > revealjs:
> >   theme: [default, clean]  # Using the "clean" theme for better
> > styling
> >   transition: fade
> >   slideNumber: true
> >   chalkboard: true
> >   previewLinks: true
> >   highlightStyle: github
> > ---
> > """
> >     )
> > 
> >     for slide_title, svg in svg_files:
> >         svg = svg.replace("\\", "/")  # Ensure paths are cross-
> > platform
> >         f.write(f"## {slide_title}\n\n")  # Each view appears as a
> > separate
> > slide with the same title
> >         f.write(f"![]({svg}){{width=100%}}\n\n")
> > 
> > print(f"\n? Quarto/Reveal.js presentation generated:
> > {MARKDOWN_FILE}")
> > -------------- next part --------------
> > An HTML attachment was scrubbed...
> > URL:
> > <https://mailman.science.uu.nl/pipermail/ipe-discuss/attachments/20
> > 250209/9edb6a0a/attachment-0001.html>



More information about the Ipe-discuss mailing list