macnotesapp icon indicating copy to clipboard operation
macnotesapp copied to clipboard

first line should be style "title" (& markdown is ignored)

Open dmd opened this issue 2 years ago • 6 comments

If I add a note using notes -e:

  • Actual behavior
    • the first line is styled as Helvetica, Regular, 12
    • subsequent lines are styled as System Font (Default), Regular, 13
  • Expected behavior
    • The first line is styled using Notes' "Title" style, which is System Font (Default), Bold, 20

If I add a note using notes -e -m:

  • Actual behavior
    • the first line is styled as Helvetica, Regular, 12
    • markdown is ignored on the first line; i.e., if you type # this is the first line the # shows up in Notes
    • subsequent lines are styled according to markdown rules
  • Expected behavior
    • EITHER the first line is styled using markdown rules OR using Notes' "Title" style - I'm not sure which is better. I would tend to expect the former but could see arguments for the latter since you're using that as the lookup key?

dmd avatar Nov 06 '22 18:11 dmd

Thanks -- I'll take a look. It's not possible to stylize the title via the Notes AppleScript interface so this is tricky to implement.

RhetTbull avatar Nov 06 '22 19:11 RhetTbull

I've been able to replicate this and did some testing via adding notes a number of different ways. If the name (title) of the note is blank, Notes sets the title to "Notes" which isn't helpful. Unfortunately, as annoying as this is, it may be something I can't fix as long as I'm stuck using the AppleScript interface to add notes. If I could find a private API that Apple uses and call that, I might be able to set the style for the title but at the moment, anything I try results in formatting being stripped from the title when added via AppleScript.

The first entry is the one created by Notes.app directly. The others were all created by macnotesapp.

[
    {
        "account": "iCloud",
        "id": "x-coredata://BA47E88C-3599-48BE-88DD-5CBC118E9CE6/ICNote/p1483",
        "name": "This is a brand new note",
        "body": "<div><h1>This is a brand new note</h1></div>\n<div><br></div>\n<div>This is body text.</div>\n",
        "creation_date": "2022-11-06T20:27:06",
        "modification_date": "2022-11-06T20:27:15",
        "password_protected": false,
        "folder": "Notes"
    },
    {
        "account": "iCloud",
        "id": "x-coredata://BA47E88C-3599-48BE-88DD-5CBC118E9CE6/ICNote/p1486",
        "name": "This is a brand new note added via `notes add -e -m`",
        "body": "<div><font face=\"Helvetica\">This is a brand new note added via `notes add -e -m`</font></div>\n<div><b><span style=\"font-size: 
24px\">This is markdown header 1</span></b></div>\n<div>This is some text</div>\n<div><b><span style=\"font-size: 18px\">This is a markdown header 
2</span></b></div>\n<div>This is more text</div>\n",
        "creation_date": "2022-11-06T20:32:13",
        "modification_date": "2022-11-06T20:32:13",
        "password_protected": false,
        "folder": "Notes"
    },
    {
        "account": "iCloud",
        "id": "x-coredata://BA47E88C-3599-48BE-88DD-5CBC118E9CE6/ICNote/p1487",
        "name": "This is a brand new note added via `notes add -e --html`",
        "body": "<div><font face=\"Helvetica\">This is a brand new note added via `notes add -e --html`</font></div>\n<div><b><span style=\"font-size: 
24px\">This is a heading</span></b></div>\n<div>This is a paragraph</div>\n<div>This is another paragraph</div>\n<div>This is a <b>bold</b> 
paragraph</div>\n",
        "creation_date": "2022-11-06T20:33:06",
        "modification_date": "2022-11-06T20:33:06",
        "password_protected": false,
        "folder": "Notes"
    },
    {
        "account": "iCloud",
        "id": "x-coredata://BA47E88C-3599-48BE-88DD-5CBC118E9CE6/ICNote/p1492",
        "name": "This is a brand new note added via `notes add -e --html` using same\u2026",
        "body": "<div><font face=\"Helvetica\">This is a brand new note added via `notes add -e --html` using same markup as 
Notes.app</font></div>\n<div><b><span style=\"font-size: 24px\">This is a brand new note added via `notes add -e --html` using same markup as 
Notes.app</span></b></div>\n<div>\\n</div>\n<div><br></div>\n<div>\\n</div>\n<div>This is body text.</div>\n<div>\\n&quot,</div>\n",
        "creation_date": "2022-11-06T20:44:57",
        "modification_date": "2022-11-06T20:44:57",
        "password_protected": false,
        "folder": "Notes"
    },
    {
        "account": "iCloud",
        "id": "x-coredata://BA47E88C-3599-48BE-88DD-5CBC118E9CE6/ICNote/p1488",
        "name": "<h1>This is a brand new note added via `notes add -e --html` but with\u2026",
        "body": "<div><font face=\"Helvetica\">&lth1&gtThis is a brand new note added via `notes add -e --html` but with header tags in the first 
line&lt/h1&gt</font></div>\n<div>This is some text</div>\n",
        "creation_date": "2022-11-06T20:34:15",
        "modification_date": "2022-11-06T20:34:15",
        "password_protected": false,
        "folder": "Notes"
    },
    {
        "account": "iCloud",
        "id": "x-coredata://BA47E88C-3599-48BE-88DD-5CBC118E9CE6/ICNote/p1485",
        "name": "This is a brand new note added via `notes add -e`",
        "body": "<div><font face=\"Helvetica\">This is a brand new note added via `notes add -e`</font></div>\n<div><br></div>\n<div>This is body 
text</div>\n",
        "creation_date": "2022-11-06T20:31:14",
        "modification_date": "2022-11-06T20:31:14",
        "password_protected": false,
        "folder": "Notes"
    }
]

