From e8e56f643b89676a6234fc69d999bd71fbcc1ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6stlin?= Date: Thu, 7 Jun 2018 10:37:41 +0200 Subject: [PATCH] Support links better suited for html export in org-kanban table Now supported are with the given priorities: ``` file:#customid id:theid file:heading heading ``` if the org-kanban table is in the same file, the variants without the file protocol are taken. Fixes #8 --- Cask | 2 +- features/work-org-kanban.feature | 40 +++++++++++++++--- org-kanban.el | 71 ++++++++++++++++++++++++++------ rakefile.rb | 22 +++++++++- todo.org | 2 + 5 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 todo.org diff --git a/Cask b/Cask index c9eaa87..bd4b6f1 100644 --- a/Cask +++ b/Cask @@ -1,7 +1,7 @@ (source gnu) (source melpa) -(package "org-kanban" "0.4.1" "Kanban for org-mode.") +(package "org-kanban" "0.4.5" "Kanban for org-mode.") (package-file "org-kanban.el") (depends-on "org") diff --git a/features/work-org-kanban.feature b/features/work-org-kanban.feature index 346918d..3062cdd 100644 --- a/features/work-org-kanban.feature +++ b/features/work-org-kanban.feature @@ -7,7 +7,12 @@ Feature: Work kanban tables * DONE b * DONE c :PROPERTIES: - :CUSTOM_ID: 1 + :CUSTOM_ID: customid1 + :ID: id1 + :END: + * DONE d + :PROPERTIES: + :ID: id2 :END: * Kanban #+BEGIN: kanban @@ -25,12 +30,13 @@ Feature: Work kanban tables |------+------| | [[a][a]] | | | | [[b][b]] | - | | [[#1][c]] | + | | [[#customid1][c]] | + | | [[id:id2][d]] | #+END: """ - Scenario: Move Todo Item - When I go to line "11" + Scenario: Move Todo Items + When I go to line "16" And I run org-kanban/shift Then I should see: """ @@ -38,7 +44,6 @@ Feature: Work kanban tables |------+------| | | [[a][a]] | | | [[b][b]] | - | | [[#1][c]] | """ And I press "j" @@ -85,3 +90,28 @@ Feature: Work kanban tables | [[a][a]] | | | | [[b][b]] | """ + + Scenario: Move Todo Items by customid + When I go to line "18" + And I run org-kanban/prev + Then I should see: + """ + | TODO | DONE | + |------+------| + | [[a][a]] | | + | | [[b][b]] | + | [[#customid1][c]] | | + """ + + Scenario: Move Todo Items by id + When I go to line "19" + And I run org-kanban/prev + Then I should see: + """ + | TODO | DONE | + |------+------| + | [[a][a]] | | + | | [[b][b]] | + | | [[#customid1][c]] | + | [[id:id2][d]] | | + """ diff --git a/org-kanban.el b/org-kanban.el index 4400ce8..55a48eb 100644 --- a/org-kanban.el +++ b/org-kanban.el @@ -7,7 +7,7 @@ ;; Contributors: ;; Aldric Giacomoni ;; Keywords: org-mode, org, kanban, tools -;; Package-Requires: ((dash "2.13.0") (emacs "24.4")) +;; Package-Requires: ((dash "2.13.0") (emacs "24.4") (org "9.1")) ;; Package-Version: 0.4.5 ;; Homepage: http://github.com/gizmomogwai/org-kanban @@ -63,7 +63,9 @@ (current-buffer) (org-heading-components) org-todo-keywords-1 - (org-entry-get nil "CUSTOM_ID"))) + (org-entry-get nil "CUSTOM_ID") + (org-entry-get nil "ID") + )) (defun org-kanban//todo-info-get-file (todo-info) "Get the buffer from a TODO-INFO." @@ -81,6 +83,10 @@ "Get the CUSTOM_ID from a heading TODO-INFO." (nth 3 todo-info)) +(defun org-kanban//todo-info-get-id (todo-info) + "Get the ID from a heading TODO-INFO." + (nth 4 todo-info)) + (defun org-kanban//heading-get-title (heading) "Get the title from a org-mode HEADING." (nth 4 heading)) @@ -97,20 +103,49 @@ link-abbreviation) heading)) -(defun org-kanban//link (file heading kanban search-for multi-file custom-id) - "Create a link to FILE and HEADING if the KANBAN value is equal to SEARCH-FOR. MULTI-FILE indicates if simple links may be used. CUSTOM_ID if available. This means, that the org-kanban table links are in one of 4 forms: with or without file: and with heading as link or #custom_id." - (if (and (stringp kanban) (string-equal search-for kanban)) +(defun org-kanban//link-for-custom-id (custom-id use-file file description) + "Create a link for CUSTOM-ID." + (if custom-id + (if use-file + (format "[[file:%s::#%s][%s]]" file custom-id description) + (format "[[#%s][%s]]" custom-id description)) + nil)) + +(defun org-kanban//link-for-id (id description) + "Create a link for ID." + (if id + (format "[[id:%s][%s]]" id description) + nil)) + +(defun org-kanban//link-for-heading (heading use-file file description) + "Create a link for a heading." + (if heading + (if use-file + (format "[[file:%s::*%s][%s]]" file heading description) + (format "[[%s][%s]]" heading description)) + (error "Illegal state"))) + +(defun org-kanban//link (file heading kanban search-for multi-file custom-id id) + "Create a link to FILE and HEADING if the KANBAN value is equal to SEARCH-FOR. MULTI-FILE indicates if the link must work across several files. CUSTOM_ID links are used if given. ID links are used if given. This means, that the org-kanban table links are in one of several forms: + - file:#custom-id + - #custom-id + - id:id + - file:heading + - heading +" + (if + (and (stringp kanban) (string-equal search-for kanban)) (let* ( (link-abbreviation (car org-kanban/abbreviation)) (link-max-length (cdr org-kanban/abbreviation)) (description (org-kanban//heading-to-description heading link-max-length link-abbreviation)) - (heading-or-id (if custom-id (format "#%s" custom-id) heading)) (use-file (and multi-file (not (eq file (current-buffer))))) - ) - (if use-file - (format "[[file:%s::%s][%s]]" file heading-or-id description) - (format "[[%s][%s]]" heading-or-id description) - )) "")) + ) + (or (org-kanban//link-for-custom-id custom-id use-file file description) + (org-kanban//link-for-id id description) + (org-kanban//link-for-heading heading use-file file description) + )) + "")) (defun org-kanban//todo-keywords (files mirrored) "Get list of org todos from FILES. MIRRORED describes if keywords should be reversed." @@ -133,7 +168,8 @@ TODO-KEYWORDS are all the current org todos. MULTI-FILE indicates, if simple fil (title (org-kanban//heading-get-title heading)) (kanban (org-kanban//heading-get-todo-keyword heading)) (custom-id (org-kanban//todo-info-get-custom-id todo-info)) - (row-entries (-map (lambda(i) (org-kanban//link file title i kanban multi-file custom-id)) todo-keywords)) + (id (org-kanban//todo-info-get-id todo-info)) + (row-entries (-map (lambda(i) (org-kanban//link file title i kanban multi-file custom-id id)) todo-keywords)) (row (string-join row-entries "|"))) (format "|%s|" row))) @@ -166,6 +202,7 @@ TODO-KEYWORDS are all the current org todos. MULTI-FILE indicates, if simple fil (defun org-kanban//find-by-custom-id (line) "" + (message "find by custom id %s" line) (let* ( (pattern "\\[\\[#\\(.*\\)\\]\\[.*\\]") (match (string-match pattern line)) @@ -182,6 +219,15 @@ TODO-KEYWORDS are all the current org todos. MULTI-FILE indicates, if simple fil (entry (and heading (org-find-exact-headline-in-buffer heading)))) (if entry (list (buffer-file-name) entry) nil))) +(defun org-kanban//find-by-id (line) + "" + (let* ( + (pattern "\\[\\[id:\\(.*\\)\\]\\[.*\\]") + (match (string-match pattern line)) + (id (and match (match-string 1 line))) + (entry (and id (org-find-entry-with-id id)))) + (if entry (list (buffer-file-name) entry) nil))) + (defun org-kanban//find () "Search for a todo matching to the current kanban table row. Return file and marker." @@ -196,6 +242,7 @@ Return file and marker." (or (org-kanban//find-by-file-and-custom-id line) (org-kanban//find-by-file-and-heading line) (org-kanban//find-by-custom-id line) + (org-kanban//find-by-id line) (org-kanban//find-by-heading line)))) (defun org-kanban/next () diff --git a/rakefile.rb b/rakefile.rb index 7286371..3373b89 100644 --- a/rakefile.rb +++ b/rakefile.rb @@ -1,3 +1,4 @@ + task :default => :test desc 'prepare' @@ -5,8 +6,25 @@ sh "cask install" end +def get_match(content, regexp) + match = regexp.match(content) + if !match + raise 'cannot match' + end + return match[1] +end + desc 'test' task :test do -# sh "cask exec ecukes --verbose --debug --reporter magnars" - sh "cask exec ecukes --reporter magnars --quiet" + org_kanban_melpa_version = get_match(File.read('org-kanban.el', encoding: 'UTF-8'), Regexp.new('Package-Version: (.*)')) + org_kanban_elisp_version = get_match(File.read('org-kanban.el', encoding: 'UTF-8'), Regexp.new('\\(message "org-kanban (.*)"\\)\\)')) + cask_version = get_match(File.read('Cask', encoding: 'UTF-8'), Regexp.new('\\(package "org-kanban" "(.*)" "Kanban for org-mode."\\)')) + if org_kanban_melpa_version != org_kanban_elisp_version or org_kanban_elisp_version != cask_version + puts "org_kanban_melpa_version: #{org_kanban_melpa_version}" + puts "org_kanban_elisp_version: #{org_kanban_elisp_version}" + puts "org_kanban_cask_version: #{cask_version}" + raise 'versions inconsistent' + end + sh "cask exec ecukes --verbose --debug --reporter magnars" +# sh "cask exec ecukes --reporter magnars --quiet" end diff --git a/todo.org b/todo.org new file mode 100644 index 0000000..84b9549 --- /dev/null +++ b/todo.org @@ -0,0 +1,2 @@ +* Todos +** TODO write test for multi file org kanban table