eq directive
This commit is contained in:
38
render.ts
38
render.ts
@@ -1,9 +1,23 @@
|
||||
import { readdirSync, statSync, readFileSync, mkdirSync, writeFileSync } from "node:fs"
|
||||
import { readdirSync, statSync, readFileSync, mkdirSync, writeFileSync, rmSync } from "node:fs"
|
||||
import { join } from "node:path"
|
||||
|
||||
const IF_PATH_RE = /^<@if\(context\.(.+?)\)>(.*)$/
|
||||
const IF_PATH_RE = /^<@if\((.+?)\)>(.*)$/
|
||||
const VAR_RE = /<@var\(context\.(.+?)(?::(\w+))?\)>/g
|
||||
const DIRECTIVE_RE = /<@(if|elseif|else|endif)(?:\(context\.(.+?)\))?>/g
|
||||
const DIRECTIVE_RE = /<@(if|elseif|else|endif)(?:\((.+?)\))?>/g
|
||||
const EQ_RE = /^eq\(context\.(.+?),\s*"(.*)"\)$/
|
||||
const PATH_RE = /^context\.(.+)$/
|
||||
|
||||
function evalCondition(expr: string, context: Record<string, unknown>): boolean {
|
||||
const eqMatch = expr.match(EQ_RE)
|
||||
if (eqMatch) {
|
||||
return resolve(context, eqMatch[1]!) === eqMatch[2]
|
||||
}
|
||||
const pathMatch = expr.match(PATH_RE)
|
||||
if (pathMatch) {
|
||||
return !!resolve(context, pathMatch[1]!)
|
||||
}
|
||||
throw new Error(`Invalid condition expression: ${expr}`)
|
||||
}
|
||||
|
||||
function resolve(context: Record<string, unknown>, path: string): unknown {
|
||||
const segments = path.split(".")
|
||||
@@ -36,7 +50,7 @@ function processIfBlocks(content: string, context: Record<string, unknown>): str
|
||||
|
||||
if (directive === "if") {
|
||||
if (isEmitting()) result += content.slice(pos, match.index)
|
||||
const truthy = !!resolve(context, condPath!)
|
||||
const truthy = evalCondition(condPath!, context)
|
||||
stack.push({ matched: truthy, active: truthy })
|
||||
pos = re.lastIndex
|
||||
} else if (directive === "elseif") {
|
||||
@@ -48,7 +62,7 @@ function processIfBlocks(content: string, context: Record<string, unknown>): str
|
||||
// A previous branch already matched — skip this one
|
||||
top.active = false
|
||||
} else {
|
||||
const truthy = !!resolve(context, condPath!)
|
||||
const truthy = evalCondition(condPath!, context)
|
||||
top.matched = truthy
|
||||
top.active = truthy
|
||||
}
|
||||
@@ -87,6 +101,15 @@ function renderDir(
|
||||
srcDir: string,
|
||||
destDir: string,
|
||||
context: Record<string, unknown>,
|
||||
) {
|
||||
rmSync(destDir, { recursive: true, force: true })
|
||||
renderDirInner(srcDir, destDir, context)
|
||||
}
|
||||
|
||||
function renderDirInner(
|
||||
srcDir: string,
|
||||
destDir: string,
|
||||
context: Record<string, unknown>,
|
||||
) {
|
||||
mkdirSync(destDir, { recursive: true })
|
||||
const entries = readdirSync(srcDir).sort()
|
||||
@@ -99,8 +122,7 @@ function renderDir(
|
||||
const ifMatch = entry.match(IF_PATH_RE)
|
||||
let outputName = entry
|
||||
if (ifMatch) {
|
||||
const conditionPath = ifMatch[1]!
|
||||
if (!resolve(context, conditionPath)) continue
|
||||
if (!evalCondition(ifMatch[1]!, context)) continue
|
||||
outputName = ifMatch[2]!
|
||||
}
|
||||
|
||||
@@ -111,7 +133,7 @@ function renderDir(
|
||||
|
||||
const destPath = join(destDir, outputName)
|
||||
if (stat.isDirectory()) {
|
||||
renderDir(srcPath, destPath, context)
|
||||
renderDirInner(srcPath, destPath, context)
|
||||
} else {
|
||||
mkdirSync(destDir, { recursive: true })
|
||||
const content = readFileSync(srcPath, "utf-8")
|
||||
|
||||
Reference in New Issue
Block a user