Skip to content

Commit

Permalink
feat: replace only renderer macro during template rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
stdword committed Mar 21, 2023
1 parent 3873243 commit 52b074b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 14 deletions.
34 changes: 21 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { renderTemplateInBlock } from './logic'
import { RenderError, StateError, StateMessage } from './errors'
import { indexOfNth, lockOn, p, sleep } from './utils/other'
import { unquote } from './utils/parsing'
import { cleanMacroArg, insertContent, isCommand, parseReference, PropertiesUtils } from './utils/logseq'
import { cleanMacroArg, insertContent, parseReference, PropertiesUtils, RendererMacro } from './utils/logseq'

import { dayjs } from './context'
import { LogseqDayjsState } from './utils/dayjs_logseq_plugin'
Expand Down Expand Up @@ -34,20 +34,23 @@ async function init() {
// Logseq reads config setting `preferredDateFormat` with some delay
// So we need to wait some time
setTimeout(onAppSettingsChanged, 100)
}
}

async function main() {
init()

const commandName = 'template'
const commandLabel = 'Full House → Insert template'
const commandContent = `{{renderer :${commandName}, TEMPLATE NAME, (optional) page reference}}`
const commandLabel = 'Insert 🏛template'
const command = RendererMacro.command('template')
const commandGuide = command
.arg('TEMPLATE NAME')
.arg('(optional) page reference')
.toString()

logseq.App.registerCommandPalette(
{ key: 'insert-template', label: commandLabel }, async (e) => {
const inserted = await insertContent(commandContent, { positionOnArg: 1 })
const inserted = await insertContent(commandGuide, { positionOnArg: 1 })
if (!inserted) {
// TODO: ask UI to insert template to the end of current page
// TODO?: ask UI to insert template to the end of current page
await logseq.UI.showMsg(
'Start editing block or select one to insert template in it',
'warning',
Expand All @@ -58,28 +61,33 @@ async function main() {
})

logseq.Editor.registerSlashCommand(commandLabel, async (e) => {
await insertContent(commandContent, { positionOnArg: 1 })
// here user always in editing mode, so no need to check insertion
await insertContent(commandGuide, { positionOnArg: 1 })
})

logseq.Editor.registerBlockContextMenuItem(
'Use as the template', async (e) => {
'Copy as 🏛template', async (e) => {
const templateName = await logseq.Editor.getBlockProperty(
e.uuid, PropertiesUtils.templateProperty)
const templateRef = templateName ? templateName : `((${e.uuid}))`
const textToCopy = `{{renderer :${commandName}, ${templateRef}}}`
const textToCopy = command.arg(templateRef).toString()

window.focus() // need to make an interactions with clipboard
await navigator.clipboard.writeText(textToCopy)

await logseq.UI.showMsg('Code copied to clipboard',
await logseq.UI.showMsg('Copied to clipboard',
'success', {timeout: 5000})
})

logseq.App.onMacroRendererSlotted(async ({ slot, payload }) => {
let [ type_, templateRef_, contextPageRef_, ...args ] = payload.arguments
if (!isCommand(type_, commandName))
const rawCommand = RendererMacro.command(type_)
if (rawCommand.name !== command.name)
return

const raw = rawCommand.arg(templateRef_).arg(contextPageRef_).args(args)
console.debug(p``, raw.toString())

templateRef_ = cleanMacroArg(templateRef_)
contextPageRef_ = cleanMacroArg(contextPageRef_)

Expand Down Expand Up @@ -107,7 +115,7 @@ async function main() {
)

try {
await renderTemplateInBlock(payload.uuid, templateRef, includingParent, contextPageRef)
await renderTemplateInBlock(payload.uuid, templateRef, includingParent, contextPageRef, raw)
} catch (error) {
if (error instanceof StateError)
await logseq.UI.showMsg(error.message, 'error', {timeout: 5000})
Expand Down
3 changes: 2 additions & 1 deletion src/logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IBatchBlock, BlockEntity, PageEntity } from '@logseq/libs/dist/LSPlugin

import { Template, InlineTemplate } from './template'
import { PageContext, BlockContext, getConfigContext, ILogseqContext } from './context'
import { p, IBlockNode, lockOn, sleep, LogseqReference, getPage, getBlock, LogseqReferenceAccessType, getPageFirstBlock, PropertiesUtils } from './utils'
import { p, IBlockNode, lockOn, sleep, LogseqReference, getPage, getBlock, LogseqReferenceAccessType, getPageFirstBlock, PropertiesUtils, RendererMacro } from './utils'
import { RenderError, StateError, StateMessage } from './errors'


Expand Down Expand Up @@ -44,6 +44,7 @@ async (
templateRef: LogseqReference,
includingParent: boolean | undefined,
pageRef: LogseqReference | null,
rawCode: RendererMacro,
) => {
console.debug(p`Render to block`, {uuid})

Expand Down
51 changes: 51 additions & 0 deletions src/utils/logseq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,54 @@ export class PropertiesUtils {
return {values, refs}
}
}


export class RendererMacro {
public name: string
public arguments: string[]

static command(name: string | null) {
return new RendererMacro(name)
}

constructor(name: string | null) {
name = name ?? ''
name = name.trim()
if (name.startsWith(':'))
name = name.slice(1)
name = name.toLowerCase().trim()

this.name = name
this.arguments = []
}
clone() {
return Object.assign(
Object.create(Object.getPrototypeOf(this)),
structuredClone(this),
)
}
arg(value: string) {
value = value ?? ''
if (!value)
return this

const obj = this.clone()
obj.arguments.push(value)
return obj
}
args(values: string[]) {
values = values ?? []
if (!values.length)
return this

const obj = this.clone()
obj.arguments.push(...values)
return obj
}
toString({useColon = true} = {}) {
return '{{renderer ' +
(useColon ? ':' : '') +
[this.name].concat(this.arguments).map(a => a.toString()).join(', ') +
'}}'
}
}

0 comments on commit 52b074b

Please sign in to comment.