emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Weight of headers
@ 2012-02-26  2:42 François Pinard
  2012-02-26 12:30 ` Nicolas Goaziou
  0 siblings, 1 reply; 6+ messages in thread
From: François Pinard @ 2012-02-26  2:42 UTC (permalink / raw)
  To: emacs-orgmode

Hello, all Org friends.

Here is a need I have once in a while, but for which I do not even have
realistic suggestions to offer (at least, so I feel).  Maybe someone
would offer more precise ideas. :-)

When I have a big Org file which I want to re-organize, one of the
criteria I use is to manage the overall plan, always keeping a logical
organization of things of course, and move things around so top-level
headers become of comparable weights.  By "weight", I mean the amount of
contents, which is a fuzzy concept (it could be measured as the number
of sub-headers or sub-items, the depth of structure, or even the raw
number or lines or characters).

It may look strange, but this is not so bizarre after all.  When reading
a book, it is unusual to have a chapter having one page next to a
chapter having hundreds of page; we expect that the effort of reading a
chapter is not widely different from the effort of reading another.  In
the same way, if I decide to tackle the topics under a header, I would
expect that the energy needed somehow announces the energy that would be
required to handle another level at the same level.  Of course, there
could be quite a variance, but nevertheless, I would like to keep that
variance within bounds.

And recursively!  The same way I would like to work an weight
equilibrium for top-level headers, I would like to do the same for the
sub-headers of a given header.

My need here is to get an estimate of the weight of displayed headers.
I could of course expand the whole document and page through to get an
idea, but at least in the document I'm currently handling, I'm just
overwhelmed.  (This is not the only document triggering this in me, I
remember having felt that need many times when I was using WorkFlowy).

I once thought that colors could encode the weight, but it just would
not fit Org mode so far that I understand it.  However, it seems that,
here and there, Org uses some overly magic to display extra information
-- for example, like with `C-c C-x C-d (`org-clock-display')'.  Maybe
that some similar machinery could be use to display header weights?  Or
maybe this would be overkill, because there are simpler ways which I
just do not know?

François

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Weight of headers
  2012-02-26  2:42 Weight of headers François Pinard
@ 2012-02-26 12:30 ` Nicolas Goaziou
  2012-02-27  3:36   ` François Pinard
  0 siblings, 1 reply; 6+ messages in thread
From: Nicolas Goaziou @ 2012-02-26 12:30 UTC (permalink / raw)
  To: François Pinard; +Cc: emacs-orgmode

Hello,

pinard@iro.umontreal.ca (François Pinard) writes:

> Here is a need I have once in a while, but for which I do not even have
> realistic suggestions to offer (at least, so I feel).  Maybe someone
> would offer more precise ideas. :-)
>
> When I have a big Org file which I want to re-organize, one of the
> criteria I use is to manage the overall plan, always keeping a logical
> organization of things of course, and move things around so top-level
> headers become of comparable weights.  By "weight", I mean the amount of
> contents, which is a fuzzy concept (it could be measured as the number
> of sub-headers or sub-items, the depth of structure, or even the raw
> number or lines or characters).
>
> It may look strange, but this is not so bizarre after all.  When reading
> a book, it is unusual to have a chapter having one page next to a
> chapter having hundreds of page; we expect that the effort of reading a
> chapter is not widely different from the effort of reading another.  In
> the same way, if I decide to tackle the topics under a header, I would
> expect that the energy needed somehow announces the energy that would be
> required to handle another level at the same level.  Of course, there
> could be quite a variance, but nevertheless, I would like to keep that
> variance within bounds.
>
> And recursively!  The same way I would like to work an weight
> equilibrium for top-level headers, I would like to do the same for the
> sub-headers of a given header.
>
> My need here is to get an estimate of the weight of displayed headers.
> I could of course expand the whole document and page through to get an
> idea, but at least in the document I'm currently handling, I'm just
> overwhelmed.  (This is not the only document triggering this in me, I
> remember having felt that need many times when I was using WorkFlowy).
>
> I once thought that colors could encode the weight, but it just would
> not fit Org mode so far that I understand it.  However, it seems that,
> here and there, Org uses some overly magic to display extra information
> -- for example, like with `C-c C-x C-d (`org-clock-display')'.  Maybe
> that some similar machinery could be use to display header weights?  Or
> maybe this would be overkill, because there are simpler ways which I
> just do not know?

The following function will give you the number of sub-headings and
paragraphs (or equivalent, i.e. tables verse-blocks....).

You'll need a recent Org to use it. 

#+begin_src emacs-lisp
(defun pinard-count-subtree-and-paragraphs ()
  "Return number of subtrees and paragraphs in the subtree at point."
  (interactive)
  (org-with-wide-buffer
   (org-narrow-to-subtree)
   (let ((tree (org-element-parse-buffer 'element)) (num-hl 0) (num-el 0))
     (org-element-map tree 'headline (lambda (hl) (incf num-hl)))
     (org-element-map
      tree '(paragraph table verse-block quote-block src-block example-block)
      (lambda (el) (incf num-el)))
     (message "Sub-headings: %d ; Parapraphs (or equivalent): %d"
              (1- num-hl) num-el))))
#+end_src

There's no colour, but it's a starter.


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Weight of headers
  2012-02-26 12:30 ` Nicolas Goaziou
@ 2012-02-27  3:36   ` François Pinard
  2012-02-27  3:56     ` François Pinard
  2012-02-27  4:52     ` Samuel Wales
  0 siblings, 2 replies; 6+ messages in thread
From: François Pinard @ 2012-02-27  3:36 UTC (permalink / raw)
  To: emacs-orgmode

Nicolas Goaziou <n.goaziou@gmail.com> writes:

> pinard@iro.umontreal.ca (François Pinard) writes:

>> My need here is to get an estimate of the weight of displayed headers.

> The following function will give you the number of sub-headings and
> paragraphs (or equivalent, i.e. tables verse-blocks....).

Wow, thanks!  That was a real good starter.

Roughly copying code from here and there (and not even understanding it,
some dead code might remain), I turned your function into the following:

--8<---------------cut here---------------start------------->8---
(defun fp-org-weight-display ()
  "Show header weights in the entire buffer.

Use \\[fp-org-weight-remove-overlays] to remove the header weights."
  (interactive)
  (fp-org-weight-remove-overlays)
  (let (weights)
      (save-excursion
	(goto-char (point-min))
        (outline-next-visible-heading 1)
        (while (not (eobp))
          (save-excursion
            (fp-org-weight-put-overlay (fp-org-weights-at-point)
                                     (funcall outline-level)))
          (outline-next-visible-heading 1))
	;; Arrange to remove the overlays upon next change.
	(when org-remove-highlights-with-change
	  (org-add-hook 'before-change-functions 'fp-org-weight-remove-overlays
			nil 'local)))))

(defvar fp-org-weight-overlays nil)
(make-variable-buffer-local 'fp-org-weight-overlays)

(defun fp-org-weight-put-overlay (weights &optional level)
  "Put an overlays on the current line, displaying WEIGHTS.
If LEVEL is given, prefix weights with a corresponding number of stars.
This creates a new overlay and stores it in `fp-org-weight-overlays', so that it
will be easy to remove."
  (let* ((c 60)
         (l (if level (org-get-valid-level level 0) 0))
	 (off 0)
	 ov tx)
    (org-move-to-column c)
    (unless (eolp) (skip-chars-backward "^ \t"))
    (skip-chars-backward " \t")
    (setq ov (make-overlay (1- (point)) (point-at-eol))
	  tx (concat (buffer-substring (1- (point)) (point))
		     (make-string (+ off (max 0 (- c (current-column)))) ?.)
		     (org-add-props (format "%s %3d headings %4d paragraphs%s"
                                            (make-string l ?*)
                                            (car weights)
                                            (cdr weights)
                                            (make-string (- 16 l) ?\ ))
			 (list 'face 'org-clock-overlay))
		     ""))
    (if (not (featurep 'xemacs))
	(overlay-put ov 'display tx)
      (overlay-put ov 'invisible t)
      (overlay-put ov 'end-glyph (make-glyph tx)))
    (push ov fp-org-weight-overlays)))

(defun fp-org-weight-remove-overlays (&optional beg end noremove)
  "Remove the occur highlights from the buffer.
BEG and END are ignored.  If NOREMOVE is nil, remove this function
from the `before-change-functions' in the current buffer."
  (interactive)
  (unless org-inhibit-highlight-removal
    (mapc 'delete-overlay fp-org-weight-overlays)
    (setq fp-org-weight-overlays nil)
    (unless noremove
      (remove-hook 'before-change-functions
		   'fp-org-weight-remove-overlays 'local))))

;; Compliment of Nicolas Goaziou <n.goaziou@gmail.com>, 2012-02-26
(defun fp-org-weights-at-point ()
  "Return cons of number of subtrees and paragraphs in the subtree at point.
Paragraphs (also encompasses equivalent structures)."
  (org-with-wide-buffer
   (org-narrow-to-subtree)
   (let ((tree (org-element-parse-buffer 'element)) (num-hl 0) (num-el 0))
     (org-element-map tree 'headline (lambda (hl) (incf num-hl)))
     (org-element-map
      tree '(paragraph table verse-block quote-block src-block example-block)
      (lambda (el) (incf num-el)))
     (cons (1- num-hl) num-el))))

(autoload 'org-element-parse-buffer "~/bureautique/emacs/_/org-mode/contrib/lisp/org-element")
(global-set-key "\C-cow" 'fp-org-weight-display)
--8<---------------cut here---------------end--------------->8---

The next to last line was needed because your function depends on
org-element.el, which is not directly available in Org mode, at least
as of today's Git repository.  Is it a better way to install that file?

Another questionable thing is that I'm using the org-clock-overly face,
while the code should probably use and define its own.

Once again, thanks Nicolas!

François

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Weight of headers
  2012-02-27  3:36   ` François Pinard
@ 2012-02-27  3:56     ` François Pinard
  2012-02-27  4:12       ` Nick Dokos
  2012-02-27  4:52     ` Samuel Wales
  1 sibling, 1 reply; 6+ messages in thread
From: François Pinard @ 2012-02-27  3:56 UTC (permalink / raw)
  To: emacs-orgmode

pinard@iro.umontreal.ca (François Pinard) writes:

> Roughly copying code from here and there (and not even understanding it,
> some dead code might remain), I turned your function into the
> following:

Hmph!  There seemingly is a problem however.

I tried it on a few files, and it usually does it works quickly, or in
no more than a few seconds.  However, on one of my Org files, after many
minutes, Emacs is still processing the command.  If I interrupt it (with
C-g), the main text displays its information, but the appendices do not.

I do not know if this matters: while all the appendices together do not
use much space in *this* file, they are merely made up of #+INCLUDE
directives, each preceded by a short introductory text.  The included
files may be a bit longish however.

François

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Weight of headers
  2012-02-27  3:56     ` François Pinard
@ 2012-02-27  4:12       ` Nick Dokos
  0 siblings, 0 replies; 6+ messages in thread
From: Nick Dokos @ 2012-02-27  4:12 UTC (permalink / raw)
  To: =?utf-8?Q?Fran=C3=A7ois?= Pinard; +Cc: nicholas.dokos, emacs-orgmode

François Pinard <pinard@iro.umontreal.ca> wrote:

> pinard@iro.umontreal.ca (François Pinard) writes:
> 
> > Roughly copying code from here and there (and not even understanding it,
> > some dead code might remain), I turned your function into the
> > following:
> 
> Hmph!  There seemingly is a problem however.
> 
> I tried it on a few files, and it usually does it works quickly, or in
> no more than a few seconds.  However, on one of my Org files, after many
> minutes, Emacs is still processing the command.  If I interrupt it (with
> C-g), the main text displays its information, but the appendices do not.
> 
> I do not know if this matters: while all the appendices together do not
> use much space in *this* file, they are merely made up of #+INCLUDE
> directives, each preceded by a short introductory text.  The included
> files may be a bit longish however.
> 

M-x toggle-debug-on-quit RET

Then when it gets into its rut and you interrupt with C-g, you'll get a
backtrace telling you where it was. If you repeat a couple of times and
you get the same backtrace each time, then you've probably found your
infinite looper.

Nick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Weight of headers
  2012-02-27  3:36   ` François Pinard
  2012-02-27  3:56     ` François Pinard
@ 2012-02-27  4:52     ` Samuel Wales
  1 sibling, 0 replies; 6+ messages in thread
From: Samuel Wales @ 2012-02-27  4:52 UTC (permalink / raw)
  To: François Pinard; +Cc: emacs-orgmode

Great way of doing it.

Another option is to create a new buffer and sort the headers by the
weight.  Ideally each header in the new buffer would be a link.

Yet another is to use the agenda.  I think it might have a new format
string option for the weight.  Then use the agenda to sort.

And another possibility is to gather weights recursively vs. for each
header.  This works for bytes.

Samuel

P.S.  Code from years ago.  Might or might not work.

;;(alpha-org-dus-tree)
(defun* alpha-org-dus-tree (&optional same (n 10))
  "Show the biggest subtrees in agenda files.  SAME says whether
to measure each node vs. each subtree."
  (interactive)
  ;;(show-all)
  ;;(with-current-buffer ...
  (switch-to-buffer "*alpha-org-dus-tree*")
  (erase-buffer)
  (insert
;;;  (cl-prettyprint
   (subseq (sort* (alpha-org-dus-tree-1 same)
                  #'>
                  :key #'car)
           0
           n)))
(defun alpha-org-dus-tree-1 (same)
  (org-map-entries #'(lambda ()
                       ;;(message "doing %s"
                       (cons (alpha-org-get-size same)
                             (org-get-heading)))
                   t
                   'agenda))
(defun alpha-org-get-size (&optional same)
  ;;(current-buffer)
  (- (save-excursion
       (ignore-errors
         (funcall (if same
                      ;;org-end-of-subtree t t
                      'org-forward-same-level
                    'outline-next-heading)
                  1))
       (point))
     (point)))

-- 
The Kafka Pandemic: http://thekafkapandemic.blogspot.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-02-27  6:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-26  2:42 Weight of headers François Pinard
2012-02-26 12:30 ` Nicolas Goaziou
2012-02-27  3:36   ` François Pinard
2012-02-27  3:56     ` François Pinard
2012-02-27  4:12       ` Nick Dokos
2012-02-27  4:52     ` Samuel Wales

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).