2018-03-18 18:46:28 +01:00
{- # LANGUAGE NoImplicitPrelude # -}
2011-01-22 05:50:18 +01:00
{- # LANGUAGE OverloadedStrings # -}
2019-02-04 22:52:31 +01:00
{- |
Module : Tests . Readers . LaTeX
2020-03-13 17:52:47 +01:00
Copyright : © 2006 - 2020 John MacFarlane
2019-02-04 22:52:31 +01:00
License : GNU GPL , version 2 or above
Maintainer : John MacFarlane < jgm @ berkeley . edu >
Stability : alpha
Portability : portable
Tests for the LaTeX reader .
- }
2011-01-12 19:10:56 +01:00
module Tests.Readers.LaTeX ( tests ) where
2011-01-12 14:16:35 +01:00
2018-03-18 18:46:28 +01:00
import Prelude
2017-10-28 05:28:29 +02:00
import Data.Text ( Text )
import qualified Data.Text as T
2017-12-15 19:13:43 +01:00
import qualified Text.Pandoc.UTF8 as UTF8
import Text.Pandoc.Readers.LaTeX ( tokenize , untokenize )
2017-03-14 17:05:36 +01:00
import Test.Tasty
2017-12-15 19:13:43 +01:00
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck
2011-01-13 19:59:44 +01:00
import Tests.Helpers
2011-01-19 08:34:34 +01:00
import Text.Pandoc
2017-03-04 13:03:41 +01:00
import Text.Pandoc.Arbitrary ( )
import Text.Pandoc.Builder
2011-01-19 08:34:34 +01:00
2017-06-10 18:26:44 +02:00
latex :: Text -> Pandoc
2017-01-15 20:42:00 +01:00
latex = purely $ readLaTeX def {
readerExtensions = getDefaultExtensions " latex " }
2011-01-22 05:50:18 +01:00
2012-02-05 22:23:06 +01:00
infix 4 =:
2011-01-22 05:50:18 +01:00
( =: ) :: ToString c
2017-06-10 18:26:44 +02:00
=> String -> ( Text , c ) -> TestTree
2011-01-22 05:50:18 +01:00
( =: ) = test latex
2011-01-12 14:16:35 +01:00
2020-07-23 20:23:21 +02:00
table' :: [ Alignment ] -> [ Row ] -> Blocks
table' aligns rows
2020-04-10 02:08:49 +02:00
= table emptyCaption
( zip aligns ( repeat ColWidthDefault ) )
( TableHead nullAttr [] )
2020-07-23 20:23:21 +02:00
[ TableBody nullAttr 0 [] rows ]
2020-04-10 02:08:49 +02:00
( TableFoot nullAttr [] )
2020-07-23 20:23:21 +02:00
simpleTable' :: [ Alignment ] -> [ [ Blocks ] ] -> Blocks
simpleTable' aligns rows
= table' aligns ( map toRow rows )
2020-04-10 02:08:49 +02:00
where
toRow = Row nullAttr . map simpleCell
2015-03-08 15:17:09 +01:00
2017-12-15 19:13:43 +01:00
tokUntokRt :: String -> Bool
tokUntokRt s = untokenize ( tokenize " random " t ) == t
where t = T . pack s
2017-03-14 17:05:36 +01:00
tests :: [ TestTree ]
2017-12-15 19:13:43 +01:00
tests = [ testGroup " tokenization "
[ testCase " tokenizer round trip on test case " $ do
orig <- T . pack <$> UTF8 . readFile " ../test/latex-reader.latex "
let new = untokenize $ tokenize " ../test/latex-reader.latex "
orig
assertEqual " untokenize . tokenize is identity " orig new
, testProperty " untokenize . tokenize is identity " tokUntokRt
]
, testGroup " basic "
2011-01-19 08:34:34 +01:00
[ " simple " =:
2011-01-23 01:01:14 +01:00
" word " =?> para " word "
2011-01-19 08:34:34 +01:00
, " space " =:
2013-12-20 02:43:25 +01:00
" some text " =?> para " some text "
2011-01-19 08:34:34 +01:00
, " emphasized " =:
2011-01-22 05:50:18 +01:00
" \ \ emph{emphasized} " =?> para ( emph " emphasized " )
2011-01-13 20:11:55 +01:00
]
, testGroup " headers "
2011-01-19 08:34:34 +01:00
[ " level 1 " =:
2013-09-01 18:13:31 +02:00
" \ \ section{header} " =?> headerWith ( " header " , [] , [] ) 1 " header "
2011-01-19 08:34:34 +01:00
, " level 2 " =:
2013-09-01 18:13:31 +02:00
" \ \ subsection{header} " =?> headerWith ( " header " , [] , [] ) 2 " header "
2011-01-19 08:34:34 +01:00
, " level 3 " =:
2013-09-01 18:13:31 +02:00
" \ \ subsubsection{header} " =?> headerWith ( " header " , [] , [] ) 3 " header "
2011-01-19 08:34:34 +01:00
, " emph " =:
2011-01-22 05:50:18 +01:00
" \ \ section{text \ \ emph{emph}} " =?>
2013-09-01 18:13:31 +02:00
headerWith ( " text-emph " , [] , [] ) 1 ( " text " <> space <> emph " emph " )
2011-01-19 08:34:34 +01:00
, " link " =:
2011-01-22 05:50:18 +01:00
" \ \ section{text \ \ href{/url}{link}} " =?>
2013-09-01 18:13:31 +02:00
headerWith ( " text-link " , [] , [] ) 1 ( " text " <> space <> link " /url " " " " link " )
2011-01-13 20:11:55 +01:00
]
2011-01-29 17:47:00 +01:00
2012-02-08 04:24:09 +01:00
, testGroup " math "
[ " escaped $ " =:
2012-02-08 04:24:09 +01:00
" $x= \ \ $4$ " =?> para ( math " x= \ \ $4 " )
2012-02-08 04:24:09 +01:00
]
2011-01-30 17:21:48 +01:00
, testGroup " space and comments "
[ " blank lines + space at beginning " =:
" \ n \ n hi " =?> para " hi "
, " blank lines + space + comments " =:
" % my comment \ n \ n \ n % another \ n \ n hi " =?> para " hi "
, " comment in paragraph " =:
Rewrote LaTeX reader with proper tokenization.
This rewrite is primarily motivated by the need to
get macros working properly. A side benefit is that the
reader is significantly faster (27s -> 19s in one
benchmark, and there is a lot of room for further
optimization).
We now tokenize the input text, then parse the token stream.
Macros modify the token stream, so they should now be effective
in any context, including math. Thus, we no longer need the clunky
macro processing capacities of texmath.
A custom state LaTeXState is used instead of ParserState.
This, plus the tokenization, will require some rewriting
of the exported functions rawLaTeXInline, inlineCommand,
rawLaTeXBlock.
* Added Text.Pandoc.Readers.LaTeX.Types (new exported module).
Exports Macro, Tok, TokType, Line, Column. [API change]
* Text.Pandoc.Parsing: adjusted type of `insertIncludedFile`
so it can be used with token parser.
* Removed old texmath macro stuff from Parsing.
Use Macro from Text.Pandoc.Readers.LaTeX.Types instead.
* Removed texmath macro material from Markdown reader.
* Changed types for Text.Pandoc.Readers.LaTeX's
rawLaTeXInline and rawLaTeXBlock. (Both now return a String,
and they are polymorphic in state.)
* Added orgMacros field to OrgState. [API change]
* Removed readerApplyMacros from ReaderOptions.
Now we just check the `latex_macros` reader extension.
* Allow `\newcommand\foo{blah}` without braces.
Fixes #1390.
Fixes #2118.
Fixes #3236.
Fixes #3779.
Fixes #934.
Fixes #982.
2017-07-01 19:31:43 +02:00
" hi % this is a comment \ n there \ n " =?>
para ( " hi " <> softbreak <> " there " )
2011-01-30 17:21:48 +01:00
]
2013-08-22 20:15:36 +02:00
, testGroup " code blocks "
[ " identifier " =:
" \ \ begin{lstlisting}[label=test] \ \ end{lstlisting} " =?> codeBlockWith ( " test " , [] , [ ( " label " , " test " ) ] ) " "
, " no identifier " =:
" \ \ begin{lstlisting} \ \ end{lstlisting} " =?> codeBlock " "
]
2015-03-08 15:17:09 +01:00
, testGroup " tables "
[ " Single cell table " =:
" \ \ begin{tabular}{|l|}Test \ \ \ \ \ \ end{tabular} " =?>
simpleTable' [ AlignLeft ] [ [ plain " Test " ] ]
, " Multi cell table " =:
" \ \ begin{tabular}{|rl|}One & Two \ \ \ \ \ \ end{tabular} " =?>
simpleTable' [ AlignRight , AlignLeft ] [ [ plain " One " , plain " Two " ] ]
, " Multi line table " =:
2017-06-10 18:26:44 +02:00
T . unlines [ " \ \ begin{tabular}{|c|} "
2015-03-08 15:17:09 +01:00
, " One \ \ \ \ "
, " Two \ \ \ \ "
, " Three \ \ \ \ "
, " \ \ end{tabular} " ] =?>
simpleTable' [ AlignCenter ]
[ [ plain " One " ] , [ plain " Two " ] , [ plain " Three " ] ]
, " Empty table " =:
" \ \ begin{tabular}{} \ \ end{tabular} " =?>
simpleTable' [] []
, " Table with fixed column width " =:
" \ \ begin{tabular}{|p{5cm}r|}One & Two \ \ \ \ \ \ end{tabular} " =?>
simpleTable' [ AlignLeft , AlignRight ] [ [ plain " One " , plain " Two " ] ]
, " Table with empty column separators " =:
" \ \ begin{tabular}{@{}r@{}l}One & Two \ \ \ \ \ \ end{tabular} " =?>
simpleTable' [ AlignRight , AlignLeft ] [ [ plain " One " , plain " Two " ] ]
2015-03-08 15:47:39 +01:00
, " Table with custom column separators " =:
2017-06-10 18:26:44 +02:00
T . unlines [ " \ \ begin{tabular}{@{($ \ \ to$)}r@{ \ \ hspace{2cm}}l} "
2015-03-08 15:47:39 +01:00
, " One&Two \ \ \ \ "
, " \ \ end{tabular} " ] =?>
simpleTable' [ AlignRight , AlignLeft ] [ [ plain " One " , plain " Two " ] ]
2015-03-08 15:30:05 +01:00
, " Table with vertical alignment argument " =:
" \ \ begin{tabular}[t]{r|r}One & Two \ \ \ \ \ \ end{tabular} " =?>
simpleTable' [ AlignRight , AlignRight ] [ [ plain " One " , plain " Two " ] ]
2020-07-23 20:23:21 +02:00
, " Table with multicolumn item " =:
" \ \ begin{tabular}{l c r} \ \ multicolumn{2}{c}{One} & Two \ \ \ \ \ \ end{tabular} " =?>
table' [ AlignLeft , AlignCenter , AlignRight ]
[ Row nullAttr [ cell AlignCenter ( RowSpan 1 ) ( ColSpan 2 ) ( plain " One " )
, simpleCell ( plain " Two " )
]
]
2020-08-08 07:45:47 +02:00
, " table with multicolumn item (#6596) " =:
" \ \ begin{tabular}{l c r}One & \ \ multicolumn{2}{c}{Two} & \ \ \ \ \ \ end{tabular} " =?>
table' [ AlignLeft , AlignCenter , AlignRight ]
[ Row nullAttr [ simpleCell ( plain " One " )
, cell AlignCenter ( RowSpan 1 ) ( ColSpan 2 ) ( plain " Two " )
]
]
2020-07-23 20:23:21 +02:00
, " Table with multirow item " =:
T . unlines [ " \ \ begin{tabular}{c} "
2020-08-15 20:40:10 +02:00
, " \ \ multirow{2}{5em}{One} \ \ \ \ Two \ \ \ \ "
2020-07-23 20:23:21 +02:00
, " \ \ end{tabular} "
] =?>
table' [ AlignCenter ]
2020-08-15 20:40:10 +02:00
[ Row nullAttr [ cell AlignDefault ( RowSpan 2 ) ( ColSpan 1 ) ( plain " One " ) ]
, Row nullAttr [ simpleCell ( plain " Two " ) ]
]
, " Table with multirow item using full prototype " =:
T . unlines [ " \ \ begin{tabular}{c} "
, " \ \ multirow[c]{2}[3]{5em}[1in]{One} \ \ \ \ Two \ \ \ \ "
, " \ \ end{tabular} "
] =?>
table' [ AlignCenter ]
[ Row nullAttr [ cell AlignDefault ( RowSpan 2 ) ( ColSpan 1 ) ( plain " One " ) ]
2020-07-23 20:23:21 +02:00
, Row nullAttr [ simpleCell ( plain " Two " ) ]
]
, " Table with nested multirow/multicolumn item " =:
2020-09-15 22:36:11 +02:00
T . unlines [ " \ \ begin{tabular}{c c c c} "
, " \ \ multicolumn{3}{c}{ \ \ multirow{2}{5em}{One}}&Two \ \ \ \ "
, " \ \ multicolumn{2}{c}{} & & Three \ \ \ \ "
, " Four&Five&Six&Seven \ \ \ \ "
2020-07-23 20:23:21 +02:00
, " \ \ end{tabular} "
] =?>
2020-09-15 22:36:11 +02:00
table' [ AlignCenter , AlignCenter , AlignCenter , AlignCenter ]
[ Row nullAttr [ cell AlignCenter ( RowSpan 2 ) ( ColSpan 3 ) ( plain " One " )
2020-07-23 20:23:21 +02:00
, simpleCell ( plain " Two " )
]
, Row nullAttr [ simpleCell ( plain " Three " ) ]
, Row nullAttr [ simpleCell ( plain " Four " )
, simpleCell ( plain " Five " )
, simpleCell ( plain " Six " )
2020-09-15 22:36:11 +02:00
, simpleCell ( plain " Seven " )
2020-07-23 20:23:21 +02:00
]
]
, " Table with multicolumn header " =:
T . unlines [ " \ \ begin{tabular}{ |l|l| } "
, " \ \ hline \ \ multicolumn{2}{|c|}{Header} \ \ \ \ "
, " \ \ hline key & val \ \ \ \ "
, " \ \ hline \ \ end{tabular} "
] =?>
table emptyCaption
( zip [ AlignLeft , AlignLeft ] ( repeat ColWidthDefault ) )
( TableHead nullAttr [ Row nullAttr [ cell AlignCenter ( RowSpan 1 ) ( ColSpan 2 ) ( plain " Header " ) ] ] )
[ TableBody nullAttr 0 [] [ Row nullAttr [ simpleCell ( plain " key " )
, simpleCell ( plain " val " )
]
]
]
( TableFoot nullAttr [] )
2020-09-15 22:36:11 +02:00
, " Table with normal empty cells " =:
T . unlines [ " \ \ begin{tabular}{|r|r|r|} "
, " A & & B \ \ \ \ "
, " & C & "
, " \ \ end{tabular} "
] =?>
table emptyCaption
( replicate 3 ( AlignRight , ColWidthDefault ) )
( TableHead nullAttr [] )
[ TableBody nullAttr 0 []
[ Row nullAttr [ simpleCell ( plain " A " )
, emptyCell
, simpleCell ( plain " B " )
]
, Row nullAttr [ emptyCell
, simpleCell ( plain " C " )
, emptyCell
] ] ]
( TableFoot nullAttr [] )
2015-03-08 15:17:09 +01:00
]
2011-01-29 17:47:00 +01:00
, testGroup " citations "
[ natbibCitations
, biblatexCitations
]
2015-04-13 02:22:39 +02:00
2017-10-13 15:11:29 +02:00
, testGroup " images "
[ " Basic image " =:
" \ \ includegraphics{foo.png} " =?>
para ( image " foo.png " " " ( text " image " ) )
, " Basic image with blank options " =:
" \ \ includegraphics[]{foo.png} " =?>
para ( image " foo.png " " " ( text " image " ) )
, " Image with both width and height " =:
" \ \ includegraphics[width=17cm,height=5cm]{foo.png} " =?>
para ( imageWith ( " " , [] , [ ( " width " , " 17cm " ) , ( " height " , " 5cm " ) ] ) " foo.png " " " " image " )
, " Image with width and height and a bunch of other options " =:
" \ \ includegraphics[width=17cm,height=5cm,clip,keepaspectratio]{foo.png} " =?>
para ( imageWith ( " " , [] , [ ( " width " , " 17cm " ) , ( " height " , " 5cm " ) ] ) " foo.png " " " " image " )
, " Image with just width " =:
" \ \ includegraphics[width=17cm]{foo.png} " =?>
para ( imageWith ( " " , [] , [ ( " width " , " 17cm " ) ] ) " foo.png " " " " image " )
, " Image with just height " =:
" \ \ includegraphics[height=17cm]{foo.png} " =?>
para ( imageWith ( " " , [] , [ ( " height " , " 17cm " ) ] ) " foo.png " " " " image " )
, " Image width relative to textsize " =:
" \ \ includegraphics[width=0.6 \ \ textwidth]{foo.png} " =?>
para ( imageWith ( " " , [] , [ ( " width " , " 60% " ) ] ) " foo.png " " " " image " )
2017-10-13 15:49:00 +02:00
, " Image with options with spaces " =:
" \ \ includegraphics[width=12cm, height = 5cm]{foo.png} " =?>
para ( imageWith ( " " , [] , [ ( " width " , " 12cm " ) , ( " height " , " 5cm " ) ] ) " foo.png " " " " image " )
2017-10-13 15:11:29 +02:00
]
2015-04-13 02:22:39 +02:00
, let hex = [ '0' .. '9' ] ++ [ 'a' .. 'f' ] in
testGroup " Character Escapes "
[ " Two-character escapes " =:
2017-06-10 18:26:44 +02:00
mconcat [ " ^^ " <> T . pack [ i , j ] | i <- hex , j <- hex ] =?>
Switch to new pandoc-types and use Text instead of String [API change].
PR #5884.
+ Use pandoc-types 1.20 and texmath 0.12.
+ Text is now used instead of String, with a few exceptions.
+ In the MediaBag module, some of the types using Strings
were switched to use FilePath instead (not Text).
+ In the Parsing module, new parsers `manyChar`, `many1Char`,
`manyTillChar`, `many1TillChar`, `many1Till`, `manyUntil`,
`mantyUntilChar` have been added: these are like their
unsuffixed counterparts but pack some or all of their output.
+ `glob` in Text.Pandoc.Class still takes String since it seems
to be intended as an interface to Glob, which uses strings.
It seems to be used only once in the package, in the EPUB writer,
so that is not hard to change.
2019-11-04 22:12:37 +01:00
para ( str $ T . pack [ '\ 0 '.. '\ 255 ' ] )
2015-04-13 02:22:39 +02:00
, " One-character escapes " =:
2017-06-10 18:26:44 +02:00
mconcat [ " ^^ " <> T . pack [ i ] | i <- hex ] =?>
Switch to new pandoc-types and use Text instead of String [API change].
PR #5884.
+ Use pandoc-types 1.20 and texmath 0.12.
+ Text is now used instead of String, with a few exceptions.
+ In the MediaBag module, some of the types using Strings
were switched to use FilePath instead (not Text).
+ In the Parsing module, new parsers `manyChar`, `many1Char`,
`manyTillChar`, `many1TillChar`, `many1Till`, `manyUntil`,
`mantyUntilChar` have been added: these are like their
unsuffixed counterparts but pack some or all of their output.
+ `glob` in Text.Pandoc.Class still takes String since it seems
to be intended as an interface to Glob, which uses strings.
It seems to be used only once in the package, in the EPUB writer,
so that is not hard to change.
2019-11-04 22:12:37 +01:00
para ( str $ T . pack $ [ 'p' .. 'y' ] ++ [ '!' .. '&' ] )
2015-04-13 02:22:39 +02:00
]
2017-08-05 19:03:31 +02:00
, testGroup " memoir scene breaks "
[ " plainbreak " =:
" hello \ \ plainbreak{2}goodbye " =?>
para ( str " hello " ) <> horizontalRule <> para ( str " goodbye " )
, " plainbreak* " =:
" hello \ \ plainbreak*{2}goodbye " =?>
para ( str " hello " ) <> horizontalRule <> para ( str " goodbye " )
, " fancybreak " =:
" hello \ \ fancybreak{b r e a k}goodbye " =?>
para ( str " hello " ) <> horizontalRule <> para ( str " goodbye " )
, " fancybreak* " =:
" hello \ \ fancybreak*{b r e a k}goodbye " =?>
para ( str " hello " ) <> horizontalRule <> para ( str " goodbye " )
, " plainfancybreak " =:
" hello \ \ plainfancybreak{4}{2}{b r e a k}goodbye " =?>
para ( str " hello " ) <> horizontalRule <> para ( str " goodbye " )
, " plainfancybreak* " =:
" hello \ \ plainfancybreak*{4}{2}{b r e a k}goodbye " =?>
para ( str " hello " ) <> horizontalRule <> para ( str " goodbye " )
, " pfbreak " =:
" hello \ \ pfbreak{}goodbye " =?>
para ( str " hello " ) <> horizontalRule <> para ( str " goodbye " )
, " pfbreak* " =:
" hello \ \ pfbreak*{}goodbye " =?>
para ( str " hello " ) <> horizontalRule <> para ( str " goodbye " )
]
2017-08-24 18:45:58 +02:00
, testGroup " biblatex roman numerals "
[ " upper " =:
" number \ \ RN{12} " =?>
para ( str " number " <> space <> str " XII " )
, " lower " =:
" number \ \ Rn{29} " =?>
para ( str " number " <> space <> str " xxix " )
, " leading zero " =:
" \ \ Rn{014} " =?>
para ( str " xiv " )
, " surrounding spaces " =:
" number \ \ Rn{ 41 } " =?>
para ( str " number " <> space <> str " xli " )
, " zero " =:
" \ \ RN{0} " =?>
para ( str " " )
, " space then unbraced argument " =:
" \ \ RN 7 ok " =?>
para ( str " VII " <> space <> str " ok " )
, " space before braced argument " =:
" \ \ Rn {13}ok " =?>
para ( str " xiiiok " )
]
2017-10-06 13:17:50 +02:00
, testGroup " polyglossia language spans "
[ " french " =:
" hello \ \ textfrench{bonjour} " =?>
para ( str " hello " <> space <> spanWith ( " " , [] , [ ( " lang " , " fr " ) ] ) ( str " bonjour " ) )
, " nested " =:
" \ \ textfrench{quelle c'est \ \ textlatin{primus}?} " =?>
para ( spanWith ( " " , [] , [ ( " lang " , " fr " ) ] ) $
str " quelle " <> space <> str " c \ 8217 est " <> space <>
spanWith ( " " , [] , [ ( " lang " , " la " ) ] ) ( str " primus " ) <> str " ? " )
, " with formatting " =:
" \ \ textgerman{wie \ \ emph{spaet} ist es?} " =?>
para ( spanWith ( " " , [] , [ ( " lang " , " de " ) ] ) $
str " wie " <> space <> emph ( str " spaet " ) <> space <> str " ist " <> space <> str " es? " )
, " language options " =:
" \ \ textgerman[variant=swiss]{hoechdeutsche} " =?>
para ( spanWith ( " " , [] , [ ( " lang " , " de-CH " ) ] ) $ str " hoechdeutsche " )
, " unknown option fallback " =:
" \ \ textgerman[variant=moon]{ueberhoechdeutsche} " =?>
para ( spanWith ( " " , [] , [ ( " lang " , " de " ) ] ) $ str " ueberhoechdeutsche " )
]
2011-01-12 14:16:35 +01:00
]
2011-01-29 17:47:00 +01:00
baseCitation :: Citation
2012-10-22 08:16:23 +02:00
baseCitation = Citation { citationId = " item1 "
, citationPrefix = []
, citationSuffix = []
, citationMode = AuthorInText
, citationNoteNum = 0
2012-10-23 04:11:56 +02:00
, citationHash = 0
2012-10-28 17:36:15 +01:00
}
2011-01-29 17:47:00 +01:00
2012-02-06 21:41:34 +01:00
rt :: String -> Inlines
Switch to new pandoc-types and use Text instead of String [API change].
PR #5884.
+ Use pandoc-types 1.20 and texmath 0.12.
+ Text is now used instead of String, with a few exceptions.
+ In the MediaBag module, some of the types using Strings
were switched to use FilePath instead (not Text).
+ In the Parsing module, new parsers `manyChar`, `many1Char`,
`manyTillChar`, `many1TillChar`, `many1Till`, `manyUntil`,
`mantyUntilChar` have been added: these are like their
unsuffixed counterparts but pack some or all of their output.
+ `glob` in Text.Pandoc.Class still takes String since it seems
to be intended as an interface to Glob, which uses strings.
It seems to be used only once in the package, in the EPUB writer,
so that is not hard to change.
2019-11-04 22:12:37 +01:00
rt = rawInline " latex " . T . pack
2012-02-06 21:41:34 +01:00
2017-03-14 17:05:36 +01:00
natbibCitations :: TestTree
2011-01-29 17:47:00 +01:00
natbibCitations = testGroup " natbib "
[ " citet " =: " \ \ citet{item1} "
2012-02-06 21:41:34 +01:00
=?> para ( cite [ baseCitation ] ( rt " \ \ citet{item1} " ) )
2011-01-29 17:47:00 +01:00
, " suffix " =: " \ \ citet[p.~30]{item1} "
=?> para
2013-07-21 20:44:49 +02:00
( cite [ baseCitation { citationSuffix = toList $ text " p. \ 160 \ & 30 " } ] ( rt " \ \ citet[p.~30]{item1} " ) )
2011-01-29 17:47:00 +01:00
, " suffix long " =: " \ \ citet[p.~30, with suffix]{item1} "
=?> para ( cite [ baseCitation { citationSuffix =
2013-07-21 20:44:49 +02:00
toList $ text " p. \ 160 \ & 30, with suffix " } ] ( rt " \ \ citet[p.~30, with suffix]{item1} " ) )
2011-01-29 17:47:00 +01:00
, " multiple " =: " \ \ citeauthor{item1} \ \ citetext{ \ \ citeyear{item1}; \ \ citeyear[p.~30]{item2}; \ \ citealp[see also][]{item3}} "
=?> para ( cite [ baseCitation { citationMode = AuthorInText }
, baseCitation { citationMode = SuppressAuthor
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " p. \ 160 \ & 30 " ]
2011-01-29 17:47:00 +01:00
, citationId = " item2 " }
, baseCitation { citationId = " item3 "
, citationPrefix = [ Str " see " , Space , Str " also " ]
, citationMode = NormalCitation }
2012-02-06 21:41:34 +01:00
] ( rt " \ \ citetext{ \ \ citeyear{item1}; \ \ citeyear[p.~30]{item2}; \ \ citealp[see also][]{item3}} " ) )
2011-01-29 17:47:00 +01:00
, " group " =: " \ \ citetext{ \ \ citealp[see][p.~34--35]{item1}; \ \ citealp[also][chap. 3]{item3}} "
=?> para ( cite [ baseCitation { citationMode = NormalCitation
, citationPrefix = [ Str " see " ]
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " p. \ 160 \ & 34 \ 8211 \ & 35 " ] }
2011-01-29 17:47:00 +01:00
, baseCitation { citationMode = NormalCitation
, citationId = " item3 "
, citationPrefix = [ Str " also " ]
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " chap. " , Space , Str " 3 " ] }
2012-02-06 21:41:34 +01:00
] ( rt " \ \ citetext{ \ \ citealp[see][p.~34--35]{item1}; \ \ citealp[also][chap. 3]{item3}} " ) )
2011-01-29 17:47:00 +01:00
, " suffix and locator " =: " \ \ citep[pp.~33, 35--37, and nowhere else]{item1} "
=?> para ( cite [ baseCitation { citationMode = NormalCitation
2013-07-21 20:44:49 +02:00
, 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} " ) )
2011-01-29 17:47:00 +01:00
, " suffix only " =: " \ \ citep[and nowhere else]{item1} "
=?> para ( cite [ baseCitation { citationMode = NormalCitation
2013-07-21 20:44:49 +02:00
, citationSuffix = toList $ text " and nowhere else " } ] ( rt " \ \ citep[and nowhere else]{item1} " ) )
2011-01-29 17:47:00 +01:00
, " no author " =: " \ \ citeyearpar{item1}, and now Doe with a locator \ \ citeyearpar[p.~44]{item2} "
2012-02-06 21:41:34 +01:00
=?> para ( cite [ baseCitation { citationMode = SuppressAuthor } ] ( rt " \ \ citeyearpar{item1} " ) <>
2011-12-13 23:29:07 +01:00
text " , and now Doe with a locator " <>
2011-01-29 17:47:00 +01:00
cite [ baseCitation { citationMode = SuppressAuthor
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " p. \ 160 \ & 44 " ]
2012-02-06 21:41:34 +01:00
, citationId = " item2 " } ] ( rt " \ \ citeyearpar[p.~44]{item2} " ) )
2011-01-29 17:47:00 +01:00
, " markup " =: " \ \ citep[ \ \ emph{see}][p. \ \ textbf{32}]{item1} "
=?> para ( cite [ baseCitation { citationMode = NormalCitation
, citationPrefix = [ Emph [ Str " see " ] ]
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " p. " , Space ,
2012-02-06 21:41:34 +01:00
Strong [ Str " 32 " ] ] } ] ( rt " \ \ citep[ \ \ emph{see}][p. \ \ textbf{32}]{item1} " ) )
2011-01-29 17:47:00 +01:00
]
2017-03-14 17:05:36 +01:00
biblatexCitations :: TestTree
2011-01-29 17:47:00 +01:00
biblatexCitations = testGroup " biblatex "
2011-01-29 18:01:30 +01:00
[ " textcite " =: " \ \ textcite{item1} "
2012-02-06 21:41:34 +01:00
=?> para ( cite [ baseCitation ] ( rt " \ \ textcite{item1} " ) )
2011-01-29 18:01:30 +01:00
, " suffix " =: " \ \ textcite[p.~30]{item1} "
=?> para
2013-07-21 20:44:49 +02:00
( cite [ baseCitation { citationSuffix = toList $ text " p. \ 160 \ & 30 " } ] ( rt " \ \ textcite[p.~30]{item1} " ) )
2011-01-29 18:01:30 +01:00
, " suffix long " =: " \ \ textcite[p.~30, with suffix]{item1} "
=?> para ( cite [ baseCitation { citationSuffix =
2013-07-21 20:44:49 +02:00
toList $ text " p. \ 160 \ & 30, with suffix " } ] ( rt " \ \ textcite[p.~30, with suffix]{item1} " ) )
2011-01-29 18:01:30 +01:00
, " multiple " =: " \ \ textcites{item1}[p.~30]{item2}[see also][]{item3} "
=?> para ( cite [ baseCitation { citationMode = AuthorInText }
, baseCitation { citationMode = NormalCitation
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " p. \ 160 \ & 30 " ]
2011-01-29 18:01:30 +01:00
, citationId = " item2 " }
, baseCitation { citationId = " item3 "
, citationPrefix = [ Str " see " , Space , Str " also " ]
, citationMode = NormalCitation }
2012-02-06 21:41:34 +01:00
] ( rt " \ \ textcites{item1}[p.~30]{item2}[see also][]{item3} " ) )
2011-01-29 18:01:30 +01:00
, " group " =: " \ \ autocites[see][p.~34--35]{item1}[also][chap. 3]{item3} "
=?> para ( cite [ baseCitation { citationMode = NormalCitation
, citationPrefix = [ Str " see " ]
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " p. \ 160 \ & 34 \ 8211 \ & 35 " ] }
2011-01-29 18:01:30 +01:00
, baseCitation { citationMode = NormalCitation
, citationId = " item3 "
, citationPrefix = [ Str " also " ]
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " chap. " , Space , Str " 3 " ] }
2012-02-06 21:41:34 +01:00
] ( rt " \ \ autocites[see][p.~34--35]{item1}[also][chap. 3]{item3} " ) )
2011-01-29 18:01:30 +01:00
, " suffix and locator " =: " \ \ autocite[pp.~33, 35--37, and nowhere else]{item1} "
=?> para ( cite [ baseCitation { citationMode = NormalCitation
2013-07-21 20:44:49 +02:00
, 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} " ) )
2011-01-29 18:01:30 +01:00
, " suffix only " =: " \ \ autocite[and nowhere else]{item1} "
=?> para ( cite [ baseCitation { citationMode = NormalCitation
2013-07-21 20:44:49 +02:00
, citationSuffix = toList $ text " and nowhere else " } ] ( rt " \ \ autocite[and nowhere else]{item1} " ) )
2011-01-29 18:01:30 +01:00
, " no author " =: " \ \ autocite*{item1}, and now Doe with a locator \ \ autocite*[p.~44]{item2} "
2012-02-06 21:41:34 +01:00
=?> para ( cite [ baseCitation { citationMode = SuppressAuthor } ] ( rt " \ \ autocite*{item1} " ) <>
2011-12-13 23:29:07 +01:00
text " , and now Doe with a locator " <>
2011-01-29 18:01:30 +01:00
cite [ baseCitation { citationMode = SuppressAuthor
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " p. \ 160 \ & 44 " ]
2012-02-06 21:41:34 +01:00
, citationId = " item2 " } ] ( rt " \ \ autocite*[p.~44]{item2} " ) )
2011-01-29 18:01:30 +01:00
, " markup " =: " \ \ autocite[ \ \ emph{see}][p. \ \ textbf{32}]{item1} "
=?> para ( cite [ baseCitation { citationMode = NormalCitation
, citationPrefix = [ Emph [ Str " see " ] ]
2013-07-21 20:44:49 +02:00
, citationSuffix = [ Str " p. " , Space ,
2012-02-06 21:41:34 +01:00
Strong [ Str " 32 " ] ] } ] ( rt " \ \ autocite[ \ \ emph{see}][p. \ \ textbf{32}]{item1} " ) )
2011-01-29 18:01:30 +01:00
, " parencite " =: " \ \ parencite{item1} "
2012-02-06 21:41:34 +01:00
=?> para ( cite [ baseCitation { citationMode = NormalCitation } ] ( rt " \ \ parencite{item1} " ) )
2011-01-29 17:47:00 +01:00
]