Update links for new webpage (#1897)

This commit is contained in:
Patrizio Bekerle 2020-10-08 18:55:39 +02:00
parent e44844c519
commit 41da7a442e
No known key found for this signature in database
GPG key ID: 2E9FFD770DABE838
139 changed files with 325749 additions and 325654 deletions

View file

@ -0,0 +1,24 @@
import QtQml 2.0
/**
* This script will make the paths of inserted media files absolute in the markdown link (tested on Linux)
*/
QtObject {
/**
* This function is called when media file is inserted into the note
*
* @param fileName string the file path of the source media file before it was copied to the media folder
* @param mediaMarkdownText string the markdown text of the media file, e.g. ![my-image](file://media/505671508.jpg)
* @return string the new markdown text of the media file
*/
function callInsertMediaHook(fileName, mediaMarkdownText) {
// get the path of the current note folder
var path = script.currentNoteFolderPath();
// Windows users might want to add an additional slash in front of the path
//path = "/" + path;
// make the path of inserted media files absolute
return mediaMarkdownText.replace(new RegExp("media", "g"), path + "/media");
}
}

View file

@ -0,0 +1,23 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is an example for adding text to the autocompletion list
*/
Script {
/**
* Hook to feed the autocompletion with tags if the current word starts with an "@"
*/
function autocompletionHook() {
// get the current word plus non-word-characters before the word to also get the "@"-character
var word = script.noteTextEditCurrentWord(true);
if (!word.startsWith("@")) {
return [];
}
// cut the "@" off of the string and do a substring search for tags
var tags = script.searchTagsByName(word.substr(1));
return tags;
}
}

View file

@ -0,0 +1,37 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is a short example of how to use detatched processes and callbacks
* to relieve the UI thread.
* Visit http://docs.qownnotes.org/ for more information about scripting
*/
Script {
function log(txt) {
script.log("[callback-example] " + txt);
}
function init() {
log("init")
for (var i = 0; i < 100; i++) {
var dur = Math.floor(Math.random() * 10) + 1;
script.startDetachedProcess("sleep", [`${dur}s`], "callback-example", i);
}
}
/**
* This function is called when a script thread is done executing.
* Hint: thread[1]==0 helps to determine if a bulk of started processes for a certain identifier is done.
*
* @param {QString} callBackIdentifier - the provided id when calling startDetachedProcess()
* @param {QString} resultSet - the result of the process
* @param {QVariantList} cmd - the entire command array [0-executablePath, 1-parameters, 2-exitCode]
* @param {QVariantList} thread - the thread information array [0-passed callbackParameter, 1-remaining threads for this identifier]
*/
function onDetachedProcessCallback(callBackIdentifier, resultSet, cmd, thread) {
if (callBackIdentifier == "callback-example") {
log(`#${thread[1]} i[${thread[0]}] t${cmd[1]}`);
}
}
}

View file

@ -0,0 +1,79 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is an example for creating custom actions, that can be invoked
* via menu entries and buttons
*/
QtObject {
/**
* Initializes the custom actions
*/
function init() {
// create a menu entry "Open with KWrite" with a button "KWrite"
script.registerCustomAction("openWithKWrite", "Open with KWrite", "KWrite");
// create a menu entry "Create meeting note" with a button and a freedesktop theme icon
script.registerCustomAction("createMeetingNote", "Create meeting note", "Meeting note", "task-new");
// create a menu entry "No button here", but no button for it
script.registerCustomAction("noButtonAction", "No button here");
// create a menu entry to transform text with rot13
script.registerCustomAction("transformTextRot13", "Transform selected text with rot13", "rot13", "text-wrap", true);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
script.log("customActionInvoked - " + identifier);
switch (identifier) {
// open the current note with KWrite
case "openWithKWrite":
var note = script.currentNote();
var fileName = note.fullNoteFilePath;
script.startDetachedProcess("kwrite", [fileName]);
break;
// create a new note with a custom content
case "createMeetingNote":
var date = new Date();
// create the headline
// we are removing the ":", because they should not be in the filename of the note
var text = "Meeting note " + date.toISOString().replace(/:/g, ".") + "\n";
var underline = "";
// add the underline for the headline
for (var i = 0; i < (text.length - 1); i++) {
underline += "=";
}
// add some text to our meeting note
text += underline + "\n\n## Important points\n\n\n## Things to remember\n\n";
// add the text that is currently in the clipboard
text += script.clipboard();
// create a new note
script.createNote(text);
break;
// transform selected text with rot13
case "transformTextRot13":
var text = script.noteTextEditSelectedText();
// do the rot13 transformation
text = text.replace(/[a-zA-Z]/g, function(c){
return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
});
script.noteTextEditWrite(text);
break;
}
}
}

View file

@ -0,0 +1,31 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is an example how to modify the headline of new notes
*/
QtObject {
/**
* This function is called before a note note is created
*
* It allows you to modify the headline of the note before it is created
* Note that you have to take care about a unique note name, otherwise
* the new note will not be created, it will just be found in the note list
*
* You can use this method for creating note templates
*
* @param headline text that would be used to create the headline
* @return {string} the headline of the note
*/
function handleNewNoteHeadlineHook(headline) {
var text = headline + " - my custom note name " + "\n";
var underline = "";
// add the underline
for (var i = 0; i < (text.length - 1); i++) {
underline += "=";
}
return text + underline;
}
}

View file

@ -0,0 +1,20 @@
import QtQml 2.0
/**
* This script adds custom styles to the application
*
* You can get the object names from the *.ui files, for example
* https://github.com/pbek/QOwnNotes/blob/develop/src/mainwindow.ui
*
* Take a look at http://doc.qt.io/qt-5/stylesheet-reference.html for
* a reference of what styles are available.
*/
QtObject {
/**
* Adds custom styles
*/
function init() {
// add a custom stylesheet to increase font size in the note list and set a font
script.addStyleSheet("QTreeWidget#noteTreeWidget {font-family: Pacifico; font-size: 28px;}");
}
}

View file

@ -0,0 +1,20 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script will disable the read-only mode if a note is double clicked
*/
Script {
/**
* This function is called after a note was double clicked
*
* @param {NoteApi} note - the note object that was clicked
*/
function noteDoubleClickedHook(note) {
// disable the read-only mode
script.triggerMenuAction("actionAllow_note_editing", 1);
// focus the note text edit
mainWindow.focusNoteTextEdit();
}
}

View file

@ -0,0 +1,31 @@
import QtQml 2.0
/**
* This script will encrypt and decrypt notes with https://keybase.io
*
* You have to use your keybase user instead of "pbek"
*/
QtObject {
/**
* This is called when the script is loaded by QOwnNotes
*/
function init() {
// disable the password dialog
script.encryptionDisablePassword();
}
/**
* This function is called when text has to be encrypted or decrypted
*
* @param text string the text to encrypt or decrypt
* @param password string the password
* @param decrypt bool if false encryption is demanded, if true decryption is demanded
* @return the encrypted decrypted text
*/
function encryptionHook(text, password, decrypt) {
// encrypt or decrypt text with keybase.io for user pbek
var param = decrypt ? ["decrypt"] : ["encrypt", "pbek"];
var result = script.startSynchronousProcess("/usr/bin/keybase", param, text);
return result;
}
}

View file

@ -0,0 +1,33 @@
import QtQml 2.0
/**
* This script will encrypt and decrypt notes with PGP
*
* You have to use your own public key instead of "F5161BD3"
* Decryption only will work if you don't have to enter a password
*/
QtObject {
/**
* This is called when the script is loaded by QOwnNotes
*/
function init() {
// disable the password dialog
script.encryptionDisablePassword();
}
/**
* This function is called when text has to be encrypted or decrypted
*
* @param text string the text to encrypt or decrypt
* @param password string the password
* @param decrypt bool if false encryption is demanded, if true decryption is demanded
* @return the encrypted decrypted text
*/
function encryptionHook(text, password, decrypt) {
// encrypt the text for public key "F5161BD3" or decrypt with gpg
// decryption only will work if you don't have to enter a password
var param = decrypt ? ["--decrypt"] : ["--encrypt", "--armor", "-r", "F5161BD3"];
var result = script.startSynchronousProcess("/usr/bin/gpg", param, text);
return result;
}
}

View file

@ -0,0 +1,31 @@
import QtQml 2.0
/**
* This script will "encrypt" and "decrypt" notes with ROT13
*/
QtObject {
/**
* This is called when the script is loaded by QOwnNotes
*/
function init() {
// disable the password dialog
script.encryptionDisablePassword();
}
/**
* This function is called when text has to be encrypted or decrypted
*
* @param text string the text to encrypt or decrypt
* @param password string the password
* @param decrypt bool if false encryption is demanded, if true decryption is demanded
* @return the encrypted decrypted text
*/
function encryptionHook(text, password, decrypt) {
// do the rot13 transformation
text = text.replace(/[a-zA-Z]/g, function(c){
return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
});
return text;
}
}

View file

@ -0,0 +1,150 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is a generic example of some functions that will be called by QOwnNotes
*/
QtObject {
/**
* This is called when the script is loaded by QOwnNotes
*/
function init() {
script.log("Script init");
}
/**
* This function is called when a note gets stored to disk
* You cannot modify stored notes, that would be a mess since
* you are most likely editing them by hand at the same time
*
* @param {Note} note - the note object of the stored note
*/
function onNoteStored(note) {
script.log("fileName was stored!");
script.log(note.id);
script.log(note.name);
script.log(note.fileName);
// tagNames() returns a list of all tag names
var tagNameList = note.tagNames();
script.log(tagNameList);
}
/**
* This function is called when a note gets stored to disk if
* "Allow note file name to be different from headline" is enabled
* in the settings
*
* It allows you to modify the name of the note file
* Return an empty string if the file name of the note should
* not be modified
*
* @param {Note} note - the note object of the stored note
* @return {string} the file name of the note
*/
function handleNoteTextFileNameHook(note) {
script.log(note.id);
script.log(note.name);
script.log(note.fileName);
// tagNames() returns a list of all tag names
var tagNameList = note.tagNames();
script.log(tagNameList);
// don't actually change anything
return "";
}
/**
* This function is called when the note name is determined for a note
*
* It allows you to modify the name of the note that is viewed
*
* Return an empty string if the name of the note should not be modified
*
* @param {NoteApi} note - the note object of the stored note
* @return {string} the name of the note
*/
function handleNoteNameHook(note) {
return note.name + " some text";
}
/**
* This function is called when the markdown html of a note is generated
*
* It allows you to modify this html
* This is for example called before by the note preview
*
* @param {Note} note - the note object
* @param {string} html - the html that is about to being rendered
* @param {string} forExport - true if the html is used for an export, false for the preview
* @return {string} the modified html or an empty string if nothing should be modified
*/
function noteToMarkdownHtmlHook(note, html, forExport) {
script.log("noteToMarkdownHtmlHook was called");
// show a custom headline and a horizontal ruler on top of the preview
return html.replace("body>", "body><h1>Custom preview for note " + note.name + "</h1><hr />");
}
/**
* This function is called when media file is inserted into the note
* If this function is defined in multiple scripts, then the first script that returns a non-empty string wins
*
* @param fileName string the file path of the source media file before it was copied to the media folder
* @param mediaMarkdownText string the markdown text of the media file, e.g. ![my-image](file://media/505671508.jpg)
* @return string the new markdown text of the media file
*/
function insertMediaHook(fileName, mediaMarkdownText) {
script.log("mediafile was inserted: " + fileName);
return "";
}
/**
* This function is called when html or a media file is pasted to a note with `Ctrl + Shift + V`
*
* @param text text of the QMimeData object
* @param html html of the QMimeData object
* @returns the string that should be inserted instead of the text from the QMimeData object
*/
function insertingFromMimeDataHook(text, html) {
script.log("text was pasted: " + text);
return "";
}
/**
* This starts a timer that triggers every 30 seconds
*/
property QtObject timer: Timer {
interval: 30000
repeat: true
running: true
property int count: 0
onTriggered: {
count++;
script.log("count = " + count);
var note = script.currentNote();
if (note) {
script.log(note.id);
script.log(note.name);
script.log(note.fileName);
// the tags property returns a list of assigned tag objects
var tags = note.tags;
// print out all tag names
for (var i in tags) {
var tag = tags[i];
script.log(tag.name);
}
// tagNames() returns a list of all tag names
var tagNameList = note.tagNames();
script.log(tagNameList);
}
}
}
}

View file

@ -0,0 +1,22 @@
import QtQml 2.0
/**
* This script will execute an external program every time a note was written to the disk
*/
QtObject {
/**
* This function is called when a note gets stored to disk
* You cannot modify stored notes, that would be a mess since
* you are most likely editing them by hand at the same time
*
* @param {Note} note - the note object of the stored note
*/
function onNoteStored(note) {
// execute an external program
// try not to alter the note file or QOwnNotes will try to update
// the file every time you change the note
script.startDetachedProcess("/path/to/my/program", [note.fileName]);
script.log("program was executed for file: " + note.fileName);
}
}

View file

@ -0,0 +1,53 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
import com.qownnotes.noteapi 1.0
/**
* This script exports multiple notes as one HTML file
*/
Script {
/**
* Initializes the custom actions
*/
function init() {
script.registerCustomAction("exportHTML", "Export notes as html file",
"", "", false, true, true);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "exportHTML") {
return;
}
var noteIds = script.selectedNotesIds();
if (noteIds.length == 0) {
return;
}
var html = "";
noteIds.forEach(function (noteId){
var note = script.fetchNoteById(noteId);
var noteHtml = note.toMarkdownHtml();
// TODO: multiple html headers have to be removed
html += noteHtml;
});
var filePath = script.getSaveFileName("Please select where to store the HTML",
"Notes.html", "HTML (*.html)");
if (filePath == "") {
return;
}
script.writeToFile(filePath, html);
}
}

