Code Monkey home page Code Monkey logo

note-station-to-markdown's Introduction

This script converts notes from Synology Note Station to plain-text markdown notes.
The script is written in Python and should work on any desktop platform.

After conversion you get:

  1. Directories named like the exported notebooks;
  2. Notes in those directories as markdown-syntax plain text files with all in-line images in-place;
  3. Assigned tags and links to attachments at the beginning of note texts;
  4. All images and attached files in media subdirectories inside notebook directories.

Local installation

  1. The script requires Python 3.5+ and pandoc installed on your system. Get the installation packages or use the package manager of your OS.
  2. Put nsx2md.py to the directory, where you want to convert notes.

Usage

  1. Export your Synology Note Station notebooks by: Setting -> Import and Export -> Export. You will get .nsx file.
  2. Adjust the .nsx file permissions if required.
  3. Copy the .nsx file(s) to the directory where you've put nsx2md.py.
  4. Set script settings if required - see the "Optional settings" section below.
  5. Run python nsx2md.py to convert all the .nsx files in the directory or python nsx2md.py path/to/export.nsx to convert a specific file.

Docker setup

build Docker image

docker build -t nsx2md .

run the docker image

docker run -it -v "$PWD:/nsx2md nsx2md <file.nsx>

Optional settings

Inside the script you can make some adjustments to the link format and notes metadata:
Select metadata options:
meta_data_in_yaml - True YAML block the following metadata that are set True, False metadata will be in text;
insert_title - True to insert note title as a markdown heading at the first line, False to disable;
insert_ctime - True to insert note creation time to the beginning of the note text, False to disable;
insert_mtime - True to insert note modification time to the beginning of the note text, False to disable;
tags - True to insert list of tags, False to disable;
tag_prepend - string to prepend each tag in a tag list inside the note, default is empty;
tag_delimiter - string to delimit tags, default is comma separated list;
no_spaces_in_tags - True to replace spaces in tag names with '_', False to keep spaces.

Select file link options:
prepend_links_with - Prepends file links with set string (ex. 'file://'), '' for no prepend
encode_links_as_uri - Encodes links' special characters with "percent-encoding, True for /link%20target style links, False for /link target style links
absolute_links - True for absolute links, False for relative links;

Select File/Attachments/Media options:
media_dir_name - name of the directory inside the produced directory where all images and attachments will be stored;
md_file_ext - extension for produced markdown syntax note files;
creation_date_in_filename - True to insert note creation time to the note file name, False to disable;

For QOwnNotes users

There are several ways to get tags from converted notes to work in QOwnNotes:

Import tags to QOwnNotes native way

  1. Convert .nsx files with default nsx2md.py settings;
  2. Add notebook directories produced by nsx2md.py as QOwnNotes note folders;
  3. Set one of these note folders as current;
  4. Enable provided import_tags.qml script in QOwnNotes (Note -> Settings -> Scripting) (remove_tag_line.py should be at the same directory);
  5. The script will add 2 new buttons and menu items:
    1. Import tags - to import tags from the tag lines of all the notes in the current note folder
    2. Remove tag lines - to remove the tag lines from all the notes in the current folder
  6. Use the buttons in the according order, any previous QOwnNotes tag data for the note folder will be lost;
  7. Move to the next note folder produced by nsx2md.py, repeat #5;
  8. Disable import_tags.qml script. That is obligatory.

"@tag tagging in note text (experimental)" QOwnNotes script

  1. For default @ tag prepends use the following nsx2md.py settings:
tag_prepend = '@'  # string to prepend each tag in a tag list inside the note, default is empty
tag_delimiter = ' '  # string to delimit tags, default is comma separated list
no_spaces_in_tags = True  # True to replace spaces in tag names with '_', False to keep spaces
  1. Convert .nsx files;
  2. Add notebook directories produced by nsx2md.py as QOwnNotes note folders.

note-station-to-markdown's People

Contributors

benfab avatar jhellerstedt avatar maboroshy avatar sweisgerber avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

note-station-to-markdown's Issues

Convert to HTML?

Is there any chance to add functionality to convert NSX to HTML for subsequent importing into other applications (e.g., OneNote)?

TypeError: '<' not supported between instances of 'str' and 'int'

Hi Maboroshy,

when run this script in Windows 10 and Python 3.7.3, I get following error output:

Found pandoc exe 2.7.3
Traceback (most recent call last):
File "nsx2md.py", line 66, in
if distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.16'):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1008.0_x64__qbz5n2kfra8p0\lib\distutils\version.py", line 52, in lt
c = self._cmp(other)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1008.0_x64__qbz5n2kfra8p0\lib\distutils\version.py", line 337, in _cmp
if self.version < other.version:
TypeError: '<' not supported between instances of 'str' and 'int'

Can I do something to fix it or is it a problem of the code?

Tables

Hi, great script! Question, are tables expected to be converted to [TABLE] with discarded content? If not, are you planning to implement table conversion, or at least embed its content between code tags perhaps?

OSError: [Errno 63] File name too long

Hi,

I got this OSError: [Errno 63] File name too long on MacOS for a file named /media/b9e5d7dfb4f4315b201e813e77057476_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40_41_42_43_44_45_46_47_48_49_50_51_52_53_54_55_56_57_58_59_60_61_62_63_64_65_66_67_68_69_70_71_72_73_74_75_76.jpeg

Anything possible to at least skip this then? Or better rename it somehow?

Really long titles crash

I have one note with a title length of 414 characters, this causes a crash on line 223 md_file_path.write_text(content, 'utf-8').

Shortening the title in the sanitise_path_string(path_str) method resolves the issue.:

    if truncate_title and len(path_str) > truncate_title_chars:
        path_str = path_str[:truncate_title_chars]