RhetTbull avatar Nov 07 '22 04:11 RhetTbull

I'd say submit this to https://feedbackassistant.apple.com/ but I have bugs of this caliber on there that are 8 years old that have never been looked at. I don't think anyone at Apple even knows it exists.

dmd avatar Nov 07 '22 12:11 dmd

I'm in the midst of a complete rewrite of this project to use ScriptingBridge (#16) and I've figured out how to apply style to the title of the note. I've not quite figured out how to replicate the default style Notes.app but think I can eventually do this. The new rewrite will be much faster and will enable a fully-interactive UI in the Terminal.

RhetTbull avatar Dec 27 '22 14:12 RhetTbull

How's that going? :) I ran into this project again today - having completely forgotten about it - because a thing I'd really like is the ability to prepend some text to a specific note ("log") while retaining the note's title.

I ended up with

#!/bin/bash

input_text=$(cat|perl -pe 's/\n/<br>/g')

current_date=$(date +"%Y-%m-%d %H:%M:%S")

combined_text="<div><h3>$current_date</h3></div><div>$input_text</div>"

jxa_script=$(cat <<EOF
function run(inputText) {
    var Notes = Application("Notes");
    var logNote = Notes.notes.whose({ name: "log" })[0];
    var currentContent = logNote.body();

    var lines = currentContent.split(/<br>/);

    if (lines[0].includes("log")) {
        lines.shift();
    }

    var newContent = "<div><h1>log</h1></div><br>" + inputText + "<br>" + lines.join("<br>");
    logNote.body = newContent;
}

run("$combined_text");
EOF
)

# Execute the JXA script with the combined text
osascript -l JavaScript -e "$jxa_script"

Which works but I'm not especially happy with it.

And then I remembered your project, but your project doesn't allow editing existing notes.

dmd avatar Jul 13 '24 14:07 dmd

I've been busy with other projects. All I use this project for is adding new notes from Terminal. Unfortunately Notes.app doesn't provide any easy way to edit and preserve style. The current version of this tool creates the title in System Bold 24 which is what Notes uses for "H1" HTML tag and that's the best I can do as the API doesn't allow specifying fonts.

The majority of the code was rewritten to use ScriptingBridge so it is more performant (with exception of accessing folders which still require AppleScript).

I've thought about an editing feature but I'm not able to preserve any formatting which might come as a shock and result in data loss. For example, if you had a note that had tables, to-do lists, etc. and you rewrote that note with this package, all formatting would be lost including the tables and to-do list. I don't know of a way around this.

If you just want to prepend you could write yourself a python function to grab the old body of the note, prepend the new value then set the body to the new value. For example, this should be a good start:

"""Prepend text to the first selected note in Notes.app.

WARNING: this may result in loss of all formatting.
"""

import sys

import macnotesapp


def prepend(note: macnotesapp.Note, text: str):
    """Prepend text to the first selected note in Notes.app.

    Args:
        note: the note to prepend text to
        text: the text to prepend
    """

    # Note.body returns the HTML for the entire note including title
    # Note.plaintext returns the plain text for the entire note including title
    # This is a limitation of the Notes.app AppleScript API
    body = note.body
    name = body.split("\n")[0]
    body = f"{name}\n<div>{text}</div>\n" + "\n".join(body.split("\n")[1:])
    note.body = body


def main():
    """Prepend text to the first selected note in Notes.app.

    Usage:
        prepend.py TEXT
    """

    if len(sys.argv) < 2:
        print(__doc__)
        sys.exit(1)

    sel = macnotesapp.NotesApp().selection
    if not sel:
        print("No note selected")
        sys.exit(1)
    note = sel[0]
    prepend(note, sys.argv[1])


if __name__ == "__main__":
    main()

I'd love to offer more control over the content but Apple limits note editing / creation to plaintext or HTML and does not offer a native API for creating or editing notes except for the very limited AppleScript API.

RhetTbull avatar Jul 13 '24 18:07 RhetTbull