View file

@ -0,0 +1,44 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script adds a menu entry to the context menu of the note list to diff selected notes in an external diff program
* The path of the diff program can be selected in the script settings of the script
*/
Script {
property string executablePath;
// register your settings variables so the user can set them in the script settings
property variant settingsVariables: [
{
"identifier": "executablePath",
"name": "Path of external diff program",
"description": "Please select the path to the executable:",
"type": "file",
"default": "kdiff3",
}
];
/**
* Initializes the custom actions
*/
function init() {
script.registerCustomAction("externalNoteDiff", "Diff selected notes", "", "", false, true, true);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "externalNoteDiff") {
return;
}
// start the diff program with the selected note paths as parameters
var params = script.selectedNotesPaths();
script.startDetachedProcess(executablePath, params);
}
}

View file

@ -0,0 +1,31 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script allows you to configure an external editor (or an other application) that should open
* a note when it is double clicked in the note list
*/
Script {
property string executablePath;
// register your settings variables so the user can set them in the script settings
property variant settingsVariables: [
{
"identifier": "executablePath",
"name": "Path of external editor",
"description": "Please select the path to the executable:",
"type": "file",
"default": "kate",
}
];
/**
* This function is called after a note was double clicked
*
* @param {NoteApi} note - the note object that was clicked
*/
function noteDoubleClickedHook(note) {
// start the editor with the note path as parameters
script.startDetachedProcess(executablePath, [note.fullNoteFilePath]);
}
}

View file

@ -0,0 +1,29 @@
import QtQml 2.0
/**
* This script creates a menu item and a button that adds a "favorite" tag to the current note
*/
QtObject {
/**
* Initializes the custom action
*/
function init() {
// create the menu entry
script.registerCustomAction("favoriteNote", "Favorite note", "fav", "bookmark-new");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
switch (identifier) {
// add a "favorite" tag to the current note
case "favoriteNote":
script.tagCurrentNote("favorite");
break;
}
}
}

View file

@ -0,0 +1,41 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This example script with input dialogs as custom actions
*/
Script {
/**
* Initializes the custom actions
*/
function init() {
script.registerCustomAction("inputDialogGetItem", "Combo box");
script.registerCustomAction("questionMessageBox", "Question message box");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
script.log("customActionInvoked - " + identifier);
switch (identifier) {
// open an input dialog with a select box
case "inputDialogGetItem":
var result = script.inputDialogGetItem(
"combo box", "Please select an item", ["Item 1", "Item 2", "Item 3"]);
script.log(result);
break;
case "questionMessageBox":
// show a question message box with an apply and a help button
// see: https://doc.qt.io/qt-5/qmessagebox.html#StandardButton-enum
var result = script.questionMessageBox(
"The text I want to show", "Some optional title", 0x01000000|0x02000000, 0x02000000);
script.log(result);
break;
}
}
}

View file

