diff --git a/merge-notes/info.json b/merge-notes/info.json
new file mode 100644
index 0000000..0059092
--- /dev/null
+++ b/merge-notes/info.json
@@ -0,0 +1,11 @@
+{
+ "name": "Merge selected notes",
+ "identifier": "merge-notes",
+ "script": "merge-notes.qml",
+ "resources": ["merge.py"],
+ "authors": ["@Maboroshy"],
+ "platforms": ["linux", "macos", "windows"],
+ "version": "0.0.1",
+ "minAppVersion": "18.08.5",
+ "description" : "This script adds a toolbar button and a note list context menu item to merge multiple selected notes. Notes are merged to the first selected note or to a new note, depending on setting. Notes are merged in the order they were selected.\n\nDependencies:\nPython 3.3+ Interpreter.\n\nThis script should be used with \"Allow note file name to be different from headline\" and \"Accept all external modification of current note\" options on."
+}
diff --git a/merge-notes/merge-notes.qml b/merge-notes/merge-notes.qml
new file mode 100644
index 0000000..d6d5133
--- /dev/null
+++ b/merge-notes/merge-notes.qml
@@ -0,0 +1,87 @@
+import QtQml 2.2
+import QOwnNotesTypes 1.0
+
+/*This script adds a toolbar button and a note list context menu item to merge multiple selected notes.
+ Notes are merged to the first selected note or to a new note, depending on settings. Notes are merged in the order they were selected.
+ Dependencies: Python 3.3+ Interpreter
+*/
+
+Script {
+ /// functions to find correct Python 3 interpreter command and set it as default
+ function getPyCommand() {
+ if (script.startSynchronousProcess('python3', '-V', '').toString().indexOf('Python 3') != '-1') {return 'python3'}
+ if (script.startSynchronousProcess('python', '-V', '').toString().indexOf('Python 3') != '-1') {return 'python'}
+ if (script.startSynchronousProcess('py', '-V', '').toString().indexOf('Python 3') != '-1') {return 'py'}
+ return ''
+ }
+
+ function setDefaultPyCommand() {
+ if (script.getPersistentVariable('MdNT/pyCommand', '') == '') {
+ script.setPersistentVariable('MdNT/pyCommand', getPyCommand())
+ }
+ return script.getPersistentVariable('MdNT/pyCommand', '')
+ }
+
+
+ property string scriptDirPath
+ property bool mergeToFirst
+ property bool deleteMerged
+ property string pyCommand
+
+ property variant settingsVariables: [
+ {
+ 'identifier': 'mergeToFirst',
+ 'name': '',
+ 'description': 'Merge selected notes to the note, which was selected first\n' +
+ 'If disabled, notes will be merged to a new note',
+ 'type': 'boolean',
+ 'default': 'False',
+ },
+ {
+ 'identifier': 'deleteMerged',
+ 'name': '',
+ 'description': 'Delete notes that were merged',
+ 'type': 'boolean',
+ 'default': 'False',
+ },
+ {
+ 'identifier': 'pyCommand',
+ 'name': 'Command/path to run Python 3 Interpreter',
+ 'description': "Put a command or path for Python 3 interpreter here.",
+ 'type': 'file',
+ 'default': setDefaultPyCommand(),
+ }
+ ]
+
+ function init() {
+ /// Check if set pyCommand can run Python 3, alert the user on failure, enable custom action on success
+ if (script.getPersistentVariable('MdNT/pyCommand', '') != pyCommand) {
+
+ if (script.startSynchronousProcess(pyCommand, '-V', '').toString().indexOf('Python 3') != '-1') {
+ script.setPersistentVariable('MdNT/pyCommand', pyCommand)
+ }
+ else {
+ script.setPersistentVariable('MdNT/pyCommand', '')
+ }
+ }
+
+ if (script.getPersistentVariable('MdNT/pyCommand', '') == '') {
+ script.informationMessageBox('The command/path for Python 3 interpreter in the script settings is not valid\n' +
+ 'Please set the correct command/path.',
+ 'Script')
+ }
+ else {
+ script.registerCustomAction('mergeNotes', 'Merge selected notes', 'Merge notes', 'merge.svg', false, false, true)
+ }
+ }
+
+ function customActionInvoked(action) {
+ if (action == 'mergeNotes') {
+ var pyScriptPath = scriptDirPath + script.dirSeparator() + 'merge.py'
+
+ script.startDetachedProcess(pyCommand, [pyScriptPath, mergeToFirst, deleteMerged, script.selectedNotesPaths().join('//>')])
+
+ // script.log(pyCommand + " '" + [pyScriptPath, mergeToFirst, deleteMerged, script.selectedNotesPaths().join('//>')].join("' '") + "'")
+ }
+ }
+}
diff --git a/merge-notes/merge.py b/merge-notes/merge.py
new file mode 100644
index 0000000..9d59fbc
--- /dev/null
+++ b/merge-notes/merge.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+import os
+import sys
+
+merge_to_first = sys.argv[1]
+delete_merged = sys.argv[2]
+note_list = sys.argv[3].split('//>')
+
+note_content_list = []
+for note_path in note_list:
+ with open(note_path, 'r') as note:
+ note_content_list.append(note.read())
+
+if merge_to_first == 'true':
+ output_path = note_list.pop(0)
+else:
+ output_path = "{}{} notes starting with '{}'{}".format(os.path.dirname(note_list[0]) + os.sep,
+ len(note_list),
+ os.path.splitext(os.path.basename(note_list[0]))[0],
+ os.path.splitext(note_list[0])[1])
+try:
+ with open(output_path, 'w') as output:
+ output.write('\n\n'.join(note_content_list))
+except:
+ pass
+else:
+ if delete_merged == 'true':
+ for note_path in note_list:
+ os.remove(note_path)
\ No newline at end of file