# How to dynamically create ID to other files?

**URL:** <https://org-roam.discourse.group/t/how-to-dynamically-create-id-to-other-files/3408>\
**Category:** How To\
**Created:** [March 25, 2024, 8:57am UTC](https://org-roam.discourse.group/t/how-to-dynamically-create-id-to-other-files/3408 "2024-03-25T08:57:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sudddddd](https://avatars.discourse-cdn.com/v4/letter/s/9fc29f/32.png) [@sudddddd](https://org-roam.discourse.group/u/sudddddd)\
**Post date:** [March 25, 2024, 8:57am UTC](https://org-roam.discourse.group/t/how-to-dynamically-create-id-to-other-files/3408/1 "2024-03-25T08:57:11Z")

</div>

I have many org-roam v2 files and want to link subheadings from each other. Currently, the approach I am following is-

1. Use `org-store-link` to generate ID for the (sub) heading in file A.
2. Use `org-roam-node-insert` to insert the previously generated ID in file B.

I wish to automate these 2 steps into 1. There should be a way in which I can select all the subheading in all org roam files and just select it to insert a link to it. If there was no ID property to it, then create it, else, use it.

I have found `counsel-org-link` to work similarly according to my requirement, but, it works for only a single file. I want to work with multiple files. Please help.

---

<div class="post-metadata">

**Author:** ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)\
**Post date:** [March 26, 2024, 11:17am UTC](https://org-roam.discourse.group/t/how-to-dynamically-create-id-to-other-files/3408/2 "2024-03-26T11:17:55Z")

</div>

I think you’d need to create your own code.

Below is an outline of the program I’d make.

You’d need a basic understanding of Elisp and how marker works (easy), and familiarity with libraries `org-element` and `completing-read` (will take time…).

It is not difficult, but time-consuming to get right (this is as far as I can do).

- Function org-roam-list-files gives you a list of all the files in a list
- For each `.org` file in the list, get all the headline elements (you should be able to use the built-in `org-element` library to parse each .org file and get the headlines with the marker (file and position) and headline title
- Create a minibuffer selection. This would depend on your completion framework (especially Ivy/Counsel), but for Vertico/Consult, it would be `completing-read` (you can see how `completing-read` does this)
- Based on the user’s selection of the headline from the minibuffer, you can visit the file and headline, and get the existing ID or create an new one (eg `org-id-get-create`)  
EDIT: Sorry, you mention `org-store-link` – I think it will work too, assuming your configuration is correctly set to create an ID when it does not exist
- At this stage, the new ID is not in the org-roam-db, so you’d need construct the ID link (not difficult because you have the ID and the headline title)  
EDIT: If you use `org-store-link`, then you should be able to use `org-insert-link` for the ID

---

<div class="post-metadata">

**Author:** ![akashp](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/akashp/32/1383_2.png) [@akashp](https://org-roam.discourse.group/u/akashp)\
**Post date:** [March 28, 2024, 6:22pm UTC](https://org-roam.discourse.group/t/how-to-dynamically-create-id-to-other-files/3408/3 "2024-03-28T18:22:40Z")

</div>

I like the idea - I already have a way to parse all the headings of a file - I think I can code this.  
But we have to solve a few problems. Firstly if we search for all the headings in all the files the process might be cpu intensive - can you work with first selecting the file then getting a list of the subheadings and headings?

or do you want to arbitarily search for all the subheadings and headings? We can cook something up. Lets work on it - let me know how you conceive of the workflow.

---

<div class="post-metadata">

**Author:** ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)\
**Post date:** [March 28, 2024, 7:52pm UTC](https://org-roam.discourse.group/t/how-to-dynamically-create-id-to-other-files/3408/4 "2024-03-28T19:52:24Z")

</div>

> [@akashp](#):
>
> Firstly if we search for all the headings in all the files the process might be cpu intensive

An alternative is to use regex for the headers in the files in org-roam-dir. This is probably better for performance than my first suggestion to use org-element to parse the files.

---

<div class="post-metadata">

**Author:** ![akashp](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/akashp/32/1383_2.png) [@akashp](https://org-roam.discourse.group/u/akashp)\
**Post date:** [May 30, 2024, 12:29pm UTC](https://org-roam.discourse.group/t/how-to-dynamically-create-id-to-other-files/3408/7 "2024-05-30T12:29:47Z")

</div>

Consult ripgrep can be utilised to search for all the headlines efficiently. The glob specifies the exclusion parameters to exclude from search. The rest is just tacking a org-id creation and insert mechanism.

```auto
(defun 0/find-headline ()
  (interactive)
  (let ((consult-ripgrep-args "rg --null --ignore-case --type=org --glob=!{org-exports,guides,journal,resources,references} --line-buffered --color=never --line-number"))
    (consult-ripgrep org-roam-directory "^\\*+\\s# ")))

(defun 0/insert-headline ()
  (interactive)
  (save-excursion
    (let* ((current-buffer (current-buffer))
	   (consult-ripgrep-args "rg --null --ignore-case --type=org --glob=!{org-exports,guides,journal,resources,references} --line-buffered --color=never --line-number")
	   (headline (consult-ripgrep org-roam-directory "^\\*+\\s# ")))
      (when headline
	(let* ((headline-text (org-get-heading t t t t))
	       (id (org-id-get-create)))
	  (save-buffer)
	  (switch-to-buffer current-buffer)
	  (insert (format "[[id:%s][%s]]" id headline-text)))))))

```