@ -0,0 +1,340 @@
import QtQml 2.0
/**
* This script detects if a GitHub issue url is in the clipboard and downloads the page
* so it can parse the headline from it to paste a markdown headline and a link
*/
QtObject {
/**
* This function is called when html or a media file is pasted to a note with `Ctrl + Shift + V`
*
* @param text text of the QMimeData object
* @param html html of the QMimeData object
* @returns the string that should be inserted instead of the text from the QMimeData object
*/
function insertingFromMimeDataHook(text, html) {
text = text.trim();
// http://www.regexpal.com is your friend
// check if the pasted text is a GitHub issue url
var re = /^http[s]?:\/\/github\.com.+\/issues\//igm;
if (re.test(text)) {
script.log("found GitHub issue url in clipboard: " + text);
// download matched GitHub url
var output = script.downloadUrlToString(text);
// parse the headline
var re2 = /<span class="\s*js-issue-title">([^>]+)<\/span>/im
var result2 = re2.exec(output);
if (result2 !== null) {
var headline = entityToHtml(result2[1].trim());
script.log("found headline: " + headline);
// generate markdown to paste
var result = "## " + headline + "\n- <" + text + ">\n";
return result;
}
script.log("no headline was found!");
} else {
script.log("no GitHub issue url was found");
}
return "";
}
/**
* Replaces html entities to characters
*/
function entityToHtml(string) {
var entity_table = {
34: "&quot;", // Quotation mark. Not required
38: "&amp;", // Ampersand. Applied before everything else in the application
60: "&lt;", // Less-than sign
62: "&gt;", // Greater-than sign
63: "&#63;", // Question mark
111: "&#111;", // Latin small letter o
160: "&nbsp;", // Non-breaking space
161: "&iexcl;", // Inverted exclamation mark
162: "&cent;", // Cent sign
163: "&pound;", // Pound sign
164: "&curren;", // Currency sign
165: "&yen;", // Yen sign
166: "&brvbar;", // Broken vertical bar
167: "&sect;", // Section sign
168: "&uml;", // Diaeresis
169: "&copy;", // Copyright sign
170: "&ordf;", // Feminine ordinal indicator
171: "&laquo;", // Left-pointing double angle quotation mark
172: "&not;", // Not sign
173: "&shy;", // Soft hyphen
174: "&reg;", // Registered sign
175: "&macr;", // Macron
176: "&deg;", // Degree sign
177: "&plusmn;", // Plus-minus sign
178: "&sup2;", // Superscript two
179: "&sup3;", // Superscript three
180: "&acute;", // Acute accent
181: "&micro;", // Micro sign
182: "&para;", // Pilcrow sign
183: "&middot;", // Middle dot
184: "&cedil;", // Cedilla
185: "&sup1;", // Superscript one
186: "&ordm;", // Masculine ordinal indicator
187: "&raquo;", // Right-pointing double angle quotation mark
188: "&frac14;", // Vulgar fraction one-quarter
189: "&frac12;", // Vulgar fraction one-half
190: "&frac34;", // Vulgar fraction three-quarters
191: "&iquest;", // Inverted question mark
192: "&Agrave;", // A with grave
193: "&Aacute;", // A with acute
194: "&Acirc;", // A with circumflex
195: "&Atilde;", // A with tilde
196: "&Auml;", // A with diaeresis
197: "&Aring;", // A with ring above
198: "&AElig;", // AE
199: "&Ccedil;", // C with cedilla
200: "&Egrave;", // E with grave
201: "&Eacute;", // E with acute
202: "&Ecirc;", // E with circumflex
203: "&Euml;", // E with diaeresis
204: "&Igrave;", // I with grave
205: "&Iacute;", // I with acute
206: "&Icirc;", // I with circumflex
207: "&Iuml;", // I with diaeresis
208: "&ETH;", // Eth
209: "&Ntilde;", // N with tilde
210: "&Ograve;", // O with grave
211: "&Oacute;", // O with acute
212: "&Ocirc;", // O with circumflex
213: "&Otilde;", // O with tilde
214: "&Ouml;", // O with diaeresis
215: "&times;", // Multiplication sign
216: "&Oslash;", // O with stroke
217: "&Ugrave;", // U with grave
218: "&Uacute;", // U with acute
219: "&Ucirc;", // U with circumflex
220: "&Uuml;", // U with diaeresis
221: "&Yacute;", // Y with acute
222: "&THORN;", // Thorn
223: "&szlig;", // Sharp s. Also known as ess-zed
224: "&agrave;", // a with grave
225: "&aacute;", // a with acute
226: "&acirc;", // a with circumflex
227: "&atilde;", // a with tilde
228: "&auml;", // a with diaeresis
229: "&aring;", // a with ring above
230: "&aelig;", // ae. Also known as ligature ae
231: "&ccedil;", // c with cedilla
232: "&egrave;", // e with grave
233: "&eacute;", // e with acute
234: "&ecirc;", // e with circumflex
235: "&euml;", // e with diaeresis
236: "&igrave;", // i with grave
237: "&iacute;", // i with acute
238: "&icirc;", // i with circumflex
239: "&iuml;", // i with diaeresis
240: "&eth;", // eth
241: "&ntilde;", // n with tilde
242: "&ograve;", // o with grave
243: "&oacute;", // o with acute
244: "&ocirc;", // o with circumflex
245: "&otilde;", // o with tilde
246: "&ouml;", // o with diaeresis
247: "&divide;", // Division sign
248: "&oslash;", // o with stroke. Also known as o with slash
249: "&ugrave;", // u with grave
250: "&uacute;", // u with acute
251: "&ucirc;", // u with circumflex
252: "&uuml;", // u with diaeresis
253: "&yacute;", // y with acute
254: "&thorn;", // thorn
255: "&yuml;", // y with diaeresis
264: "&#264;", // Latin capital letter C with circumflex
265: "&#265;", // Latin small letter c with circumflex
338: "&OElig;", // Latin capital ligature OE
339: "&oelig;", // Latin small ligature oe
352: "&Scaron;", // Latin capital letter S with caron
353: "&scaron;", // Latin small letter s with caron
372: "&#372;", // Latin capital letter W with circumflex
373: "&#373;", // Latin small letter w with circumflex
374: "&#374;", // Latin capital letter Y with circumflex
375: "&#375;", // Latin small letter y with circumflex
376: "&Yuml;", // Latin capital letter Y with diaeresis
402: "&fnof;", // Latin small f with hook, function, florin
710: "&circ;", // Modifier letter circumflex accent
732: "&tilde;", // Small tilde
913: "&Alpha;", // Alpha
914: "&Beta;", // Beta
915: "&Gamma;", // Gamma
916: "&Delta;", // Delta
917: "&Epsilon;", // Epsilon
918: "&Zeta;", // Zeta
919: "&Eta;", // Eta
920: "&Theta;", // Theta
921: "&Iota;", // Iota
922: "&Kappa;", // Kappa
923: "&Lambda;", // Lambda
924: "&Mu;", // Mu
925: "&Nu;", // Nu
926: "&Xi;", // Xi
927: "&Omicron;", // Omicron
928: "&Pi;", // Pi
929: "&Rho;", // Rho
931: "&Sigma;", // Sigma
932: "&Tau;", // Tau
933: "&Upsilon;", // Upsilon
934: "&Phi;", // Phi
935: "&Chi;", // Chi
936: "&Psi;", // Psi
937: "&Omega;", // Omega
945: "&alpha;", // alpha
946: "&beta;", // beta
947: "&gamma;", // gamma
948: "&delta;", // delta
949: "&epsilon;", // epsilon
950: "&zeta;", // zeta
951: "&eta;", // eta
952: "&theta;", // theta
953: "&iota;", // iota
954: "&kappa;", // kappa
955: "&lambda;", // lambda
956: "&mu;", // mu
957: "&nu;", // nu
958: "&xi;", // xi
959: "&omicron;", // omicron
960: "&pi;", // pi
961: "&rho;", // rho
962: "&sigmaf;", // sigmaf
963: "&sigma;", // sigma
964: "&tau;", // tau
965: "&upsilon;", // upsilon
966: "&phi;", // phi
967: "&chi;", // chi
968: "&psi;", // psi
969: "&omega;", // omega
977: "&thetasym;", // Theta symbol
978: "&upsih;", // Greek upsilon with hook symbol
982: "&piv;", // Pi symbol
8194: "&ensp;", // En space
8195: "&emsp;", // Em space
8201: "&thinsp;", // Thin space
8204: "&zwnj;", // Zero width non-joiner
8205: "&zwj;", // Zero width joiner
8206: "&lrm;", // Left-to-right mark
8207: "&rlm;", // Right-to-left mark
8211: "&ndash;", // En dash
8212: "&mdash;", // Em dash
8216: "&lsquo;", // Left single quotation mark
8217: "&rsquo;", // Right single quotation mark
8218: "&sbquo;", // Single low-9 quotation mark
8220: "&ldquo;", // Left double quotation mark
8221: "&rdquo;", // Right double quotation mark
8222: "&bdquo;", // Double low-9 quotation mark
8224: "&dagger;", // Dagger
8225: "&Dagger;", // Double dagger
8226: "&bull;", // Bullet
8230: "&hellip;", // Horizontal ellipsis
8240: "&permil;", // Per mille sign
8242: "&prime;", // Prime
8243: "&Prime;", // Double Prime
8249: "&lsaquo;", // Single left-pointing angle quotation
8250: "&rsaquo;", // Single right-pointing angle quotation
8254: "&oline;", // Overline
8260: "&frasl;", // Fraction Slash
8364: "&euro;", // Euro sign
8472: "&weierp;", // Script capital
8465: "&image;", // Blackletter capital I
8476: "&real;", // Blackletter capital R
8482: "&trade;", // Trade mark sign
8501: "&alefsym;", // Alef symbol
8592: "&larr;", // Leftward arrow
8593: "&uarr;", // Upward arrow
8594: "&rarr;", // Rightward arrow
8595: "&darr;", // Downward arrow
8596: "&harr;", // Left right arrow
8629: "&crarr;", // Downward arrow with corner leftward. Also known as carriage return
8656: "&lArr;", // Leftward double arrow. ISO 10646 does not say that lArr is the same as the 'is implied by' arrow but also does not have any other character for that function. So ? lArr can be used for 'is implied by' as ISOtech suggests
8657: "&uArr;", // Upward double arrow
8658: "&rArr;", // Rightward double arrow. ISO 10646 does not say this is the 'implies' character but does not have another character with this function so ? rArr can be used for 'implies' as ISOtech suggests
8659: "&dArr;", // Downward double arrow
8660: "&hArr;", // Left-right double arrow
// Mathematical Operators
8704: "&forall;", // For all
8706: "&part;", // Partial differential
8707: "&exist;", // There exists
8709: "&empty;", // Empty set. Also known as null set and diameter
8711: "&nabla;", // Nabla. Also known as backward difference
8712: "&isin;", // Element of
8713: "&notin;", // Not an element of
8715: "&ni;", // Contains as member
8719: "&prod;", // N-ary product. Also known as product sign. Prod is not the same character as U+03A0 'greek capital letter pi' though the same glyph might be used for both
8721: "&sum;", // N-ary summation. Sum is not the same character as U+03A3 'greek capital letter sigma' though the same glyph might be used for both
8722: "&minus;", // Minus sign
8727: "&lowast;", // Asterisk operator
8729: "&#8729;", // Bullet operator
8730: "&radic;", // Square root. Also known as radical sign
8733: "&prop;", // Proportional to
8734: "&infin;", // Infinity
8736: "&ang;", // Angle
8743: "&and;", // Logical and. Also known as wedge
8744: "&or;", // Logical or. Also known as vee
8745: "&cap;", // Intersection. Also known as cap
8746: "&cup;", // Union. Also known as cup
8747: "&int;", // Integral
8756: "&there4;", // Therefore
8764: "&sim;", // tilde operator. Also known as varies with and similar to. The tilde operator is not the same character as the tilde, U+007E, although the same glyph might be used to represent both
8773: "&cong;", // Approximately equal to
8776: "&asymp;", // Almost equal to. Also known as asymptotic to
8800: "&ne;", // Not equal to
8801: "&equiv;", // Identical to
8804: "&le;", // Less-than or equal to
8805: "&ge;", // Greater-than or equal to
8834: "&sub;", // Subset of
8835: "&sup;", // Superset of. Note that nsup, 'not a superset of, U+2283' is not covered by the Symbol font encoding and is not included.
8836: "&nsub;", // Not a subset of
8838: "&sube;", // Subset of or equal to
8839: "&supe;", // Superset of or equal to
8853: "&oplus;", // Circled plus. Also known as direct sum
8855: "&otimes;", // Circled times. Also known as vector product
8869: "&perp;", // Up tack. Also known as orthogonal to and perpendicular
8901: "&sdot;", // Dot operator. The dot operator is not the same character as U+00B7 middle dot
// Miscellaneous Technical
8968: "&lceil;", // Left ceiling. Also known as an APL upstile
8969: "&rceil;", // Right ceiling
8970: "&lfloor;", // left floor. Also known as APL downstile
8971: "&rfloor;", // Right floor
9001: "&lang;", // Left-pointing angle bracket. Also known as bra. Lang is not the same character as U+003C 'less than'or U+2039 'single left-pointing angle quotation mark'
9002: "&rang;", // Right-pointing angle bracket. Also known as ket. Rang is not the same character as U+003E 'greater than' or U+203A 'single right-pointing angle quotation mark'
// Geometric Shapes
9642: "&#9642;", // Black small square
9643: "&#9643;", // White small square
9674: "&loz;", // Lozenge
// Miscellaneous Symbols
9702: "&#9702;", // White bullet
9824: "&spades;", // Black (filled) spade suit
9827: "&clubs;", // Black (filled) club suit. Also known as shamrock
9829: "&hearts;", // Black (filled) heart suit. Also known as shamrock
9830: "&diams;" // Black (filled) diamond suit
}
for (var i in entity_table) {
for (var i in entity_table) {
if (i != 38) {
string = string.replace(new RegExp(entity_table[i], "g"), String.fromCharCode(i));
}
}
string = string.replace(new RegExp("&#(x?)(\\d+);", "g"), function(match, p1, p2, string) {
return String.fromCharCode(((p1 == 'x') ? parseInt(p2, 16) : p2));
});
string = string.replace(new RegExp(entity_table[38], "g"), String.fromCharCode(38));
return string;
}
}
}

