about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-12-19 12:26:25 +0100
committerbptato <nincsnevem662@gmail.com>2021-12-19 12:26:57 +0100
commit9a3cd69ea8b99b04cb64800b75f4d2aa3e81fc84 (patch)
tree0a5d2dd69a4435ea64cabc4eb638e0e0ad09d586 /src
parent3360c8b7d3ca98712e7440d5f8d73705afc03dc9 (diff)
downloadchawan-9a3cd69ea8b99b04cb64800b75f4d2aa3e81fc84.tar.gz
More configuration options
Diffstat (limited to 'src')
-rw-r--r--src/config/config.nim20
-rw-r--r--src/config/toml.nim8
-rw-r--r--src/main.nim2
-rw-r--r--src/utils/twtstr.nim131
4 files changed, 94 insertions, 67 deletions
diff --git a/src/config/config.nim b/src/config/config.nim
index 68ddd353..63fcb7eb 100644
--- a/src/config/config.nim
+++ b/src/config/config.nim
@@ -38,6 +38,7 @@ type
     nmap*: ActionMap
     lemap*: ActionMap
     stylesheet*: string
+    ambiguous_double*: bool
 
 func getRealKey(key: string): string =
   var realk: string
@@ -124,13 +125,28 @@ proc readUserStylesheet(dir, file: string): string =
       f.close()
 
 proc parseConfig(config: var Config, dir: string, t: TomlValue) =
+  if "general" in t:
+    let general = t["general"]
+    if "double-width-ambiguous" in general:
+      config.ambiguous_double = general["double-width-ambiguous"].b
   if "page" in t:
     for k, v in t["page"].pairs:
       config.nmap[getRealKey(k)] = getAction(v.s)
     for k, v in t["line"].pairs:
       config.lemap[getRealKey(k)] = getLineAction(v.s)
-  if "stylesheet" in t:
-    config.stylesheet = readUserStylesheet(dir, t["stylesheet"].s)
+  if "css" in t:
+    let css = t["css"]
+    if "include" in css:
+      let val = css["include"]
+      case val.vt
+      of VALUE_STRING:
+        config.stylesheet &= readUserStylesheet(dir, val.s)
+      of VALUE_ARRAY:
+        for child in val.a:
+          config.stylesheet &= readUserStylesheet(dir, child.s)
+      else: discard
+    if "inline" in css:
+      config.stylesheet &= css["inline"].s
 
 proc staticReadConfig(): Config =
   result.parseConfig("res", parseToml(newStringStream(staticRead"res/config.toml")))
diff --git a/src/config/toml.nim b/src/config/toml.nim
index cfdb7763..03c17af5 100644
--- a/src/config/toml.nim
+++ b/src/config/toml.nim
@@ -8,7 +8,7 @@ import unicode
 import utils/twtstr
 
 type
-  ValueType = enum
+  ValueType* = enum
     VALUE_STRING, VALUE_INTEGER, VALUE_FLOAT, VALUE_BOOLEAN, VALUE_DATE_TIME,
     VALUE_TABLE, VALUE_ARRAY VALUE_TABLE_ARRAY
 
@@ -121,12 +121,12 @@ proc consumeString(state: var TomlParser, first: char): string =
 
   if first == '"':
     if state.has(1):
-      let s = state.peek(0, 2)
+      let s = state.peek(0, 1)
       if s == "\"\"":
         multiline = true
   elif first == '\'':
     if state.has(1):
-      let s = state.peek(0, 2)
+      let s = state.peek(0, 1)
       if s == "''":
         multiline = true
 
@@ -146,6 +146,8 @@ proc consumeString(state: var TomlParser, first: char): string =
         let c2 = state.peek(0)
         let c3 = state.peek(1)
         if c2 == first and c3 == first:
+          discard state.consume()
+          discard state.consume()
           break
       else:
         break
diff --git a/src/main.nim b/src/main.nim
index 06c6bdb5..d9d10efa 100644
--- a/src/main.nim
+++ b/src/main.nim
@@ -10,6 +10,7 @@ import html/parser
 import io/buffer
 import io/term
 import config/config
+import utils/twtstr
 
 let clientInstance = newHttpClient()
 proc loadRemotePage*(url: string): string =
@@ -77,4 +78,5 @@ proc main*() =
     lastUri = newUri
 
 readConfig()
+width_table = makewidthtable(gconfig.ambiguous_double)
 main()
diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim
index 2ec9967c..52abade7 100644
--- a/src/utils/twtstr.nim
+++ b/src/utils/twtstr.nim
@@ -533,60 +533,6 @@ func is_dwidth(r: Rune): bool =
       (ucs >= 0x20000 and ucs <= 0x2fffd) or
       (ucs >= 0x30000 and ucs <= 0x3fffd)))
 
-func makewidthtable(): array[0..0x10FFFF, byte] =
-  for r in low(char)..high(char):
-    if r.isControlChar():
-      result[int(r)] = 2 #TODO this should be 0
-    else:
-      result[int(r)] = 1
-
-  var i = 0
-  var next_combining = combining[i]
-  for ucs in 256..0x10FFFF:
-    if ucs >= next_combining[0]:
-      if ucs <= next_combining[1]:
-        result[ucs] = 0
-        continue
-      elif i + 1 < combining.len:
-        inc i
-        next_combining = combining[i]
-
-    if Rune(ucs).is_dwidth():
-      result[ucs] = 2
-    else:
-      result[ucs] = 1
-
-# compute lookup table on startup
-# TODO: we could have an option to store it in the executable but honestly I
-# don't see the need to
-let width_table = makewidthtable()
-
-{.push boundChecks:off.}
-func width*(r: Rune): int =
-  {.cast(noSideEffect).}:
-    return int(width_table[int(r)])
-
-func width*(s: string): int =
-  for r in s.runes():
-    result += width(r)
-
-func width*(s: seq[Rune]): int =
-  for r in s:
-    result += width(r)
-
-func width*(s: seq[Rune], min, max: int): int =
-  var i = min
-  var mi = min(max, s.len)
-  while i < mi:
-    result += width(s[i])
-    inc i
-
-func width*(s: seq[Rune], min: int): int =
-  var i = min
-  while i < s.len:
-    result += width(s[i])
-    inc i
-
 # sorted list of non-overlapping intervals of East Asian Ambiguous characters,
 # generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c"
 
@@ -674,18 +620,79 @@ func bisearch(ucs: Rune, table: openarray[(int, int)]): bool =
       return true
   return false
 
-
-func mk_wcwidth_cjk(r: Rune): int =
+func is_dwidth_cjk(r: Rune): bool =
   # binary search in table of non-spacing characters
   if bisearch(r, ambiguous):
-    return 2;
+    return true
 
-  return r.width();
+  return r.is_dwidth()
 
-func mk_wcswidth_cjk(s: string): int =
-  for r in s.runes:
-    result += mk_wcwidth_cjk(r)
-  return result
+# compute lookup table on startup
+var width_table*: array[0..0x10FFFF, byte]
+
+func makewidthtable*(cjk: bool): array[0..0x10FFFF, byte] =
+  for r in low(char)..high(char):
+    if r.isControlChar():
+      result[int(r)] = 2 #TODO this should be 0
+    else:
+      result[int(r)] = 1
+
+  var i = 0
+  var next_combining = combining[i]
+  if cjk:
+    for ucs in 256..0x10FFFF:
+      if ucs >= next_combining[0]:
+        if ucs <= next_combining[1]:
+          result[ucs] = 0
+          continue
+        elif i + 1 < combining.len:
+          inc i
+          next_combining = combining[i]
+
+      if Rune(ucs).is_dwidth_cjk():
+        result[ucs] = 2
+      else:
+        result[ucs] = 1
+  else:
+    for ucs in 256..0x10FFFF:
+      if ucs >= next_combining[0]:
+        if ucs <= next_combining[1]:
+          result[ucs] = 0
+          continue
+        elif i + 1 < combining.len:
+          inc i
+          next_combining = combining[i]
+
+      if Rune(ucs).is_dwidth():
+        result[ucs] = 2
+      else:
+        result[ucs] = 1
+
+{.push boundChecks:off.}
+func width*(r: Rune): int =
+  {.cast(noSideEffect).}:
+    return int(width_table[int(r)])
+
+func width*(s: string): int =
+  for r in s.runes():
+    result += width(r)
+
+func width*(s: seq[Rune]): int =
+  for r in s:
+    result += width(r)
+
+func width*(s: seq[Rune], min, max: int): int =
+  var i = min
+  var mi = min(max, s.len)
+  while i < mi:
+    result += width(s[i])
+    inc i
+
+func width*(s: seq[Rune], min: int): int =
+  var i = min
+  while i < s.len:
+    result += width(s[i])
+    inc i
 
 const CanHaveDakuten = "かきくけこさしすせそたちつてとはひふへほカキクケコサシスセソタチツテトハヒフヘホ".toRunes()