Thanks for your help and kits. I think the code below gets the job done. This is the first time I’ve written Javascript code. So it is neither good nor complete, but it works for my use case.
For all the others stumbling across this thread:
Use case is for people who can’t use plugins because they rely heavy on working with mobile devices.
Prerequisites:
- kits up and running
- A page in your graph with the name InsertMeeting and the javascript code below.
- A macro which you name like you want and calls the insertmeeting function
:my-meeting "<div class='kit' data-kit='insertmeeting'>$1</div>"
Besides the subject of the meeting is every other parameter optional given we have a macro named my-meeting then the intended call is
{{my-meeting Topic <%today%>; Organizer; Project; Tag}}
However, you can call it like this:
{{my-meeting Topic <%today%>}}
Or omitting the date like this:
{{my-meeting Topic}}
This gives you an empty header with a highlighted topic.
If you want to omit eg. the organizer you have to write:
{{my-meeting Topic <%today%>;; Project; Tag}}
Important: If you want to have multiple Tags, Organizers or Projects you have to separate them with a .
(dot followed by a whitespace).
The following code will replace them with a comma. Background is that a comma is interpreted by the macro engine.
Example:
{{my-meeting Topic <%today%>; Organizer1. Organizer2; Project1. Project2; Tag1. Tag2. Tag3}}
The resulting meeting looks like this:
// This is helper function to create a meeting by macro without a Template.
// It is based on the "kits" implementation
// https://discuss.logseq.com/t/edit-and-run-javascript-code-inside-logseq-itself/20763
// by mentaloid https://discuss.logseq.com/u/mentaloid
//
// Use case is for people who can't use plugins because they rely heavy on working with mobile devices.
// Besides the subject of the meeting is every other parameter optional
// given we have a macro named my-meeting then the intended call is
// {{my-meeting Topic <%today%>; Organizer; Project; Tag}}
//
// However, you can call it like this:
//
// {{my-meeting Topic <%today%>}}
//
// Or omitting the date like this:
//
// {{my-meeting Topic}}
//
// This gives you an empty header with a highlighted topic.
//
// If you want to omit eg. the organizer you have to write:
//
// {{my-meeting Topic <%today%>;; Project; Tag}}
//
// Important: If you want to have multiple Tags, Organizers or Projects you have to separate
// them with a `. ` (dot followed by a whitespace).
// The following code will replace them with a comma. Background is that a comma is interpreted
// by the macro engine.
// Example:
//
// {{my-meeting Topic <%today%>; Organizer1. Organizer2; Project1. Project2; Tag1. Tag2. Tag3}}
logseq.kits.setStatic(function insertmeeting(div){
console.info("function insertmeeting called");
const debug = false;
const blockId = div.closest(".ls-block").getAttribute("blockid");
const content = logseq.api.get_block(blockId).content;
const macroStart = content.indexOf(`{{` + div.closest(".macro").dataset.macroName);
const macroEnd = content.indexOf(`}}`, macroStart) + 2;
const rawData = content.slice(0, macroStart) + div.innerHTML + content.slice(macroEnd);
const header = {
subject: `Meeting subject`,
subject_color: `background-color:: yellow`,
organizer: `organizer:: `,
project: `project:: `,
tag: `tag:: `,
collapsed: `collapsed:: false`
};
const meetingItems = {
participants: `Participants`,
agenda: `Agenda`,
discussion: `Discussion`,
tasks: `Tasks`,
projectNotes: `related notes of same project`,
projectQuery: "",
bodyheader_color: `background-color:: red`
};
//
if (debug){
console.log("insertmeeting: split data");
console.log(`Macro Start: ` + macroStart);
console.log(`Macro End: ` + macroEnd);
console.log(`content: ` + content);
console.log(`innerHTML: ` + div.innerHTML);
console.log(`innerText: ` + div.innerText);
console.log(`textContent: ` + div.textContent);
console.log(`RawData: ` + rawData);
}
//Build up the meeting header block
const words = rawData.split(/;/);
if (debug){
words.forEach(myArrayConsole);
}
// as comma `,` is used in macros we need a different delimiter
// in our case we use point with a whitespace `. `
// these delimiters have to be replaced for the header with `, `
const search = '. ';
const replace = ', ';
let headerBlock = "";
let project = "";
// In this for loop we build the header block
// besides the subject of the meeting every other parameter is optional
// given we have a macro named my-meeting then the intended call is
// {{my-meeting Topic <%today%>; Organizer; Project; Tag1. Tag2. Tag3}}
// however, you can call it like this:
// {{my-meeting Topic <%today%>}} or omitting the date like this {{my-meeting Topic}}
for (let index = 0; index <= 3; index++) {
switch(index){
case 0:
if (words[index]){
header.subject = words[index];
}
if (debug){
console.log("Subject= " + header.subject);
}
break;
case 1:
if (words[index]){
header.organizer += words[index].replaceAll(search, replace);
}
if (debug){
console.log("Organizer= " + header.organizer);
}
break;
case 2:
if (words[index]){
project += words[index].replaceAll(search, replace);
} else {
project = `t.b.d`;
}
header.project += project;
if (debug){
console.log("Project= " + header.project);
}
break;
case 3:
if (words[index]){
header.tag += words[index].replaceAll(search, replace);
}
if (debug){
console.log("Tag= " + header.tag);
}
break;
default:
console.error("header array index mismatch");
}
}
// here we build our meeting header
headerBlock += header.subject + `\n`;
headerBlock += header.subject_color + `\n`;
headerBlock += header.organizer + `\n`;
headerBlock += header.project + `\n`;
headerBlock += header.tag + `\n`;
headerBlock += header.collapsed + `\n`;
console.info("Update Header Block");
// here the header block is updated and the original macro is replaced
logseq.api.update_block(blockId, headerBlock);
meetingItems.projectQuery += `{{query (and (property :project` + `"` + project + `"` + `) (not (page Templates)))}}`;
myBlockInsert(meetingItems.participants + `\n` + meetingItems.bodyheader_color );
myBlockInsert(meetingItems.agenda + `\n` + meetingItems.bodyheader_color );
myBlockInsert(meetingItems.discussion + `\n` + meetingItems.bodyheader_color );
myBlockInsert(meetingItems.tasks + `\n` + meetingItems.bodyheader_color );
myBlockInsert(meetingItems.projectNotes + `\n`);
myBlockInsert(meetingItems.projectQuery + `\n`);
function myBlockInsert(item) {
if (debug){
console.log(item);
}
logseq.api.insert_block(blockId, item, {focus: true, before: false, sibling: false});
return;
}
function myArrayConsole(item) {
console.log("myArrayConsole");
console.log(item);
return;
}
});