View file

@ -0,0 +1,45 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script creates a menu item and a button to create or jump to the current date's journal entry
*/
QtObject {
/**
* Initializes the custom action
*/
function init() {
script.registerCustomAction("journalEntry", "Create or open a journal entry", "Journal", "document-new");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "journalEntry") {
return;
}
// get the date headline
var m = new Date();
var headline = m.getFullYear() + ("0" + (m.getMonth()+1)).slice(-2) + ("0" + m.getDate()).slice(-2);
var fileName = headline + ".md";
var note = script.fetchNoteByFileName(fileName);
// check if note was found
if (note.id > 0) {
// jump to the note if it was found
script.log("found journal entry: " + headline);
script.setCurrentNote(note);
} else {
// create a new journal entry note if it wasn't found
// keep in mind that the note will not be created instantly on the disk
script.log("creating new journal entry: " + headline);
script.createNote(headline + "\n========\n\n");
}
}
}

View file

@ -0,0 +1,49 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script creates a menu item and a button to create or jump to the current date's meeting note
*/
QtObject {
/**
* Initializes the custom action
*/
function init() {
script.registerCustomAction("meetingNote", "Create or open a meeting note", "Meeting", "document-new");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "meetingNote") {
return;
}
// get the date headline
var m = new Date();
var headline = "Teammeeting " + m.getFullYear() + "-" + ("0" + (m.getMonth()+1)).slice(-2) + "-" + ("0" + m.getDate()).slice(-2);
var fileName = headline + ".md";
var note = script.fetchNoteByFileName(fileName);
// check if note was found
if (note.id > 0) {
// jump to the note if it was found
script.log("found meeting note: " + headline);
script.setCurrentNote(note);
} else {
// create a new meeting note if it wasn't found
// keep in mind that the note will not be created instantly on the disk
script.log("creating new meeting note: " + headline);
script.createNote(headline + "\n====================\n\n");
// tag the current note
script.tagCurrentNote("meeting");
script.tagCurrentNote("fuf");
}
}
}

View file

@ -0,0 +1,118 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script creates a menu item and a button that parses the text that was copied
* from a task email of the webservice 5pm and creates a new note with a headline,
* the link to the task and the description
*/
QtObject {
/**
* Initializes the custom action
*/
function init() {
// create a menu entry "New 5pm note" with a button and a freedesktop theme icon
script.registerCustomAction("new5pmNote", "New 5pm note", "5pm", "task-new");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
switch (identifier) {
// create a new note from a 5pm mail text in the clipboard
case "new5pmNote":
// get the text that is currently in the clipboard
text = script.clipboard();
// http://www.regexpal.com is your friend
var re1 = /^(.+)\sStart Datum/igm;
var result1 = re1.exec(text);
if (result1 === null) {
re1 = /^Neue Aufgabe von [\w\s]+$\s\s^(.+)$/igm;
result1 = re1.exec(text);
}
if (result1 === null) {
re1 = /^Nachricht aktualisiert von [\w\s]+$\s\s^Aufgabe: (.+)$/igm;
result1 = re1.exec(text);
}
if (result1 === null) {
re1 = /^Neue Nachricht erstellt von [\w\s]+$\s\s^Aufgabe: (.+)$/igm;
result1 = re1.exec(text);
}
var re2 = /^Direkter Zugriff hier: (http.+\d+)$/im;
var result2 = re2.exec(text);
var re3 = /^Projekt: .+\nBeschreibung: ((.|\n)+)^Priorität: /igm;
var result3 = re3.exec(text);
if (result3 === null) {
re3 = /^Projekt: .+\n((.|\n)+)^Direkter Zugriff hier: /igm;
result3 = re3.exec(text);
}
script.log("result1: " + result1);
script.log("result2: " + result2);
// script.log(result3);
// return an empty string if we didn't find anything
if ((result1 === null) || (result2 === null)) {
script.log("no 5pm task was found");
return "";
}
var url = result2[1];
// script.log("url: " + url);
var re4 = /task=(\d+)/i;
var result4 = re4.exec(url);
// script.log("result4: " + result4);
var id = result4[1];
var headline = result1[1] + " (" + id + ")";
// add the headline of the task
var text = headline + "\n";
// add "=" characters so that the headline is really a headline
for (var i = 0; i < headline.length; i++) {
text += "=";
}
// add the url to the task
text += "\n\n- <" + url + ">";
// add the description of the task
if (result3 !== null) {
var description = result3[1];
text += "\n\n" + description
}
// add a date headline
var m = new Date();
var dateString =
("0" + m.getDate()).slice(-2) + "." +
("0" + (m.getMonth()+1)).slice(-2) + "." +
(" " + m.getFullYear()).slice(-2);
text += "\n\n## " + dateString + "\n\n";
// create a new note
script.createNote(text);
// tag the current note
script.tagCurrentNote("todo");
// workaround because the parsers don't seem to work every time
script.reloadScriptingEngine();
break;
}
}
}

View file

