How to get the headline an element belongs to - emacs

I can use org-element-context on a, e.g., link on the page and walk up the parents to see which paragraph it belongs to. However, I'd like to get the value of the header the paragraph/link is under. Is there a sane way to do this? I'm new to the org-mode AST, so any general tips would be appreciated.

It depends on what information you need out of the heading:
If you just want the text of the heading, you can use org-get-heading. (EDIT: This function appears to have been added somewhere between Org versions 8.2.10 and 8.3.2.) Note that this function returns a propertized text string (see this manual entry for more information, but for most purposes, you can ignore the text properties and just treat it as a string).
If you want the position of heading, I (surprisingly) can't find anything that just gives you that out of the box. I'd do something like this:
(defun my/org-back-to-heading-safe (&optional invisible-ok)
"As `org-back-to-heading', but return nil before first heading."
(condition-case err
(org-back-to-heading invisible-ok)
(error nil)))
(defun my/org-get-heading-pos ()
"Return position of heading containing point.
If before the first heading of the buffer, return nil.
Do not move point."
(save-excursion (my/org-back-to-heading-safe :invisible-ok)))
If you want the full list like org-element-context, you can do something similar:
(defun my/org-element-heading ()
"Return context for heading containing point.
As `org-element-context', if point is on a heading. Otherwise,
return the value `org-element-context' would return if point were
on its heading.
If before the first heading of the buffer, return nil."
(save-excursion
(when (my/org-back-to-heading-safe :invisible-ok)
(org-element-context))))

Related

Can Emacs' org-mode recognize tags within (instead of just at the endof ) a headline

