How to Auto Title notes that were imported?

I had thousands of notes with this problem, I had left them untitled and used Evernote's feature of showing the first lines to distinguish them, but when moving them to Joplin I only get the titles, so I need to edit the titles to reflect the first line.

So I asked Bing for help to craft some python code to fix this problem. After some back and forth we came up with a program that reads every .enex file in its directory and for each note if the title is "Untitled Note" and there is a first line of text that can be used as a replacement, then the title is changed to reflect the first line.

Use this to modify your .enex files before importing them into Joplin.

Note: This program overwrites the files so keep a backup of the originals if you want to keep them.

Note: I had one bug caused when a source-url field contained an '=' character, not sure why, but when I edited the enex file to delete this line it worked fine.

Note: Some of this code could theoretically be simpler but then it encountered errors when opening complex data files, something to do with non-unicode characters encountered in the .enex files. This is the simplest version that worked for all of the .enex files that I had.

Here's the code:

# max chars in title
titleLength = 40

import re
import html
import os
import xml.etree.ElementTree as ET

# define a function that takes a string as an argument and strips all html fields
def strip_html_fields(new_title):
    # use re.sub to replace any html tags with an empty string
    # the pattern is < followed by any characters until >, with the flags re.IGNORECASE and re.DOTALL
    # the replacement is an empty string
    # the string is new_title
    return re.sub("<.*?>", "", new_title, flags=re.IGNORECASE | re.DOTALL)

# Define a function that takes a file name as an argument to process that file
def process_file(file_name):
    print("##################")
    print(file_name)
    # parse input.enex file
    tree = ET.parse(file_name)
    root = tree.getroot()
    
    # Loop through all the notes in the tree
    for note in root.findall("note"):
    
        # Get the title and the content of the note
        title = note.find("title").text
        content = note.find("content").text
    
        # Check if the title is "Untitled Note"
        if title == "Untitled Note":
    
            # Find the first div in the content
            start = content.find("<div>")
            end = content.find("</div>")
    
            # Extract the text between the div tags
            new_title = content[start + 5 : end]
            new_title = strip_html_fields(new_title)
            new_title = new_title[:titleLength]
            new_title = new_title.strip()
            
            if new_title: 
                # Replace the title with the new title
                note.find("title").text = new_title
                print(new_title)
        note.find("content").text = '<![CDATA[' + content + ']]>'
    
    # write the modified tree to output.enex file
    tree.write(file_name)
    
    # open the .enex file in binary mode to convert HTML character codes into text equivalents
    with open(file_name, "rb") as f:
        # read the file content as bytes
        data = f.read()
        # decode the bytes using utf-8 encoding
        text = data.decode("utf-8")
        # unescape the HTML character codes using the html.unescape function
        text = html.unescape(text)
    
    # open the .enex file in binary mode to write the output
    with open(file_name, "wb") as f:
        # encode the text using utf-8 encoding
        data = text.encode("utf-8")
        # write the data to the file using the file object's write method
        f.write(data)

# Get the current directory
current_dir = os.getcwd()

# Loop through all the files in the current directory
for file in os.listdir(current_dir):
    # Check if the file has the .enex extension
    if file.endswith(".enex"):
        # Apply the function to the file name
        process_file(file)

To use this just save this code in a text file called RenameNotes.py
Place the text file in a directory with some .enex files you wish to transform.
Then open a terminal in this directory and type:
python RenameNotes.py
The resulting .enex files should be able to be imported into Joplin with the note titles reflecting the first line of the note.
Remember, make a backup!
Good luck!

4 Likes