diff --git a/contrib/autostyle.lua b/contrib/autostyle.lua new file mode 100644 index 0000000..83ebb84 --- /dev/null +++ b/contrib/autostyle.lua @@ -0,0 +1,144 @@ +--[[ +Autostyle +Automatically apply a given style when an exif tag is present in the file. This tagged is checked with exiftool, in order to be able to match very exotic tags. +I wrote this initially to be able to apply a style to compensate for Auto-DR from my Fujifilm camera + +AUTHOR +Marc Cousin (cousinmarc@gmail.com) + +INSTALATION +* copy this file in $CONFIGDIR/lua/ where CONFIGDIR +is your darktable configuration directory +* add the following line in the file $CONFIGDIR/luarc + require "autostyle" + +USAGE +* set the exif configuration string in your lua configuration + mine, for instance, is AutoDynamicRange=200%=>DR200" + meaning that I automatically want to apply my DR200 style on all + images where exiftool returns '200%' for the AutoDynamicRange tag +* if you want to be able to apply it manually to already imported + images, define a shortcut (lua shortcuts). As I couldn't find an event for + when a development is removed, so the autostyle won't be applied again, + this shortcut is also helpful then +* import your images, or use the shortcut on your already imported images +* To determine which tag you want, list all tags with exiftool: + exiftool -j XE021351.RAF, and find the one you want to use + you can check it with + > exiftool -AutoDynamicRange XE021351.RAF + Auto Dynamic Range : 200% + + +LICENSE +GPLv2 + +]] + +local darktable = require "darktable" + + +-- Forward declare the functions +local autostyle_apply_one_image,autostyle_apply_one_image_event,autostyle_apply,exiftool_attribute,capture + +-- Tested it with darktable 1.6.1 and darktable git from 2014-01-25 +darktable.configuration.check_version(...,{2,0,2},{2,1,0}) + +-- Receive the event triggered +function autostyle_apply_one_image_event(event,image) + autostyle_apply_one_image(image) +end + +-- Apply the style to an image, if it matches the tag condition +function autostyle_apply_one_image (image) + -- We need the tag, the value and the style_name provided from the configuration string + local tag,value,style_name=string.match(darktable.preferences.read("autostyle","exif_tag","string"),"(%g+)%s*=%s*(%g+)%s*=>%s*(%g+)") + + -- check they all exist (correct syntax) + if (not tag) then + darktable.print("EXIF TAG not found in " .. darktable.preferences.read("autostyle","exif_tag","string")) + return + end + if (not value) then + darktable.print("value to match not found in " .. darktable.preferences.read("autostyle","exif_tag","string")) + return + end + if (not style_name) then + darktable.print("style name not found in " .. darktable.preferences.read("autostyle","exif_tag","string")) + return + end + + -- First find the style (we have its name) + local styles= darktable.styles + local style + for _,s in ipairs(styles) do + if s.name == style_name then + style=s + end + end + if (not style) then + darktable.print("style not found for autostyle: " .. style_name) + end + + -- Apply the style to image, if it is tagged + local ok,auto_dr_attr= pcall(exiftool_attribute,image.path .. '/' .. image.filename,tag) + -- If the lookup fails, stop here + if (not ok) then + return + end + if auto_dr_attr==value then +-- darktable.print("Image " .. image.filename .. ": autostyle automatically applied " .. darktable.preferences.read("autostyle","exif_tag","string") ) + darktable.styles.apply(style,image) +-- else +-- darktable.print("Image " .. image.filename .. ": autostyle not applied, exif tag " .. darktable.preferences.read("autostyle","exif_tag","string") .. " not matched: " .. auto_dr_attr) + end +end + + +function autostyle_apply( shortcut) + local images = darktable.gui.action_images + for _,image in pairs(images) do + autostyle_apply_one_image(image) + end +end + +-- Retrieve the attribute through exiftool +function exiftool_attribute(path,attr) + local cmd="exiftool -" .. attr .. " '" ..path.. "'"; + local exifresult=get_stdout(cmd) + local attribute=string.match(exifresult,": (.*)") + if (attribute == nil) then + darktable.print( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">") + -- Raise an error to the caller + error( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">"); + end + return attribute +end + +-- run command and retrieve stdout +function get_stdout(cmd) + -- Open the command, for reading + local fd = assert(io.popen(cmd, 'r')) + -- yield to other lua threads until data is ready to be read + coroutine.yield("FILE_READABLE",fd) + -- slurp the whole file + local data = assert(fd:read('*a')) + + fd:close() + -- Replace carriage returns and linefeeds with spaces + data = string.gsub(data, '[\n\r]+', ' ') + -- Remove spaces at the beginning + data = string.gsub(data, '^%s+', '') + -- Remove spaces at the end + data = string.gsub(data, '%s+$', '') + return data +end + +-- Registering events +darktable.register_event("shortcut",autostyle_apply, + "Apply your chosen style from exiftool tags") + +darktable.preferences.register("autostyle","exif_tag","string","Autostyle: EXIF_tag=value=>style","apply a style automatically if an EXIF_tag matches value. Find the tag with exiftool","") + +darktable.register_event("post-import-image",autostyle_apply_one_image_event) + + diff --git a/contrib/copy_attach_detach_tags.lua b/contrib/copy_attach_detach_tags.lua index f2b5f52..d5a7ec8 100644 --- a/contrib/copy_attach_detach_tags.lua +++ b/contrib/copy_attach_detach_tags.lua @@ -1,22 +1,35 @@ --[[ - copyright (c) 2014 Christian Kanzian - LICENSE GPLv2 - ]] + This file is part of darktable, + copyright 2014-2015 by Christian Kanzian. + + This program 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. + + This program 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 this program. If not, see . +]] --[[ -(MULTI-)COPY ATTACH DETACH TAG -A simple script that will create three shortcuts to copy, attach and detach image tags. + (MULTI-)COPY ATTACH DETACH TAG + A simple script that will create three shortcuts to copy, attach and detach image tags. INSTALATION -* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory -* add the following line in the file $CONFIGDIR/luarc require "copy_attach_detach_tags.lua" + * copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory + * add the following line in the file $CONFIGDIR/luarc require "copy_attach_detach_tags" USAGE -* set the shortcuts for copy, attach and detach in the preferences dialog -* copy will create a list of tags from all selected images -* attaches copied tags to selected images, whereby - darktable internal tags starting with 'darktable|' will not be touched -* detach removes all expect darktable internal tags from selected images + * set the shortcuts for copy, attach and detach in the preferences dialog + * copy will create a list of tags from all selected images + * attaches copied tags to selected images, whereby + darktable internal tags starting with 'darktable|' will not be touched + * detach removes all expect darktable internal tags from selected images ]] @@ -26,10 +39,12 @@ dt.configuration.check_version(...,{2,0,0}) local image_tags = {} local function mcopy_tags() -local sel_images = dt.gui.selection() -local tag_list_tmp = {} -local hash = {} + local sel_images = dt.gui.action_images + local tag_list_tmp = {} + local hash = {} + -- empty tag table before copy new tags + image_tags = {} for _,image in ipairs(sel_images) do local image_tags_tmp = {} image_tags_tmp = dt.tags.get_tags(image) @@ -50,7 +65,7 @@ local hash = {} end end - -- dt.print("Tags copied.") + dt.print("Image tags copied ...") return(image_tags) end @@ -58,10 +73,10 @@ local hash = {} local function attach_tags() if next(image_tags) == nil then - dt.print("No tags copied, please copy tags first.") + dt.print("No tags to attached, please copy tags first.") end - local sel_images = dt.gui.selection() + local sel_images = dt.gui.action_images for _,image in ipairs(sel_images) do local present_image_tags = {} @@ -81,13 +96,14 @@ local function attach_tags() end end end + dt.print("Tags attached ...") end local function detach_tags() - local sel_images = dt.gui.selection() + local sel_images = dt.gui.action_images for _,image in ipairs(sel_images) do local present_image_tags = {} @@ -99,7 +115,8 @@ local function detach_tags() end end end - end + dt.print("Tags removed from image(s).") +end -- shortcut for copy dt.register_event("shortcut", @@ -118,4 +135,4 @@ dt.register_event("shortcut", -- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua --- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; \ No newline at end of file +-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; diff --git a/contrib/cr2hdr.lua b/contrib/cr2hdr.lua new file mode 100644 index 0000000..e6bc214 --- /dev/null +++ b/contrib/cr2hdr.lua @@ -0,0 +1,113 @@ +--[[ + Copyright (C) 2015 Till Theato . + + This program 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. + + This program 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 this program. If not, see . +]] +--[[ +cr2hdr Magic Lantern Dual ISO processing. + +This script automates the steps involved to process an image created +with the Magic Lantern Dual ISO module. Upon invoking the script with a +shortcut "cr2hdr" provided by Magic Lantern is run on the selected +images. The processed files are imported. They are also made group +leaders to hide the original files. + +ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT +* cr2hdr (sources can be obtained through the Magic Lantern repository) + +USAGE +* require this script from your main lua file +* trigger conversion on selected/hovered images by shortcut (set shortcut in settings dialog) +* it is also possible to have the script run after importing a collection (optin, since it is not that fast) +]] + +local darktable = require "darktable" + +-- Tested with darktable 1.6.2 +darktable.configuration.check_version(...,{2,0,2}) + +local queue = {} +local processed_files = {} +local job + +local function file_imported(event, image) + local filename = image.path .. "/" .. image.filename + if processed_files[filename] then + image.make_group_leader(image) + processed_files[filename] = false + else + if darktable.preferences.read("cr2hdr", "onimport", "bool") then + table.insert(queue, image) + end + end +end + +local function stop_conversion(job) + job.valid = false +end + +local function convert_image(image) + if string.sub(image.filename, -3) == "CR2" then + local filename = image.path .. "/" .. image.filename + local result = coroutine.yield("RUN_COMMAND", "cr2hdr " .. filename) + local out_filename = string.gsub(filename, ".CR2", ".DNG") + local file = io.open(out_filename) + if file then + file:close() + processed_files[out_filename] = true + darktable.database.import(out_filename) + else + darktable.print_error(filename .. ": cr2hdr failed.") + end + else + darktable.print_error(image.filename .. " is not a Canon RAW.") + end +end + +local function convert_images() + if next(queue) == nil then return end + + job = darktable.gui.create_job("Dual ISO conversion", true, stop_conversion) + for key,image in pairs(queue) do + if job.valid then + job.percent = (key-1)/#queue + convert_image(image) + else + break + end + end + local success_count = 0 + for _ in pairs(processed_files) do success_count = success_count + 1 end + darktable.print("Dual ISO conversion successful on " .. success_count .. "/" .. #queue .. " images.") + job.valid = false + processed_files = {} + queue = {} +end + +local function film_imported(event, film) + if darktable.preferences.read("cr2hdr", "onimport", "bool") then + convert_images() + end +end + +local function convert_action_images(shortcut) + queue = darktable.gui.action_images + convert_images() +end + +darktable.register_event("shortcut", convert_action_images, "Run cr2hdr (Magic Lantern DualISO converter) on selected images") +darktable.register_event("post-import-image", file_imported) +darktable.register_event("post-import-film", film_imported) + +darktable.preferences.register("cr2hdr", "onimport", "bool", "Invoke on import", "If true then cr2hdr will try to proccess every file during importing. Warning: cr2hdr is quite slow even in figuring out on whether the file is Dual ISO or not.", false) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index c4758fc..fc6a804 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -104,7 +104,7 @@ local function create_kml_file(storage, image_table, extra_data) -- Creates dir if not exsists imageFoldername = "files/" local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername - coroutine.yield("run_command", mkdirCommand) + coroutine.yield("RUN_COMMAND", mkdirCommand) end @@ -122,9 +122,9 @@ local function create_kml_file(storage, image_table, extra_data) local concertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" -- USE coroutine.yield. It does not block the UI - coroutine.yield("run_command", concertToThumbCommand) + coroutine.yield("RUN_COMMAND", concertToThumbCommand) local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" - coroutine.yield("run_command", concertCommand) + coroutine.yield("RUN_COMMAND", concertCommand) local pattern = "[/]?([^/]+)$" filmName = string.match(_.film.path, pattern) @@ -222,7 +222,7 @@ local function create_kml_file(storage, image_table, extra_data) local createKMZCommand = "zip --test --move --junk-paths " createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" " createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" \""..dt.configuration.tmp_dir.."/"..imageFoldername.."\"*" - coroutine.yield("run_command", createKMZCommand) + coroutine.yield("RUN_COMMAND", createKMZCommand) end -- Open the file with the standard programm @@ -234,7 +234,7 @@ local function create_kml_file(storage, image_table, extra_data) else kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMLFilename.."\"" end - coroutine.yield("run_command", kmlFileOpenCommand) + coroutine.yield("RUN_COMMAND", kmlFileOpenCommand) end @@ -253,4 +253,3 @@ dt.preferences.register("kml_export", "CreateKMZ", "bool", "KML export: Create K -- Register dt.register_storage("kml_export", "KML/KMZ Export", nil, create_kml_file) - diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index a66c28a..d5575a2 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -59,9 +59,11 @@ local function playSlideshowMusic(_, old_view, new_view) --dt.print_error(playCommand) coroutine.yield("RUN_COMMAND", playCommand) else - stopCommand = "rhythmbox-client --pause" - --dt.print_error(stopCommand) - coroutine.yield("RUN_COMMAND", stopCommand) + if (old_view.id == "slideshow") then + stopCommand = "rhythmbox-client --pause" + --dt.print_error(stopCommand) + coroutine.yield("RUN_COMMAND", stopCommand) + end end end end diff --git a/contrib/video.lua b/contrib/video.lua index c94ab5e..61d98a1 100644 --- a/contrib/video.lua +++ b/contrib/video.lua @@ -90,14 +90,14 @@ local function create_video(storage, image_table, extra_data) dt.print_error("this is the command: "..command) -- USE coroutine.yield. It does not block the UI - coroutine.yield("run_command", command) + coroutine.yield("RUN_COMMAND", command) dt.print("Video created in "..exportDirectory) if ( dt.preferences.read("video","OpenVideo","bool") == true ) then -- USE coroutine.yield. It does not block the UI local playVideoCommand = "xdg-open "..exportDirectory.."/"..exportFilename - coroutine.yield("run_command", playVideoCommand) + coroutine.yield("RUN_COMMAND", playVideoCommand) end end @@ -115,4 +115,3 @@ dt.preferences.register("video", "Codec", "enum", "Video exort: Codec","Video co -- Register dt.register_storage("video", "Video Export", show_status, create_video) - diff --git a/official/image_path_in_ui.lua b/official/image_path_in_ui.lua new file mode 100644 index 0000000..7026bfb --- /dev/null +++ b/official/image_path_in_ui.lua @@ -0,0 +1,63 @@ +--[[ + This file is part of darktable, + copyright (c) 2014 Jérémy Rosen + + 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 . +]] +--[[ +IMAGE_PATH_IN_UI +Add a widget with the path of the selected images for easy copy/past +Simple shortcuts to have multiple selection bufers + + +USAGE +* require this file from your main lua config file: + +This plugin will add a widget at the bottom of the left column in lighttable mode + + +]] +local dt = require "darktable" +dt.configuration.check_version(...,{2,0,0}) + +local main_label = dt.new_widget("label"){selectable = true} + +local function reset_widget() + local selection = dt.gui.selection() + local result = "" + local array = {} + for _,img in pairs(selection) do + array[img.path] = true + end + for path in pairs(array) do + if result == "" then + result = path + else + result = result.."\n"..path + end + end + main_label.label = result +end + +main_label.reset_callback = reset_widget + +dt.register_lib("image_path_no_ui","Selected Images path",true,false,{ + [dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER",300} + }, main_label + ); + +dt.register_event("mouse-over-image-changed",reset_widget); + + -- +-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua diff --git a/official/import_filter_manager.lua b/official/import_filter_manager.lua new file mode 100644 index 0000000..140b569 --- /dev/null +++ b/official/import_filter_manager.lua @@ -0,0 +1,79 @@ +--[[ + This file is part of darktable, + copyright (c) 2015 Tobias Ellinghaus + + 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 . +]] +--[[ +IMPORT FILTER MANAGER +This script adds a dropdown list with import filters to the import dialog. +Scripts can add new filters by registering them with + darktable.register_import_filter(name, callback) +The callback has type function(event, images), i.e., it is the same as when +directly registering the pre-import event. + + +USAGE +* require this script from your main lua file +* also require some files with import filters, for example import_filters.lua. + it is important to add them AFTER this one! +]] + +local dt = require "darktable" + +local import_filter_list = {} +local n_import_filters = 1 + +-- allow changing the filter from the preferences +dt.preferences.register("import_filter_manager", "active_filter", "string", + "import filter", "the name of the filter used for importing images", "") + + +-- the dropdown to select the active filter from the import dialog +local filter_dropdown = dt.new_widget("combobox") +{ + label = "import filter", + editable = false, + + changed_callback = function(widget) + dt.preferences.write("import_filter_manager", "active_filter", "string", widget.value) + end, + + "" -- the first entry in the list is hard coded to "" so it's possible to have no filter +} +dt.gui.libs.import.register_widget(filter_dropdown) + + +-- this is just a wrapper which calls the active import filter +dt.register_event("pre-import", function(event, images) + local active_filter = dt.preferences.read("import_filter_manager", "active_filter", "string") + if active_filter == "" then return end + local callback = import_filter_list[active_filter] + if callback then callback(event, images) end +end) + + +-- add a new global function to register import filters +dt.register_import_filter = function(name, callback) + local active_filter = dt.preferences.read("import_filter_manager", "active_filter", "string") + dt.print_error("registering import filter `" .. name .. "'") + import_filter_list[name] = callback + n_import_filters = n_import_filters + 1 + filter_dropdown[n_import_filters] = name + if name == active_filter then filter_dropdown.value = n_import_filters end +end + + +-- vim: shiftwidth=2 expandtab tabstop=2 cindent +-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; diff --git a/official/import_filters.lua b/official/import_filters.lua new file mode 100644 index 0000000..5980a72 --- /dev/null +++ b/official/import_filters.lua @@ -0,0 +1,80 @@ +--[[ + This file is part of darktable, + copyright (c) 2015 Tobias Ellinghaus + + 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 . +]] +--[[ +EXAMPLE IMPORT FILTERS +This script goes along with the import filter manager. It adds two filters: +* ignore jpegs: this one does the same as the existing option in the import dialog + and just skips all JPEGs during import. +* prefer raw over jpeg: this one is a bit more elaborate, it ignores JPEGs when there + is also another file with the same basename, otherwise it + allows JPEGs, too. + +USAGE +* require this script from your main lua file AFTER import_filter_manager.lua +]] + +local dt = require "darktable" + +-- we get fed a sorted list of filenames. just setting images to ignore to nil is enough + +-- ignore jpeg +dt.register_import_filter("ignore jpegs", function(event, images) + dt.print_error("ignoring all jpegs") + for i, img in ipairs(images) do + local extension = img:match("[^.]*$"):upper() + if (extension == "JPG") or (extension == "JPEG") then + images[i] = nil + end + end +end) + + +-- ignore jpeg iff another format for the image is found +dt.register_import_filter("prefer raw over jpeg", function(event, images) + dt.print_error("prefering raw over jpeg") + local current_base = "" + local jpg_indices = {} + local other_format_found = false + for i, img in ipairs(images) do + local extension = img:match("[^.]*$"):upper() + local base = img:match("^.*[.]") + + if base ~= current_base then + -- we are done with the base name, act according to what we found out + if other_format_found then + for _, jpg in ipairs(jpg_indices) do + images[jpg] = nil + end + end + current_base = base + other_format_found = false + for k,_ in pairs(jpg_indices) do jpg_indices[k] = nil end + end + + -- remember what we have here to act accordingly after all instances of this base name were checked + if (extension == "JPG") or (extension == "JPEG") then + table.insert(jpg_indices, i) + else + other_format_found = true + end + + end +end) + +-- vim: shiftwidth=2 expandtab tabstop=2 cindent +-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; diff --git a/official/selection_to_pdf.lua b/official/selection_to_pdf.lua new file mode 100644 index 0000000..2930e55 --- /dev/null +++ b/official/selection_to_pdf.lua @@ -0,0 +1,154 @@ +--[[ + This file is part of darktable, + copyright (c) 2015 Jérémy Rosen & 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 file (via Latex) containing all selected images + +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 the pdf file + + +]] +local dt = require "darktable" +dt.configuration.check_version(...,{2,0,0}) + +dt.preferences.register + ("selection_to_pdf","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="Title" +} +local widget = dt.new_widget("box") { + orientation=horizontal, + dt.new_widget("label"){label = "Title:"}, + title_widget +} + +local ending = [[ +\end{document} +]] + +local thumbs_per_line=4; +local width = 1/thumbs_per_line-0.01 + +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 thumbnail(latexfile,i,image,file) + local title + if image.title == "" then + title = image.filename + if image.duplicate_index > 0 then + title = title.."["..image.duplicate_index.."]" + end + + else + title = image.title + end + + -- 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(file, "(.*)(%..*)", "%1") + local ext=string.gsub(file, "(.*)(%..*)", "%2") + my_write(latexfile,"\\begin{minipage}[b]{"..width.."\\textwidth}\n") + my_write(latexfile,"\\includegraphics[width=\\textwidth]{{"..filenoext.."}"..ext.."}\\newline\n") + my_write(latexfile,"\\centering{"..i..": \\verb|"..title.."|}\n") + my_write(latexfile,"\\end{minipage}\\quad\n") +end + +dt.register_storage("export_pdf","Export thumbnails to pdf", + nil, + function(storage,image_table) + local my_title = title_widget.text + if my_title == "" then + my_title = "Title" + end + local preamble = [[ +\documentclass[a4paper,10pt]{article} +\usepackage{graphicx} +\pagestyle{empty} +\parindent0pt +\usepackage{geometry} +\geometry{a4paper,left=5mm,right=5mm, top=5mm, bottom=5mm} +\begin{document} +{\Large\bfseries ]]..my_title..[[} \\ +\bigskip\bigskip +]] + + 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 + thumbnail(latexfile,i,img,file) + if i % thumbs_per_line == 0 then + my_write(latexfile,"\n\\bigskip\n") + end + 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 = coroutine.yield("RUN_COMMAND",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("selection_to_pdf","Open with","string") + command = command.." "..pdffile + local result = coroutine.yield("RUN_COMMAND",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 + for img,file in pairs(image_table) do + os.remove(file) + end + end,nil,nil,widget) + +-- +-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua