Skip to content

Commit

Permalink
feat(engine): autodetecting of syntax style
Browse files Browse the repository at this point in the history
  • Loading branch information
stdword committed Jul 28, 2023
1 parent a718df6 commit ef6d611
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 4 deletions.
88 changes: 87 additions & 1 deletion src/extensions/customized_eta.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Eta } from 'eta'

import { dayjs } from '../context'
import { IBlockNode, walkBlockTree } from '../utils'


class CustomizedEta extends Eta {
Expand All @@ -14,7 +15,51 @@ class CustomizedEta extends Eta {
}
}

export const eta = new CustomizedEta({
const etaForCompatibility = new Eta({
useWith: true, /** Make data available on the global object instead of `varName` */
varName: 'fh', /** Name of the data object. Default "it" */
// functionHeader: 'const c = fh.c', /** Raw JS code inserted in the template function. Useful for declaring global variables */

autoEscape: false, /** Automatically XML-escape interpolations */
// escapeFunction: eta.XMLEscape,

autoFilter: true, /** Apply a `filterFunction` to every interpolation or raw interpolation */
filterFunction: function (value: any): string {
if (value instanceof dayjs)
// @ts-expect-error
return value.toPage()

if (typeof value === 'string')
return value

return String(value)
},

/** Configure automatic whitespace trimming: left & right */
/** values:
* "nl" - trim new lines
* "slurp" - trim whitespaces
* false — no trimming
* */
autoTrim: [false, false],

tags: ['``{', '}``'],
parse: {
exec: '!',
interpolate: '',
raw: '~',
},

plugins: [], // [{processFnString: null, processAST: null, processTemplate: null}],
// TODO: https://github.com/nebrelbug/eta_plugin_mixins

cache: false, /** cache templates if `name` or `filename` is passed */
cacheFilepaths: false, /** Holds cache of resolved filepaths */
views: '', /** Directory that contains templates */
debug: false, /** Pretty-format error messages (adds runtime penalties) */
})

const eta = new CustomizedEta({
useWith: true, /** Make data available on the global object instead of `varName` */
varName: 'fh', /** Name of the data object. Default "it" */
// functionHeader: 'const c = fh.c', /** Raw JS code inserted in the template function. Useful for declaring global variables */
Expand Down Expand Up @@ -82,6 +127,47 @@ export const eta = new CustomizedEta({
debug: false, /** Pretty-format error messages (adds runtime penalties) */
})

export async function isOldSyntax(block: IBlockNode) {
let useOldSyntax = false

const openTag_ = '``{'
const [ openTag, closeTag ] = [ escapeRegExp(openTag_), escapeRegExp('}``') ]
const prefix = escapeRegExp('!')
const openTagWithPrefixRegexp = new RegExp(openTag + '(-|_)?\\s*(' + prefix + ')\\s', 'g')
const statementsSignsRegexp = new RegExp(openTag + '(?<code>.*)(?<!.*\\b(=|var|let|const|return|if|switch|for|function|try|class|while)\\b.*)' + closeTag, 'gs')
const captureInsideRegexp = new RegExp(openTag + '(?<code>.*)' + closeTag, 'gs')


await walkBlockTree(block, async (b, lvl) => {
if (b.content.indexOf(openTag_) === -1)
return

let m = openTagWithPrefixRegexp.exec(b.content)
if (m) {
useOldSyntax = true
return
}

m = statementsSignsRegexp.exec(b.content)
if (m) {
m = captureInsideRegexp.exec(b.content)
// has no single «=»
if (!(m && m.groups && (m.groups.code.indexOf('=') !== -1 && m.groups.code.indexOf('==') === -1)))
useOldSyntax = true
}
})

return useOldSyntax
}

export class RenderingSyntax {
static latest(): Eta {
return eta
}
static async autoSelect(block: IBlockNode): Promise<Eta> {
return (await isOldSyntax(block)) ? etaForCompatibility : eta
}
}

function compileBody(buff) {
// @ts-expect-error
Expand Down
8 changes: 5 additions & 3 deletions src/template.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '@logseq/libs'
import { IBatchBlock, BlockEntity } from '@logseq/libs/dist/LSPlugin.user'

import { eta } from './extensions/customized_eta'
import { RenderingSyntax } from './extensions/customized_eta'
import { ILogseqContext, BlockContext, Context, dayjs, ArgsContext } from './context'
import { RenderError } from './errors'
import { getTemplateTagsContext } from './tags'
Expand Down Expand Up @@ -151,6 +151,7 @@ export class Template implements ITemplate {
c: contextObj,
}

const renderrer = await RenderingSyntax.autoSelect(this.block as IBlockNode)
return await walkBlockTree(this.block as IBlockNode, async (b, lvl) => {
if (lvl === 0 && !this.includingParent)
return ''
Expand All @@ -161,7 +162,7 @@ export class Template implements ITemplate {
page: context.block.page,
level: lvl,
})
return eta.renderString(b.content, renderContext)
return renderrer.renderString(b.content, renderContext)
})
}
getArgProperties() {
Expand Down Expand Up @@ -202,9 +203,10 @@ export class InlineTemplate implements ITemplate {
c: contextObj,
}

const renderrer = RenderingSyntax.latest()
const body = '`` ' + this.body + ' ``'
return {
content: eta.renderString(body, renderContext),
content: renderrer.renderString(body, renderContext),
children: [],
}
}
Expand Down

0 comments on commit ef6d611

Please sign in to comment.