From 0009bc4d35e65ff7bca5205ff44de2ffa5137d7c Mon Sep 17 00:00:00 2001 From: luginf Date: Sat, 23 May 2026 11:34:03 +0200 Subject: [PATCH 1/9] custom syntax new-note-namer --- new-note-namer/info.json | 6 +- new-note-namer/new-note-namer.qml | 110 ++++++++++++++++++++++-------- 2 files changed, 85 insertions(+), 31 deletions(-) diff --git a/new-note-namer/info.json b/new-note-namer/info.json index ad33d4c..81411f8 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 name 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..bbde948 100644 --- a/new-note-namer/new-note-namer.qml +++ b/new-note-namer/new-note-namer.qml @@ -8,6 +8,12 @@ import QOwnNotesTypes 1.0 */ QtObject { property bool extraDialogForFileName + property bool underlineHeading + property bool useSearchTermAsName + property string searchTermHeadingStyle + property string customHeadingOpen + property string customHeadingClose + property string _pendingSearchTerm: "" property variant settingsVariables: [ { 'identifier': 'extraDialogForFileName', @@ -18,52 +24,100 @@ QtObject { }, { 'identifier': 'underlineHeading', - 'name': 'Underline heading', - 'description': 'Highlight the first line by underlining it with =, if not checked, use a preceding # instead.', + 'name': 'Setext Markdown underline heading', + 'description': 'Use Setext heading style (Title / =====) for the dialog flow; if unchecked, use ATX (# Title).', + 'type': 'boolean', + 'default': 'false' + }, + { + 'identifier': 'useSearchTermAsName', + 'name': 'Name note from search term', + 'description': 'Skip the title dialog and use the current search term as the note name.', 'type': 'boolean', 'default': 'false' }, + { + 'identifier': 'searchTermHeadingStyle', + 'name': 'Search term note – heading style', + 'description': 'Title format when creating a note from the search term.', + 'type': 'selection', + 'default': '0', + 'items': { + '0': 'ATX Markdown heading (# Title)', + '1': 'Setext Markdown underline heading (Title / =====)', + '2': 'Custom heading (opening and closing tags)' + } + }, + { + 'identifier': 'customHeadingOpen', + 'name': 'Search term note – custom heading opening tag', + 'description': 'Text inserted before the note name (only used when heading style is "Custom").', + 'type': 'string', + 'default': '' + }, + { + 'identifier': 'customHeadingClose', + 'name': 'Search term note – custom heading closing tag', + 'description': 'Text inserted after the note name (only used when heading style is "Custom").', + 'type': 'string', + 'default': '' + }, ] - property bool underlineHeading - function handleNewNoteHeadlineHook(note) { - var newName = newNamer("New note", "New note title", "Title"); - script.log(note.fileCreated); - script.log(note.fileLastModified); + function handleNewNoteHeadlineHook(headline) { + // 'headline' is a plain string (the search term or default text), not a Note object. + if (useSearchTermAsName) { + _pendingSearchTerm = headline; + return headline; // noteOpenedHook will replace content with the chosen heading style + } + var newName = newNamer("New note", "New note title", "Title"); if (underlineHeading) { return newName + "\n" + "=".repeat(newName.length); - } else { - return "# " + newName; } + return "# " + newName; } - 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; + function buildHeadline(name) { + if (searchTermHeadingStyle === "2") { + return customHeadingOpen + name + customHeadingClose; } - - 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 + if (searchTermHeadingStyle === "1") { + return name + "\n" + "=".repeat(name.length); + } + return "# " + name; // "0" (ATX) or unset + } + 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 ""; } + if (useSearchTermAsName && _pendingSearchTerm !== "") { + return _pendingSearchTerm; // set by handleNewNoteHeadlineHook + } + if (extraDialogForFileName) { return newNamer("New note", "New file name", "File name"); - } else { - return noteTitle; } + + var noteLines = (note.noteText || "").split("\n"); + var firstLine = noteLines[0]; + var noteTitle = firstLine.slice(2); // Remove the preceding "# " + if (underlineHeading) { + noteTitle = firstLine; + } + return noteTitle; + } + function noteOpenedHook(note) { + if (_pendingSearchTerm === "") { + return; + } + var name = _pendingSearchTerm; + _pendingSearchTerm = ""; + script.noteTextEditSetSelection(0, (note.noteText || "").length); + script.noteTextEditWrite(buildHeadline(name)); + mainWindow.focusNoteTextEdit(); } function init() { script.log("New-note-namer active"); From 23f4948d2ff675ad4c399e6069f4703d7121ab61 Mon Sep 17 00:00:00 2001 From: luginf Date: Sat, 23 May 2026 15:02:32 +0200 Subject: [PATCH 2/9] fix new note namer --- new-note-namer/new-note-namer.qml | 79 ++++++++++++++++--------------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/new-note-namer/new-note-namer.qml b/new-note-namer/new-note-namer.qml index bbde948..b29afe3 100644 --- a/new-note-namer/new-note-namer.qml +++ b/new-note-namer/new-note-namer.qml @@ -7,57 +7,49 @@ import QOwnNotesTypes 1.0 Avoids cumbersome renaming and title editing. */ QtObject { - property bool extraDialogForFileName - property bool underlineHeading property bool useSearchTermAsName - property string searchTermHeadingStyle + property bool extraDialogForFileName + property string headingStyle property string customHeadingOpen property string customHeadingClose property string _pendingSearchTerm: "" property variant settingsVariables: [ { - '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.', - 'type': 'boolean', - 'default': 'false' - }, - { - 'identifier': 'underlineHeading', - 'name': 'Setext Markdown underline heading', - 'description': 'Use Setext heading style (Title / =====) for the dialog flow; if unchecked, use ATX (# Title).', + 'identifier': 'useSearchTermAsName', + 'name': 'Name note from search term', + 'description': 'Skip the title dialog and use the current search term as the note name.', 'type': 'boolean', 'default': 'false' }, { - 'identifier': 'useSearchTermAsName', - 'name': 'Name note from search term', - 'description': 'Skip the title dialog and use the current search term as the note name.', + '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.', 'type': 'boolean', 'default': 'false' }, { - 'identifier': 'searchTermHeadingStyle', - 'name': 'Search term note – heading style', - 'description': 'Title format when creating a note from the search term.', + 'identifier': 'headingStyle', + 'name': 'Heading style', + 'description': 'Title format for new notes.', 'type': 'selection', 'default': '0', 'items': { '0': 'ATX Markdown heading (# Title)', - '1': 'Setext Markdown underline heading (Title / =====)', + '1': 'Setext Markdown heading (Title / =====)', '2': 'Custom heading (opening and closing tags)' } }, { 'identifier': 'customHeadingOpen', - 'name': 'Search term note – custom heading opening tag', + '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': 'Search term note – custom heading closing tag', + 'name': 'Custom heading – closing tag', 'description': 'Text inserted after the note name (only used when heading style is "Custom").', 'type': 'string', 'default': '' @@ -71,21 +63,35 @@ QtObject { return headline; // noteOpenedHook will replace content with the chosen heading style } - var newName = newNamer("New note", "New note title", "Title"); - if (underlineHeading) { - return newName + "\n" + "=".repeat(newName.length); - } - return "# " + newName; + // If QOwnNotes already provided a headline (its own dialog, or a search term), + // apply the chosen style directly rather than asking again. + var name = headline !== "" ? headline : newNamer("New note", "New note title", "Title"); + return buildHeadline(name); } function buildHeadline(name) { - if (searchTermHeadingStyle === "2") { + if (headingStyle === "2") { return customHeadingOpen + name + customHeadingClose; } - if (searchTermHeadingStyle === "1") { + if (headingStyle === "1") { return name + "\n" + "=".repeat(name.length); } return "# " + name; // "0" (ATX) or unset } + function extractTitle(noteText) { + var firstLine = (noteText || "").split("\n")[0]; + if (headingStyle === "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 (headingStyle === "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 @@ -94,20 +100,17 @@ QtObject { } if (useSearchTermAsName && _pendingSearchTerm !== "") { - return _pendingSearchTerm; // set by handleNewNoteHeadlineHook + if (extraDialogForFileName) { + return newNamer("New note", "New file name", _pendingSearchTerm); + } + return _pendingSearchTerm; } if (extraDialogForFileName) { - return newNamer("New note", "New file name", "File name"); + return newNamer("New note", "New file name", extractTitle(note.noteText)); } - var noteLines = (note.noteText || "").split("\n"); - var firstLine = noteLines[0]; - var noteTitle = firstLine.slice(2); // Remove the preceding "# " - if (underlineHeading) { - noteTitle = firstLine; - } - return noteTitle; + return extractTitle(note.noteText); } function noteOpenedHook(note) { if (_pendingSearchTerm === "") { From 6a36a5fca1d115d952a4602c9fd37a5c282ecc6c Mon Sep 17 00:00:00 2001 From: luginf Date: Sat, 23 May 2026 18:27:49 +0200 Subject: [PATCH 3/9] simplify interface --- new-note-namer/new-note-namer.qml | 34 +------------------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/new-note-namer/new-note-namer.qml b/new-note-namer/new-note-namer.qml index b29afe3..ec70fe4 100644 --- a/new-note-namer/new-note-namer.qml +++ b/new-note-namer/new-note-namer.qml @@ -7,20 +7,11 @@ import QOwnNotesTypes 1.0 Avoids cumbersome renaming and title editing. */ QtObject { - property bool useSearchTermAsName property bool extraDialogForFileName property string headingStyle property string customHeadingOpen property string customHeadingClose - property string _pendingSearchTerm: "" property variant settingsVariables: [ - { - 'identifier': 'useSearchTermAsName', - 'name': 'Name note from search term', - 'description': 'Skip the title dialog and use the current search term as the note name.', - 'type': 'boolean', - 'default': 'false' - }, { 'identifier': 'extraDialogForFileName', 'name': 'Extra dialog for note title', @@ -58,13 +49,7 @@ QtObject { function handleNewNoteHeadlineHook(headline) { // 'headline' is a plain string (the search term or default text), not a Note object. - if (useSearchTermAsName) { - _pendingSearchTerm = headline; - return headline; // noteOpenedHook will replace content with the chosen heading style - } - - // If QOwnNotes already provided a headline (its own dialog, or a search term), - // apply the chosen style directly rather than asking again. + // If already provided (search term or QOwnNotes own dialog), use it directly. var name = headline !== "" ? headline : newNamer("New note", "New note title", "Title"); return buildHeadline(name); } @@ -99,29 +84,12 @@ QtObject { return ""; } - if (useSearchTermAsName && _pendingSearchTerm !== "") { - if (extraDialogForFileName) { - return newNamer("New note", "New file name", _pendingSearchTerm); - } - return _pendingSearchTerm; - } - if (extraDialogForFileName) { return newNamer("New note", "New file name", extractTitle(note.noteText)); } return extractTitle(note.noteText); } - function noteOpenedHook(note) { - if (_pendingSearchTerm === "") { - return; - } - var name = _pendingSearchTerm; - _pendingSearchTerm = ""; - script.noteTextEditSetSelection(0, (note.noteText || "").length); - script.noteTextEditWrite(buildHeadline(name)); - mainWindow.focusNoteTextEdit(); - } function init() { script.log("New-note-namer active"); } From 395dc5bf7337d1d72bf0c15e221f2d237d1c5211 Mon Sep 17 00:00:00 2001 From: luginf Date: Sat, 23 May 2026 19:49:32 +0200 Subject: [PATCH 4/9] add extra dialog for more versability --- new-note-namer/info.json | 2 +- new-note-namer/new-note-namer.qml | 32 +++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/new-note-namer/info.json b/new-note-namer/info.json index 81411f8..5e74d1c 100644 --- a/new-note-namer/info.json +++ b/new-note-namer/info.json @@ -6,5 +6,5 @@ "platforms": ["linux", "macos", "windows"], "version": "0.0.4", "minAppVersion": "17.06.2", - "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 name 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 :)" + "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 ec70fe4..e958615 100644 --- a/new-note-namer/new-note-namer.qml +++ b/new-note-namer/new-note-namer.qml @@ -7,15 +7,24 @@ 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 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' }, @@ -49,8 +58,16 @@ QtObject { function handleNewNoteHeadlineHook(headline) { // 'headline' is a plain string (the search term or default text), not a Note object. - // If already provided (search term or QOwnNotes own dialog), use it directly. - var name = headline !== "" ? headline : newNamer("New note", "New note title", "Title"); + // 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 { + // If already provided (search term or QOwnNotes own dialog), use it directly. + name = _searchTerm; + } return buildHeadline(name); } function buildHeadline(name) { @@ -84,11 +101,14 @@ QtObject { 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", extractTitle(note.noteText)); + return newNamer("New note", "New file name", defaultName); } - return extractTitle(note.noteText); + return defaultName; } function init() { script.log("New-note-namer active"); From fff296443796a0d7e18b92ea80232f286e5473e1 Mon Sep 17 00:00:00 2001 From: luginf Date: Sun, 24 May 2026 11:41:15 +0200 Subject: [PATCH 5/9] adding a readme with full instructions --- new-note-namer/README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 new-note-namer/README.md diff --git a/new-note-namer/README.md b/new-note-namer/README.md new file mode 100644 index 0000000..9ec8e74 --- /dev/null +++ b/new-note-namer/README.md @@ -0,0 +1,37 @@ +# 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. From 40144e5f9c61b42f256bc5e9091dea25588213ec Mon Sep 17 00:00:00 2001 From: luginf Date: Sun, 24 May 2026 12:15:38 +0200 Subject: [PATCH 6/9] trigger new CI --- new-note-namer/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 new-note-namer/README.md diff --git a/new-note-namer/README.md b/new-note-namer/README.md old mode 100644 new mode 100755 From 7c62dbe29d8e741102772e060890dc20713dadb8 Mon Sep 17 00:00:00 2001 From: Patrizio Bekerle Date: Sun, 24 May 2026 22:49:10 +0200 Subject: [PATCH 7/9] lint: format file Signed-off-by: Patrizio Bekerle --- new-note-namer/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/new-note-namer/README.md b/new-note-namer/README.md index 9ec8e74..934cb5a 100755 --- a/new-note-namer/README.md +++ b/new-note-namer/README.md @@ -20,11 +20,11 @@ The two dialog options are independent: each defaults to the search term, regard | 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` | +| 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 | +| 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. From c7ba29ea350afe5adb7ba318df7f93f2fd3894a7 Mon Sep 17 00:00:00 2001 From: luginf Date: Tue, 26 May 2026 10:29:36 +0200 Subject: [PATCH 8/9] We're making the new-note-namer script upgrade-safe for existing users. The code and README are updated with backward-compatible migration logic for the renamed heading setting. --- new-note-namer/README.md | 15 +++++++++++++++ new-note-namer/new-note-namer.qml | 26 ++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/new-note-namer/README.md b/new-note-namer/README.md index 934cb5a..5cd7a72 100755 --- a/new-note-namer/README.md +++ b/new-note-namer/README.md @@ -35,3 +35,18 @@ The two dialog options are independent: each defaults to the search term, regard - 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/new-note-namer.qml b/new-note-namer/new-note-namer.qml index e958615..aa0005c 100644 --- a/new-note-namer/new-note-namer.qml +++ b/new-note-namer/new-note-namer.qml @@ -13,6 +13,7 @@ QtObject { 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', @@ -54,6 +55,13 @@ QtObject { 'type': 'string', 'default': '' }, + { + 'identifier': 'underlineHeading', + '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' + }, ] function handleNewNoteHeadlineHook(headline) { @@ -70,18 +78,28 @@ QtObject { } return buildHeadline(name); } + // 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"; + } + return headingStyle; + } function buildHeadline(name) { - if (headingStyle === "2") { + var style = effectiveHeadingStyle(); + if (style === "2") { return customHeadingOpen + name + customHeadingClose; } - if (headingStyle === "1") { + if (style === "1") { return name + "\n" + "=".repeat(name.length); } return "# " + name; // "0" (ATX) or unset } function extractTitle(noteText) { var firstLine = (noteText || "").split("\n")[0]; - if (headingStyle === "2") { + var style = effectiveHeadingStyle(); + if (style === "2") { var t = firstLine.slice(customHeadingOpen.length); var closeLen = customHeadingClose.length; if (closeLen > 0 && t.slice(-closeLen) === customHeadingClose) { @@ -89,7 +107,7 @@ QtObject { } return t; } - if (headingStyle === "1") { + if (style === "1") { return firstLine; // setext: first line is the bare title } return firstLine.slice(2); // ATX: remove "# " From f7dcd393af72684d9ca190d63e2754bcb9427958 Mon Sep 17 00:00:00 2001 From: luginf Date: Tue, 26 May 2026 10:36:11 +0200 Subject: [PATCH 9/9] run prettier on README --- new-note-namer/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/new-note-namer/README.md b/new-note-namer/README.md index 5cd7a72..8843a7e 100755 --- a/new-note-namer/README.md +++ b/new-note-namer/README.md @@ -43,10 +43,10 @@ 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 | +| 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.