-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathdocument_rename_pdfs.lua
204 lines (170 loc) · 7.1 KB
/
document_rename_pdfs.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
function plugindef()
finaleplugin.RequireScore = false
finaleplugin.RequireSelection = false
finaleplugin.RequireDocument = true
finaleplugin.Author = "Aaron Sherber"
finaleplugin.AuthorURL = "https://aaron.sherber.com"
finaleplugin.Copyright = "CC0 https://creativecommons.org/publicdomain/zero/1.0/"
finaleplugin.Version = "1.0.1"
finaleplugin.Date = "2023-02-26"
finaleplugin.Id = "d9282b18-12ed-488a-b0e2-011a1ba7d5b4"
finaleplugin.RevisionNotes = [[
v1.0.1 First public release
]]
finaleplugin.Notes = [[
The main goal of this script is to emulate the tokens that Sibelius allows when exporting PDFs.
Using this script, you can change the names of your PDFs, after they have been created,
to include any combination of the score filename, score title, part name, part number,
total number of parts, current date, and current time.
A simple use of the script would be to prepend the part number so that your PDFs can be sorted in
the order they appear in the "Manage Parts" dialog.
The script will also fix filename artifacts that result from certain Finale versions and
PDF drivers – for example, an extra "x" after the score filename or a truncated filename
if the part names contains a "/".
The script assumes that PDFs currently have the default names assigned by Finale – generally,
"[score filename] - [part name].pdf".
]]
return "Rename PDFs...", "", "Renames all PDFs for the current document"
end
local mixin = require("library.mixin")
local configuration = require("library.configuration")
local library = require("library.general_library")
local config = {
last_template = "%n %t - %p.pdf"
}
local script_name = library.calc_script_name()
configuration.get_user_settings(script_name, config)
local function get_current_path_file_and_extension()
local documents = finale.FCDocuments()
documents:LoadAll()
local doc = documents:FindCurrent()
local file_name = mixin.FCMString()
local path_name = mixin.FCMString()
local file_path = mixin.FCMString()
doc:GetPath(file_path)
file_path:SplitToPathAndFile(path_name, file_name)
local extension = mixin.FCMString()
:SetString(file_name)
:ExtractFileExtension()
if extension.Length > 0 then
file_name:TruncateAt(file_name:FindLast("." .. extension.LuaString))
end
return path_name.LuaString, file_name.LuaString, extension.LuaString
end
local fcmstr = function(str)
return mixin.FCMString():SetLuaString(str)
end
local function browse_for_path(path_name, file_name)
local result = nil
local dlg = mixin.FCMFolderBrowseDialog(finenv.UI())
:SetFolderPath(fcmstr(path_name))
:SetUseFinaleAPI(false)
:SetWindowTitle(fcmstr("Select Folder for " .. file_name .. " PDFs"))
if dlg:Execute() then
local str = mixin.FCMString()
dlg:GetFolderPath(str)
result = str:AssureEndingPathDelimiter().LuaString
end
return result
end
local function get_template(file_name)
local dialog_title = "Rename " .. file_name .. " PDFs"
local dialog = mixin.FCMCustomWindow()
:SetTitle(dialog_title)
local max_width = math.max(#dialog_title, 42) * 6
local first_label_y = 53 -- "You can include"
local label_y_offset = 17 -- line spacing
local placeholder_x = 12 -- "%f"
local description_x = 36 -- "Score filename"
dialog:CreateStatic(0, 0)
:SetText("New filename template")
:SetWidth(max_width)
dialog:CreateEdit(0, label_y_offset, "template")
:SetText(config.last_template)
:SetWidth(max_width)
dialog:CreateHorizontalLine(0, 44, max_width)
dialog:CreateStatic(0, first_label_y)
:SetText("You can include the following placeholders:")
:SetWidth(max_width)
local counter = 2
local function add_placeholder_and_description(ph, desc)
local y = first_label_y + (counter * label_y_offset) - 12
dialog:CreateStatic(placeholder_x, y):SetText(ph):SetWidth(16)
dialog:CreateStatic(description_x, y):SetText(desc):SetWidth(#desc * 6)
counter = counter + 1
end
add_placeholder_and_description("%f", "Score filename")
add_placeholder_and_description("%t", "Score title")
add_placeholder_and_description("%p", "Part name")
add_placeholder_and_description("%n", "Part number")
add_placeholder_and_description("%o", "Total number of parts")
add_placeholder_and_description("%d", "Date (format YYYY-MM-DD)")
add_placeholder_and_description("%h", "Time (format HHNN)")
dialog:CreateOkButton()
dialog:CreateCancelButton()
if dialog:ExecuteModal() == finale.EXECMODAL_OK then
local template = dialog:GetControl("template"):GetText()
if not template:find("%.pdf$") then
template = template .. ".pdf"
end
config.last_template = template
configuration.save_user_settings(script_name, config)
return template
end
end
local function rename_one_pdf(path, old_name, template, template_data)
for k, v in pairs(template_data) do
template = template:gsub("%%" .. k, v)
end
return os.rename(
path .. old_name .. ".pdf",
path .. template
)
end
local function rename_all_pdfs()
local path_name, file_name = get_current_path_file_and_extension()
path_name = browse_for_path(path_name, file_name)
if not path_name then return end
local template = get_template(file_name)
if not template then return end
local template_data = {
f = file_name,
d = os.date("%Y-%m-%d"),
h = os.date("%H%M")
}
local str = finale.FCString()
local file_info = finale.FCFileInfoText()
file_info:LoadTitle(str)
file_info:GetText(str)
template_data.t = str.LuaString
local parts = finale.FCParts()
parts:LoadAll()
template_data.o = string.format("%.2d", parts:GetCount())
for part in each(parts) do
part:GetName(str)
local part_name = str.LuaString
template_data.n = string.format("%.2d", part.OrderID)
if part:IsScore() then
template_data.p = part_name
rename_one_pdf(path_name, file_name, template, template_data)
else
local escaped_name = part_name:gsub("/", "_")
local truncated_name = part_name:gsub("^.*/", "")
template_data.p = escaped_name
local possible_names = {
-- normal
string.format("%s - %s", file_name, escaped_name),
-- "x" added to filename
string.format("%sx - %s", file_name, escaped_name),
-- "Filename - Flute/Piccolo" truncated to "Piccolo"
truncated_name,
}
for _, possible_name in pairs(possible_names) do
if rename_one_pdf(path_name, possible_name, template, template_data) then
break
end
end
end
end
end
rename_all_pdfs()