@ -0,0 +1,127 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script creates a menu item and a button that parses the text that was copied
* from a task webpage of the webservice bitrix24 and creates a new note with a headline,
* the link to the task and the description
*/
QtObject {
/**
* Initializes the custom action
*/
function init() {
// create a menu entry "New Bitrix note" with a button and a freedesktop theme icon
script.registerCustomAction("newBitrixTaskNote", "New Bitrix task note", "Bitrix", "task-new");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
switch (identifier) {
// create a new note from a Bitrix task webpage text in the clipboard
// like from https://yourname.bitrix24.com/workgroups/group/10/tasks/task/view/150/
case "newBitrixTaskNote":
// get the text that is currently in the clipboard
var html = script.clipboard(true);
script.log(html);
// https://regex101.com is your friend
// var headlineRegExp = /<span class="pagetitle-inner".*?>(.+?)<\/span>/im;
var headlineRegExp = /<span id="pagetitle".*?>(.+?)<\/?span/im;
var headlineMatch = headlineRegExp.exec(html);
var headline = headlineMatch !== null ? headlineMatch[1] : "";
// remove the "aufgabe" text and all "/"
headline = headline.replace("(aufgabe #", "(#").replace(/\s*\//igm, "");
if (headline == "") {
script.informationMessageBox("No Bitrix task headline was found!", "Bitrix task note");
return;
}
// add the task id to the headline
var taskIdRegExp = /<div class="task-detail-subtitle-status.*?".*?>Aufgabe #(\d+)/im;
var taskIdMatch = taskIdRegExp.exec(html);
if (taskIdMatch !== null) {
headline += " (#" + taskIdMatch[1] + ")";
}
var descriptionRegExp = /<div.*? id="task-detail-description".*?>(.+?)<\/div>/im;
var descriptionMatch = descriptionRegExp.exec(html);
var description = descriptionMatch !== null ? descriptionMatch[1] : "";
// replace links
// description = description.replace(/<a href="(.+?)".*?>(.+?)<\/a>/gim, "[$2]($1)");
description = description.replace(/<a href="(.+?)".*?>(.+?)<\/a>/gim, "&lt;$1&gt;");
// transform html breaks to \n and remove all other tags
description = description.replace(/<br.*?>/gim, "\n").replace(/<.+?>/gim, "");
// var urlRegExp = /<form name="COMMENTS_.+?".*? action="(.+?)" method/im;
var urlRegExp = /<a href="(.+?\d+\/tasks\/task\/view\/d+\/)[\?#].*?" class="main-buttons-item-link"/im;
var urlMatch = urlRegExp.exec(html);
var url = urlMatch !== null ? urlMatch[1] : "";
// fallback url parsing
if (url == "") {
var urlRegExp = /<\/span><a href="(.+?)[\?#].*?" class="task-view-button edit.*?"/im;
var urlMatch = urlRegExp.exec(html);
var url = urlMatch !== null ? urlMatch[1] : "";
// we got the edit-url, but we want the view-url
url = url.replace("task/edit", "task/view");
}
// script.log("headline");
// script.log(headline);
// script.log(url);
// script.log(descriptionMatch);
// script.log(description);
// script.log(url);
// add the headline of the task
var text = headline + "\n";
// add "=" characters so that the headline is really a headline
for (var i = 0; i < headline.length; i++) {
text += "=";
}
// add the url to the task
if (url != "") {
text += "\n\n- <" + url + ">";
}
// add the description of the task
if (description != "") {
text += "\n\n" + description;
}
text = text.replace(/&gt;/gim, ">").replace(/&lt;/gim, "<");
// add a date headline
var m = new Date();
var dateString =
("0" + m.getDate()).slice(-2) + "." +
("0" + (m.getMonth()+1)).slice(-2) + "." +
m.getFullYear();
text += "\n\n## " + dateString + "\n\n";
// create a new note
script.createNote(text);
// tag the current note
script.tagCurrentNote("todo");
// workaround because the parsers don't seem to work every time
script.reloadScriptingEngine();
break;
}
}
}

View file

@ -0,0 +1,108 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script creates a menu item and a button that parses the text that was copied
* from an issue webpage of Jira and creates a new note with a headline,
* the link to the issue and the description
*/
QtObject {
/**
* Initializes the custom action
*/
function init() {
// create a menu entry "New Jira note" with a button and a freedesktop theme icon
script.registerCustomAction("newJiraIssueNote", "New Jira issue note", "Jira", "task-new");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "newJiraIssueNote") {
return;
}
// create a new note from a Jira issue webpage text in the clipboard
// like from https://jira.madsack-online.de/browse/EZ-127185
// get the text that is currently in the clipboard
var html = script.clipboard(true);
// script.log(html);
// https://regex101.com is your friend
var headlineRegExp = /<h1 id="summary-val".*?>(.+?)<\/?h1>/im;
var headlineMatch = headlineRegExp.exec(html);
var headline = headlineMatch !== null ? headlineMatch[1] : "";
// remove all /, " and '
headline = headline.replace(/\s*\//igm, "").replace(/["']/igm, "").replace(/<.+?>/igm, "");
if (headline == "") {
script.informationMessageBox("No Jira issue headline was found!", "Jira issue note");
return;
}
// add the issue id to the headline
var issueIdRegExp = /<a class="issue-link" data-issue-key="([^"]+)" href="(http[^"]+\/browse\/[^"]+)" id="key-val"/im;
var issueIdMatch = issueIdRegExp.exec(html);
var url;
if (issueIdMatch !== null) {
headline += " (" + issueIdMatch[1] + ")";
url = issueIdMatch[2];
}
var descriptionRegExp = /<div.*? id="description-val".*?>(.+?)<\/div>/im;
var descriptionMatch = descriptionRegExp.exec(html);
var description = descriptionMatch !== null ? descriptionMatch[1] : "";
// replace links
// description = description.replace(/<a href="(.+?)".*?>(.+?)<\/a>/gim, "[$2]($1)");
description = description.replace(/<a href="(.+?)".*?>(.+?)<\/a>/gim, "&lt;$1&gt;");
// transform html breaks to \n, <p> into \n\n and remove all other tags
description = description.replace(/<br.*?>/gim, "\n").replace(/<\/p>/gim, "\n\n").replace(/<.+?>/gim, "").trim();
// add the headline of the issue
var text = headline + "\n";
// add "=" characters so that the headline is really a headline
for (var i = 0; i < headline.length; i++) {
text += "=";
}
text += "\n\n";
// add the url to the issue
if (url != "") {
text += "- <" + url + ">\n\n";
}
// add the description of the issue
if (description != "") {
text += description + "\n\n";
}
text = text.replace(/&gt;/gim, ">").replace(/&lt;/gim, "<");
// add a date headline
var m = new Date();
var dateString =
("0" + m.getDate()).slice(-2) + "." +
("0" + (m.getMonth()+1)).slice(-2) + "." +
m.getFullYear();
text += "\n\n## " + dateString + "\n\n";
// create a new note
script.createNote(text);
// tag the current note
script.tagCurrentNote("todo");
// workaround because the parsers don't seem to work every time
// script.reloadScriptingEngine();
}
}

View file

@ -0,0 +1,29 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/* This script shows current note statistics in a "label":
Char(+s) = characters including spaces
Char(s) = characters excluding spaces
Words = character groups divided by spaces
Paras = paragraphs - character groups divided by line breaks
*/
QtObject {
function init() {script.registerLabel("note stats")}
function noteStats(note) {
script.setLabelText("note stats",
"<table align=center width=90%>
<tr>
<td align=center>Char(+s) <b>" + note.noteText.length + "</b></th>
<td align=center>Char(s) <b>" + note.noteText.match(/[^ ]/gi).length + "</b></th>
<td align=center>Words <b>" + note.noteText.split(/\s+/).length + "</b></th>
<td align=center>Paras <b>" + (note.noteText.match(/^.*?\S/gm) || "").length + "</b></th>
</tr>
</table>")
}
function noteOpenedHook(note) {noteStats(note)}
function onNoteStored(note) {noteStats(note)}
}

View file

@ -0,0 +1,104 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script handles tagging in a note for tags in the note text like:
* @tag1 @tag2 @tag3
*/
Script {
/**
* Handles note tagging for a note
*
* This function is called when tags are added to, removed from or renamed in
* a note or the tags of a note should be listed
*
* @param note
* @param action can be "add", "remove", "rename" or "list"
* @param tag to be added, removed or renamed
* @param newTagName tag name to be renamed to if action = "rename"
* @return note text string or string-list of tag ids (if action = "list")
*/
function noteTaggingByObjectHook(note, action, tag, newTagName) {
var tagName = tag.name;
var noteText = note.noteText;
var tagRegExp = RegExp("\\B@" + escapeRegExp(tagName) + "\\b");
script.log("action: " + action);
switch (action) {
// adds the tag "tagName" to the note
// the new note text has to be returned so that the note can be updated
// returning an empty string indicates that nothing has to be changed
case "add":
// check if tag already exists
if (noteText.search(tagRegExp) > 0) {
return "";
}
// add the tag at the end of the note
noteText += "\n@" + tagName;
script.log("Adding tag '" + tagName + "' to note");
return noteText;
break;
// removes the tag "tagName" from the note
// the new note text has to be returned so that the note can be updated
// returning an empty string indicates that nothing has to be changed
case "remove":
noteText = noteText.replace(tagRegExp, "");
script.log("Removing tag '" + tagName + "' from note");
return noteText;
break;
// renames the tag "tagName" in the note to "newTagName"
// the new note text has to be returned so that the note can be updated
// returning an empty string indicates that nothing has to be changed
case "rename":
noteText = noteText.replace(tagRegExp, "@" + newTagName);
script.log("Renaming tag '" + tagName + "' in note");
return noteText;
break;
// returns a list of all tag names of the note
case "list":
var tag = script.getTagByNameBreadcrumbList(["level1a", "level2b", "level3b"]);
script.log(tag.id);
script.log(tag.name);
var re = new RegExp("\\B@([^\\s,]+)", "gi"),
result, tagIdList = [];
while ((result = re.exec(noteText)) !== null) {
var tagName = result[1];
tag.fetchByName(tagName);
var tagId = tag.id;
if (tagId == 0) {
// TODO: create tag and set tagId
continue;
}
// add the tag if it wasn't in the list
if (tagIdList.indexOf(tagId) == -1) {
tagIdList.push(tagId);
script.log(tagId);
}
}
if (tagIdList.length > 0) {
script.log("Found tags '" + tagIdList + "' in note");
}
return tagIdList;
break;
}
return "";
}
/**
* Escapes a string for regular expressions
*/
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
}

View file

@ -0,0 +1,89 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script handles tagging in a note for tags in the note text like:
* @tag1 @tag2 @tag3
*/
Script {
/**
* Handles note tagging for a note
*
* This function is called when tags are added to, removed from or renamed in
* a note or the tags of a note should be listed
*
* @param note
* @param action can be "add", "remove", "rename" or "list"
* @param tagName tag name to be added, removed or renamed
* @param newTagName tag name to be renamed to if action = "rename"
* @return string or string-list (if action = "list")
*/
function noteTaggingHook(note, action, tagName, newTagName) {
var noteText = note.noteText;
var tagRegExp = RegExp("\\B@" + escapeRegExp(tagName) + "\\b");
switch (action) {
// adds the tag "tagName" to the note
// the new note text has to be returned so that the note can be updated
// returning an empty string indicates that nothing has to be changed
case "add":
// check if tag already exists
if (noteText.search(tagRegExp) > 0) {
return "";
}
// add the tag at the end of the note
noteText += "\n@" + tagName;
script.log("Adding tag '" + tagName + "' to note");
return noteText;
break;
// removes the tag "tagName" from the note
// the new note text has to be returned so that the note can be updated
// returning an empty string indicates that nothing has to be changed
case "remove":
noteText = noteText.replace(tagRegExp, "");
script.log("Removing tag '" + tagName + "' from note");
return noteText;
break;
// renames the tag "tagName" in the note to "newTagName"
// the new note text has to be returned so that the note can be updated
// returning an empty string indicates that nothing has to be changed
case "rename":
noteText = noteText.replace(tagRegExp, "@" + newTagName);
script.log("Renaming tag '" + tagName + "' in note");
return noteText;
break;
// returns a list of all tag names of the note
case "list":
var re = new RegExp("\\B@([^\\s,]+)", "gi"),
result, tagNameList = [];
while ((result = re.exec(noteText)) !== null) {
var tagName = result[1];
// add the tag if it wasn't in the list
if (tagNameList.indexOf(tagName) == -1) {
tagNameList.push(tagName);
}
}
if (tagNameList.length > 0) {
script.log("Found tags '" + tagNameList + "' in note");
}
return tagNameList;
break;
}
return "";
}
/**
* Escapes a string for regular expressions
*/
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
}

View file

@ -0,0 +1,82 @@
import QtQml 2.0
/**
* This script parses the text that was copied from a task email of the webservice 5pm
* and creates a note text with a headline, the link to the task and the description
*/
QtObject {
/**
* This function is called when html or a media file is pasted to a note with `Ctrl + Shift + V`
*
* @param text text of the QMimeData object
* @param html html of the QMimeData object
* @returns the string that should be inserted instead of the text from the QMimeData object
*/
function insertingFromMimeDataHook(text, html) {
// script.log(text);
// script.log(html);
// http://www.regexpal.com is your friend
var re1 = /^Neue Aufgabe von [\w\s]+$\s\s^(.+)$/igm;
var result1 = re1.exec(text);
if (result1 === null) {
re1 = /^Nachricht aktualisiert von [\w\s]+$\s\s^Aufgabe: (.+)$/igm;
result1 = re1.exec(text);
}
if (result1 === null) {
re1 = /^Neue Nachricht erstellt von [\w\s]+$\s\s^Aufgabe: (.+)$/igm;
result1 = re1.exec(text);
}
var re2 = /^Direkter Zugriff hier: (http.+\d+)$/igm;
var result2 = re2.exec(text);
var re3 = /^Projekt: .+\nBeschreibung: ((.|\n)+)^Priorität: /igm;
var result3 = re3.exec(text);
if (result3 === null) {
re3 = /^Projekt: .+\n((.|\n)+)^Direkter Zugriff hier: /igm;
result3 = re3.exec(text);
}
// script.log(result1);
// script.log(result2);
// script.log(result3);
// return an empty string if we didn't find anything
if ((result1 === null) || (result2 === null)) {
script.log("no 5pm task was found");
return "";
}
var url = result2[1];
var re4 = /(\d+)$/igm;
var result4 = re4.exec(url);
var id = result4[1];
var headline = result1[1] + " (" + id + ")";
// add the headline of the task
var text = headline + "\n";
// add "=" charactes so that the headline is really a headline
for (var i = 0; i < headline.length; i++) {
text += "=";
}
// add the url to the task
text += "\n\n- <" + url + ">";
// add the description of the task
if (result3 !== null) {
var description = result3[1];
text += "\n\n" + description
}
// return the text that should be pasted
return text;
}
}

View file

@ -0,0 +1,16 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is an example how to get a notification when a note was opened
*/
QtObject {
/**
* This function is called after a note was opened
*
* @param {Note} note - the note object that was opened
*/
function noteOpenedHook(note) {
script.log(note.fullNoteFilePath);
}
}

View file

@ -0,0 +1,39 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script creates a menu item and a button that parses the text that was copied from the Skype Electron client
* to the clipboard and tries to extract and paste text from it
*/
QtObject {
/**
* Initializes the custom action
*/
function init() {
// create a menu entry with a button and a freedesktop theme icon
script.registerCustomAction("pasteFromSkypeHistory", "Paste text from Skype history", "Paste Skype Text", "edit-paste");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "pasteFromSkypeHistory") {
return;
}
// get the text that is currently in the clipboard
var html = script.clipboard(true);
// script.log(html);
var textRegExp = /<p.*?>(.+?)<\/p>/gim;
var match;
while ((match = textRegExp.exec(html)) !== null) {
script.noteTextEditWrite(match[1].replace(/<.+?>/gim, "") + "\n");
}
}
}

View file

@ -0,0 +1,19 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is an example of pasting an image link with the full file url if a file is dropped into QOwnNotes
* It was created for this question: https://github.com/pbek/QOwnNotes/issues/623
*/
Script {
/**
* This function is called when html or a media file is pasted to a note with `Ctrl + Shift + V`
*
* @param text text of the QMimeData object
* @param html html of the QMimeData object
* @returns the string that should be inserted instead of the text from the QMimeData object
*/
function insertingFromMimeDataHook(text, html) {
return "![My image name](" + text + ")";
}
}

View file

@ -0,0 +1,38 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script creates a menu item and a button that generates and pastes an image from
* Latex code in the clipboard
*/
QtObject {
/**
* Initializes the custom action
*/
function init() {
// create a menu entry to paste Latex code as an image
script.registerCustomAction("pasteLatexImage", "Paste Latex image", "Latex", "insert-image", true);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
switch (identifier) {
case "pasteLatexImage":
// get the text that is currently in the clipboard
var text = script.clipboard();
// use the webservice to generate and download the image
var url = "http://latex.codecogs.com/gif.latex?" + text;
var markdown = script.downloadUrlToMedia(url);
// write the image markdown to the note
script.noteTextEditWrite(markdown);
break;
}
}
}

View file

@ -0,0 +1,34 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This is an example on how to use persistent variables.
*/
Script {
function init() {
script.registerCustomAction("persistentVariablesSetTest", "Persistent variables set test", "Persistent var set test", "edit-copy");
script.registerCustomAction("persistentVariablesGetTest", "Persistent variables get test", "Persistent var get test", "edit-paste");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier == "persistentVariablesSetTest") {
var result = script.inputDialogGetItem(
"combo box", "Please select an item", ["Item 1", "Item 2", "Item 3"]);
// store persistent variable
script.setPersistentVariable("PersistentVariablesTest/myVar", result);
}
if (identifier == "persistentVariablesGetTest") {
// load and log persistent variable
script.log(script.getPersistentVariable("PersistentVariablesTest/myVar", "nothing here yet"));
}
}
}

View file

@ -0,0 +1,76 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/* This script is tested only on GNU/Linux, it's not tested on OSX and won't work on Windows.
* If you know how to make it properly rename note files in Windows feel free to make a pull request.
*
* This script implements custom action buttons to prepend current note name with a special (or any other)
* unicode symbols so the note will be "pinned" on top of the list with "alphabetical sorting" on.
* You can use different symbols, one at a time, to "pin" notes.
* That allows to make kind of hierarchy of pinned notes.
*
* Notes can be "unpinned" by using same symbol second time.
*
* Since the script actually creates a new note with the same content assigned tags won't be saved.
*
* This script should be used with "Allow note file name to be different from headline",
* "Accept all external modification of current note", "Sort by -> Alphabetical" options on. */
QtObject {
/* Put different symbols to prepend note name here, as much of them as you like.
* You can get more unicode symbols at https://unicode-table.com/en/#dingbats
* Some unicode symbols can be unavailable in font set used in your system. */
property var symbol:["★", "⚑", "✔", "☎"]
/// Each symbol will get own button to add it to selected note name.
function init() {
for (var n = 0; n < symbol.length; n++) {
script.registerCustomAction(n, "Mark note with " + symbol[n], symbol[n])
}
}
/// Each symbol uses single algorithm to prepend note name with it.
function customActionInvoked(n) {
if (symbol.indexOf(symbol[n]) == -1) {
exit()
}
/// Get note data
var note = script.currentNote()
var fullFileName = note.fullNoteFilePath
var fileName = note.fileName
var filePath = fullFileName.replace(fileName,"")
script.log("Note: " + note + fullFileName)
/* Delete symbol if note is "pinned" by it.
* Or prepend "unpinned" note with that symbol.
* Or "repin" note with the new symbol. */
if (fileName.substring(0,2) == symbol[n] + " ") {
var newFileName = fileName.substring(2)
script.log("Note " + fileName + " unmarked")
}
else if (symbol.indexOf(fileName.substring(0,1)) != -1 && fileName.substring(1,2) == " ") {
var newFileName = symbol[n] + " " + fileName.substring(2)
script.log("Note " + fileName + " marked with " + symbol[n])
}
else {
var newFileName = symbol[n] + " " + fileName
script.log("Note " + fileName + " marked with " + symbol[n])
}
/* Since QOwnNotes doesn't allow to delete notes with scripting yet,
* rename the note file by a system's native command with a new "prepended" name.
* Use different commands for Windows and POSIX systems. */
if (script.platformIsWindows()) {
script.log("This script currently doesn't work in Windows. Sorry for inconvenience." )
} else {
var moveCommand = "mv"
var arguments = [fullFileName,filePath + newFileName]
}
script.startSynchronousProcess(moveCommand, arguments, "")
}
}

View file

@ -0,0 +1,49 @@
import QtQml 2.0
/**
* This is an example for custom styling of html in the note preview
*/
QtObject {
/**
* This function is called before the markdown html of a note is generated
*
* It allows you to modify what is passed to the markdown to html converter
*
* The method can for example be used in multiple scripts to render code (like LaTeX math or mermaid)
* to its graphical representation for the preview
*
* The note will not be changed in this process
*
* @param {NoteApi} note - the note object
* @param {string} markdown - the markdown that is about to being converted to html
* @param {string} forExport - true if the html is used for an export, false for the preview
* @return {string} the modified markdown or an empty string if nothing should be modified
*/
function preNoteToMarkdownHtmlHook(note, markdown, forExport) {
markdown = markdown.replace("- special text", "- something else");
return markdown;
}
/**
* This function is called when the markdown html of a note is generated
*
* It allows you to modify this html
* This is for example called before by the note preview
*
* @param {Note} note - the note object
* @param {string} html - the html that is about to being rendered
* @param {string} forExport - true if the html is used for an export, false for the preview
* @return {string} the modified html or an empty string if nothing should be modified
*/
function noteToMarkdownHtmlHook(note, html, forExport) {
// see http://doc.qt.io/qt-5/richtext-html-subset.html for a list of
// supported css styles
if (forExport) {
var stylesheet = "h2 {margin-left: 25px; color: blue;} h3 {margin-left: 45px;} h4 {margin-left: 65px;}";
} else {
var stylesheet = "h2 {margin-left: 20px; color: red;} h3 {margin-left: 40px;} h4 {margin-left: 60px;}";
}
html = html.replace("</style>", stylesheet + "</style>");
return html;
}
}

