diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,22 @@
 # Revision history for djot
 
+## 0.1.3 -- 2026-02-01
+
+* Fix nested sections bug when sections contain only lists (#14).
+  When a section contained only list elements (no paragraphs),
+  subsequent headings at the same level were incorrectly nested
+  inside the previous section instead of being siblings.
+
+* CLI: add `--version` option (#13).
+
+* Export version from Djot module. [API change]
+
+* Remove some INLINE pragmas. These don't make a measurable
+  difference in benchmarks.
+
+* There can't be a blank line btw block attrs and block.
+  Cf. https://github.com/jgm/djot.js/issues/118
+
 ## 0.1.2.4 -- 2025-11-30
 
 * Ensure that `'95--'96` doesn't get parsed as singlequoted.
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -5,13 +5,14 @@
 import qualified Data.ByteString as B
 import Data.ByteString.Builder (hPutBuilder)
 import Djot ( ParseOptions(..), RenderOptions(..), SourcePosOption(..),
-              parseDoc, renderHtml, renderDjot )
+              parseDoc, renderHtml, renderDjot, version )
 import System.Environment (getArgs)
 import System.IO (stderr, stdout, hPutStrLn)
 import System.Exit ( ExitCode(ExitFailure), exitWith, exitSuccess )
 import Text.DocLayout (render)
 import Text.Read (readMaybe)
 import qualified Data.Text.IO as TIO
+import Data.Version (showVersion)
 
 data OutputFormat = Html | Djot | Ast
   deriving (Eq, Show)
@@ -60,7 +61,11 @@
      putStrLn "  --wrap auto|preserve*|none"
      putStrLn "  --columns NUMBER"
      putStrLn "  --sourcepos none*|block|all"
+     putStrLn "  --version"
      putStrLn "  --help"
+     exitSuccess
+   go _opts ("--version" : _) = do
+     putStrLn $ "djot " <> showVersion version
      exitSuccess
    go opts (xs@('-':_) : as) =
      case break (== '=') xs of  -- support e.g. '--columns=33'
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.2.4
+version:            0.1.3
 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
@@ -44,6 +44,8 @@
                       Djot.Blocks
                       Djot.Html
                       Djot.Djot
+    other-modules:    Paths_djot
+    autogen-modules:  Paths_djot
     ghc-options: -Wall -O2
 
 executable djoths
diff --git a/src/Djot.hs b/src/Djot.hs
--- a/src/Djot.hs
+++ b/src/Djot.hs
@@ -7,6 +7,7 @@
   , SourcePosOption(..)
   , RenderOptions(..)
   , module Djot.AST
+  , version
   )
 where
 
@@ -15,3 +16,4 @@
 import Djot.Html (renderHtml)
 import Djot.Djot (renderDjot)
 import Djot.AST
+import Paths_djot (version)
diff --git a/src/Djot/Blocks.hs b/src/Djot/Blocks.hs
--- a/src/Djot/Blocks.hs
+++ b/src/Djot/Blocks.hs
@@ -43,6 +43,7 @@
                         , psReferenceMap = mempty
                         , psAutoReferenceMap = mempty
                         , psNoteMap = mempty
+                        , psLastAttributeLine = 0
                         , psAttributes = mempty
                         , psAttrParserState = Nothing
                         , psIds = mempty
@@ -748,7 +749,9 @@
       case parseAttributes Nothing bs of
         Done (attr, off)
           | B8.all isWs (B8.drop off bs) -> do
-             updateState $ \st -> st{ psAttributes = psAttributes st <> attr }
+             linenum <- sourceLine
+             updateState $ \st -> st{ psAttributes = psAttributes st <> attr
+                                    , psLastAttributeLine = linenum - 1 }
              pure container
           | otherwise -> do
              ils <- parseTextLines container
@@ -914,6 +917,7 @@
   , psReferenceMap :: ReferenceMap
   , psAutoReferenceMap :: ReferenceMap
   , psNoteMap :: NoteMap
+  , psLastAttributeLine :: Int
   , psAttributes :: Attr
   , psAttrParserState :: Maybe AttrParserState
   , psIds :: Set ByteString
@@ -956,7 +960,6 @@
                           replicateM_ (length (c:cs)) closeCurrentContainer
 
 
-{-# INLINE processLines #-}
 processLines :: P ()
 processLines = do
   -- check continuations for open containers and close any that don't match
@@ -1037,7 +1040,6 @@
     _ :| [] -> closeCurrentContainer >> finalize <$> getTip
     _ -> closeCurrentContainer >> finalizeDocument
 
-{-# INLINE closeCurrentContainer #-}
 -- | Close container and add to parent container.
 closeCurrentContainer :: P ()
 closeCurrentContainer = do
@@ -1063,16 +1065,17 @@
                      c{ containerEndLine = psLastLine st
                       , containerEndColumn = psLastColumnPrevLine st } :| [] }
 
-{-# INLINE modifyContainers #-}
 modifyContainers :: (NonEmpty Container -> NonEmpty Container) -> P ()
 modifyContainers f =
   updateState $ \st -> st{ psContainerStack = f (psContainerStack st) }
 
-{-# INLINE addContainer #-}
 addContainer :: BlockSpec -> Int -> ContainerData -> P ()
 addContainer bspec curcol bdata = do
   curline <- sourceLine
-  attr <- psAttributes <$> getState
+  lastAttrLine <- psLastAttributeLine <$> getState
+  attr <- if curline == lastAttrLine + 1
+             then psAttributes <$> getState
+             else pure mempty  -- ignore attributes with intervening blank line
   opts <- psParseOptions <$> getState
   let newcontainer = emptyContainer { containerSpec = bspec
                                     , containerStartLine = curline
@@ -1121,7 +1124,6 @@
   when (curindent < indent) $
      optional_ (spaceOrTab *> gobbleSpaceToIndent indent)
 
-{-# INLINE getTip #-}
 -- Get tip of container stack.
 getTip :: P Container
 getTip = NonEmpty.head . psContainerStack <$> getState
@@ -1130,10 +1132,13 @@
 closeContainingSections lev = do
   tip <- getTip
   case containerData tip of
-    SectionData lev' _ | lev' >= lev ->
-      closeCurrentContainer >>
-      closeContainingSections lev
-    _ -> pure ()
+    SectionData lev' _
+      | lev' >= lev -> closeCurrentContainer >> closeContainingSections lev
+      | otherwise -> pure ()  -- section with lower level, stop
+    _ | blockContainsBlock (containerSpec tip) /= Just Normal ->
+        -- close containers that can't directly contain sections (e.g., List)
+        closeCurrentContainer >> closeContainingSections lev
+    _ -> pure ()  -- container can hold sections, stop here
 
 -- TODO avoid detour through String
 toIdentifier :: ByteString -> ByteString
diff --git a/test/regression.test b/test/regression.test
--- a/test/regression.test
+++ b/test/regression.test
@@ -215,3 +215,43 @@
 .
 <p>I like the Lemon Jelly album titled ’64–’95.</p>
 ```
+
+https://github.com/jgm/djot.js/issues/118
+
+```
+{#ident
+  .class}
+
+Para
+.
+<p>Para</p>
+```
+
+Issue jgm/djoths#14 - nested sections with list-only content:
+
+```
+## Section 1
+
+- item
+
+## Section 2
+
+- item
+.
+<section id="Section-1">
+<h2>Section 1</h2>
+<ul>
+<li>
+item
+</li>
+</ul>
+</section>
+<section id="Section-2">
+<h2>Section 2</h2>
+<ul>
+<li>
+item
+</li>
+</ul>
+</section>
+```
