diff --git a/README b/README
--- a/README
+++ b/README
@@ -2170,8 +2170,8 @@
     code rather than block quotations.  Text between `\begin{code}`
     and `\end{code}` will also be treated as Haskell code.
 
-  - In markdown output, code blocks with class `haskell` will be
-    rendered using bird tracks, and block quotations will be
+  - In markdown output, code blocks with classes `haskell` and `literate`
+    will be rendered using bird tracks, and block quotations will be
     indented one space, so they will not be treated as Haskell code.
     In addition, headers will be rendered setext-style (with underlines)
     rather than atx-style (with '#' characters). (This is because ghc
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,20 @@
+pandoc (1.9.0.4)
+
+  * Raised version bound on test-framework to avoid problems
+    compiling tests on GHC 7.4.1.
+
+  * LaTeX reader: Use raw LaTeX as fallback inline text for Cites,
+    so citations don't just disappear unless you process with
+    citeproc.  Ignore `\bibliographystyle`, `\nocite`.
+
+  * Simplified tex2pdf; it will always run latex twice to
+    resolve table of contents and hyperrefs.
+
+pandoc (1.9.0.3)
+
+  * Require Cabal >= 1.10.
+  * Tweaked cabal file to meet Cabal 1.10 requirements.
+
 pandoc (1.9.0.2)
 
   * Allow build with json 0.4 or 0.5.  Otherwise we can't build with
diff --git a/man/man1/pandoc.1 b/man/man1/pandoc.1
--- a/man/man1/pandoc.1
+++ b/man/man1/pandoc.1
@@ -1188,9 +1188,10 @@
 Text between \f[C]\\begin{code}\f[] and \f[C]\\end{code}\f[] will also
 be treated as Haskell code.
 .IP \[bu] 2
-In markdown output, code blocks with class \f[C]haskell\f[] will be
-rendered using bird tracks, and block quotations will be indented one
-space, so they will not be treated as Haskell code.
+In markdown output, code blocks with classes \f[C]haskell\f[] and
+\f[C]literate\f[] will be rendered using bird tracks, and block
+quotations will be indented one space, so they will not be treated as
+Haskell code.
 In addition, headers will be rendered setext-style (with underlines)
 rather than atx-style (with \[aq]#\[aq] characters).
 (This is because ghc treats \[aq]#\[aq] characters in column 1 as
diff --git a/pandoc.cabal b/pandoc.cabal
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -1,5 +1,5 @@
 Name:            pandoc
-Version:         1.9.0.3
+Version:         1.9.0.4
 Cabal-Version:   >= 1.10
 Build-Type:      Custom
 License:         GPL
@@ -400,7 +400,7 @@
   else
     Buildable:        False
   Other-Extensions: TemplateHaskell, QuasiQuotes
-  Build-Depends:    Diff, test-framework >= 0.3 && < 0.5,
+  Build-Depends:    Diff, test-framework >= 0.3 && < 0.6,
                     test-framework-hunit >= 0.2 && < 0.3,
                     test-framework-quickcheck2 >= 0.2.9 && < 0.3,
                     QuickCheck >= 2.4 && < 2.6,
diff --git a/src/Tests/Readers/LaTeX.hs b/src/Tests/Readers/LaTeX.hs
--- a/src/Tests/Readers/LaTeX.hs
+++ b/src/Tests/Readers/LaTeX.hs
@@ -7,7 +7,6 @@
 import Tests.Arbitrary()
 import Text.Pandoc.Builder
 import Text.Pandoc
-import Data.Monoid (mempty)
 
 latex :: String -> Pandoc
 latex = readLaTeX defaultParserState
@@ -65,16 +64,19 @@
                        , citationNoteNum = 0
                        , citationHash    = 0 }
 
+rt :: String -> Inlines
+rt = rawInline "latex"
+
 natbibCitations :: Test
 natbibCitations = testGroup "natbib"
   [ "citet" =: "\\citet{item1}"
-    =?> para (cite [baseCitation] mempty)
+    =?> para (cite [baseCitation] (rt "\\citet{item1}"))
   , "suffix" =: "\\citet[p.~30]{item1}"
     =?> para
-        (cite [baseCitation{ citationSuffix = toList $ text "p.\160\&30" }] mempty)
+        (cite [baseCitation{ citationSuffix = toList $ text "p.\160\&30" }] (rt "\\citet[p.~30]{item1}"))
   , "suffix long" =: "\\citet[p.~30, with suffix]{item1}"
     =?> para (cite [baseCitation{ citationSuffix =
-                       toList $ text "p.\160\&30, with suffix" }] mempty)
+                       toList $ text "p.\160\&30, with suffix" }] (rt "\\citet[p.~30, with suffix]{item1}"))
   , "multiple" =: "\\citeauthor{item1} \\citetext{\\citeyear{item1}; \\citeyear[p.~30]{item2}; \\citealp[see also][]{item3}}"
     =?> para (cite [baseCitation{ citationMode = AuthorInText }
                    ,baseCitation{ citationMode = SuppressAuthor
@@ -83,7 +85,7 @@
                    ,baseCitation{ citationId = "item3"
                                 , citationPrefix = [Str "see",Space,Str "also"]
                                 , citationMode = NormalCitation }
-                   ] mempty)
+                   ] (rt "\\citetext{\\citeyear{item1}; \\citeyear[p.~30]{item2}; \\citealp[see also][]{item3}}"))
   , "group" =: "\\citetext{\\citealp[see][p.~34--35]{item1}; \\citealp[also][chap. 3]{item3}}"
     =?> para (cite [baseCitation{ citationMode = NormalCitation
                                 , citationPrefix = [Str "see"]
@@ -92,36 +94,36 @@
                                 , citationId = "item3"
                                 , citationPrefix = [Str "also"]
                                 , citationSuffix = [Str "chap.",Space,Str "3"] }
-                   ] mempty)
+                   ] (rt "\\citetext{\\citealp[see][p.~34--35]{item1}; \\citealp[also][chap. 3]{item3}}"))
   , "suffix and locator" =: "\\citep[pp.~33, 35--37, and nowhere else]{item1}"
     =?> para (cite [baseCitation{ citationMode = NormalCitation
-                                , citationSuffix = [Str "pp.\160\&33,",Space,Str "35\8211\&37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] mempty)
+                                , citationSuffix = [Str "pp.\160\&33,",Space,Str "35\8211\&37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] (rt "\\citep[pp.~33, 35--37, and nowhere else]{item1}"))
   , "suffix only" =: "\\citep[and nowhere else]{item1}"
     =?> para (cite [baseCitation{ citationMode = NormalCitation
-                                , citationSuffix = toList $ text "and nowhere else" }] mempty)
+                                , citationSuffix = toList $ text "and nowhere else" }] (rt "\\citep[and nowhere else]{item1}"))
   , "no author" =: "\\citeyearpar{item1}, and now Doe with a locator \\citeyearpar[p.~44]{item2}"
-    =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] mempty <>
+    =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] (rt "\\citeyearpar{item1}") <>
               text ", and now Doe with a locator " <>
               cite [baseCitation{ citationMode = SuppressAuthor
                                 , citationSuffix = [Str "p.\160\&44"]
-                                , citationId = "item2" }] mempty)
+                                , citationId = "item2" }] (rt "\\citeyearpar[p.~44]{item2}"))
   , "markup" =: "\\citep[\\emph{see}][p. \\textbf{32}]{item1}"
     =?> para (cite [baseCitation{ citationMode = NormalCitation
                                 , citationPrefix = [Emph [Str "see"]]
                                 , citationSuffix = [Str "p.",Space,
-                                    Strong [Str "32"]] }] mempty)
+                                    Strong [Str "32"]] }] (rt "\\citep[\\emph{see}][p. \\textbf{32}]{item1}"))
   ]
 
 biblatexCitations :: Test
 biblatexCitations = testGroup "biblatex"
   [ "textcite" =: "\\textcite{item1}"
-    =?> para (cite [baseCitation] mempty)
+    =?> para (cite [baseCitation] (rt "\\textcite{item1}"))
   , "suffix" =: "\\textcite[p.~30]{item1}"
     =?> para
-        (cite [baseCitation{ citationSuffix = toList $ text "p.\160\&30" }] mempty)
+        (cite [baseCitation{ citationSuffix = toList $ text "p.\160\&30" }] (rt "\\textcite[p.~30]{item1}"))
   , "suffix long" =: "\\textcite[p.~30, with suffix]{item1}"
     =?> para (cite [baseCitation{ citationSuffix =
-                       toList $ text "p.\160\&30, with suffix" }] mempty)
+                       toList $ text "p.\160\&30, with suffix" }] (rt "\\textcite[p.~30, with suffix]{item1}"))
   , "multiple" =: "\\textcites{item1}[p.~30]{item2}[see also][]{item3}"
     =?> para (cite [baseCitation{ citationMode = AuthorInText }
                    ,baseCitation{ citationMode = NormalCitation
@@ -130,7 +132,7 @@
                    ,baseCitation{ citationId = "item3"
                                 , citationPrefix = [Str "see",Space,Str "also"]
                                 , citationMode = NormalCitation }
-                   ] mempty)
+                   ] (rt "\\textcites{item1}[p.~30]{item2}[see also][]{item3}"))
   , "group" =: "\\autocites[see][p.~34--35]{item1}[also][chap. 3]{item3}"
     =?> para (cite [baseCitation{ citationMode = NormalCitation
                                 , citationPrefix = [Str "see"]
@@ -139,24 +141,24 @@
                                 , citationId = "item3"
                                 , citationPrefix = [Str "also"]
                                 , citationSuffix = [Str "chap.",Space,Str "3"] }
-                   ] mempty)
+                   ] (rt "\\autocites[see][p.~34--35]{item1}[also][chap. 3]{item3}"))
   , "suffix and locator" =: "\\autocite[pp.~33, 35--37, and nowhere else]{item1}"
     =?> para (cite [baseCitation{ citationMode = NormalCitation
-                                , citationSuffix = [Str "pp.\160\&33,",Space,Str "35\8211\&37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] mempty)
+                                , citationSuffix = [Str "pp.\160\&33,",Space,Str "35\8211\&37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] (rt "\\autocite[pp.~33, 35--37, and nowhere else]{item1}"))
   , "suffix only" =: "\\autocite[and nowhere else]{item1}"
     =?> para (cite [baseCitation{ citationMode = NormalCitation
-                                , citationSuffix = toList $ text "and nowhere else" }] mempty)
+                                , citationSuffix = toList $ text "and nowhere else" }] (rt "\\autocite[and nowhere else]{item1}"))
   , "no author" =: "\\autocite*{item1}, and now Doe with a locator \\autocite*[p.~44]{item2}"
-    =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] mempty <>
+    =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] (rt "\\autocite*{item1}") <>
               text ", and now Doe with a locator " <>
               cite [baseCitation{ citationMode = SuppressAuthor
                                 , citationSuffix = [Str "p.\160\&44"]
-                                , citationId = "item2" }] mempty)
+                                , citationId = "item2" }] (rt "\\autocite*[p.~44]{item2}"))
   , "markup" =: "\\autocite[\\emph{see}][p. \\textbf{32}]{item1}"
     =?> para (cite [baseCitation{ citationMode = NormalCitation
                                 , citationPrefix = [Emph [Str "see"]]
                                 , citationSuffix = [Str "p.",Space,
-                                    Strong [Str "32"]] }] mempty)
+                                    Strong [Str "32"]] }] (rt "\\autocite[\\emph{see}][p. \\textbf{32}]{item1}"))
   , "parencite" =: "\\parencite{item1}"
