Guest User

Untitled

a guest
Aug 28th, 2025
22
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 6.22 KB | Source Code | 0 0
  1. import QtQml 2.0
  2. import QOwnNotesTypes 1.0
  3.  
  4. /**
  5.  * This script handles tagging in a note for tags in the note text like:
  6.  * @tag1 @tag2 @tag3
  7.  * @tag_one would tag the note with "tag one" tag.
  8.  */
  9.  
  10. Script {
  11.     property bool putToBeginning
  12.     property variant settingsVariables: [
  13.         {
  14.             "identifier": "tagMarker",
  15.             "name": "Tag word marker",
  16.             "description": "A word that starts with this characters is recognized as tag",
  17.             "type": "string",
  18.             "default": "@"
  19.         },
  20.         {
  21.             "identifier": "putToBeginning",
  22.             "name": "Put tags to beginning of note rather than to end",
  23.             "description": "If enabled tags, added by UI, will be put to the first line of note or right after top headline",
  24.             "type": "boolean",
  25.             "default": "false"
  26.         },
  27.     ]
  28.     property string tagMarker
  29.     property variant noteTagCache: ({})
  30.  
  31.     /**
  32.      * Hook to feed the autocompletion with tags if the current word starts with the tag marker
  33.      */
  34.     function autocompletionHook() {
  35.         // get the current word plus non-word-characters before the word to also get the tag marker
  36.         var word = script.noteTextEditCurrentWord(true);
  37.  
  38.         if (!word.startsWith(tagMarker)) {
  39.             return [];
  40.         }
  41.  
  42.         // cut the tag marker off of the string and do a substring search for tags
  43.         var tags = script.searchTagsByName(word.substr(tagMarker.length));
  44.  
  45.         // convert tag names with spaces to in-text tags with "_", "tag one" to @tag_one
  46.         for (var i = 0; i < tags.length; i++) {
  47.             tags[i] = tags[i].replace(/ /g, "_");
  48.         }
  49.  
  50.         return tags;
  51.     }
  52.  
  53.     // Escapes a string for regular expressions
  54.     function escapeRegExp(str) {
  55.         return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
  56.     }
  57.  
  58.     /**
  59.      * Handles note tagging for a note
  60.      *
  61.      * This function is called when tags are added to, removed from or renamed in
  62.      * a note or the tags of a note should be listed
  63.      *
  64.      * @param note
  65.      * @param action can be "add", "remove", "rename" or "list"
  66.      * @param tagName tag name to be added, removed or renamed
  67.      * @param newTagName tag name to be renamed to if action = "rename"
  68.      * @return string or string-list (if action = "list")
  69.      */
  70.     function noteTaggingHook(note, action, tagName, newTagName) {
  71.         var noteText = note.noteText;
  72.         var tagRegExp = RegExp("\\B%1(?=($|\\s|\\b)) ?".arg(escapeRegExp(tagMarker + tagName).replace(/ /g, "_")));
  73.  
  74.         switch (action) {
  75.         // adds the tag "tagName" to the note
  76.         // the new note text has to be returned so that the note can be updated
  77.         // returning an empty string indicates that nothing has to be changed
  78.         case "add":
  79.             // check if tag already exists
  80.             if (noteText.search(tagRegExp) > 0) {
  81.                 return "";
  82.             }
  83.  
  84.             const tag = tagMarker + tagName.replace(/ /g, "_");
  85.  
  86.             // add the tag to the beginning or to the end of the note
  87.             if (putToBeginning) {
  88.  
  89.                 // make an array of up to 3 first lines and other text as last item
  90.                 var textLines = [];
  91.                 var lineCount = 0;
  92.                 var lineStart = 0;
  93.                 var lineEnd = 0;
  94.  
  95.                 for (; lineCount != 3; lineCount++) {
  96.                     lineEnd = noteText.indexOf("\n", lineStart + 1);
  97.  
  98.                     if (lineEnd == -1)
  99.                         continue;
  100.  
  101.                     textLines.push(noteText.substring(lineStart, lineEnd));
  102.                     lineStart = lineEnd;
  103.                 }
  104.  
  105.                 textLines.push(noteText.substring(lineStart));
  106.  
  107.                 // if line after headline is a line for tags add tag there,
  108.                 // or make a new line for tags after headline
  109.                 function appendTag(text, tag, prepend) {
  110.                     if (text.substring(0, tagMarker.length) == tagMarker || text.substring(1, tagMarker.length + 1) == tagMarker)
  111.                         return text + " " + tag;
  112.                     else
  113.                         return prepend + tag + "\n" + text;
  114.                 }
  115.  
  116.                 // use different tag line number depending on a headline type
  117.                 if (textLines[0].substring(0, 1) == "#")
  118.                     textLines[1] = appendTag(textLines[1], tag, "\n");
  119.                 else if (textLines[1].search(/=+/) != -1)
  120.                     textLines[2] = appendTag(textLines[2], tag, "\n");
  121.                 else
  122.                     textLines[0] = appendTag(textLines[0], tag, "");
  123.  
  124.                 noteText = textLines.join("");
  125.             } else
  126.                 noteText += "\n" + tag;
  127.  
  128.             return noteText;
  129.  
  130.         // removes the tag "tagName" from the note
  131.         // the new note text has to be returned so that the note can be updated
  132.         // returning an empty string indicates that nothing has to be changed
  133.         case "remove":
  134.             return noteText.replace(tagRegExp, "");
  135.  
  136.         // renames the tag "tagName" in the note to "newTagName"
  137.         // the new note text has to be returned so that the note can be updated
  138.         // returning an empty string indicates that nothing has to be changed
  139.         case "rename":
  140.             return noteText.replace(tagRegExp, tagMarker + newTagName.replace(/ /g, "_"));
  141.  
  142.         // returns a list of all tag names of the note
  143.         case "list":
  144.         var noteTextAndTags = noteTagCache[note.id]
  145.             if (noteTextAndTags != undefined && noteTextAndTags[0] == noteText)
  146.                 return noteTextAndTags[1]
  147.  
  148.             var re = new RegExp("\\B%1([^\\s,;%1]+)".arg(escapeRegExp(tagMarker)), "gi"), result, tagNameList = [];
  149.  
  150.             while ((result = re.exec(noteText)) !== null) {
  151.                 tagName = result[1].replace(/_/g, " ");
  152.  
  153.                 // add the tag if it wasn't in the list
  154.                 if (tagNameList.indexOf(tagName) == -1) {
  155.                     tagNameList.push(tagName);
  156.                 }
  157.             }
  158.             noteTagCache[note.id] = [noteText, tagNameList]
  159.             return tagNameList;
  160.         }
  161.  
  162.         return "";
  163.     }
  164. }
Advertisement
Add Comment
Please, Sign In to add comment