TiMueller · 2022-09-29 11:41
I am writing a novel in emacs, and I use level-1-headings for chapters and level-2-headings for scenes.
To have the right overview over the length of the current chapter, I wrote a function that counts the number of characters, starting from the `outline-up-heading` to the `outline-forward-same-level`, and divides them by 1.800 to give me a feeling for the number of pages the current chapter has.
If I start the function in the last chapter, though, I get the error message "No following same-level heading". Of course, there is none, and I'd like to use `point-max` in this case. But how can I find out whether I'm in the last chapter, using elisp? Is there a way to find out whether there is a header of the same level following?
Thank you for any advice!
lj-read-it · 2022-09-29 12:06
This is only in the abstract because I'm not fluent enough in ELisp to get a working code snippet off the top of my head, but it looks like you should detect whether `outline-forward-same-level` exists and set the end point of the character count at `outline-forward-same-level` or `point-max` depending on whether it does?
TiMueller · 2022-09-29 13:02
Yes, this is what I am trying to do. But I cannot find a way to detect wether `outline-forward-same-level` will work before actually calling it, and then, when it isn't working (because it reaches the end of the buffer), it throws the error and just exists my function. It is exactly this "you should detect" that I am missing. Any ideas are welcome!
YannZed · 2022-09-29 13:34
I actually had a similar problem and just hacked together a small solution that seems to work for now (in org mode but should be directly relatable to outline): https://github.com/ymherklotz/emacs-zettelkasten/blob/master/org-zettelkasten.el#L103-L114
The main idea is to get the current heading and the next heading, and compare if they are the same point or not. If they are the same point, you know you are at the end, otherwise not.
The other benefit of the function I linked is that it will automatically go over the current section, no matter where your actual point is.
itistheblurstoftimes · 2022-09-29 13:37
There are a few different ways to do this, but you could catch the error with condition-case and, if thrown, return (point-max). This seems to work, which will return the point of the next same level heading or point-max. If you don't want to move the point you can substitute save-excursion for progn; if you do want to move the point you can wrap (point-max) with (goto-char).
`(condition-case nil (progn (outline-forward-same-level 1) (point)) (error (point-max)))`
takeonrules · 2022-09-29 13:46
Can you catch the error and then call the other function?
TiMueller · 2022-09-29 13:59
Thank you so much! This was the solution, it works like a charm now. My programming skills are very limited, I didn't know one could catch an error like this and even use it for a condition-case. I'm excitied it solved my problem and I learned something valuable for the future too.
TiMueller · 2022-09-29 14:00
I didn't know one can catch an error and go on with the program. But it was the solution, it wonderfully works with itistheblurstoftimes' code now.
TiMueller · 2022-09-29 14:04
Thank you very much! This is interesting. I tried it out: `org-forward-heading-same-level` just stays at point when there is no further heading on this level, while `outline-forward-same-level` throws an error and exits the function. I didn't know they behave differently. It's an elegant solution how you just compare wether point has moved.