-    =?> para (cite [baseCitation{ citationMode = NormalCitation }] mempty)
+    =?> para (cite [baseCitation{ citationMode = NormalCitation }] (rt "\\parencite{item1}"))
   ]
diff --git a/src/Text/Pandoc/PDF.hs b/src/Text/Pandoc/PDF.hs
--- a/src/Text/Pandoc/PDF.hs
+++ b/src/Text/Pandoc/PDF.hs
@@ -42,6 +42,7 @@
 import System.IO (hClose)
 import Control.Concurrent (putMVar, takeMVar, newEmptyMVar, forkIO)
 import Text.Pandoc.UTF8 as UTF8
+import Control.Monad (unless)
 
 tex2pdf :: String       -- ^ tex program (pdflatex, lualatex, xelatex)
         -> String       -- ^ latex source
@@ -54,7 +55,8 @@
          -> String                          -- ^ tex source
          -> IO (Either ByteString ByteString)
 tex2pdf' tmpDir program source = do
-  (exit, log', mbPdf) <- runTeXProgram program 3 tmpDir source
+  let numruns = 2 -- should suffice for toc and hyperrefs
+  (exit, log', mbPdf) <- runTeXProgram program numruns tmpDir source
   let msg = "Error producing PDF from TeX source."
   case (exit, mbPdf) of
        (ExitFailure _, _)      -> return $ Left $
@@ -76,41 +78,29 @@
      then log'
      else BC.unlines (msg'' ++ lineno)
 
-parseLine :: ByteString -> Bool
-parseLine ln =
-  if "LaTeX Warning:" `BC.isPrefixOf` ln
-      then if "Rerun" `elem` ws
-              then True
-              else False
-      else False
-   where ws = BC.words ln
-
-hasUndefinedRefs :: ByteString -> Bool
-hasUndefinedRefs = or . map parseLine . BC.lines
-
 -- running tex programs
 
 -- Run a TeX program on an input bytestring and return (exit code,
 -- contents of stdout, contents of produced PDF if any).  Rerun
--- latex as needed to resolve references, but don't run bibtex/biber.
+-- a fixed number of times to resolve references.
 runTeXProgram :: String -> Int -> FilePath -> String
               -> IO (ExitCode, ByteString, Maybe ByteString)
 runTeXProgram program runsLeft tmpDir source = do
-  withTempFile tmpDir "tex2pdf" $ \file h -> do
-    UTF8.hPutStr h source
-    hClose h
+    let file = tmpDir </> "input.tex"
+    exists <- doesFileExist file
+    unless exists $ UTF8.writeFile file source
     let programArgs = ["-halt-on-error", "-interaction", "nonstopmode",
          "-output-directory", tmpDir, file]
     (exit, out, err) <- readCommand program programArgs
-    removeFile file
-    let pdfFile = replaceDirectory (replaceExtension file ".pdf") tmpDir
-    pdfExists <- doesFileExist pdfFile
-    pdf <- if pdfExists
-              then Just `fmap` B.readFile pdfFile
-              else return Nothing
-    if hasUndefinedRefs out && runsLeft > 0
+    if runsLeft > 1
        then runTeXProgram program (runsLeft - 1) tmpDir source
-       else return (exit, out <> err, pdf)
+       else do
+         let pdfFile = replaceDirectory (replaceExtension file ".pdf") tmpDir
+         pdfExists <- doesFileExist pdfFile
+         pdf <- if pdfExists
+                   then Just `fmap` B.readFile pdfFile
+                   else return Nothing
+         return (exit, out <> err, pdf)
 
 -- utility functions
 
diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs
--- a/src/Text/Pandoc/Readers/LaTeX.hs
+++ b/src/Text/Pandoc/Readers/LaTeX.hs
@@ -250,7 +250,8 @@
     -- newcommand, etc. should be parsed by macro, but we need this
     -- here so these aren't parsed as inline commands to ignore
   , "special", "pdfannot", "pdfstringdef"
-  , "bibliography", "maketitle", "makeindex", "makeglossary"
+  , "bibliography", "bibliographystyle"
+  , "maketitle", "makeindex", "makeglossary"
   , "addcontentsline", "addtocontents", "addtocounter"
      -- \ignore{} is used conventionally in literate haskell for definitions
      -- that are to be processed by the compiler but not printed.
@@ -394,60 +395,60 @@
          pure (link url "" lab))
   , ("includegraphics", optional opt *> (unescapeURL <$> braced) >>=
        (\src -> pure (image src "" (str "image"))))
-  , ("cite", citation NormalCitation False)
-  , ("citep", citation NormalCitation False)
-  , ("citep*", citation NormalCitation False)
-  , ("citeal", citation NormalCitation False)
-  , ("citealp", citation NormalCitation False)
-  , ("citealp*", citation NormalCitation False)
-  , ("autocite", citation NormalCitation False)
-  , ("footcite", citation NormalCitation False)
-  , ("parencite", citation NormalCitation False)
-  , ("supercite", citation NormalCitation False)
-  , ("footcitetext", citation NormalCitation False)
-  , ("citeyearpar", citation SuppressAuthor False)
-  , ("citeyear", citation SuppressAuthor False)
-  , ("autocite*", citation SuppressAuthor False)
-  , ("cite*", citation SuppressAuthor False)
-  , ("parencite*", citation SuppressAuthor False)
-  , ("textcite", citation AuthorInText False)
-  , ("citet", citation AuthorInText False)
-  , ("citet*", citation AuthorInText False)
-  , ("citealt", citation AuthorInText False)
-  , ("citealt*", citation AuthorInText False)
-  , ("textcites", citation AuthorInText True)
-  , ("cites", citation NormalCitation True)
-  , ("autocites", citation NormalCitation True)
-  , ("footcites", citation NormalCitation True)
-  , ("parencites", citation NormalCitation True)
-  , ("supercites", citation NormalCitation True)
-  , ("footcitetexts", citation NormalCitation True)
-  , ("Autocite", citation NormalCitation False)
-  , ("Footcite", citation NormalCitation False)
-  , ("Parencite", citation NormalCitation False)
-  , ("Supercite", citation NormalCitation False)
-  , ("Footcitetext", citation NormalCitation False)
-  , ("Citeyearpar", citation SuppressAuthor False)
-  , ("Citeyear", citation SuppressAuthor False)
-  , ("Autocite*", citation SuppressAuthor False)
-  , ("Cite*", citation SuppressAuthor False)
-  , ("Parencite*", citation SuppressAuthor False)
-  , ("Textcite", citation AuthorInText False)
-  , ("Textcites", citation AuthorInText True)
-  , ("Cites", citation NormalCitation True)
-  , ("Autocites", citation NormalCitation True)
-  , ("Footcites", citation NormalCitation True)
-  , ("Parencites", citation NormalCitation True)
-  , ("Supercites", citation NormalCitation True)
-  , ("Footcitetexts", citation NormalCitation True)
+  , ("cite", citation "cite" NormalCitation False)
+  , ("citep", citation "citep" NormalCitation False)
+  , ("citep*", citation "citep*" NormalCitation False)
+  , ("citeal", citation "citeal" NormalCitation False)
+  , ("citealp", citation "citealp" NormalCitation False)
+  , ("citealp*", citation "citealp*" NormalCitation False)
+  , ("autocite", citation "autocite" NormalCitation False)
+  , ("footcite", citation "footcite" NormalCitation False)
+  , ("parencite", citation "parencite" NormalCitation False)
+  , ("supercite", citation "supercite" NormalCitation False)
+  , ("footcitetext", citation "footcitetext" NormalCitation False)
+  , ("citeyearpar", citation "citeyearpar" SuppressAuthor False)
+  , ("citeyear", citation "citeyear" SuppressAuthor False)
+  , ("autocite*", citation "autocite*" SuppressAuthor False)
+  , ("cite*", citation "cite*" SuppressAuthor False)
+  , ("parencite*", citation "parencite*" SuppressAuthor False)
+  , ("textcite", citation "textcite" AuthorInText False)
+  , ("citet", citation "citet" AuthorInText False)
+  , ("citet*", citation "citet*" AuthorInText False)
+  , ("citealt", citation "citealt" AuthorInText False)
+  , ("citealt*", citation "citealt*" AuthorInText False)
+  , ("textcites", citation "textcites" AuthorInText True)
+  , ("cites", citation "cites" NormalCitation True)
+  , ("autocites", citation "autocites" NormalCitation True)
+  , ("footcites", citation "footcites" NormalCitation True)
+  , ("parencites", citation "parencites" NormalCitation True)
+  , ("supercites", citation "supercites" NormalCitation True)
+  , ("footcitetexts", citation "footcitetexts" NormalCitation True)
+  , ("Autocite", citation "Autocite" NormalCitation False)
+  , ("Footcite", citation "Footcite" NormalCitation False)
+  , ("Parencite", citation "Parencite" NormalCitation False)
+  , ("Supercite", citation "Supercite" NormalCitation False)
+  , ("Footcitetext", citation "Footcitetext" NormalCitation False)
+  , ("Citeyearpar", citation "Citeyearpar" SuppressAuthor False)
+  , ("Citeyear", citation "Citeyear" SuppressAuthor False)
+  , ("Autocite*", citation "Autocite*" SuppressAuthor False)
+  , ("Cite*", citation "Cite*" SuppressAuthor False)
+  , ("Parencite*", citation "Parencite*" SuppressAuthor False)
+  , ("Textcite", citation "Textcite" AuthorInText False)
+  , ("Textcites", citation "Textcites" AuthorInText True)
+  , ("Cites", citation "Cites" NormalCitation True)
+  , ("Autocites", citation "Autocites" NormalCitation True)
+  , ("Footcites", citation "Footcites" NormalCitation True)
+  , ("Parencites", citation "Parencites" NormalCitation True)
+  , ("Supercites", citation "Supercites" NormalCitation True)
+  , ("Footcitetexts", citation "Footcitetexts" NormalCitation True)
   , ("citetext", complexNatbibCitation NormalCitation)
   , ("citeauthor", (try (tok *> optional sp *> controlSeq "citetext") *>
                         complexNatbibCitation AuthorInText)
-                   <|> citation AuthorInText False)
+                   <|> citation "citeauthor" AuthorInText False)
   ] ++ map ignoreInlines
   -- these commands will be ignored unless --parse-raw is specified,
   -- in which case they will appear as raw latex blocks:
