# Creating an org-roam note from an existing headline

**URL:** <https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978>\
**Category:** How To\
**Created:** [November 17, 2020, 11:46pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978 "2020-11-17T23:46:33Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![telotortium](https://avatars.discourse-cdn.com/v4/letter/t/a587f6/32.png) [@telotortium](https://org-roam.discourse.group/u/telotortium)\
**Post date:** [November 17, 2020, 11:46pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/1 "2020-11-17T23:46:33Z")

</div>

I have a notes files with a bunch of headlines containing various notes written over several years. Many of these notes are short and would belong in a system like org-roam, but there hasn’t been an easy way to migrate these notes into org-roam. So I’ve gone ahead and written a function [`org-roam-create-note-from-headline`](https://github.com/telotortium/doom.d/blob/f0295cc510d31c813e2a61ab2fc4aad3ae531e49/org-config.el#L1250-L1271):

```auto
(defun org-roam-create-note-from-headline ()
  "Create an Org-roam note from the current headline and jump to it.

Normally, insert the headline’s title using the ’#title:’ file-level property
and delete the Org-mode headline. However, if the current headline has a
Org-mode properties drawer already, keep the headline and don’t insert
‘#+title:'. Org-roam can extract the title from both kinds of notes, but using
‘#+title:’ is a bit cleaner for a short note, which Org-roam encourages."
  (interactive)
  (let ((title (nth 4 (org-heading-components)))
        (has-properties (org-get-property-block)))
    (org-cut-subtree)
    (org-roam-find-file title nil nil 'no-confirm)
    (org-paste-subtree)
    (unless has-properties
      (kill-line)
      (while (outline-next-heading)
        (org-promote)))
    (goto-char (point-min))
    (when has-properties
      (kill-line)
      (kill-line))))

```

---

<div class="post-metadata">

**Author:** ![real-or-random](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/real-or-random/32/514_2.png) [@real-or-random](https://org-roam.discourse.group/u/real-or-random)\
**Post date:** [November 22, 2020, 4:54pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/2 "2020-11-22T16:54:49Z")

</div>

Thanks for sharing. I think that’s useful, in particular if you use org-roam more like a wiki rahter than like a zettelkasten. Sometimes things get too large and deserve their own file.

---

<div class="post-metadata">

**Author:** ![JeffBrown](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/jeffbrown/32/254_2.png) [@JeffBrown](https://org-roam.discourse.group/u/JeffBrown)\
**Post date:** [November 22, 2020, 11:01pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/3 "2020-11-22T23:01:53Z")

</div>

This is super handy!!! Thanks!

---

<div class="post-metadata">

**Author:** ![agibragimov](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/agibragimov/32/589_2.png) [@agibragimov](https://org-roam.discourse.group/u/agibragimov)\
**Post date:** [January 4, 2021, 4:59am UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/4 "2021-01-04T04:59:30Z")

</div>

This is pretty cool and almost exactly what I needed. As soon as I started using org-roam (which is just a few hours ago) I felt grasping for something like this. Thank you for this snippet. I see how this can be improved:

- #+roam\_tags can be set (based on org tags of the heading and roam\_tags of the original file)
- if there any links to the heading, they could be replaced with the link to the new note

---

<div class="post-metadata">

**Author:** ![japhir](https://avatars.discourse-cdn.com/v4/letter/j/b2d939/32.png) [@japhir](https://org-roam.discourse.group/u/japhir)\
**Post date:** [January 5, 2021, 12:59pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/5 "2021-01-05T12:59:00Z")

</div>

A further improvement could be to convert the

```auto
:PROPERTIES: 
:CREATED: [2021-01-05 Tue 13:59]
:END:

```

drawer into a `#+created: [2021-01-05 Tue 13:59]` file property at the top :).

Of course, if this property drawer exists (which it does for almost all of my notes) it would be nice if it would still convert the heading itself to `#+title: xxx` at the top of the file.

---

<div class="post-metadata">

**Author:** ![gnohz](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/gnohz/32/803_2.png) [@gnohz](https://org-roam.discourse.group/u/gnohz)\
**Post date:** [July 30, 2021, 9:23pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/6 "2021-07-30T21:23:01Z")

</div>

How to implement this in V2?  
Thanks.

---

<div class="post-metadata">

**Author:** ![gnohz](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/gnohz/32/803_2.png) [@gnohz](https://org-roam.discourse.group/u/gnohz)\
**Post date:** [July 30, 2021, 9:58pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/7 "2021-07-30T21:58:57Z")

</div>

I tried to change

```auto
(org-roam-find-file title nil nil 'no-confirm)

```

to

```auto
        (org-roam-node-find 'other-window title nil)

```

and it works.

---

<div class="post-metadata">

**Author:** ![doubleloop](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/doubleloop/32/99_2.png) [@doubleloop](https://org-roam.discourse.group/u/doubleloop)\
**Post date:** [July 31, 2021, 3:23pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/8 "2021-07-31T15:23:18Z")

</div>

I think this new feature just added may provide this functionality now: [(feat): add org-roam-extract-subtree (#1710) · org-roam/org-roam@829ee68 · GitHub](https://github.com/org-roam/org-roam/commit/829ee688606213da6aca11cbcecfbb512c159f0f)

---

<div class="post-metadata">

**Author:** ![gnohz](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/gnohz/32/803_2.png) [@gnohz](https://org-roam.discourse.group/u/gnohz)\
**Post date:** [July 31, 2021, 10:12pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/9 "2021-07-31T22:12:43Z")

</div>

Not working with my current setup though…

1. It didn’t use my template, so the file name is still [YearMonthDate.xxx.org](http://YearMonthDate.xxx.org)
2. Error message: non-existent agenda file [R]emove from list or [A]bort?

---

<div class="post-metadata">

**Author:** ![gsgx](https://avatars.discourse-cdn.com/v4/letter/g/aeb1de/32.png) [@gsgx](https://org-roam.discourse.group/u/gsgx)\
**Post date:** [August 29, 2022, 10:26pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/10 "2022-08-29T22:26:29Z")

</div>

I also had various issues with `org-roam-extract-subtree`, so I needed to use this snippet. I’ve modified it a bit for my use case, as I need to do multiple headlines at once and don’t need to worry about properties:

```auto
(defun gsgx/org-roam-create-note-from-headline ()
  "Create an Org-roam note from the current headline if it doesn't
exist without jumping to it"
  (let* ((title (nth 4 (org-heading-components)))
         ;; Read in the name of the node, with the title filled in
         ;; TODO: How can I just use the title without user input?
         (node (org-roam-node-read title)))
    ;; Skip the node if it already exists
    (if (org-roam-node-file node)
        (message "Skipping %s, node already exists" title)
      ;; Without this the subsequent kills seem to be grouped together, not
      ;; sure why
      (kill-new "")
      ;; Cut the subtree from the original file
      (org-cut-subtree)
      ;; Create the new capture file
      (org-roam-capture- :node node)
      ;; Paste in the subtree
      (org-paste-subtree)
      ;; Removing the heading from new node
      (kill-whole-line)
      ;; Finalizing the capture will save and close the capture buffer
      (org-capture-finalize nil)
      ;; Because we've deleted a subtree, we need the following line to make the
      ;; `org-map-entries' call continue from the right place
      (setq org-map-continue-from
            (org-element-property :begin (org-element-at-point))))))

(defun gsgx/org-roam-create-note-from-headlines ()
  (interactive)
  (if (region-active-p)
      ;; `region-start-level' means we'll map over only headlines that are at
      ;; the same level as the first headline in the region. This may or may not
      ;; be what you want
      (org-map-entries
       'gsgx/org-roam-create-note-from-headline t 'region-start-level)
    ;; If no region was selected, just create the note from the current headline
    (gsgx/org-roam-create-note-from-headline)))

```

Hopefully that helps someone who comes across this thread. I would like to improve this by having an argument that I can set to not even prompt me for the titles at all if I’m sure the headline titles work, but I wasn’t able to figure out how to do that.

---

<div class="post-metadata">

**Author:** ![lr0](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/lr0/32/1464_2.png) [@lr0](https://org-roam.discourse.group/u/lr0)\
**Post date:** [February 1, 2024, 11:47pm UTC](https://org-roam.discourse.group/t/creating-an-org-roam-note-from-an-existing-headline/978/11 "2024-02-01T23:47:55Z")

</div>

For people reading this 4 years later, just use org-roam-extract-subtree.
