mirror of
https://github.com/jgm/pandoc.git
synced 2026-09-20 22:46:06 +00:00
A new command line option `--syntax-highlighting` is provided; it takes the values `none`, `default`, `idiomatic`, a style name, or a path to a theme file. It replaces the `--no-highlighting`, `--highlighting-style`, and `--listings` options. The `writerListings` and `writerHighlightStyle` fields of the `WriterOptions` type are replaced with `writerHighlightStyle`. Closes: #10525
256 lines
11 KiB
Haskell
256 lines
11 KiB
Haskell
{-# LANGUAGE OverloadedStrings #-}
|
|
module Tests.Writers.LaTeX (tests) where
|
|
|
|
import Data.Text (pack, unpack)
|
|
import Test.Tasty
|
|
import Test.Tasty.HUnit (HasCallStack)
|
|
import Tests.Helpers
|
|
import Text.Pandoc
|
|
import Text.Pandoc.Arbitrary ()
|
|
import Text.Pandoc.Builder
|
|
|
|
latex :: (ToPandoc a) => a -> String
|
|
latex = latexWithOpts def
|
|
|
|
latexListing :: (ToPandoc a) => a -> String
|
|
latexListing = latexWithOpts def{ writerHighlightMethod = IdiomaticHighlighting }
|
|
|
|
latexWithOpts :: (ToPandoc a) => WriterOptions -> a -> String
|
|
latexWithOpts opts = unpack . purely (writeLaTeX opts) . toPandoc
|
|
|
|
beamerWithOpts :: (ToPandoc a) => WriterOptions -> a -> String
|
|
beamerWithOpts opts = unpack . purely (writeBeamer opts) . toPandoc
|
|
|
|
{-
|
|
"my test" =: X =?> Y
|
|
|
|
is shorthand for
|
|
|
|
test latex "my test" $ X =?> Y
|
|
|
|
which is in turn shorthand for
|
|
|
|
test latex "my test" (X,Y)
|
|
-}
|
|
|
|
infix 4 =:
|
|
(=:) :: (ToString a, ToPandoc a, HasCallStack)
|
|
=> String -> (a, String) -> TestTree
|
|
(=:) = test latex
|
|
|
|
tests :: [TestTree]
|
|
tests = [ testGroup "code blocks"
|
|
[ "in footnotes" =: note (para "hi" <> codeBlock "hi") =?>
|
|
"\\footnote{hi\n\n\\begin{Verbatim}\nhi\n\\end{Verbatim}\n}"
|
|
, test latexListing "identifier" $ codeBlockWith ("id",[],[]) "hi" =?>
|
|
("\\begin{lstlisting}[label=id]\nhi\n\\end{lstlisting}" :: String)
|
|
, test latexListing "no identifier" $ codeBlock "hi" =?>
|
|
("\\begin{lstlisting}\nhi\n\\end{lstlisting}" :: String)
|
|
]
|
|
, testGroup "definition lists"
|
|
[ "with internal link" =: definitionList [(link "#go" "" (str "testing"),
|
|
[plain (text "hi there")])] =?>
|
|
"\\begin{description}\n\\tightlist\n\\item[{\\hyperref[go]{testing}}]\nhi there\n\\end{description}"
|
|
]
|
|
, testGroup "math"
|
|
[ "escape |" =: para (math "\\sigma|_{\\{x\\}}") =?>
|
|
"\\(\\sigma|_{\\{x\\}}\\)"
|
|
]
|
|
, testGroup "headers"
|
|
[ "unnumbered header" =:
|
|
headerWith ("foo",["unnumbered"],[]) 1
|
|
(text "Header 1" <> note (plain $ text "note")) =?>
|
|
"\\section*{\\texorpdfstring{Header 1\\footnote{note}}{Header 1}}\\label{foo}\n\\addcontentsline{toc}{section}{Header 1}\n"
|
|
, "in list item" =:
|
|
bulletList [header 2 (text "foo")] =?>
|
|
"\\begin{itemize}\n\\item ~\n \\subsection{foo}\n\\end{itemize}"
|
|
, "in definition list item" =:
|
|
definitionList [(text "foo", [header 2 (text "bar"),
|
|
para $ text "baz"])] =?>
|
|
"\\begin{description}\n\\item[foo] ~ \n\\subsection{bar}\n\nbaz\n\\end{description}"
|
|
, "containing image" =:
|
|
header 1 (image "imgs/foo.jpg" "" (text "Alt text")) =?>
|
|
"\\section{\\texorpdfstring{\\protect\\pandocbounded{\\includegraphics[keepaspectratio,alt={Alt text}]{imgs/foo.jpg}}}{Alt text}}"
|
|
]
|
|
, testGroup "inline code"
|
|
[ "struck out and highlighted" =:
|
|
strikeout (codeWith ("",["haskell"],[]) "foo" <> space
|
|
<> str "bar") =?>
|
|
"\\st{\\mbox{\\VERB|\\NormalTok{foo}|} bar}"
|
|
, "struck out and not highlighted" =:
|
|
strikeout (code "foo" <> space
|
|
<> str "bar") =?>
|
|
"\\st{\\mbox{\\texttt{foo}} bar}"
|
|
, "single quotes" =:
|
|
code "dog's" =?> "\\texttt{dog\\textquotesingle{}s}"
|
|
, "backtick" =:
|
|
code "`nu?`" =?> "\\texttt{\\textasciigrave{}nu?\\textasciigrave{}}"
|
|
]
|
|
, testGroup "inline note"
|
|
[ "Big note in emph" =:
|
|
emph (str "This sentence"
|
|
<> note (para (str "paragraph1")
|
|
<> para (str "paragraph2"))
|
|
<> str " has footnote.")
|
|
=?>
|
|
"\\emph{This sentence}\\footnote{paragraph1\n\n paragraph2}"
|
|
<> "\\emph{ has footnote.}"
|
|
, "Big note in strong" =:
|
|
strong (str "This sentence"
|
|
<> note (para (str "paragraph1")
|
|
<> para (str "paragraph2"))
|
|
<> str " has footnote.")
|
|
=?>
|
|
"\\textbf{This sentence}\\footnote{paragraph1\n\n paragraph2}"
|
|
<> "\\textbf{ has footnote.}"
|
|
|
|
, "Big note in underline" =:
|
|
underline (str "This sentence"
|
|
<> note (para (str "paragraph1")
|
|
<> para (str "paragraph2"))
|
|
<> str " has footnote.")
|
|
=?>
|
|
"\\ul{This sentence}\\footnote{paragraph1\n\n paragraph2}"
|
|
<> "\\ul{ has footnote.}"
|
|
|
|
, "Big note in strikeout" =:
|
|
strikeout (str "This sentence"
|
|
<> note (para (str "paragraph1")
|
|
<> para (str "paragraph2"))
|
|
<> str " has footnote.")
|
|
=?>
|
|
"\\st{This sentence}\\footnote{paragraph1\n\n paragraph2}"
|
|
<> "\\st{ has footnote.}"
|
|
|
|
, "Small note in emph" =:
|
|
emph (str "This sentence"
|
|
<> note (para (str "paragraph"))
|
|
<> str " has footnote.")
|
|
=?>
|
|
"\\emph{This sentence\\footnote{paragraph} has footnote.}"
|
|
|
|
, "Big note nested in emph and strong" =:
|
|
emph (str "This "
|
|
<> strong (str "nested sentence "
|
|
<> note (para (str "paragraph1")
|
|
<> para (str "paragraph2"))
|
|
<> str "has ")
|
|
<> str "footnote."
|
|
)
|
|
=?>
|
|
"\\emph{This \\textbf{nested sentence }}\\footnote{paragraph1\n\n"
|
|
<> " paragraph2}\\emph{\\textbf{has }footnote.}"
|
|
|
|
, "Two Big notes in emph" =:
|
|
emph (str "This sentence"
|
|
<> note (para (str "1-paragraph1")
|
|
<> para (str "1-paragraph2"))
|
|
<> str " has"
|
|
<> note (para (str "2-paragraph1")
|
|
<> para (str "2-paragraph2"))
|
|
<> str " footnote.")
|
|
=?>
|
|
"\\emph{This sentence}\\footnote{1-paragraph1\n\n 1-paragraph2}"
|
|
<> "\\emph{ has}\\footnote{2-paragraph1\n\n 2-paragraph2}"
|
|
<> "\\emph{ footnote.}"
|
|
]
|
|
, testGroup "writer options"
|
|
[ testGroup "top-level division" $
|
|
let
|
|
headers = header 1 (text "header1")
|
|
<> header 2 (text "header2")
|
|
<> header 3 (text "header3")
|
|
|
|
latexTopLevelDiv :: (ToPandoc a) => TopLevelDivision -> a -> String
|
|
latexTopLevelDiv division =
|
|
latexWithOpts def{ writerTopLevelDivision = division }
|
|
|
|
beamerTopLevelDiv :: (ToPandoc a)
|
|
=> TopLevelDivision -> a -> String
|
|
beamerTopLevelDiv division =
|
|
beamerWithOpts def { writerTopLevelDivision = division }
|
|
in
|
|
[ test (latexTopLevelDiv TopLevelSection)
|
|
"sections as top-level" $ headers =?>
|
|
unlines [ "\\section{header1}\n"
|
|
, "\\subsection{header2}\n"
|
|
, "\\subsubsection{header3}"
|
|
]
|
|
, test (latexTopLevelDiv TopLevelChapter)
|
|
"chapters as top-level" $ headers =?>
|
|
unlines [ "\\chapter{header1}\n"
|
|
, "\\section{header2}\n"
|
|
, "\\subsection{header3}"
|
|
]
|
|
, test (latexTopLevelDiv TopLevelPart)
|
|
"parts as top-level" $ headers =?>
|
|
unlines [ "\\part{header1}\n"
|
|
, "\\chapter{header2}\n"
|
|
, "\\section{header3}"
|
|
]
|
|
, test (latexTopLevelDiv TopLevelDefault)
|
|
"default top-level" $ headers =?>
|
|
unlines [ "\\section{header1}\n"
|
|
, "\\subsection{header2}\n"
|
|
, "\\subsubsection{header3}"
|
|
]
|
|
, test (beamerTopLevelDiv TopLevelSection)
|
|
"sections as top-level in beamer" $ headers =?>
|
|
unlines [ "\\section{header1}\n"
|
|
, "\\subsection{header2}\n"
|
|
, "\\subsubsection{header3}"
|
|
]
|
|
, test (beamerTopLevelDiv TopLevelChapter)
|
|
"chapters are as part in beamer" $ headers =?>
|
|
unlines [ "\\part{header1}\n"
|
|
, "\\section{header2}\n"
|
|
, "\\subsection{header3}"
|
|
]
|
|
, test (beamerTopLevelDiv TopLevelPart)
|
|
"parts as top-level in beamer" $ headers =?>
|
|
unlines [ "\\part{header1}\n"
|
|
, "\\section{header2}\n"
|
|
, "\\subsection{header3}"
|
|
]
|
|
, test (beamerTopLevelDiv TopLevelDefault)
|
|
"default top-level in beamer" $ headers =?>
|
|
unlines [ "\\section{header1}\n"
|
|
, "\\subsection{header2}\n"
|
|
, "\\subsubsection{header3}"
|
|
]
|
|
, test (latexTopLevelDiv TopLevelPart)
|
|
"part top-level, section not in toc" $
|
|
( headerWith ("", ["unnumbered"], []) 1 (text "header1")
|
|
<> headerWith ("", ["unnumbered"], []) 2 (text "header2")
|
|
<> headerWith ("", ["unnumbered"], []) 3 (text "header3")
|
|
<> headerWith ("", ["unnumbered"], []) 4 (text "header4")
|
|
<> headerWith ("", ["unnumbered"], []) 5 (text "header5")
|
|
<> headerWith ("", ["unnumbered"], []) 6 (text "header6"))
|
|
=?>
|
|
unlines [ "\\part*{header1}"
|
|
, "\\addcontentsline{toc}{part}{header1}\n"
|
|
, "\\chapter*{header2}"
|
|
, "\\addcontentsline{toc}{chapter}{header2}\n"
|
|
, "\\section*{header3}"
|
|
, "\\addcontentsline{toc}{section}{header3}\n"
|
|
, "\\subsection*{header4}"
|
|
, "\\addcontentsline{toc}{subsection}{header4}\n"
|
|
, "\\subsubsection*{header5}"
|
|
, "\\addcontentsline{toc}{subsubsection}{header5}\n"
|
|
, "\\paragraph*{header6}"
|
|
, "\\addcontentsline{toc}{paragraph}{header6}"
|
|
]
|
|
]
|
|
]
|
|
, testGroup "figures"
|
|
[ "placement" =:
|
|
figureWith ("", [], [("latex-placement", "htbp")])
|
|
(simpleCaption $ plain "caption")
|
|
(plain $ image (pack "img.jpg") (pack "") (text "alt text"))
|
|
=?>
|
|
"\\begin{figure}[htbp]\n\\centering\n"
|
|
<> "\\pandocbounded{\\includegraphics[keepaspectratio,alt={alt text}]{img.jpg}}\n"
|
|
<> "\\caption{caption}\n\\end{figure}"
|
|
]
|
|
]
|