You can get this result by setting the CUSTOM_ID
property.
From the following file:
* Test
:PROPERTIES:
:CREATED: [2014-10-02 Thu 11:48]
:END:
** Sub no custom
:PROPERTIES:
:CREATED: [2014-10-02 Thu 11:49]
:END:
** Sub custom
:PROPERTIES:
:CREATED: [2014-10-02 Thu 11:49]
:CUSTOM_ID: Custom
:END:
I get the following Export (C-c C-e h H
):
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1. Test</a>
<ul>
<li><a href="#sec-1-1">1.1. Sub no custom</a></li>
<li><a href="#Custom">1.2. Sub custom</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1"><span class="section-number-2">1</span> Test</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-sec-1-1" class="outline-3">
<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Sub no custom</h3>
<div class="outline-text-3" id="text-1-1">
</div>
</div>
<div id="outline-container-Custom" class="outline-3">
<h3 id="Custom"><a id="sec-1-2"></a><span class="section-number-3">1.2</span> Sub custom</h3>
So Sub no custom
is linked to by #sec-1-1
while Sub custom
uses #custom
as the reference.
AutoGenerating IDs
Adding org-id
to the list of loaded org-modules
or directly evaluating (require 'org-id)
will allow for IDs to be generated using org-id-get-create
. The following will insert IDs automatically and use them on export.
;; Use custom ID if present, otherwise create a new one when trying to
;; resolve links
(setq org-id-link-to-org-use-id
'create-if-interactive-and-no-custom-id)
;; Based on org-expiry-insinuate
(add-hook 'org-insert-heading-hook 'org-id-get-create)
(add-hook 'org-after-todo-state-change-hook 'org-id-get-create)
(add-hook 'org-after-tags-change-hook 'org-id-get-create)
This should look through your existing headlines in a buffer and update the IDs. It will only create IDs if none are present.
(defun my/org-update-ids ()
(interactive)
(let* ((tree (org-element-parse-buffer 'headline))
(map (reverse
(org-element-map tree 'headline
(lambda (hl)
(org-element-property :begin hl))))))
(save-excursion
(cl-loop for point in map do
(goto-char point)
(org-id-get-create)))))
Note. This will not fix TOC links to point to the correct IDs. TOC is only configured to use CUSTOM_ID
or sec-#-#
for generating links. You can however access the sections by their ID's (I would suggest changing org-id-method
to org
from uuid
to shorten the ID length if you intend to use it this way.
CUSTOM_ID
is still probably your best bet if you actually want human-legible IDs for the headlines. my/org-update-ids
should be able to be used as a starting point for that (map through the buffer for each headline, go to headline then perform action).
A starting point would be (org-entry-put (point) "CUSTOM_ID" id)
for setting and (org-entry-get (point) "CUSTOM_ID")
for getting. Determinining what to use as id
is dependant on how you want them named.