eq directive

This commit is contained in:
Gregor Lohaus
2026-04-15 22:37:13 +02:00
parent 5edb1139b9
commit 0fd19254e9
7 changed files with 74 additions and 129 deletions

View File

@@ -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")