有没有一种基于子标题todo-keyword来计算组织模式标题属性的方法?

问题描述 投票:0回答:1

这是我使用org-capture记录我的一天的方式

*** 2020-05-14 Thursday
:PROPERTIES:
:DoneA: 1
:DoneB: 1
:DoneC: 0
:Done: 0
:Kill: 1
:Gone: 1
:Rate: 5
:END:
:LOGBOOK:
CLOCK: [2020-05-14 Thu 04:55]--[2020-05-14 Thu 05:05] =>  0:10
:END:
**** DONE [#A] task a
**** GONE [#A] another task a
**** DONE [#B] task b
**** KILL other task

我手动计数并键入每个属性并使用简单费率手动填写费率属性

对于DONE [#A],我给分5,#B 3,KILL 2,走了-5因此费率属性= 5

是否有内置的函数或emacs可以基于org-todo-keywords计算子标题并将其放在上层标题PROPERTIES中?

我的elisp技能不足以提供自定义功能

emacs org-mode
1个回答
1
投票

没有这样的功能(这取决于您要查找的内容以及想要记录的方式的详细信息),但是肯定有构建自己的构建块,因此,我鼓励您提高自己的简易技能,尽管我会在下面尝试给出一个有动力的示例。

[首先要知道的是,组织模式提供a powerful functionorg-map-entries,它们可以遍历一组所选标题,并在访问每个标题时应用任意功能。例如,这是其用法的一个简单示例(直接来自手册-参见上面的链接),用于计算子树​​中与某些表达式match匹配的条目数:

(defun count-tasks (match)
  (length (org-map-entries t match 'tree)))

如果定义此功能,请将光标放在感兴趣的日期的标题(示例中为*** 2020-05-14 Thursday,然后按如下所示调用它:

 ESC-ESC-: (count-tasks "/+DONE) RET

它将返回子树中DONE个条目的数量-在您的示例中,该数量应为2。

要知道的第二件事是,有一个Property API提供了在标题上获取(org-entry-get)和设置(org-entry-put)属性的函数。因此,例如,您可以通过执行以下操作来为子树中的DONE任务数设置“ Done”属性(我假设您的光标仍然像以前一样位于标题):

  ESC-ESC-: (org-entry-put (point) "Done" (format "%d" (count-tasks "/+DONE")) RET

[我们计算任务,用format将数字转换为字符串,并添加(或修改)名为Done的属性,以将其字符串化的数字作为值。

这些都是碎片。现在,您必须将它们组合在一起以执行所需的操作。有些比赛比较复杂,例如要计算优先级为DONE的所有A标题,您需要说(count-tasks "PRIORITY=\"A\"/+DONE")

因此,您只需要对要计数的每个项目执行此操作,并设置适当的属性,但还要记住每个计数,以便您可以计算费率。那只是这些计数的加权和,如果您对向量有一点了解,您可能会意识到它是两个向量的dot (scalar) product:权重向量和计数向量,您可以通过乘以相应的元素来获得将两个向量中的所有向量相加,然后将所有结果相加(顺便说一句,您的权重未完全指定:您缺少DoneC类别的权重-我选择在下面为该类别添加权重1)。有多种方式可以做到这一点,具体取决于您如何表示这些向量。举一个简单的例子,我可以将它们表示为元素列表,然后在两个列表上将速率实现为map-reduce操作:

(defun rate (counts)
  (let ((weights '(5 3 1 2 -5)))
   (seq-reduce #'+ (mapcar* #'* weights counts) 0)))

您应该阅读mapcar*seq-reduce的文档字符串:它们非常有用(APL是一种经常使用这些操作的语言),但是如果您发现它有点晦涩,您也可以实现使用循环:

(defun rate-iter (counts)
  (let ((weights '(5 3 1 2 -5))
        (rate 0))
    (while counts
      (setq rate (+ rate (* (car counts) (car weights)))
            counts (cdr counts)
            weights (cdr weights)))
    rate))

然后您可以按照与上述完全相同的方式将其作为属性输入:

ESC-ESC-: (org-entry-put (point) "Rate" (format "%d" (rate counts)))

这些都是片段,但您仍然必须编写一些代码以将它们放在一起。希望这会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.