2d443ecb07
The org reader test file had grown large, to the point that editor performance was negatively affected in some cases. The tests are spread over multiple submodules, and re-combined into a tasty TestTree in the main org reader test file.
516 lines
16 KiB
Haskell
516 lines
16 KiB
Haskell
{-# LANGUAGE OverloadedStrings #-}
|
||
module Tests.Readers.Org.Inline (tests) where
|
||
|
||
import Data.List (intersperse)
|
||
import Test.Tasty (TestTree, testGroup)
|
||
import Tests.Helpers ((=?>))
|
||
import Tests.Readers.Org.Shared ((=:), spcSep)
|
||
import Text.Pandoc
|
||
import Text.Pandoc.Builder
|
||
import Text.Pandoc.Shared (underlineSpan)
|
||
import qualified Data.Text as T
|
||
import qualified Tests.Readers.Org.Inline.Note as Note
|
||
import qualified Tests.Readers.Org.Inline.Smart as Smart
|
||
|
||
tests :: [TestTree]
|
||
tests =
|
||
[ "Plain String" =:
|
||
"Hello, World" =?>
|
||
para (spcSep [ "Hello,", "World" ])
|
||
|
||
, "Emphasis" =:
|
||
"/Planet Punk/" =?>
|
||
para (emph . spcSep $ ["Planet", "Punk"])
|
||
|
||
, "Strong" =:
|
||
"*Cider*" =?>
|
||
para (strong "Cider")
|
||
|
||
, "Strong Emphasis" =:
|
||
"/*strength*/" =?>
|
||
para (emph . strong $ "strength")
|
||
|
||
, "Emphasized Strong preceded by space" =:
|
||
" */super/*" =?>
|
||
para (strong . emph $ "super")
|
||
|
||
, "Underline" =:
|
||
"_underline_" =?>
|
||
para (underlineSpan $ "underline")
|
||
|
||
, "Strikeout" =:
|
||
"+Kill Bill+" =?>
|
||
para (strikeout . spcSep $ [ "Kill", "Bill" ])
|
||
|
||
, "Verbatim" =:
|
||
"=Robot.rock()=" =?>
|
||
para (code "Robot.rock()")
|
||
|
||
, "Code" =:
|
||
"~word for word~" =?>
|
||
para (code "word for word")
|
||
|
||
, "Math $..$" =:
|
||
"$E=mc^2$" =?>
|
||
para (math "E=mc^2")
|
||
|
||
, "Math $$..$$" =:
|
||
"$$E=mc^2$$" =?>
|
||
para (displayMath "E=mc^2")
|
||
|
||
, "Math \\[..\\]" =:
|
||
"\\[E=ℎν\\]" =?>
|
||
para (displayMath "E=ℎν")
|
||
|
||
, "Math \\(..\\)" =:
|
||
"\\(σ_x σ_p ≥ \\frac{ℏ}{2}\\)" =?>
|
||
para (math "σ_x σ_p ≥ \\frac{ℏ}{2}")
|
||
|
||
, "Symbol" =:
|
||
"A * symbol" =?>
|
||
para (str "A" <> space <> str "*" <> space <> "symbol")
|
||
|
||
, "Superscript simple expression" =:
|
||
"2^-λ" =?>
|
||
para (str "2" <> superscript "-λ")
|
||
|
||
, "Superscript multi char" =:
|
||
"2^{n-1}" =?>
|
||
para (str "2" <> superscript "n-1")
|
||
|
||
, "Subscript simple expression" =:
|
||
"a_n" =?>
|
||
para (str "a" <> subscript "n")
|
||
|
||
, "Subscript multi char" =:
|
||
"a_{n+1}" =?>
|
||
para (str "a" <> subscript "n+1")
|
||
|
||
, "Linebreak" =:
|
||
"line \\\\ \nbreak" =?>
|
||
para ("line" <> linebreak <> "break")
|
||
|
||
, "Inline note" =:
|
||
"[fn::Schreib mir eine E-Mail]" =?>
|
||
para (note $ para "Schreib mir eine E-Mail")
|
||
|
||
, "Markup-chars not occuring on word break are symbols" =:
|
||
T.unlines [ "this+that+ +so+on"
|
||
, "seven*eight* nine*"
|
||
, "+not+funny+"
|
||
] =?>
|
||
para ("this+that+ +so+on" <> softbreak <>
|
||
"seven*eight* nine*" <> softbreak <>
|
||
strikeout "not+funny")
|
||
|
||
, "No empty markup" =:
|
||
"// ** __ <> == ~~ $$" =?>
|
||
para (spcSep [ "//", "**", "__", "<>", "==", "~~", "$$" ])
|
||
|
||
, "Adherence to Org's rules for markup borders" =:
|
||
"/t/& a/ / ./r/ (*l*) /e/! /b/." =?>
|
||
para (spcSep [ emph $ "t/&" <> space <> "a"
|
||
, "/"
|
||
, "./r/"
|
||
, "(" <> strong "l" <> ")"
|
||
, emph "e" <> "!"
|
||
, emph "b" <> "."
|
||
])
|
||
|
||
, "Quotes are allowed border chars" =:
|
||
"/'yep/ *sure\"*" =?>
|
||
para (emph "'yep" <> space <> strong "sure\"")
|
||
|
||
, "Spaces are forbidden border chars" =:
|
||
"/nada /" =?>
|
||
para "/nada /"
|
||
|
||
, "Markup should work properly after a blank line" =:
|
||
T.unlines ["foo", "", "/bar/"] =?>
|
||
(para $ text "foo") <> (para $ emph $ text "bar")
|
||
|
||
, "Inline math must stay within three lines" =:
|
||
T.unlines [ "$a", "b", "c$", "$d", "e", "f", "g$" ] =?>
|
||
para ((math "a\nb\nc") <> softbreak <>
|
||
"$d" <> softbreak <> "e" <> softbreak <>
|
||
"f" <> softbreak <> "g$")
|
||
|
||
, "Single-character math" =:
|
||
"$a$ $b$! $c$?" =?>
|
||
para (spcSep [ math "a"
|
||
, "$b$!"
|
||
, (math "c") <> "?"
|
||
])
|
||
|
||
, "Markup may not span more than two lines" =:
|
||
"/this *is +totally\nnice+ not*\nemph/" =?>
|
||
para ("/this" <> space <>
|
||
strong ("is" <> space <>
|
||
strikeout ("totally" <>
|
||
softbreak <> "nice") <>
|
||
space <> "not") <>
|
||
softbreak <> "emph/")
|
||
|
||
, "Sub- and superscript expressions" =:
|
||
T.unlines [ "a_(a(b)(c)d)"
|
||
, "e^(f(g)h)"
|
||
, "i_(jk)l)"
|
||
, "m^()n"
|
||
, "o_{p{q{}r}}"
|
||
, "s^{t{u}v}"
|
||
, "w_{xy}z}"
|
||
, "1^{}2"
|
||
, "3_{{}}"
|
||
, "4^(a(*b(c*)d))"
|
||
] =?>
|
||
para (mconcat $ intersperse softbreak
|
||
[ "a" <> subscript "(a(b)(c)d)"
|
||
, "e" <> superscript "(f(g)h)"
|
||
, "i" <> (subscript "(jk)") <> "l)"
|
||
, "m" <> (superscript "()") <> "n"
|
||
, "o" <> subscript "p{q{}r}"
|
||
, "s" <> superscript "t{u}v"
|
||
, "w" <> (subscript "xy") <> "z}"
|
||
, "1" <> (superscript "") <> "2"
|
||
, "3" <> subscript "{}"
|
||
, "4" <> superscript ("(a(" <> strong "b(c" <> ")d))")
|
||
])
|
||
, "Verbatim text can contain equal signes (=)" =:
|
||
"=is_subst = True=" =?>
|
||
para (code "is_subst = True")
|
||
|
||
, testGroup "Images"
|
||
[ "Image" =:
|
||
"[[./sunset.jpg]]" =?>
|
||
(para $ image "./sunset.jpg" "" "")
|
||
|
||
, "Image with explicit file: prefix" =:
|
||
"[[file:sunrise.jpg]]" =?>
|
||
(para $ image "sunrise.jpg" "" "")
|
||
|
||
, "Multiple images within a paragraph" =:
|
||
T.unlines [ "[[file:sunrise.jpg]]"
|
||
, "[[file:sunset.jpg]]"
|
||
] =?>
|
||
(para $ (image "sunrise.jpg" "" "")
|
||
<> softbreak
|
||
<> (image "sunset.jpg" "" ""))
|
||
|
||
, "Image with html attributes" =:
|
||
T.unlines [ "#+ATTR_HTML: :width 50%"
|
||
, "[[file:guinea-pig.gif]]"
|
||
] =?>
|
||
(para $ imageWith ("", [], [("width", "50%")]) "guinea-pig.gif" "" "")
|
||
]
|
||
|
||
, "Explicit link" =:
|
||
"[[http://zeitlens.com/][pseudo-random /nonsense/]]" =?>
|
||
(para $ link "http://zeitlens.com/" ""
|
||
("pseudo-random" <> space <> emph "nonsense"))
|
||
|
||
, "Self-link" =:
|
||
"[[http://zeitlens.com/]]" =?>
|
||
(para $ link "http://zeitlens.com/" "" "http://zeitlens.com/")
|
||
|
||
, "Absolute file link" =:
|
||
"[[/url][hi]]" =?>
|
||
(para $ link "file:///url" "" "hi")
|
||
|
||
, "Link to file in parent directory" =:
|
||
"[[../file.txt][moin]]" =?>
|
||
(para $ link "../file.txt" "" "moin")
|
||
|
||
, "Empty link (for gitit interop)" =:
|
||
"[[][New Link]]" =?>
|
||
(para $ link "" "" "New Link")
|
||
|
||
, "Image link" =:
|
||
"[[sunset.png][file:dusk.svg]]" =?>
|
||
(para $ link "sunset.png" "" (image "dusk.svg" "" ""))
|
||
|
||
, "Image link with non-image target" =:
|
||
"[[http://example.com][./logo.png]]" =?>
|
||
(para $ link "http://example.com" "" (image "./logo.png" "" ""))
|
||
|
||
, "Plain link" =:
|
||
"Posts on http://zeitlens.com/ can be funny at times." =?>
|
||
(para $ spcSep [ "Posts", "on"
|
||
, link "http://zeitlens.com/" "" "http://zeitlens.com/"
|
||
, "can", "be", "funny", "at", "times."
|
||
])
|
||
|
||
, "Angle link" =:
|
||
"Look at <http://moltkeplatz.de> for fnords." =?>
|
||
(para $ spcSep [ "Look", "at"
|
||
, link "http://moltkeplatz.de" "" "http://moltkeplatz.de"
|
||
, "for", "fnords."
|
||
])
|
||
|
||
, "Absolute file link" =:
|
||
"[[file:///etc/passwd][passwd]]" =?>
|
||
(para $ link "file:///etc/passwd" "" "passwd")
|
||
|
||
, "File link" =:
|
||
"[[file:target][title]]" =?>
|
||
(para $ link "target" "" "title")
|
||
|
||
, "Anchor" =:
|
||
"<<anchor>> Link here later." =?>
|
||
(para $ spanWith ("anchor", [], []) mempty <>
|
||
"Link" <> space <> "here" <> space <> "later.")
|
||
|
||
, "Inline code block" =:
|
||
"src_emacs-lisp{(message \"Hello\")}" =?>
|
||
(para $ codeWith ( ""
|
||
, [ "commonlisp" ]
|
||
, [ ("org-language", "emacs-lisp") ])
|
||
"(message \"Hello\")")
|
||
|
||
, "Inline code block with arguments" =:
|
||
"src_sh[:export both :results output]{echo 'Hello, World'}" =?>
|
||
(para $ codeWith ( ""
|
||
, [ "bash" ]
|
||
, [ ("org-language", "sh")
|
||
, ("export", "both")
|
||
, ("results", "output")
|
||
]
|
||
)
|
||
"echo 'Hello, World'")
|
||
|
||
, "Inline code block with toggle" =:
|
||
"src_sh[:toggle]{echo $HOME}" =?>
|
||
(para $ codeWith ( ""
|
||
, [ "bash" ]
|
||
, [ ("org-language", "sh")
|
||
, ("toggle", "yes")
|
||
]
|
||
)
|
||
"echo $HOME")
|
||
|
||
, "Citation" =:
|
||
"[@nonexistent]" =?>
|
||
let citation = Citation
|
||
{ citationId = "nonexistent"
|
||
, citationPrefix = []
|
||
, citationSuffix = []
|
||
, citationMode = NormalCitation
|
||
, citationNoteNum = 0
|
||
, citationHash = 0}
|
||
in (para $ cite [citation] "[@nonexistent]")
|
||
|
||
, "Citation containing text" =:
|
||
"[see @item1 p. 34-35]" =?>
|
||
let citation = Citation
|
||
{ citationId = "item1"
|
||
, citationPrefix = [Str "see"]
|
||
, citationSuffix = [Space ,Str "p.",Space,Str "34-35"]
|
||
, citationMode = NormalCitation
|
||
, citationNoteNum = 0
|
||
, citationHash = 0}
|
||
in (para $ cite [citation] "[see @item1 p. 34-35]")
|
||
|
||
, "Org-ref simple citation" =:
|
||
"cite:pandoc" =?>
|
||
let citation = Citation
|
||
{ citationId = "pandoc"
|
||
, citationPrefix = mempty
|
||
, citationSuffix = mempty
|
||
, citationMode = AuthorInText
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
in (para $ cite [citation] "cite:pandoc")
|
||
|
||
, "Org-ref simple citation with underscores" =:
|
||
"cite:pandoc_org_ref" =?>
|
||
let citation = Citation
|
||
{ citationId = "pandoc_org_ref"
|
||
, citationPrefix = mempty
|
||
, citationSuffix = mempty
|
||
, citationMode = AuthorInText
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
in (para $ cite [citation] "cite:pandoc_org_ref")
|
||
|
||
, "Org-ref simple citation succeeded by comma" =:
|
||
"cite:pandoc," =?>
|
||
let citation = Citation
|
||
{ citationId = "pandoc"
|
||
, citationPrefix = mempty
|
||
, citationSuffix = mempty
|
||
, citationMode = AuthorInText
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
in (para $ cite [citation] "cite:pandoc" <> str ",")
|
||
|
||
, "Org-ref simple citation succeeded by dot" =:
|
||
"cite:pandoc." =?>
|
||
let citation = Citation
|
||
{ citationId = "pandoc"
|
||
, citationPrefix = mempty
|
||
, citationSuffix = mempty
|
||
, citationMode = AuthorInText
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
in (para $ cite [citation] "cite:pandoc" <> str ".")
|
||
|
||
, "Org-ref simple citation succeeded by colon" =:
|
||
"cite:pandoc:" =?>
|
||
let citation = Citation
|
||
{ citationId = "pandoc"
|
||
, citationPrefix = mempty
|
||
, citationSuffix = mempty
|
||
, citationMode = AuthorInText
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
in (para $ cite [citation] "cite:pandoc" <> str ":")
|
||
|
||
, "Org-ref simple citep citation" =:
|
||
"citep:pandoc" =?>
|
||
let citation = Citation
|
||
{ citationId = "pandoc"
|
||
, citationPrefix = mempty
|
||
, citationSuffix = mempty
|
||
, citationMode = NormalCitation
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
in (para $ cite [citation] "citep:pandoc")
|
||
|
||
, "Org-ref extended citation" =:
|
||
"[[citep:Dominik201408][See page 20::, for example]]" =?>
|
||
let citation = Citation
|
||
{ citationId = "Dominik201408"
|
||
, citationPrefix = toList "See page 20"
|
||
, citationSuffix = toList ", for example"
|
||
, citationMode = NormalCitation
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
in (para $ cite [citation] "[[citep:Dominik201408][See page 20::, for example]]")
|
||
|
||
, testGroup "Berkeley-style citations" $
|
||
let pandocCite = Citation
|
||
{ citationId = "Pandoc"
|
||
, citationPrefix = mempty
|
||
, citationSuffix = mempty
|
||
, citationMode = NormalCitation
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
pandocInText = pandocCite { citationMode = AuthorInText }
|
||
dominikCite = Citation
|
||
{ citationId = "Dominik201408"
|
||
, citationPrefix = mempty
|
||
, citationSuffix = mempty
|
||
, citationMode = NormalCitation
|
||
, citationNoteNum = 0
|
||
, citationHash = 0
|
||
}
|
||
dominikInText = dominikCite { citationMode = AuthorInText }
|
||
in [
|
||
"Berkeley-style in-text citation" =:
|
||
"See @Dominik201408." =?>
|
||
(para $ "See "
|
||
<> cite [dominikInText] "@Dominik201408"
|
||
<> ".")
|
||
|
||
, "Berkeley-style parenthetical citation list" =:
|
||
"[(cite): see; @Dominik201408;also @Pandoc; and others]" =?>
|
||
let pandocCite' = pandocCite {
|
||
citationPrefix = toList "also"
|
||
, citationSuffix = toList "and others"
|
||
}
|
||
dominikCite' = dominikCite {
|
||
citationPrefix = toList "see"
|
||
}
|
||
in (para $ cite [dominikCite', pandocCite'] "")
|
||
|
||
, "Berkeley-style plain citation list" =:
|
||
"[cite: See; @Dominik201408; and @Pandoc; and others]" =?>
|
||
let pandocCite' = pandocInText {
|
||
citationPrefix = toList "and"
|
||
}
|
||
in (para $ "See "
|
||
<> cite [dominikInText] ""
|
||
<> "," <> space
|
||
<> cite [pandocCite'] ""
|
||
<> "," <> space <> "and others")
|
||
]
|
||
|
||
, "Inline LaTeX symbol" =:
|
||
"\\dots" =?>
|
||
para "…"
|
||
|
||
, "Inline LaTeX command" =:
|
||
"\\textit{Emphasised}" =?>
|
||
para (emph "Emphasised")
|
||
|
||
, "Inline LaTeX command with spaces" =:
|
||
"\\emph{Emphasis mine}" =?>
|
||
para (emph "Emphasis mine")
|
||
|
||
, "Inline LaTeX math symbol" =:
|
||
"\\tau" =?>
|
||
para (emph "τ")
|
||
|
||
, "Unknown inline LaTeX command" =:
|
||
"\\notacommand{foo}" =?>
|
||
para (rawInline "latex" "\\notacommand{foo}")
|
||
|
||
, "Export snippet" =:
|
||
"@@html:<kbd>M-x org-agenda</kbd>@@" =?>
|
||
para (rawInline "html" "<kbd>M-x org-agenda</kbd>")
|
||
|
||
, "MathML symbol in LaTeX-style" =:
|
||
"There is a hackerspace in Lübeck, Germany, called nbsp (unicode symbol: '\\nbsp')." =?>
|
||
para ("There is a hackerspace in Lübeck, Germany, called nbsp (unicode symbol: ' ').")
|
||
|
||
, "MathML symbol in LaTeX-style, including braces" =:
|
||
"\\Aacute{}stor" =?>
|
||
para "Ástor"
|
||
|
||
, "MathML copy sign" =:
|
||
"\\copy" =?>
|
||
para "©"
|
||
|
||
, "MathML symbols, space separated" =:
|
||
"\\ForAll \\Auml" =?>
|
||
para "∀ Ä"
|
||
|
||
, "LaTeX citation" =:
|
||
"\\cite{Coffee}" =?>
|
||
let citation = Citation
|
||
{ citationId = "Coffee"
|
||
, citationPrefix = []
|
||
, citationSuffix = []
|
||
, citationMode = NormalCitation
|
||
, citationNoteNum = 0
|
||
, citationHash = 0}
|
||
in (para . cite [citation] $ rawInline "latex" "\\cite{Coffee}")
|
||
|
||
, "Macro" =:
|
||
T.unlines [ "#+MACRO: HELLO /Hello, $1/"
|
||
, "{{{HELLO(World)}}}"
|
||
] =?>
|
||
para (emph "Hello, World")
|
||
|
||
, "Macro repeting its argument" =:
|
||
T.unlines [ "#+MACRO: HELLO $1$1"
|
||
, "{{{HELLO(moin)}}}"
|
||
] =?>
|
||
para "moinmoin"
|
||
|
||
, "Macro called with too few arguments" =:
|
||
T.unlines [ "#+MACRO: HELLO Foo $1 $2 Bar"
|
||
, "{{{HELLO()}}}"
|
||
] =?>
|
||
para "Foo Bar"
|
||
|
||
, testGroup "Footnotes" Note.tests
|
||
, testGroup "Smart punctuation" Smart.tests
|
||
]
|