about summary refs log tree commit diff stats
path: root/src/config
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-11-29 22:32:38 +0100
committerbptato <nincsnevem662@gmail.com>2022-11-29 22:32:52 +0100
commit6c4b7671df166bec49b1a175f759974ff5962a38 (patch)
tree3c31ced89b880df1c3870145667503bea24ee5e3 /src/config
parentf2daba3542cabb4741e2dc38d1bf36a2d1564f60 (diff)
downloadchawan-6c4b7671df166bec49b1a175f759974ff5962a38.tar.gz
Add siteconf, fix lineedit bugs
This enables rule-based dynamic url rewriting.
Also, lineedit is a bit less broken now (though it's still less than
ideal.)
Diffstat (limited to 'src/config')
-rw-r--r--src/config/config.nim31
-rw-r--r--src/config/toml.nim61
2 files changed, 83 insertions, 9 deletions
diff --git a/src/config/config.nim b/src/config/config.nim
index 316e6d33..4db66283 100644
--- a/src/config/config.nim
+++ b/src/config/config.nim
@@ -5,6 +5,8 @@ import streams
 
 import buffer/cell
 import config/toml
+import js/javascript
+import js/regex
 import types/color
 import utils/twtstr
 
@@ -16,6 +18,14 @@ type
 
   ActionMap = Table[string, string]
 
+  StaticSiteConfig = object
+    url: string
+    subst: Option[string]
+
+  SiteConfig* = object
+    url*: Regex
+    subst*: (proc(s: string): Option[string])
+
   Config* = ref ConfigObj
   ConfigObj* = object
     nmap*: ActionMap
@@ -31,6 +41,7 @@ type
     mincontrast*: float
     editor*: string
     tmpdir*: string
+    siteconf: seq[StaticSiteConfig]
 
   BufferConfig* = object
     userstyle*: string
@@ -48,6 +59,17 @@ func getForkServerConfig*(config: Config): ForkServerConfig =
 func getBufferConfig*(config: Config): BufferConfig =
   result.userstyle = config.stylesheet
 
+proc getSiteConfig*(config: Config, jsctx: JSContext): seq[SiteConfig] =
+  for sc in config.siteconf:
+    if sc.subst.isSome:
+      let re = compileRegex(sc.url, 0)
+      let fun = jsctx.eval(sc.subst.get, "<siteconf>", JS_EVAL_TYPE_GLOBAL)
+      let f = getJSFunction[string, string](jsctx, fun.val)
+      result.add(SiteConfig(
+        url: re.get,
+        subst: f.get
+      ))
+
 func getRealKey(key: string): string =
   var realk: string
   var control = 0
@@ -190,6 +212,15 @@ proc parseConfig(config: Config, dir: string, t: TomlValue) =
         case k
         of "editor": config.editor = v.s
         of "tmpdir": config.tmpdir = v.s
+    of "siteconf":
+      for v in v:
+        var conf = StaticSiteConfig()
+        for k, v in v:
+          case k
+          of "url": conf.url = v.s
+          of "substitute_url": conf.subst = some(v.s)
+        if conf.url != "":
+          config.siteconf.add(conf)
 
 proc parseConfig(config: Config, dir: string, stream: Stream) =
   config.parseConfig(dir, parseToml(stream))
diff --git a/src/config/toml.nim b/src/config/toml.nim
index dd0b4fe1..c5a93b8a 100644
--- a/src/config/toml.nim
+++ b/src/config/toml.nim
@@ -9,8 +9,14 @@ import utils/twtstr
 
 type
   ValueType* = enum
-    VALUE_STRING, VALUE_INTEGER, VALUE_FLOAT, VALUE_BOOLEAN, VALUE_DATE_TIME,
-    VALUE_TABLE, VALUE_ARRAY VALUE_TABLE_ARRAY
+    VALUE_STRING = "string"
+    VALUE_INTEGER = "integer"
+    VALUE_FLOAT = "float"
+    VALUE_BOOLEAN = "boolean"
+    VALUE_DATE_TIME = "datetime"
+    VALUE_TABLE = "table"
+    VALUE_ARRAY = "array"
+    VALUE_TABLE_ARRAY = "tablearray"
 
   SyntaxError = object of ValueError
 
@@ -22,6 +28,7 @@ type
     root: TomlTable
     node: TomlNode
     currkey: seq[string]
+    tarray: bool
 
   TomlValue* = ref object
     case vt*: ValueType
@@ -57,10 +64,18 @@ type
 func `[]`*(val: TomlValue, key: string): TomlValue =
   return val.t.map[key]
 
-iterator pairs*(val: TomlValue): (string, TomlValue) =
-  for k, v in val.t.map.pairs:
+iterator pairs*(val: TomlTable): (string, TomlValue) {.inline.} =
+  for k, v in val.map.pairs:
     yield (k, v)
 
+iterator pairs*(val: TomlValue): (string, TomlValue) {.inline.} =
+  for k, v in val.t:
+    yield (k, v)
+
+iterator items*(val: TomlValue): TomlTable {.inline.} =
+  for v in val.ta:
+    yield v
+
 func contains*(val: TomlValue, key: string): bool =
   return key in val.t.map
 
@@ -196,11 +211,14 @@ proc flushLine(state: var TomlParser) =
       while i < keys.len - 1:
         if keys[i] in table.map:
           let node = table.map[keys[i]]
-          if node.vt != VALUE_TABLE:
+          if node.vt == VALUE_TABLE:
+            table = node.t
+          elif node.vt == VALUE_TABLE_ARRAY:
+            assert state.tarray
+            table = node.ta[^1]
+          else:
             let s = keys.join(".")
             state.valueError(fmt"re-definition of node {s}")
-          else:
-            table = node.t
         else:
           let node = TomlTable()
           table.map[keys[i]] = TomlValue(vt: VALUE_TABLE, t: node)
@@ -268,9 +286,15 @@ proc consumeTable(state: var TomlParser): TomlTable =
     of ' ', '\t': discard
     of '\n':
       return result
+    of ']':
+      if state.tarray:
+        discard state.consume()
+        return result
+      else:
+        state.syntaxError("redundant ] character after key")
     of '[':
-      #TODO table array
-      state.syntaxError("arrays of tables are not supported yet")
+      state.tarray = true
+      discard state.consume()
     of '"', '\'':
       result.key = state.consumeKey()
     elif c.isBare():
@@ -287,7 +311,26 @@ proc consumeNoState(state: var TomlParser): bool =
     of ' ', '\t': discard
     of '[':
       discard state.consume()
+      state.tarray = false
       let table = state.consumeTable()
+      if state.tarray:
+        var node = state.root
+        for i in 0 ..< table.key.high:
+          if table.key[i] in node.map:
+            node = node.map[table.key[i]].t
+          else:
+            let t2 = TomlTable()
+            node.map[table.key[i]] = TomlValue(vt: VALUE_TABLE, t: t2)
+            node = t2
+        if table.key[^1] in node.map:
+          let last = node.map[table.key[^1]]
+          if last.vt != VALUE_TABLE_ARRAY:
+            let key = table.key.join('.')
+            state.valueError(fmt"re-definition of node {key} as table array (was {last.vt})")
+          last.ta.add(table)
+        else:
+          let last = TomlValue(vt: VALUE_TABLE_ARRAY, ta: @[table])
+          node.map[table.key[^1]] = last
       state.currkey = table.key
       state.node = table
       return false