diff --git a/new-note-namer/README.md b/new-note-namer/README.md new file mode 100755 index 0000000..8843a7e --- /dev/null +++ b/new-note-namer/README.md @@ -0,0 +1,52 @@ +# New note namer + +Sets the note title and file name at creation time, with optional dialogs for each field. +Especially useful when the _Allow note file name to be different from note title_ option is enabled in QOwnNotes. + +## Settings + +| Setting | Description | +| ------------------------------------------ | ----------------------------------------------------------------------------------- | +| **Show a dialog to define the note title** | If checked, a dialog asks for a custom title (pre-filled with the search term). | +| **Show a dialog to define the file name** | If checked, a dialog asks for a custom file name (pre-filled with the search term). | +| **Heading style** | Format applied to the title: ATX (`# Title`), Setext (`Title / =====`), or Custom. | +| **Custom heading – opening tag** | Text inserted before the title (Custom style only). | +| **Custom heading – closing tag** | Text inserted after the title (Custom style only). | + +The two dialog options are independent: each defaults to the search term, regardless of the other. + +## Behaviour + +| Source | Dialog: note title | Dialog: file name | Title | File name | +| ---------------- | ------------------ | ----------------- | ---------------------------- | ------------------------------------------- | +| Search "foo" | ☐ | ☐ | `# foo` | `foo` | +| Search "foo" | ☑ | ☐ | dialog pre-filled with `foo` | `foo` (search term, independent from title) | +| Search "foo" | ☐ | ☑ | `# foo` | dialog pre-filled with `foo` | +| Search "foo" | ☑ | ☑ | dialog pre-filled with `foo` | dialog pre-filled with `foo` | +| Menu (no search) | — | ☐ | dialog (no pre-fill) | = entered title | +| Menu (no search) | — | ☑ | dialog (no pre-fill) | dialog pre-filled with entered title | + +> **Note:** the `n:` search prefix (name-only filter) is automatically stripped from the note name. + +## Tips + +- Leave both dialogs unchecked for a fully automatic workflow: create a note directly from the search bar with one keypress. +- Check only _file name_ to keep the search term as the title but write a longer or different file name. +- Check only _title_ to write a custom heading while keeping the file name equal to the search term. +- The heading style applies in all cases, including when no dialog is shown. +- All settings require a **script engine reload** to take effect after being changed. + +## Upgrading from v0.0.2 + +v0.0.2 had a single boolean setting **Underline heading** that chose between ATX (`# Title`) and Setext (`Title / =====`). +This was replaced by the **Heading style** selection in v0.0.3. + +Your stored preference is migrated automatically: + +| v0.0.2 setting | Effective heading style after upgrade | +| ------------------- | -------------------------------------------------------------- | +| Unchecked (default) | ATX (`# Title`) — no change | +| Checked | Setext (`Title / =====`) — preserved via the deprecated toggle | + +The deprecated **Underline heading (deprecated)** entry remains visible in the script settings so QOwnNotes can still read your stored value. +Once you have set **Heading style** to your preferred option you can safely uncheck the deprecated toggle. diff --git a/new-note-namer/info.json b/new-note-namer/info.json index ad33d4c..5e74d1c 100644 --- a/new-note-namer/info.json +++ b/new-note-namer/info.json @@ -2,9 +2,9 @@ "name": "New note namer", "identifier": "new-note-namer", "script": "new-note-namer.qml", - "authors": ["@diegovskytl", "@Mystechry"], + "authors": ["@diegovskytl", "@Mystechry", "@luginf"], "platforms": ["linux", "macos", "windows"], - "version": "0.0.2", + "version": "0.0.4", "minAppVersion": "17.06.2", - "description": "Enables a dialog window (or two) so the user can choose the note title and file name at the moment of creation.
Specially useful when the 'Allow note file name to be different to note title. \n No more cumbersome renaming :)" + "description": "Enables a dialog window (or two, or even none) so the user can choose the note title and file name at the moment of creation, or simply use the search term for the filename and title of the note with custom formattings.