View file

@ -0,0 +1,79 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script adds a menu entry to the context menu of the note edit to insert a
* scribble image to the media-folder, that will be edited by an external image editor
*
* The path of the image editor and the image template can be selected in the script settings of the script
*/
Script {
property string executablePath;
property string imagePath;
property bool executeInBackground;
// the path to the script's directory will be set here
property string scriptDirPath;
// register your settings variables so the user can set them in the script settings
property variant settingsVariables: [
{
"identifier": "executablePath",
"name": "Path of external image editor",
"description": "Please select the path of the executable:",
"type": "file",
"default": "gimp",
},
{
"identifier": "imagePath",
"name": "Path of template image",
"description": "Please select the path of the template image:",
"type": "file",
"default": scriptDirPath + "/scribble.png",
},
{
"identifier": "executeInBackground",
"name": "Execute image editor in background",
"description": "If the image editor is executed in the background you will be able to work with QOwnNotes while you are editing the scribble, but the note preview will not be refreshed automatically after you close the image editor.",
"text": "Execute in background",
"type": "boolean",
"default": false,
}
];
/**
* Initializes the custom actions
*/
function init() {
script.registerCustomAction("scribble", "Add scribble", "Scribble", "view-preview", true, false, false);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "scribble") {
return;
}
// insert the scribble template image as media file
var mediaFile = script.insertMediaFile(imagePath, true);
var mediaFilePath = mediaFile.replace("file://media", script.currentNoteFolderPath() + "/media");
// write the scribble image to the note
script.noteTextEditWrite("![scribble](" + mediaFile + ")\n");
var params = [mediaFilePath];
// edit the scribble image
if (executeInBackground) {
script.startDetachedProcess(executablePath, params);
} else {
script.startSynchronousProcess(executablePath, params);
script.regenerateNotePreview();
}
}
}

View file

@ -0,0 +1,34 @@
import QtQml 2.0
/**
* This script creates scripting labels
*
*/
QtObject {
/**
* Initializes the labels
*/
function init() {
script.registerLabel("html-label", "<strong>Strong</strong> HTML text<br />with three lines<br />and a <a href='https://www.qownnotes.org'>link to a website</a>.");
script.registerLabel("long-label", "another very long text, another very long text, another very long text, another very long text, another very long text, another very long text, another very long text, another very long text, another very long text, another very long text, another very long text that will wrap");
script.registerLabel("counter-label");
}
/**
* This starts a timer that triggers two seconds
*/
property QtObject timer: Timer {
interval: 1000
repeat: true
running: true
property int count: 0
onTriggered: {
count++;
script.setLabelText("counter-label", "count = " + count);
}
}
}

View file

@ -0,0 +1,95 @@
import QtQml 2.0
/**
* This script creates a menu item and a button that converts the selected Markdown
* text to BBCode in the clipboard
*
* Dependencies:
* http://pandoc.org
* https://github.com/2ion/pandoc-bbcode
*/
QtObject {
property string panbbcodePath;
property string pandocPath;
// register your settings variables so the user can set them in the script settings
property variant settingsVariables: [
{
"identifier": "pandocPath",
"name": "Pandoc path",
"description": "Please select the path to your Pandoc executable:",
"type": "file",
"default": "pandoc",
},
{
"identifier": "panbbcodePath",
"name": "panbbcode path",
"description": "Please select the path to your <code>panbbcode.lua</code> executable:",
"type": "file",
"default": "/opt/scripts/panbbcode.lua",
},
];
/**
* Initializes the custom action
*/
function init() {
script.registerCustomAction("markdownToBBCode", "Markdown to BBCode", "BBCode", "edit-copy", true, true);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "markdownToBBCode") {
return;
}
// get the selected text from the note text edit
var text = script.noteTextEditSelectedText();
// you need pandoc and the BBCode writer from https://github.com/2ion/pandoc-bbcode
// to convert Markdown to BBCode
var params = ["-t", panbbcodePath, "-f", "markdown"];
var result = script.startSynchronousProcess(pandocPath, params, text);
// do some code list cleanup
result = replaceAll(result, "[list=*]", "[list]");
result = replaceAll(result, "[/*]", "");
// convert inline code blocks to italic
// do this 10 times to take care of multiple code blocks in a line
for (var i = 0; i < 10; i++) {
result = result.replace(/^(.+?)\[code\](.+?)\[\/code\]/img, "$1[i]$2[/i]");
}
// convert headlines to bold
result = replaceAll(result, "[h]", "[b]");
result = replaceAll(result, "[/h]", "[/b]");
// convert `em` to `i`
result = replaceAll(result, "[em]", "[i]");
result = replaceAll(result, "[/em]", "[/i]");
// link some users
result = replaceAll(result, "@Georg", "[USER=1]Georg[/USER]");
result = replaceAll(result, "@Sören", "[USER=2]Sören[/USER]");
result = replaceAll(result, "@Robert", "[USER=16]Robert[/USER]");
result = replaceAll(result, "@Stephan", "[USER=8]Stephan[/USER]");
result = replaceAll(result, "@Gunnar", "[USER=14]Gunnar[/USER]");
// put the result into the clipboard
script.setClipboardText(result);
}
function replaceAll(str, find, replace) {
return String(str).replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
function escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
}

View file

@ -0,0 +1,63 @@
import QtQml 2.0
/**
* This script creates a menu item and a button that converts the selected Markdown
* text to Jira code in the clipboard
*
* Dependencies:
* Node.js: https://nodejs.org/en/download/
* https://github.com/kylefarris/J2M
*
* first you have to install jira2md:
* npm install jira2md
*/
QtObject {
property string nodejsExecutablePath;
// register your settings variables so the user can set them in the script settings
property variant settingsVariables: [
{
"identifier": "nodejsExecutablePath",
"name": "Node.js path",
"description": "Please select the path to your Node.js executable:",
"type": "file",
"default": "nodejs",
}
];
/**
* Initializes the custom action
*/
function init() {
script.registerCustomAction("markdownToJira", "Markdown to Jira", "Jira", "edit-copy", true, true);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "markdownToJira") {
return;
}
// get the selected text from the note text edit
var text = script.noteTextEditSelectedText();
// fix unordered lists
text = text.replace(/^-/gm, "*");
text = text.replace(/\t-/gm, "\t*");
// you need NodeJs and jira2md (https://github.com/kylefarris/J2M) to convert Markdown to Jira
var params = ["-e", "console.log(require('jira2md').to_jira(require('fs').readFileSync('/dev/stdin').toString()))"];
var result = script.startSynchronousProcess(nodejsExecutablePath, params, text);
// replace some names
result = String(result).replace(/\@Georg/ig, "[~g.franz]").replace(/\@Jacob/ig, "[~j.ester]").replace(/\@Gandalf/ig, "[~g.sievers]");
// put the result into the clipboard
script.setClipboardText(result);
}
}

View file

@ -0,0 +1,73 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
import com.qownnotes.noteapi 1.0
/**
* This script generates a 10 character alphanumeric id for the current note and also allows to jump to the note by it
*/
Script {
/**
* Initializes the custom actions
*/
function init() {
script.registerCustomAction("generateId", "Generate unique id for current note",
"Unique id", "xml-element-new", false, false, true);
script.registerCustomAction("jumpById", "Jump to note with unique id",
"Jump to id", "edit-find", true, false, false);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
switch (identifier) {
case "generateId":
var uniqueId = uniqueid();
var noteText = script.currentNote().noteText;
// check if we already have generated an id for the note
if (noteText.search("id:\\[") != -1) {
script.log("Note already has a unique id");
return;
}
var noteText = script.currentNote().noteText;
noteText += "\nid:[" + uniqueId + "]";
script.noteTextEditSelectAll();
script.noteTextEditWrite(noteText);
break;
case "jumpById":
var uniqueId = script.inputDialogGetText("Unique id", "Please enter the id of the note");
var noteIds = script.fetchNoteIdsByNoteTextPart("id:[" + uniqueId + "]");
if (noteIds.length == 0) {
return;
}
var note = script.fetchNoteById(noteIds[0]);
script.setCurrentNote(note);
break;
}
}
function uniqueid() {
// always start with a letter
var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65));
do {
// between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
var ascicode=Math.floor((Math.random()*42)+48);
if (ascicode<58 || ascicode>64) {
// exclude all chars between : (58) and @ (64)
idstr+=String.fromCharCode(ascicode);
}
} while (idstr.length<10);
return idstr.toLowerCase();
}
}

View file

@ -0,0 +1,49 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is an example how to add the tag names to the file names of notes
* when a note file gets stored in QOwnNotes
*/
QtObject {
/**
* This function is called when a note gets stored to disk if
* "Allow note file name to be different from headline" is enabled
* in the settings
*
* It allows you to modify the name of the note file
* Return an empty string if the file name of the note should
* not be modified
*
* @param {Note} note - the note object of the stored note
* @return {string} the file name of the note without file extension
*/
function handleNoteTextFileNameHook(note) {
// the current note name is the fallback
var fileName = note.name;
// get a list of note text lines
var noteLines = note.noteText.split("\n");
// set the first line of the note as base for the file name
if (noteLines.length > 0) {
// you maybe also want to exclude some disallowed characters here
fileName = noteLines[0];
}
// get a list of all assigned tag names
var tagNameList = note.tagNames();
// add the tag names to the filename
if (tagNameList.length > 0) {
fileName += " [" + tagNameList.join("] [") + "]";
}
script.log("note file name: " + fileName);
var noteExists = script.noteExistsByFileName(fileName + ".md", note.id);
script.log("note " + (noteExists ? "exists" : "doesn't exist"));
return fileName;
}
}

