Importing RedNotebook and Tomboy files

Use case or problem

importing legacy files from Tomboy and Rednotebook

Proposed solution

a plugin to parse and import the old markup files

Current workaround (optional)

reading the files as plaintext

Is anyone working on this already? I wanted to import a RedNotebook and was considering creating an importer for that too.

I’m also interested in importing my old RedNotebook into Obsidian. Did you create an importer?

Had the same problem here and created a little python script which is admittedly very basic, but which did the job for me. Feel free to improve my code, available on Github: KMfFDEeKT/rednotebook_file_import_obsidian

Here is a PHP I wrote to bring forward all my Rednotebook using its HTML export. It will write out individual day files from it.

<?php
/**
 * RedNotebook reformat to Obsidian Notes
 * VB - May 2024
 */

// Load up parameters passed from CLI
// eg:  thisprogram.php --File=Hello.txt
// $parms = (getArgs($_SERVER['argv']));
// echo $parms['hello']
// output:  Hello.txt
function getArgs($args) {
	$out = array();
	$last_arg = null;
	for($i = 1, $il = sizeof($args); $i < $il; $i++) {
		if( (bool)preg_match("/^--(.+)/", $args[$i], $match) ) {
		 $parts = explode("=", $match[1]);
		 $key = preg_replace("/[^a-z0-9]+/", "", $parts[0]);
			if(isset($parts[1])) {
			 $out[$key] = $parts[1];
			}
			else {
			 $out[$key] = true;
			}
		 $last_arg = $key;
		}
		else if( (bool)preg_match("/^-([a-zA-Z0-9]+)/", $args[$i], $match) ) {
			for( $j = 0, $jl = strlen($match[1]); $j < $jl; $j++ ) {
			 $key = $match[1][$j];
			 $out[$key] = true;
			}
		 $last_arg = $key;
		}
		else if($last_arg !== null) {
		 $out[$last_arg] = $args[$i];
		}
	}
	return $out;
} // getArgs
 
 
// Log Data to File - Will create and add to a file
// - Tags: Logfile
// LogTextToFile($incPath.SYSTEM_LOGFILES."File-".Date('Y-m-d').".log", $data)
function LogTextToFile($pFileName, $pData)
{
	// Test folder exists
	//mkDirectoryInDebugMode($pFileName);

	$textFileLog = $pFileName; //$incPath.SYSTEM_LOGFILES."File-".Date('Y-m-d').".log";
	// Open to add to log file
	if ($fh = fopen($textFileLog, 'a'))
	{
		fwrite($fh, $pData);
		fclose($fh);
	}
} // LogTextToFile


/////////////////
// MAIN
// -- Load the HTML Export from a folder
// -- Write out all Obsidian Day files in same folder
// eg: php RedNoteBookImport.php --file=RedNotebook-Export_2024-05-25.html --uploadpath="C:\ObsidianNotes\Main\Main\HTML import"

$parms = (getArgs($_SERVER['argv']));
$mFileToLoad	= "";
$mUploadPath	= "";
if (isset($parms['file']))
{
	$mFileToLoad	= $parms['file'];
}
if (isset($parms['uploadpath']))
{
	$mUploadPath	= $parms['uploadpath'];
}


$mFileCandidate = $mUploadPath."/". $mFileToLoad;

if (file_exists($mFileCandidate))
{
	echo '*** SELECTED REDNOTEBOOK FILE: '.$mFileCandidate.' '."\n";

	// To Do
	/*
	- Loop through File
	- Find day break indicators:   <h1>Thursday
	- Break out Day <h1>Thursday, 2020-10-01</h1>
	- Build output string until the next day break
	- Save as 2020-10-01.md
	- Check for <p>, flag on and off.  When on, add <br> to the line
	
	*/


	$handle = fopen($mFileCandidate, "r");
	$mDayFile 	= '';
	$mPFlag		= false;
	$mDayText 	= '';
	while (($mLine = fgets($handle)))	// fgetcsv
	{
		if (!$mLine) continue;
		
		$mCut 	= substr($mLine, 0, 7);
		$mDayArr	= array('<h1>Thu', '<h1>Fri', '<h1>Sat', '<h1>Sun', '<h1>Mon', '<h1>Tue', '<h1>Wed');
		if (in_array($mCut, $mDayArr))
		{
			// Found a new day
			
			// Write the old file
			if (($mDayFile <> '') && ($mDayText <> ''))
			{
				echo('Writing: '.$mDayFile."\n");
				if (file_exists($mDayFile))
				{
					unlink($mDayFile);
				}
				LogTextToFile($mDayFile, $mDayText);
			}
			
			// Set up the new details
			$mDayParts	= explode(',', $mLine);
			$mDayFile 	= $mUploadPath."/".substr($mDayParts[1], 1, 10).'.md';	// eg: 2020-10-01.md
			$mDayText 	= '';
			
		}
		else
		{
			// Ignore empty lines
			// Ignore the Date Spans 
			if ((trim($mLine) <> '') && (substr($mLine, 0, 12) <> '<span id="20'))
			{
				// See if we are in a <p>
				// -- I use line breaks, so will add <br> if in a <p>

				if (substr($mLine, 0, 4) == '</p>')
				{
					$mPFlag		= false;
				}			
				
				$mAdd = '';
				if ($mPFlag)
				{
					$mAdd = '<br>';
				}
				
				// This keeps it tight
				if (substr($mLine, 0, 3) == '<p>')
				{
					$mPFlag		= true;
				}
				
				$mLineOut = $mLine;
				
				// Custom stuff... test for -- ... which I use as bullets
				if (substr($mLine, 0, 3) == '-- ')
				{
					$mLineOut = '<li>'.substr($mLine,3,9999); '</li>';
				}
				
				// Just add the line to the file
				$mDayText .= trim($mLineOut).$mAdd.chr(10);
			}
		}
			
	}
	fclose($handle);
	
	// Final write
	if (($mDayFile <> '') && ($mDayText <> ''))
	{
		echo('Writing: '.$mDayFile."\n");
		if (file_exists($mDayFile))
		{
			unlink($mDayFile);
		}
		LogTextToFile($mDayFile, $mDayText);
	}	
}
else
{
	// Not found
	echo('Not Found'."\n");
}
?>

I have a quick update to the above. Obsidian does a great job Importing HTML. So, instead of saving to .MD, have it save to .HTML, and then import the HTML files using the Importer. This makes it just about perfect.

Update line 122 to:

			// Set up the new details
			// -- When exporting from RedNotebook, make sure the date format is %A, %y-%m-%d
			$mDayParts	= explode(',', $mLine);
			$mDayFile 	= $mUploadPath."/".substr($mDayParts[1], 1, 10).'.html';	// eg: 2020-10-01.html
			// Update:  Save to HTML, and then import HTML into Obsidian.  This is cleaner
			$mDayText 	= '';

In case someone is still interested: I recently developed GitHub - marph91/jimmy: Convert your notes to Markdown. It’s a standalone app that’s capable of converting RedNotebook and Tomboy-ng notes to Markdown (tested with a few example notes only, though).