Specially useful when the 'Allow note file name to be different to note title. \n No more cumbersome renaming :)" } diff --git a/new-note-namer/new-note-namer.qml b/new-note-namer/new-note-namer.qml index 960fcac..aa0005c 100644 --- a/new-note-namer/new-note-namer.qml +++ b/new-note-namer/new-note-namer.qml @@ -7,63 +7,126 @@ import QOwnNotesTypes 1.0 Avoids cumbersome renaming and title editing. */ QtObject { + property bool extraDialogForTitle property bool extraDialogForFileName + property string headingStyle + property string _searchTerm: "" + property string customHeadingOpen + property string customHeadingClose + property bool underlineHeading // deprecated — kept so existing stored settings still load property variant settingsVariables: [ + { + 'identifier': 'extraDialogForTitle', + 'name': 'Show a dialog to define the note title', + 'description': 'If checked, ask for a custom note title.', + 'type': 'boolean', + 'default': 'false' + }, { 'identifier': 'extraDialogForFileName', - 'name': 'Extra dialog for note title', - 'description': 'Show an additional dialog window so user can write a file name different to the note title.', + 'name': 'Show a dialog to define the file name', + 'description': 'If checked, ask for a custom file name.', 'type': 'boolean', 'default': 'false' }, + { + 'identifier': 'headingStyle', + 'name': 'Heading style', + 'description': 'Title format for new notes.', + 'type': 'selection', + 'default': '0', + 'items': { + '0': 'ATX Markdown heading (# Title)', + '1': 'Setext Markdown heading (Title / =====)', + '2': 'Custom heading (opening and closing tags)' + } + }, + { + 'identifier': 'customHeadingOpen', + 'name': 'Custom heading – opening tag', + 'description': 'Text inserted before the note name (only used when heading style is "Custom").', + 'type': 'string', + 'default': '' + }, + { + 'identifier': 'customHeadingClose', + 'name': 'Custom heading – closing tag', + 'description': 'Text inserted after the note name (only used when heading style is "Custom").', + 'type': 'string', + 'default': '' + }, { 'identifier': 'underlineHeading', - 'name': 'Underline heading', - 'description': 'Highlight the first line by underlining it with =, if not checked, use a preceding # instead.', + 'name': 'Underline heading (deprecated)', + 'description': 'Deprecated: use "Heading style" above instead. Kept so that users upgrading from v0.0.2 automatically keep their Setext-heading preference without needing to change settings.', 'type': 'boolean', 'default': 'false' }, ] - property bool underlineHeading - function handleNewNoteHeadlineHook(note) { - var newName = newNamer("New note", "New note title", "Title"); - script.log(note.fileCreated); - script.log(note.fileLastModified); - - if (underlineHeading) { - return newName + "\n" + "=".repeat(newName.length); + function handleNewNoteHeadlineHook(headline) { + // 'headline' is a plain string (the search term or default text), not a Note object. + // Strip QOwnNotes search filter prefixes (e.g. "n:" for name-only search). + _searchTerm = headline.replace(/^n:/i, ""); + var name; + if (extraDialogForTitle || _searchTerm === "") { + // Show dialog: pre-fill with the search term if available, otherwise a placeholder. + name = newNamer("New note", "New note title", _searchTerm !== "" ? _searchTerm : "Title"); } else { - return "# " + newName; + // If already provided (search term or QOwnNotes own dialog), use it directly. + name = _searchTerm; } + return buildHeadline(name); } - function handleNoteTextFileNameHook(note) { - script.log("note name: " + note.name); - script.log("file name: " + note.fileName); - script.log(note.fileCreated); - script.log(note.fileLastModified); - - var noteLines = note.noteText.split("\n"); - var firstLine = noteLines[0]; - var noteTitle = firstLine.slice(2); // Remove the preceding "# " - if (underlineHeading) { - // Underlined headings use the entire first line - noteTitle = firstLine; + // Migration helper: underlineHeading=true from v0.0.2 maps to Setext ("1"). + // headingStyle "1" or "2" set explicitly always wins. + function effectiveHeadingStyle() { + if (headingStyle === "0" && underlineHeading) { + return "1"; } - - script.log("note title: " + noteTitle); - - // right when a note is created, the fileCreated property value is 'Invald Date' - // this blocks the hook to further change the note file name if the note title is changed + return headingStyle; + } + function buildHeadline(name) { + var style = effectiveHeadingStyle(); + if (style === "2") { + return customHeadingOpen + name + customHeadingClose; + } + if (style === "1") { + return name + "\n" + "=".repeat(name.length); + } + return "# " + name; // "0" (ATX) or unset + } + function extractTitle(noteText) { + var firstLine = (noteText || "").split("\n")[0]; + var style = effectiveHeadingStyle(); + if (style === "2") { + var t = firstLine.slice(customHeadingOpen.length); + var closeLen = customHeadingClose.length; + if (closeLen > 0 && t.slice(-closeLen) === customHeadingClose) { + t = t.slice(0, t.length - closeLen); + } + return t; + } + if (style === "1") { + return firstLine; // setext: first line is the bare title + } + return firstLine.slice(2); // ATX: remove "# " + } + function handleNoteTextFileNameHook(note) { + // right when a note is created, the fileCreated property value is 'Invalid Date' + // this blocks the hook from further changing the note file name if the note title is changed if (note.fileCreated != "Invalid Date") { return ""; } + // Default file name: search term if available, otherwise derived from the title. + var defaultName = _searchTerm !== "" ? _searchTerm : extractTitle(note.noteText); + if (extraDialogForFileName) { - return newNamer("New note", "New file name", "File name"); - } else { - return noteTitle; + return newNamer("New note", "New file name", defaultName); } + + return defaultName; } function init() { script.log("New-note-namer active");