diff --git a/contrib/pdf_slideshow.lua b/contrib/pdf_slideshow.lua
new file mode 100644
index 0000000..bfcdedc
--- /dev/null
+++ b/contrib/pdf_slideshow.lua
@@ -0,0 +1,242 @@
+--[[
+ This file is part of darktable,
+ copyright (c) 2017 Pascal Obry
+
+ darktable is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ darktable is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with darktable. If not, see .
+]]
+--[[
+SELECTION_TO_PDF
+Generates a PDF slideshow (via Latex) containing all selected images
+one per slide.
+
+ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT
+* a PDF-Viewer
+* pdflatex (Latex)
+
+USAGE
+* require this file from your main lua config file:
+
+This plugin will add a new exporter that will allow you to generate a pdf slideshow.
+The interface will let you add:
+ - a global title for the slideshow (prefix in all slide label)
+ - a delay for the transition between each slide
+
+Each slide will contain a single picture with a label at the bottom with the
+format (all fields can be the empty string):
+
+ / /
+
+]]
+local dt = require "darktable"
+local df = require "lib/dtutils.file"
+require "official/yield"
+
+local gettext = dt.gettext
+
+-- Tell gettext where to find the .mo file translating messages for a particular domain
+gettext.bindtextdomain("pdf_slideshow",dt.configuration.config_dir.."/lua/")
+
+local function _(msgid)
+ return gettext.dgettext("pdf_slideshow", msgid)
+end
+
+if not df.check_if_bin_exists("pdflatex") then
+ dt.print_error(_("pdflatex not found"))
+ return
+end
+
+dt.configuration.check_version(...,{4,0,0},{5,0,0})
+
+dt.preferences.register
+ ("pdf_slideshow","open with","string",
+ _("a pdf viewer"),
+ _("can be an absolute pathname or the tool may be in the PATH"),
+ "xdg-open")
+
+local title_widget = dt.new_widget("entry") {
+ placeholder=_("slideshow title")
+}
+local delay_widget = dt.new_widget("slider")
+{
+ label = _("transition delay (s)"),
+ soft_min = 1, -- The soft minimum value for the slider, the slider can't go beyond this point
+ soft_max = 20, -- The soft maximum value for the slider, the slider can't go beyond this point
+ hard_min = 1, -- The hard minimum value for the slider, the user can't manually enter a value beyond this point
+ hard_max = 60, -- The hard maximum value for the slider, the user can't manually enter a value beyond this point
+ value = 5, -- The current value of the slider
+ step = 1,
+ digits = 0
+}
+local check_button_title = dt.new_widget("check_button")
+{
+ label = _('include image title'),
+ value = true,
+ tooltip = _('whether to include the image title (if defined) into the slide')
+}
+local check_button_author = dt.new_widget("check_button")
+{
+ label = _('include image author'),
+ value = true,
+ tooltip = _('whether to include the image author (if defined) into the slide')
+}
+local widget = dt.new_widget("box") {
+ orientation=horizontal,
+ dt.new_widget("label"){label = _("slideshow title")},
+ title_widget,
+ dt.new_widget("label"){label = ""},
+ delay_widget,
+ check_button_author,
+ check_button_title
+}
+
+local ending = [[
+\end{document}
+]]
+
+-- only jpeg files are supported by latex
+local function support_format(storage, format)
+ fmt = string.lower(format.name)
+ if string.match(fmt,"jpeg") ~= nil and string.match(fmt,"2000") == nil then
+ return true
+ else
+ return false
+ end
+end
+
+local filename =dt.configuration.tmp_dir.."/pdfout.tex"
+
+local function my_write(latexfile,arg)
+ local res,errmsg = latexfile:write(arg)
+ if not res then
+ error(errmsg)
+ end
+end
+
+local function slide(latexfile,i,image,file)
+ local title = ""
+ if title_widget.text ~= "" then
+ title = title_widget.text
+ end
+ if check_button_author.value == true and image.creator ~= "" then
+ if title ~= "" then
+ title = title.." / "
+ end
+ title = title..image.creator
+ end
+ if check_button_title.value == true and image.title ~= "" then
+ if title ~= "" then
+ title = title.." / "
+ end
+ title = title..image.title
+ end
+
+ -- make sure there is no non-printable characters in the title
+ title = string.gsub(title, "\n", "")
+ title = string.gsub(title, "\r", "")
+ title = string.gsub(title, "\t", "")
+
+ local lfile = "slide"..i..".jpg"
+ os.rename(file, lfile)
+
+ -- fact is that latex will get confused if the filename has multiple dots.
+ -- so \includegraphics{file.01.jpg} wont work. We need to output the filename
+ -- and extention separated, e.g: \includegraphics{{file.01}.jpg}
+ local filenoext=string.gsub(lfile, "(.*)(%..*)", "%1")
+ local ext=string.gsub(lfile, "(.*)(%..*)", "%2")
+ my_write(latexfile,"\\begin{minipage}[b]{0,99\\textwidth}\n")
+
+ my_write(latexfile,"\\includegraphics[height=0.95\\textheight]{{"..filenoext.."}"..ext.."}\\newline\n")
+ my_write(latexfile,"\\centering{{\\color{white}\\verb|"..title.."|}}\n")
+ my_write(latexfile,"\\end{minipage}\\quad\n")
+end
+
+dt.register_storage("pdf_slideshow",_("pdf slideshow"),
+ nil,
+ function(storage,image_table)
+
+ local preamble = [[
+ \documentclass[a4paper,10pt,landscape]{beamer}
+ \usetheme{default}
+ \usepackage[utf8]{inputenc}
+ \usepackage{graphicx}
+ \usepackage[space]{grffile} % needed to support filename with spaces
+ \pagestyle{empty}
+ \parindent0pt
+ \usepackage{geometry}
+ \usepackage{color}
+ \pagecolor{black!100}
+ \color{white}
+ \geometry{a4paper,landscape,left=5mm,right=5mm, top=5mm, bottom=5mm}
+ \mode
+ \transduration{]]..delay_widget.value..[[}
+ \setbeamertemplate{footline}{}
+ \setbeamertemplate{headline}{}
+ \setbeamertemplate{frametitle}{}
+ \setbeamertemplate{navigation symbols}{}
+ \setbeamercolor{background canvas}{fg=white,bg=black!100}
+ \setbeamercolor{normal text}{fg=white}
+ \hypersetup{pdfstartpage=1,pdfpagemode=FullScreen}
+ \begin{document}
+ ]]
+
+ local errmsg
+ local latexfile
+ latexfile,errmsg=io.open(filename,"w")
+ if not latexfile then
+ error(errmsg)
+ end
+ my_write(latexfile,preamble)
+ local i = 1
+ for img,file in pairs(image_table) do
+ slide(latexfile,i,img,file)
+ my_write(latexfile,"\n\\bigskip\n")
+ i = i+1
+ end
+ my_write(latexfile,ending)
+ latexfile:close()
+
+ -- convert to PDF
+ local dir=string.gsub(filename, "(.*/)(.*)", "%1")
+ local locfile=string.gsub(filename, "(.*/)(.*)", "%2")
+ local command = "pdflatex -halt-on-error -output-directory "..dir.." "..locfile
+ local result = dt.control.execute(command)
+ if result ~= 0 then
+ dt.print(_("problem running pdflatex")) -- this one is probably usefull to the user
+ error(_("problem running ")..command)
+ end
+
+ -- open the PDF
+ local pdffile=string.gsub(filename, ".tex", ".pdf")
+ command = dt.preferences.read("pdf_slideshow","open with","string")
+ command = command.." "..pdffile
+ local result = dt.control.execute(command)
+ if result ~= 0 then
+ dt.print(_("problem running pdf viewer")) -- this one is probably usefull to the user
+ error(_("problem running ")..command)
+ end
+
+ -- finally do some clean-up
+ local i = 1
+ for img,file in pairs(image_table) do
+ local lfile = "slide"..i..".jpg"
+ os.remove(lfile)
+ i = i+1
+ end
+ end,
+ support_format,
+ nil,
+ widget)
+
+--
+-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua