diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,11 @@
+texmath (0.13.3.2)
+
+  * Typst writer: preserve lineless fractions (#302, Don Yin).
+
+  * TeX reader: accept empty delimiters in \genfrac (#300, Don Yin).
+
+  * TeX reader: support \over and \atop (#116, Don Yin).
+
 texmath (0.13.3.1)
 
   * OMML writer: omit `m:sty` when `m:nor` is used (#299).
diff --git a/src/Text/TeXMath/Readers/TeX.hs b/src/Text/TeXMath/Readers/TeX.hs
--- a/src/Text/TeXMath/Readers/TeX.hs
+++ b/src/Text/TeXMath/Readers/TeX.hs
@@ -299,7 +299,9 @@
 
 binomCmds :: M.Map Text (Exp -> Exp -> Exp)
 binomCmds = M.fromList
-            [ ("\\choose", \x y ->
+            [ ("\\over", EFraction NormalFrac)
+            , ("\\atop", EFraction NoLineFrac)
+            , ("\\choose", \x y ->
                 EDelimited "(" ")" [Right (EFraction NoLineFrac x y)])
             , ("\\brack", \x y ->
                 EDelimited "[" "]" [Right (EFraction NoLineFrac x y)])
@@ -311,12 +313,10 @@
 
 genfrac :: Text -> TP Exp
 genfrac "\\genfrac" = do
-  let opener = option "" $
-                T.singleton <$> ((char '\\' >> anyChar) <|> anyChar)
-  let closer = option "" $
-                T.singleton <$> ((char '\\' >> anyChar) <|> anyChar)
-  openDelim <- braces opener <|> opener
-  closeDelim <- braces closer <|> closer
+  let delim = option "" $
+                T.singleton <$> ((char '\\' >> anyChar) <|> satisfy (/= '}'))
+  openDelim <- braces delim <|> delim
+  closeDelim <- braces delim <|> delim
   bar <- False <$ try (braces (string "0pt")) <|> True <$ texToken
   displayStyle <- True <$ try (braces (char '0')) <|> False <$ texToken
   x <- texToken
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
@@ -144,6 +144,8 @@
     = s
   | otherwise = "\"" <> s <> "\""
 writeExp (EGrouped es) = writeExps es
+writeExp (EFraction NoLineFrac e1 e2) =
+  "mat(delim: #none, " <> mkArray [[[e1]], [[e2]]] <> ")"
 writeExp (EFraction _fractype e1 e2) =
   case (e1, e2) of
     (EGrouped _, _) -> "frac(" <> writeExp e1 <> ", " <> writeExp e2 <> ")"
diff --git a/test/reader/tex/atop.test b/test/reader/tex/atop.test
new file mode 100644
--- /dev/null
+++ b/test/reader/tex/atop.test
@@ -0,0 +1,12 @@
+<<< tex
+{a + b \atop c} \over d + e
+
+>>> native
+[ EFraction
+    NormalFrac
+    (EFraction
+       NoLineFrac
+       (EGrouped [ EIdentifier "a" , ESymbol Bin "+" , EIdentifier "b" ])
+       (EIdentifier "c"))
+    (EGrouped [ EIdentifier "d" , ESymbol Bin "+" , EIdentifier "e" ])
+]
diff --git a/test/reader/tex/genfrac-empty.test b/test/reader/tex/genfrac-empty.test
new file mode 100644
--- /dev/null
+++ b/test/reader/tex/genfrac-empty.test
@@ -0,0 +1,40 @@
+<<< tex
+\genfrac{}{}{0pt}{}{a}{b}
+\genfrac{}{}{1pt}{}{a}{b}
+\genfrac{}{}{1pt}{0}{a}{b}
+\genfrac{(}{}{0pt}{}{a}{b}
+\genfrac{}{)}{0pt}{}{a}{b}
+\genfrac(]{0pt}{2}{a}{b}
+
+>>> native
+[ EDelimited
+    ""
+    ""
+    [ Right (EFraction NoLineFrac (EIdentifier "a") (EIdentifier "b"))
+    ]
+, EDelimited
+    ""
+    ""
+    [ Right (EFraction NormalFrac (EIdentifier "a") (EIdentifier "b"))
+    ]
+, EDelimited
+    ""
+    ""
+    [ Right (EFraction DisplayFrac (EIdentifier "a") (EIdentifier "b"))
+    ]
+, EDelimited
+    "("
+    ""
+    [ Right (EFraction NoLineFrac (EIdentifier "a") (EIdentifier "b"))
+    ]
+, EDelimited
+    ""
+    ")"
+    [ Right (EFraction NoLineFrac (EIdentifier "a") (EIdentifier "b"))
+    ]
+, EDelimited
+    "("
+    "]"
+    [ Right (EFraction NoLineFrac (EIdentifier "a") (EIdentifier "b"))
+    ]
+]
diff --git a/test/reader/tex/over.test b/test/reader/tex/over.test
new file mode 100644
--- /dev/null
+++ b/test/reader/tex/over.test
@@ -0,0 +1,11 @@
+<<< tex
+{{1} {2} \over {3} {4}} + {5}
+
+>>> native
+[ EFraction
+    NormalFrac
+    (EGrouped [ ENumber "1" , ENumber "2" ])
+    (EGrouped [ ENumber "3" , ENumber "4" ])
+, ESymbol Bin "+"
+, ENumber "5"
+]
diff --git a/test/writer/typst/choose.test b/test/writer/typst/choose.test
--- a/test/writer/typst/choose.test
+++ b/test/writer/typst/choose.test
@@ -18,4 +18,4 @@
     ]
 ]
 >>> typst
-binom(a, {frac(b, c + 2)})
+binom(a, {mat(delim: #none, b; c + 2)})
diff --git a/test/writer/typst/genfrac.test b/test/writer/typst/genfrac.test
--- a/test/writer/typst/genfrac.test
+++ b/test/writer/typst/genfrac.test
@@ -6,4 +6,4 @@
     ]
 ]
 >>> typst
-{x / y}
+{mat(delim: #none, x; y)}
diff --git a/test/writer/typst/nolinefrac.test b/test/writer/typst/nolinefrac.test
new file mode 100644
--- /dev/null
+++ b/test/writer/typst/nolinefrac.test
@@ -0,0 +1,9 @@
+<<< tex
+{a \atop b} \quad
+\genfrac{}{}{0pt}{}{a + b}{c + d} \quad
+\genfrac{[}{]}{0pt}{}{a}{b} \quad
+\genfrac{}{}{0pt}{}{}{b} \quad
+\genfrac{}{}{0pt}{}{a}{} \quad
+\binom{a}{b} \quad \frac{a}{b}
+>>> typst
+mat(delim: #none, a; b) quad mat(delim: #none, a + b; c + d) quad [mat(delim: #none, a; b)] quad mat(delim: #none, #none; b) quad mat(delim: #none, a; #none) quad binom(a, b) quad a / b
diff --git a/texmath.cabal b/texmath.cabal
--- a/texmath.cabal
+++ b/texmath.cabal
@@ -1,5 +1,5 @@
 Name:                texmath
-Version:             0.13.3.1
+Version:             0.13.3.2
 Cabal-Version:       2.0
 Build-type:          Simple
 Synopsis:            Conversion between math formats.
