218
lib/dtutils.lua
Normal file
218
lib/dtutils.lua
Normal file
@@ -0,0 +1,218 @@
|
||||
local dtutils = {}
|
||||
|
||||
dtutils.libdoc = {
|
||||
Name = [[dtutils]],
|
||||
Synopsis = [[A Darktable lua utilities library]],
|
||||
Usage = [[local du = require "lib/dtutils"]],
|
||||
Description = [[dtutils provides a common library of functions used to build
|
||||
lua scripts. There are also sublibraries that provide more functions.]],
|
||||
Return_Value = [[du - library - the library of functions]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[dtutils.debug(3), dtutils.file(3), dtutils.log(3), dtutils.string(3)]],
|
||||
Reference = [[]],
|
||||
License = [[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 <http://www.gnu.org/licenses/>.]],
|
||||
Copyright = [[Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.
|
||||
Copyright (C) 2016 Tobias Jakobs]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
local log = require "lib/dtutils.log"
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
dtutils.libdoc.functions["split"] = {
|
||||
Name = [[split]],
|
||||
Synopsis = [[split a string on a specified separator]],
|
||||
Usage = [[local du = require "lib/dtutils"
|
||||
|
||||
local result = du.split(str, pat)
|
||||
str - string - the string to split
|
||||
pat - string - the pattern to split on]],
|
||||
Description = [[split separates a string into a table of strings. The strings are separated at each
|
||||
occurrence of the supplied pattern. The pattern may be any pattern as described in the lua docs.
|
||||
Each match of the pattern is consumed and not returned.]],
|
||||
Return_Value = [[result - a table of strings on success, or an empty table on error]],
|
||||
Limitations = [[]],
|
||||
Example = [[split("/a/long/path/name/to/a/file.txt", "/") would return a table like
|
||||
{a, "long", "path", "name", "to", a, "file.txt"}]],
|
||||
See_Also = [[]],
|
||||
Reference = [[http://lua-users.org/wiki/SplitJoin]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils.split(str, pat)
|
||||
local t = {}
|
||||
local fpat = "(.-)" .. pat
|
||||
local last_end = 1
|
||||
local s, e, cap = str:find(fpat, 1)
|
||||
while s do
|
||||
if s ~= 1 or cap ~= "" then
|
||||
table.insert(t,cap)
|
||||
end
|
||||
last_end = e+1
|
||||
s, e, cap = str:find(fpat, last_end)
|
||||
end
|
||||
if last_end <= #str then
|
||||
cap = str:sub(last_end)
|
||||
table.insert(t, cap)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
dtutils.libdoc.functions["join"] = {
|
||||
Name = [[join]],
|
||||
Synopsis = [[join a table of strings with a specified separator]],
|
||||
Usage = [[local du = require "lib/dtutils"
|
||||
|
||||
local result = du.join(tabl, pat)
|
||||
tabl - a table of strings
|
||||
pat - a separator]],
|
||||
Description = [[join assembles a table of strings into a string with the specified pattern
|
||||
in between each string]],
|
||||
Return_Value = [[result - string - the joined string on success, or an empty string on failure]],
|
||||
Limitations = [[]],
|
||||
Example = [[join({a, "long", "path", "name", "to", a, "file.txt"}, " ") would return the string
|
||||
"a long path name to a file.txt"]],
|
||||
See_Also = [[]],
|
||||
Reference = [[http://lua-users.org/wiki/SplitJoin]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils.join(tabl, pat)
|
||||
returnstr = ""
|
||||
for i,str in pairs(tabl) do
|
||||
returnstr = returnstr .. str .. pat
|
||||
end
|
||||
return string.sub(returnstr, 1, -(pat:len() + 1))
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
prequire - a protected lua require
|
||||
|
||||
SYNOPSIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
local result = du.prequire(req_name)
|
||||
req_name - the filename of the lua code to load without the ".lua" filetype
|
||||
|
||||
DESCRIPTION
|
||||
prequire is a protected require that can survive an error in the code being loaded without
|
||||
bringing down the calling routine.
|
||||
|
||||
RETURN VALUE
|
||||
result - the code or true on success, otherwise an error message
|
||||
|
||||
EXAMPLE
|
||||
prequire("lib/dtutils.file") which would load lib/dtutils/file.lua
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions["prequire"] = {
|
||||
Name = [[prequire]],
|
||||
Synopsis = [[a protected lua require]],
|
||||
Usage = [[local du = require "lib/dtutils"
|
||||
|
||||
local status, lib = du.prequire(req_name)
|
||||
req_name - the filename of the lua code to load without the ".lua" filetype]],
|
||||
Description = [[prequire is a protected require that can survive an error in the code being loaded without
|
||||
bringing down the calling routine.]],
|
||||
Return_Value = [[status - boolean - true on success
|
||||
lib - if status is true, then the code, otherwise an error message]],
|
||||
Limitations = [[]],
|
||||
Example = [[local status, lib = prequire("lib/dtutils.file") which would load lib/dtutils/file.lua which
|
||||
would return a status of true and the reference to the library in lib.]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils.prequire(req_name)
|
||||
local status, lib = pcall(require, req_name)
|
||||
if status then
|
||||
log.msg(log.info, "Loaded " .. req_name)
|
||||
else
|
||||
log.msg(log.info, "Error loading " .. req_name)
|
||||
end
|
||||
return status, lib
|
||||
end
|
||||
|
||||
dtutils.libdoc.functions["spairs"] = {
|
||||
Name = [[spairs]],
|
||||
Synopsis = [[an iterator that provides sorted pairs from a table]],
|
||||
Usage = [[local du = require "lib/dtutils"
|
||||
|
||||
for key, value in du.spairs(t, order) do
|
||||
t - table - table of key, value pairs
|
||||
order - function - an optional function to sort the pairs
|
||||
if none is supplied, table.sort() is used]],
|
||||
Description = [[spairs is an iterator that returns key, value pairs from a table in sorted
|
||||
order. The sorting order is the result of table.sort() if no function is
|
||||
supplied, otherwise sorting is done as specified in the function.]],
|
||||
Return_Value = [[]],
|
||||
Limitations = [[]],
|
||||
Example = [[HighScore = { Robin = 8, Jon = 10, Max = 11 }
|
||||
|
||||
-- basic usage, just sort by the keys
|
||||
for k,v in spairs(HighScore) do
|
||||
print(k,v)
|
||||
end
|
||||
--> Jon 10
|
||||
--> Max 11
|
||||
--> Robin 8
|
||||
|
||||
-- this uses an custom sorting function ordering by score descending
|
||||
for k,v in spairs(HighScore, function(t,a,b) return t[b] < t[a] end) do
|
||||
print(k,v)
|
||||
end
|
||||
--> Max 11
|
||||
--> Jon 10
|
||||
--> Robin 8]],
|
||||
See_Also = [[]],
|
||||
Reference = [[Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
-- Sort a table
|
||||
function dtutils.spairs(_table, order) -- Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua
|
||||
-- collect the keys
|
||||
local keys = {}
|
||||
for _key in pairs(_table) do keys[#keys + 1] = _key end
|
||||
|
||||
-- if order function given, sort by it by passing the table and keys a, b,
|
||||
-- otherwise just sort the keys
|
||||
if order then
|
||||
table.sort(keys, function(a,b) return order(_table, a, b) end)
|
||||
else
|
||||
table.sort(keys)
|
||||
end
|
||||
|
||||
-- return the iterator function
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
if keys[i] then
|
||||
return keys[i], _table[keys[i]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return dtutils
|
||||
161
lib/dtutils/debug.lua
Normal file
161
lib/dtutils/debug.lua
Normal file
@@ -0,0 +1,161 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
Copyright (c) 2014 Jérémy Rosen
|
||||
Copyright (c) 2016 Bill Ferguson
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
DEBUG HELPERS
|
||||
A collection of helper functions to help debugging lua scripts.
|
||||
|
||||
require it as
|
||||
|
||||
dhelpers = require "lib/dtutils.debug"
|
||||
|
||||
Each function is documented in its own header
|
||||
|
||||
|
||||
]]
|
||||
|
||||
|
||||
local dt = require "darktable"
|
||||
local io = require "io"
|
||||
local table = require "table"
|
||||
require "darktable.debug"
|
||||
local log = require "lib/dtutils.log"
|
||||
local M = {} -- The actual content of the module
|
||||
|
||||
M.libdoc = {
|
||||
Name = [[dtutils.debug]],
|
||||
Synopsis = [[debugging helpers used in developing darktable lua scripts]],
|
||||
Usage = [[local dd = require "lib/dtutils.debug"]],
|
||||
Description = [[dtutils.debug provides an interface to the darktable debugging routines.]],
|
||||
Return_Value = [[dd - library - the darktable lua debugging helpers]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = log.libdoc.License,
|
||||
Copyright = [[Copyright (c) 2014 Jérémy Rosen
|
||||
Copyright (c) 2016 Bill Ferguson
|
||||
]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
M.libdoc.functions["tracepoint"] = {
|
||||
Name = [[tracepoint]],
|
||||
Synopsis = [[print out a tracepoint and dump the arguments]],
|
||||
Usage = [[local dd = require "lib/dtutils.debug"
|
||||
|
||||
local result = tracepoint(name, ...)
|
||||
name - string - the name of the tracepoint to print out
|
||||
... - arguments - variables to dump the contents of]],
|
||||
Description = [[tracepoint prints its name and dumps its parameters using
|
||||
dt.debug]],
|
||||
Return_Value = [[result - ... - the supplied argument list]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function M.tracepoint(name,...)
|
||||
log.msg(log.always, 4, "***** "..name.." ****")
|
||||
params = {...}
|
||||
log.msg(log.always, 0, dt.debug.dump(params,"parameters"))
|
||||
return ...;
|
||||
end
|
||||
|
||||
M.libdoc.functions["new_tracepoint"] = {
|
||||
Name = [[new_tracepoint]],
|
||||
Synopsis = [[create a function returning a tracepoint]],
|
||||
Usage = [[local dd = require "lib/dtutils.debug"
|
||||
|
||||
local result = new_tracepoint(name, ...)
|
||||
name - string - the name of the tracepoint to print out
|
||||
... - arguments - variables to dump the contents of]],
|
||||
Description = [[A function that returns a tracepoint function with the given name
|
||||
This is mainly used to debug callbacks.]],
|
||||
Return_Value = [[result - function - a function that returns the result of a tracepoint]],
|
||||
Limitations = [[]],
|
||||
Example = [[register_event(event, dd.new_tracepoint("hit callback"))
|
||||
|
||||
will print the following each time the callback is called
|
||||
|
||||
**** hit callback ****
|
||||
<all the callback's parameters dumped>]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function M.new_tracepoint(name)
|
||||
return function(...) return M.tracepoint(name,...) end
|
||||
end
|
||||
|
||||
|
||||
M.libdoc.functions["dprint"] = {
|
||||
Name = [[dprint]],
|
||||
Synopsis = [[pass a variable to dt.debug.dump and print the results to stdout]],
|
||||
Usage = [[local dd = require "lib/dtutils.debug"
|
||||
|
||||
dd.dprint(var)
|
||||
var - variable - any variable that you want to see the contents of]],
|
||||
Description = [[Wrapper around debug.dump, will directly print to stdout,
|
||||
same calling convention]],
|
||||
Return_Value = [[]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function M.dprint(...)
|
||||
log.msg(log.always, 4, dt.debug.dump(...))
|
||||
end
|
||||
|
||||
M.libdoc.functions["terse_dump"] = {
|
||||
Name = [[terse_dump]],
|
||||
Synopsis = [[set dt.debug.known to shorten all image dumps to a single line]],
|
||||
Usage = [[local dd = require "lib/dtutils.debug"
|
||||
|
||||
dd.terse_dump()]],
|
||||
Description = [[terse_dump sets dt.debug.known to shorten all images to a single line.
|
||||
If you don't need to debug the content of images, this will avoid them flooding your logs]],
|
||||
Return_Value = [[]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function M.terse_dump()
|
||||
for _,v in ipairs(dt.database) do
|
||||
dt.debug.known[v] = tostring(v)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
return M
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
394
lib/dtutils/file.lua
Normal file
394
lib/dtutils/file.lua
Normal file
@@ -0,0 +1,394 @@
|
||||
local dtutils_file = {}
|
||||
local dt = require "darktable"
|
||||
|
||||
local log = require "lib/dtutils.log"
|
||||
|
||||
dtutils_file.libdoc = {
|
||||
Name = [[dtutils.file]],
|
||||
Synopsis = [[common darktable lua file functions]],
|
||||
Usage = [[local df = require "lib/dtutils.file"]],
|
||||
Description = [[[dtutils.file provides common file manipulation functions used in
|
||||
constructing Darktable lua scripts]],
|
||||
Return_Value = [[df - library - the file functions]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = log.libdoc.License,
|
||||
Copyright = [[Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.]],
|
||||
Copyright = [[Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.
|
||||
Copyright (C) 2016 Tobias Jakobs]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("dtutils.file",dt.configuration.config_dir.."/lua/locale/")
|
||||
|
||||
local function _(msgid)
|
||||
return gettext.dgettext("dtutils.file", msgid)
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["check_if_bin_exists"] = {
|
||||
Name = [[check_if_bin_exists]],
|
||||
Synopsis = [[check if an executable is in the path]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.check_if_bin_exists(bin)
|
||||
bin - string - the binary to check for]],
|
||||
Description = [[check_if_bin_exists checks to see if the specified binary executable is
|
||||
in the path.]],
|
||||
Return_Value = [[result - boolean - true if the executable was found, false if not]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.check_if_bin_exists(bin)
|
||||
local result = os.execute("which " .. bin)
|
||||
if not result then
|
||||
result = false
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["split_filepath"] = {
|
||||
Name = [[split_filepath]],
|
||||
Synopsis = [[split a filepath into parts]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.split_filepath(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[split_filepath splits a filepath into the path, filename, basename and filetype and puts
|
||||
that in a table]],
|
||||
Return_Value = [[result - table - a table containing the path, filename, basename, and filetype]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.split_filepath(str)
|
||||
-- strip out single quotes from quoted pathnames
|
||||
str = string.gsub(str, "'", "")
|
||||
local result = {}
|
||||
-- Thank you Tobias Jakobs for the awesome regular expression, which I tweaked a little
|
||||
result["path"], result["filename"], result["basename"], result["filetype"] = string.match(str, "(.-)(([^\\/]-)%.?([^%.\\/]*))$")
|
||||
return result
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["get_path"] = {
|
||||
Name = [[get_path]],
|
||||
Synopsis = [[get the path from a file path]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_path(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[get_path strips the filename and filetype from a path and returns the path]],
|
||||
Return_Value = [[result - string - the path]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.get_path(str)
|
||||
local parts = dtutils_file.split_filepath(str)
|
||||
return parts["path"]
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["get_filename"] = {
|
||||
Name = [[get_filename]],
|
||||
Synopsis = [[get the filename and extension from a file path]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_filename(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[get_filename strips the path from a filepath and returns the filename]],
|
||||
Return_Value = [[result - string - the file name and type]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.get_filename(str)
|
||||
local parts = dtutils_file.split_filepath(str)
|
||||
return parts["filename"]
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["get_basename"] = {
|
||||
Name = [[get_basename]],
|
||||
Synopsis = [[get the filename without the path or extension]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_basename(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[get_basename returns the name of the file without the path or filetype
|
||||
]],
|
||||
Return_Value = [[result - string - the basename of the file]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.get_basename(str)
|
||||
local parts = dtutils_file.split_filepath(str)
|
||||
return parts["basename"]
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["get_filetype"] = {
|
||||
Name = [[get_filetype]],
|
||||
Synopsis = [[get the filetype from a filename]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_filetype(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[get_filetype returns the filetype from the supplied filepath]],
|
||||
Return_Value = [[result - string - the filetype]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.get_filetype(str)
|
||||
local parts = dtutils_file.split_filepath(str)
|
||||
return parts["filetype"]
|
||||
end
|
||||
|
||||
|
||||
-- Thanks Tobias Jakobs for the idea
|
||||
dtutils_file.libdoc.functions["check_if_file_exists"] = {
|
||||
Name = [[check_if_file_exists]],
|
||||
Synopsis = [[check if a file or path exist]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.check_if_file_exists(filepath)
|
||||
filepath - string - a file or path to check]],
|
||||
Description = [[check_if_file_exists checks to see if a file or path exists]],
|
||||
Return_Value = [[result - boolean - true if the file or path exists, false if it doesn't]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.check_if_file_exists(filepath)
|
||||
local result = os.execute("test -e " .. filepath)
|
||||
if not result then
|
||||
result = false
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["chop_filetype"] = {
|
||||
Name = [[chop_filetype]],
|
||||
Synopsis = [[remove a filetype from a filename]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.chop_filetype(path)
|
||||
path - string - a filename with or without a path]],
|
||||
Description = [[chop_filetype removes the filetype from the filename]],
|
||||
Return_Value = [[result - string - the path and filename without the filetype]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.chop_filetype(path)
|
||||
local length = dtutils_file.get_filetype(path):len() + 2
|
||||
return string.sub(path, 1, -length)
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["file_copy"] = {
|
||||
Name = [[file_copy]],
|
||||
Synopsis = [[copy a file to another name/location]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.file_copy(fromFile, toFile)
|
||||
fromFile - string - name of file to copy from
|
||||
toFile - string - name of file to copy to]],
|
||||
Description = [[copy a file using a succession of methods from operating system
|
||||
to a pure lua solution]],
|
||||
Return_Value = [[result - boolean - nil on error, true on success]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.file_copy(fromFile, toFile)
|
||||
local result = nil
|
||||
-- if cp exists, use it
|
||||
if dtutils_file.check_if_bin_exists("cp") then
|
||||
result = os.execute("cp '" .. fromFile .. "' '" .. toFile .. "'")
|
||||
end
|
||||
-- if cp was not present, or if cp failed, then a pure lua solution
|
||||
if not result then
|
||||
local fileIn, err = io.open(fromFile, 'rb')
|
||||
if fileIn then
|
||||
local fileOut, errr = io.open(toFile, 'w')
|
||||
if fileOut then
|
||||
local content = fileIn:read(4096)
|
||||
while content do
|
||||
fileOut:write(content)
|
||||
content = fileIn:read(4096)
|
||||
end
|
||||
result = true
|
||||
fileIn:close()
|
||||
fileOut:close()
|
||||
else
|
||||
log.msg(log.error, errr)
|
||||
end
|
||||
else
|
||||
log.msg(log.error, err)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["file_move"] = {
|
||||
Name = [[file_move]],
|
||||
Synopsis = [[move a file from one directory to another]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.file_move(fromFile, toFile)
|
||||
fromFile - string - name of the original file
|
||||
toFile - string - the new file location and name]],
|
||||
Description = [[Move a file from one place to another. Try a succession of methods from
|
||||
builtin to operating system to a pure lua solution.]],
|
||||
Return_Value = [[result - boolean - nil on error, some value on success]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.file_move(fromFile, toFile)
|
||||
local success = os.rename(fromFile, toFile)
|
||||
if not success then
|
||||
-- an error occurred, so let's try using the operating system function
|
||||
if dtutils_file.check_if_bin_exists("mv") then
|
||||
success = os.execute("mv '" .. fromFile .. "' '" .. toFile .. "'")
|
||||
end
|
||||
-- if the mv didn't exist or succeed, then...
|
||||
if not success then
|
||||
-- pure lua solution
|
||||
success = dtutils_file.file_copy(fromFile, toFile)
|
||||
if success then
|
||||
os.remove(fromFile)
|
||||
else
|
||||
log.msg(log.error, "Unable to move " .. fromFile .. " to " .. toFile .. ". Leaving " .. fromFile .. " in place.")
|
||||
end
|
||||
end
|
||||
end
|
||||
return success -- nil on error, some value if success
|
||||
end
|
||||
|
||||
dtutils_file.libdoc.functions["filename_increment"] = {
|
||||
Name = [[filename_increment]],
|
||||
Synopsis = [[add a two digit increment to a filename]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.filename_increment(filepath)
|
||||
filepath - string - filename to increment]],
|
||||
Description = [[filename_increment solves the problem of filename confllict by adding an
|
||||
increment to the filename. If the supplied filename has no increment then
|
||||
"01" is added to the basename. If the filename already has an increment, then
|
||||
1 is added to it and the filename returned.]],
|
||||
Return_Value = [[result - string - the incremented filename]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.filename_increment(filepath)
|
||||
|
||||
-- break up the filepath into parts
|
||||
local path = dtutils_file.get_path(filepath)
|
||||
local basename = dtutils_file.get_basename(filepath)
|
||||
local filetype = dtutils_file.get_filetype(filepath)
|
||||
|
||||
-- check to see if we've incremented before
|
||||
local increment = string.match(basename, "_(%d-)$")
|
||||
|
||||
if increment then
|
||||
-- we do 2 digit increments so make sure we didn't grab part of the filename
|
||||
if string.len(increment) > 2 then
|
||||
-- we got the filename so set the increment to 01
|
||||
increment = "01"
|
||||
else
|
||||
increment = string.format("%02d", tonumber(increment) + 1)
|
||||
basename = string.gsub(basename, "_(%d-)$", "")
|
||||
end
|
||||
else
|
||||
increment = "01"
|
||||
end
|
||||
local incremented_filepath = path .. basename .. "_" .. increment .. "." .. filetype
|
||||
|
||||
return incremented_filepath
|
||||
end
|
||||
|
||||
|
||||
dtutils_file.libdoc.functions["create_unique_filename"] = {
|
||||
Name = [[create_unique_filename]],
|
||||
Synopsis = [[create a unique filename from the supplied argment]],
|
||||
Usage = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.create_unique_filename(filepath)
|
||||
filepath - string - the path and filename requested]],
|
||||
Description = [[create_unique_filename takes a requested filepath and checks to see if
|
||||
it exists. If if doesn't then it's returned intact. If it already exists, then a two
|
||||
digit increment is added to the filename and it is tested again. The increment keeps
|
||||
increasing until either a unique filename is found or there have been 100 attempts.]],
|
||||
Return_Value = [[result - string - the incremented filename]],
|
||||
Limitations = [[create_unique_filename will only attempt 100 increments.]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_file.create_unique_filename(filepath)
|
||||
while dtutils_file.check_if_file_exists(filepath) do
|
||||
filepath = dtutils_file.filename_increment(filepath)
|
||||
-- limit to 99 more exports of the original export
|
||||
if string.match(dtfileutils.get_basename(filepath), "_(d-)$") == "99" then
|
||||
break
|
||||
end
|
||||
end
|
||||
return filepath
|
||||
end
|
||||
|
||||
return dtutils_file
|
||||
291
lib/dtutils/log.lua
Normal file
291
lib/dtutils/log.lua
Normal file
@@ -0,0 +1,291 @@
|
||||
|
||||
local dtutils_log = {}
|
||||
|
||||
dtutils_log.libdoc = {
|
||||
Name = [[dtutils.log]],
|
||||
Synopsis = [[darktable lua logging library]],
|
||||
Usage = [[local log = require "lib/dtutils.log"]],
|
||||
Description = [[log provides a multi-level logging solution for use with
|
||||
the darktable lua scripts. With this library you can leave log messages
|
||||
scattered through out your code and only turn them on as necessary.]],
|
||||
Return_Value = [[log - library - the darktable lua logging functions]],
|
||||
Limitations = [[]],
|
||||
Example = [[local log = require "lib/dtutils.log"
|
||||
|
||||
local cur_level = log.log_level()
|
||||
log.log_level(log.warn)
|
||||
|
||||
print out warning, error and success messages as code is running
|
||||
|
||||
log.log_level(debug)
|
||||
|
||||
print out debugging messages too because this isnt working
|
||||
|
||||
log.log_level(info)
|
||||
|
||||
I want to make sure this is working ok
|
||||
|
||||
log.log_level(cur_level)
|
||||
|
||||
reset the logging level back to normal]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[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 <http://www.gnu.org/licenses/>.]],
|
||||
Copyright = [[Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
local dt = require "darktable"
|
||||
local dt_print_error = dt.print_error
|
||||
-- work around until dt.print_log()
|
||||
local dt_print_log = dt.print_error
|
||||
local dt_print = dt.print
|
||||
|
||||
-- set the default log levels
|
||||
|
||||
dtutils_log.debug = {
|
||||
label = "DEBUG:",
|
||||
enabled = false,
|
||||
engine = dt_print_log,
|
||||
level = 1,
|
||||
}
|
||||
dtutils_log.info = {
|
||||
label = "INFO:",
|
||||
enable = false,
|
||||
engine = dt_print_log,
|
||||
level = 2,
|
||||
}
|
||||
dtutils_log.warn = {
|
||||
label = "WARN:",
|
||||
enabled = false,
|
||||
engine = dt_print_log,
|
||||
level = 3,
|
||||
}
|
||||
dtutils_log.error = {
|
||||
label = "ERROR:",
|
||||
enabled = true,
|
||||
engine = dt_print_error,
|
||||
level = 4,
|
||||
}
|
||||
dtutils_log.success = {
|
||||
label = "SUCCESS:",
|
||||
enabled = true,
|
||||
engine = dt_print_log,
|
||||
level = 5,
|
||||
}
|
||||
dtutils_log.screen = {
|
||||
label = "",
|
||||
enabled = true,
|
||||
engine = dt_print,
|
||||
level = 9,
|
||||
}
|
||||
dtutils_log.always = {
|
||||
label = "",
|
||||
enabled = true,
|
||||
engine = dt_print_log,
|
||||
level = 9,
|
||||
}
|
||||
dtutils_log.critical = {
|
||||
label = "CRITICAL:",
|
||||
enabled = true,
|
||||
engine = print,
|
||||
level = 9,
|
||||
}
|
||||
|
||||
dtutils_log.libdoc.functions["caller"] = {
|
||||
Name = [[caller]],
|
||||
Synopsis = [[get the name and line number of the calling routine]],
|
||||
Usage = [[local log = require "lib/dtutils.log"
|
||||
|
||||
result = log.caller(level)
|
||||
level - number - the number of stack levels to go down to retrieve the caller routine information]],
|
||||
Description = [[caller gets the name and line number of the calling routine and returns it]],
|
||||
Return_Value = [[result - string - the name and line number of the calling function or 'callback: ' if the attempt to get the
|
||||
caller returns nil]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_log.caller(level)
|
||||
local name = debug.getinfo(level).name
|
||||
local lineno = nil
|
||||
local source = nil
|
||||
if name then
|
||||
lineno = debug.getinfo(level).currentline
|
||||
-- returns the path to the file prefixed with @
|
||||
source = debug.getinfo(level).source
|
||||
-- we just need the filename, so grab it from the string
|
||||
-- Thanks, Tobias Jakobs :-)
|
||||
source = string.match(source, "@.-([^\\/]-%.?[^%.\\/]*)$")
|
||||
return name .. ": " .. source .. ": " .. lineno .. ":"
|
||||
else
|
||||
return "callback:"
|
||||
end
|
||||
end
|
||||
|
||||
dtutils_log.libdoc.functions["msg"] = {
|
||||
Name = [[msg]],
|
||||
Synopsis = [[print a log message]],
|
||||
Usage = [[local log = require "lib/log"
|
||||
|
||||
log.msg(level, ...)
|
||||
level - table - the type of message, one of:
|
||||
log.debug - debugging messages
|
||||
log.info - informational messages
|
||||
log.warn - warning messages
|
||||
log.error - error messages
|
||||
log.success - success messages
|
||||
log.always - an internal message for debugging
|
||||
log.screen - output 1 line of text to the screen
|
||||
log.critical - print a critical message to the console
|
||||
|
||||
... - string(s) - the message to print, which could be a comma separated set of strings]],
|
||||
Description = [[msg checks the level to see if it is enabled, then prints the level type and message if it is.
|
||||
Messages are output using the engine configured in each log level.]],
|
||||
Return_Value = [[]],
|
||||
Limitations = [[If you use log.msg in a callback, the name of the calling routine can't be determined. A solution
|
||||
is to include some means of reference such as the name of the callback as an argument, i.e.
|
||||
|
||||
log.msg(log.debug, "libPlugin.format_combobox:", "value is " .. self.value)
|
||||
|
||||
which would result in
|
||||
|
||||
DEBUG: callback: libPlugin.format_combobox: value is JPEG]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_log.msg(level, ...)
|
||||
if level.enabled then
|
||||
local args = {...}
|
||||
local call_level = 3
|
||||
if level == dtutils_log.always then
|
||||
call_level = args[1]
|
||||
table.remove(args, 1)
|
||||
end
|
||||
local log_msg = level.label
|
||||
if level.engine ~= dt_screen and call_level ~= 0 then
|
||||
log_msg = log_msg .. dtutils_log.caller(call_level) .. " "
|
||||
elseif log_msg:len() > 2 then
|
||||
log_msg = log_msg .. " "
|
||||
end
|
||||
for i = 1,#args do
|
||||
log_msg = log_msg .. tostring(args[i]) .. " "
|
||||
end
|
||||
level.engine(log_msg)
|
||||
end
|
||||
end
|
||||
|
||||
dtutils_log.libdoc.functions["log_level"] = {
|
||||
Name = [[log_level]],
|
||||
Synopsis = [[get or set the log level]],
|
||||
Usage = [[local log = require "lib/log"
|
||||
|
||||
local result = log.log_level(...)
|
||||
... - arguments - if none is supplied, then the current log level is returned as one of:
|
||||
log.debug, log.info, log.warn, log.error, log.success. If one of log.debug, log.info, log.warn,
|
||||
log.error, or log.success is supplied as the argument then the log level is set to that value. All
|
||||
log levels greater than or equal in value will be enabled. Any levels of lesser value will be disabled.]],
|
||||
Description = [[log_level gets and sets the logging level. When called with no arguments the current log level
|
||||
is returned as one of log.debug, log.info, log.warn, log.error, or log.success. When called with one of log.debug,
|
||||
log.info, log.warn, log.error or log.success then the log level is set. When setting the log level all levels
|
||||
equal or greater are enabled and any of lesser value are disabled. See the example.]],
|
||||
Return_Value = [[result - the log level, one of log.debug, log.info, log.warn, log.error or log.success]],
|
||||
Limitations = [[]],
|
||||
Example = [[Assume that the current log level is log.error. Calling log.log_level() will return log.error.
|
||||
Calling log.log_level(log.info) will leave log.debug disabled, and enable log.info, log.warn, log.error and
|
||||
log.success. log.info will be returned as the log_level.]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_log.log_level(...)
|
||||
local levels = {"debug", "info", "warn", "error", "success"}
|
||||
local args = {...}
|
||||
local log_level = nil
|
||||
if #args > 0 then
|
||||
log_level = args[1]
|
||||
if log_level == dtutils_log.critical or
|
||||
log_level == dtutils_log.screen or
|
||||
log_level == dtutils_log.always then
|
||||
-- these aren't valid for setting levels
|
||||
return nil
|
||||
else
|
||||
for _,v in ipairs(levels) do
|
||||
if dtutils_log[v].level >= log_level.level then
|
||||
dtutils_log[v].enabled = true
|
||||
else
|
||||
dtutils_log[v].enabled = false
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for _,v in ipairs(levels) do
|
||||
if dtutils_log[v].enabled == true then
|
||||
log_level = dtutils_log[v]
|
||||
end
|
||||
end
|
||||
end
|
||||
return log_level
|
||||
end
|
||||
|
||||
dtutils_log.libdoc.functions["engine"] = {
|
||||
Name = [[engine]],
|
||||
Synopsis = [[get and set the output engine]],
|
||||
Usage = [[local log = require "lib/dtutils.log"
|
||||
|
||||
result = log.engine(level, ...)
|
||||
level - table - the log level to get or set the engine for, one of log.debug, log.info, log.warn, log.error
|
||||
log.success, log.always, log.screen, log.critical
|
||||
... - function - the output function, one of dt.print, dt.print_error, dt.print_log, print
|
||||
if not function is included, the current engine is returned for the specified log level]],
|
||||
Description = [[engine returns the output engine for the specified log level if a second argument is not
|
||||
supplied. If a function is supplied as the second argment, then the output engine for the specified log level
|
||||
is set to that.]],
|
||||
Return_Value = [[result - function - the current output engine]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_log.print_engine(level, ...)
|
||||
local engines = {"dt_print", "dt_print_error", "dt_print_log", "print"}
|
||||
local args = {...}
|
||||
local cur_engine = ""
|
||||
if #args == 0 then
|
||||
cur_engine = level.engine
|
||||
else
|
||||
for _,v in ipairs(engines) do
|
||||
if args[1] == v then
|
||||
level.engine = args[1]
|
||||
cur_engine = level.engine
|
||||
end
|
||||
end
|
||||
end
|
||||
return cur_engine
|
||||
end
|
||||
|
||||
return dtutils_log
|
||||
173
lib/dtutils/string.lua
Normal file
173
lib/dtutils/string.lua
Normal file
@@ -0,0 +1,173 @@
|
||||
local dtutils_string = {}
|
||||
dtutils_string.libdoc = {
|
||||
Name = [[dtutils.string]],
|
||||
Synopsis = [[a library of string utilities for use in darktable lua scripts]],
|
||||
Usage = [[local ds = require "lib/dtutils.string"]],
|
||||
Description = [[This library contains string manipulation routines to aid in building
|
||||
darktable lua scripts.]],
|
||||
Return_Value = [[du - library - the darktable lua string library]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[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 <http://www.gnu.org/licenses/>.]],
|
||||
Copyright = [[Copyright (c) 2016 Bill Ferguson <wpferguson@gmail.com>]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
dtutils_string.libdoc.functions["strip_accents"] = {
|
||||
Name = [[strip_accents]],
|
||||
Synopsis = [[strip accents from characters]],
|
||||
Usage = [[local ds = require "lib/dtutils.string"
|
||||
|
||||
local result = ds.strip_accents(str)
|
||||
str - string - the string with characters that need accents removed]],
|
||||
Description = [[strip_accents removes accents from accented characters returning the
|
||||
unaccented character.]],
|
||||
Return_Value = [[result - string - the string containing unaccented characters]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[Copied from https://forums.coronalabs.com/topic/43048-remove-special-characters-from-string/]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_string.strip_accents( str )
|
||||
local tableAccents = {}
|
||||
tableAccents["à"] = "a"
|
||||
tableAccents["á"] = "a"
|
||||
tableAccents["â"] = "a"
|
||||
tableAccents["ã"] = "a"
|
||||
tableAccents["ä"] = "a"
|
||||
tableAccents["ç"] = "c"
|
||||
tableAccents["è"] = "e"
|
||||
tableAccents["é"] = "e"
|
||||
tableAccents["ê"] = "e"
|
||||
tableAccents["ë"] = "e"
|
||||
tableAccents["ì"] = "i"
|
||||
tableAccents["í"] = "i"
|
||||
tableAccents["î"] = "i"
|
||||
tableAccents["ï"] = "i"
|
||||
tableAccents["ñ"] = "n"
|
||||
tableAccents["ò"] = "o"
|
||||
tableAccents["ó"] = "o"
|
||||
tableAccents["ô"] = "o"
|
||||
tableAccents["õ"] = "o"
|
||||
tableAccents["ö"] = "o"
|
||||
tableAccents["ù"] = "u"
|
||||
tableAccents["ú"] = "u"
|
||||
tableAccents["û"] = "u"
|
||||
tableAccents["ü"] = "u"
|
||||
tableAccents["ý"] = "y"
|
||||
tableAccents["ÿ"] = "y"
|
||||
tableAccents["À"] = "A"
|
||||
tableAccents["Á"] = "A"
|
||||
tableAccents["Â"] = "A"
|
||||
tableAccents["Ã"] = "A"
|
||||
tableAccents["Ä"] = "A"
|
||||
tableAccents["Ç"] = "C"
|
||||
tableAccents["È"] = "E"
|
||||
tableAccents["É"] = "E"
|
||||
tableAccents["Ê"] = "E"
|
||||
tableAccents["Ë"] = "E"
|
||||
tableAccents["Ì"] = "I"
|
||||
tableAccents["Í"] = "I"
|
||||
tableAccents["Î"] = "I"
|
||||
tableAccents["Ï"] = "I"
|
||||
tableAccents["Ñ"] = "N"
|
||||
tableAccents["Ò"] = "O"
|
||||
tableAccents["Ó"] = "O"
|
||||
tableAccents["Ô"] = "O"
|
||||
tableAccents["Õ"] = "O"
|
||||
tableAccents["Ö"] = "O"
|
||||
tableAccents["Ù"] = "U"
|
||||
tableAccents["Ú"] = "U"
|
||||
tableAccents["Û"] = "U"
|
||||
tableAccents["Ü"] = "U"
|
||||
tableAccents["Ý"] = "Y"
|
||||
|
||||
local normalizedString = ""
|
||||
|
||||
for strChar in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do
|
||||
if tableAccents[strChar] ~= nil then
|
||||
normalizedString = normalizedString..tableAccents[strChar]
|
||||
else
|
||||
normalizedString = normalizedString..strChar
|
||||
end
|
||||
end
|
||||
|
||||
return normalizedString
|
||||
|
||||
end
|
||||
|
||||
dtutils_string.libdoc.functions["escape_xml_characters"] = {
|
||||
Name = [[escape_xml_characters]],
|
||||
Synopsis = [[escape characters for xml documents]],
|
||||
Usage = [[local ds = require "lib/dtutils.string"
|
||||
|
||||
local result = ds.escape_xml_characters(str)
|
||||
str - string - the string that needs escaped]],
|
||||
Description = [[escape_xml_characters provides the escape sequences for
|
||||
"&", '"', "'", "<", and ">" with the corresponding "&",
|
||||
""", "'", "<", and ">".]],
|
||||
Return_Value = [[result - string - the string containing escapes for the xml characters]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
-- Keep & first, otherwise it will double escape other characters
|
||||
function dtutils_string.escape_xml_characters( str )
|
||||
|
||||
str = string.gsub(str,"&", "&")
|
||||
str = string.gsub(str,"\"", """)
|
||||
str = string.gsub(str,"'", "'")
|
||||
str = string.gsub(str,"<", "<")
|
||||
str = string.gsub(str,">", ">")
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
dtutils_string.libdoc.functions["urlencode"] = {
|
||||
Name = [[urlencode]],
|
||||
Synopsis = [[encode a string in a websage manner]],
|
||||
Usage = [[local ds = require "lib/dtutils.string"
|
||||
|
||||
local result = ds.urlencode(str)
|
||||
str - string - the string that needs to be made websafe]],
|
||||
Description = [[urlencode converts a string into a websafe version suitable for
|
||||
use in a web browser.]],
|
||||
Return_Value = [[result - string - a websafe string]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[https://forums.coronalabs.com/topic/43048-remove-special-characters-from-string/]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_string.urlencode(str)
|
||||
if (str) then
|
||||
str = string.gsub (str, "\n", "\r\n")
|
||||
str = string.gsub (str, "([^%w ])", function () return string.format ("%%%02X", string.byte()) end)
|
||||
str = string.gsub (str, " ", "+")
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
return dtutils_string
|
||||
@@ -1,93 +0,0 @@
|
||||
--[[
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
DEBUG HELPERS
|
||||
A collection of helper functions to help debugging lua scripts.
|
||||
|
||||
require it as
|
||||
|
||||
dhelpers = require "official/debug-helpers"
|
||||
|
||||
Each function is documented in its own header
|
||||
|
||||
|
||||
]]
|
||||
|
||||
|
||||
local dt = require "darktable"
|
||||
local io = require "io"
|
||||
local table = require "table"
|
||||
require "darktable.debug"
|
||||
local M = {} -- The actual content of the module
|
||||
|
||||
--[[
|
||||
A function which prints its name and its parameters
|
||||
* name : the name of the tracepoint
|
||||
* ... : anything, will be dumped using dt.debug
|
||||
]]
|
||||
function M.tracepoint(name,...)
|
||||
print("***** "..name.." ****")
|
||||
params = {...}
|
||||
print(dt.debug.dump(params,"parameters"))
|
||||
return ...;
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
A function that returns a tracepoint function with the given name
|
||||
This is mainly used to debug callbacks,
|
||||
|
||||
register_event(event, dhelpers.new_tracepoint("hit callback"))
|
||||
|
||||
will print the following each time the callback is called
|
||||
|
||||
**** hit callback ****
|
||||
<all the callback's parameters dumped>
|
||||
|
||||
]]
|
||||
function M.new_tracepoint(name)
|
||||
return function(...) return M.tracepoint(name,...) end
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Wrapper around debug.dump, will directly print to stdout,
|
||||
same calling covention
|
||||
]]
|
||||
|
||||
function M.dprint(...)
|
||||
print(dt.debug.dump(...))
|
||||
end
|
||||
|
||||
--[[
|
||||
sets dt.debug.known to shorten all images to a single line
|
||||
|
||||
if you don't need to debug the content of images, this will avoid them flooding your logs
|
||||
]]
|
||||
function M.terse_dump()
|
||||
for _,v in ipairs(dt.database) do
|
||||
dt.debug.known[v] = tostring(v)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
return M
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
76
tools/get_lib_manpages.lua
Normal file
76
tools/get_lib_manpages.lua
Normal file
@@ -0,0 +1,76 @@
|
||||
--[[
|
||||
get_lib_manpages.lua - retrieve the included library documentation and output it as man pages
|
||||
|
||||
Copyright (c) 2016, Bill Ferguson
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local log = require "lib/dtutils.log"
|
||||
local libname = nil
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
local keys = {"Name", "Synopsis", "Usage", "Description", "Return_Value", "Limitations",
|
||||
"Example", "See_Also", "Reference", "License", "Copyright"}
|
||||
|
||||
local function output_man(d)
|
||||
local name = d["Name"]
|
||||
if not libname then
|
||||
libname = name
|
||||
end
|
||||
local fname = "/tmp/" .. name .. ".3"
|
||||
local mf = io.open(fname, "w")
|
||||
if mf then
|
||||
mf:write(".TH " .. string.upper(name) .. " 3 \"\" \"\" \"Darktable " .. libname .. " functions\"\n")
|
||||
for _,section in ipairs(keys) do
|
||||
if d[section]:len() > 0 then
|
||||
mf:write(".SH " .. string.upper(string.gsub(section, "_", " ")) .. "\n")
|
||||
mf:write(d[section] .. "\n")
|
||||
end
|
||||
end
|
||||
mf:close()
|
||||
if df.check_if_bin_exists("groff") then
|
||||
if df.check_if_bin_exists("ps2pdf") then
|
||||
os.execute("groff -man " .. fname .. " | ps2pdf - " .. fname .. ".pdf")
|
||||
else
|
||||
log.msg(log.error, "Missing ps2pdf. Can't generate pdf man pages.")
|
||||
end
|
||||
else
|
||||
log.msg(log.error, "Missing groff. Can't generate pdf man pages.")
|
||||
end
|
||||
else
|
||||
log.msg(log.error, "Can't open file " .. fname .. "for writing")
|
||||
end
|
||||
end
|
||||
|
||||
-- find the libraries
|
||||
|
||||
local output = io.popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort")
|
||||
|
||||
-- loop through the libraries
|
||||
|
||||
for line in output:lines() do
|
||||
line = string.gsub(line, "/", ".")
|
||||
local lib_name = line:sub(3,-5)
|
||||
if lib_name:len() > 2 then
|
||||
lib_name = "lib/" .. lib_name
|
||||
local lib = require(lib_name)
|
||||
|
||||
-- print the documentation for the library
|
||||
if lib.libdoc then
|
||||
local doc = lib.libdoc
|
||||
if doc then
|
||||
output_man(doc)
|
||||
for _,fdoc in pairs(doc.functions) do
|
||||
|
||||
-- print the documentation for each of the functions
|
||||
output_man(fdoc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
libname = nil
|
||||
end
|
||||
|
||||
49
tools/get_libdoc.lua
Normal file
49
tools/get_libdoc.lua
Normal file
@@ -0,0 +1,49 @@
|
||||
--[[
|
||||
get_libdoc.lua - retrieve the included library documentation and output it
|
||||
|
||||
Copyright (c) 2016, Bill Ferguson
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
local keys = {"Name", "Synopsis", "Usage", "Description", "Return_Value", "Limitations",
|
||||
"Example", "See_Also", "Reference", "License", "Copyright"}
|
||||
|
||||
local function output_doc(d)
|
||||
for _,section in ipairs(keys) do
|
||||
if d[section]:len() > 0 then
|
||||
print(string.upper(string.gsub(section, "_", " ")))
|
||||
print("\t" .. d[section] .. "\n")
|
||||
end
|
||||
end
|
||||
print("\f")
|
||||
end
|
||||
|
||||
-- find the libraries
|
||||
|
||||
local output = io.popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort")
|
||||
|
||||
-- loop through the libraries
|
||||
|
||||
for line in output:lines() do
|
||||
line = string.gsub(line, "/", ".")
|
||||
local lib_name = line:sub(3,-5)
|
||||
if lib_name:len() > 2 then
|
||||
lib_name = "lib/" .. lib_name
|
||||
local lib = require(lib_name)
|
||||
|
||||
-- print the documentation for the library
|
||||
if lib.libdoc then
|
||||
local doc = lib.libdoc
|
||||
output_doc(doc)
|
||||
for _,fdoc in pairs(doc.functions) do
|
||||
|
||||
-- print the documentation for each of the functions
|
||||
output_doc(fdoc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user