0

I have a use case where I tag a particular node in my Org-mode document with a unique hash. I then want to be able to programmatically access that node and append something to it. To that effect I wrote an Elisp function that returns a list of nodes with matching tags (this list should contain a single element in the non-pathological case):

(cl-defun get-node-by-tag (tag)
    "Given TAG, search the designated Org file and return a list
of nodes with matching tags."
    (with-temp-buffer
      (insert-file-contents *org-notes-file*)
      (let ((contents (org-element-parse-buffer)))
    (labels ((extract (el)
              (let ((c (org-element-contents el)))
                (append (when
                    (member tag (org-element-property :tags el))
                      (list el))
                    (mapcan #'extract (org-element-contents el))))))
      (extract contents)))))

I then get the result, which is of the form:

((headline
  (:raw-value "TODO Jake VanderPlas - Python Data Science Handbook" :begin 10089 :end 10343 :pre-blank 0 :contents-begin 10190 :contents-end 10343 :level 5 :priority nil :tags
...

and use its :end property to position myself at the end of that node.

Now here's the problem. I wrote the code on my work Emacs (27.2, running on Win 10), where it works fine. When I tried running it on my home machine (Emacs 27.1, running on PureOS), I found that the Org Element API returns results that are off by 2. The files on which I operate are different on both systems, but that shouldn't make a difference. One thing that came to my mind is the newline incompatibility (LF in Unix vs. CRLF in DOS/Windows), but I find it hard to believe the API would fail to take this into account. So I'm at a loss as to why the results are off. I'll appreciate any suggestions.

EDIT: As per @NickD's comment below, I'm attaching Org versions:

  • Home system (erroneous): 9.3
  • Work system (correct): 9.3

So the only difference here is the OS on which they run. And yes, the result is obviously wrong, i.e. I end up at the next node.

4
  • Do M-x org-version for both instances and update your question with that information. It may be that the earlier version (if there is one) was at fault and was fixed in the later version. Does the off-by-2 result cause you to end up at an obviously wrong place (e,g. within, rather than at the end of, the last word in the section)? Or is the difference just whitespace?
    – NickD
    Nov 7 at 14:21
  • Unfortunately I have no suggestion for the problem, but I was wondering if there is some particular reason for using cl-defun and labels instead of just using org-element-map... Nov 7 at 14:21
  • @dalanicolai For some reason I found my approach easier at the time of writing that code. It's an early draft, so it's likely I'll incorporate your suggestion. Thanks. Nov 7 at 15:05
  • Also, the let-bound c seems to be unused.
    – NickD
    Nov 8 at 5:09
0

The question about line endings may be checked by running a test file through unix2dos and seeing if you get the correct results from it at home.

I also suggest upgrading Org to the current version, 9.5, and see if that makes a difference. org-element-parse-buffer does call org-skip-whitespace, which does as its name suggests.

This would be a bug, if you verify that it's the line endings, and should be reported. You can use org-submit-bug-report.

2
  • Thanks for the suggestions. I upgraded to 9.5 and the problem persists. I'll try with the newline conversion. Nov 17 at 23:56
  • OK, I think I found a solution. Turns out the code works fine when there's an empty line between nodes, but fails when there isn't. So systematically subtracting 1 from the end position makes it work in both cases. I don't know if this behavior should be considered a bug or a feature :). Nov 18 at 0:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.