diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,12 @@
+texmath (0.12.7.1)
+
+ * Typst writer:
+
+   + Improve under/overbrace/bracket/line.
+   + Fix bugs with super/subscript grouping (#212).
+   + Fix case where super/subscript is on an empty element,
+     by inserting a zws.
+
 texmath (0.12.7)
 
   * Add typst writer. New module: Text.TeXMath.Writers.Typst.
diff --git a/src/Text/TeXMath/Writers/Typst.hs b/src/Text/TeXMath/Writers/Typst.hs
--- a/src/Text/TeXMath/Writers/Typst.hs
+++ b/src/Text/TeXMath/Writers/Typst.hs
@@ -27,6 +27,7 @@
 import qualified Text.TeXMath.Shared as S
 import Data.Generics (everywhere, mkT)
 import Data.Text (Text)
+import Data.Char (isDigit, isAlpha)
 
 -- import Debug.Trace
 -- tr' x = trace (show x) x
@@ -64,10 +65,20 @@
     needsEscape '_' = True
     needsEscape _ = False
 
-writeExp' :: Exp -> Text
-writeExp' (EGrouped es) = "(" <> writeExps es <> ")"
-writeExp' e = writeExp e
+writeExpS :: Exp -> Text
+writeExpS (EGrouped es) = "(" <> writeExps es <> ")"
+writeExpS e =
+  case writeExp e of
+    t | T.all (\c -> isDigit c || c == '.') t -> t
+      | T.all (\c -> isAlpha c || c == '.') t -> t
+      | otherwise -> "(" <> t <> ")"
 
+writeExpB :: Exp -> Text
+writeExpB e =
+  case writeExp e of
+    "" -> "zws"
+    t -> t
+
 writeExp :: Exp -> Text
 writeExp (ENumber s) = s
 writeExp (ESymbol _t s) =
@@ -90,10 +101,16 @@
     (EGrouped _, _) -> "frac(" <> writeExp e1 <> ", " <> writeExp e2 <> ")"
     (_, EGrouped _) -> "frac(" <> writeExp e1 <> ", " <> writeExp e2 <> ")"
     _ -> writeExp e1 <> " / " <> writeExp e2
-writeExp (ESub b e1) = writeExp' b <> "_" <> writeExp' e1
-writeExp (ESuper b e1) = writeExp' b <> "^" <> writeExp' e1
-writeExp (ESubsup b e1 e2) = writeExp' b <> "_" <> writeExp' e1 <>
-                                            "^" <> writeExp' e2
+writeExp (ESub b e1) = writeExpB b <> "_" <> writeExpS e1
+writeExp (ESuper b e1) = writeExpB b <> "^" <> writeExpS e1
+writeExp (ESubsup b e1 e2) = writeExpB b <> "_" <> writeExpS e1 <>
+                                           "^" <> writeExpS e2
+writeExp (EOver _ (EOver _ b (ESymbol TOver "\9182")) e1) =
+  "overbrace(" <> writeExp b <> ", " <> writeExp e1 <> ")"
+writeExp (EOver _ (EOver _ b (ESymbol TOver "\9140")) e1) =
+  "overbracket(" <> writeExp b <> ", " <> writeExp e1 <> ")"
+writeExp (EOver _ (EOver _ b (ESymbol TOver "_")) e1) =
+  "overline(" <> writeExp b <> ", " <> writeExp e1 <> ")"
 writeExp (EOver _convertible b e1) =
   case e1 of
     ESymbol Accent "`" -> "grave" <> inParens (writeExp b)
@@ -111,19 +128,26 @@
     ESymbol Accent "\x2190" -> "<-" <> inParens (writeExp b)
     ESymbol TOver "\9182" -> "overbrace(" <> writeExp b <> ")"
     ESymbol TOver "\9140" -> "overbracket(" <> writeExp b <> ")"
-    _ -> writeExp' b <> "^" <> writeExp' e1
+    ESymbol TOver "_" -> "overline(" <> writeExp b <> ")"
+    _ -> writeExpB b <> "^" <> writeExpS e1
+writeExp (EUnder _ (EUnder _ b (ESymbol TUnder "_")) e1) =
+  "underline(" <> writeExp b <> ", " <> writeExp e1 <> ")"
+writeExp (EUnder _ (EUnder _ b (ESymbol TUnder "\9182")) e1) =
+  "underbrace(" <> writeExp b <> ", " <> writeExp e1 <> ")"
+writeExp (EUnder _ (EUnder _ b (ESymbol TUnder "\9140")) e1) =
+  "underbrace(" <> writeExp b <> ", " <> writeExp e1 <> ")"
 writeExp (EUnder _convertible b e1) =
   case e1 of
     ESymbol TUnder "_" -> "underline(" <> writeExp b <> ")"
     ESymbol TUnder "\9182" -> "underbrace(" <> writeExp b <> ")"
     ESymbol TUnder "\9140" -> "underbracket(" <> writeExp b <> ")"
-    _ -> writeExp' b <> "_" <> writeExp' e1
+    _ -> writeExpB b <> "_" <> writeExpS e1
 writeExp (EUnderover convertible b e1 e2) =
   case (e1, e2) of
     (_, ESymbol Accent _) -> writeExp (EUnder convertible (EOver False b e2) e1)
     (_, ESymbol TOver _) -> writeExp (EUnder convertible (EOver False b e2) e1)
     (ESymbol TUnder _, _) -> writeExp (EOver convertible (EUnder False b e1) e2)
-    _ -> writeExp' b <> "_" <> writeExp' e1 <> "^" <> writeExp' e2
+    _ -> writeExpB b <> "_" <> writeExpS e1 <> "^" <> writeExpS e2
 writeExp (ESqrt e) = "sqrt(" <> writeExp e <> ")"
 writeExp (ERoot i e) = "root(" <> writeExp i <> ", " <> writeExp e <> ")"
 writeExp (ESpace width) =
diff --git a/test/writer/typst/04.test b/test/writer/typst/04.test
--- a/test/writer/typst/04.test
+++ b/test/writer/typst/04.test
@@ -17,4 +17,4 @@
     (ENumber "2")
 ]
 >>> typst
