doing 1.0.74 → 1.0.79
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -6
- data/bin/doing +17 -4
- data/lib/doing/helpers.rb +1 -1
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +208 -33
- data/lib/helpers/fuzzyfilefinder +0 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24a207b31d2f64fc81c00b1484f62a5ab2609ded162fc9733cb54463c652d63e
|
4
|
+
data.tar.gz: dfc767b0d8cec0229e9ad3823f5853d81c343261198c6638e364331920dc7989
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f64972ed2d157a0b52afa882d257190d236ebb5805d0ff8049d3ab65ca92974a1cbe2e11ba2ee1ea9cd04b751bd4cc6874f409d442cdfb9347c37bacb6fc47c
|
7
|
+
data.tar.gz: 9d3432a35cd14d44474ef32e90df40943a2a9ed7eb7c232a2361816aba255b7ed39992dc7b4cfa000afb93abbe4cea3036c9eec244a2fe141f7dca70ce400095
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ If there's something I want to look at later but doesn't need to be added to a t
|
|
27
27
|
|
28
28
|
## Installation
|
29
29
|
|
30
|
-
The current version of `doing` is <!--VER-->1.0.
|
30
|
+
The current version of `doing` is <!--VER-->1.0.78<!--END VER-->.
|
31
31
|
|
32
32
|
$ [sudo] gem install doing
|
33
33
|
|
@@ -268,7 +268,7 @@ You can add additional custom views. Just nest them under the `views` key (inden
|
|
268
268
|
count: 5
|
269
269
|
wrap_width: 0
|
270
270
|
date_format: '%F %_I:%M%P'
|
271
|
-
template: '%date | %title%note'
|
271
|
+
template: '%date | %title%note'
|
272
272
|
|
273
273
|
The `section` key is the default section to pull entries from. Count and section can be overridden at runtime with the `-c` and `-s` flags. Setting `section` to `All` will combine all sections in the output.
|
274
274
|
|
@@ -505,7 +505,7 @@ You can include a `transform` section in the autotag config which contains pairs
|
|
505
505
|
transform:
|
506
506
|
- (\w+)-\d+:$1
|
507
507
|
|
508
|
-
This creates a search pattern looking for a string of word characters followed by a hyphen and one or more digits, e.g. `@projecttag-12`. Do not include the @ symbol in the pattern. The replacement (`$
|
508
|
+
This creates a search pattern looking for a string of word characters followed by a hyphen and one or more digits, e.g. `@projecttag-12`. Do not include the @ symbol in the pattern. The replacement (`$l`) indicates that the first matched group (in parenthesis) should be used to generate the new tag, resulting in `@projecttag` being added to the entry.
|
509
509
|
|
510
510
|
##### Annotating
|
511
511
|
|
@@ -619,11 +619,14 @@ Now you can run `doing import --type timing -s SECTION PATH`, where SECTION is t
|
|
619
619
|
|
620
620
|
#### Interactive Usage
|
621
621
|
|
622
|
-
|
622
|
+
FuzzyFileFinder (`fzf`) is included with doing (<https://github.com/junegunn/fzf>), and you can use `doing select` to get a menu of all your items (or items in a given section) which can be searched with fuzzy matching. The menu allows multiple selections to be acted on directly.
|
623
|
+
|
624
|
+
To use the menu, type a search string or use the arrow keys to navigate up and down. Tip: searching is "fuzzy" by default, but you can start your search with a single quote (`'`) to force an exact match. Press tab on an entry you'd like to perform an action on. A marker will show up on the left indicating the entry is selected. Repeat the process and select as many entries as needed. When you hit Return, the selection will be passed back to doing. Use Control-A to select all visible entries.
|
623
625
|
|
624
|
-
|
626
|
+
Doing can perform several functions with this menu. Not all of doing's features are available, but the core functionality you'd need is there, plus you can open the selected entries on one page in your text editor, make changes to them, and when you save and close the entries are updated accordingly. This allows editing of everything from timestamps to tags to notes.
|
625
627
|
|
626
|
-
|
628
|
+
If no actions are specified, an interactive menu of options will be
|
629
|
+
presented.
|
627
630
|
|
628
631
|
Run `doing help select` for a list of options:
|
629
632
|
|
@@ -634,13 +637,19 @@ Run `doing help select` for a list of options:
|
|
634
637
|
-f, --finish - Add @done with current time to selected item(s)
|
635
638
|
--flag - Add flag to selected item(s)
|
636
639
|
-m, --move=SECTION - Move selected items to section (default: none)
|
640
|
+
-o, --output=FORMAT - Output format for export (doing|taskpaper|csv|html|json|template|timeline) (default: none)
|
641
|
+
-q, --query=QUERY - Initial search query for filtering (default: none)
|
642
|
+
-r, --remove - Reverse -c, -f, --flag, and -t (remove instead of adding)
|
637
643
|
-s, --section=SECTION - Select from a specific section (default: none)
|
644
|
+
--save_to=FILE - Save selected entries to file using --output format (default: none)
|
638
645
|
-t, --tag=TAG - Tag selected entries (default: none)
|
639
646
|
|
640
647
|
For example, `doing select -d -a` would present the menu, and then mark selected entries as @done (with timestamp) and move them to the Archive section.
|
641
648
|
|
642
649
|
Multiple actions can be performed at once by combining options. You can also combine the `--editor` switch with any other options. Other actions will be performed first, then the entries --- with any modifications performed --- will be presented in the editor for tweaking.
|
643
650
|
|
651
|
+
**Note:** when using the `--editor` flag to open selections in your text editor, entries will be separated by `---` lines. These must remain in place for doing to track the changes. You can do anything you want to the entries, modify dates, change text, add notes, etc., as long as you leave the dividers in place. You can even delete an entry entirely, leaving the dividers around the missing line and the entry will be removed from your doing file when you save and exit the editor.
|
652
|
+
|
644
653
|
---
|
645
654
|
|
646
655
|
## Extras
|
data/bin/doing
CHANGED
@@ -257,9 +257,9 @@ command :template do |c|
|
|
257
257
|
end
|
258
258
|
|
259
259
|
desc 'Display an interactive menu to perform operations (requires fzf)'
|
260
|
-
long_desc '
|
260
|
+
long_desc 'List all entries and select with typeahead fuzzy matching.
|
261
261
|
|
262
|
-
|
262
|
+
Multiple selections are allowed, hit tab to add the highlighted entry to the selection. Return processes the selected entries.'
|
263
263
|
command :select do |c|
|
264
264
|
c.desc 'Select from a specific section'
|
265
265
|
c.arg_name 'SECTION'
|
@@ -269,6 +269,9 @@ command :select do |c|
|
|
269
269
|
c.arg_name 'TAG'
|
270
270
|
c.flag %i[t tag]
|
271
271
|
|
272
|
+
c.desc 'Reverse -c, -f, --flag, and -t (remove instead of adding)'
|
273
|
+
c.switch %i[r remove], negatable: false
|
274
|
+
|
272
275
|
# c.desc 'Add @done to selected item(s), using start time of next item as the finish time'
|
273
276
|
# c.switch %i[a auto], negatable: false, default_value: false
|
274
277
|
|
@@ -279,6 +282,10 @@ command :select do |c|
|
|
279
282
|
c.arg_name 'SECTION'
|
280
283
|
c.flag %i[m move]
|
281
284
|
|
285
|
+
c.desc 'Initial search query for filtering'
|
286
|
+
c.arg_name 'QUERY'
|
287
|
+
c.flag %i[q query]
|
288
|
+
|
282
289
|
c.desc 'Cancel selected items (add @done without timestamp)'
|
283
290
|
c.switch %i[c cancel], negatable: false, default_value: false
|
284
291
|
|
@@ -294,9 +301,15 @@ command :select do |c|
|
|
294
301
|
c.desc 'Add flag to selected item(s)'
|
295
302
|
c.switch %i[flag], negatable: false, default_value: false
|
296
303
|
|
304
|
+
c.desc 'Save selected entries to file using --output format'
|
305
|
+
c.arg_name 'FILE'
|
306
|
+
c.flag %i[save_to]
|
307
|
+
|
308
|
+
c.desc 'Output format for export (doing|taskpaper|csv|html|json|template|timeline)'
|
309
|
+
c.arg_name 'FORMAT'
|
310
|
+
c.flag %i[o output], must_match: /^(?:doing|taskpaper|html|csv|json|template|timeline)$/i
|
311
|
+
|
297
312
|
c.action do |_global_options, options, args|
|
298
|
-
section = options[:section] || 'All'
|
299
|
-
edit = options[:editor]
|
300
313
|
wwid.interactive(options)
|
301
314
|
end
|
302
315
|
end
|
data/lib/doing/helpers.rb
CHANGED
@@ -92,7 +92,7 @@ class ::String
|
|
92
92
|
def link_urls(opt = {})
|
93
93
|
opt[:format] ||= :html
|
94
94
|
if opt[:format] == :html
|
95
|
-
gsub(%r{(?mi)((http|https)://)
|
95
|
+
gsub(%r{(?mi)((http|https)://)([\w\-_]+(\.[\w\-_]+)+)([\w\-.,@?^=%&:/~+#]*[\w\-@^=%&/~+#])?}) do |_match|
|
96
96
|
m = Regexp.last_match
|
97
97
|
proto = m[1].nil? ? 'http://' : ''
|
98
98
|
%(<a href="#{proto}#{m[0]}" title="Link to #{m[0]}">[#{m[3]}]</a>)
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
@@ -300,7 +300,7 @@ class WWID
|
|
300
300
|
tmpfile.unlink
|
301
301
|
end
|
302
302
|
|
303
|
-
input.split(/\n/).delete_if {|line| line =~ /^#/ }.join("\n")
|
303
|
+
input.split(/\n/).delete_if {|line| line =~ /^#/ }.join("\n")
|
304
304
|
end
|
305
305
|
|
306
306
|
#
|
@@ -462,7 +462,7 @@ class WWID
|
|
462
462
|
## @return (Bool) yes or no
|
463
463
|
##
|
464
464
|
def yn(question, default_response: false)
|
465
|
-
default = default_response ?
|
465
|
+
default = default_response ? default_response : 'n'
|
466
466
|
|
467
467
|
# if this isn't an interactive shell, answer default
|
468
468
|
return default.downcase == 'y' unless $stdout.isatty
|
@@ -766,6 +766,22 @@ class WWID
|
|
766
766
|
all_items.max_by { |item| item['date'] }
|
767
767
|
end
|
768
768
|
|
769
|
+
##
|
770
|
+
## @brief Generate a menu of options and allow user selection
|
771
|
+
##
|
772
|
+
## @return (String) The selected option
|
773
|
+
##
|
774
|
+
def choose_from(options, prompt)
|
775
|
+
puts prompt
|
776
|
+
options.each_with_index do |section, i|
|
777
|
+
puts format('% 3d: %s', i + 1, section)
|
778
|
+
end
|
779
|
+
print "#{colors['green']}> #{colors['default']}"
|
780
|
+
num = STDIN.gets
|
781
|
+
return false if num =~ /^[a-z ]*$/i
|
782
|
+
|
783
|
+
options[num.to_i - 1]
|
784
|
+
end
|
769
785
|
|
770
786
|
##
|
771
787
|
## @brief Display an interactive menu of entries
|
@@ -773,7 +789,7 @@ class WWID
|
|
773
789
|
## @param opt (Hash) Additional options
|
774
790
|
##
|
775
791
|
def interactive(opt = {})
|
776
|
-
|
792
|
+
fzf = File.join(File.dirname(__FILE__), '../helpers/fuzzyfilefinder')
|
777
793
|
|
778
794
|
section = opt[:section] ? guess_section(opt[:section]) : 'All'
|
779
795
|
|
@@ -807,7 +823,7 @@ class WWID
|
|
807
823
|
out.join('')
|
808
824
|
end
|
809
825
|
|
810
|
-
res = `echo #{Shellwords.escape(options.join("\n"))}
|
826
|
+
res = `echo #{Shellwords.escape(options.join("\n"))}|#{fzf} --header="Arrows to navigate, tab to mark for selection, enter to perform action" --prompt="Select entries to act on> " -m --bind ctrl-a:select-all -q "#{opt[:query]}"`
|
811
827
|
selected = []
|
812
828
|
res.split(/\n/).each do |item|
|
813
829
|
idx = item.match(/^(\d+)\)/)[1].to_i
|
@@ -819,6 +835,68 @@ class WWID
|
|
819
835
|
return
|
820
836
|
end
|
821
837
|
|
838
|
+
actions = %i[editor delete tag flag finish cancel tag archive output save_to]
|
839
|
+
has_action = false
|
840
|
+
actions.each do |a|
|
841
|
+
if opt[a]
|
842
|
+
has_action = true
|
843
|
+
break
|
844
|
+
end
|
845
|
+
end
|
846
|
+
|
847
|
+
unless has_action
|
848
|
+
action = choose_from(
|
849
|
+
[
|
850
|
+
"add tag",
|
851
|
+
"remove tag",
|
852
|
+
"archive",
|
853
|
+
"cancel",
|
854
|
+
"delete",
|
855
|
+
"edit",
|
856
|
+
"finish",
|
857
|
+
"flag",
|
858
|
+
"move",
|
859
|
+
"output format"
|
860
|
+
],
|
861
|
+
'What do you want to do with the selected items?')
|
862
|
+
case action
|
863
|
+
when /(add|remove) tag/
|
864
|
+
print "Enter tag: "
|
865
|
+
tag = STDIN.gets
|
866
|
+
return if tag =~ /^ *$/
|
867
|
+
opt[:tag] = tag.strip
|
868
|
+
opt[:remove] = true if action =~ /remove tag/
|
869
|
+
when /output format/
|
870
|
+
output_format = choose_from(%w[doing taskpaper json timeline html csv], 'Which output format?')
|
871
|
+
return if tag =~ /^ *$/
|
872
|
+
opt[:output] = output_format.strip
|
873
|
+
res = yn("Save to file?", default_response: 'n')
|
874
|
+
if res
|
875
|
+
print "File path/name: "
|
876
|
+
filename = STDIN.gets.strip
|
877
|
+
return if filename.empty?
|
878
|
+
opt[:save_to] = filename
|
879
|
+
end
|
880
|
+
when /archive/
|
881
|
+
opt[:archive] = true
|
882
|
+
when /delete/
|
883
|
+
opt[:delete] = true
|
884
|
+
when /edit/
|
885
|
+
opt[:editor] = true
|
886
|
+
when /finish/
|
887
|
+
opt[:finish] = true
|
888
|
+
when /cancel/
|
889
|
+
opt[:cancel] = true
|
890
|
+
when /move/
|
891
|
+
section = choose_section.strip
|
892
|
+
return if section =~ /^ *$/
|
893
|
+
opt[:move] = section.strip
|
894
|
+
when /flag/
|
895
|
+
opt[:flag] = true
|
896
|
+
end
|
897
|
+
end
|
898
|
+
|
899
|
+
|
822
900
|
if opt[:delete]
|
823
901
|
res = yn("Delete #{selected.size} items?", default_response: 'y')
|
824
902
|
if res
|
@@ -830,17 +908,35 @@ class WWID
|
|
830
908
|
|
831
909
|
if opt[:flag]
|
832
910
|
tag = @config['marker_tag'] || 'flagged'
|
833
|
-
selected.map!
|
911
|
+
selected.map! do |item|
|
912
|
+
if opt[:remove]
|
913
|
+
untag_item(item, tag)
|
914
|
+
else
|
915
|
+
tag_item(item, tag, date: false)
|
916
|
+
end
|
917
|
+
end
|
834
918
|
end
|
835
919
|
|
836
920
|
if opt[:finish] || opt[:cancel]
|
837
921
|
tag = 'done'
|
838
|
-
selected.map!
|
922
|
+
selected.map! do |item|
|
923
|
+
if opt[:remove]
|
924
|
+
untag_item(item, tag)
|
925
|
+
else
|
926
|
+
tag_item(item, tag, date: !opt[:cancel])
|
927
|
+
end
|
928
|
+
end
|
839
929
|
end
|
840
930
|
|
841
931
|
if opt[:tag]
|
842
932
|
tag = opt[:tag]
|
843
|
-
selected.map!
|
933
|
+
selected.map! do |item|
|
934
|
+
if opt[:remove]
|
935
|
+
untag_item(item, tag)
|
936
|
+
else
|
937
|
+
tag_item(item, tag, date: false)
|
938
|
+
end
|
939
|
+
end
|
844
940
|
end
|
845
941
|
|
846
942
|
if opt[:archive] || opt[:move]
|
@@ -860,13 +956,17 @@ class WWID
|
|
860
956
|
editable += "\n#{old_note}" unless old_note.nil?
|
861
957
|
editable_items << editable
|
862
958
|
end
|
959
|
+
divider = "\n-----------\n"
|
960
|
+
input = editable_items.map(&:strip).join(divider) + "\n\n# You may delete entries, but leave all divider lines in place"
|
863
961
|
|
864
|
-
new_items = fork_editor(
|
962
|
+
new_items = fork_editor(input).split(/#{divider}/)
|
865
963
|
|
866
964
|
new_items.each_with_index do |new_item, i|
|
965
|
+
|
867
966
|
input_lines = new_item.split(/[\n\r]+/).delete_if {|line| line =~ /^#/ || line =~ /^\s*$/ }
|
868
967
|
title = input_lines[0]&.strip
|
869
|
-
|
968
|
+
|
969
|
+
if title.nil? || title =~ /^#{divider.strip}$/ || title.strip.empty?
|
870
970
|
delete_item(selected[i])
|
871
971
|
else
|
872
972
|
note = input_lines.length > 1 ? input_lines[1..-1] : []
|
@@ -880,13 +980,47 @@ class WWID
|
|
880
980
|
item = selected[i].dup
|
881
981
|
item['title'] = title
|
882
982
|
item['note'] = note
|
883
|
-
item['date'] = Time.parse(date)
|
983
|
+
item['date'] = Time.parse(date) || selected[i]['date']
|
884
984
|
update_item(selected[i], item)
|
885
985
|
end
|
886
986
|
end
|
887
987
|
|
888
988
|
write(@doing_file)
|
889
989
|
end
|
990
|
+
|
991
|
+
if opt[:output]
|
992
|
+
selected.map! do |item|
|
993
|
+
item['title'] = "#{item['title']} @project(#{item['section']})"
|
994
|
+
item
|
995
|
+
end
|
996
|
+
|
997
|
+
@content = {'Export' => {'original' => 'Export:', 'items' => selected}}
|
998
|
+
options = {section: 'Export'}
|
999
|
+
|
1000
|
+
if opt[:output] !~ /(doing|taskpaper)/
|
1001
|
+
options[:output] = opt[:output]
|
1002
|
+
else
|
1003
|
+
options[:template] = '- %date | %title%note'
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
output = list_section(options)
|
1007
|
+
|
1008
|
+
if opt[:save_to]
|
1009
|
+
file = File.expand_path(opt[:save_to])
|
1010
|
+
if File.exist?(file)
|
1011
|
+
# Create a backup copy for the undo command
|
1012
|
+
FileUtils.cp(file, "#{file}~")
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
File.open(file, 'w+') do |f|
|
1016
|
+
f.puts output
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
@results.push("Export saved to #{file}")
|
1020
|
+
else
|
1021
|
+
puts output
|
1022
|
+
end
|
1023
|
+
end
|
890
1024
|
end
|
891
1025
|
|
892
1026
|
##
|
@@ -1068,6 +1202,33 @@ class WWID
|
|
1068
1202
|
@content[section]['items'] = section_items
|
1069
1203
|
end
|
1070
1204
|
|
1205
|
+
##
|
1206
|
+
## @brief Remove a tag on an item from the index
|
1207
|
+
##
|
1208
|
+
## @param old_item (Item) The item to tag
|
1209
|
+
## @param tag (string) The tag to remove
|
1210
|
+
##
|
1211
|
+
def untag_item(old_item, tags)
|
1212
|
+
title = old_item['title'].dup
|
1213
|
+
if tags.is_a? ::String
|
1214
|
+
tags = tags.split(/ *, */).map {|t| t.strip.gsub(/\*/,'[^ (]*') }
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
tags.each do |tag|
|
1218
|
+
if title =~ /@#{tag}/
|
1219
|
+
title.chomp!
|
1220
|
+
title.gsub!(/ +@#{tag}(\(.*?\))?/, '')
|
1221
|
+
new_item = old_item.dup
|
1222
|
+
new_item['title'] = title
|
1223
|
+
update_item(old_item, new_item)
|
1224
|
+
return new_item
|
1225
|
+
else
|
1226
|
+
@results.push(%(Item isn't tagged @#{tag}: "#{title}" in #{old_item['section']}))
|
1227
|
+
return old_item
|
1228
|
+
end
|
1229
|
+
end
|
1230
|
+
end
|
1231
|
+
|
1071
1232
|
##
|
1072
1233
|
## @brief Tag an item from the index
|
1073
1234
|
##
|
@@ -1075,23 +1236,29 @@ class WWID
|
|
1075
1236
|
## @param tag (string) The tag to apply
|
1076
1237
|
## @param date (Boolean) Include timestamp?
|
1077
1238
|
##
|
1078
|
-
def tag_item(old_item,
|
1239
|
+
def tag_item(old_item, tags, remove: false, date: false)
|
1079
1240
|
title = old_item['title'].dup
|
1241
|
+
if tags.is_a? ::String
|
1242
|
+
tags = tags.split(/ *, */).map(&:strip)
|
1243
|
+
end
|
1244
|
+
|
1080
1245
|
done_date = Time.now
|
1081
|
-
|
1082
|
-
title
|
1083
|
-
|
1084
|
-
|
1246
|
+
tags.each do |tag|
|
1247
|
+
if title !~ /@#{tag}/
|
1248
|
+
title.chomp!
|
1249
|
+
if date
|
1250
|
+
title += " @#{tag}(#{done_date.strftime('%F %R')})"
|
1251
|
+
else
|
1252
|
+
title += " @#{tag}"
|
1253
|
+
end
|
1254
|
+
new_item = old_item.dup
|
1255
|
+
new_item['title'] = title
|
1256
|
+
update_item(old_item, new_item)
|
1257
|
+
return new_item
|
1085
1258
|
else
|
1086
|
-
|
1259
|
+
@results.push(%(Item already @#{tag}: "#{title}" in #{old_item['section']}))
|
1260
|
+
return old_item
|
1087
1261
|
end
|
1088
|
-
new_item = old_item.dup
|
1089
|
-
new_item['title'] = title
|
1090
|
-
update_item(old_item, new_item)
|
1091
|
-
return new_item
|
1092
|
-
else
|
1093
|
-
@results.push(%(Item already @#{tag}: "#{title}" in #{old_item['section']}))
|
1094
|
-
return old_item
|
1095
1262
|
end
|
1096
1263
|
end
|
1097
1264
|
|
@@ -1305,10 +1472,10 @@ class WWID
|
|
1305
1472
|
if File.exist?(file)
|
1306
1473
|
# Create a backup copy for the undo command
|
1307
1474
|
FileUtils.cp(file, "#{file}~")
|
1475
|
+
end
|
1308
1476
|
|
1309
|
-
|
1310
|
-
|
1311
|
-
end
|
1477
|
+
File.open(file, 'w+') do |f|
|
1478
|
+
f.puts output
|
1312
1479
|
end
|
1313
1480
|
|
1314
1481
|
if @config.key?('run_after')
|
@@ -1522,13 +1689,16 @@ class WWID
|
|
1522
1689
|
note ||= ''
|
1523
1690
|
|
1524
1691
|
tags = []
|
1692
|
+
attributes = {}
|
1525
1693
|
skip_tags = %w[meanwhile done cancelled flagged]
|
1526
1694
|
i['title'].scan(/@([^(\s]+)(?:\((.*?)\))?/).each do |tag|
|
1527
1695
|
tags.push(tag[0]) unless skip_tags.include?(tag[0])
|
1696
|
+
attributes[tag[0]] = tag[1] if tag[1]
|
1528
1697
|
end
|
1698
|
+
|
1529
1699
|
if opt[:output] == 'json'
|
1530
1700
|
|
1531
|
-
|
1701
|
+
i = {
|
1532
1702
|
date: i['date'],
|
1533
1703
|
end_date: end_date,
|
1534
1704
|
title: title.strip, #+ " #{note}"
|
@@ -1537,6 +1707,10 @@ class WWID
|
|
1537
1707
|
tags: tags
|
1538
1708
|
}
|
1539
1709
|
|
1710
|
+
attributes.each { |attr, val| i[attr.to_sym] = val }
|
1711
|
+
|
1712
|
+
items_out << i
|
1713
|
+
|
1540
1714
|
elsif opt[:output] == 'timeline'
|
1541
1715
|
new_item = {
|
1542
1716
|
'id' => index + 1,
|
@@ -1640,7 +1814,7 @@ class WWID
|
|
1640
1814
|
|
1641
1815
|
totals = opt[:totals] ? tag_times('html', opt[:sort_tags]) : ''
|
1642
1816
|
engine = Haml::Engine.new(template)
|
1643
|
-
|
1817
|
+
out = engine.render(Object.new,
|
1644
1818
|
{ :@items => items_out, :@page_title => page_title, :@style => style, :@totals => totals })
|
1645
1819
|
else
|
1646
1820
|
items.each do |item|
|
@@ -1652,11 +1826,12 @@ class WWID
|
|
1652
1826
|
reset = ''
|
1653
1827
|
end
|
1654
1828
|
|
1655
|
-
if (item.
|
1829
|
+
if (item.key?('note') && !item['note'].empty?) && @config[:include_notes]
|
1656
1830
|
note_lines = item['note'].delete_if do |line|
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1831
|
+
line =~ /^\s*$/
|
1832
|
+
end
|
1833
|
+
note_lines.map! { |line| "\t\t#{line.sub(/^\t*/, '').sub(/^-/, '—')} " }
|
1834
|
+
if opt[:wrap_width]&.positive?
|
1660
1835
|
width = opt[:wrap_width]
|
1661
1836
|
note_lines.map! do |line|
|
1662
1837
|
line.strip.gsub(/(.{1,#{width}})(\s+|\Z)/, "\t\\1\n")
|
@@ -1669,7 +1844,7 @@ class WWID
|
|
1669
1844
|
output = opt[:template].dup
|
1670
1845
|
|
1671
1846
|
output.gsub!(/%[a-z]+/) do |m|
|
1672
|
-
if colors.
|
1847
|
+
if colors.key?(m.sub(/^%/, ''))
|
1673
1848
|
colors[m.sub(/^%/, '')]
|
1674
1849
|
else
|
1675
1850
|
m
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.79
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -168,6 +168,7 @@ files:
|
|
168
168
|
- lib/doing/helpers.rb
|
169
169
|
- lib/doing/version.rb
|
170
170
|
- lib/doing/wwid.rb
|
171
|
+
- lib/helpers/fuzzyfilefinder
|
171
172
|
- lib/templates/doing.css
|
172
173
|
- lib/templates/doing.haml
|
173
174
|
homepage: http://brettterpstra.com/project/doing/
|