I am learning how to use Emacs and org-mode, and am wondering whether Emacs can support tags within rather than just at the end of headlines (whether natively or through a package or configuration in ~/.emacs).
Put differently, Emacs natively supports tags in this form:
* This is a headline. :tag1:tag2:
Is there a way to get Emacs to recognize tags in the format below in addition?
* This is a headline with :tag1: and :tag2:.
I've been searching for answers for several hours, and haven't found this question anywhere else; I'd be grateful for any advice!
The real answer to this question is in #lawlist's comment above, that (to quote #lawlist) it "is not possible [to get org-mode to recognize tags within a line of text instead of at the end of the line] without substantially modifying several aspects of org-mode yourself."
For this reason, if #lawlist writes the comment up as an answer, I'll accept it. I'm also writing up this additional answer, though, for anyone like me who comes along and, learning this, wants a way to take some text and automatically generate org-mode tags for it. Following the discussion in the comments above, I've written a function in elisp below, which allows a user to highlight some text and automatically find any tags within the text (here, in the form {{tag}}) and concatenate them in org-mode tag format at the end of the first line.
(defvar tag-regexp-for-generating-org-mode-tag-list-from-text "{{\\(.*?\\)}}"
"A regular expression, in double-quotes, used for finding 'tags' within lines of text (these can then be translated into org-mode syntax tags.
For example, in the string \"This text contains the 'tags' {{tag1}} and {{tag2}}\", the default regular expression
\"{{\\(.*?\\)}}\"
would find \"tag1\" and \"tag2\", which could then be transformed into org-mode syntax tags, \":tag1:tag2:\"")
;; Following https://emacs.stackexchange.com/a/12335, use just the selected region.
(defun generate-org-mode-tag-list-from-selected-text (beginning-of-selected-region end-of-selected-region)
"Take a highlighted section of text, find all strings within that text that match the search parameters defined in the variable tag-regexp-for-generating-org-mode-tag-list-from-text (by default, strings of the form {{tag1}} {{tag2}}), and concatenate them into a set of org-mode tags (:tag1:tag2:)
When text is highlighted, the argumentes beginning-of-selected-region and end-of-selected-region will be automatically populated.
"
(interactive "r") ;; 'r' mode will auto-populate 'beginning-of-selected-region' and 'end-of-selected-region' above with the values of region-beginning and region-end.
(if (use-region-p) ;; If a region is actively highlighted
(progn ;; Start a multi-line sequence of commands
;; Following https://learnxinyminutes.com/docs/elisp/, go to the beginning-of-selected-region (here, of the selected region), and do a find-and-replace.
(setq list-of-tag-strings (list)) ;; Create a blank list, which we'll fill in below.
(goto-char beginning-of-selected-region) ;; Go to the beginning of the selected region (we'll then search forward from there.
;; A regex of "{{\\(.*?\\)}}" below looks for tags in {{this}} form. You can specify any other regex here instead.
(while (re-search-forward tag-regexp-for-generating-org-mode-tag-list-from-text end-of-selected-region 't) ;; Search forward, but only up to the end-point of the selected region (otherwise, end-of-selected-region could be replaced with nil here).
(add-to-list 'list-of-tag-strings ;; Add to the list called list-of-tag-strings
(replace-regexp-in-string "[[:space:]|:|-]+" "_" (match-string 1)) ;; Since org-mode tags cannot have spaces or colons (or dashes?) within them, replace any of those in the first capture group from the regular expression above ('match-string 1' returns whatever was in the parentheses in the regular expression above) with an underscore.
t) ;; Append (first checking for duplicate items) the first capture group from the regular expression above (i.e., what's inside the parentheses in the regular expression) to a list. The t tells the function to append (rather than prepend) to the list.
) ;; End of while statement
;; Go to the end of the first line of the selected region.
(goto-char beginning-of-selected-region)
(end-of-line)
(if (> (length list-of-tag-strings) 0) ;; If the length of the list of found tags is greater than 0:
(insert " " ":" (mapconcat 'identity list-of-tag-strings ":") ":")) ;; Insert two spaces, a ':', the items from the list each separated by a ':', and a final ':'.
(message "Tags gathered from the selected region (which comprises character markers %d to %d) and printed on the first line of the region." beginning-of-selected-region end-of-selected-region))
;; 'Else' part of the statement:
(message "No region is selected for gathering tags. To run the function, you need to highlight a region first.")
))
You can then highlight text like this, and run the function with M-x generate-tag-list-from-selected-text:
This is a test {{with}} some {{tags}} in it.
This is another test with an {{additional tag}} and {{one:more}}.
This text will then become
This is a test {{with}} some {{tags}} in it. :with:tags:additional_tag:one_more:
This is another test with an {{additional tag}} and {{one:more}}.
Since this is the first function I've written in elisp, I used two sources for understanding the basics of elisp syntax, specifically regarding a) using just a selected area of text and b) running find-and-replace operations on that text. Given that the function uses the generic structure of the code vs. its specific content, I'm thinking that I'm within my rights to open up the function with a CC0 dedication (I do this because of StackOverflow's ongoing discussion about licensing of code on this site).

Automatically assigning tags in org-mode

I hate assigning tags when the tag already exists in the headline. I'd like to figure out a way to have org-mode evaluate a headline (preferably right after I hit "enter") and, if it contains any words that match tags in my org-tag-alist, have those tags created for the headline.
As an example:
If I have various individual's names and various project names and possibly even terms like "today", "tomorrow", and "next week" already in my org-tag-alist then, when I type something like:
"TODO Remember to ask Joe tomorrow about the due dates for the XYZ project."
and hit enter, then the headline would be evaluated and the tags :Joe:XYZ:Tomorrow: would be generated for the item.
Has anyone seen something like this or have a suggestion as to how I could go about it myself?
This function gets the headline of the entry the point is one, splits it into words and adds as a tag any word it finds in either org-tag-alist or org-tag-persistent-alist
(defun org-auto-tag ()
(interactive)
(let ((alltags (append org-tag-persistent-alist org-tag-alist))
(headline-words (split-string (org-get-heading t t)))
)
(mapcar (lambda (word) (if (assoc word alltags)
(org-toggle-tag word 'on)))
headline-words))
)
It might be useful to add a function like this to org-capture-before-finalize-hook to automatically tag newly captured entries.

Where/How to store text, if not in kill-ring/registers [elisp, emacs]

I would like to be able to store text between 2 positions (the string in between), but I don't know where to conveniently store it, perhaps just locally, or even globally (let or setq). The answer is probably out there, but I couldn't find it.
Example:
I would like to store text in a symbol in order to search for it backwards. Let's say the region from (point) until the first whitespace character.
My previous way of doing this was using (kill-ring-save), but I know this is a bad practice.
From (here) (message "hello")(point)
I would be interested in both better techniques for doing this, as well as the best way to store a string which is somehwere around (point).
The regular no-frills answer would be to just use let. Contrary to what you seem to believe, it does not allocate global storage. In fact, it does just the opposite.
(let ((myvalue "temporary string"))
(message myvalue) )
=> "temporary string"
myvalue
=> Lisp error: (void-variable myvalue)
And you can easily write a function with a variable whose value is set only during the function's execution. The interactive form allows you to easily obtain the values of point and mark.
(defun mysearch (point mark)
(interactive "r")
(let ((str (buffer-substring-no-properties point mark))
(message "your search for %s can commence ..." str) ) )
A common idiom is to use save-excursion to move point to another place, then grab the region between the original location and where you ended up, then do something with it. When you exit the save-excursion, the cursor's position (and several other things) will be restored to how they were before.
(defun mysearch ()
(interactive)
(save-excursion
(let ((here (point)) str)
(forward-word -1)
(setq str (buffer-substring-no-properties (point) here))
(message "your search for %s can commence ..." str) ) ) )
Perhaps you also want to look at http://ergoemacs.org/emacs/elisp_idioms.html
If you need to persist the value between function invocations, then the common thing to do is to defvar a variable like #phils suggests. Several variables with a common prefix sounds like you should be creating a separate module for yourself. For a flexible solution with low namespace footprint, create your own obarray (and achieve some sort of guru status). See also http://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Symbols.html#Definition%20of%20mapatoms
If a temporary local scope is all you require, then you definitely want to use let.
Otherwise you would usually define a variable (keeping in mind when you name it that elisp has no name spaces, so best practice is to use as reliably unique a prefix for all symbol names in a given library as practical).
(defvar SYMBOL &optional INITVALUE DOCSTRING)
If you omit the INITVALUE argument, the variable will not be bound initially, but ensures that your variable will use dynamic binding once used.
Then you just setq the variable as required.
Edit:
To obtain a buffer's contents between two points, use either of
(buffer-substring START END)
(buffer-substring-no-properties START END)
depending on whether or not you wish to preserve text properties.

flyspell correct the previous to previous mistake

suppose I have buffer contents as follows
teh msot |
curser is at |. generally I can correct msot to most with single C-; press (flyspell-auto-correct-previous-word). What I want is to correct teh to the, i.e previous to previous mistake. (or in general nth spell)
It seems flyspell-auto-correct-previous-word is taking numerical argument but not yielding intended result.
what am I missing.?
UPDATE:
Why I need this., when I write research notes, flyspell mistakenly marks some scientific words wrong. So need to skip the one or two false marks.
C-h f flyspell-auto-correct-previous-word tells me that the numerical argument is called "position". That does not look like what you are looking for. Position is likely to refer to a position in the buffer. Looking at the flyspell sourcecode reveals that the parameter is not used in the intendet way (cant tell what an overlay is thoug...)
;*---------------------------------------------------------------------*/
;* flyspell-auto-correct-previous-word ... */
;*---------------------------------------------------------------------*/
(defun flyspell-auto-correct-previous-word (position)
"*Auto correct the first mispelled word that occurs before point."
(interactive "d")
(add-hook 'pre-command-hook
(function flyspell-auto-correct-previous-hook) t t)
(save-excursion
(unless flyspell-auto-correct-previous-pos
;; only reset if a new overlay exists
(setq flyspell-auto-correct-previous-pos nil)
(let ((overlay-list (overlays-in (point-min) position))
(new-overlay 'dummy-value))
[SNIP]
also the (interactive "d") shows that the current position of point is assigned to position in case of an interactive call.
matthias

Avoid \printbibliography being swallowed by Org-mode headings

When using Org-mode and its LaTeX export BibTeX or Biblatex is often used to handle references. In that case the LaTeX command \printbibliography is often included in the org file. \printbibliography is placed in the org file where LaTeX is supposed to write out the reference list. What \printbibliography does is to insert a LaTeX header along with the reference list. In most cases \printbibliography is placed at the end of the org file simply because in most documents the reference list is to be placed last. This means that \printbibliography will be included under the last heading in the org file, e.g.
* Heading
\printbibliography
It also means that when that heading is folded the \printbibliography will be swallowed:
* Heading...
But this goes against the meaning of \printbibliography because it includes its own heading in the output. Also, it will be confusing when \printbibliography is swallowed and a new heading is placed after it because then the reference list will no longer appear last in the document.
How can I make it so that \printbibliography is not swallowed by sections in Org-mode? A bonus question: how can I make it so that Org-mode does not create headings after \printbibliography unless C-Ret is pressed when the cursor is after it?
In searching for a solution to this problem I found http://comments.gmane.org/gmane.emacs.orgmode/49545.
A workaround for this problem is to make \printbibliography not return a LaTeX heading so that it can appropriately be placed under an Org-mode heading.
With biblatex this can be done by supplying \printbibliography with the option heading=none and placing it under an appropriate heading. Here is an example:
* Heading
* References
\printbibliography[heading=none]
This way references can be kept in a heading of its own and \printbibliography being swallowed by a heading is not a problem because it is being swallowed by its own heading.
The following is lightly tested but works for me using tab and shift-tab to hide and display things. Those are the only hiding and showing commands that I use, so if you use other commands they may have to be advised or fixed in some other way.
You can of course change org-footer-regexp to anything you want. I was hoping to not have to use any advice, but without advising org-end-of-subtree the last heading never cycles with tab because it thinks it's not hidden, so it hides it and then org-cycle-hook unhides it. It calls org-end-of-subtree before running org-pre-cycle-hook so that's not an option either.
(defvar org-footer-regexp "^\\\\printbibliography\\[.*\\]$"
"Regexp to match the whole line of the first line of the footer which should always be shown.")
(defun show-org-footer (&rest ignore)
(save-excursion
(goto-char (point-max))
(when (re-search-backward org-footer-regexp nil t)
(outline-flag-region (1- (point)) (point-max) nil))))
(add-hook 'org-cycle-hook 'show-org-footer)
(add-hook 'org-occur-hook 'show-org-footer)
(defadvice org-end-of-subtree (after always-show-org-footer
()
activate)
(when (>= (point) (1- (point-max)))
(re-search-backward org-footer-regexp nil t)
(setq ad-return-value (point))))
One solution would be the following:
#+macro: printbiblio (add extra spaces here, but cannot add comment)
* Test 2
This is a test
* {{{printbiblio}}}
Test text
\printbibliography
*
asdf
Like this you end up with a blank heading at the bottom of the document. The macro expands to a blank block of text so you end up with
\section{Test 2}
\label{sec-1}
This is a test
\section{}
Test text
\printbibliography
\section{}
asdf
This also ensures you cannot accidentally add headlines after your bibliography, since it is it's own (empty) headline. It might be (seems to be actually) included in the table of contents, which is unfortunate but I would suspect the solution would be at worst run a post-export to remove the empty headline from the file (or manually do so before converting to PDF).
Another solution would be to put the bibliography under a heading named "References" like so:
* Heading
Some text
* References
\printbibliography
and remove the \section{References} from the resulting latex file by adding this to your emacs init file
(defun org-export-latex-remove-references-heading (contents backend info)
(if (not (eq backend 'latex))
contents
(replace-regexp-in-string "\\\\section\\*?{References}\\s-*\\\\label{.*?}" "" contents)
))
(add-hook 'org-export-filter-final-output-functions 'org-export-latex-remove-references-heading)
Note that this assumes you only have one heading that's named "References", as it replaces all occurrences of it. It also assumes the sections are in this format:
\section{References}
\label{<any_string>}
\printbibliography
For other formats you need to change the regular expression in the org-export-latex-remove-references-heading function.
* References
:PROPERTIES:
:UNNUMBERED: t
:END:
\printbibliography[heading=none]
There is an easier way to solve this.
Just add an "unnumbered" properties to the heading and it will be exported without any numbering.