diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,17 @@
 # Changelog for commonmark
 
+## 0.3
+
+  * Applicative instances of IsBlock, IsInline etc. (Ashley Yakeley).
+    [API change]
+
+  * Require separation between title quotes and URL (Michael Howell).
+    This commit brings commonmark-hs into alignment with commonmark.js.
+
+  * Don't warn about deriving typeable.
+
+  * Add CPP to avoid warning for ghc >= 9.10.
+
 ## 0.2.6.1
 
   * Fix parsing of link destinations that look like `code` or
diff --git a/commonmark.cabal b/commonmark.cabal
--- a/commonmark.cabal
+++ b/commonmark.cabal
@@ -1,6 +1,6 @@
 cabal-version:  2.2
 name:           commonmark
-version:        0.2.6.1
+version:        0.3
 synopsis:       Pure Haskell commonmark parser.
 description:
    This library provides the core data types and functions
@@ -80,7 +80,7 @@
     ghc-options:      -Wunused-packages
   if impl(ghc >= 8.8)
     ghc-options:  -fwrite-ide-info -hiedir=.hie
-  ghc-options: -Wall -fno-warn-unused-do-bind -funbox-small-strict-fields
+  ghc-options: -Wall -fno-warn-deriving-typeable -fno-warn-unused-do-bind -funbox-small-strict-fields
   default-language: Haskell2010
   other-extensions: StrictData
 
diff --git a/src/Commonmark/Html.hs b/src/Commonmark/Html.hs
--- a/src/Commonmark/Html.hs
+++ b/src/Commonmark/Html.hs
@@ -3,6 +3,7 @@
 {-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE MonoLocalBinds             #-}
 module Commonmark.Html
   ( Html
   , htmlInline
diff --git a/src/Commonmark/Inlines.hs b/src/Commonmark/Inlines.hs
--- a/src/Commonmark/Inlines.hs
+++ b/src/Commonmark/Inlines.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE BangPatterns      #-}
@@ -50,7 +51,10 @@
 import           Commonmark.Types
 import           Control.Monad              (guard, mzero, mplus)
 import           Control.Monad.Trans.State.Strict
+#if MIN_VERSION_base(4,20,0)
+#else
 import           Data.List                  (foldl')
+#endif
 import           Unicode.Char               (isAscii, isAlpha)
 import qualified Data.IntMap.Strict         as IntMap
 import qualified Data.Map.Strict            as M
@@ -941,9 +945,8 @@
   _ <- symbol '('
   optional whitespace
   target <- untokenize <$> pLinkDestination
+  title <- option "" $ unEntity <$> (whitespace *> pLinkTitle)
   optional whitespace
-  title <- option "" $
-             unEntity <$> (pLinkTitle <* optional whitespace)
   _ <- symbol ')'
   return $! LinkInfo { linkDestination = target
                     , linkTitle = title
diff --git a/src/Commonmark/SourceMap.hs b/src/Commonmark/SourceMap.hs
--- a/src/Commonmark/SourceMap.hs
+++ b/src/Commonmark/SourceMap.hs
@@ -5,6 +5,7 @@
 {-# LANGUAGE MultiParamTypeClasses      #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE MonoLocalBinds             #-}
 module Commonmark.SourceMap
   ( SourceMap(..)
   , WithSourceMap(..)
diff --git a/src/Commonmark/Types.hs b/src/Commonmark/Types.hs
--- a/src/Commonmark/Types.hs
+++ b/src/Commonmark/Types.hs
@@ -2,6 +2,8 @@
 {-# LANGUAGE FunctionalDependencies     #-}
 {-# LANGUAGE OverloadedStrings          #-}
 {-# LANGUAGE MonoLocalBinds             #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE UndecidableInstances       #-}
 
 module Commonmark.Types
   ( Format(..)
@@ -79,6 +81,19 @@
   code :: Text -> a
   rawInline :: Format -> Text -> a
 
+instance {-# OVERLAPPABLE #-} (Applicative f, IsInline a, Monoid (f a), Show (f a)) => IsInline (f a) where
+  lineBreak = pure lineBreak
+  softBreak = pure softBreak
+  str t = pure $ str t
+  entity t = pure $ entity t
+  escapedChar c = pure $ escapedChar c
+  emph = fmap emph
+  strong = fmap strong
+  link d t = fmap $ link d t
+  image s t = fmap $ image s t
+  code t = pure $ code t
+  rawInline f t = pure $ rawInline f t
+
 class (Monoid b, Show b, Rangeable b, IsInline il, HasAttributes b)
       => IsBlock il b | b -> il where
   paragraph :: il -> b
@@ -95,6 +110,17 @@
                           -> b
   list :: ListType -> ListSpacing -> [b] -> b
 
+instance {-# OVERLAPPABLE #-} (Applicative f, Monoid (f il), Show (f il), Monoid (f b), Show (f b), IsBlock il b) => IsBlock (f il) (f b) where
+  paragraph = fmap paragraph
+  plain = fmap plain
+  thematicBreak = pure thematicBreak
+  blockQuote = fmap blockQuote
+  codeBlock p q = pure $ codeBlock p q
+  heading l = fmap $ heading l
+  rawBlock f t = pure $ rawBlock f t
+  referenceLinkDefinition l dt = pure $ referenceLinkDefinition l dt
+  list lt ls fbs = fmap (list lt ls) $ sequenceA fbs
+
 newtype SourceRange = SourceRange
         { unSourceRange :: [(SourcePos, SourcePos)] }
   deriving (Eq, Ord, Data, Typeable)
@@ -122,6 +148,9 @@
 class Rangeable a where
   ranged :: SourceRange -> a -> a
 
+instance {-# OVERLAPPABLE #-} (Functor f, Rangeable a) => Rangeable (f a) where
+  ranged sr = fmap $ ranged sr
+
 prettyRange :: SourceRange -> String
 prettyRange (SourceRange xs) = go "" xs
   where
@@ -147,6 +176,9 @@
 
 class HasAttributes a where
   addAttributes :: Attributes -> a -> a
+
+instance {-# OVERLAPPABLE #-} (Functor f, HasAttributes a) => HasAttributes (f a) where
+  addAttributes attrs = fmap $ addAttributes attrs
 
 class ToPlainText a where
   toPlainText :: a -> Text
diff --git a/test/regression.md b/test/regression.md
--- a/test/regression.md
+++ b/test/regression.md
@@ -482,3 +482,28 @@
 .
 <p><a href="%60">x</a> <a href="`"></p>
 ````````````````````````````````
+
+https://github.com/pulldown-cmark/pulldown-cmark/issues/1099
+
+Link must be separated from title by at least one space
+
+```````````````````````````````` example
+[a](https://example.com"test")
+[a](<https://example.com>"test")
+[a](https://example.com(test))
+[a](<https://example.com>(test))
+
+[a](https://example.com "test")
+[a](<https://example.com> "test")
+[a](https://example.com (test))
+[a](<https://example.com> (test))
+.
+<p><a href="https://example.com%22test%22">a</a>
+[a](<a href="https://example.com">https://example.com</a>&quot;test&quot;)
+<a href="https://example.com(test)">a</a>
+[a](<a href="https://example.com">https://example.com</a>(test))</p>
+<p><a href="https://example.com" title="test">a</a>
+<a href="https://example.com" title="test">a</a>
+<a href="https://example.com" title="test">a</a>
+<a href="https://example.com" title="test">a</a></p>
+````````````````````````````````