-  [ "index" ]
+  [ "index", "nocite" ]
 
 unescapeURL :: String -> String
 unescapeURL ('\\':x:xs) | isEscapable x = x:unescapeURL xs
@@ -839,8 +840,10 @@
         AuthorInText   -> c {citationMode = mode} : cs
         _              -> map (\a -> a {citationMode = mode}) (c:cs)
 
-citation :: CitationMode -> Bool -> LP Inlines
-citation mode multi = (flip cite mempty) <$> cites mode multi
+citation :: String -> CitationMode -> Bool -> LP Inlines
+citation name mode multi = do
+  (c,raw) <- withRaw $ cites mode multi
+  return $ cite c (rawInline "latex" $ "\\" ++ name ++ raw)
 
 complexNatbibCitation :: CitationMode -> LP Inlines
 complexNatbibCitation mode = try $ do
@@ -858,8 +861,9 @@
                    skipSpaces
                    optional $ char ';'
                    return $ addPrefix pref $ addSuffix suff $ cits'
-  (c:cits) <- grouped parseOne
-  return $ cite (c{ citationMode = mode }:cits) mempty
+  (c:cits, raw) <- withRaw $ grouped parseOne
+  return $ cite (c{ citationMode = mode }:cits)
+           (rawInline "latex" $ "\\citetext" ++ raw)
 
 -- tables
 
diff --git a/tests/latex-reader.native b/tests/latex-reader.native
--- a/tests/latex-reader.native
+++ b/tests/latex-reader.native
@@ -259,7 +259,7 @@
 ,HorizontalRule
 ,Header 1 [Str "LaTeX"]
 ,BulletList
- [[Para [Cite [Citation {citationId = "smith.1899", citationPrefix = [], citationSuffix = [Str "22-23"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] []]]
+ [[Para [Cite [Citation {citationId = "smith.1899", citationPrefix = [], citationSuffix = [Str "22-23"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline "latex" "\\cite[22-23]{smith.1899}"]]]
  ,[Para [RawInline "latex" "\\doublespacing"]]
  ,[Para [Math InlineMath "2+2=4"]]
  ,[Para [Math InlineMath "x \\in y"]]
