Giter VIP home page Giter VIP logo

Comments (9)

pbek avatar pbek commented on September 18, 2024

Yes, # is used for headlines in markdown and always will be sub-optimal for tags. If you see a way to take care of that special case in the script feel free to make a pull request.

from scripts.

pbek avatar pbek commented on September 18, 2024

But you also might get your tags interpreted as headlines in QOwnNotes itself.

from scripts.

Maboroshy avatar Maboroshy commented on September 18, 2024

The script would only parse #tag, no space, as tags. While for the headlines # Headline format, with space, is much more common. Some markdown implementations don't even parse #Headline as a headline. So one solution is to keep all your headlines in # Headline format.

Another solution is to parse a note for tags only in specific place. That is what "Epsilon Notes compatible tags (YAML tags)" script does. It keeps the tags only in YAML front-matter, before the note text.

I don't think there are much more ways to resolve your issue.

from scripts.

Jnath-alf avatar Jnath-alf commented on September 18, 2024

Thank you for your respective answers.

I hope it’s not too confusing, because English isn’t my native language. I use the automatic 😳 translator.

I do not have the skills to write the script, it was a remark of humble user. If I knew how to program I would gladly have contributed.

All my titles are in # Headline format (with space). The applications I use do not interpret #Headline (without space) as a title. #Headline would be the "Headline" tag.

What "in-note-text-tagging" produces, using # as a tag word marker, is:

  • for an h2 title, ## Headline, a tag 🏷️#
  • for an h3 title, ### Headline, a tag 🏷️##

And so on until h6 => 🏷️#####.

In fact, in an series of hash keys, the first hash is interpreted as a tag word marker, and all the other hash then form a tag.

A character string which would have the form ###QOwnNotes would give 🏷️##QOwnNotes.

A hash after another hash ## should cancel the tag function.

Or that to produce a tag, all characters are possible after # except another hash character.

That said, in practice, this is a minor annoyance. There are at most five unnecessary tags in my tag list. That doesn't stop me from using QOwnNotes. It’s great software, clear and elegant (I discovered it very recently)

from scripts.

Maboroshy avatar Maboroshy commented on September 18, 2024

That's interesting. What OS do you use and what's the language of your notes? Could you paste the text of some test note that creates such tags.

from scripts.

Jnath-alf avatar Jnath-alf commented on September 18, 2024

OS: Windows 10
Langage: French

Test note:

Note 2020-02-03T17.56.47
========================

Sed ac ornare orci. Vivamus ullamcorper pellentesque est. Pellentesque porttitor nunc vel nisi bibendum, vel fermentum magna fermentum. Donec.

## Cras a mi

Sed pretium bibendum est, sed mattis libero bibendum quis. Nulla vel nulla bibendum, luctus odio sit amet, aliquet lacus. Maecenas consequat massa sed venenatis facilisis. Donec vel sapien lorem. Nullam tellus justo, ullamcorper ut quam sit amet, tincidunt finibus tortor.

## Morbi ut mauris aliquam, volutpat

Duis sagittis sapien in dolor ultrices tincidunt. Nunc elit turpis, auctor non egestas ut, dignissim a massa. Vestibulum faucibus metus quis sodales cursus. Nunc molestie ultrices lorem a volutpat. Pellentesque orci mi, feugiat nec leo et, tristique tempus ex.

#elementum

This note creates two tags:

  • 🏷️#
  • 🏷️elementum

from scripts.

Maboroshy avatar Maboroshy commented on September 18, 2024

It's a bug with the regexp. I haven't yet found an easy way to resolve it without losing declared ability to use any string as a tag marker. I'll look for a hard way.

from scripts.

Maboroshy avatar Maboroshy commented on September 18, 2024
Try this one:
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
* @tag_one would tag the note with "tag one" tag.
*/

