¿Manera idiomática de contar los subárboles del modo org?

7

¿Hay alguna forma idiomática de contar los subárboles del modo org?

Busqué aquí en emacs.sx y otros motores de búsqueda, pero no pude encontrar una respuesta.

Sé que uno podría contar fácilmente los subárboles con una expresión regular, pero me preguntaba si la API de la organización tiene medios para satisfacer necesidades de conteo más sofisticadas, como,

  • ¿Cuántos titulares de segundo nivel bajo el árbol actual?
  • ¿Cuántos titulares de tercer nivel en total hay en el búfer actual?
gsl
fuente

Respuestas:

4

org-map-entries es una forma típica de hacer esto:

(org-map-entry FUNC y opcional MATCH SCOPE y rest SKIP)

Llame a FUNC en cada título seleccionado por MATCH en SCOPE.

Devuelve los resultados de FUNC, por lo que puede contarlos para obtener el número de titulares que coinciden MATCH(que es una org-agendacadena de búsqueda de estilo). SCOPEse puede configurar para treeverificar que solo el punto del árbol esté activado , nilpara buscar en todo el búfer, regionpara buscar en la región actual y algunas otras más especializadas.

Si solo le importa la cantidad de resultados, la función no tiene que hacer nada. Tus ejemplos se convierten en:

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

La MATCHcadena puede buscar etiquetas, propiedades o cualquier otra cosa que pueda hacer una búsqueda de agenda.

erikstokes
fuente
1
¡Gafe! Las grandes mentes siempre se encuentran :-)
NickD
4

Estos no han sido probados pero deberían estar cerca:

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

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

org-map-entrieses muy poderoso y puede hacer mucho más que contar cosas: vea el documento para más detalles (que incluye un ejemplo muy cercano a esto).

NickD
fuente
1
Desearía poder aceptar dos respuestas, la tuya es tan buena como la de Erikstokes. Como no se puede hacer, tuve que dar prioridad al tiempo. Muchas gracias por el enlace.
gsl
1
Eso es completamente apropiado.
NickD
1

Y aquí está la forma no / 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
fuente
Gracias, probé el código hace unas horas y no funcionaba, pero ahora funciona perfectamente. No puedo aceptarlo como respuesta para la "forma idiomática", pero aún así aprecio el código y lo voté. Muy agradable. Gracias.
gsl
1
Uf. Estaba tan cerca de un voto negativo. De todos modos, gracias por las amables palabras.
jagrg