Skip to content
Open
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
6 changes: 6 additions & 0 deletions packages/cannoli-core/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,12 @@ export class CannoliFactory {
reference.shouldExtract = true;
reference.name = innerMatch[1];
this.handleModifiers(reference, innerMatch[2]);
} else if ((innerMatch = /^\+\+@(.*?)([\W]*)$/.exec(content))) {
// Create note reference
reference.type = ReferenceType.CreateNoteAtNewPath;
reference.shouldExtract = true;
reference.name = innerMatch[1];
this.handleModifiers(reference, innerMatch[2]);
} else {
// Standard variable
reference.name = content;
Expand Down
1 change: 1 addition & 0 deletions packages/cannoli-core/src/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export enum ReferenceType {
Floating = "floating",
Note = "note",
CreateNote = "create-note",
CreateNoteAtNewPath = "create-note-at-new-path",
Selection = "selection",
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import { ContentNode } from "../ContentNode";
import { FloatingNode } from "../../../FloatingNode";

export class ReferenceNode extends ContentNode {
// @ts-expect-error - reference is not always set, fix this
reference: Reference;
reference!: Reference;
originalReference!: Reference;

constructor(
nodeData:
Expand All @@ -31,9 +31,15 @@ export class ReferenceNode extends ContentNode {
this.error(`Could not find reference.`);
} else {
this.reference = this.references[0];
this.originalReference = { ...this.references[0] };
}
}

reset(): void {
this.reference = { ...this.originalReference };
super.reset();
}

async execute(): Promise<void> {
this.executing();

Expand Down Expand Up @@ -92,6 +98,7 @@ export class ReferenceNode extends ContentNode {

if (
this.reference.type === ReferenceType.CreateNote ||
this.reference.type === ReferenceType.CreateNoteAtNewPath ||
(this.reference.type === ReferenceType.Variable &&
this.reference.shouldExtract)
) {
Expand Down Expand Up @@ -257,7 +264,10 @@ export class ReferenceNode extends ContentNode {
);

// If this reference is a create note type, create the note
if (this.reference.type === ReferenceType.CreateNote) {
if (
this.reference.type === ReferenceType.CreateNote ||
this.reference.type === ReferenceType.CreateNoteAtNewPath
) {
let noteName;

// If there are properties edges, create a yaml frontmatter section, and fill it with the properties, where the key is the edge.text and the value is the edge.content
Expand Down Expand Up @@ -295,11 +305,19 @@ export class ReferenceNode extends ContentNode {
throw new Error("No fileManager found");
}

noteName = await this.run.fileManager.createNoteAtExistingPath(
referenceNameEdge.content,
path,
content ?? "",
);
if (this.reference.type === ReferenceType.CreateNote) {
noteName = await this.run.fileManager.createNoteAtExistingPath(
referenceNameEdge.content,
path,
content ?? "",
);
} else if (this.reference.type === ReferenceType.CreateNoteAtNewPath) {
noteName = await this.run.fileManager.createNoteAtNewPath(
referenceNameEdge.content,
path,
content ?? "",
);
}
} catch (e) {
if (e instanceof Error) {
this.error(`Could not create note: ${e.message}`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1 @@
{
"nodes":[
{"id":"4456b948335f3b94","type":"group","x":-334,"y":260,"width":731,"height":518,"label":"Defining path"},
{"id":"837ba0cd52636e4c","type":"group","x":-280,"y":-335,"width":677,"height":518,"label":"Creating notes"},
{"id":"fc94ad73861dd0b4","type":"text","text":"{{+@articleName}}","x":-40,"y":-146,"width":250,"height":60,"color":"6"},
{"id":"375c5de56f45d5e1","type":"text","text":"The Truth About Hula Hoops","x":-260,"y":-296,"width":285,"height":60,"color":"6"},
{"id":"679af4d2d1190b6b","type":"text","text":"Write a paragraph about a sinister history of hula hoops","x":85,"y":-315,"width":292,"height":79},
{"id":"bd60374fe51f025d","type":"text","text":"","x":-64,"y":-20,"width":299,"height":183,"color":"6"},
{"id":"58140dc2db7bc769","type":"text","text":"You can create a note using a special reference node.\n\nAdd a \"+\" before the variable in a dynamic reference node, and it will create that note.","x":-660,"y":-236,"width":354,"height":180},
{"id":"4c6e2bf4a9959f15","type":"text","text":"Write an overly apologetic email about how we're out of altoids","x":85,"y":280,"width":292,"height":100},
{"id":"6b9ee922dd00451b","type":"text","text":"{{+@title}}","x":-40,"y":449,"width":250,"height":60,"color":"6"},
{"id":"7a8aaacc8a5f8e49","type":"text","text":"This feature should play nicely with other plugins like templater.","x":-635,"y":0,"width":329,"height":72},
{"id":"8372acb7e244fb15","type":"text","text":"","x":-64,"y":575,"width":299,"height":183,"color":"6"},
{"id":"0f4591137e166313","type":"text","text":"No more Altoids","x":-117,"y":280,"width":180,"height":60,"color":"6"},
{"id":"b0608205e7a748f6","type":"text","text":"/Cannoli College/4. Vault interaction","x":-306,"y":350,"width":250,"height":60,"color":"6"},
{"id":"f3c97367ffc6cce1","type":"text","text":"You can define where the new note will be created using an arrow that starts with \"/\".\n\nIf it's a valid path, then the note will be created there.","x":-700,"y":310,"width":342,"height":180},
{"id":"dec1b7beb803bffa","type":"text","text":"This example will create a new note in this folder.","x":-608,"y":575,"width":250,"height":60}
],
"edges":[
{"id":"87857bf3a2254dec","fromNode":"375c5de56f45d5e1","fromSide":"bottom","toNode":"fc94ad73861dd0b4","toSide":"top","label":"articleName"},
{"id":"a49c245f203702e6","fromNode":"679af4d2d1190b6b","fromSide":"bottom","toNode":"fc94ad73861dd0b4","toSide":"top"},
{"id":"283a21bf831d34da","fromNode":"fc94ad73861dd0b4","fromSide":"bottom","toNode":"bd60374fe51f025d","toSide":"top"},
{"id":"c0aea91c093cd031","fromNode":"6b9ee922dd00451b","fromSide":"bottom","toNode":"8372acb7e244fb15","toSide":"top"},
{"id":"7aca371238d9f008","fromNode":"0f4591137e166313","fromSide":"bottom","toNode":"6b9ee922dd00451b","toSide":"top","label":"title"},
{"id":"f2ab13710488acaa","fromNode":"4c6e2bf4a9959f15","fromSide":"bottom","toNode":"6b9ee922dd00451b","toSide":"top"},
{"id":"f9e1ee261742cf86","fromNode":"b0608205e7a748f6","fromSide":"bottom","toNode":"6b9ee922dd00451b","toSide":"left","label":"/"}
]
}
{"nodes":[{"id":"4456b948335f3b94","type":"group","x":-334,"y":260,"width":731,"height":518,"label":"Defing path"},{"id":"19b3af6c47c3e008","type":"group","x":-260,"y":840,"width":731,"height":518,"label":"New path"},{"id":"837ba0cd52636e4c","type":"group","x":-280,"y":-335,"width":677,"height":518,"label":"Creati notes"},{"id":"fc94ad73861dd0b4","type":"text","text":"{{+@articleName}}","x":-40,"y":-146,"width":250,"height":60,"cor":"6"},{"id":"375c5de56f45d5e1","type":"text","text":"The Truth About Hula Hoops","x":-260,"y":-296,"width":285,"height":60,"cor":"6"},{"id":"679af4d2d1190b6b","type":"text","text":"Write a paragraph about a sinister history of hula hoops","x":85,"y":-315,"width":292,"height":79,"cor":"4"},{"id":"bd60374fe51f025d","type":"text","text":"Legend has it that the hula hoop was born not from a child's delight but from a tinker's darker ambition, a simple ring that slipped through centuries like a sly, spinning secret; in one telling, Victorian metalworkers crafted the first hoops to test a theory of rhythm and obedience, watching as people swayed and grew uncomfortably attuned to the beat, while in another, wartime engineers perfected a hollow, whistling design that could carry messages and malice in its centrifugal hum. By the time plastic made them cheap and ubiquitous, the hoops seemed to have a will of their own—left on a playground at dusk they whispered against the pavement, aligning themselves with the sway of passing bodies, reminding anyone who watched that circular motion can be comforting or coercive. Collectors speak in low voices of rings that never stopped spinning, of children who learned tricks they could not unlearn, and of a profitable fad that blurred into something like ritual: bright, cheerful exteriors hiding a long, unbroken history of obsession and control. Even now, a discarded hoop glinting in the gutter can feel like a small, patient relic, waiting for the next generation to turn and twirl into a story far older and stranger than any toy catalog.","x":-64,"y":-20,"width":299,"height":183,"cor":"6"},{"id":"58140dc2db7bc769","type":"text","text":"You can create a note using a special reference node.\n\nAdd a \"+\" before the variable in a dynamic reference node, and it will create that note.","x":-660,"y":-236,"width":354,"heht":180},{"id":"7a8aaacc8a5f8e49","type":"text","text":"This feature should play nicely with other plugins like templater.","x":-635,"y":0,"width":329,"hght":72},{"id":"f3c97367ffc6cce1","type":"text","text":"You can define where the new note will be created using an arrow that starts with \"/\".\n\nIf it's a valid path, then the note will be created there.","x":-700,"y":310,"width":342,"heht":180},{"id":"dec1b7beb803bffa","type":"text","text":"This example will create a new note in this folder.","x":-608,"y":575,"width":250,"hght":60},{"id":"4c6e2bf4a9959f15","type":"text","text":"Write an overly apologetic email about how we're out of altoids","x":85,"y":280,"width":292,"height":100,"cor":"4"},{"id":"6b9ee922dd00451b","type":"text","text":"{{+@title}}","x":-40,"y":449,"width":250,"height":60,"cor":"6"},{"id":"8372acb7e244fb15","type":"text","text":"Subject: A Very Sincere (and Very Sorry) Apology — We’re Out of Altoids\n\nHi everyone,\n\nI am truly, deeply, profoundly sorry to be the bearer of such devastating news: we are out of Altoids. I realize this is not a small thing. I understand how much you count on that unmistakable snap of metal and the bracing peppermint that has seen you through long meetings, awkward elevator rides, and coffee-breath emergencies. For that void in your oral hygiene ritual, I am mortified.\n\nI can only offer my sincerest apologies for not anticipating the surge in demand. The shelves were full this morning and by mid-afternoon they were, regrettably, bare. I should have foreseen the lunchtime mint migration and the late-afternoon mint emergency protocol. I should have done better. I failed you. Please accept my heartfelt apology.\n\nI know apologies are just words, and you deserve action. Here’s what I’m doing right now to make this right:\n- Ordering a fresh stash of Altoids for expedited delivery — expected arrival: [insert ETA if you want to customize]. I’ll personally make sure they arrive and are placed where they belong.\n- In the meantime, I’ve stocked up on alternatives (peppermint gum, breath spray, and other mints) and they’re available in the pantry at [location]. They are not Altoids, and I recognize that is a huge distinction.\n- If you rely on Altoids for a specific reason (presentation breath, post-lunch confidence, life rituals), tell me and I will try to prioritize accordingly.\n\nI am embarrassed and humbled by this oversight. If you would prefer another solution — I can reimburse you for a personal Altoids purchase, bring a tin to your desk, or deputize someone to smuggle them in from the nearest store — I will do it. Your preference matters; please reply with what would help most.\n\nAgain, I am so sorry for the inconvenience, the disappointment, and any faint whiffs of indignation this may have caused. I will be making it my personal mission to restore Altoid equilibrium as swiftly as possible.\n\nThank you for your understanding (and for not staging a mint mutiny). I deeply appreciate your patience.\n\nWith abject apologies and renewed mint vigilance,\n\n[Your Name]","x":-64,"y":575,"width":299,"height":183,"cor":"6"},{"id":"0f4591137e166313","type":"text","text":"No more Altoids","x":-117,"y":280,"width":180,"height":60,"cor":"6"},{"id":"b0608205e7a748f6","type":"text","text":"/Cannoli College/4. Vault interaction","x":-306,"y":350,"width":250,"height":60,"cor":"6"},{"id":"205da096e98072fd","type":"text","text":"A whimsical word","x":-43,"y":860,"width":180,"height":60,"cor":"6"},{"id":"e873b05b9fe76012","type":"text","text":"What is Abracadabra?","x":159,"y":860,"width":292,"height":100,"cor":"4"},{"id":"a8e40f361a987d0a","type":"text","text":"/Cannoli College/A New Whisper/","x":-232,"y":930,"width":250,"height":99,"cor":"6"},{"id":"aff7357fe7bdc922","type":"text","text":"{{++@title}}","x":34,"y":1029,"width":250,"height":60,"cor":"6"},{"id":"a11a624640d6b990","type":"text","text":"\"Abracadabra\" is a traditional magic word — an incantation historically used in rituals, amulets, and later by stage magicians. Pronounced roughly \"ah-BRAH-kah-DAH-brah,\" it has a long and uncertain history.\n\nKey points:\n- Earliest known use: a 2nd–3rd century Roman medical text (Serenus Sammonicus) recommends writing the word in a diminishing triangular pattern on an amulet to cure fever or disease.\n- Etymology: uncertain. Popular theories link it to Aramaic phrases meaning \"I will create as I speak,\" to the Gnostic word \"abraxas,\" or to other Semitic or Greek roots, but no single origin is universally accepted.\n- Historical use: medieval and Renaissance charm-makers used it to ward off illness and evil; it appeared on talismans and in folk-magic traditions.\n- Modern use: from the 19th century onward it became a stock phrase of stage magic (a playful verbal cue when producing an effect). It also appears widely in literature, music, film, and occult systems (e.g., Aleister Crowley’s variant \"abracadabra\" / \"abrahadabra\").\n\nIn everyday speech now it’s mostly a whimsical shorthand for making something happen quickly or mysteriously.","x":10,"y":1155,"width":299,"height":183,"cor":"6"},{"id":"4232d8ccb9f718fe","type":"text","text":"You can also define new paths that do not exist in the vault, and create them using \"++\" sign before the note reference.\nJust make sure you define a path that does Not exist already.\n\nIf it's a valid path, then the note will be created there.","x":-626,"y":840,"width":342,"heht":230},{"id":"4c4ed9b59233a2b2","type":"text","text":"This example will create a new note in a new folder \"A New Whisper\" in this folder.","x":-560,"y":1102,"width":250,"height":145}],"edges":[{"id":"87857bf3a2254dec","fromNode":"375c5de56f45d5e1","fromSide":"bottom","toNode":"fc94ad73861dd0b4","toSide":"top","label":"articleName"},{"id":"a49c245f203702e6","fromNode":"679af4d2d1190b6b","fromSide":"bottom","toNode":"fc94ad73861dd0b4","toSide":"top"},{"id":"283a21bf831d34da","fromNode":"fc94ad73861dd0b4","fromSide":"bottom","toNode":"bd60374fe51f025d","toSide":"top"},{"id":"c0aea91c093cd031","fromNode":"6b9ee922dd00451b","fromSide":"bottom","toNode":"8372acb7e244fb15","toSide":"top"},{"id":"7aca371238d9f008","fromNode":"0f4591137e166313","fromSide":"bottom","toNode":"6b9ee922dd00451b","toSide":"top","label":"title"},{"id":"f2ab13710488acaa","fromNode":"4c6e2bf4a9959f15","fromSide":"bottom","toNode":"6b9ee922dd00451b","toSide":"top"},{"id":"f9e1ee261742cf86","fromNode":"b0608205e7a748f6","fromSide":"bottom","toNode":"6b9ee922dd00451b","toSide":"left","label":"/"},{"id":"740c6877dc2ac572","fromNode":"e873b05b9fe76012","fromSide":"bottom","toNode":"aff7357fe7bdc922","toSide":"top"},{"id":"781e5311f98bb14d","fromNode":"aff7357fe7bdc922","fromSide":"bottom","toNode":"a11a624640d6b990","toSide":"top"},{"id":"de929e195b09cfd9","fromNode":"205da096e98072fd","fromSide":"bottom","toNode":"aff7357fe7bdc922","toSide":"top","label":"title"},{"id":"11902fe6beaaaaf8","fromNode":"a8e40f361a987d0a","fromSide":"bottom","toNode":"aff7357fe7bdc922","toSide":"left","label":"/"}],"metadata":{"version":"1.0-1.0","frontmatter":{}}}
Loading