Groovy PowerPoint DSL
I’m really not shaving a yak here, but I created a PowerPoint DSL to give a presentation about DSLs! Let’s jump to the code immediately, because if you’re reading this, you must be interested in DSLs.
This is the (Groovy) DSL I wrote:
builder.slideshow(filename:'Test.ppt') {
slide(title: 'Introduction') {
bullet(text: 'Bullet 1')
bullet(text: 'Bullet 2')
}
slide(title: 'Slide 2') {
bullet(text: 'Bullet 3')
bullet(text: 'Bullet 4')
}
slide(title: 'Example') {
textbox("""This is a slide
With a lot of extra lines
Which make no sense
At all""")
}
imageslide(src:'background.png')
}
The DSL is pretty straightforward. I didn’t support all features of PowerPoint (nor would I want to, nor is it feasible), but the basics are here. The DSL currently supports all of the above:
- Slides with titles
- Bullets, which can be added to the slides
- Textboxes, which are large text area’s
- Imageslides, which are slides consisting of only images. This is to support all the ‘Beyond Bullet Points’ lovers 😉
While the DSL is far from complete (you could add individual images, position them using X,Y coordinates, add tables, add notes and more), the idea is clear: in a consistent and easy to read structure you can define all those elements you need in a powerpoint presentation. All the missing elements, like stated above, can easily be added by adding it to corresponding domain and exporter.
Domain and exporter you say? Yes! There are ofcourse multiple approaches in creating the DSL, but I’ve kept some parts apart from each other. Under the hood, the DSL is transformed into a very simple domain model, also consisting of slides, bullets, textboxes, etc. This extra layer is introduced to create a separation of concerns. Now, the only responsibility of the Builder is to build the domain model, instead of parsing the DSL and also creating the Powerpoint. The creation of the powerpoint is now delegated to a (also) simple Exporter, which understands the API of the POI library used to create the actual PowerPoint file. So, the model is built by the Groovy Builder, and, once the build phase is complete, the model is given to the exporter, which traverses the model. This makes the code cleaner and also allows easy testing of both the DSL and the Exporter. Ofcourse, I tested none, but instead relied on my excellent programming skills……(The next blog is about TDD, okay??)
This resulted in the following diagram:

Application diagram
I like the approach, but if you don’t, or know a better way, please let me know. I’d really appreciate feedback, since I will probably use a similar approach in the next DSL I create.
The code, and the resulting PowerPoint, can be found in the uploaded zipfile. Like I said: as always, let me know what you think!



That’s cool, I like your idea very much!
I often need to make presentations to different audiences about the same topic, so I need to create different slide files. Most of these files’ content are same, but with few slides different. When I modified the slide files, I have to copy the modification to each slide file, that is very inconvenient for me.
If I could create the slide file by using a DSL, then what I need to do is: 1) modifying the DSL, 2) re-generate slides files.
Hope you can continue to complete your approach!
flyisland
February 28, 2009
Hi flyisland, thanks for the reponse. I’m not really planning on extending the powerpoint, though I see your point how it could be useful in your situation. You can download the source in the zipfile if you want to extend it. I wouldn’t mind to assist you if you run into problems.
You can also find the code here: https://github.com/bodiam/powerpointdsl/tree
Erik Pragt
February 28, 2009
Very practical and concrete example for a presentation on DSLs. Eat your own dog food, really 🙂
Guillaume Laforge
February 28, 2009
Very cool. Can’t wait to download your code and fool around with it. Thanks for sharing…. 🙂
Public Farley
March 1, 2009
Support for Videos? Would like to easily do: //##### Video slide
Slide vidSlide = m_ppt.createSlide();
//Set movie
int thumbIndex = m_ppt.addPicture(new File(“media\\blank.bmp”), Picture.DIB);
int movieIndex = m_ppt.addMovie(“video_data\\30_Sec.wmv”, MovieShape.MOVIE_AVI );
MovieShape movie = new MovieShape(movieIndex,thumbIndex);
movie.setAnchor(new java.awt.Rectangle(10, 75, 699, 394));
movie.setAutoPlay(false);
vidSlide.addShape(movie);
//Title
TextBox vidSlideTitle = vidSlide.addTitle();
vidSlideTitle.setText(“Slide with a movie file”);
vidSlideTitle.setAnchor(new java.awt.Rectangle(54, 15, 612, 90));
//Textbox
TextBox txtDisclaimer = new TextBox();
txtDisclaimer.setAnchor(new java.awt.Rectangle(500, 510, 200, 90));
txtDisclaimer.setText(“(Double-click to play)”);
Garvin
November 22, 2010