I've been using org-element to identify blocks in org buffers[1]. It's working great in both before & after change functions. It can readily identify newly formed blocks as well as blocks which get "damaged" (header/footer edited). So much better than scanning the buffer yourself, especially since the work of identifying elements is going to be done anyway.
I had hoped to apply a unique `field' to the hard space prefix of indented org blocks (real indentation, not just via org-indent). This would make it easier to keep point "in the block" while navigating and editing inside it. Unfortunately, the presence of `field' properties in an org buffer interferes with org-element's updates, as it makes free use of e.g. `line-beginning-position' (which stops at field boundaries). This can lead to misidentification and even lead to hangs in org-element scanning [2, org 9.8pre-53cd3f]. I suspect the solution is simply to bind `inhibit-field-motion' to t during relevant org-element scanning functions. Note that the font-locking of blocks is not similarly interfered with by fields. [1] https://github.com/jdtsmith/org-modern-indent/blob/fcd4368476a9c4eadfac4d6f51159d90a15de15a/org-modern-indent.el#L106 [2] In an empty org buffer with org-indent-mode enabled, evaluate: (let ((pref (propertize " " 'field 'org-test))) (insert "* Heading\n\n" pref "#+begin_example\n" pref " Some Text\n" pref "#+end_example\n\n* New Heading\n\n"))