-S_upright("new") eq S_upright("old") minus lr((5 minus T))^2 / 2
+S_(upright("new")) eq S_(upright("old")) minus lr((5 minus T))^2 / 2
diff --git a/test/writer/typst/08.test b/test/writer/typst/08.test
--- a/test/writer/typst/08.test
+++ b/test/writer/typst/08.test
@@ -30,4 +30,4 @@
 , EDelimited "(" ")" [ Right (EIdentifier "z") ]
 ]
 >>> typst
-lr(|z^‾|) eq lr(|z|) comma lr(|lr((z^‾))^n|) eq lr(|z|)^n comma arg lr((z^n)) eq n arg lr((z))
+lr(|z^(‾)|) eq lr(|z|) comma lr(|lr((z^(‾)))^n|) eq lr(|z|)^n comma arg lr((z^n)) eq n arg lr((z))
diff --git a/test/writer/typst/13.test b/test/writer/typst/13.test
--- a/test/writer/typst/13.test
+++ b/test/writer/typst/13.test
@@ -54,4 +54,4 @@
     (EGrouped [ EIdentifier "n" , ESymbol Ord "!" ])
 ]
 >>> typst
-()_p F_q lr((a_1 comma dots.h comma a_p semi c_1 comma dots.h comma c_q semi z)) eq sum_(n eq 0)^oo frac(lr((a_1))_n dots.h.c lr((a_p))_n, lr((c_1))_n dots.h.c lr((c_q))_n) frac(z^n, n excl)
+zws_p F_q lr((a_1 comma dots.h comma a_p semi c_1 comma dots.h comma c_q semi z)) eq sum_(n eq 0)^oo frac(lr((a_1))_n dots.h.c lr((a_p))_n, lr((c_1))_n dots.h.c lr((c_q))_n) frac(z^n, n excl)
diff --git a/test/writer/typst/binomial_coefficient.test b/test/writer/typst/binomial_coefficient.test
--- a/test/writer/typst/binomial_coefficient.test
+++ b/test/writer/typst/binomial_coefficient.test
@@ -40,4 +40,4 @@
        ])
 ]
 >>> typst
-bold(C) lr((n comma k)) eq bold(C)_k^n eq ()_n bold(C)_k eq lr((n / k)) eq frac(n excl, k excl thin lr((n minus k)) excl)
+bold(C) lr((n comma k)) eq bold(C)_k^n eq zws_n bold(C)_k eq lr((n / k)) eq frac(n excl, k excl thin lr((n minus k)) excl)
diff --git a/test/writer/typst/complex1.test b/test/writer/typst/complex1.test
--- a/test/writer/typst/complex1.test
+++ b/test/writer/typst/complex1.test
@@ -601,20 +601,20 @@
     ]
 ]
 >>> typst
-upright("Bernoulli Trials") & P paren.l E paren.r eq lr((n / k)) p_()^k (paren.l 1 hyph.minus p paren.r)_()^(n hyph.minus k)\
+upright("Bernoulli Trials") & P paren.l E paren.r eq lr((n / k)) p_()^k paren.l 1 hyph.minus p paren.r_()^(n hyph.minus k)\
 upright("Cauchy-Schwarz Inequality") & lr((sum_(k eq 1)^n a_k^() b_k^()))_()^2 lt.eq lr((sum_(k eq 1)^n a_k^2)) lr((sum_(k eq 1)^n b_k^2))\
 upright("Cauchy Formula") & f paren.l z paren.r thin dot.c "Ind"_gamma^() paren.l z paren.r eq frac(1, 2 pi i) integral.cont_gamma^() frac(f paren.l xi paren.r, xi hyph.minus z) thin d xi\
 upright("Cross Product") & V_1^() times V_2^() eq mat(delim: "|", i, j, k; frac(diff X, diff u), frac(diff Y, diff u), 0; frac(diff X, diff v), frac(diff Y, diff v), 0)\
 upright("Vandermonde Determinant") & mat(delim: "|", 1, 1, dots.h.c, 1; v_1^(), v_2^(), dots.h.c, v_n^(); v_1^2, v_2^2, dots.h.c, v_n^2; dots.v, dots.v, dots.down, dots.v; v_1^(n hyph.minus 1), v_2^(n hyph.minus 1), dots.h.c, v_n^(n hyph.minus 1)) eq product_(1 lt.eq i lt j lt.eq n)^() paren.l v_j^() hyph.minus v_i^() paren.r\
-upright("Lorenz Equations") & x^˙_() & eq & sigma paren.l y hyph.minus x paren.r\
-y^˙_() & eq & rho x hyph.minus y hyph.minus x z\
-z^˙_() & eq & hyph.minus beta z plus x y\
+upright("Lorenz Equations") & x^(˙)_() & eq & sigma paren.l y hyph.minus x paren.r\
+y^(˙)_() & eq & rho x hyph.minus y hyph.minus x z\
+z^(˙)_() & eq & hyph.minus beta z plus x y\
 upright("Maxwell's Equations") & {nabla zws times B^harpoon.lt_() hyph.minus thin 1 / c thin frac(diff zws E^harpoon.lt_(), diff zws t) & eq & frac(4 pi, c) thin j^harpoon.lt_()\
 nabla zws dot.c E^harpoon.lt_() & eq & 4 pi rho\
 nabla zws times E^harpoon.lt_() thin plus thin 1 / c thin frac(diff zws B^harpoon.lt_(), diff zws t) & eq & 0^harpoon.lt_()\
 nabla zws dot.c B^harpoon.lt_() & eq & 0\
 upright("Einstein Field Equations") & R_(mu nu)^() hyph.minus 1 / 2 thin g_(mu nu)^() thin R eq frac(8 pi G, c_()^4) thin T_(mu nu)^()\
-upright("Ramanujan Identity") & frac(1, paren.l sqrt(phi sqrt(5)) hyph.minus phi paren.r e_()^25 / pi) eq 1 plus frac(e_()^(hyph.minus 2 pi), 1 plus frac(e_()^(hyph.minus 4 pi), 1 plus frac(e_()^(hyph.minus 6 pi), 1 plus frac(e_()^(hyph.minus 8 pi), 1 plus dots.h))))\
+upright("Ramanujan Identity") & frac(1, paren.l sqrt(phi sqrt(5)) hyph.minus phi paren.r e_()^(25 / pi)) eq 1 plus frac(e_()^(hyph.minus 2 pi), 1 plus frac(e_()^(hyph.minus 4 pi), 1 plus frac(e_()^(hyph.minus 6 pi), 1 plus frac(e_()^(hyph.minus 8 pi), 1 plus dots.h))))\
 upright("Another Ramanujan identity") & sum_(k eq 1)^oo 1 / 2_()^(⌊ k dot.c zws phi ⌋) eq frac(1, 2_()^0 plus frac(1, 2_()^1 plus dots.h.c))\
 upright("Rogers-Ramanujan Identity") & 1 plus sum_(k eq 1)^oo frac(q_()^(k_()^2 plus k), paren.l 1 hyph.minus q paren.r paren.l 1 hyph.minus q_()^2 paren.r dots.h.c paren.l 1 hyph.minus q_()^k paren.r) eq product_(j eq 0)^oo frac(1, paren.l 1 hyph.minus q_()^(5 j plus 2) paren.r paren.l 1 hyph.minus q_()^(5 j plus 3) paren.r) comma upright("  ") upright("  ") f o r med bar.v q bar.v lt 1 dot\
 upright("Commutative Diagram") & H & arrow.l & K\
diff --git a/test/writer/typst/complex2.test b/test/writer/typst/complex2.test
--- a/test/writer/typst/complex2.test
+++ b/test/writer/typst/complex2.test
@@ -401,7 +401,7 @@
 upright("Stacked exponents") & g paren.l z paren.r eq e_()^(hyph.minus paren.l z hyph.minus a paren.r_()^2)\
 upright("Stacked exponents") & g paren.l z paren.r eq e_()^(hyph.minus sum_(i eq 0)^oo z_i^2)\
 upright("Stacked exponents") & g paren.l y paren.r eq e_()^(hyph.minus sum_(i eq 0)^oo y_i^2)\
-upright("Stacked exponents") & g paren.l z paren.r eq e_()^(hyph.minus sum_(i eq 0)^oo z_()^frac(2, a hyph.minus i))\
+upright("Stacked exponents") & g paren.l z paren.r eq e_()^(hyph.minus sum_(i eq 0)^oo z_()^(frac(2, a hyph.minus i)))\
 upright("Cross Product") & frac(x_1^() hyph.minus x_2^(), x_3^() hyph.minus x_4^()) frac(x_1^() hyph.minus x_4^(), x_2^() hyph.minus x_3^())\
 upright("Cross Product") & paren.l frac(x_1^() hyph.minus x_2^(), x_3^() hyph.minus x_4^()) paren.r paren.l frac(x_1^() hyph.minus x_4^(), x_2^() hyph.minus x_3^()) paren.r\
 upright("Cross Product") & lr((frac(x_1^() hyph.minus x_2^(), x_3^() hyph.minus x_4^()))) lr((frac(x_1^() hyph.minus x_4^(), x_2^() hyph.minus x_3^())))\
diff --git a/test/writer/typst/complex_number.test b/test/writer/typst/complex_number.test
--- a/test/writer/typst/complex_number.test
+++ b/test/writer/typst/complex_number.test
@@ -24,4 +24,4 @@
     (EText TextNormal "complex number")
 ]
 >>> typst
