content: {-# LANGUAGE OverloadedStrings #-}
  {- |
     Module      : Tests.Readers.Org.Inline
     Copyright   : © 2014-2024 Albert Krewinkel
     License     : GNU GPL, version 2 or above
  
     Maintainer  : Albert Krewinkel <albert+pandoc@tarleb.com>
     Stability   : alpha
     Portability : portable
  
  Tests parsing of org inlines.
  -}
  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.Builder
  import qualified Data.Text as T
  import qualified Tests.Readers.Org.Inline.Citation as Citation
  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 (underline "underline")
  
    , "Strikeout" =:
        "+Kill Bill+" =?>
        para (strikeout . spcSep $ [ "Kill", "Bill" ])
  
    , "Verbatim" =:
        "=Robot.rock()=" =?>
        para (codeWith ("", ["verbatim"], []) "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")
  
    , "Superscript-like, but not after string" =:
        "a ^caret" =?>
        para "a ^caret"
  
    , "Subscript simple expression" =:
        "a_n" =?>
        para (str "a" <> subscript "n")
  
    , "Subscript multi char" =:
        "a_{n+1}" =?>
        para (str "a" <> subscript "n+1")
  
    , "Subscript-like, but not after string" =:
        "_underscore" =?>
        para "_underscore"
  
    , "Subscript takes precedence before underline" =:
        "text_subscript_" =?>
        para (str "text" <> subscript "subscript" <> str "_")
  
    , "Linebreak" =:
        "line \\\\ \nbreak" =?>
        para ("line" <> linebreak <> "break")
  
    , "Inline note" =:
        "[fn::Schreib mir eine E-Mail]" =?>
        para (note $ para "Schreib mir eine E-Mail")
  
    , "By default, markup-chars not occurring on word break are symbols" =:
        T.unlines [ "#+pandoc-emphasis-pre:"
                  , "#+pandoc-emphasis-post:"
                  , "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/! ze\x200b/r/\x200bo /b/." =?>
        para (spcSep [ emph $ "t/&" <> space <> "a"
                     , "/"
                     , "./r/"
                     , "(" <> strong "l" <> ")"
                     , emph "e" <> "!"
                     , "ze\x200b" <> emph "r" <> "\x200bo"
                     , emph "b" <> "."
                     ])
  
    , "Quotes are allowed border chars" =:
        "/'yep/ *sure\"*" =?>
        para (emph "'yep" <> space <> strong "sure\"")
  
    , "Spaces are forbidden border chars" =:
        "/nada /" =?>
        para "/nada /"
  
    , "Zero width spaces are forbidden border chars" =:
        "/emph\x200b/asis" =?>
        para "/emph\x200b/asis"
  
    , "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 signs (=)" =:
        "=is_subst = True=" =?>
        para (codeWith ("", ["verbatim"], []) "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" "" "")
  
      , "HTML attributes can have trailing spaces" =:
        T.unlines [ "#+attr_html: :width 100% :height 360px  "
                  , "[[file:fireworks.jpg]]"
                  ] =?>
        let kv = [("width", "100%"), ("height", "360px")]
        in para (imageWith (mempty, mempty, kv) "fireworks.jpg" mempty mempty)
  
  
      , "Uppercase extension" =:
        "[[file:test.PNG]]" =?>
        para (image "test.PNG" "" "")
      ]
  
    , "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/")
  
    , "Internal self-link (reference)" =:
      "[[#rabbit]]" =?>
      para (link "#rabbit" "" "#rabbit")
  
    , "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" "" ""))
  
    , "Link to image" =:
      "[[https://example.com/image.jpg][Look!]]" =?>
      para (link "https://example.com/image.jpg" "" (str "Look!"))
  
    , "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 a blank argument array" =:
        "src_sh[]{echo 'Hello, World'}" =?>
      para (codeWith ( ""
                         , [ "bash" ]
                         , [ ("org-language", "sh") ])
                         "echo 'Hello, World'")
  
    , "Inline code block with toggle" =:
        "src_sh[:toggle]{echo $HOME}" =?>
      para (codeWith ( ""
                         , [ "bash" ]
                         , [ ("org-language", "sh")
                           , ("toggle", "yes")
                           ]
                         )
                         "echo $HOME")
  
    , "Inline LaTeX symbol" =:
        "\\dots" =?>
        para "…"
  
    , "Inline LaTeX command" =:
        "\\textit{Emphasised}" =?>
        para (emph "Emphasised")
  
    , "Inline LaTeX command with spaces" =:
        "\\emph{Emphasis mine}" =?>
        para (rawInline "latex" "\\emph{Emphasis mine}")
  
    , "Inline math symbols" =:
        "\\tau \\oplus \\alpha" =?>
        para "τ ⊕ α"
  
    , "Inline LaTeX math command" =:
        "\\crarr" =?>
        para "↵"
  
    , "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 "∀ Ä"
  
    , "Macro" =:
        T.unlines [ "#+MACRO: HELLO /Hello, $1/"
                  , "{{{HELLO(World)}}}"
                  ] =?>
        para (emph "Hello, World")
  
    , "Macro duplicating 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"
    , "Macro called with an escaped comma" =:
        T.unlines [ "#+MACRO: HELLO Foo $1"
                  , "{{{HELLO(moin\\, niom)}}}"
                  ] =?>
        para "Foo moin, niom"
  
    , testGroup "Citations" Citation.tests
    , testGroup "Footnotes" Note.tests
    , testGroup "Smart punctuation" Smart.tests
    ]
  