Idiomatische Methode zum Zählen von Teilbäumen im Org-Modus?

7

Gibt es eine idiomatische Möglichkeit, Teilbäume im Org-Modus zu zählen?

Ich habe hier auf emacs.sx und anderen Suchmaschinen gesucht, aber keine Antwort gefunden.

Ich weiß, dass man mit einem regulären Ausdruck leicht Teilbäume zählen kann, aber ich habe mich gefragt, ob die org-API Mittel hat, um anspruchsvollere Zählanforderungen zu erfüllen, wie z.

  • Wie viele Überschriften der zweiten Ebene unter dem aktuellen Baum?
  • Wie viele Überschriften der dritten Ebene insgesamt im aktuellen Puffer?
gsl
quelle

Antworten:

4

org-map-entries ist ein typischer Weg, dies zu tun:

(org-map-Einträge FUNC & optional MATCH SCOPE & Rest SKIP)

Rufen Sie FUNC an jeder von MATCH in SCOPE ausgewählten Überschrift auf.

Es gibt die Ergebnisse von zurück FUNC, sodass Sie sie zählen können, um die Anzahl der übereinstimmenden Überschriften zu erhalten MATCH(dies ist eine org-agendaStilsuchzeichenfolge). SCOPEkann eingestellt werden, um treezu überprüfen, ob nur der Baumpunkt aktiviert ist, nilum den gesamten Puffer regionzu durchsuchen, um die aktuelle Region und einige andere spezialisiertere Regionen zu durchsuchen.

Wenn Sie sich nur um die Anzahl der Ergebnisse kümmern, muss die Funktion nichts tun. Ihre Beispiele werden zu:

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

Die MATCHZeichenfolge kann nach Tags, Eigenschaften oder anderen Elementen suchen, nach denen Sie eine Agenda-Suche durchführen können.

erikstokes
quelle
1
Verhexen! Große Köpfe treffen sich immer :-)
NickD
4

Diese sind ungetestet, sollten aber nahe beieinander liegen:

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

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

org-map-entriesist sehr leistungsfähig und kann viel mehr als nur Dinge zählen: Einzelheiten finden Sie im Dokument (einschließlich eines Beispiels, das diesem sehr nahe kommt).

NickD
quelle
1
Ich wünschte, ich könnte zwei Antworten akzeptieren, deine ist so gut wie die von Erikstokes. Da dies nicht möglich ist, musste ich dem Timing Vorrang einräumen. Vielen Dank für den Link.
gsl
1
Das ist völlig angemessen.
NickD
1

Und hier ist der nicht / weniger idiomatische Weg:

(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
quelle
Vielen Dank, ich habe den Code vor ein paar Stunden getestet und er hat nicht funktioniert, aber jetzt funktioniert er perfekt. Ich kann es nicht als Antwort für den "idiomatischen Weg" akzeptieren, aber ich schätze den Code trotzdem und stimme zu. Sehr schön. Vielen Dank.
gsl
1
Puh. Ich war so nah an einer Gegenstimme. Trotzdem danke für die freundlichen Worte.
Jagrg