Compare commits
2 commits
53f6c36c77
...
2cc899e9c6
Author | SHA1 | Date | |
---|---|---|---|
2cc899e9c6 | |||
310347304d |
2 changed files with 86 additions and 25 deletions
|
@ -2,6 +2,8 @@ task build, "build":
|
|||
switch("outdir", "bin")
|
||||
setCommand "c", "src/typstgen.nim"
|
||||
|
||||
task dev, "dev":
|
||||
exec "nimble setup -l"
|
||||
|
||||
# begin Nimble config (version 2)
|
||||
--noNimblePath
|
||||
|
|
109
src/typstgen.nim
109
src/typstgen.nim
|
@ -1,39 +1,90 @@
|
|||
import std/[streams, tables, strutils, os]
|
||||
import std/[os, sequtils, streams, strutils, tables]
|
||||
import yaml, hwylterm
|
||||
|
||||
|
||||
type
|
||||
Component = Table[string, string]
|
||||
TypstTemplate = object
|
||||
keys: seq[string]
|
||||
src: string
|
||||
Config = object
|
||||
components {.defaultVal: @[]}: seq[Table[string, string]]
|
||||
templates {.defaultVal: initTable[string, string]()}: Table[string, string]
|
||||
components {.defaultVal: @[]}: seq[Component]
|
||||
templates {.defaultVal: initTable[string, TypstTemplate]()}: Table[string, TypstTemplate]
|
||||
|
||||
func `%`(t: TypstTemplate, a: openArray[string]): string =
|
||||
t.src % a
|
||||
|
||||
proc checkTemplates(templates: Table[string, TypstTemplate]) =
|
||||
## quit if any templates have the same keys
|
||||
var keyTable: Table[string, seq[string]]
|
||||
|
||||
for name, templ in templates.pairs():
|
||||
let k = templ.keys.join(";")
|
||||
if k in keyTable:
|
||||
keyTable[k].add name
|
||||
else:
|
||||
keyTable[k] = @[name]
|
||||
|
||||
for keys, names in keyTable.pairs():
|
||||
if names.len > 1:
|
||||
quit("non-unique key combos in templates: " & names.join(","))
|
||||
|
||||
|
||||
proc typstGen(configPath: string) =
|
||||
proc addDefaultTemplates(c: var Config) =
|
||||
# TODO: more default templates?
|
||||
if "raw" notin c.templates:
|
||||
c.templates["raw"] = TypstTemplate(keys: @["raw"], src: "$raw")
|
||||
|
||||
if "image" notin c.templates:
|
||||
c.templates["image"] = TypstTemplate(keys: @["image"], src: """
|
||||
#figure(
|
||||
image("$image"),
|
||||
caption: [$image]
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
if "figure" notin c.templates:
|
||||
c.templates["figure"] = TypstTemplate(keys: @["image", "caption"], src: """
|
||||
#align(center)[
|
||||
#figure(
|
||||
image("$image"),
|
||||
caption: [
|
||||
$image
|
||||
]
|
||||
)
|
||||
$caption
|
||||
]
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
proc loadConfig(configPath: string): Config =
|
||||
|
||||
var config: Config
|
||||
var s = newFileStream(configPath)
|
||||
load(s, config)
|
||||
s.close()
|
||||
load(s, result)
|
||||
close s
|
||||
|
||||
var output: string
|
||||
addDefaultTemplates result
|
||||
checkTemplates result.templates
|
||||
|
||||
if not config.templates.hasKey("raw"):
|
||||
config.templates["raw"] = "$text"
|
||||
proc getTemplate(c: Config, component: Component): TypstTemplate =
|
||||
let k = component.keys().toSeq()
|
||||
for _, templ in c.templates.pairs():
|
||||
if templ.keys == k:
|
||||
return templ
|
||||
|
||||
quit($bb("[red]error[/] failed to find template for component:\n") & $component)
|
||||
|
||||
func componentToFmtArgs(t: Table[string, string]): seq[string] =
|
||||
for k, v in t.pairs:
|
||||
result.add k
|
||||
result.add v
|
||||
func toFmtArgs(comp: Component): seq[string] =
|
||||
for k, v in comp.pairs: result.add k; result.add v
|
||||
|
||||
for component in config.components:
|
||||
var kind = "figure"
|
||||
var component = component
|
||||
discard component.pop("kind", kind)
|
||||
output &= config.templates[kind] % componentToFmtArgs(component)
|
||||
|
||||
echo output
|
||||
proc applyTemplate(c: Config, component: Component): string =
|
||||
let templ = c.getTemplate(component)
|
||||
result = templ % component.toFmtArgs()
|
||||
|
||||
proc typstGen(c: Config): string =
|
||||
for component in c.components:
|
||||
result &= c.applyTemplate(component)
|
||||
|
||||
when isMainModule:
|
||||
import hwylterm/[cli, parseopt3]
|
||||
|
@ -45,10 +96,13 @@ when isMainModule:
|
|||
[
|
||||
("h", "help", "show this help"),
|
||||
("c","config", "path to config file"),
|
||||
("","check", "load config and exit"),
|
||||
]
|
||||
)
|
||||
var p = initOptParser()
|
||||
var configPath = "typstgen.yml"
|
||||
var
|
||||
p = initOptParser(longNoVal= @["check"])
|
||||
configPath = "typstgen.yml"
|
||||
check: bool
|
||||
for kind, key, val in p.getopt():
|
||||
case kind
|
||||
of cmdError: quit($bb"[red]cli error[/]: " & p.message)
|
||||
|
@ -60,9 +114,14 @@ when isMainModule:
|
|||
writeHelp(); quit 0
|
||||
of "config", "c":
|
||||
configPath = val
|
||||
of "check":
|
||||
check = true
|
||||
|
||||
if not fileExists(configPath):
|
||||
quit($bbfmt("file: [b]{configPath}[/] does not exist"))
|
||||
typstGen(configPath)
|
||||
|
||||
let config = loadConfig(configPath)
|
||||
if check: quit 0
|
||||
echo typstGen(config)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue