diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
 # Revision history for djot
 
+## 0.1.4.2 -- 2026-08-27
+
+  * Djot renderer: emit raw blocks/inlines for formats other than djot (#18).
+
+  * Djot renderer: Fix calculation of fence length. We needed to add
+    one to the length of the biggest backtick string in the code.
+
+  * Fix two bugs in footnote handling:
+
+    - Allow spaces and newlines in footnote references, as with djot.js.
+    - Don't put a duplicate id on a second reference to same note.
+
 ## 0.1.4.1 -- 2026-07-21
 
   * Fix bug in verbatim parsing (#17). We were wrongly allowing
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.4.1
+version:            0.1.4.2
 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/Djot.hs b/src/Djot/Djot.hs
--- a/src/Djot/Djot.hs
+++ b/src/Djot/Djot.hs
@@ -11,7 +11,7 @@
 
 import Djot.AST
 import Djot.Options (RenderOptions(..))
-import Data.Char (ord, chr)
+import Data.Char (ord, chr, isSpace)
 import Djot.Parse (utf8ToStr)
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Char8 as B8
@@ -230,11 +230,7 @@
                     then pure ">"
                     else prefixed "> " <$> toLayout bls
                CodeBlock lang bs -> do
-                 let longesttickline =
-                       case B8.lines bs of
-                         [] -> 0
-                         ls -> maximum $ map (B8.length . B8.takeWhile (=='`')) ls
-                 let numticks = max 3 longesttickline
+                 let numticks = getFenceLength bs
                  let ticks = literal $ T.replicate numticks "`"
                  let lang' = if lang == mempty
                                 then mempty
@@ -251,7 +247,14 @@
                  pure $ body $+$ caption
                RawBlock (Format "djot") bs ->
                  pure $ literal (fromUtf8 bs)
-               RawBlock _ _ -> pure mempty)
+               RawBlock (Format f) bs
+                 | isSaneFormat f -> do
+                   let numticks = getFenceLength bs
+                   let ticks = literal $ T.replicate numticks "`"
+                   pure $ (ticks <> literal (fromUtf8 ("=" <> f)))
+                        $$ literal (fromUtf8 bs)
+                        $$ ticks
+                 | otherwise -> pure mempty)
          <* modify' (\st -> st{ afterSpace = True
                               -- Handle case of one bullet list right after
                               -- another; we need to change the bullet to
@@ -419,7 +422,10 @@
           EmailLink email -> pure $ "<" <> literal (fromUtf8 email) <> ">"
           UrlLink url -> pure $ "<" <> literal (fromUtf8 url) <> ">"
           RawInline (Format "djot") bs -> pure $ literal (fromUtf8 bs)
-          RawInline _ _ -> pure mempty
+          RawInline (Format f) bs
+            | isSaneFormat f ->
+                pure $ toVerbatimSpan bs <> literal (fromUtf8 ("{=" <> f <> "}"))
+            | otherwise -> pure mempty
           FootnoteReference label -> do
             order <- gets noteOrder
             case M.lookup label order of
@@ -493,3 +499,14 @@
    go (Node _pos _ (Div bls')) n =
      max (n + 1) (foldr go (n + 1) (unMany bls'))
    go _ n = n
+
+getFenceLength :: ByteString -> Int
+getFenceLength bs = max 3 (longesttickline + 1)
+  where
+    longesttickline =
+        case B8.lines bs of
+          [] -> 0
+          ls -> maximum $ map (B8.length . B8.takeWhile (=='`')) ls
+
+isSaneFormat :: ByteString -> Bool
+isSaneFormat bs = not (B8.any (\c -> isSpace c || c == '}' || c == '`') bs)
diff --git a/src/Djot/Html.hs b/src/Djot/Html.hs
--- a/src/Djot/Html.hs
+++ b/src/Djot/Html.hs
@@ -19,7 +19,7 @@
 import Data.ByteString.Builder (Builder, byteString, word8, intDec)
 import qualified Data.Sequence as Seq
 import qualified Data.Map.Strict as M
-import Data.Maybe (fromMaybe)
+import Data.Maybe (fromMaybe, isNothing)
 import Data.List (sort)
 import Control.Monad.State
 import qualified Data.Foldable as F
@@ -310,9 +310,10 @@
                                              M.insert label rendered (renderedNotes st) }
                    pure num
         let num' = B8.pack $ show num
-        pure $ inTags "a" pos (Attr [("id", "fnref" <> num'),
-                                     ("href", "#fn" <> num'),
-                                     ("role", "doc-noteref")] <> attr) $
+        pure $ inTags "a" pos (Attr ([("id", "fnref" <> num')
+                                       | isNothing (M.lookup label noterefs)] ++
+                                     [("href", "#fn" <> num'),
+                                      ("role", "doc-noteref")]) <> attr) $
                  inTags "sup" pos mempty (escapeHtml num')
 
 {-# INLINE inTags #-}
diff --git a/src/Djot/Inlines.hs b/src/Djot/Inlines.hs
--- a/src/Djot/Inlines.hs
+++ b/src/Djot/Inlines.hs
@@ -338,8 +338,7 @@
 pFootnoteReference = do
   asciiChar '['
   asciiChar '^'
-  label <- byteStringOf $ skipMany $
-             skipSatisfyByte (\c -> c /= ']' && not (isWs c))
+  label <- byteStringOf $ skipMany $ skipSatisfyByte (\c -> c /= ']')
   asciiChar ']'
   pure $ footnoteReference label
 
diff --git a/test/footnotes.test b/test/footnotes.test
--- a/test/footnotes.test
+++ b/test/footnotes.test
@@ -13,7 +13,7 @@
 another ref to the first note[^a].
 .
 <p>test<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a> and another<a id="fnref2" href="#fn2" role="doc-noteref"><sup>2</sup></a>.</p>
-<p>another ref to the first note<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a>.</p>
+<p>another ref to the first note<a href="#fn1" role="doc-noteref"><sup>1</sup></a>.</p>
 <section role="doc-endnotes">
 <hr>
 <ol>
@@ -85,7 +85,47 @@
 <p>very long footnote<a id="fnref2" href="#fn2" role="doc-noteref"><sup>2</sup></a><a href="#fnref1" role="doc-backlink">↩︎</a></p>
 </li>
 <li id="fn2">
-<p>bla bla<a id="fnref2" href="#fn2" role="doc-noteref"><sup>2</sup></a><a href="#fnref2" role="doc-backlink">↩︎</a></p>
+<p>bla bla<a href="#fn2" role="doc-noteref"><sup>2</sup></a><a href="#fnref2" role="doc-backlink">↩︎</a></p>
+</li>
+</ol>
+</section>
+```
+
+Footnote references are normalized like reference labels, so consecutive
+space/newlines are collapsed:
+```
+[^a
+  b]
+
+[^a b]:
+    foo
+.
+<p><a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
+<section role="doc-endnotes">
+<hr>
+<ol>
+<li id="fn1">
+<p>foo<a href="#fnref1" role="doc-backlink">↩︎</a></p>
+</li>
+</ol>
+</section>
+```
+
+Issue #146: Footnote labels can't contain line breaks (so this
+is interpreted not as a footnote but as an inline footnote reference):
+
+```
+[^a
+b]:  
+    foo
+.
+<p><a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a>:  
+foo</p>
+<section role="doc-endnotes">
+<hr>
+<ol>
+<li id="fn1">
+<p><a href="#fnref1" role="doc-backlink">↩︎</a></p>
 </li>
 </ol>
 </section>
