hookapp 0.0.7 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/LICENSE.md +31 -0
- data/OVERVIEW.md +80 -0
- data/README.md +282 -21
- data/Rakefile +1 -1
- data/bin/hook +127 -10
- data/buildnotes.md +29 -0
- data/hook.rdoc +63 -4
- data/hookapp.gemspec +9 -8
- data/html/App.html +119 -0
- data/html/GLI.html +99 -0
- data/html/GLI/Commands.html +99 -0
- data/html/GLI/Commands/Doc.html +99 -0
- data/html/GLI/Commands/MarkdownDocumentListener.html +717 -0
- data/html/Hook.html +113 -0
- data/html/HookApp.html +1222 -0
- data/html/Hooker.html +119 -0
- data/html/README_rdoc.html +328 -0
- data/html/String.html +427 -0
- data/html/created.rid +9 -0
- data/html/css/fonts.css +167 -0
- data/html/css/rdoc.css +619 -0
- data/html/fonts/Lato-Light.ttf +0 -0
- data/html/fonts/Lato-LightItalic.ttf +0 -0
- data/html/fonts/Lato-Regular.ttf +0 -0
- data/html/fonts/Lato-RegularItalic.ttf +0 -0
- data/html/fonts/SourceCodePro-Bold.ttf +0 -0
- data/html/fonts/SourceCodePro-Regular.ttf +0 -0
- data/html/images/add.png +0 -0
- data/html/images/arrow_up.png +0 -0
- data/html/images/brick.png +0 -0
- data/html/images/brick_link.png +0 -0
- data/html/images/bug.png +0 -0
- data/html/images/bullet_black.png +0 -0
- data/html/images/bullet_toggle_minus.png +0 -0
- data/html/images/bullet_toggle_plus.png +0 -0
- data/html/images/date.png +0 -0
- data/html/images/delete.png +0 -0
- data/html/images/find.png +0 -0
- data/html/images/loadingAnimation.gif +0 -0
- data/html/images/macFFBgHack.png +0 -0
- data/html/images/package.png +0 -0
- data/html/images/page_green.png +0 -0
- data/html/images/page_white_text.png +0 -0
- data/html/images/page_white_width.png +0 -0
- data/html/images/plugin.png +0 -0
- data/html/images/ruby.png +0 -0
- data/html/images/tag_blue.png +0 -0
- data/html/images/tag_green.png +0 -0
- data/html/images/transparent.png +0 -0
- data/html/images/wrench.png +0 -0
- data/html/images/wrench_orange.png +0 -0
- data/html/images/zoom.png +0 -0
- data/html/index.html +308 -0
- data/html/js/darkfish.js +84 -0
- data/html/js/navigation.js +105 -0
- data/html/js/navigation.js.gz +0 -0
- data/html/js/search.js +110 -0
- data/html/js/search_index.js +1 -0
- data/html/js/search_index.js.gz +0 -0
- data/html/js/searcher.js +229 -0
- data/html/js/searcher.js.gz +0 -0
- data/html/table_of_contents.html +409 -0
- data/lib/completion/hook_completion.bash +22 -0
- data/lib/completion/hook_completion.fish +31 -0
- data/lib/completion/hook_completion.zsh +22 -0
- data/lib/helpers/fuzzyfilefinder +0 -0
- data/lib/hook.rb +5 -1
- data/lib/hook/hookapp.rb +489 -0
- data/lib/hook/hooker.rb +1 -344
- data/lib/hook/markdown_document_listener.rb +164 -0
- data/lib/hook/string.rb +60 -0
- data/lib/hook/version.rb +3 -1
- metadata +76 -12
@@ -0,0 +1,22 @@
|
|
1
|
+
# Source this script from ~/.zshrc
|
2
|
+
_hook_targets()
|
3
|
+
{
|
4
|
+
local cmds cur ff
|
5
|
+
if (($COMP_CWORD == 1))
|
6
|
+
then
|
7
|
+
cur="${COMP_WORDS[1]}"
|
8
|
+
cmds="$(hook help -c)"
|
9
|
+
COMPREPLY=($(compgen -W "$cmds" -- "$cur"))
|
10
|
+
COMPREPLY=( "${COMPREPLY[@]/%/ }" )
|
11
|
+
else
|
12
|
+
# get all matching files and directories
|
13
|
+
COMPREPLY=($(compgen -f -- "${COMP_WORDS[$COMP_CWORD]}"))
|
14
|
+
|
15
|
+
for ((ff=0; ff<${#COMPREPLY[@]}; ff++)); do
|
16
|
+
[[ -d ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+='/'
|
17
|
+
[[ -f ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+=' '
|
18
|
+
done
|
19
|
+
fi
|
20
|
+
}
|
21
|
+
|
22
|
+
complete -o bashdefault -o default -o nospace -F _hook_targets hook
|
Binary file
|
data/lib/hook.rb
CHANGED
data/lib/hook/hookapp.rb
ADDED
@@ -0,0 +1,489 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shellwords'
|
4
|
+
require 'uri'
|
5
|
+
# Hook.app functions
|
6
|
+
module HookApp
|
7
|
+
# Create a single regex for validation of an
|
8
|
+
# array by first char or full match.
|
9
|
+
def format_regex(options)
|
10
|
+
fmt_rx_array = []
|
11
|
+
options.map {|fmt| fmt_rx_array.push(fmt.sub(/^(.)(.*?)$/, '\1(\2)?')) }
|
12
|
+
Regexp.new("^(#{fmt_rx_array.join('|')})$",'i')
|
13
|
+
end
|
14
|
+
|
15
|
+
# Check if format fully matches or matches the first
|
16
|
+
# character of available options.
|
17
|
+
# Return full valid format or nil
|
18
|
+
def validate_format(fmt, options)
|
19
|
+
valid_format_rx = options.map { |format| format.sub(/^(.)(.*)$/, '^\1(\2)?$') }
|
20
|
+
valid_format = nil
|
21
|
+
valid_format_rx.each_with_index do |rx, i|
|
22
|
+
cmp = Regexp.new(rx, 'i')
|
23
|
+
next unless fmt =~ cmp
|
24
|
+
|
25
|
+
valid_format = options[i]
|
26
|
+
break
|
27
|
+
end
|
28
|
+
valid_format
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get a Hook bookmark for file or URL. Return bookmark hash.
|
32
|
+
def bookmark_for(url)
|
33
|
+
url.valid_hook!
|
34
|
+
raise "Invalid target: #{url}" unless url
|
35
|
+
|
36
|
+
begin
|
37
|
+
mark = `osascript <<'APPLESCRIPT'
|
38
|
+
tell application "Hook"
|
39
|
+
set _hook to make bookmark with data "#{url}"
|
40
|
+
if _hook is missing value
|
41
|
+
return ""
|
42
|
+
else
|
43
|
+
return name of _hook & "||" & address of _hook & "||" & path of _hook
|
44
|
+
end if
|
45
|
+
end tell
|
46
|
+
APPLESCRIPT`.strip
|
47
|
+
rescue p => e
|
48
|
+
raise e
|
49
|
+
end
|
50
|
+
|
51
|
+
raise "Error getting bookmark for #{url}" if mark.empty?
|
52
|
+
mark.split_hook
|
53
|
+
end
|
54
|
+
|
55
|
+
# Get bookmarks hooked to file or URL. Return array of bookmark hashes.
|
56
|
+
def get_hooks(url)
|
57
|
+
url.valid_hook!
|
58
|
+
raise "Invalid target: #{url}" unless url
|
59
|
+
|
60
|
+
hooks = `osascript <<'APPLESCRIPT'
|
61
|
+
tell application "Hook"
|
62
|
+
set _mark to make bookmark with data "#{url}"
|
63
|
+
if _mark is missing value
|
64
|
+
return ""
|
65
|
+
end if
|
66
|
+
set _hooks to hooked bookmarks of _mark
|
67
|
+
set _out to {}
|
68
|
+
repeat with _hook in _hooks
|
69
|
+
set _out to _out & (name of _hook & "||" & address of _hook & "||" & path of _hook)
|
70
|
+
end repeat
|
71
|
+
set {astid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "^^"}
|
72
|
+
set _output to _out as string
|
73
|
+
set AppleScript's text item delimiters to astid
|
74
|
+
return _output
|
75
|
+
end tell
|
76
|
+
APPLESCRIPT`.strip
|
77
|
+
hooks.split_hooks
|
78
|
+
end
|
79
|
+
|
80
|
+
# Get a bookmark from the foreground document of specified app.
|
81
|
+
def bookmark_from_app(app, opts)
|
82
|
+
mark = `osascript <<'APPLESCRIPT'
|
83
|
+
tell application "System Events" to set front_app to name of first application process whose frontmost is true
|
84
|
+
tell application "#{app}" to activate
|
85
|
+
delay 2
|
86
|
+
tell application "Hook"
|
87
|
+
set _hook to (bookmark from active window)
|
88
|
+
set _output to (name of _hook & "||" & address of _hook & "||" & path of _hook)
|
89
|
+
end tell
|
90
|
+
tell application front_app to activate
|
91
|
+
return _output
|
92
|
+
APPLESCRIPT`.strip.split_hook
|
93
|
+
title = mark[:name].empty? ? "#{app.cap} link" : mark[:name]
|
94
|
+
output = opts[:markdown] ? "[#{title}](#{mark[:url]})" : mark[:url]
|
95
|
+
|
96
|
+
if opts[:copy]
|
97
|
+
"Copied Markdown link for '#{title}' to clipboard" if output.clip
|
98
|
+
else
|
99
|
+
output
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Search boomark names/titles. Return array of bookmark hashes.
|
104
|
+
def search_name(search)
|
105
|
+
`osascript <<'APPLESCRIPT'
|
106
|
+
set searchString to "#{search.strip}"
|
107
|
+
tell application "Hook"
|
108
|
+
set _marks to every bookmark whose name contains searchString
|
109
|
+
set _out to {}
|
110
|
+
repeat with _hook in _marks
|
111
|
+
set _out to _out & (name of _hook & "||" & address of _hook & "||" & path of _hook)
|
112
|
+
end repeat
|
113
|
+
set {astid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "^^"}
|
114
|
+
set _output to _out as string
|
115
|
+
set AppleScript's text item delimiters to astid
|
116
|
+
return _output
|
117
|
+
end tell
|
118
|
+
APPLESCRIPT`.strip.split_hooks
|
119
|
+
end
|
120
|
+
|
121
|
+
# Search bookmark paths and addresses. Return array of bookmark hashes.
|
122
|
+
def search_path_or_address(search)
|
123
|
+
`osascript <<'APPLESCRIPT'
|
124
|
+
set searchString to "#{search.strip}"
|
125
|
+
tell application "Hook"
|
126
|
+
set _marks to every bookmark whose path contains searchString or address contains searchString
|
127
|
+
set _out to {}
|
128
|
+
repeat with _hook in _marks
|
129
|
+
set _out to _out & (name of _hook & "||" & address of _hook & "||" & path of _hook)
|
130
|
+
end repeat
|
131
|
+
set {astid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "^^"}
|
132
|
+
set _output to _out as string
|
133
|
+
set AppleScript's text item delimiters to astid
|
134
|
+
return _output
|
135
|
+
end tell
|
136
|
+
APPLESCRIPT`.strip.split_hooks
|
137
|
+
end
|
138
|
+
|
139
|
+
# Get all known bookmarks. Return array of bookmark hashes.
|
140
|
+
def all_bookmarks
|
141
|
+
`osascript <<'APPLESCRIPT'
|
142
|
+
tell application "Hook"
|
143
|
+
set _marks to every bookmark
|
144
|
+
set _out to {}
|
145
|
+
repeat with _hook in _marks
|
146
|
+
set _out to _out & (name of _hook & "||" & address of _hook & "||" & path of _hook)
|
147
|
+
end repeat
|
148
|
+
set {astid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "^^"}
|
149
|
+
set _output to _out as string
|
150
|
+
set AppleScript's text item delimiters to astid
|
151
|
+
return _output
|
152
|
+
end tell
|
153
|
+
APPLESCRIPT`.strip.split_hooks
|
154
|
+
end
|
155
|
+
|
156
|
+
# Search bookmarks, using both names and addresses unless options contain ":names_only".
|
157
|
+
# Return results as formatted list.
|
158
|
+
def search_bookmarks(search, opts)
|
159
|
+
unless search.nil? || search.empty?
|
160
|
+
result = search_name(search)
|
161
|
+
unless opts[:names_only]
|
162
|
+
more_results = search_path_or_address(search)
|
163
|
+
result = result.concat(more_results).uniq
|
164
|
+
end
|
165
|
+
else
|
166
|
+
result = all_bookmarks
|
167
|
+
end
|
168
|
+
|
169
|
+
separator = opts[:format] == 'paths' && opts[:null_separator] ? "\0" : "\n"
|
170
|
+
|
171
|
+
output = output_array(result, opts)
|
172
|
+
|
173
|
+
if opts[:format] =~ /^v/
|
174
|
+
"Search results for: #{search}\n---------\n" + output.join("\n")
|
175
|
+
else
|
176
|
+
output.join(separator)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Create a bookmark for specified file/url and copy to the clipboard.
|
181
|
+
def clip_bookmark(url, opts)
|
182
|
+
mark = bookmark_for(url)
|
183
|
+
copy_bookmark(mark[:name], mark[:url], opts)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Create a bookmark from specified title and url and copy to the clipboard.
|
187
|
+
def copy_bookmark(title, url, opts)
|
188
|
+
raise "No URL found" if url.empty?
|
189
|
+
title = title.empty? ? 'No title' : title
|
190
|
+
output = opts[:markdown] ? "[#{title}](#{url})" : url
|
191
|
+
output.clip
|
192
|
+
%(Copied #{opts[:markdown] ? 'Markdown link' : 'Hook URL'} for '#{title}' to clipboard)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Generate a menu of available hooks for selecting one or more hooks to operate on.
|
196
|
+
# Revamped to use `fzf`, which is embedded as `lib/helpers/fuzzyfilefinder` to avoid any conflicts.
|
197
|
+
# Allows multiple selections with tab key, and type-ahead fuzzy filtering of results.
|
198
|
+
def select_hook(marks)
|
199
|
+
# intpad = marks.length.to_s.length + 1
|
200
|
+
# marks.each_with_index do |mark, i|
|
201
|
+
# STDERR.printf "%#{intpad}d) %s\n", i + 1, mark[:name]
|
202
|
+
# end
|
203
|
+
# STDERR.print 'Open which bookmark: '
|
204
|
+
# sel = STDIN.gets.strip.to_i
|
205
|
+
# raise 'Invalid selection' unless sel.positive? && sel <= marks.length
|
206
|
+
|
207
|
+
# marks[sel - 1]
|
208
|
+
|
209
|
+
options = marks.map {|mark|
|
210
|
+
if mark[:name]
|
211
|
+
id = mark[:name]
|
212
|
+
elsif mark[:path]
|
213
|
+
id = mark[:path]
|
214
|
+
elsif mark[:url]
|
215
|
+
id = mark[:url]
|
216
|
+
else
|
217
|
+
return false
|
218
|
+
end
|
219
|
+
|
220
|
+
if mark[:path]
|
221
|
+
loc = File.dirname(mark[:path])
|
222
|
+
elsif mark[:url]
|
223
|
+
url = URI.parse(mark[:url])
|
224
|
+
id = mark[:url]
|
225
|
+
loc = url.scheme + " - " + url.hostname
|
226
|
+
else
|
227
|
+
loc = ""
|
228
|
+
end
|
229
|
+
|
230
|
+
"#{id}\t#{mark[:path]}\t#{mark[:url]}\t#{loc}"
|
231
|
+
}.delete_if { |mark| !mark }
|
232
|
+
|
233
|
+
raise "Error processing available hooks" if options.empty?
|
234
|
+
|
235
|
+
args = ['--layout=reverse-list',
|
236
|
+
'--header="esc: cancel, tab: multi-select, return: open > "',
|
237
|
+
'--prompt=" Select hooks > "',
|
238
|
+
'--multi',
|
239
|
+
'--tabstop=4',
|
240
|
+
'--delimiter="\t"',
|
241
|
+
'--with-nth=1,4',
|
242
|
+
'--height=60%',
|
243
|
+
'--min-height=10'
|
244
|
+
]
|
245
|
+
|
246
|
+
fzf = File.join(File.dirname(__FILE__), '../helpers/fuzzyfilefinder')
|
247
|
+
|
248
|
+
sel = `echo #{Shellwords.escape(options.join("\n"))} | '#{fzf}' #{args.join(' ')}`.chomp
|
249
|
+
res = sel.split(/\n/).map { |s|
|
250
|
+
ps = s.split(/\t/)
|
251
|
+
{ name: ps[0], path: ps[1], url: ps[2] }
|
252
|
+
}
|
253
|
+
|
254
|
+
if res.size == 0
|
255
|
+
raise 'Cancelled (empty response)'
|
256
|
+
end
|
257
|
+
|
258
|
+
res
|
259
|
+
end
|
260
|
+
|
261
|
+
# Open the Hook GUI for browsing/performing actions on a file or url
|
262
|
+
def open_gui(url)
|
263
|
+
result = `osascript <<'APPLESCRIPT'
|
264
|
+
tell application "Hook"
|
265
|
+
set _mark to make bookmark with data "#{url.valid_hook}"
|
266
|
+
if _mark is missing value
|
267
|
+
return "Failed to create bookmark for #{url}"
|
268
|
+
else
|
269
|
+
invoke on _mark
|
270
|
+
return ""
|
271
|
+
end if
|
272
|
+
end tell
|
273
|
+
APPLESCRIPT`.strip
|
274
|
+
raise result unless result.empty?
|
275
|
+
end
|
276
|
+
|
277
|
+
# Select from a menu of available hooks and open using macOS `open`.
|
278
|
+
def open_linked(url)
|
279
|
+
marks = get_hooks(url)
|
280
|
+
if marks.empty?
|
281
|
+
warn "No hooks found for #{url}"
|
282
|
+
else
|
283
|
+
res = select_hook(marks)
|
284
|
+
res.each {|mark|
|
285
|
+
`open '#{mark[:url]}'`
|
286
|
+
}
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# Link 2 or more files/urls with bi-directional hooks.
|
291
|
+
def link_files(args)
|
292
|
+
target = args.pop
|
293
|
+
target.valid_hook!
|
294
|
+
raise "Invalid target: #{target}" unless target
|
295
|
+
|
296
|
+
args.each do |file|
|
297
|
+
file.valid_hook!
|
298
|
+
raise "Invalid target: #{file}" unless file
|
299
|
+
|
300
|
+
puts "Linking #{file} and #{target}..."
|
301
|
+
`osascript <<'APPLESCRIPT'
|
302
|
+
tell application "Hook"
|
303
|
+
set _mark1 to make bookmark with data "#{file}"
|
304
|
+
set _mark2 to make bookmark with data "#{target}"
|
305
|
+
hook _mark1 and _mark2
|
306
|
+
return true
|
307
|
+
end tell
|
308
|
+
APPLESCRIPT`
|
309
|
+
end
|
310
|
+
"Linked #{args.length} files to #{target}"
|
311
|
+
end
|
312
|
+
|
313
|
+
# Copy all hooks from source file to target file
|
314
|
+
def clone_hooks(args)
|
315
|
+
target = args.pop.valid_hook
|
316
|
+
source = args[0].valid_hook
|
317
|
+
|
318
|
+
if target && source
|
319
|
+
hooks = get_hooks(source)
|
320
|
+
hooks.each do |hook|
|
321
|
+
`osascript <<'APPLESCRIPT'
|
322
|
+
tell application "Hook"
|
323
|
+
set _mark1 to make bookmark with data "#{hook[:url]}"
|
324
|
+
set _mark2 to make bookmark with data "#{target}"
|
325
|
+
hook _mark1 and _mark2
|
326
|
+
return true
|
327
|
+
end tell
|
328
|
+
APPLESCRIPT`
|
329
|
+
end
|
330
|
+
"Hooks from #{source} cloned to #{target}"
|
331
|
+
else
|
332
|
+
raise 'Invalid file specified'
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
# Delete all hooked files/urls from target file
|
337
|
+
def delete_all_hooks(url)
|
338
|
+
STDERR.print "Are you sure you want to delete ALL hooks from #{url} (y/N)? "
|
339
|
+
res = STDIN.gets.strip
|
340
|
+
if res =~ /^y/i
|
341
|
+
get_hooks(url).each do |hook|
|
342
|
+
`osascript <<'APPLESCRIPT'
|
343
|
+
tell application "Hook"
|
344
|
+
set _mark1 to make bookmark with data "#{hook[:url]}"
|
345
|
+
set _mark2 to make bookmark with data "#{url}"
|
346
|
+
unhook _mark1 and _mark2
|
347
|
+
return true
|
348
|
+
end tell
|
349
|
+
APPLESCRIPT`
|
350
|
+
end
|
351
|
+
"Removed all hooks from #{url}"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
# Delete hooks between two files/urls
|
356
|
+
def delete_hooks(args, opts)
|
357
|
+
urls = args.map(&:valid_hook).delete_if { |url| !url }
|
358
|
+
output = []
|
359
|
+
if opts[:all]
|
360
|
+
urls.each_with_index do |url, i|
|
361
|
+
raise "Invalid target: #{args[i]}" unless url
|
362
|
+
|
363
|
+
output.push(delete_all_hooks(url))
|
364
|
+
end
|
365
|
+
return output.join("\n")
|
366
|
+
end
|
367
|
+
|
368
|
+
if urls.length == 2
|
369
|
+
source = urls[0]
|
370
|
+
target = urls[1]
|
371
|
+
`osascript <<'APPLESCRIPT'
|
372
|
+
tell application "Hook"
|
373
|
+
set _mark1 to make bookmark with data "#{source}"
|
374
|
+
set _mark2 to make bookmark with data "#{target}"
|
375
|
+
unhook _mark1 and _mark2
|
376
|
+
return true
|
377
|
+
end tell
|
378
|
+
APPLESCRIPT`
|
379
|
+
"Hook removed between #{source} and #{target}"
|
380
|
+
else
|
381
|
+
raise 'Invalid number of URLs or files specified'
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
# Create bi-directional links between every file/url in the list of arguments
|
386
|
+
def link_all(args)
|
387
|
+
args.each do |file|
|
388
|
+
source = file.valid_hook
|
389
|
+
link_to = args.dup.map(&:valid_hook).reject { |url| url == source }
|
390
|
+
link_to.each do |url|
|
391
|
+
`osascript <<'APPLESCRIPT'
|
392
|
+
tell application "Hook"
|
393
|
+
set _mark1 to make bookmark with data "#{source}"
|
394
|
+
set _mark2 to make bookmark with data "#{url}"
|
395
|
+
hook _mark1 and _mark2
|
396
|
+
return true
|
397
|
+
end tell
|
398
|
+
APPLESCRIPT`
|
399
|
+
end
|
400
|
+
end
|
401
|
+
"Linked #{args.length} files to each other"
|
402
|
+
end
|
403
|
+
|
404
|
+
# Get a list of all hooks on a file/url.
|
405
|
+
def linked_bookmarks(args, opts)
|
406
|
+
result = []
|
407
|
+
|
408
|
+
separator = args.length == 1 && opts[:format] == 'paths' && opts[:null_separator] ? "\0" : "\n"
|
409
|
+
|
410
|
+
if args.nil? || args.empty?
|
411
|
+
result = output_array(all_bookmarks, opts)
|
412
|
+
else
|
413
|
+
args.each do |url|
|
414
|
+
source_mark = bookmark_for(url)
|
415
|
+
filename = source_mark[:name]
|
416
|
+
|
417
|
+
case opts[:format]
|
418
|
+
when /^m/
|
419
|
+
filename = "[#{source_mark[:name]}](#{source_mark[:url]})"
|
420
|
+
filename += " <file://#{CGI.escape(source_mark[:path])}>" if source_mark[:path]
|
421
|
+
when /^p/
|
422
|
+
filename = "File: #{source_mark[:name]}"
|
423
|
+
filename += " (#{source_mark[:path]})" if source_mark[:path]
|
424
|
+
when /^h/
|
425
|
+
filename = "File: #{source_mark[:name]}"
|
426
|
+
filename += " (#{source_mark[:url]})" if source_mark[:url]
|
427
|
+
else
|
428
|
+
filename = "Bookmarks attached to #{source_mark[:path] || source_mark[:url]}"
|
429
|
+
end
|
430
|
+
|
431
|
+
hooks_arr = get_hooks(url)
|
432
|
+
|
433
|
+
output = output_array(hooks_arr, opts)
|
434
|
+
result.push({ file: filename, links: output.join(separator) })
|
435
|
+
end
|
436
|
+
|
437
|
+
|
438
|
+
if result.length > 1 || opts[:format] == 'verbose'
|
439
|
+
result.map! do |res|
|
440
|
+
"#{res[:file]}\n\n#{res[:links]}\n"
|
441
|
+
end
|
442
|
+
else
|
443
|
+
result.map! do |res|
|
444
|
+
res[:links]
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
result.join(separator)
|
449
|
+
end
|
450
|
+
|
451
|
+
# Output an array of hooks in the given format.
|
452
|
+
def output_array(hooks_arr, opts)
|
453
|
+
if !hooks_arr.empty?
|
454
|
+
hooks_arr.reject! { |h| h[:path].nil? || h[:path] == '' } if opts[:files_only]
|
455
|
+
|
456
|
+
output = []
|
457
|
+
|
458
|
+
case opts[:format]
|
459
|
+
when /^m/
|
460
|
+
hooks_arr.each do |h|
|
461
|
+
if h[:name].empty?
|
462
|
+
title = h[:url]
|
463
|
+
else
|
464
|
+
title = h[:name]
|
465
|
+
end
|
466
|
+
output.push("- [#{title}](#{h[:url]})")
|
467
|
+
end
|
468
|
+
when /^p/
|
469
|
+
hooks_arr.each do |h|
|
470
|
+
output.push(h[:path].nil? ? h[:url] : h[:path])
|
471
|
+
end
|
472
|
+
when /^h/
|
473
|
+
hooks_arr.each do |h|
|
474
|
+
output.push(h[:url])
|
475
|
+
end
|
476
|
+
else
|
477
|
+
hooks_arr.each do |h|
|
478
|
+
output.push("Title: #{h[:name]}\nPath: #{h[:path]}\nAddress: #{h[:url]}\n---------------------")
|
479
|
+
end
|
480
|
+
end
|
481
|
+
else
|
482
|
+
output = ['No bookmarks']
|
483
|
+
end
|
484
|
+
|
485
|
+
output
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
|