Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
421 changes: 402 additions & 19 deletions helpers/NPFrontMatter.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions helpers/__tests__/NPFrontMatter/NPFrontMatterFormatting.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,73 @@ describe(`${PLUGIN_NAME}`, () => {
expect(result).toEqual(expected)
})

test('should not treat invalid YAML content as frontmatter', () => {
const before = `---
**Event:** <%- calendarItemLink %>
**Links:** <%- eventLink %>
**Attendees:** <%- eventAttendees %>
**Location:** <%- eventLocation %>
---
### Agenda
+

### Notes
-

### Actions
* `
const result = f.getSanitizedFmParts(before)
// Should treat the entire content as body since the content between --- is not valid YAML
expect(result.attributes).toEqual({})
expect(result.body).toEqual(before)
expect(result.frontmatter).toEqual('')
})

test('should treat content with template tags as frontmatter', () => {
const before = `---
title: <%- eventTitle %>
date: <%- eventDate() %>
type: meeting-note
---
# Meeting Notes

Some content here.`
const result = f.getSanitizedFmParts(before)
// Should extract the frontmatter correctly even with template tags
expect(result.attributes).toEqual({
title: '<%- eventTitle %>',
date: '<%- eventDate() %>',
type: 'meeting-note',
})
expect(result.body).toEqual('# Meeting Notes\n\nSome content here.')
// The frontmatter field should contain the actual frontmatter content when fm library succeeds
expect(result.frontmatter).toContain('title:')
expect(result.frontmatter).toContain('date:')
expect(result.frontmatter).toContain('type:')
})

test('should treat valid YAML content as frontmatter even when fm library fails', () => {
const before = `---
title: Valid YAML
date: 2024-01-15
type: note
invalid_yaml: [unclosed array
---
# Valid Content

This is the body.`
const result = f.getSanitizedFmParts(before)
// Should extract the frontmatter correctly using fallback logic
expect(result.attributes).toEqual({
title: 'Valid YAML',
date: '2024-01-15',
type: 'note',
invalid_yaml: '[unclosed array',
})
expect(result.body).toEqual('# Valid Content\n\nThis is the body.')
expect(result.frontmatter).toEqual('')
})

