Maneira linguística de contar subárvores no modo org?

7

Existe uma maneira idiomática de contar subárvores no modo org?

Eu procurei aqui no emacs.sx e em outros mecanismos de pesquisa, mas não consegui encontrar uma resposta.

Eu sei que é possível contar facilmente subárvores com uma regex, mas eu queria saber se a API da organização tem meios para atender a necessidades de contagem mais sofisticadas, como,

  • Quantas manchetes de segundo nível sob a árvore atual?
  • Quantos títulos de terceiro nível no total no buffer atual?
gsl
fonte

Respostas:

4

org-map-entries é uma maneira típica de fazer isso:

(entradas do org-map-FUNC e ESCOPO DE PARTIDA opcional e resto SKIP)

Ligue para FUNC em cada título selecionado por MATCH no SCOPE.

Ele retorna os resultados de FUNC, para que você possa contá-los para obter o número de títulos correspondentes MATCH(que é uma org-agendastring de pesquisa de estilo). SCOPEpode ser configurado para treeverificar apenas o ponto da árvore, nilpesquisar o buffer inteiro, regionpesquisar a região atual e algumas outras mais especializadas.

Se você se importa apenas com o número de resultados, a função não precisa fazer nada. Seus exemplos se transformam em:

  • (length (org-map-entries t "LEVEL=2" 'tree))
  • (length (org-map-entries t "LEVEL=3" nil))

A MATCHstring pode procurar por tags, propriedades ou qualquer outra coisa que você possa fazer uma pesquisa na agenda.

erikstokes
fonte
11
Jinx! Grandes mentes sempre atender :-)
NickD
4

Estes não foram testados, mas devem estar próximos:

(length (org-map-entries t "LEVEL=2" 'tree))

(length (org-map-entries t "LEVEL=3" 'file))

org-map-entriesé muito poderoso e pode fazer muito mais do que contar coisas: consulte o documento para obter detalhes (que inclui um exemplo muito próximo disso).

NickD
fonte
11
Eu gostaria de poder aceitar duas respostas, a sua é tão boa quanto a de Erikstokes. Como isso não pode ser feito, tive que dar prioridade ao tempo. Muito obrigado pelo link.
GSL
11
Isso é inteiramente apropriado.
NickD
1

E aqui está a maneira não / menos idiomática:

(defun count-subtrees ()
  (interactive)
  (let (lvs)
    (save-excursion
      (goto-char (point-max))
      (while (outline-previous-heading)
        (let* ((hl (org-element-at-point))
               (lv (org-element-property :level hl)))
          (push lv lvs))))
    (let* ((depth (cl-sort lvs #'<))
           (min-lv (car depth))
           (max-lv (car (last depth))))
      (cl-loop for lv from min-lv to max-lv
               for count = (cl-count-if (lambda (elt)
                                          (= elt lv))
                                        lvs)
               collect (print (cons lv count))))))
jagrg
fonte
Obrigado, testei o código algumas horas atrás e ele não estava funcionando, mas agora funciona perfeitamente. Não posso aceitá-lo como resposta para o "caminho idiomático", mas ainda assim aprecio o código e com o voto positivo. Muito agradável. Obrigado.
gsl
11
Ufa. Eu estava tão perto de um voto negativo. De qualquer forma, obrigado pelas amáveis ​​palavras.
precisa saber é