Skip to content

Commit

Permalink
feat(views): support special assets url schema & links to images
Browse files Browse the repository at this point in the history
  • Loading branch information
stdword committed Apr 3, 2023
1 parent d15c817 commit f51b31b
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 17 deletions.
39 changes: 26 additions & 13 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,9 @@ export class ArgsContext extends Context {
public _args: string[]
public _hideUndefinedMode = false

static create(templateRef: LogseqReference, args: string[]) {
const entries: [string, string | boolean][] = [['0', templateRef.original]]
for (let [ index, value ] of Object.entries(args)) {
static parse(args: string[]): [string, string][] {
const entries: [string, string][] = []
for (let [ _, value ] of Object.entries(args)) {
// Check whether it is named arg

// # Strict rules for name of the arg
Expand All @@ -249,6 +249,7 @@ export class ArgsContext extends Context {

// TODO: create a setting to control strictness

let name = ''
if (value.startsWith('::')) {
// special case: user has disabled named-arg parsing
value = value.slice(1)
Expand All @@ -257,17 +258,29 @@ export class ArgsContext extends Context {
const easyRgexp= /^:(\S+)\s*/ui
const match = value.match(easyRgexp)
if (match) {
const [ consumed, name ] = match
let namedValue: string | boolean = value.slice(consumed.length)
if (!namedValue)
namedValue = true
else
namedValue = cleanMacroArg(namedValue, {escape: false, unquote: true})

entries.push([ name, namedValue ])
let consumed: string
[ consumed, name ] = match
value = value.slice(consumed.length)
if (value)
value = cleanMacroArg(value, {escape: false, unquote: true})
}
}

entries.push([ name, value ])
}

return entries
}
static create(templateRef: LogseqReference, args: string[]) {
const entries: [string, string | boolean][] = [['0', templateRef.original]]

for (let [ index, [name, value_] ] of Object.entries(ArgsContext.parse(args))) {
let value: string | boolean = value_
if (name && !value)
value = true

if (name)
entries.push([ name, value ])
entries.push([ (+index + 1).toString(), value ])
entries.push([ `$${+index + 1}`, value ])
}
Expand Down Expand Up @@ -335,7 +348,7 @@ export class ConfigContext extends Context {
)
}

constructor(settings, currentGraph, config, logseq) {
constructor(settings, currentGraph, config, other) {
super()

this.graph = {
Expand Down Expand Up @@ -369,7 +382,7 @@ export class ConfigContext extends Context {
hidden: settings['hidden'],
},
}
this.appVersion = logseq.version
this.appVersion = other.version
this.pluginVersion = logseq.baseInfo.version

this.preferredWorkflow = config.preferredWorkflow as 'now' | 'todo'
Expand Down
78 changes: 74 additions & 4 deletions src/utils/mldoc_ast.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Mldoc } from 'mldoc'
import { ILogseqContext } from '../context'
import { ArgsContext, ILogseqContext } from '../context'
import { cleanMacroArg, resolveAssetsURLProtocol } from './logseq'

import { html, p } from './other'

Expand Down Expand Up @@ -160,6 +161,8 @@ class MldocASTtoHTMLCompiler {
return compiledValue ?? ''
}
case 'Link': {
const meta: string = data.metadata ?? ''

let label = ''
if (data.label && data.label.length) {
const node = data.label[0]
Expand All @@ -176,6 +179,9 @@ class MldocASTtoHTMLCompiler {
switch (type)
{ case 'Search': {
const term = url ?? ''
const [ protocol, link ] = this.resolveAssetsLink('', term)
if (protocol)
return this.createImageLink(protocol, link, label, meta)
return this.createPageRef(term, label)
} case 'Page_ref': {
const name = url ?? ''
Expand All @@ -184,8 +190,14 @@ class MldocASTtoHTMLCompiler {
const uuid = url ?? ''
return await this.createBlockRef(uuid, label)
} case 'Complex': {
const { protocol, link } = url ?? {}
return this.createExternalLink(protocol, link, label)
console.log({data});
let protocol = (url ?? {}).protocol ?? ''
let link = (url ?? {}).link ?? '';
[ protocol, link ] = this.resolveAssetsLink(protocol, link)
const inclusion = data.full_text.startsWith('!')
if (inclusion)
return this.createImageLink(protocol, link, label, meta)
return this.createLink(protocol, link, label)
}
default:
console.warn(p`Unknown link type:`, {type, url})
Expand All @@ -199,6 +211,30 @@ class MldocASTtoHTMLCompiler {
})).join('')
}

resolveAssetsLink(protocol: string, link: string) {
let needExpand = true
if (link.startsWith('/')) {
protocol = 'assets'
needExpand = false
}

const prefix = '../assets'
if (link.startsWith(prefix)) {
link = link.slice(prefix.length)
protocol = 'assets'
}

if (protocol === 'assets') {
protocol = 'file'
if (needExpand)
// @ts-expect-error
link = top!.LSPlugin.pluginHelpers.path.join(
this.context.config.graph.path, 'assets', link)
}

return [protocol, link]
}

async createBlockRef(uuid: string, label: string): Promise<string> {
const uuidLabel = `((${uuid}))`
const block = await logseq.Editor.getBlock(uuid)
Expand Down Expand Up @@ -261,7 +297,7 @@ class MldocASTtoHTMLCompiler {
</span>
`
}
createExternalLink(protocol: string, link: string, label: string): string {
createLink(protocol: string, link: string, label: string): string {
label = label.trim()
if (protocol)
link = `${protocol}://${link}`
Expand All @@ -275,4 +311,38 @@ class MldocASTtoHTMLCompiler {
>${label}</a>
`
}
createImageLink(protocol: string, link: string, label: string, meta: string): string {
if (meta.startsWith('{'))
meta = meta.slice(1)
if (meta.endsWith('}'))
meta = meta.slice(0, -1)

const argsMeta_ = meta.split(',').map(a => cleanMacroArg(a, {escape: false, unquote: true}))
const argsMeta = ArgsContext.parse(argsMeta_)
const { width, height } = Object.fromEntries(argsMeta)

label = label.trim()
const link_ = link
if (protocol)
link = `${protocol}://${link}`

return html`
<div class="asset-container">
<img class="rounded-sm relative" loading="lazy" src="${link}" ${label ? `title="${label}"` : ''} ${height ? `height="${height}"` : ''} ${width ? `width="${width}"` : ''} />
<div class="asset-overlay"></div>
<div class="asset-action-bar" aria-hidden="true">
<div class="flex"></div>
<a class="asset-action-btn" href="${link}" title="${link}" data-on-click="" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-external-link" width="18" height="18" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M11 7h-5a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-5"></path>
<path d="M10 14l10 -10"></path>
<path d="M15 4l5 0l0 5"></path>
</svg>
</a>
</div>
</div>
</div>
`
}
}

0 comments on commit f51b31b

Please sign in to comment.