Script {
    property string tagMarker
    property bool putToBeginning
    property string tagHighlightColor

    property variant settingsVariables: [
        {
            "identifier": "tagMarker",
            "name": "Tag word marker",
            "description": "A word that starts with this characters is recognized as tag",
            "type": "string",
            "default": "@",
        },
        {
            "identifier": "putToBeginning",
            "name": "Put tags to beginning of note rather than to end",
            "description": "If enabled tags, added by UI, will be put to the first line of note or right after top headline",
            "type": "boolean",
            "default": "false",
        },
        {
            "identifier": "tagHighlightColor",
            "name": "The color for tag highlighting in note preview",
            "description": "Put a <a href=\"https://www.w3.org/TR/SVG/types.html#ColorKeywords\">color name</a> or a <a href=\"http://doc.qt.io/qt-5/qcolor.html#setNamedColor\">supported</a> color code here. Leave empty to disable tag highlighting in preview.",
            "type": "string",
            "default": "purple",
        },
    ]
    
    /**
    * 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%1(?=($|\\s|\\b)) ?".arg(escapeRegExp(tagMarker + tagName).replace(/ /g, "_")));

        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 "";
                }
                
                const tag = tagMarker + tagName.replace(/ /g, "_");
                
                // add the tag to the beginning or to the end of the note
                if (putToBeginning) {
                    
                    // make an array of up to 3 first lines and other text as last item
                    var textLines = [];
                    for (var lineCount = 0, lineStart = 0, lineEnd = 0; lineCount != 3; lineCount++) {
                        lineEnd = noteText.indexOf("\n", lineStart + 1);

                        if (lineEnd == -1)
                            continue;

                        textLines.push(noteText.substring(lineStart, lineEnd));
                        lineStart = lineEnd;
                    }

                    textLines.push(noteText.substring(lineStart));
                    
                    // if line after headline is a line for tags add tag there, 
                    // or make a new line for tags after headline
                    function appendTag(text, tag, prepend) {
                        if (text.substring(0, tagMarker.length) == tagMarker ||
                            text.substring(1, tagMarker.length + 1) == tagMarker)
                            return text + " " + tag;
                        else
                            return prepend + tag + "\n" + text;
                    }
                    
                    // use different tag line number depending on a headline type
                    if (textLines[0].substring(0, 1) == "#")
                        textLines[1] = appendTag(textLines[1], tag, "\n");
                    else if (textLines[1].search(/=+/) != -1)
                        textLines[2] = appendTag(textLines[2], tag, "\n");
                    else
                        textLines[0] = appendTag(textLines[0], tag, "");
                        
                    noteText = textLines.join("");
                }

                else 
                    noteText += "\n" + tag;
                
                return noteText;

            // 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":
                return noteText.replace(tagRegExp, "");

            // 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":
                return noteText.replace(tagRegExp, tagMarker + newTagName.replace(/ /g, "_"));

            // returns a list of all tag names of the note
            case "list":
                var tag_re = new RegExp("\\B%1([^\\s,;]+)".arg(escapeRegExp(tagMarker)), "gi"),
                    result, tagNameList = [];
                    
                // A hack to enable using '#' as a tag marker. 
                // '###' will be invalidated and won't become '##' tag.     
                var invalid_tag_re = RegExp("^[%1]+$".arg(escapeRegExp(tagMarker)))
                                    
                while ((result = tag_re.exec(noteText)) !== null) {                   
                    tagName = result[1].replace(/_/g, " ");
                    
                    if (tagName.search(invalid_tag_re) != -1)
                        continue
                    
                    // add the tag if it wasn't in the list
                    if (tagNameList.indexOf(tagName) == -1 && tagName != tagMarker) {
                        tagNameList.push(tagName);
                    }
                }
                return tagNameList;
        }
    
        return "";
    }
    
    // Removes tag marker in note preview and highlights tag name with set color
    function noteToMarkdownHtmlHook(note, html) {
        if (tagHighlightColor == "")
            return;
        
        var re = new RegExp("\\B%1([^\\s,;]+)".arg(escapeRegExp(tagMarker)), "gi"), result;

        while ((result = re.exec(html)) !== null)
            html = html.replace(result[0], '<b><font color="%1">%2</font></b>'.arg(tagHighlightColor).arg(result[1]));
            
        return html;
    }
    
    // Escapes a string for regular expressions
    function escapeRegExp(str) {
        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    }

    /**
    * Hook to feed the autocompletion with tags if the current word starts with the tag marker
    */
    function autocompletionHook() {
        // get the current word plus non-word-characters before the word to also get the tag marker
        var word = script.noteTextEditCurrentWord(true);

        if (!word.startsWith(tagMarker)) {
            return [];
        }
        
        // cut the tag marker off of the string and do a substring search for tags
        var tags = script.searchTagsByName(word.substr(tagMarker.length));
        
        // convert tag names with spaces to in-text tags with "_", "tag one" to @tag_one 
        for (var i = 0; i < tags.length; i++) {
            tags[i] = tags[i].replace(/ /g, "_");
        }
        
        return tags;
    }
}

from scripts.

Jnath-alf avatar Jnath-alf commented on September 18, 2024

I tested the script today, and it works.

  • Titles in ## headline format (with space) do not generate any interaction with #tags.
  • Titles in ##headline format (without space) are interpreted as tags, in this case #headline.

For my use this is not a problem since I always separate the hash signs and the title of a space.
So I can now use the tag word marker #.

Thank you so much.

from scripts.

Related Issues (20)

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.