View file

@ -0,0 +1,112 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This is an example on how to register variables that can be set by the user in
* the script settings.
*/
Script {
// you have to define your registered variables so you can access them later
property string myString;
property bool myBoolean;
property string myText;
property int myInt;
property string myFile;
property string mySelection;
// register your settings variables so the user can set them in the script settings
//
// unfortunately there is no QVariantHash in Qt, we only can use
// QVariantMap (that has no arbitrary ordering) or QVariantList (which at
// least can be ordered arbitrarily)
property variant settingsVariables: [
{
"identifier": "myString",
"name": "I am a line edit",
"description": "Please enter a valid string:",
"type": "string",
"default": "My default value",
},
{
"identifier": "myBoolean",
"name": "I am a checkbox",
"description": "Some description",
"text": "Check this checkbox",
"type": "boolean",
"default": true,
},
{
"identifier": "myText",
"name": "I am a textbox",
"description": "Please enter your text:",
"type": "text",
"default": "This can be a really long text\nwith multiple lines.",
},
{
"identifier": "myInt",
"name": "I am a number selector",
"description": "Please enter a number:",
"type": "integer",
"default": 42,
},
{
"identifier": "myFile",
"name": "I am a file selector",
"description": "Please select the file:",
"type": "file",
"default": "pandoc",
},
{
"identifier": "mySelection",
"name": "I am an item selector",
"description": "Please select an item:",
"type": "selection",
"default": "option2",
"items": {"option1": "Text for option 1", "option2": "Text for option 2", "option3": "Text for option 3"},
}
];
function init() {
script.registerCustomAction("variablesTest", "Variables test", "Var test", "edit-copy");
doSomethingWithYourVariables();
}
function doSomethingWithYourVariables() {
// these variables will be set by QOwnNotes from the settings
// if the user didn't set a variable your default value will be set
script.log(myString);
script.log(myBoolean);
script.log(myText);
script.log(myInt);
script.log(myFile);
script.log(mySelection);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier != "variablesTest") {
return;
}
doSomethingWithYourVariables();
}
/**
* Registers the settings variables again
*
* Use this method if you want to use code to override your variables, like setting
* default values depended on the operating system.
*/
function registerSettingsVariables() {
if (script.platformIsWindows()) {
// override the myFile default value
settingsVariables[3].default = "pandoc.exe"
}
}
}

View file

@ -0,0 +1,81 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script shows current weather statistics in a "scripting label"
*
* The Yahoo weather api is used for fetching the weather data
* https://developer.yahoo.com/weather/
*/
Script {
// you have to define your registered variables so you can access them later
property string city;
property bool useFahrenheit;
// register your settings variables so the user can set them in the script settings
property variant settingsVariables: [
{
"identifier": "city",
"name": "City",
"description": "Please enter your city:",
"type": "string",
"default": "Graz",
},
{
"identifier": "useFahrenheit",
"name": "Unit",
"description": "Use Fahrenheit instead of Celsius",
"type": "boolean",
"default": false,
},
];
function init() {
script.registerLabel("weather stats")
weatherStats();
}
function weatherStats() {
script.log(useFahrenheit);
var unitString = useFahrenheit ? "f" : "c"
var json = script.downloadUrlToString("https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22" + city + "%22)%20and%20u%3D%27" + unitString + "%27&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys");
var weatherInfo = JSON.parse(json);
var temp = weatherInfo.query.results.channel.item.condition.temp
var tempUnit = weatherInfo.query.results.channel.units.temperature;
var conditionText = weatherInfo.query.results.channel.item.condition.text
var weatherCity = weatherInfo.query.results.channel.location.city
var windSpeed = weatherInfo.query.results.channel.wind.speed
var windUnit = weatherInfo.query.results.channel.units.speed;
if (!useFahrenheit) {
tempUnit = "°" + tempUnit;
}
script.setLabelText("weather stats",
"<table align='center' width='90%'>
<tr>
<td align='center'>
Weather in <b>" + weatherCity + "</b>: " + conditionText + " at <b>" + temp + " " + tempUnit + "</b>
(" + windSpeed + " " + windUnit + " wind)
</tb>
</tr>
</table>")
}
/**
* This starts a timer that triggers every 10min
*/
property QtObject timer: Timer {
interval: 600000
repeat: true
running: true
property int count: 0
onTriggered: {
weatherStats();
}
}
}

View file

@ -0,0 +1,44 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
import QtWebSockets 1.1
/**
* This is an example on how to use web sockets as a client
* when sending data to an echo server
*
* Under Ubuntu Linux I installed: qml-module-qtwebsockets
*
* Also see: http://doc.qt.io/qt-5/qml-qtwebsockets-websocket.html
*/
WebSocket {
id: socket
url: "ws://echo.websocket.org"
function init() {
script.registerCustomAction("socketClientTest", "socketClientTest", "socketClientTest", "edit-copy");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier == "socketClientTest") {
socket.active = !socket.active
}
}
onTextMessageReceived: {
script.log("Received message: " + message);
}
onStatusChanged: if (socket.status == WebSocket.Error) {
script.log("Error: " + socket.errorString)
} else if (socket.status == WebSocket.Open) {
socket.sendTextMessage("Hello World")
} else if (socket.status == WebSocket.Closed) {
script.log("Socket closed");
}
active: false
}

View file

@ -0,0 +1,39 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
Script {
/**
* Create a new note with page url, screenshot and page text if a page is
* sent to QOwnNotes from the browser extension
*/
function websocketRawDataHook(requestType, pageUrl, pageTitle, rawData,
screenshotDataUrl) {
// we only want to handle page requests, selection requests are ignored
if (requestType != "page") {
return false;
}
let underline = "";
// add underline characters
for (var i = 0; i < (pageTitle.length - 1); i++) {
underline += "=";
}
// create a new note with page title as headline
const text = pageTitle + "\n" + underline + "\ntest\n";
script.createNote(text);
console.log(rawData);
// add html for page url and the screenshot to the note as markdown
const html = "<a href=\"" + pageUrl + "\">" + pageTitle + "</a><br />" +
"<br /><img src=\"" + screenshotDataUrl + "\" /><br /><br />";
mainWindow.insertHtmlAsMarkdownIntoCurrentNote(html);
// add html to the note as markdown
// we do that separately so it the raw html of the page can't disturbe the rest of our note
mainWindow.insertHtmlAsMarkdownIntoCurrentNote(rawData);
return true;
}
}

View file

@ -0,0 +1,21 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
Script {
/**
* Writes the selected text on the webpage that was sent to QOwnNotes from
* the browser extension into the current note
*/
function websocketRawDataHook(requestType, pageUrl, pageTitle, rawData,
screenshotDataUrl) {
// we only want to handle selection requests, page requests are ignored
if (requestType != "selection") {
return false;
}
// write selected text from the page to the current note
script.noteTextEditWrite(rawData);
return true;
}
}

View file

@ -0,0 +1,50 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
import QtWebSockets 1.1
/**
* This is an example on how to use web sockets as socket server
* This can be for example used to remote control QOwnNotes
*
* You can test the socket server by connecting to it on
* https://www.websocket.org/echo.html?location=ws://127.0.0.1:35345
*
* Under Ubuntu Linux I installed: qml-module-qtwebsockets
*
* Also see: http://doc.qt.io/qt-5/qml-qtwebsockets-websocketserver.html
*/
WebSocketServer {
// if you don't set a port then a random port will be chosen
port: 35345
id: server
listen: true
function init() {
script.registerCustomAction("socketServerTest", "Print socket server url", "socketServerTest", "edit-copy");
script.log("Socket server url: " + server.url);
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
if (identifier == "socketServerTest") {
script.log("Socket server url: " + server.url);
}
}
onClientConnected: {
webSocket.onTextMessageReceived.connect(function(message) {
script.log(qsTr("Server received message: %1").arg(message));
webSocket.sendTextMessage(qsTr("Hello Client!"));
});
}
onErrorStringChanged: {
script.log(qsTr("Server error: %1").arg(errorString));
}
}

View file

@ -0,0 +1,48 @@
import QtQml 2.0
import QOwnNotesTypes 1.0
/**
* This script is an example for creating custom actions, that can be invoked
* via menu entries and buttons
*/
QtObject {
/**
* Initializes the custom actions
*/
function init() {
// create a menu entry "Create Zettelkasten note" with a button and a freedesktop theme icon
script.registerCustomAction("createZettelkastenNote", "Create Zettelkasten note", "Zettelkasten note", "task-new");
}
/**
* This function is invoked when a custom action is triggered
* in the menu or via button
*
* @param identifier string the identifier defined in registerCustomAction
*/
function customActionInvoked(identifier) {
script.log("customActionInvoked - " + identifier);
switch (identifier) {
// create a new note with a custom content
case "createZettelkastenNote":
var m = new Date();
// create the headline
var text = m.getFullYear() + ("0" + (m.getMonth()+1)).slice(-2) + ("0" + m.getDate()).slice(-2) + ("0" + m.getHours()).slice(-2) + ("0" + m.getMinutes()).slice(-2) + ("0" + m.getSeconds()).slice(-2) + " Title\n";
var underline = "";
// add the underline for the headline
for (var i = 0; i < (text.length - 1); i++) {
underline += "-";
}
// add some text to our Zettelkasten note
text += underline + "\n\n Note\n\n\n# keywords\n\n### Cf\n\n---\n\n### References\n\n";
// create a new note
script.createNote(text);
break;
}
}
}