Skip to content

Commit

Permalink
refactor: move & extract some code
Browse files Browse the repository at this point in the history
  • Loading branch information
stdword committed Feb 11, 2024
1 parent 57008ee commit 555af89
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 80 deletions.
49 changes: 11 additions & 38 deletions src/app.tsx
Expand Up @@ -4,7 +4,10 @@ import { render } from 'preact'

import { LogseqDayjsState } from './extensions/dayjs_logseq_plugin'
import { dayjs } from './context'
import { renderTemplateInBlock, renderTemplateView, renderView } from './logic'
import {
renderTemplateInBlock, renderTemplateView, renderView,
templateMacroStringForBlock, templateMacroStringForPage,
} from './logic'
import {
indexOfNth, lockOn, p, sleep,
cleanMacroArg, parseReference, isEmptyString,
Expand Down Expand Up @@ -270,62 +273,32 @@ async function main() {
function registerBlockContextCopyCommand(label: string, commandName: string) {
logseq.Editor.registerBlockContextMenuItem(
label, async (e) => {
const block = await logseq.Editor.getBlock(e.uuid)
if (!block) {
const macro = await templateMacroStringForBlock(e.uuid)
if (!macro) {
console.debug(p`Assertion error: block should exists`, e.uuid)
return
}

const templateName = PropertiesUtils.getProperty(
block, PropertiesUtils.templateProperty
).text
let templateRef = templateName
if (!templateRef) {
const uuidExisted = PropertiesUtils.hasProperty(block.content, PropertiesUtils.idProperty)
if (!uuidExisted)
logseq.Editor.upsertBlockProperty(e.uuid, PropertiesUtils.idProperty, e.uuid)
templateRef = `((${e.uuid}))`
}

let command = RendererMacro.command(commandName).arg(templateRef)

const templateUsage = PropertiesUtils.getTemplateUsageString(block, {cleanMarkers: true})
if (templateUsage)
command = command.arg(templateUsage, {raw: true})

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

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

function registerPageContextCopyCommand(label: string, commandName: string) {
logseq.App.registerPageMenuItem(
label, async ({ page: pageName }) => {
const pageRefString = `[[${pageName}]]`
const pageRef = parseReference(pageRefString)!
const page = await getPage(pageRef)
if (!page) {
const command = await templateMacroStringForPage(pageName)
if (!command) {
console.debug(p`Assertion error: page should exists`, pageName)
return
}

let command = RendererMacro.command(commandName).arg(pageRefString)

const block = await getPageFirstBlock(pageRef)
if (block) {
const templateUsage = PropertiesUtils.getTemplateUsageString(block, {cleanMarkers: true})
if (templateUsage)
command = command.arg(templateUsage, {raw: true})
}

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

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

Expand Down
45 changes: 45 additions & 0 deletions src/logic.ts
Expand Up @@ -444,3 +444,48 @@ export async function renderView(
const argsContext = ArgsContext.create(template.name, args)
await _renderTemplateView(slot, blockUUID, template, rawCode, argsContext)
}

export async function templateMacroStringForBlock(uuid: string, isView: boolean = false): Promise<string> {
const block = await logseq.Editor.getBlock(uuid)
if (!block)
return ''

const templateName = PropertiesUtils.getProperty(
block, PropertiesUtils.templateProperty
).text
let templateRef = templateName
if (!templateRef) {
const uuidExisted = PropertiesUtils.hasProperty(block.content, PropertiesUtils.idProperty)
if (!uuidExisted)
await logseq.Editor.upsertBlockProperty(uuid, PropertiesUtils.idProperty, uuid)
templateRef = `((${uuid}))`
}

const commandName = isView ? 'template-view' : 'template'
let command = RendererMacro.command(commandName).arg(templateRef)

const templateUsage = Template.getUsageString(block, {cleanMarkers: true})
if (templateUsage)
command = command.arg(templateUsage, {raw: true})

return command.toString()
}
export async function templateMacroStringForPage(name: string, isView: boolean = false): Promise<string> {
const pageRefString = `[[${name}]]`
const pageRef = parseReference(pageRefString)!
const page = await getPage(pageRef)
if (!page)
return ''

const commandName = isView ? 'template-view' : 'template'
let command = RendererMacro.command(commandName).arg(pageRefString)

const block = await getPageFirstBlock(pageRef)
if (block) {
const templateUsage = Template.getUsageString(block, {cleanMarkers: true})
if (templateUsage)
command = command.arg(templateUsage, {raw: true})
}

return command.toString()
}
35 changes: 34 additions & 1 deletion src/template.ts
Expand Up @@ -7,7 +7,7 @@ import { RenderError } from './errors'
import { getTemplateTagsContext } from './tags'
import {
p, IBlockNode, walkBlockTree, coerceToBool, LogseqReferenceAccessType,
PropertiesUtils, Properties
PropertiesUtils, Properties, unquote
} from './utils'


Expand Down Expand Up @@ -51,13 +51,46 @@ export interface ITemplate {
}

export class Template implements ITemplate {
static readonly carriagePositionMarker = '{|}'

public block: BlockEntity
public name: string
public includingParent: boolean
public accessedVia: LogseqReferenceAccessType

private _initialized: boolean

static getUsageString(
block: BlockEntity,
opts: { cleanMarkers?: boolean } = {cleanMarkers: false},
): string {
let usage = PropertiesUtils.getProperty(
block, PropertiesUtils.templateUsageProperty
).text
if (!usage)
return ''

usage = Template.cleanUsageString(usage, { cleanMarkers: opts.cleanMarkers })

return usage
}
static cleanUsageString(
value: string,
opts: { cleanMarkers?: boolean } = {cleanMarkers: false},
) {
// value can be `quoted` or ``double quoted``
value = unquote(value, '``')
value = unquote(value, '``')

if (opts.cleanMarkers) {
// supports only two markers, so left intact any others
value = value.replace(Template.carriagePositionMarker, '')
value = value.replace(Template.carriagePositionMarker, '')
}

return value
}

constructor(
block: BlockEntity, args: {
name?: string,
Expand Down
7 changes: 4 additions & 3 deletions src/ui/insert.tsx
Expand Up @@ -5,6 +5,7 @@ import fuzzysort from 'fuzzysort'

import './insert.css'
import { PropertiesUtils, RendererMacro, setEditingCursorSelection, sleep, unquote } from '../utils'
import { Template } from '../template'


export const isMacOS = navigator.userAgent.toUpperCase().indexOf('MAC') >= 0
Expand Down Expand Up @@ -47,7 +48,7 @@ async function prepareDataLogic(): Promise<Data> {
else if (lowerLabel === 'template')
item.label = 'Template'

item.usage = PropertiesUtils.cleanTemplateUsageString(item.usage, {cleanMarkers: false})
item.usage = Template.cleanUsageString(item.usage, {cleanMarkers: false})

return item
})
Expand Down Expand Up @@ -139,8 +140,8 @@ async function insertLogic(

const selectionPositions = [] as number[]
for (const marker of [
PropertiesUtils.carriagePositionMarker,
PropertiesUtils.carriagePositionMarker,
Template.carriagePositionMarker,
Template.carriagePositionMarker,
]) {
const position = content.indexOf(marker)
if (position !== -1) {
Expand Down
39 changes: 1 addition & 38 deletions src/utils/logseq.ts
Expand Up @@ -376,8 +376,6 @@ export class PropertiesUtils {
static readonly templateUsageProperty = 'template-usage'
static readonly includingParentProperty = 'template-including-parent'

static readonly carriagePositionMarker = '{|}'

static propertyContentFormat = f`\n?^[^\\S]*${'name'}::.*$`
static propertyRestrictedChars = '\\s:;,^@#~"`/|\\(){}[\\]'

Expand All @@ -404,41 +402,6 @@ export class PropertiesUtils {
)
}

static getTemplateUsageString(
block: BlockEntity,
opts: {
cleanMarkers?: boolean
} = {cleanMarkers: false}
): string {
let usage = PropertiesUtils.getProperty(
block, PropertiesUtils.templateUsageProperty
).text
if (!usage)
return ''

usage = PropertiesUtils.cleanTemplateUsageString(usage, { cleanMarkers: opts.cleanMarkers })

return usage
}
static cleanTemplateUsageString(
value: string,
opts: {
cleanMarkers?: boolean
} = {cleanMarkers: false}
) {
// value can be `quoted` or ``double quoted``
value = unquote(value, '``')
value = unquote(value, '``')

if (opts.cleanMarkers) {
// supports only two markers, so left intact any others
value = value.replace(PropertiesUtils.carriagePositionMarker, '')
value = value.replace(PropertiesUtils.carriagePositionMarker, '')
}

return value
}

static getProperty(obj: BlockEntity | PageEntity, name: string): LogseqProperty {
const nameCamelCased = PropertiesUtils.toCamelCase(name)

Expand Down Expand Up @@ -607,7 +570,7 @@ export class Macro {
}

export class RendererMacro extends Macro {
static command(name: string) {
static command(name: string): RendererMacro {
return new RendererMacro(name)
}

Expand Down

0 comments on commit 555af89

Please sign in to comment.