- April 2020 - Initial version as simplenote2enex - the initial idea was to have a utility that processes Simple Note export files (JSON format) and produces Evernote ENEX files that presumably would be readable by other note taking apps that import ENEX. The first such app would be Joplin.
- July / August 2020 - Based on feedback from users (see in particular Issue 2 ), the initial assumption of producing generic ENEX turned out not to be correct.
- The utility generates a very simple ENEX envelope (based on evernote's example) but does not generate the "inner" html content that ENEX-importing apps apparently expect. For each Simple Note note, it just pastes inside that ENEX envelope the contents from the json item (typically markdown or plain text).
- The above "sort of works". Joplin can actually import the "pseudo ENEX" files generated by the tool (Menu> File / Import / ENEX Evernote Export File (as Markdown)), and it could in fact import my 500+ notes.
- In some cases, though, as documented in issue #2, the behavior is not exactly correct, and it requires some small kludges to get Joplin to accept the "enex" files.
- 23/8/2020 - Based on the above, and to avoid creating false expectations:
- Change utility and repository name from simplenote2enex to simplenote2joplin to reflect the actual behavior.
- Modify this file (README.md) to reflect the utility behavior.
- Use "pseudo-ENEX" instead of "ENEX" in this file to avoid confusing any user.
- simplenote2joplin.py is a Python (3.7) script to convert Notes from Simple Note, a popular multiplatform Note taking app, to a format based on (but not equal) to the ENEX XML-based format, that can be imported (with some caveats) by the Joplin note-taking app.
- IMPORTANT: See the "Document History" section above for a history of this utility.
- simplenote2joplin requires Python 3.6+, mainly because of extensive use of f-Strings.
$ python simplenote2joplin.py --help
usage: simplenote2joplin.py [-h] --json-file JSON_FILE [--author AUTHOR]
[--create-title] [--title_size TITLE_SIZE]
[--tag-filter TAG_FILTER] [--match-tagged]
[--match-untagged] [--invert-match]
[--verbose-level VERBOSE_LEVEL] [--number NUM_NOTES]
optional arguments:
-h, --help show this help message and exit
--json-file JSON_FILE
Simple Note export file (json) to be converted to ENEX
--author AUTHOR Specify an author for all converted notes
--create-title Attempt to create a title for each pseudo-ENEX note from
first line of "Simple Note" notes
--title_size TITLE_SIZE
Maximum size in characters of title - default 250
--tag-filter TAG_FILTER
Comma-separated list of tags. Will convert notes
matching any tag in list
--match-tagged Convert tagged notes
--match-untagged Convert untagged notes
--invert-match Invert match after combining (OR) all other
filters/matching conditions
--verbose-level VERBOSE_LEVEL
Verbose output level. Output to stderr. Default 0 - no
output
--number NUM_NOTES Number of notes to convert (Optional, default is
convert all notes)
- All examples assume the existence of a JSON file generated by exporting from Simple Note (Menu: File / Export Notes) . A sample file is available at the repository
- Convert all notes in file test1.json; attempt to generate a <title>first line of note</title> from the first line in each note (default separator '\r\n'); fill pseudo-ENEX 'author' field with 'John D.'. Output to stdout. Redirect to file 'all.test1.enex'. Sample available
- Note : when importing the pseudo-ENEX files into Joplin, the default behavior appears to create a Joplin "notebook" with the name of the pseudo-ENEX file.
$ python simplenote2joplin.py --json-file test1.json --author 'John D.' --create-title --verbose-level 1 > all.test1.enex
Processing file: test1.json
Notes author: John D.
Active notes: 8
Converted 8 notes
- Note: the next examples pipe the output to a grep command to highlight the filtering behavior.
- For the output to be useful as pseudo-ENEX file to be imported, it should be redirected to a file (in these examples, somefile.enex)
- Thus we use the GNU tee command to pipe the output both to a file and to the grep command.
- Convert all notes in file test1.json matching tags "tag1" and "tag3". Redirect output to somefile.enex
$ python simplenote2joplin.py --json-file test1.json --author 'John D.' --create-title --verbose-level 1 --tag-filter 'tag1,tag3' | tee somefile.enex | grep -E "<tag>|<title>"
Processing file: test1.json
Notes author: John D.
Active notes: 8
Converted 4 notes
<title>Test - Markdown with single tag</title>
<tag>tag1</tag>
<title>Test - Markdown with three tags</title>
<tag>tag1</tag>
<tag>tag2</tag>
<tag>tag3</tag>
<title>Test - Markdown with 2 tags</title>
<tag>tag1</tag>
<tag>tag2</tag>
<title>Test - Markdown with 4 tags</title>
<tag>tag1</tag>
<tag>tag2</tag>
<tag>tag3</tag>
<tag>tag4</tag>
- Invert match of previous command - convert only notes without 'tag1' or 'tag3'. Note this also includes untagged notes in the conversion.
$ python simplenote2joplin.py --json-file test1.json --author 'John D.' --create-title --verbose-level 1 --tag-filter 'tag1,tag3' --invert-match | tee somefile.enex | grep -E "<tag>|<title>"
Processing file: test1.json
Notes author: John D.
Active notes: 8
Converted 4 notes
<title>Test No Markdown plain test - One tag</title>
<tag>test1</tag>
<title>Test No Markdown plain test - NO tag</title>
<title>Test - Markdown No tag</title>
<title>Test - Markdown with single tag (tag4)</title>
<tag>tag4</tag>
- Convert all untagged Notes and notes with tag 'test1'
$ python simplenote2joplin.py --json-file test1.json --author 'John D.' --create-title --verbose-level 1 --tag-filter 'test1' --match-untagged | tee somefile.enex | grep -E "<tag>|<title>"
Processing file: test1.json
Notes author: John D.
Active notes: 8
Converted 3 notes
<title>Test No Markdown plain test - One tag</title>
<tag>test1</tag>
<title>Test No Markdown plain test - NO tag</title>
<title>Test - Markdown No tag</title>
-
I have successfully imported into Joplin an pseudo-ENEX file with 500+ notes, generated from my Simple Note deployment.
- I tested the import with joplin CLI (joplin import --log-level debug thefile.enex) , and found two hiccups, both related to having "&" in the Note title; solved by changing the character to "-". Inquired about this bug/feature in the Joplin forum)
- Once sorted I imported from the Joplin desktop application without a glitch : File / Import / ENEX - Evernote Export File (as Markdown)
- NOTE: This ampersand-issue is tracked in issue #3.
- NOTE: Implemented a quick fix to the issue above : if a note title is to be generated, replace any instance of "&" in the note title text with the ampersand html code ("&"). At the moment this functionality is hardcoded. It may become driven by a command-line switch, if it is useful.
-
Importing with the Joplin desktop application appears to hang if for some reason it cannot process some element due to some encoding error or problem, such as the one reported above.
- Troubleshooting importing pseudo-ENEX files is made simpler if using joplin's CLI application, available at https://joplinapp.org/terminal/
- IMPORTANT note: It appears that --even if installed in the same system -- the desktop Joplin application and the CLI command Joplin use different databases and in effect manage a different set of notes.
- One option is to use the CLI application for testing / troubleshooting if the desktop/GUI Joplin application hangs when importing a specific pseudo-ENEX file. Once all the offending notes have been identified and modified, perform the import procedure from the Joplin GUI app.
- Alternatively, it is possible to use Joplin's debugging functionality documented at: https://github.com/laurent22/joplin/blob/master/readme/debugging.md
- Troubleshooting importing pseudo-ENEX files is made simpler if using joplin's CLI application, available at https://joplinapp.org/terminal/
-
Issue 2 reported two problems with the behavior of simplenote2joplin (formerly known as simplenote2enex )
-
All empty lines are removed -
- Partial fix : substitute every occurrence of
'\r\n\r\n'
(two empty lines) in the json content with'\r\n<br/>
before inserting into the XML template.
- Partial fix : substitute every occurrence of
-
This fix does not address the proper display of tables immediately after (single '\r\n') a block of text, list, etc. To properly display tables, they should be preceded by two empty lines in the original Simple Note (
'\r\n\r\n'
in the json). -
pseudo-ENEX note title not generated if note content started with the "line separator" ("\r\n").
- Modified to remove whitespace and one or more sequences of "\r\n" at the beginning or the end of the note content.
- In the process, also added a cli parameter to control the maximum size of generated note title (default value 250 chars)
-
The main conclusion after discussing Issue 2 with the users is that the utility does not generate actual generic ENEX but some kind of pseudo-enex format that is (generally) importable by Joplin, with some exceptions. Thus the change of name and clarifications documented in the first section
-
-
Simple Note (www.simplenote.com) is a popular Note taking and synchronization application, developed by Automattic (sic), the makers of WordPress.
-
Simple Note is indeed simple and works seamlessly across the main platforms and operating systems: Mac, Windows, Linux, Web App, Android and IOS. It does pretty well what it says in the can.
-
I have been using Simple Note since early 2018 (Linux, Windows and Android) and I have about 600 notes. I am very happy with this application and intend to continue using it.
- The main advantages I see are the robust synchronization between mobile and desktop/web (based on Automattic's Simperium Library (www.simperium.com)) and the simplicity of the interface.
- The main drawback, in my opinion, is the lack of client side encryption. Lack of encryption limits its usability for me to "don't-care-if-it-becomes-public" items, like cooking recipes and general note taking on books, music, films, technical tips, shopping lists, etc.
- Simple Note is only text based with support of markdown. I am personally happy with that "limitation" since it fits well with a subset of my needs (I write my notes in very rudimentary markdown). At the same time I want to explore other Note applications with other options like embedding images.
- Simple Note does not export Notes to ENEX format (thus the need for simplenote2joplin). It exports notes to a proprietary JSON format.
- Exporting Notes from Simple Note ('File/Export Notes' or 'Ctrl-Shift-E') generates a zip file with default name notes.zip
- Extracting notes.zip (to, say, directory notes) yields the following directory structure :
$ tree ./notes
./notes
├── source
│ └── notes.json <<--- the file processed by simplenote2joplin
├── <Active Note 1 name>.txt
├── <Active Note 2 name>.txt
│ (...)
├── <Active Note N name>.txt
├── trash
│ ├── <Deleted note 1 name>.txt
│ ├── <Deleted note 2 name>.txt
│ │ (...)
│ ├── <Deleted note M name>.txt
- The file notes.json contains two main sections (a 2-element JSON array.)
- activeNotes (focus of this utility) - contains one JSON object per Active Note. Each note will be read by simplenote2joplin (json module) and processed as a "dict"
- trashedNotes contains one JSON object per Deleted (trashed) Note. This section is not read at the moment by simplenote2joplin, although it would be a simple addition.
- ENEX is the Evernote xml-based import/export format for notes, used as some kind of "lingua franca" by many note-taking applications.
- See: https://evernote.com/blog/how-evernotes-xml-export-format-works/
- Example of ENEX file : https://gist.github.com/evernotegists/6116886
- I am exploring other Note taking applications, starting with Joplin, "an open source note taking and to-do application with synchronization capabilities for Windows, macOS, Linux, Android and iOS"
- Information about Joplin can be found at:
- Homepage: https://joplinapp.org/
- GitHub: https://github.com/laurent22/joplin
- Forum: https://discourse.joplinapp.org/