diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
 # Revision history for djot
 
+## 0.1.4 -- 2026-03-17
+
+  * Ensure that delims aren't matched in link destinations (#15).
+
+  * Change behavior for empty link label. To match djot.js; we now
+    take the string content (rather than raw source) of the link
+    description, so e.g. emphasis is ignored.
+
+  * Html renderer: don't emit empty href for undefined ref link.
+    This conforms to djot.js behavior, expected in tests.
+
+  * Update links_and_images test from reference impl: djot.js.
+
 ## 0.1.3 -- 2026-02-01
 
 * Fix nested sections bug when sections contain only lists (#14).
diff --git a/djot.cabal b/djot.cabal
--- a/djot.cabal
+++ b/djot.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               djot
-version:            0.1.3
+version:            0.1.4
 synopsis:           Parser and renderer for djot light markup syntax.
 description:        Djot (<https://djot.net>) is a light markup language.
                     This package provides a data structure to represent
diff --git a/src/Djot/Html.hs b/src/Djot/Html.hs
--- a/src/Djot/Html.hs
+++ b/src/Djot/Html.hs
@@ -273,7 +273,7 @@
                    Reference label -> do
                      rm <- gets referenceMap
                      case lookupReference label rm of
-                       Nothing -> pure $ Attr [("href", "")]
+                       Nothing -> pure mempty
                        Just (u, Attr as) -> pure $ Attr (("href",u):as)
         inTags "a" pos (attr' <> attr) <$> toBuilder ils
       Image ils target -> do
diff --git a/src/Djot/Inlines.hs b/src/Djot/Inlines.hs
--- a/src/Djot/Inlines.hs
+++ b/src/Djot/Inlines.hs
@@ -360,12 +360,12 @@
 pImage :: P Inlines
 pImage = do
   asciiChar '!'
-  (res, raw) <- withByteString pBracketed
+  res <- pBracketed
   case res of
     Left ils -> pure (str "!" <> ils)
     Right ils ->
             ((str "!" <>) <$> pAddAttributes (span_ ils))
-        <|> (image ils <$> (pDestination <|> pReference raw))
+        <|> (image ils <$> (pDestination <|> pReference ils))
         <|> pure (str "![" <> ils <> str "]")
 
 pAutolink :: P Inlines
@@ -381,20 +381,23 @@
 
 pLinkOrSpan :: P Inlines
 pLinkOrSpan = do
-  (res, raw) <- withByteString pBracketed
+  res <- pBracketed
   case res of
     Left ils -> pure ils
     Right ils ->
             (span_ ils <$ lookahead (asciiChar '{'))
-        <|> (link ils <$> (pDestination <|> pReference raw))
+        <|> (link ils <$> (pDestination <|> pReference ils))
         <|> pure (str "[" <> ils <> str "]")
 
 -- We allow balanced pairs of parens inside.
 pDestination :: P Target
 pDestination = do
+  oldActiveDelims <- activeDelims <$> getState
+  updateState $ \st -> st{ activeDelims = mempty }
   asciiChar '('
   res <- byteStringOf $ pInBalancedParens 0
   asciiChar ')'
+  updateState $ \st -> st{ activeDelims = oldActiveDelims }
   pure $ Direct (snd (handleEscapesAndNewlines res))
  where
   handleEscapesAndNewlines = B8.foldl' go (False, mempty)
@@ -416,16 +419,16 @@
             <|> ((nestlevel - 1) <$ asciiChar ')')
        pInBalancedParens lev
 
-pReference :: ByteString -> P Target
-pReference rawDescription = do
+pReference :: Inlines -> P Target
+pReference description = do
   asciiChar '['
   bs <- byteStringOf $ pAtMost 400 $ skipSatisfyByte
            (\c -> c /= '[' && c /= ']')
   asciiChar ']'
   let label = normalizeLabel $
               if B.null bs
-                 then B.drop 1 $ B.dropEnd 1
-                               $ B8.filter (/= '\n') rawDescription
+                 then B8.filter (/= '\n')
+                      $ inlinesToByteString description
                  else bs
   pure $ Reference label
 
diff --git a/test/links_and_images.test b/test/links_and_images.test
--- a/test/links_and_images.test
+++ b/test/links_and_images.test
@@ -87,7 +87,7 @@
 [link][a and
 b]
 .
-<p><a href="">link</a></p>
+<p><a>link</a></p>
 ```
 
 Reference definitions can't have line breaks in the key:
@@ -99,7 +99,7 @@
 [a and
 b]: url
 .
-<p><a href="">link</a></p>
+<p><a>link</a></p>
 <p>[a and
 b]: url</p>
 ```
@@ -111,7 +111,7 @@
 
 [link]: /url
 .
-<p><a href="">Link</a></p>
+<p><a>Link</a></p>
 ```
 
 Attributes on reference definitions get transferred to
@@ -140,7 +140,7 @@
 ```
 [link _and_ link][]
 
-[link _and_ link]: url
+[link and link]: url
 .
 <p><a href="url">link <em>and</em> link</a></p>
 ```
@@ -174,19 +174,32 @@
 <p><a href="hello *ab*">closed</a></p>
 ```
 
-Here the strong takes precedence over the link because it
-starts first:
+Here the link takes precedence because the star inside the
+destination is protected from closing emphasis:
 ```
 *[closed](hello*)
 .
-<p><strong>[closed](hello</strong>)</p>
+<p>*<a href="hello*">closed</a></p>
 ```
 
-Avoid this with a backslash escape:
+This also works with a backslash escape:
 ```
 *[closed](hello\*)
 .
 <p>*<a href="hello*">closed</a></p>
+```
+
+Underscores in link destinations don't interfere with emphasis:
+```
+_[link](http://example.com?foo_bar=1), more text_
+.
+<p><em><a href="http://example.com?foo_bar=1">link</a>, more text</em></p>
+```
+
+```
+_hello [link](a_b) world_
+.
+<p><em>hello <a href="a_b">link</a> world</em></p>
 ```
 
 Link in link?