-c eq overbrace(a_brace.b_upright("real") plus (b upright(i))_brace.b_upright("imaginary"))^upright("complex number")
+c eq overbrace(a_brace.b_(upright("real")) plus b upright(i)_brace.b_(upright("imaginary")), upright("complex number"))
diff --git a/test/writer/typst/deMorgans_law.test b/test/writer/typst/deMorgans_law.test
--- a/test/writer/typst/deMorgans_law.test
+++ b/test/writer/typst/deMorgans_law.test
@@ -36,4 +36,4 @@
     (ESymbol TOver "\175")
 ]
 >>> typst
-not lr((p and q)) arrow.l.r.double lr((not p)) or lr((not q)) (union.big_(i eq 1)^n A_i)^macron eq sect.big_(i eq 1)^n A_i^macron
+not lr((p and q)) arrow.l.r.double lr((not p)) or lr((not q)) union.big_(i eq 1)^n A_i^macron eq sect.big_(i eq 1)^n A_i^macron
diff --git a/test/writer/typst/divergence.test b/test/writer/typst/divergence.test
--- a/test/writer/typst/divergence.test
+++ b/test/writer/typst/divergence.test
@@ -22,4 +22,4 @@
     (EGrouped [ ESymbol Ord "\8706" , EIdentifier "z" ])
 ]
 >>> typst
-nabla dot.op v^⃗ eq frac(diff v_x, diff x) plus frac(diff v_y, diff y) plus frac(diff v_z, diff z)
+nabla dot.op v^(⃗) eq frac(diff v_x, diff x) plus frac(diff v_y, diff y) plus frac(diff v_z, diff z)
diff --git a/test/writer/typst/moore_determinant.test b/test/writer/typst/moore_determinant.test
--- a/test/writer/typst/moore_determinant.test
+++ b/test/writer/typst/moore_determinant.test
@@ -51,4 +51,4 @@
     ]
 ]
 >>> typst
-M eq mat(delim: "[", alpha_1, alpha_1^q, dots.h.c, alpha_1^q^(n minus 1); alpha_2, alpha_2^q, dots.h.c, alpha_2^q^(n minus 1); dots.v, dots.v, dots.down, dots.v; alpha_m, alpha_m^q, dots.h.c, alpha_m^q^(n minus 1))
+M eq mat(delim: "[", alpha_1, alpha_1^q, dots.h.c, alpha_1^(q^(n minus 1)); alpha_2, alpha_2^q, dots.h.c, alpha_2^(q^(n minus 1)); dots.v, dots.v, dots.down, dots.v; alpha_m, alpha_m^q, dots.h.c, alpha_m^(q^(n minus 1)))
diff --git a/test/writer/typst/nestScript.test b/test/writer/typst/nestScript.test
--- a/test/writer/typst/nestScript.test
+++ b/test/writer/typst/nestScript.test
@@ -7,4 +7,4 @@
           (EIdentifier "x") (ESuper (EIdentifier "y") (EIdentifier "z"))))
 ]
 >>> typst