But this requires adding new settings as for example:

truncate_title = True # Catch problems with titles that are too long
truncate_title_chars = 200 # Do not allow more than X characters for a title

Syntax Error: invalid syntax

I'm sure this is a blatant noobie error, but ... I get...

F:\nsx2md>python nsx2md.py
File "nsx2md.py", line 7

^
SyntaxError: invalid syntax

I'm running Win10x64 with Python37 (x64) and lastest Pandoc (x64). Both Python and Pandoc are in PATH. I tried moving the py script and the nsx file into the Python folder, but same message.

Error on Linux

any suggestions?

Traceback (most recent call last):
  File "nsx2md.py", line 33, in <module>
    config_data = json.loads(nsx.read('config.json'))
  File "/usr/lib64/python3.4/json/__init__.py", line 312, in loads
    s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'

Notestation 2.4.3-0810
Python 2.7.5
pandoc 1.12.3.1
RHEL 7.3

Thank you so much

Needed just this today and really appreciate that you made it and released it.

Feel free to close this issue, just wanted to say thanks.

Crash when trash is not empty

When the trash is not empty, it gives me this error on line 132:
parent_notebook = notebook_id_to_path_index[parent_notebook_id]

KeyError: '1027_#00000000'

Emptying the trash and re-exporting the notebook solves the issue.

Make pandoc.Wait(5) time adjustable

A few of my notes were triggering this error, which appears to be a 5s wait for pandoc to do its thing:

Traceback (most recent call last):
  File "./nsx2md.py", line 133, in <module>
    pandoc.wait(5)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 990, in wait
    return self._wait(timeout=timeout)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 1616, in _wait
    raise TimeoutExpired(self.args, timeout)
subprocess.TimeoutExpired: Command '['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none', '--atx-headers', '-o', '/var/folders/gg/8fhvnc85693bnnpcw53k1jt80000gn/T/tmpqskz8j8t', '/var/folders/gg/8fhvnc85693bnnpcw53k1jt80000gn/T/tmpvw_o1sn3']' timed out after 5 seconds

I solved it by changing the wait to 20s:

pandoc = subprocess.Popen(pandoc_args)
pandoc.wait(20)

Maybe the delay could be extended by default, or just break it out as a setting like the other options at the top of the file?

Thanks a million the script works great! I'm using it to migrate from DS Note to Joplin currently

Error if attachments with identical file names

The script delivers an error if two notes have attachments, which have identical filenames.

The error message reads as follows:

Traceback (most recent call last): File "nsx2md.py", line 119, in <module> '{}/{}/{}'.format(notebook_title, media_dir, name)) FileExistsError: [WinError 183] Eine Datei kann nicht erstellt werden, wenn sie bereits vorhanden ist:

Would it be possible to change the code in a way that it attaches increasing numbers to filenames if they already exist?

wrong "interpretation" of some media file

Wonderful script, you saved my life.
Just found some media filename were not correctly "translated". It was the case with special char in the filename with % char
ex: filename in the media folder: 5-petit-de%CC%81jeuner.png
and the link was media 5-petit-de%25CC%2581jeuner.png
as you can see the script systematically skips the 2 digits following the % char
not a big deal, but opportunity for improvement

Convert Notes with tables and pictures

Converting plain text notes works quite well on Windows 11, but I'm currently having two problems:

  1. Notes with tables
  2. Notes with images/screenshots

1 Message:

Unconverted table found. Tweaking pandoc options may (or may not) allow to convert it.

How to tweek pandoc?
This error does not stop the conversion.

2 Message:

Traceback (most recent call last):
File "C:\Users\Lagavulin\Documents\Einstellungen\NAS\Notes\nsx2md.py", line 236, in
link_path = urllib.request.pathname2url(link_path).replace('///', '')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.752.0_x64__qbz5n2kfra8p0\Lib\nturl2path.py", line 73, in pathname2url
raise OSError(error)
OSError: Bad path: media/2456https://static.tp-link.com/image023_1493261584939q.png

This error is particularly annoying because it aborts the conversion.
It would be helpful if, when an error occurs, the conversion would skip the erroneous note and continue with the next one. Then, if necessary, I would copy the incorrect notes by hand.

Thanks again for having a look in this.

Attachments are not linked correctly

Attachments seem not to be incorporated correctly. They are apparently not working for two reasons.

  1. They must have an absolute path
  2. Blanks need to be escaped via %20

image

Problems with import-tag-to-QON.qml

I successfully installed the import-tag-to-QON.qml script. The script dialogue is telling me that the scripts seems to be valid.

However, if I click on an imported note, no tag will be created. The note starts with

Tags: tagName

image

List notes that are not converted

After the script completes I get the message:

Converted 16 notebooks and 371 out of 384 notes. Press Enter to quit...

Is it possible to get more info about what was not converted? Thanks!

Enhancement: Possibility to put the tags with @

When using the "@tag tagging in note text (experimental)" script in QOwnNote it is useful to import the tags directly with an @, so you could add the following:
use_at_tags = False # True when you want to use experimental @tags of QOwnNotes

Modification for the tag writing:

if note_data.get('tag', '') and use_at_tags:
            content = 'Tags: @{}  \n{}'.format(', @'.join(note_data['tag']), content)
        else:
            content = 'Tags: {}  \n{}'.format(', '.join(note_data['tag']), content)

Cannot see Pictures after Export with your Script

Hi,
first of all, thank you for your great job.
I have this issue with Pictures.
I exported all my DS Notes and then imported in Obsidian.
I can't see the pictures, when the format is like this after the export:
But if I try to link it like this ![[15101598275384230.png]], it works.
Do you habe any suggestion?
Thank you very much!
Michael

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.