71 lines
2.3 KiB
Nim
71 lines
2.3 KiB
Nim
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
|
# SPDX-License-Identifier: Unlicense
|
|
|
|
import preserves, syndicate
|
|
import ../schema/[assertions, config]
|
|
|
|
{.passC: staticExec("pkg-config --cflags libxslt").}
|
|
{.passL: staticExec("pkg-config --libs libxslt").}
|
|
|
|
{.pragma: libxslt, header: "libxslt/xslt.h", importc.}
|
|
|
|
type
|
|
xmlDocPtr {.libxslt.} = distinct pointer
|
|
xsltStylesheetPtr {.libxslt.} = distinct pointer
|
|
|
|
proc xmlParseFile(filename: cstring): xmlDocPtr {.libxslt.}
|
|
proc xmlFreeDoc(p: xmlDocPtr) {.libxslt.}
|
|
|
|
proc xsltParseStylesheetFile(filename: cstring): xsltStylesheetPtr {.libxslt.}
|
|
|
|
proc xsltApplyStylesheet(
|
|
style: xsltStylesheetPtr, doc: xmlDocPtr, params: cstringArray): xmlDocPtr {.libxslt.}
|
|
|
|
proc xsltFreeStylesheet(style: xsltStylesheetPtr) {.libxslt.}
|
|
|
|
proc xsltSaveResultToString(txt: ptr pointer; len: ptr cint; res: xmlDocPtr; style: xsltStylesheetPtr): cint {.libxslt.}
|
|
|
|
proc c_free*(p: pointer) {.importc: "free", header: "<stdlib.h>".}
|
|
|
|
proc xsltSaveResultToString(res: xmlDocPtr; style: xsltStylesheetPtr): string =
|
|
var
|
|
txt: pointer
|
|
len: cint
|
|
if xsltSaveResultToString(addr txt, addr len, res, style) < 0:
|
|
raise newException(CatchableError, "xsltSaveResultToString failed")
|
|
if len > 0:
|
|
result = newString(int len)
|
|
copyMem(result[0].addr, txt, len)
|
|
c_free(txt)
|
|
|
|
proc initLibXml =
|
|
discard
|
|
|
|
proc spawnXsltActor*(turn: var Turn; root: Cap): Actor {.discardable.} =
|
|
spawn("xslt", turn) do (turn: var Turn):
|
|
initLibXml()
|
|
during(turn, root, ?:XsltArguments) do (ds: Cap):
|
|
let sheetsPat = ?Observe(pattern: !XsltTransform) ?? {0: grab(), 1: grab()}
|
|
during(turn, ds, sheetsPat) do (stylesheet: Literal[string], input: Literal[string]):
|
|
let
|
|
cur = xsltParseStylesheetFile(stylesheet.value)
|
|
doc = xmlParseFile(input.value)
|
|
params = allocCStringArray([])
|
|
res = xsltApplyStylesheet(cur, doc, params)
|
|
output = xsltSaveResultToString(res, cur)
|
|
xmlFreeDoc(res)
|
|
xmlFreeDoc(doc)
|
|
deallocCStringArray(params)
|
|
xsltFreeStylesheet(cur)
|
|
publish(turn, ds, XsltTransform(
|
|
stylesheet: stylesheet.value,
|
|
input: input.value,
|
|
output: output,
|
|
))
|
|
|
|
when isMainModule:
|
|
import syndicate/relays
|
|
runActor("main") do (turn: var Turn; root: Cap):
|
|
connectStdio(turn, root)
|
|
spawnXsltActor(turn, root)
|