-v^w^x^y^z
+v^(w^(x^(y^z)))
diff --git a/test/writer/typst/primes1.test b/test/writer/typst/primes1.test
--- a/test/writer/typst/primes1.test
+++ b/test/writer/typst/primes1.test
@@ -37,4 +37,4 @@
 , ESuper (ESymbol Accent "'") (ESymbol Accent "'")
 ]
 >>> typst
-x^2 plus 2^2 plus x^prime plus x^quote.single plus x^"''" plus x prime plus x^quote.single^quote.single plus x^quote.single^2 plus x^(quote.single plus quote.single) plus x^quote.single^quote.single plus x^quote.single^quote.single plus quote.single^quote.single plus quote.single^quote.single
+x^2 plus 2^2 plus x^prime plus x^quote.single plus x^("''") plus x prime plus x^quote.single^quote.single plus x^quote.single^2 plus x^(quote.single plus quote.single) plus x^quote.single^quote.single plus x^(quote.single^quote.single) plus quote.single^quote.single plus quote.single^quote.single
diff --git a/test/writer/typst/primes2.test b/test/writer/typst/primes2.test
--- a/test/writer/typst/primes2.test
+++ b/test/writer/typst/primes2.test
@@ -27,4 +27,4 @@
 , ESuper (EIdentifier "H") (ESymbol Accent "\8279")
 ]
 >>> typst
-H^quote.double H^quote.single H^ast H^grave H^ª H^degree H^² H^³ H^acute H^¹ H^º H^quote.l.single H^quote.r.single H^quote.low.single H^quote.high.single H^quote.l.double H^quote.r.double H^quote.low.double H^quote.high.double H^prime H^prime.double H^prime.triple H^prime.rev H^prime.double.rev H^prime.triple.rev H^prime.quad
+H^quote.double H^quote.single H^ast H^grave H^ª H^degree H^(²) H^(³) H^acute H^(¹) H^º H^quote.l.single H^quote.r.single H^quote.low.single H^quote.high.single H^quote.l.double H^quote.r.double H^quote.low.double H^quote.high.double H^prime H^prime.double H^prime.triple H^prime.rev H^prime.double.rev H^prime.triple.rev H^prime.quad
diff --git a/test/writer/typst/substack.test b/test/writer/typst/substack.test
--- a/test/writer/typst/substack.test
+++ b/test/writer/typst/substack.test
@@ -33,5 +33,5 @@
     ]
 ]
 >>> typst
-sum_0 lt i lt m\
-0 lt j lt n P lr((i comma j))
+sum_(0 lt i lt m\
+0 lt j lt n) P lr((i comma j))
diff --git a/test/writer/typst/subsup.test b/test/writer/typst/subsup.test
--- a/test/writer/typst/subsup.test
+++ b/test/writer/typst/subsup.test
@@ -65,4 +65,4 @@
 , ESubsup (ESpace (1 % 1)) (EIdentifier "x") (ENumber "3")
 ]
 >>> typst
-x_b^a quad x_b^a quad min_A quad max_B quad det_C quad Pr_A quad gcd_A quad u^̇^2 quad u^macron_epsilon quad underline(u)_b^a quad overbrace(a plus b)^upright("term") quad overbracket(a plus b)^c quad (a plus b)_brace.b_c quad (a plus b)_bracket.b_c quad^H e 3 quad_x A quad_x^3
+x_b^a quad x_b^a quad min_A quad max_B quad det_C quad Pr_A quad gcd_A quad u^(̇)^2 quad u^macron_epsilon quad underline(u)_b^a quad overbrace(a plus b, upright("term")) quad overbracket(a plus b, c) quad a plus b_brace.b_c quad a plus b_bracket.b_c quad^H e 3 quad_x A quad_x^3
diff --git a/texmath.cabal b/texmath.cabal
--- a/texmath.cabal
+++ b/texmath.cabal
@@ -1,5 +1,5 @@
 Name:                texmath
-Version:             0.12.7
+Version:             0.12.7.1
 Cabal-Version:       >= 1.10
 Build-type:          Simple
 Synopsis:            Conversion between math formats.