describe('sanitizeFrontmatterInNote()', () => {
test.skip('should do nothing if none are necesary', () => {
const note = new Note({ content: 'baz' })
Expand Down
6 changes: 5 additions & 1 deletion helpers/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { logDebug } from './dev'
import { showMessageYesNo, showMessage } from './userInput'
import { getFolderFromFilename } from '@helpers/folders'
import { getNoteTitleFromTemplate } from './NPFrontMatter'

/**
* Run Editor.save() if active Editor is dirty and needs saving
Expand Down Expand Up @@ -37,7 +38,10 @@ export async function checkAndProcessFolderAndNewNoteTitle(templateNote: TNote,
// Check if the template wants the note to be created in a folder and if so, move the empty note to the trash and create a new note in the folder
const isEditorEmpty = editorIsEmpty()
const theFolder = frontmatterAttributes?.folder?.trim() || ''
const newNoteTitle = frontmatterAttributes?.newNoteTitle?.trim() || ''

// Use the new function to get note title from template, checking both newNoteTitle and inline title
const newNoteTitle = getNoteTitleFromTemplate(templateNote?.content || '') || frontmatterAttributes?.newNoteTitle?.trim() || ''

logDebug(`checkAndProcessFolderAndNewNoteTitle starting: templateNote:"${templateNote?.title || ''}", frontmatterAttributes:${JSON.stringify(frontmatterAttributes)}`)
if (theFolder.length > 0 || newNoteTitle.length > 0) {
if (isEditorEmpty) {
Expand Down
8 changes: 8 additions & 0 deletions np.MeetingNotes/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@

See Plugin [README](https://github.com/NotePlan/plugins/blob/main/np.MeetingNotes/README.md) for details on available commands and use case.

## [2.0.3] - 2025-08-06 @dwertheimer

- Make it possible for a template to have any level of heading for the title (was previously H1 only)

## [2.0.2] - 2025-08-05 @dwertheimer

- Fix bug where inline H1 title was not being used in templateNew (thx @crussell)

## [2.0.1] - 2025-08-02 @dwertheimer

- Add override when inserting a template into a blank note but template has folder or newNoteTitle attribute
Expand Down
2 changes: 1 addition & 1 deletion np.MeetingNotes/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"noteplan.minAppVersion": "3.5.0",
"plugin.id": "np.MeetingNotes",
"plugin.name": "✍️ Meeting Notes",
"plugin.version": "2.0.1",
"plugin.version": "2.0.3",
"plugin.description": "Create Meeting Notes from events using templates.",
"plugin.author": "NotePlan",
"plugin.dependencies": [],
Expand Down
10 changes: 6 additions & 4 deletions np.MeetingNotes/src/NPMeetingNotes.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { getNoteByFilename } from '../../helpers/note'
import { isCalendarNoteFilename } from '@helpers/regex'
import { log, logDebug, logError, clo, JSP, timer } from '@helpers/dev'
import { findProjectNoteUrlInText } from '@helpers/urls'
import { getAttributes } from '@helpers/NPFrontMatter'
import { getAttributes, getNoteTitleFromTemplate } from '@helpers/NPFrontMatter'
import { checkAndProcessFolderAndNewNoteTitle } from '@helpers/editor'

/**
Expand Down Expand Up @@ -210,7 +210,7 @@ function titleExistsInNote(content: string): string | null {
// logDebug(pluginJson, `titleExistsInNote attributes?.title=${attributes?.title}`)
// if (attributes?.title) return attributes.title // commenting this out because attributes is the template's attributes, not the resulting doc
const lines = content.split('\n')
const headingLine = lines.find((l) => l.startsWith('# '))
const headingLine = lines.find((l) => l.match(/^#{1,6}\s+/))
logDebug(pluginJson, `titleExistsInNote headingLine || null=${headingLine || 'null (no title in content)'}`)
return headingLine || null
}
Expand All @@ -227,7 +227,7 @@ function getNoteTitle(_noteTitle: string, renderedTemplateContent: string, attri
// if (attributes?.title) return attributes.title
// grab the first line of the result as the title
const lines = renderedTemplateContent.split('\n')
const headingLine = lines.find((l) => l.startsWith('#')) // may need to infer the title from a ## title etc.
const headingLine = lines.find((l) => l.match(/^#{1,6}\s+/)) // may need to infer the title from a ## title etc.
const noteTitle = headingLine ? headingLine.replace(/(^#*\s*)/, '').trim() : ''
logDebug(pluginJson, `No title specified directly. Trying to infer it from the headingLine: "${headingLine || ''}" => "${noteTitle}"`)
return noteTitle
Expand Down Expand Up @@ -292,7 +292,9 @@ async function createNoteAndLinkEvent(selectedEvent: TCalendarItem | null, rende
const append: string = attrs?.append || ''
const prepend: string = attrs?.prepend || ''
const cursor: string = attrs?.cursor || ''
const newNoteTitle: string = attrs?.newNoteTitle || ''
// Use the new function to get note title from template, checking both newNoteTitle and inline title
const templateNoteTitle = getNoteTitleFromTemplate(renderedContent)
const newNoteTitle: string = templateNoteTitle || attrs?.newNoteTitle || ''

let noteTitle: string = (append || prepend || cursor).trim()
const location: string = append.length ? 'append' : cursor.length ? 'cursor' : 'prepend'
Expand Down
17 changes: 17 additions & 0 deletions np.Templating/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@

See Plugin [Documentation](https://noteplan.co/templates/docs) for details on available commands and use case.

## [2.0.17] 2025-08-06 @dwertheimer
- Fix bug where non-fm-body templates which started with -- were being treated as frontmatter

## [2.0.16] 2025-08-06 @dwertheimer
- Add pivot offset to date.now() method

## [2.0.15] 2025-08-06 @dwertheimer
- Fix date module edge cases with timezones

## [2.0.14] 2025-08-06 @dwertheimer
- Make it possible for a template to have any level of heading for the title (was previously H1 only)

## [2.0.13] 2025-08-05 @dwertheimer
- Fix bug where inline H1 title was not being used in templateNew (thx @crussell)
- Ensure that inline H1 title is not created in frontmatter even if there is other frontmatter being created
- if there is newNoteTitle and also an inline H1 title, the newNoteTitle will take precedence and will be created in frontmatter

## [2.0.12] 2025-08-02 @dwertheimer
- Fix templateNew to handle blank meeting note edge case

Expand Down
Loading
Loading