diff options
author | Leon Rische <leon.rische@me.com> | 2020-05-02 23:26:02 +0200 |
---|---|---|
committer | Leon Rische <leon.rische@me.com> | 2020-05-02 23:26:02 +0200 |
commit | e8303241918970b680701bc645b9b37af3634249 (patch) | |
tree | 8459e177ac39a63d7ea3871e446091f03c40cb98 | |
parent | 4bdd0f0e9ed4ddcb0773e1813eb787a22c49cfc9 (diff) |
Escape quotes in filenames, don't wrap cards into a file object
-rw-r--r-- | awk/index.awk | 39 | ||||
-rw-r--r-- | org-fc.el | 83 |
2 files changed, 56 insertions, 66 deletions
diff --git a/awk/index.awk b/awk/index.awk index 6559f3c..09f8d09 100644 --- a/awk/index.awk +++ b/awk/index.awk @@ -37,26 +37,21 @@ function parse_time(time) { return "(" ts_h " " ts_l ")"; } +# TODO: I'm sure there are cases not covered by this +function escape_filename(str) { + gsub(/\\/, "\\\\", str); + gsub(/"/, "\\\"", str); + return str; +} + ## File Parsing BEGINFILE { - # Data for files is only printed once we have encountered the - # first card. - printed_file_line = 0; - needs_file_closing = 0; - - # Stack of parent headline tags, level 0 is used for filetags + # Reset filetags parent_tags[0] = ""; state = state_file; } -ENDFILE { - if (needs_file_closing) { - print " ))"; - needs_file_closing = 0; - } -} - ## Filetags match($0, /#\+FILETAGS:[ \t]+(.*)/, a) { @@ -111,15 +106,6 @@ $0 ~ review_data_drawer { state = state_properties_done; } else if (state == state_review_data) { state = state_review_data_done; - # If this is the first card in a file, print the file "header" - if (!printed_file_line) { - print " (" \ - ":path \"" FILENAME "\"" \ - " :cards ("; - printed_file_line = 1; - needs_file_closing = 1; - } - # Card header inherited_tags = ""; for (i = 0; i < level; i++) { @@ -127,8 +113,9 @@ $0 ~ review_data_drawer { } local_tags = parent_tags[level]; - print " (" \ - ":id \"" properties["ID"] "\"" \ + print " (" \ + ":path \"" escape_filename(FILENAME) "\"" \ + " :id \"" properties["ID"] "\"" \ " :type " properties[type_property] \ " :created " parse_time(properties[created_property]) \ " :suspended " (suspended ? "t" : "nil") \ @@ -138,7 +125,7 @@ $0 ~ review_data_drawer { # Card positions for (i = 1; i < review_index; i++) { - print " (" \ + print " (" \ ":position \"" review_data[i]["position"] "\"" \ " :ease " review_data[i]["ease"] \ " :box " review_data[i]["box"] \ @@ -146,7 +133,7 @@ $0 ~ review_data_drawer { " :due " parse_time(review_data[i]["due"]) \ ")" } - print " ))"; + print " ))"; } next; } @@ -1193,10 +1193,10 @@ file (absolute path) as input." "Generate the shell command for calling COMMAND with xargs." (concat "xargs -0 " command)) +;;;; AWK Wrapper Functions + (defun org-fc-awk-index (paths) - "Generate a list of all files, cards & positions in PATHS. -If FILTER-DUE is non-nil, only list non-suspended cards that are -due for review." + "Generate a list of all cards and positions in PATHS." (read (shell-command-to-string (org-fc-awk--pipe @@ -1207,27 +1207,24 @@ due for review." :utils t :variables (org-fc-awk--indexer-variables))))))) -;;;; AWK Wrapper Functions - (defun org-fc-awk-positions-for-paths (paths &optional filter-due) "Generate a list of non-suspended positions in PATHS. If FILTER-DUE is non-nil, only list non-suspended cards that are due for review." (let (res (now (current-time))) - (dolist (file (org-fc-awk-index paths)) - (dolist (card (plist-get file :cards)) - (unless (plist-get card :suspended) - (dolist (pos (plist-get card :positions)) - (if (or (not filter-due) - (time-less-p (plist-get pos :due) now)) - (push - (list - :path (plist-get file :path) - :id (plist-get card :id) - :type (plist-get card :type) - :due (plist-get pos :due) - :position (plist-get pos :position)) - res)))))) + (dolist (card (org-fc-awk-index paths)) + (unless (plist-get card :suspended) + (dolist (pos (plist-get card :positions)) + (if (or (not filter-due) + (time-less-p (plist-get pos :due) now)) + (push + (list + :path (plist-get card :path) + :id (plist-get card :id) + :type (plist-get card :type) + :due (plist-get pos :due) + :position (plist-get pos :position)) + res))))) res)) (defun org-fc-awk-stats-reviews () @@ -1652,6 +1649,13 @@ rating the card." (lambda (pos) (time-less-p (plist-get pos :due) now)) (org-fc-awk-positions-for-paths paths)))) +(defun org-fc--hashtable-to-alist (ht) + "Convert a hash-table HT to an alist." + (let (res) + (dolist (key (hash-table-keys ht)) + (push (cons key (gethash key ht)) res)) + res)) + (defun org-fc-stats (index) "Compute statistics for an INDEX of cards and positions." (let* ((total 0) (suspended 0) @@ -1663,30 +1667,29 @@ rating the card." (time-day (time-subtract now (* 24 60 60))) (time-week (time-subtract now (* 7 24 60 60))) (time-month (time-subtract now (* 30 24 60 60)))) - (dolist (file index) - (dolist (card (plist-get file :cards)) - (incf total 1) - (if (plist-get card :suspended) - (incf suspended 1) - (let ((created (plist-get card :created))) - (if (time-less-p time-day created) - (incf created-day 1)) - (if (time-less-p time-week created) - (incf created-week 1)) - (if (time-less-p time-month created) - (incf created-month 1)) - (dolist (pos (plist-get card :positions)) - (incf n-pos 1) - (if (time-less-p (plist-get pos :due) now) - (incf n-due 1)) - (incf avg-ease (plist-get pos :ease)) - (incf avg-box (plist-get pos :box)) - (incf avg-interval (plist-get pos :interval))))) - (incf (gethash (plist-get card :type) by-type 0) 1))) + (dolist (card index) + (incf total 1) + (if (plist-get card :suspended) + (incf suspended 1) + (let ((created (plist-get card :created))) + (if (time-less-p time-day created) + (incf created-day 1)) + (if (time-less-p time-week created) + (incf created-week 1)) + (if (time-less-p time-month created) + (incf created-month 1)) + (dolist (pos (plist-get card :positions)) + (incf n-pos 1) + (if (time-less-p (plist-get pos :due) now) + (incf n-due 1)) + (incf avg-ease (plist-get pos :ease)) + (incf avg-box (plist-get pos :box)) + (incf avg-interval (plist-get pos :interval))))) + (incf (gethash (plist-get card :type) by-type 0) 1)) (list :total total :suspended suspended :due n-due - :by-type (org-fc-hashtable-to-alist by-type) + :by-type (org-fc--hashtable-to-alist by-type) :created-day created-day :created-week created-week :created-month created-month |