diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2019-03-21 21:25:00 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2019-03-21 21:25:00 +0100 |
| commit | fdae89fac1e5491d5902c48dbf7c14e0bd4435cc (patch) | |
| tree | 803b8f25cce48da12b34cc4dcf41590d06d09fc6 | |
| parent | 34285cac1518491cf5240b90e0fd971a4a3d1dc5 (diff) | |
| download | mark-fdae89fac1e5491d5902c48dbf7c14e0bd4435cc.tar.gz mark-fdae89fac1e5491d5902c48dbf7c14e0bd4435cc.zip | |
rewrite mark to use more coreutils and support multiple marks per day
| -rw-r--r-- | README.md | 12 | ||||
| -rw-r--r-- | mark.fish | 397 |
2 files changed, 134 insertions, 275 deletions
@@ -1,18 +1,18 @@ # mark -mark is a little fish-shell script to mark days and get statistics about your marks. +`mark` is a little fish-shell utility to mark days in a simple plaintext format. ## Requirements + fish-shell -+ cal -+ date -+ cat -+ sed ++ coreutils ## Usage -At the current state you have to use all mark functions on there own. + No cmd specified + Usage: mark [cmd | <mark>] date [cmd args] + Cmds: + print [before] [after]: print marks in range [date-before, date-after] ## License @@ -1,286 +1,145 @@ # Copyright (c) 2017-2019 Florian Fischer. All rights reserved. # Use of this source code is governed by a MIT license found in the LICENSE file. -function __mark_print_block -d "prints block from mark_store" -a block file - set c (string match -r "#$block#[^#]*" (echo (cat $file))) - set c (string replace "#$block#" "" $c) - echo (string trim $c) +function mark_find_store --argument store + if test -n "$store" -a -f "$store" + echo $store + return + end + + if set -q MARK_STORE + echo $MARK_STORE + return + end + + for dir in $XDG_DATA_DIRS + if test -f $dir/mark/marks + echo $dir/mark/marks + return + end + end + + set xdg_data_home $XDG_DATA_HOME + if test -z $xdg_data_home + set xdg_data_home ~/.local/share + end + if test -f $xdg_data_home/mark/marks + echo $xdg_data_home/mark/marks + return + end + + if test -f ~/.marks + echo ~/.marks + return + end + + echo "Creating new mark file at $xdg_data_home/mark/marks" >&2 + mkdir -p $xdg_data_home/mark + mark_new_year_block (date +%Y) > $xdg_data_home/mark/marks + echo $xdg_data_home/mark/marks end -function __mark_get --description 'extract information from a mark_store' \ - -a store year month day range - - set marks (__mark_print_block store $store) - set marks (string split " " $marks) - - # find year in marks - for i in (seq 1 (count $marks)) - if string match -q -r "^$year:\$" $marks[$i] - set year_offset $i - break - end - end - - # return if year not in the data - if not set -q year_offset - echo year $year not found in the store >&2 - return 1 - end - - if test $day -eq 0 - # collect all marks in month - set marks_list - for m in (string split "" (string split ':' $marks[(math $month+$year_offset)])[2]) - # check if $m is a mark - if test $m != '?' - set incremented false - # check if a count for $m is already stored in $marks_list - for e in $marks_list - if test $e = mark_$m - set incremented true - # build count variable name - set cur mark_$m - # increment mark count - set $cur (math $$cur + 1) - end - end - # add count for $m if it was not in $marks_list - if test $incremented = false - set mark_$m 1 - set marks_list $marks_list mark_$m - end - end - end - # print result - echo (count $marks_list) different marks found: - for e in $marks_list - echo (string split '_' $e)[2]:$$e - end - else - # get range - if test $range -ne 0 - set range (math $range - 1) - set start_s (date -d "$year-$month-$day - $range days" +%s) - set start_d (string split "-" (date -d @$start_s +%Y-%m-%d)) - - set year_diff (math $year - $start_d[1]) - set first_year_offset (math "$year_offset - 13*$year_diff") - - if test $first_year_offset -le 0 - echo range is to big for available data! >&2 - return 1 - end - - # collect relevant marks - # $s = oldest month to add - set s $start_d[2] - set e 12 - for y in (seq $first_year_offset +13 $year_offset) - # set e if last year is reached - if test $y -eq $year_offset - set e $month - end - for i in (seq $s $e) - set line_marks (string split ":" $marks[(math $y + $i)])[2] - # ignore empty lines (years <yyyy>:\n) - if not test "" = $line_marks - set range_marks $range_marks $line_marks - end - end - # reset s -> start with january - set s 0 - end - - set marks (string split "" $range_marks) - - set marks $marks[(math $start_d[3])..(math $start_d[3] + $range)] - - echo (string join "" $marks) - else - set marks (string split "" (string split ":" $marks[(math $month+$year_offset)])[2]) - echo $marks[$day] - end - end +function mark_new_year_block --argument year + echo "$year": + echo "01: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "02: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "03: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "04: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "05: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "06: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "07: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "08: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "09: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "10: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "11: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" + echo "12: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?" end -function __mark_new_store --description "generates new mark store for one year" - set year (date "+%Y") - echo "#colors#" - echo "#store#" - echo $year: - for m in (seq 1 12) - echo -n "$m:" - switch $m - case 1 3 5 7 8 10 12 - set days 31 - case 4 6 9 11 - set days 30 - case 2 - if date -d "$year-02-29" >/dev/null ^/dev/null - set days 29 - else - set days 28 - end - end - - for d in (seq 1 $days) - echo -n "?" - end - echo - end - echo "#end#" +function mark_years_in_store + grep -o "....:" (mark_find_store) | sed "s/.//5" end -function __mark_print_month --description "print overview over a month" \ - -a store year month - - # get marks - set marks (string split " " (__mark_print_block "store" $store)) - set marks (string split ":" $marks[(math $month + 1)])[2] - set marks (string split "" $marks) - - # get colors - set colors (__mark_print_block "colors" $store) - - # get formatted representation for month - set month (cal $month $year) - # strip of headline - set month $month[2..-1] - # day count - set day 1 - for l in $month - set chars (string split "" $l) - set cursor 1 - # used if day is double-digit - set cursor_n $cursor - while test $cursor -le (count $chars) - if string match -q -r "[0-9]" $chars[$cursor] - if test (string length $day) -eq 2 - set cursor_n (math $cursor + 1) - end - if test $marks[$day] != "?" - # find color - if set col (string match -r "$marks[$day]:[^\ ]*" $colors) - set col (string split ":" $col)[2] - set_color $col - else - # default to yellow - set_color yellow - end - - echo -n (string join "" $chars[$cursor..$cursor_n]) - set_color normal - else - echo -n (string join "" $chars[$cursor..$cursor_n]) - end - test $cursor_n -ne $cursor; and set cursor (math $cursor + 1) - set day (math $day + 1) - else - echo -n $chars[$cursor] - end - set cursor (math $cursor + 1) - set cursor_n $cursor - end - echo - end +function mark_print_year --argument year + grep --color=never -A12 $year (mark_find_store) end -function __mark_set --description 'mark a day in a store' \ - -a store year month day sign force - - # calculate offset: $day+1 (+1 if m > 9) because of "<month>:" - set offset (math -s0 "$day + 1 + $month/10") - - set marks (__mark_print_block store $store) - set marks (string split " " $marks) - - # copy everything before #store# - string split " " (string match -r "^.*#store#" (echo (cat $store))) > $store.new - - # crawl store - set m 0 - # correct year sub-block - set is_year false - for l in $marks - if begin test $is_year = false - and string match -q -r "^$year:\$" $l - end - set is_year true - end - - if test $is_year = true - if test $m -ne $month - echo $l >> $store.new - else - # replace the char at offset with $sign - if test $force = true - echo $l | sed "s/^\(.\{$offset\}\)./\1$sign/" >> $store.new - else - echo $l | sed "s/^\(.\{$offset\}\)?/\1$sign/" >> $store.new - end - end - - set m (math "$m+1") - # not in year sub-block any more - if test $m -eq 13 - set is_year false - end - else - echo $l >> $store.new - end - end - - #copy everything after #store# - set store_and_rest (string match -r "#store#.*\$" (echo (cat $store))) - string split " " (string replace -r "#store#[^#]*" "" $store_and_rest) >> $store.new - - mv $store.new $store +function mark_print_month --argument year month + mark_print_year $year | sed -n (math $month +1)"p" end -function mark - # defaults - set store $__mark_store - set year (date "+%Y") - set month (math (date "+%m") "*1") - set day (math (date "+%d") "*1") - # range of marks returned around date - set range 0 - # sign to write to the store - set sign ! - set force false +function mark_print_date --argument date + set date (string split "-" $date) + mark_print_month $date[1] $date[2] | cut -d' ' -f(math $date[3] + 1) +end - for i in (seq 2 (count $argv)) - if string match -q -- "-d=*" "$argv[$i]" - set day (string replace -- "-d=" "" $argv[$i]) - else if string match -q -- "-m=*" "$argv[$i]" - set month (string replace -- "-m=" "" $argv[$i]) - else if string match -q -- "-y=*" "$argv[$i]" - set year (string replace -- "-y=" "" $argv[$i]) - else if string match -q -- "-s=*" "$argv[$i]" - set store (string replace -- "-s=" "" "$argv[$i]") - else if string match -q -- "-z=*" "$argv[$i]" - set sign (string replace -- "-z=" "" "$argv[$i]") - else if string match -q -- "-r=*" "$argv[$i]" - set range (string replace -- "-r=" "" "$argv[$i]") - else if string match -q -- "-f" "$argv[$i]" - set force true - else - echo unrecognised option: $argv[$i] >&2 - return 1 - end - end +function mark_print_dates --argument date before after + if test -n "$before" -a "$before" -gt 0 + for b in (seq 1 $before | tac) + set cur_date (date -I -d "$date - $b days") + mark_print_date $cur_date + end + end + + mark_print_date $date + + if test -n "$after" -a "$after" -gt 0 + for a in (seq 1 $after) + set cur_date (date -I -d "$date + $a days") + mark_print_date $cur_date + end + end +end - if not test -f $store - echo "store is not a file" >&2 - return 1 - end +function mark_append_mark --argument mark date + set date_a (string split "-" $date) + set year $date_a[1] + set month $date_a[2] + set day $date_a[3] + + for y in (mark_years_in_store) + if test "$y" != $year + mark_print_year $y + else + # set first mark + if test (mark_print_date $date) = "?" + mark_print_year $year | sed (math $month + 1)"s/ [^[:space:]]*/ $mark/"$day + # append to marks + else + mark_print_year $year | sed (math $month + 1)"s/ [^[:space:]]*/&$mark/"$day + end + end + echo + end +end - switch $argv[1] - case "set" "s" - __mark_set $store $year $month $day $sign $force - case "get" "g" - __mark_get $store $year $month $day $range - case "month" "m" - __mark_print_month $store $year $month - end +function mark --argument cmd date + if test -z "$cmd" + echo "No cmd specified" + echo "Usage: mark [cmd | <mark>] date [cmd args]" + echo "Cmds:" + echo " print [before] [after]: print marks in range [date-before, date-after]" + return 1 + end + + if test -n "$argv[2]" + if not date -d "$argv[2]" > /dev/null 2>&1 + echo $argv[2] " is not a valid date" >&2 + end + set date "$argv[2]" + else + set date (date -I) + end + + switch "$cmd" + case "print" + mark_print_dates $date $argv[3] $argv[4] + case "*" + set store (mark_find_store) + + cp $store $store.bak + + mark_append_mark $cmd $date > $store.new + + mv $store.new $store + end end |
