Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/NotePlan/plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
dwertheimer committed Feb 23, 2022
2 parents 69daa66 + dff25b7 commit 4891c03
Show file tree
Hide file tree
Showing 45 changed files with 639 additions and 360 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ All NotePlan plugins follow `semver` versioning. For details, please refer to [s

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

## [3.1.0] - 2022-02-19 (@mikeerickson)
- fixed issue with release script
- refactored release validation in CLI `npc plugin:release`
- add guard to make sure releasing from plugins directory

## [3.0.2] - 2022-02-17 (@mikeerickson)
- restored `docs` command

Expand Down
23 changes: 23 additions & 0 deletions cd.FormattedDateTime/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# cd.FormattedDateTime Changelog

## About cd.FormattedDateTime Plugin

Example Plugin to demonstrate how to integrate np.Templating Plugin into a standard NotePlan Plugin

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

## [0.0.1] - 2022-02-22 (mikeerickson)

### Added
Initial Release

## Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Plugin Versioning Uses Semver

All NotePlan plugins follow `semver` versioning. For details, please refer to [semver website](https://semver.org/)
4 changes: 4 additions & 0 deletions cd.FormattedDateTime/FormattedDateTime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# FormattedDateTime
*****
#### Demonstration using extended method
<%= myFormattedDateTime({format: '%A, %B %d, %Y'}) %>
19 changes: 19 additions & 0 deletions cd.FormattedDateTime/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# FormattedDateTime Noteplan Plugin
Example NotePlan Plugin demonstration how to integrate np.Templating

## License

Copyright &copy; 2022 Mike Erickson
Released under the MIT license

## Credits

**FormattedDateTime for NotePlan** written by **Mike Erickson**

E-Mail: [[email protected]](mailto:[email protected])

Support: [https://github.com/NotePlan/plugins/issues](https://github.com/NotePlan/plugins/issues)

Twitter: [@codedungeon](http://twitter.com/codedungeon)

Website: [codedungeon.io](http://codedungeon.io)
38 changes: 38 additions & 0 deletions cd.FormattedDateTime/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"macOS.minVersion": "10.13.0",
"noteplan.minAppVersion": "3.4.1",
"plugin.id": "cd.FormattedDateTime",
"plugin.name": "🧩 FormattedDateTime",
"plugin.version": "0.0.1",
"plugin.description": "Sample Templating Plugin",
"plugin.author": "codedungeon",
"plugin.dependencies": [],
"plugin.script": "script.js",
"plugin.url": "https://github.com/NotePlan/plugins/blob/main/cd.FormattedDateTime/README.md",
"plugin.commands": [
{
"name": "xx:formattedDateTime",
"description": "Display Formatted Date Time",
"jsFunction": "templateFormattedDateTime",
"alias": []
}
],
"plugin.settings": [
{
"type": "heading",
"title": "FormattedDateTime Settings"
},
{
"key": "version",
"type": "hidden",
"description": "FormattedDateTime Settings Version"
},
{
"key": "format",
"title": "Format",
"type": "string",
"description": "Date Time Format",
"default": "%A, %B %d, %Y"
}
]
}
51 changes: 51 additions & 0 deletions cd.FormattedDateTime/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// @flow
// NOTE: Strip out all the comments if you want to just read the code (hopefully pretty self explanatory)

import pluginJson from '../plugin.json'

// import np.Templating Library
import NPTemplating from 'NPTemplating'

import { formattedDateTimeTemplate } from '@plugins/dwertheimer.DateAutomations/src/dateFunctions'
// import { getSetting } from '@helpers/NPconfiguration'

import { updateSettingData } from '@helpers/NPconfiguration'
import { log, logError } from '@helpers/dev'

export async function templateFormattedDateTime(): Promise<void> {
try {
// NOTE: this is only here to initialize settings since the plugin was never installed
await updateSettingData(pluginJson)

const templateObj = {
methods: {
myFormattedDateTime: async (params: any = {}) => {
// this is only looking in current plugin settings file, more generic method coming in getSetting
const defaultFormat: string = DataStore.settings.format

// build format string passed to `formattedDateTimeTemplate`
const format: string = params && params.hasOwnProperty('format') ? params.format : defaultFormat

// NOTE: np.Templating actually passes an as it is defined in template, unlike existing templating passes things as a string
// create string version of format block which `formattedDateTimeTemplate` expects
const formatString: string = `{format: ${format}}`

// call existing `formattedDateTimeTemplate` from `./dwertheimer.DateAutomations/src/dateFunctions`
return formattedDateTimeTemplate(formatString)
},
},
}

// Assumes a template with name `FormattedDateTime` exists
// see `FormattedDateTime.md` in plugin root for sample
const result: string = (await NPTemplating.renderTemplate('FormattedDateTime', templateObj)) || ''

Editor.insertTextAtCursor(result)
} catch (error) {
logError(pluginJson, `templateFormattedDateTime :: ${error}`)
}
}

export async function onUpdateOrInstall(): Promise<void> {
updateSettingData(pluginJson)
}
35 changes: 28 additions & 7 deletions helpers/NPCalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@ import { keepTodayPortionOnly } from './calendar'
import {
getDateFromUnhyphenatedDateString,
getISODateStringFromCalendarFilename,
type HourMinObj,
printDateRange,
removeDateTagsAndToday,
todaysDateISOString,
} from './dateTime'
import {
addMinutes,
differenceInMinutes,
} from 'date-fns'
import { clo } from './dev'
import { displayTitle } from './general'
import { findEndOfActivePartOfNote } from './paragraph'
import {
Expand All @@ -39,7 +46,6 @@ import {
} from './timeblocks'
import { showMessage, showMessageYesNo } from './userInput'

import type { HourMinObj } from './dateTime'

export type EventsConfig = {
eventsHeading: string,
Expand All @@ -53,6 +59,7 @@ export type EventsConfig = {
processedTagName?: string /* if not set, uses RE_EVENT_ID */,
removeTimeBlocksWhenProcessed?: boolean,
calendarToWriteTo?: string,
defaultEventDuration: number
}

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -141,16 +148,30 @@ export async function writeTimeBlocksToCalendar(config: EventsConfig, note: TNot
}
timeBlockString = `${datePart} ${timeBlockString}`
// NB: parseDateText returns an array, so we'll use the first one as most likely
const timeblockDateRange = Calendar.parseDateText(timeBlockString)[0]
let timeblockDateRange = Calendar.parseDateText(timeBlockString)[0]

if (timeblockDateRange) {
// We have a valid timeblock, so let's make the event etc.
// First strip out time + date (if present) from the timeblock line,

// First see if this is a zero-length event, which happens when no end time
// was specified. If we have a defaultEventDuration then use it.
if (differenceInMinutes(timeblockDateRange.start, timeblockDateRange.end) === 0 && config.defaultEventDuration > 0)
{
const newEndDate = addMinutes(timeblockDateRange.end, config.defaultEventDuration)
timeblockDateRange = { start: timeblockDateRange.start, end: newEndDate}
}

// Strip out time + date (if present) from the timeblock line,
// as we don't want those to go into the calendar event itself (=restOfTask).
// But also keep a version with date (if present) as we don't want to lose that from the task itself.
let restOfTaskWithoutTimeBlock = thisPara.content.replace(origTimeBlockString, '').trim() // take off timeblock
let restOfTaskWithoutDateTime = restOfTaskWithoutTimeBlock.replace(`>${datePart}`, '').trim() // take off >date (if present)
restOfTaskWithoutDateTime = restOfTaskWithoutDateTime.replace(datePart, '').trim() // take off date (if present)
let restOfTaskWithoutTimeBlock = thisPara.content
.replace(origTimeBlockString, '')
.replace(/\s{2,}/g, ' ')
.trimEnd() // take off timeblock
let restOfTaskWithoutDateTime =
removeDateTagsAndToday(restOfTaskWithoutTimeBlock)
.replace(timeBlockString, '')
.replace(/\s{2,}/g, ' ')
console.log(`\tWill process time block '${timeBlockString}' for '${restOfTaskWithoutDateTime}'`)

// Do we want to add this particular event?
Expand All @@ -171,7 +192,7 @@ export async function writeTimeBlocksToCalendar(config: EventsConfig, note: TNot

// Remove time block string (if wanted)
let thisParaContent = thisPara.content
console.log(`\tstarting with thisPara.content: '${thisParaContent}'`)
// console.log(`\tstarting with thisPara.content: '${thisParaContent}'`)
if (config.removeTimeBlocksWhenProcessed) {
thisParaContent = restOfTaskWithoutTimeBlock
}
Expand Down
24 changes: 9 additions & 15 deletions helpers/NPConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ const log = (msg: string = ''): void => {
* @return return this as structured data, in the format specified by the first line of the codeblock (should be `javascript`)
*/
export async function getConfiguration(configSection: string = ''): Promise<any> {
const configFile = DataStore.projectNotes
.filter((n) => n.filename?.startsWith(STATIC_TEMPLATE_FOLDER))
.find((n) => !!n.title?.startsWith('_configuration'))
const configFile = DataStore.projectNotes.filter((n) => n.filename?.startsWith(STATIC_TEMPLATE_FOLDER)).find((n) => !!n.title?.startsWith('_configuration'))

const content: ?string = configFile?.content
if (content == null) {
Expand Down Expand Up @@ -98,11 +96,7 @@ export async function initConfiguration(pluginJsonData: any): Promise<any> {
* @param {any} pluginJsonData - plugin.json data for which plugin is being migrated
* @return {number} migration result (-1 migration section not found, 1 success, 0 no migration necessary)
*/
export async function migrateConfiguration(
configSection: string,
pluginJsonData: any,
silentMode?: boolean = false,
): Promise<number> {
export async function migrateConfiguration(configSection: string, pluginJsonData: any, silentMode?: boolean = false): Promise<number> {
// migrationResult
// will be 1 if _configuration was migrated to plugin settings
// will be 0 if no migration necessary
Expand Down Expand Up @@ -205,15 +199,15 @@ export function updateSettingData(pluginJsonData: any): number {
return updateResult
}

export function getSetting(
pluginName?: string = '',
key: string = '',
defaultValue?: { [string]: mixed },
): { [string]: mixed } | null {
return null
export function getSetting(pluginName?: string = '', key: string = '', defaultValue?: { [string]: mixed }): any | null {
// this method is not working as I have to figure out a way to get the path to data directory
return 'INCOMPLETE'

const pluginSettingsData = DataStore.loadJSON(`../${pluginName}/settings.json`)
return pluginSettingsData?.[key] ? pluginSettingsData[key] : defaultValue
}

export function getSettings(pluginName?: string = '', defaultValue?: { [string]: mixed }): { [string]: mixed } | null {
export function getSettings(pluginName?: string = '', defaultValue?: { [string]: mixed }): any | null {
return null
}

Expand Down
2 changes: 1 addition & 1 deletion helpers/dateTime.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export function removeDateTags(content: string): string {
export function removeDateTagsAndToday(tag: string): string {
return removeDateTags(tag)
.replace(/>today/, '')
.replace(/ {2,}/gm, ' ')
.replace(/\s{2,}/g, ' ')
.trimEnd()
}

Expand Down
6 changes: 5 additions & 1 deletion helpers/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ export function log(pluginInfo: any, message: any = '', type: string = 'LOG'): s
msg = `${dt().padEnd(19)} | ${type.padEnd(5)} | ${pluginId} v${pluginVersion} :: ${_message(message)}`
} else {
msgType = arguments.length === 2 ? message : type
msg = `${dt().padEnd(19)} | ${msgType.padEnd(5)} | INVALID_PLUGIN_INFO :: ${_message(pluginInfo)}`
if (message.length > 0) {
msg = `${dt().padEnd(19)} | ${msgType.padEnd(5)} | ${pluginInfo} :: ${_message(message)}`
} else {
msg = `${dt().padEnd(19)} | ${msgType.padEnd(5)} | INVALID_PLUGIN_INFO :: ${_message(pluginInfo)}`
}
}

console.log(msg)
Expand Down
2 changes: 1 addition & 1 deletion jgclark.DailyJournal/plugin.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"noteplan.min_version": "3.3.2",
"noteplan.minAppVersion": "3.3.2",
"macOS.minVersion": "10.13.0",
"plugin.id": "jgclark.DailyJournal",
"plugin.name": "☀️ Daily Journal",
Expand Down
4 changes: 4 additions & 0 deletions jgclark.EventHelpers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ See [website README for more details](https://github.com/NotePlan/plugins/tree/m

<!-- Improve detection of target dates -->

## [0.11.5] - 2022-02-20
### Added
- new `defaultEventDuration` (in minutes) which is used if the time block doesn't have an end time, to create it. Otherwise the event will be 0 minutes long.

## [0.11.4] - 2022-02-07
### Fixed
- fix to allow `matchingEvent` calls to be run from Templates, after change to new built-in Settings screen
Expand Down
4 changes: 3 additions & 1 deletion jgclark.EventHelpers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ This plugin provides commands to help work with Calendars and Events:
- `/insert day's events as list`: insert list of this day's calendar events at cursor
- `/list day's events to log`: write list of this day's calendar events to console log
- `/insert matching events`: adds this day's calendar events matching certain patterns at cursor
- `/time blocks to calendar`: takes [NotePlan-defined time blocks](https://help.noteplan.co/article/52-part-2-tasks-events-and-reminders#timeblocking) and converts to full Calendar events, in your current default calendar, as set by iCal.
- `/time blocks to calendar`: takes [NotePlan-defined time blocks](https://help.noteplan.co/article/52-part-2-tasks-events-and-reminders#timeblocking) and converts to full Calendar events, in your current default calendar, as set by iCal. (If the end time is not given, then the 'defaultEventDuration' setting is used to give it an end time.)
- `/process date offsets`: finds date offset patterns and turns them into due dates, based on date at start of section. (See [Templates for Dates](#template-for-dates) below for full details.)

The first four of these have a number of [options described below](#configuration).
See [Theme customisation](#theme-customisation) below for more on how to customise display of time blocks and events.

## Date Offsets
This is best understood with a quick example:

Expand Down Expand Up @@ -70,6 +71,7 @@ This uses JSON5 format: ensure there are commas at the end of all that lines tha
- **calendarSet**: optional ["array","of calendar","names"] to filter by when showing list of events. If empty or missing, no filtering will be done.
- **addMatchingEvents**: for `/add matching events` is a set of pairs of strings. The first string is what is matched for in an event's title. If it does match the second string is used as the format for how to insert the event details at the cursor. This uses the same `*|TITLE|*`, `*|START|*` (time), `*|END|*` (time), `*|NOTES|*` and `*|URL|*` format items below ... NB: At this point the 'location' field is unfortunately _not_ available through the API.
- **calendarNameMappings**: optional - add mappings for your calendar names to appear in the output - e.g. from "Thomas" to "Me" with "Thomas;Me".
- **defaultEventDuration**: Event duration (in minutes) to use when making an event from a time block, if an end time is not given.

### Using Event Lists from a Template
If you use Templates, this command can be called when a Template is inserted (including in the `/day start` command which applies your `Daily Note Template` file). To do this insert `{{events()}}` wherever you wish it to appear in the Template. By default it gives a simple markdown list of event title and start time. To **customise the list display**, you can add a `'template:"..."'` parameter to the `{{events()}}` command that sets how to present the list, and a separate parameter for items with no start/end times (`'allday_template:"..."`).
Expand Down
20 changes: 11 additions & 9 deletions jgclark.EventHelpers/__tests__/eventsToNotes.test.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
/* global describe, expect, test, toEqual */
import { sortByCalendarNameAndStartTime } from '../src/eventsToNotes'
import { clo } from '../../helpers/dev'

describe('eventsToNotes.js tests', () => {

describe('sortByCalendarNameAndStartTime()', () => {
let sortedMap: { cal: string, start: string, text: string }[] = []
sortedMap.push({cal:'calA',start:'10:00', text:'event string 2'})
sortedMap.push({cal:'calA',start:'23:00', text:'event string 5'})
sortedMap.push({cal:'calB',start:'09:00', text:'event string 1'})
sortedMap.push({cal:'calB',start:'12:00', text:'event string 4'})
sortedMap.push({cal:'calC',start:'11:00', text:'event string 3'})

let mapForSorting: { cal: string, start: string, text: string }[] = []
mapForSorting.push({cal:'calB',start:'09:00', text:'event string 1'})
mapForSorting.push({cal:'calA',start:'10:00', text:'event string 2'})
mapForSorting.push({cal:'calC',start:'11:00', text:'event string 3'})
mapForSorting.push({cal:'calB',start:'12:00', text:'event string 4'})
mapForSorting.push({cal:'calA',start:'23:00', text:'event string 5'})
mapForSorting.push({cal:'calC',start:'11:00', text:'event string 6'})
mapForSorting.push({ cal: 'calC', start: '11:00', text: 'event string 6' })

let sortedMap: { cal: string, start: string, text: string }[] = []
sortedMap.push({cal:'calA',start:'10:00', text:'event string 2'})
sortedMap.push({cal:'calA',start:'23:00', text:'event string 5'})
sortedMap.push({cal:'calB',start:'09:00', text:'event string 1'})
sortedMap.push({cal:'calB',start:'12:00', text:'event string 4'})
sortedMap.push({cal:'calC',start:'11:00', text:'event string 3'})
sortedMap.push({ cal: 'calC', start: '11:00', text: 'event string 6' })

test('should sort by calendar name then start time test 1', () => {
const result = mapForSorting.sort(sortByCalendarNameAndStartTime())
console.log(result)
// clo(result)
expect(result).toEqual(sortedMap)
})
})
Expand Down
Loading

0 comments on commit 4891c03

Please sign in to comment.