git.iko.soy/typeable/pandoc
on master help sign in
Add Basic JATS reader based on DocBook reader
commit5d3c9e56460165be452b672f12fc476e7a5ed3a9 authorHamish Mackenzie <Hamish.K.Mackenzie@googlemail.com> dateWed 20 Dec 2017, 13:54 (9 years ago) parent1e21cfb
8 files changed+2704−1
pandoc.cabal+3 src/Text/Pandoc/Readers.hs+4−1 src/Text/Pandoc/Readers/JATS.hs+387 test/Tests/Old.hs+2 test/Tests/Readers/JATS.hs+111 test/jats-reader.native+422 test/jats-reader.xml+1773 test/test-pandoc.hs+2
pandoc.cabal+3
@@ -214,6 +214,7 @@ extra-source-files:
214214 test/creole-reader.txt
215215 test/creole-reader.native
216216 test/rst-reader.rst
217+ test/jats-reader.xml
217218 test/s5-basic.html
218219 test/s5-fancy.html
219220 test/s5-fragment.html
@@ -436,6 +437,7 @@ library
436437 Text.Pandoc.Readers.RST,
437438 Text.Pandoc.Readers.Org,
438439 Text.Pandoc.Readers.DocBook,
440+ Text.Pandoc.Readers.JATS,
439441 Text.Pandoc.Readers.OPML,
440442 Text.Pandoc.Readers.Textile,
441443 Text.Pandoc.Readers.Native,
@@ -623,6 +625,7 @@ test-suite test-pandoc
623625 Tests.Shared
624626 Tests.Readers.LaTeX
625627 Tests.Readers.HTML
628+ Tests.Readers.JATS
626629 Tests.Readers.Markdown
627630 Tests.Readers.Org
628631 Tests.Readers.RST
src/Text/Pandoc/Readers.hs+4−1
@@ -52,6 +52,7 @@ module Text.Pandoc.Readers
5252 , readOrg
5353 , readLaTeX
5454 , readHtml
55+ , readJATS
5556 , readTextile
5657 , readDocBook
5758 , readOPML
@@ -84,7 +85,8 @@ import Text.Pandoc.Readers.DocBook
8485import Text.Pandoc.Readers.Docx
8586import Text.Pandoc.Readers.EPUB
8687import Text.Pandoc.Readers.Haddock
87−import Text.Pandoc.Readers.HTML
88+import Text.Pandoc.Readers.HTML (readHtml)
89+import Text.Pandoc.Readers.JATS (readJATS)
8890import Text.Pandoc.Readers.LaTeX
8991import Text.Pandoc.Readers.Markdown
9092import Text.Pandoc.Readers.MediaWiki
@@ -129,6 +131,7 @@ readers = [ ("native" , TextReader readNative)
129131 ,("org" , TextReader readOrg)
130132 ,("textile" , TextReader readTextile) -- TODO : textile+lhs
131133 ,("html" , TextReader readHtml)
134+ ,("jats" , TextReader readJATS)
132135 ,("latex" , TextReader readLaTeX)
133136 ,("haddock" , TextReader readHaddock)
134137 ,("twiki" , TextReader readTWiki)
src/Text/Pandoc/Readers/JATS.hsnew file+387
@@ -0,0 +1,387 @@
1+{-# LANGUAGE ExplicitForAll, TupleSections #-}
2+module Text.Pandoc.Readers.JATS ( readJATS ) where
3+import Control.Monad.State.Strict
4+import Data.Char (isDigit, isSpace, toUpper)
5+import Data.Default
6+import Data.Generics
7+import Data.List (intersperse)
8+import Data.Maybe (maybeToList, fromMaybe)
9+import Data.Text (Text)
10+import qualified Data.Text as T
11+import Text.HTML.TagSoup.Entity (lookupEntity)
12+import Text.Pandoc.Builder
13+import Text.Pandoc.Class (PandocMonad)
14+import Text.Pandoc.Options
15+import Text.Pandoc.Shared (underlineSpan, crFilter, safeRead)
16+import Text.TeXMath (readMathML, writeTeX)
17+import Text.XML.Light
18+
19+type JATS m = StateT JATSState m
20+
21+data JATSState = JATSState{ jatsSectionLevel :: Int
22+ , jatsQuoteType :: QuoteType
23+ , jatsMeta :: Meta
24+ , jatsAcceptsMeta :: Bool
25+ , jatsBook :: Bool
26+ , jatsFigureTitle :: Inlines
27+ , jatsContent :: [Content]
28+ } deriving Show
29+
30+instance Default JATSState where
31+ def = JATSState{ jatsSectionLevel = 0
32+ , jatsQuoteType = DoubleQuote
33+ , jatsMeta = mempty
34+ , jatsAcceptsMeta = False
35+ , jatsBook = False
36+ , jatsFigureTitle = mempty
37+ , jatsContent = [] }
38+
39+
40+readJATS :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
41+readJATS _ inp = do
42+ let tree = normalizeTree . parseXML
43+ $ T.unpack $ crFilter inp
44+ (bs, st') <- flip runStateT (def{ jatsContent = tree }) $ mapM parseBlock tree
45+ return $ Pandoc (jatsMeta st') (toList . mconcat $ bs)
46+
47+-- normalize input, consolidating adjacent Text and CRef elements
48+normalizeTree :: [Content] -> [Content]
49+normalizeTree = everywhere (mkT go)
50+ where go :: [Content] -> [Content]
51+ go (Text (CData CDataRaw _ _):xs) = xs
52+ go (Text (CData CDataText s1 z):Text (CData CDataText s2 _):xs) =
53+ Text (CData CDataText (s1 ++ s2) z):xs
54+ go (Text (CData CDataText s1 z):CRef r:xs) =
55+ Text (CData CDataText (s1 ++ convertEntity r) z):xs
56+ go (CRef r:Text (CData CDataText s1 z):xs) =
57+ Text (CData CDataText (convertEntity r ++ s1) z):xs
58+ go (CRef r1:CRef r2:xs) =
59+ Text (CData CDataText (convertEntity r1 ++ convertEntity r2) Nothing):xs
60+ go xs = xs
61+
62+convertEntity :: String -> String
63+convertEntity e = Data.Maybe.fromMaybe (map toUpper e) (lookupEntity e)
64+
65+-- convenience function to get an attribute value, defaulting to ""
66+attrValue :: String -> Element -> String
67+attrValue attr =
68+ fromMaybe "" . maybeAttrValue attr
69+
70+maybeAttrValue :: String -> Element -> Maybe String
71+maybeAttrValue attr elt =
72+ lookupAttrBy (\x -> qName x == attr) (elAttribs elt)
73+
74+-- convenience function
75+named :: String -> Element -> Bool
76+named s e = qName (elName e) == s
77+
78+--
79+
80+acceptingMetadata :: PandocMonad m => JATS m a -> JATS m a
81+acceptingMetadata p = do
82+ modify (\s -> s { jatsAcceptsMeta = True } )
83+ res <- p
84+ modify (\s -> s { jatsAcceptsMeta = False })
85+ return res
86+
87+checkInMeta :: (PandocMonad m, Monoid a) => JATS m () -> JATS m a
88+checkInMeta p = do
89+ accepts <- jatsAcceptsMeta <$> get
90+ when accepts p
91+ return mempty
92+
93+addMeta :: PandocMonad m => ToMetaValue a => String -> a -> JATS m ()
94+addMeta field val = modify (setMeta field val)
95+
96+instance HasMeta JATSState where
97+ setMeta field v s = s {jatsMeta = setMeta field v (jatsMeta s)}
98+ deleteMeta field s = s {jatsMeta = deleteMeta field (jatsMeta s)}
99+
100+isBlockElement :: Content -> Bool
101+isBlockElement (Elem e) = qName (elName e) `elem` blocktags
102+ where blocktags = paragraphLevel ++ lists ++ mathML ++ other
103+ paragraphLevel = ["address", "array", "boxed-text", "chem-struct-wrap",
104+ "code", "fig", "fig-group", "graphic", "media", "preformat",
105+ "supplementary-material", "table-wrap", "table-wrap-group",
106+ "alternatives", "disp-formula", "disp-formula-group"]
107+ lists = ["def-list", "list"]
108+ mathML = ["tex-math", "mml:math"]
109+ other = ["p", "related-article", "related-object", "ack", "disp-quote",
110+ "speech", "statement", "verse-group", "x"]
111+isBlockElement _ = False
112+
113+-- Trim leading and trailing newline characters
114+trimNl :: String -> String
115+trimNl = reverse . go . reverse . go
116+ where go ('\n':xs) = xs
117+ go xs = xs
118+
119+-- function that is used by both graphic (in parseBlock)
120+-- and inline-graphic (in parseInline)
121+getGraphic :: PandocMonad m => Element -> JATS m Inlines
122+getGraphic e = do
123+ let atVal a = attrValue a e
124+ attr = (atVal "id", words $ atVal "role", [])
125+ imageUrl = atVal "href"
126+ captionOrLabel = case filterChild (\x -> named "caption" x
127+ || named "label" x) e of
128+ Nothing -> return mempty
129+ Just z -> mconcat <$>
130+ mapM parseInline (elContent z)
131+ figTitle <- gets jatsFigureTitle
132+ let (caption, title) = if isNull figTitle
133+ then (captionOrLabel, atVal "title")
134+ else (return figTitle, "fig:")
135+ fmap (imageWith attr imageUrl title) caption
136+
137+getBlocks :: PandocMonad m => Element -> JATS m Blocks
138+getBlocks e = mconcat <$>
139+ mapM parseBlock (elContent e)
140+
141+
142+parseBlock :: PandocMonad m => Content -> JATS m Blocks
143+parseBlock (Text (CData CDataRaw _ _)) = return mempty -- DOCTYPE
144+parseBlock (Text (CData _ s _)) = if all isSpace s
145+ then return mempty
146+ else return $ plain $ trimInlines $ text s
147+parseBlock (CRef x) = return $ plain $ str $ map toUpper x
148+parseBlock (Elem e) =
149+ case qName (elName e) of
150+ "p" -> parseMixed para (elContent e)
151+ "code" -> codeBlockWithLang
152+ "preformat" -> codeBlockWithLang
153+ "disp-quote" -> parseBlockquote
154+ "list" -> case attrValue "list-type" e of
155+ "bullet" -> bulletList <$> listitems
156+ listType -> do
157+ let start = fromMaybe 1 $
158+ (strContent <$> (filterElement (named "list-item") e
159+ >>= filterElement (named "lable")))
160+ >>= safeRead
161+ orderedListWith (start, parseListStyleType listType, DefaultDelim)
162+ <$> listitems
163+ "def-list" -> definitionList <$> deflistitems
164+ "sec" -> gets jatsSectionLevel >>= sect . (+1)
165+ "title" -> return mempty
166+ "title-group" -> checkInMeta getTitle
167+ "graphic" -> para <$> getGraphic e
168+ "journal-meta" -> metaBlock
169+ "article-meta" -> metaBlock
170+ "custom-meta" -> metaBlock
171+ "table" -> parseTable
172+ "fig" -> divWith (attrValue "id" e, ["fig"], []) <$> getBlocks e
173+ "table-wrap" -> divWith (attrValue "id" e, ["table-wrap"], []) <$> getBlocks e
174+ "caption" -> divWith (attrValue "id" e, ["caption"], []) <$> sect 6
175+ "ref-list" -> divWith ("refs", [], []) <$> getBlocks e
176+ "ref" -> divWith ("ref-" <> attrValue "id" e, [], []) <$> getBlocks e
177+ "?xml" -> return mempty
178+ _ -> getBlocks e
179+ where parseMixed container conts = do
180+ let (ils,rest) = break isBlockElement conts
181+ ils' <- (trimInlines . mconcat) <$> mapM parseInline ils
182+ let p = if ils' == mempty then mempty else container ils'
183+ case rest of
184+ [] -> return p
185+ (r:rs) -> do
186+ b <- parseBlock r
187+ x <- parseMixed container rs
188+ return $ p <> b <> x
189+ codeBlockWithLang = do
190+ let classes' = case attrValue "language" e of
191+ "" -> []
192+ x -> [x]
193+ return $ codeBlockWith (attrValue "id" e, classes', [])
194+ $ trimNl $ strContentRecursive e
195+ parseBlockquote = do
196+ attrib <- case filterChild (named "attribution") e of
197+ Nothing -> return mempty
198+ Just z -> (para . (str "— " <>) . mconcat)
199+ <$>
200+ mapM parseInline (elContent z)
201+ contents <- getBlocks e
202+ return $ blockQuote (contents <> attrib)
203+ parseListStyleType "roman-lower" = LowerRoman
204+ parseListStyleType "roman-upper" = UpperRoman
205+ parseListStyleType "alpha-lower" = LowerAlpha
206+ parseListStyleType "alpha-upper" = UpperAlpha
207+ parseListStyleType _ = DefaultStyle
208+ listitems = mapM getBlocks $ filterChildren (named "list-item") e
209+ deflistitems = mapM parseVarListEntry $ filterChildren
210+ (named "def-item") e
211+ parseVarListEntry e' = do
212+ let terms = filterChildren (named "term") e'
213+ let items = filterChildren (named "def") e'
214+ terms' <- mapM getInlines terms
215+ items' <- mapM getBlocks items
216+ return (mconcat $ intersperse (str "; ") terms', items')
217+ getTitle = do
218+ tit <- case filterChild (named "article-title") e of
219+ Just s -> getInlines s
220+ Nothing -> return mempty
221+ subtit <- case filterChild (named "subtitle") e of
222+ Just s -> (text ": " <>) <$>
223+ getInlines s
224+ Nothing -> return mempty
225+ addMeta "title" (tit <> subtit)
226+
227+ parseTable = do
228+ let isCaption x = named "title" x || named "caption" x
229+ caption <- case filterChild isCaption e of
230+ Just t -> getInlines t
231+ Nothing -> return mempty
232+ let e' = fromMaybe e $ filterChild (named "tgroup") e
233+ let isColspec x = named "colspec" x || named "col" x
234+ let colspecs = case filterChild (named "colgroup") e' of
235+ Just c -> filterChildren isColspec c
236+ _ -> filterChildren isColspec e'
237+ let isRow x = named "row" x || named "tr" x
238+ headrows <- case filterChild (named "thead") e' of
239+ Just h -> case filterChild isRow h of
240+ Just x -> parseRow x
241+ Nothing -> return []
242+ Nothing -> return []
243+ bodyrows <- case filterChild (named "tbody") e' of
244+ Just b -> mapM parseRow
245+ $ filterChildren isRow b
246+ Nothing -> mapM parseRow
247+ $ filterChildren isRow e'
248+ let toAlignment c = case findAttr (unqual "align") c of
249+ Just "left" -> AlignLeft
250+ Just "right" -> AlignRight
251+ Just "center" -> AlignCenter
252+ _ -> AlignDefault
253+ let toWidth c = case findAttr (unqual "colwidth") c of
254+ Just w -> fromMaybe 0
255+ $ safeRead $ '0': filter (\x ->
256+ isDigit x || x == '.') w
257+ Nothing -> 0 :: Double
258+ let numrows = case bodyrows of
259+ [] -> 0
260+ xs -> maximum $ map length xs
261+ let aligns = case colspecs of
262+ [] -> replicate numrows AlignDefault
263+ cs -> map toAlignment cs
264+ let widths = case colspecs of
265+ [] -> replicate numrows 0
266+ cs -> let ws = map toWidth cs
267+ tot = sum ws
268+ in if all (> 0) ws
269+ then map (/ tot) ws
270+ else replicate numrows 0
271+ let headrows' = if null headrows
272+ then replicate numrows mempty
273+ else headrows
274+ return $ table caption (zip aligns widths)
275+ headrows' bodyrows
276+ isEntry x = named "entry" x || named "td" x || named "th" x
277+ parseRow = mapM (parseMixed plain . elContent) . filterChildren isEntry
278+ sect n = do isbook <- gets jatsBook
279+ let n' = if isbook || n == 0 then n + 1 else n
280+ headerText <- case filterChild (named "title") e `mplus`
281+ (filterChild (named "info") e >>=
282+ filterChild (named "title")) of
283+ Just t -> getInlines t
284+ Nothing -> return mempty
285+ oldN <- gets jatsSectionLevel
286+ modify $ \st -> st{ jatsSectionLevel = n }
287+ b <- getBlocks e
288+ let ident = attrValue "id" e
289+ modify $ \st -> st{ jatsSectionLevel = oldN }
290+ return $ headerWith (ident,[],[]) n' headerText <> b
291+-- lineItems = mapM getInlines $ filterChildren (named "line") e
292+ metaBlock = acceptingMetadata (getBlocks e) >> return mempty
293+
294+getInlines :: PandocMonad m => Element -> JATS m Inlines
295+getInlines e' = (trimInlines . mconcat) <$>
296+ mapM parseInline (elContent e')
297+
298+strContentRecursive :: Element -> String
299+strContentRecursive = strContent .
300+ (\e' -> e'{ elContent = map elementToStr $ elContent e' })
301+
302+elementToStr :: Content -> Content
303+elementToStr (Elem e') = Text $ CData CDataText (strContentRecursive e') Nothing
304+elementToStr x = x
305+
306+parseInline :: PandocMonad m => Content -> JATS m Inlines
307+parseInline (Text (CData _ s _)) = return $ text s
308+parseInline (CRef ref) =
309+ return $ maybe (text $ map toUpper ref) text $ lookupEntity ref
310+parseInline (Elem e) =
311+ case qName (elName e) of
312+ "italic" -> emph <$> innerInlines
313+ "bold" -> strong <$> innerInlines
314+ "strike" -> strikeout <$> innerInlines
315+ "sub" -> subscript <$> innerInlines
316+ "sup" -> superscript <$> innerInlines
317+ "underline" -> underlineSpan <$> innerInlines
318+ "break" -> return linebreak
319+ "sc" -> smallcaps <$> innerInlines
320+
321+ "code" -> codeWithLang
322+ "monospace" -> codeWithLang
323+
324+ "inline-graphic" -> getGraphic e
325+ "disp-quote" -> do
326+ qt <- gets jatsQuoteType
327+ let qt' = if qt == SingleQuote then DoubleQuote else SingleQuote
328+ modify $ \st -> st{ jatsQuoteType = qt' }
329+ contents <- innerInlines
330+ modify $ \st -> st{ jatsQuoteType = qt }
331+ return $ if qt == SingleQuote
332+ then singleQuoted contents
333+ else doubleQuoted contents
334+
335+ "xref" -> do
336+ ils <- innerInlines
337+ let rid = attrValue "rid" e
338+ let refType = ("ref-type",) <$> maybeAttrValue "ref-type" e
339+ let attr = (attrValue "id" e, [], maybeToList refType)
340+ return $ linkWith attr ('#' : rid) "" ils
341+ "ext-link" -> do
342+ ils <- innerInlines
343+ let title = fromMaybe "" $ findAttr (QName "title" (Just "http://www.w3.org/1999/xlink") Nothing) e
344+ let href = case findAttr (QName "href" (Just "http://www.w3.org/1999/xlink") Nothing) e of
345+ Just h -> h
346+ _ -> '#' : attrValue "rid" e
347+ let ils' = if ils == mempty then str href else ils
348+ let attr = (attrValue "id" e, [], [])
349+ return $ linkWith attr href title ils'
350+
351+ "disp-formula" -> formula displayMath
352+ "inline-formula" -> formula math
353+ "math" | qPrefix (elName e) == Just "mml" -> return . math $ mathML e
354+ "tex-math" -> return . math $ strContent e
355+
356+ "email" -> return $ link ("mailto:" ++ strContent e) ""
357+ $ str $ strContent e
358+ "uri" -> return $ link (strContent e) "" $ str $ strContent e
359+ "fn" -> (note . mconcat) <$>
360+ mapM parseBlock (elContent e)
361+ -- Note: this isn't a real docbook tag; it's what we convert
362+ -- <?asciidor-br?> to in handleInstructions, above. A kludge to
363+ -- work around xml-light's inability to parse an instruction.
364+ _ -> innerInlines
365+ where innerInlines = (trimInlines . mconcat) <$>
366+ mapM parseInline (elContent e)
367+ mathML x =
368+ case readMathML . showElement $ everywhere (mkT removePrefix) x of
369+ Left _ -> mempty
370+ Right m -> writeTeX m
371+ formula constructor = do
372+ let whereToLook = fromMaybe e $ filterElement (named "alternatives") e
373+ texMaths = map strContent $
374+ filterChildren (named "tex-math") whereToLook
375+ mathMLs = map mathML $
376+ filterChildren isMathML whereToLook
377+ return . mconcat . take 1 . map constructor $ texMaths ++ mathMLs
378+
379+ isMathML x = qName (elName x) == "math" &&
380+ qPrefix (elName x) == Just "mml"
381+ removePrefix elname = elname { qPrefix = Nothing }
382+ codeWithLang = do
383+ let classes' = case attrValue "language" e of
384+ "" -> []
385+ l -> [l]
386+ return $ codeWith (attrValue "id" e,classes',[]) $ strContentRecursive e
387+
test/Tests/Old.hs+2
@@ -79,6 +79,8 @@ tests = [ testGroup "markdown"
7979 ]
8080 , testGroup "jats"
8181 [ testGroup "writer" $ writerTests "jats"
82+ , test "reader" ["-r", "jats", "-w", "native", "-s"]
83+ "jats-reader.xml" "jats-reader.native"
8284 ]
8385 , testGroup "native"
8486 [ testGroup "writer" $ writerTests "native"
test/Tests/Readers/JATS.hsnew file+111
@@ -0,0 +1,111 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+module Tests.Readers.JATS (tests) where
3+
4+import Data.Text (Text)
5+import Test.Tasty
6+import Tests.Helpers
7+import Text.Pandoc
8+import Text.Pandoc.Arbitrary ()
9+import Text.Pandoc.Builder
10+
11+jats :: Text -> Pandoc
12+jats = purely $ readJATS def
13+
14+tests :: [TestTree]
15+tests = [ testGroup "inline code"
16+ [ test jats "basic" $ "<p>\n <monospace>@&amp;</monospace>\n</p>" =?> para (code "@&")
17+ ]
18+ , testGroup "images"
19+ [ test jats "basic" $ "<graphic mimetype=\"image\" mime-subtype=\"\" xlink:href=\"/url\" xlink:title=\"title\" />"
20+ =?> para (image "/url" "title" mempty)
21+ ]
22+ , test jats "bullet list" $
23+ "<list list-type=\"bullet\">\n\
24+ \ <list-item>\n\
25+ \ <p>\n\
26+ \ first\n\
27+ \ </p>\n\
28+ \ </list-item>\n\
29+ \ <list-item>\n\
30+ \ <p>\n\
31+ \ second\n\
32+ \ </p>\n\
33+ \ </list-item>\n\
34+ \ <list-item>\n\
35+ \ <p>\n\
36+ \ third\n\
37+ \ </p>\n\
38+ \ </list-item>\n\
39+ \</list>"
40+ =?> bulletList [ para $ text "first"
41+ , para $ text "second"
42+ , para $ text "third"
43+ ]
44+ , testGroup "definition lists"
45+ [ test jats "with internal link" $
46+ "<def-list>\n\
47+ \ <def-item>\n\
48+ \ <term>\n\
49+ \ <xref alt=\"testing\" rid=\"go\">testing</xref>\n\
50+ \ </term>\n\
51+ \ <def>\n\
52+ \ <p>\n\
53+ \ hi there\n\
54+ \ </p>\n\
55+ \ </def>\n\
56+ \ </def-item>\n\
57+ \</def-list>"
58+ =?> definitionList [(link "#go" "" (str "testing"),
59+ [para (text "hi there")])]
60+ ]
61+ , testGroup "math"
62+ [ test jats "escape |" $
63+ "<p>\n\
64+ \ <inline-formula><alternatives>\n\
65+ \ <tex-math><![CDATA[\\sigma|_{\\{x\\}}]]></tex-math>\n\
66+ \ <mml:math display=\"inline\" xmlns:mml=\"http://www.w3.org/1998/Math/MathML\"><mml:mrow><mml:mi>σ</mml:mi><mml:msub><mml:mo stretchy=\"false\" form=\"prefix\">|</mml:mo><mml:mrow><mml:mo stretchy=\"false\" form=\"prefix\">{</mml:mo><mml:mi>x</mml:mi><mml:mo stretchy=\"false\" form=\"postfix\">}</mml:mo></mml:mrow></mml:msub></mml:mrow></mml:math></alternatives></inline-formula>\n\
67+ \</p>"
68+ =?> para (math "\\sigma|_{\\{x\\}}")
69+ , test jats "tex-math only" $
70+ "<p>\n\
71+ \ <inline-formula><alternatives>\n\
72+ \ <tex-math><![CDATA[\\sigma|_{\\{x\\}}]]></tex-math>\n\
73+ \</p>"
74+ =?> para (math "\\sigma|_{\\{x\\}}")
75+ , test jats "math ml only" $
76+ "<p>\n\
77+ \ <inline-formula><alternatives>\n\
78+ \ <mml:math display=\"inline\" xmlns:mml=\"http://www.w3.org/1998/Math/MathML\"><mml:mrow><mml:mi>σ</mml:mi><mml:msub><mml:mo stretchy=\"false\" form=\"prefix\">|</mml:mo><mml:mrow><mml:mo stretchy=\"false\" form=\"prefix\">{</mml:mo><mml:mi>x</mml:mi><mml:mo stretchy=\"false\" form=\"postfix\">}</mml:mo></mml:mrow></mml:msub></mml:mrow></mml:math></alternatives></inline-formula>\n\
79+ \</p>"
80+ =?> para (math "\\sigma|_{\\{ x\\}}")
81+ ]
82+ , testGroup "headers"
83+-- TODO fix footnotes in headers
84+-- [ test jats "unnumbered header" $
85+-- "<sec>\n\
86+-- \ <title>Header 1<fn>\n\
87+-- \ <p>\n\
88+-- \ note\n\
89+-- \ </p>\n\
90+-- \ </fn></title>\n\
91+-- \</sec>"
92+-- =?> header 1
93+-- (text "Header 1" <> note (plain $ text "note"))
94+ [ test jats "unnumbered sub header" $
95+ "<sec id=\"foo\">\n\
96+ \ <title>Header</title>\n\
97+ \ <sec id=\"foo2\">\n\
98+ \ <title>Sub-Header</title>\n\
99+ \ </sec>\n\
100+ \</sec>"
101+ =?> headerWith ("foo", [], []) 1
102+ (text "Header")
103+ <> headerWith ("foo2", [], []) 2
104+ (text "Sub-Header")
105+ , test jats "containing image" $
106+ "<sec>\n\
107+ \ <title><inline-graphic mimetype=\"image\" mime-subtype=\"jpeg\" xlink:href=\"imgs/foo.jpg\" /></title>\n\
108+ \</sec>"
109+ =?> header 1 (image "imgs/foo.jpg" "" mempty)
110+ ]
111+ ]
test/jats-reader.nativenew file+422
@@ -0,0 +1,422 @@
1+Pandoc (Meta {unMeta = fromList [("title",MetaInlines [Str "Pandoc",Space,Str "Test",Space,Str "Suite"])]})
2+[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",SoftBreak,Str "Gruber's",Space,Str "markdown",Space,Str "test",Space,Str "suite."]
3+,Header 1 ("headers",[],[]) [Str "Headers"]
4+,Header 2 ("level-2-with-an-embedded-link",[],[]) [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",SoftBreak,Link ("",[],[]) [Str "embedded",SoftBreak,Str "link"] ("/url","")]
5+,Header 3 ("level-3-with-emphasis",[],[]) [Str "Level",Space,Str "3",Space,Str "with",Space,Emph [Str "emphasis"]]
6+,Header 4 ("level-4",[],[]) [Str "Level",Space,Str "4"]
7+,Header 5 ("level-5",[],[]) [Str "Level",Space,Str "5"]
8+,Header 1 ("level-1",[],[]) [Str "Level",Space,Str "1"]
9+,Header 2 ("level-2-with-emphasis",[],[]) [Str "Level",Space,Str "2",Space,Str "with",Space,Emph [Str "emphasis"]]
10+,Header 3 ("level-3",[],[]) [Str "Level",Space,Str "3"]
11+,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]
12+,Header 2 ("level-2",[],[]) [Str "Level",Space,Str "2"]
13+,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]
14+,Header 1 ("paragraphs",[],[]) [Str "Paragraphs"]
15+,Para [Str "Here's",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]
16+,Para [Str "In",Space,Str "Markdown",Space,Str "1.0.0",Space,Str "and",Space,Str "earlier.",Space,Str "Version",Space,Str "8.",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",SoftBreak,Str "list",Space,Str "item.",Space,Str "Because",Space,Str "a",Space,Str "hard-wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",SoftBreak,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item."]
17+,Para [Str "Here's",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet.",Space,Str "*",Space,Str "criminey."]
18+,Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here."]
19+,Header 1 ("block-quotes",[],[]) [Str "Block",Space,Str "Quotes"]
20+,Para [Str "E-mail",Space,Str "style:"]
21+,BlockQuote
22+ [Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote.",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short."]]
23+,BlockQuote
24+ [Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote:"]
25+ ,CodeBlock ("",[],[]) "sub status {\n print \"working\";\n}"
26+ ,Para [Str "A",Space,Str "list:"]
27+ ,OrderedList (1,DefaultStyle,DefaultDelim)
28+ [[Para [Str "item",Space,Str "one"]]
29+ ,[Para [Str "item",Space,Str "two"]]]
30+ ,Para [Str "Nested",Space,Str "block",Space,Str "quotes:"]
31+ ,BlockQuote
32+ [Para [Str "nested"]]
33+ ,BlockQuote
34+ [Para [Str "nested"]]]
35+,Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "block",Space,Str "quote:",Space,Str "2",Space,Str ">",Space,Str "1."]
36+,Para [Str "Box-style:"]
37+,BlockQuote
38+ [Para [Str "Example:"]
39+ ,CodeBlock ("",[],[]) "sub status {\n print \"working\";\n}"]
40+,BlockQuote
41+ [OrderedList (1,DefaultStyle,DefaultDelim)
42+ [[Para [Str "do",Space,Str "laundry"]]
43+ ,[Para [Str "take",Space,Str "out",Space,Str "the",Space,Str "trash"]]]]
44+,Para [Str "Here's",Space,Str "a",Space,Str "nested",Space,Str "one:"]
45+,BlockQuote
46+ [Para [Str "Joe",Space,Str "said:"]
47+ ,BlockQuote
48+ [Para [Str "Don't",Space,Str "quote",Space,Str "me."]]]
49+,Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph."]
50+,Header 1 ("code-blocks",[],[]) [Str "Code",Space,Str "Blocks"]
51+,Para [Str "Code:"]
52+,CodeBlock ("",[],[]) "---- (should be four hyphens)\n\nsub status {\n print \"working\";\n}\n\nthis code block is indented by one tab"
53+,Para [Str "And:"]
54+,CodeBlock ("",[],[]) " this code block is indented by two tabs\n\nThese should not be escaped: \\$ \\\\ \\> \\[ \\{"
55+,Header 1 ("lists",[],[]) [Str "Lists"]
56+,Header 2 ("unordered",[],[]) [Str "Unordered"]
57+,Para [Str "Asterisks",Space,Str "tight:"]
58+,BulletList
59+ [[Para [Str "asterisk",Space,Str "1"]]
60+ ,[Para [Str "asterisk",Space,Str "2"]]
61+ ,[Para [Str "asterisk",Space,Str "3"]]]
62+,Para [Str "Asterisks",Space,Str "loose:"]
63+,BulletList
64+ [[Para [Str "asterisk",Space,Str "1"]]
65+ ,[Para [Str "asterisk",Space,Str "2"]]
66+ ,[Para [Str "asterisk",Space,Str "3"]]]
67+,Para [Str "Pluses",Space,Str "tight:"]
68+,BulletList
69+ [[Para [Str "Plus",Space,Str "1"]]
70+ ,[Para [Str "Plus",Space,Str "2"]]
71+ ,[Para [Str "Plus",Space,Str "3"]]]
72+,Para [Str "Pluses",Space,Str "loose:"]
73+,BulletList
74+ [[Para [Str "Plus",Space,Str "1"]]
75+ ,[Para [Str "Plus",Space,Str "2"]]
76+ ,[Para [Str "Plus",Space,Str "3"]]]
77+,Para [Str "Minuses",Space,Str "tight:"]
78+,BulletList
79+ [[Para [Str "Minus",Space,Str "1"]]
80+ ,[Para [Str "Minus",Space,Str "2"]]
81+ ,[Para [Str "Minus",Space,Str "3"]]]
82+,Para [Str "Minuses",Space,Str "loose:"]
83+,BulletList
84+ [[Para [Str "Minus",Space,Str "1"]]
85+ ,[Para [Str "Minus",Space,Str "2"]]
86+ ,[Para [Str "Minus",Space,Str "3"]]]
87+,Header 2 ("ordered",[],[]) [Str "Ordered"]
88+,Para [Str "Tight:"]
89+,OrderedList (1,DefaultStyle,DefaultDelim)
90+ [[Para [Str "First"]]
91+ ,[Para [Str "Second"]]
92+ ,[Para [Str "Third"]]]
93+,Para [Str "and:"]
94+,OrderedList (1,DefaultStyle,DefaultDelim)
95+ [[Para [Str "One"]]
96+ ,[Para [Str "Two"]]
97+ ,[Para [Str "Three"]]]
98+,Para [Str "Loose",Space,Str "using",Space,Str "tabs:"]
99+,OrderedList (1,DefaultStyle,DefaultDelim)
100+ [[Para [Str "First"]]
101+ ,[Para [Str "Second"]]
102+ ,[Para [Str "Third"]]]
103+,Para [Str "and",Space,Str "using",Space,Str "spaces:"]
104+,OrderedList (1,DefaultStyle,DefaultDelim)
105+ [[Para [Str "One"]]
106+ ,[Para [Str "Two"]]
107+ ,[Para [Str "Three"]]]
108+,Para [Str "Multiple",Space,Str "paragraphs:"]
109+,OrderedList (1,DefaultStyle,DefaultDelim)
110+ [[Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one."]
111+ ,Para [Str "Item",Space,Str "1.",Space,Str "graf",Space,Str "two.",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",SoftBreak,Str "dog's",Space,Str "back."]]
112+ ,[Para [Str "Item",Space,Str "2."]]
113+ ,[Para [Str "Item",Space,Str "3."]]]
114+,Para [Str "List",Space,Str "styles:"]
115+,OrderedList (1,DefaultStyle,DefaultDelim)
116+ []
117+,OrderedList (1,LowerRoman,DefaultDelim)
118+ []
119+,Header 2 ("nested",[],[]) [Str "Nested"]
120+,BulletList
121+ [[Para [Str "Tab"]
122+ ,BulletList
123+ [[Para [Str "Tab"]
124+ ,BulletList
125+ [[Para [Str "Tab"]]]]]]]
126+,Para [Str "Here's",Space,Str "another:"]
127+,OrderedList (1,DefaultStyle,DefaultDelim)
128+ [[Para [Str "First"]]
129+ ,[Para [Str "Second:"]
130+ ,BulletList
131+ [[Para [Str "Fee"]]
132+ ,[Para [Str "Fie"]]
133+ ,[Para [Str "Foe"]]]]
134+ ,[Para [Str "Third"]]]
135+,Para [Str "Same",Space,Str "thing",Space,Str "but",Space,Str "with",Space,Str "paragraphs:"]
136+,OrderedList (1,DefaultStyle,DefaultDelim)
137+ [[Para [Str "First"]]
138+ ,[Para [Str "Second:"]
139+ ,BulletList
140+ [[Para [Str "Fee"]]
141+ ,[Para [Str "Fie"]]
142+ ,[Para [Str "Foe"]]]]
143+ ,[Para [Str "Third"]]]
144+,Header 2 ("tabs-and-spaces",[],[]) [Str "Tabs",Space,Str "and",Space,Str "spaces"]
145+,BulletList
146+ [[Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"]]
147+ ,[Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]
148+ ,BulletList
149+ [[Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"]]
150+ ,[Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]]]]]
151+,Header 2 ("fancy-list-markers",[],[]) [Str "Fancy",Space,Str "list",Space,Str "markers"]
152+,Para [Str "Autonumbering:"]
153+,OrderedList (1,DefaultStyle,DefaultDelim)
154+ [[Para [Str "Autonumber."]]
155+ ,[Para [Str "More."]
156+ ,OrderedList (1,DefaultStyle,DefaultDelim)
157+ [[Para [Str "Nested."]]]]]
158+,Header 2 ("definition",[],[]) [Str "Definition"]
159+,DefinitionList
160+ [([Str "Violin"],
161+ [[Para [Str "Stringed",Space,Str "musical",Space,Str "instrument."]
162+ ,Para [Str "Torture",Space,Str "device."]]])
163+ ,([Str "Cello",LineBreak,Str "Violoncello"],
164+ [[Para [Str "Low-voiced",Space,Str "stringed",Space,Str "instrument."]]])]
165+,Header 1 ("inline-markup",[],[]) [Str "Inline",Space,Str "Markup"]
166+,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",SoftBreak,Str "this"],Str "."]
167+,Para [Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",SoftBreak,Strong [Str "is",Space,Str "this"],Str "."]
168+,Para [Str "Empty",Space,Strong [],Space,Str "and",Space,Emph [],Str "."]
169+,Para [Str "An",SoftBreak,Emph [Link ("",[],[]) [Str "emphasized",SoftBreak,Str "link"] ("/url","")],Str "."]
170+,Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]
171+,Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]
172+,Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]
173+,Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]
174+,Para [Str "This",Space,Str "is",Space,Str "code:",Space,Code ("",[],[]) ">",Str ",",Space,Code ("",[],[]) "$",Str ",",SoftBreak,Code ("",[],[]) "\\",Str ",",Space,Code ("",[],[]) "\\$",Str ",",SoftBreak,Code ("",[],[]) "<html>",Str "."]
175+,Para [Str "This",Space,Str "is",Space,SmallCaps [Str "small",Space,Str "caps"],Str "."]
176+,Para [Str "These",Space,Str "are",Space,Str "all",Space,Str "underlined:",Space,Str "foo",Space,Str "and",Space,Str "bar."]
177+,Para [Str "These",Space,Str "are",Space,Str "all",Space,Str "strikethrough:",Space,Strikeout [Str "foo"],Str ",",SoftBreak,Strikeout [Str "bar"],Str ",",Space,Str "and",Space,Strikeout [Str "baz"],Str "."]
178+,Header 1 ("smart-quotes-ellipses-dashes",[],[]) [Str "Smart",Space,Str "quotes,",Space,Str "ellipses,",Space,Str "dashes"]
179+,Para [Str "\"Hello,\"",Space,Str "said",Space,Str "the",Space,Str "spider.",Space,Str "\"'Shelob'",Space,Str "is",Space,Str "my",Space,Str "name.\""]
180+,Para [Str "'A',",Space,Str "'B',",Space,Str "and",Space,Str "'C'",Space,Str "are",Space,Str "letters."]
181+,Para [Str "'Oak,'",Space,Str "'elm,'",Space,Str "and",Space,Str "'beech'",Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees.",Space,Str "So",Space,Str "is",Space,Str "'pine.'"]
182+,Para [Str "'He",Space,Str "said,",Space,Str "\"I",Space,Str "want",Space,Str "to",Space,Str "go.\"'",Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70's?"]
183+,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Str "'",Code ("",[],[]) "code",Str "'",Space,Str "and",Space,Str "a",SoftBreak,Str "\"",Link ("",[],[]) [Str "quoted",SoftBreak,Str "link"] ("http://example.com/?foo=1&bar=2",""),Str "\"."]
184+,Para [Str "Some",Space,Str "dashes:",Space,Str "one---two",Space,Str "---",Space,Str "three--four",Space,Str "--",Space,Str "five."]
185+,Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5-7,",Space,Str "255-66,",Space,Str "1987-1999."]
186+,Para [Str "Ellipses...and.",Space,Str ".",Space,Str ".and",Space,Str ".",Space,Str ".",Space,Str ".",Space,Str "."]
187+,Header 1 ("latex",[],[]) [Str "LaTeX"]
188+,BulletList
189+ [[Para [Str "\\cite[22-23]{smith.1899}"]]
190+ ,[Para [Str "\\doublespacing"]]
191+ ,[Para [Str "$2+2=4$"]]
192+ ,[Para [Str "$x",Space,Str "\\in",Space,Str "y$"]]
193+ ,[Para [Str "$\\alpha",Space,Str "\\wedge",Space,Str "\\omega$"]]
194+ ,[Para [Str "$223$"]]
195+ ,[Para [Str "$p$-Tree"]]
196+ ,[Para [Str "$\\frac{d}{dx}f(x)=\\lim_{h\\to",Space,Str "0}\\frac{f(x+h)-f(x)}{h}$"]]
197+ ,[Para [Str "Here's",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,Str "$\\alpha",Space,Str "+",Space,Str "\\omega",Space,Str "\\times",SoftBreak,Str "x^2$."]]]
198+,Para [Str "These",Space,Str "shouldn't",Space,Str "be",Space,Str "math:"]
199+,BulletList
200+ [[Para [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation,",Space,Str "write",SoftBreak,Code ("",[],[]) "$e = mc^2$",Str "."]]
201+ ,[Para [Str "$22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money.",Space,Str "So",Space,Str "is",Space,Str "$34,000.",Space,Str "(It",SoftBreak,Str "worked",Space,Str "if",Space,Str "\"lot\"",Space,Str "is",Space,Str "emphasized.)"]]
202+ ,[Para [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",SoftBreak,Str "emphasized"],Space,Str "23$."]]]
203+,Para [Str "Here's",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]
204+,Para [Str "\\begin{tabular}{|l|l|}\\hline",Space,Str "Animal",Space,Str "&",Space,Str "Number",Space,Str "\\\\",Space,Str "\\hline",Space,Str "Dog",Space,Str "&",SoftBreak,Str "2",Space,Str "\\\\",Space,Str "Cat",Space,Str "&",Space,Str "1",Space,Str "\\\\",Space,Str "\\hline",Space,Str "\\end{tabular}"]
205+,Header 1 ("special-characters",[],[]) [Str "Special",Space,Str "Characters"]
206+,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]
207+,BulletList
208+ [[Para [Str "I",Space,Str "hat:",Space,Str "\206"]]
209+ ,[Para [Str "o",Space,Str "umlaut:",Space,Str "\246"]]
210+ ,[Para [Str "section:",Space,Str "\167"]]
211+ ,[Para [Str "set",Space,Str "membership:",Space,Str "elem"]]
212+ ,[Para [Str "copyright:",Space,Str "\169"]]]
213+,Para [Str "AT&T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name."]
214+,Para [Str "AT&T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it."]
215+,Para [Str "This",Space,Str "&",Space,Str "that."]
216+,Para [Str "4",Space,Str "<",Space,Str "5."]
217+,Para [Str "6",Space,Str ">",Space,Str "5."]
218+,Para [Str "Backslash:",Space,Str "\\"]
219+,Para [Str "Backtick:",Space,Str "`"]
220+,Para [Str "Asterisk:",Space,Str "*"]
221+,Para [Str "Underscore:",Space,Str "_"]
222+,Para [Str "Left",Space,Str "brace:",Space,Str "{"]
223+,Para [Str "Right",Space,Str "brace:",Space,Str "}"]
224+,Para [Str "Left",Space,Str "bracket:",Space,Str "["]
225+,Para [Str "Right",Space,Str "bracket:",Space,Str "]"]
226+,Para [Str "Left",Space,Str "paren:",Space,Str "("]
227+,Para [Str "Right",Space,Str "paren:",Space,Str ")"]
228+,Para [Str "Greater-than:",Space,Str ">"]
229+,Para [Str "Hash:",Space,Str "#"]
230+,Para [Str "Period:",Space,Str "."]
231+,Para [Str "Bang:",Space,Str "!"]
232+,Para [Str "Plus:",Space,Str "+"]
233+,Para [Str "Minus:",Space,Str "-"]
234+,Header 1 ("links",[],[]) [Str "Links"]
235+,Header 2 ("explicit",[],[]) [Str "Explicit"]
236+,Para [Str "Just",Space,Str "a",SoftBreak,Link ("",[],[]) [Str "URL"] ("/url/",""),Str "."]
237+,Para [Link ("",[],[]) [Str "URL",SoftBreak,Str "and",Space,Str "title"] ("/url/","title"),Str "."]
238+,Para [Link ("",[],[]) [Str "URL",SoftBreak,Str "and",Space,Str "title"] ("/url/","title preceded by two spaces"),Str "."]
239+,Para [Link ("",[],[]) [Str "URL",SoftBreak,Str "and",Space,Str "title"] ("/url/","title preceded by a tab"),Str "."]
240+,Para [Link ("",[],[]) [Str "URL",SoftBreak,Str "and",Space,Str "title"] ("/url/","title with \"quotes\" in it")]
241+,Para [Link ("",[],[]) [Str "URL",SoftBreak,Str "and",Space,Str "title"] ("/url/","title with single quotes")]
242+,Para [Str "Email",Space,Str "link",Space,Str "(nobody",Space,Str "[at]",Space,Str "nowhere.net)"]
243+,Para [Link ("",[],[]) [Str "Empty"] ("",""),Str "."]
244+,Header 2 ("reference",[],[]) [Str "Reference"]
245+,Para [Str "Foo",SoftBreak,Link ("",[],[]) [Str "bar"] ("/url/",""),Str "."]
246+,Para [Str "Foo",SoftBreak,Link ("",[],[]) [Str "bar"] ("/url/",""),Str "."]
247+,Para [Str "Foo",SoftBreak,Link ("",[],[]) [Str "bar"] ("/url/",""),Str "."]
248+,Para [Str "With",Space,Link ("",[],[]) [Str "embedded",SoftBreak,Str "[brackets]"] ("/url/",""),Str "."]
249+,Para [Link ("",[],[]) [Str "b"] ("/url/",""),Space,Str "by",SoftBreak,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link."]
250+,Para [Str "Indented",SoftBreak,Link ("",[],[]) [Str "once"] ("/url",""),Str "."]
251+,Para [Str "Indented",SoftBreak,Link ("",[],[]) [Str "twice"] ("/url",""),Str "."]
252+,Para [Str "Indented",SoftBreak,Link ("",[],[]) [Str "thrice"] ("/url",""),Str "."]
253+,Para [Str "This",Space,Str "should",Space,Str "[not]",Space,Str "be",Space,Str "a",Space,Str "link."]
254+,CodeBlock ("",[],[]) "[not]: /url"
255+,Para [Str "Foo",SoftBreak,Link ("",[],[]) [Str "bar"] ("/url/","Title with \"quotes\" inside"),Str "."]
256+,Para [Str "Foo",SoftBreak,Link ("",[],[]) [Str "biz"] ("/url/","Title with \"quote\" inside"),Str "."]
257+,Header 2 ("with-ampersands",[],[]) [Str "With",Space,Str "ampersands"]
258+,Para [Str "Here's",Space,Str "a",SoftBreak,Link ("",[],[]) [Str "link",SoftBreak,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
259+,Para [Str "Here's",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",SoftBreak,Link ("",[],[]) [Str "AT&T"] ("http://att.com/","AT&T"),Str "."]
260+,Para [Str "Here's",Space,Str "an",SoftBreak,Link ("",[],[]) [Str "inline",SoftBreak,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
261+,Para [Str "Here's",Space,Str "an",SoftBreak,Link ("",[],[]) [Str "inline",SoftBreak,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]
262+,Header 2 ("autolinks",[],[]) [Str "Autolinks"]
263+,Para [Str "With",Space,Str "an",Space,Str "ampersand:",SoftBreak,Link ("",[],[]) [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
264+,BulletList
265+ [[Para [Str "In",Space,Str "a",Space,Str "list?"]]
266+ ,[Para [Link ("",[],[]) [Str "http://example.com/"] ("http://example.com/","")]]
267+ ,[Para [Str "It",Space,Str "should."]]]
268+,Para [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Str "nobody",Space,Str "[at]",Space,Str "nowhere.net"]
269+,BlockQuote
270+ [Para [Str "Blockquoted:",SoftBreak,Link ("",[],[]) [Str "http://example.com/"] ("http://example.com/","")]]
271+,Para [Str "Auto-links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",SoftBreak,Code ("",[],[]) "<http://example.com/>"]
272+,CodeBlock ("",[],[]) "or here: <http://example.com/>"
273+,Header 1 ("images",[],[]) [Str "Images"]
274+,Para [Str "From",Space,Str "\"Voyage",Space,Str "dans",Space,Str "la",Space,Str "Lune\"",Space,Str "by",Space,Str "Georges",Space,Str "Melies",Space,Str "(1902):"]
275+,Para [Image ("",[],[]) [] ("lalune.jpg","Voyage dans la Lune")]
276+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",SoftBreak,Image ("",[],[]) [] ("movie.jpg",""),SoftBreak,Str "icon."]
277+,Header 1 ("footnotes",[],[]) [Str "Footnotes"]
278+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference",Link ("",[],[]) [Str "(1)"] ("#note_1",""),Str ",",SoftBreak,Str "and",SoftBreak,Str "another",Link ("",[],[]) [Str "(longnote)"] ("#note_longnote",""),Str ".",SoftBreak,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",SoftBreak,Str "contains",Space,Str "a",Space,Str "space^(my",Space,Str "note)."]
279+,Para [Link ("",[],[]) [Str "(1)"] ("#ref_1",""),Space,Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",SoftBreak,Str "go",Space,Str "anywhere",Space,Str "in",Space,Str "the",Space,Str "document,",Space,Str "not",Space,Str "just",Space,Str "at",Space,Str "the",Space,Str "end."]
280+,Para [Link ("",[],[]) [Str "(longnote)"] ("#ref_longnote",""),Space,Str "Here's",SoftBreak,Str "the",Space,Str "other",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."]
281+,Para [Str "Caret",Space,Str "characters",Space,Str "are",Space,Str "used",Space,Str "to",Space,Str "indicate",Space,Str "that",Space,Str "the",Space,Str "blocks",Space,Str "all",Space,Str "belong",Space,Str "to",SoftBreak,Str "a",Space,Str "single",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "block",Space,Str "quotes)."]
282+,CodeBlock ("",[],[]) " { <code> }"
283+,Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "use",Space,Str "a",Space,Str "caret",Space,Str "at",Space,Str "the",Space,Str "beginning",Space,Str "of",Space,Str "every",Space,Str "line,",Space,Str "as",SoftBreak,Str "with",Space,Str "blockquotes,",Space,Str "but",Space,Str "all",Space,Str "that",Space,Str "you",Space,Str "need",Space,Str "is",Space,Str "a",Space,Str "caret",Space,Str "at",Space,Str "the",Space,Str "beginning",SoftBreak,Str "of",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "the",Space,Str "block",Space,Str "and",Space,Str "any",Space,Str "preceding",Space,Str "blank",Space,Str "lines."]
284+,Para [Str "text",Space,Emph [Str "Leading",Space,Str "space"]]
285+,Para [Emph [Str "Trailing",Space,Str "space"],Space,Str "text"]
286+,Para [Str "text",Space,Emph [Str "Leading",Space,Str "spaces"]]
287+,Para [Emph [Str "Trailing",Space,Str "spaces"],Space,Str "text"]
288+,Header 1 ("tables",[],[]) [Str "Tables"]
289+,Header 2 ("tables-with-headers",[],[]) [Str "Tables",Space,Str "with",Space,Str "Headers"]
290+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
291+ [[Para [Str "X"]]
292+ ,[Para [Str "Y"]]
293+ ,[Para [Str "Z"]]]
294+ [[[Para [Str "1"]]
295+ ,[Para [Str "2"]]
296+ ,[Para [Str "3"]]]
297+ ,[[Para [Str "4"]]
298+ ,[Para [Str "5"]]
299+ ,[Para [Str "6"]]]]
300+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
301+ [[Para [Str "X"]]
302+ ,[Para [Str "Y"]]
303+ ,[Para [Str "Z"]]]
304+ [[[Para [Str "1"]]
305+ ,[Para [Str "2"]]
306+ ,[Para [Str "3"]]]
307+ ,[[Para [Str "4"]]
308+ ,[Para [Str "5"]]
309+ ,[Para [Str "6"]]]]
310+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
311+ [[Para [Str "X"]]
312+ ,[Para [Str "Y"]]
313+ ,[Para [Str "Z"]]]
314+ [[[Para [Str "1"]]
315+ ,[Para [Str "2"]]
316+ ,[Para [Str "3"]]]
317+ ,[[Para [Str "4"]]
318+ ,[Para [Str "5"]]
319+ ,[Para [Str "6"]]]]
320+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
321+ [[Para [Str "X"]]
322+ ,[Para [Str "Y"]]
323+ ,[Para [Str "Z"]]]
324+ [[[Para [Str "1"]]
325+ ,[Para [Str "2"]]
326+ ,[Para [Str "3"]]]
327+ ,[[Para [Str "4"]]
328+ ,[Para [Str "5"]]
329+ ,[Para [Str "6"]]]]
330+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
331+ [[Para [Str "X"]]
332+ ,[Para [Str "Y"]]
333+ ,[Para [Str "Z"]]]
334+ [[[Para [Str "1"]]
335+ ,[Para [Str "2"]]
336+ ,[Para [Str "3"]]]
337+ ,[[Para [Str "4"]]
338+ ,[Para [Str "5"]]
339+ ,[Para [Str "6"]]]]
340+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
341+ [[Para [Str "X"]]
342+ ,[Para [Str "Y"]]
343+ ,[Para [Str "Z"]]]
344+ [[[Para [Str "1"]]
345+ ,[Para [Str "2"]]
346+ ,[Para [Str "3"]]]
347+ ,[[Para [Str "4"]]
348+ ,[Para [Str "5"]]
349+ ,[Para [Str "6"]]]]
350+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
351+ [[Para [Str "X"]]
352+ ,[Para [Str "Y"]]
353+ ,[Para [Str "Z"]]]
354+ [[[Para [Str "1"]]
355+ ,[Para [Str "2"]]
356+ ,[Para [Str "3"]]]
357+ ,[[Para [Str "4"]]
358+ ,[Para [Str "5"]]
359+ ,[Para [Str "6"]]]]
360+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
361+ [[Para [Str "X"]]
362+ ,[Para [Str "Y"]]
363+ ,[Para [Str "Z"]]]
364+ [[[Para [Str "1"]]
365+ ,[Para [Str "2"]]
366+ ,[Para [Str "3"]]]
367+ ,[[Para [Str "4"]]
368+ ,[Para [Str "5"]]
369+ ,[Para [Str "6"]]]]
370+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
371+ [[Para [Str "X"]]
372+ ,[Para [Str "Y"]]
373+ ,[Para [Str "Z"]]]
374+ [[[Para [Str "1"]]
375+ ,[Para [Str "2"]]
376+ ,[Para [Str "3"]]]
377+ ,[[Para [Str "4"]]
378+ ,[Para [Str "5"]]
379+ ,[Para [Str "6"]]]]
380+,Header 2 ("tables-without-headers",[],[]) [Str "Tables",Space,Str "without",Space,Str "Headers"]
381+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
382+ [[]
383+ ,[]
384+ ,[]]
385+ [[[Para [Str "1"]]
386+ ,[Para [Str "2"]]
387+ ,[Para [Str "3"]]]
388+ ,[[Para [Str "4"]]
389+ ,[Para [Str "5"]]
390+ ,[Para [Str "6"]]]]
391+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
392+ [[]
393+ ,[]
394+ ,[]]
395+ [[[Para [Str "1"]]
396+ ,[Para [Str "2"]]
397+ ,[Para [Str "3"]]]
398+ ,[[Para [Str "4"]]
399+ ,[Para [Str "5"]]
400+ ,[Para [Str "6"]]]]
401+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
402+ [[]
403+ ,[]
404+ ,[]]
405+ [[[Para [Str "1"]]
406+ ,[Para [Str "2"]]
407+ ,[Para [Str "3"]]]
408+ ,[[Para [Str "4"]]
409+ ,[Para [Str "5"]]
410+ ,[Para [Str "6"]]]]
411+,Table [] [AlignLeft,AlignLeft,AlignLeft] [0.0,0.0,0.0]
412+ [[]
413+ ,[]
414+ ,[]]
415+ [[[Para [Str "1"]]
416+ ,[Para [Str "2"]]
417+ ,[Para [Str "3"]]]
418+ ,[[Para [Str "4"]]
419+ ,[Para [Str "5"]]
420+ ,[Para [Str "6"]]]]
421+,Header 2 ("empty-tables",[],[]) [Str "Empty",Space,Str "Tables"]
422+,Para [Str "This",Space,Str "section",Space,Str "should",Space,Str "be",Space,Str "empty."]]
test/jats-reader.xmlnew file+1773
@@ -0,0 +1,1773 @@
1+<?xml version="1.0" encoding="utf-8" ?>
2+<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.0 20120330//EN"
3+ "JATS-journalpublishing1.dtd">
4+<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" dtd-version="1.0" article-type="other">
5+<front>
6+<journal-meta>
7+<journal-title-group>
8+</journal-title-group>
9+<publisher>
10+<publisher-name></publisher-name>
11+</publisher>
12+</journal-meta>
13+<article-meta>
14+<title-group>
15+<article-title>Pandoc Test Suite</article-title>
16+</title-group>
17+</article-meta>
18+</front>
19+<body>
20+<p>
21+ This is a set of tests for pandoc. Most of them are adapted from John
22+ Gruber's markdown test suite.
23+</p>
24+<sec id="headers">
25+ <title>Headers</title>
26+ <sec id="level-2-with-an-embedded-link">
27+ <title>Level 2 with an
28+ <ext-link ext-link-type="uri" xlink:href="/url">embedded
29+ link</ext-link></title>
30+ <sec id="level-3-with-emphasis">
31+ <title>Level 3 with <italic>emphasis</italic></title>
32+ <sec id="level-4">
33+ <title>Level 4</title>
34+ <sec id="level-5">
35+ <title>Level 5</title>
36+ </sec>
37+ </sec>
38+ </sec>
39+ </sec>
40+</sec>
41+<sec id="level-1">
42+ <title>Level 1</title>
43+ <sec id="level-2-with-emphasis">
44+ <title>Level 2 with <italic>emphasis</italic></title>
45+ <sec id="level-3">
46+ <title>Level 3</title>
47+ <p>
48+ with no blank line
49+ </p>
50+ </sec>
51+ </sec>
52+ <sec id="level-2">
53+ <title>Level 2</title>
54+ <p>
55+ with no blank line
56+ </p>
57+ </sec>
58+</sec>
59+<sec id="paragraphs">
60+ <title>Paragraphs</title>
61+ <p>
62+ Here's a regular paragraph.
63+ </p>
64+ <p>
65+ In Markdown 1.0.0 and earlier. Version 8. This line turns into a
66+ list item. Because a hard-wrapped line in the middle of a paragraph
67+ looked like a list item.
68+ </p>
69+ <p>
70+ Here's one with a bullet. * criminey.
71+ </p>
72+ <p>
73+ There should be a hard line break<break />here.
74+ </p>
75+</sec>
76+<sec id="block-quotes">
77+ <title>Block Quotes</title>
78+ <p>
79+ E-mail style:
80+ </p>
81+ <disp-quote>
82+ <p>
83+ This is a block quote. It is pretty short.
84+ </p>
85+ </disp-quote>
86+ <disp-quote>
87+ <p>
88+ Code in a block quote:
89+ </p>
90+ <preformat>sub status {
91+ print &quot;working&quot;;
92+}</preformat>
93+ <p>
94+ A list:
95+ </p>
96+ <list list-type="order">
97+ <list-item>
98+ <p>
99+ item one
100+ </p>
101+ </list-item>
102+ <list-item>
103+ <p>
104+ item two
105+ </p>
106+ </list-item>
107+ </list>
108+ <p>
109+ Nested block quotes:
110+ </p>
111+ <disp-quote>
112+ <p>
113+ nested
114+ </p>
115+ </disp-quote>
116+ <disp-quote>
117+ <p>
118+ nested
119+ </p>
120+ </disp-quote>
121+ </disp-quote>
122+ <p>
123+ This should not be a block quote: 2 &gt; 1.
124+ </p>
125+ <p>
126+ Box-style:
127+ </p>
128+ <disp-quote>
129+ <p>
130+ Example:
131+ </p>
132+ <preformat>sub status {
133+ print &quot;working&quot;;
134+}</preformat>
135+ </disp-quote>
136+ <disp-quote>
137+ <list list-type="order">
138+ <list-item>
139+ <p>
140+ do laundry
141+ </p>
142+ </list-item>
143+ <list-item>
144+ <p>
145+ take out the trash
146+ </p>
147+ </list-item>
148+ </list>
149+ </disp-quote>
150+ <p>
151+ Here's a nested one:
152+ </p>
153+ <disp-quote>
154+ <p>
155+ Joe said:
156+ </p>
157+ <disp-quote>
158+ <p>
159+ Don't quote me.
160+ </p>
161+ </disp-quote>
162+ </disp-quote>
163+ <p>
164+ And a following paragraph.
165+ </p>
166+</sec>
167+<sec id="code-blocks">
168+ <title>Code Blocks</title>
169+ <p>
170+ Code:
171+ </p>
172+ <preformat>---- (should be four hyphens)
173+
174+sub status {
175+ print &quot;working&quot;;
176+}
177+
178+this code block is indented by one tab</preformat>
179+ <p>
180+ And:
181+ </p>
182+ <preformat> this code block is indented by two tabs
183+
184+These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
185+</sec>
186+<sec id="lists">
187+ <title>Lists</title>
188+ <sec id="unordered">
189+ <title>Unordered</title>
190+ <p>
191+ Asterisks tight:
192+ </p>
193+ <list list-type="bullet">
194+ <list-item>
195+ <p>
196+ asterisk 1
197+ </p>
198+ </list-item>
199+ <list-item>
200+ <p>
201+ asterisk 2
202+ </p>
203+ </list-item>
204+ <list-item>
205+ <p>
206+ asterisk 3
207+ </p>
208+ </list-item>
209+ </list>
210+ <p>
211+ Asterisks loose:
212+ </p>
213+ <list list-type="bullet">
214+ <list-item>
215+ <p>
216+ asterisk 1
217+ </p>
218+ </list-item>
219+ <list-item>
220+ <p>
221+ asterisk 2
222+ </p>
223+ </list-item>
224+ <list-item>
225+ <p>
226+ asterisk 3
227+ </p>
228+ </list-item>
229+ </list>
230+ <p>
231+ Pluses tight:
232+ </p>
233+ <list list-type="bullet">
234+ <list-item>
235+ <p>
236+ Plus 1
237+ </p>
238+ </list-item>
239+ <list-item>
240+ <p>
241+ Plus 2
242+ </p>
243+ </list-item>
244+ <list-item>
245+ <p>
246+ Plus 3
247+ </p>
248+ </list-item>
249+ </list>
250+ <p>
251+ Pluses loose:
252+ </p>
253+ <list list-type="bullet">
254+ <list-item>
255+ <p>
256+ Plus 1
257+ </p>
258+ </list-item>
259+ <list-item>
260+ <p>
261+ Plus 2
262+ </p>
263+ </list-item>
264+ <list-item>
265+ <p>
266+ Plus 3
267+ </p>
268+ </list-item>
269+ </list>
270+ <p>
271+ Minuses tight:
272+ </p>
273+ <list list-type="bullet">
274+ <list-item>
275+ <p>
276+ Minus 1
277+ </p>
278+ </list-item>
279+ <list-item>
280+ <p>
281+ Minus 2
282+ </p>
283+ </list-item>
284+ <list-item>
285+ <p>
286+ Minus 3
287+ </p>
288+ </list-item>
289+ </list>
290+ <p>
291+ Minuses loose:
292+ </p>
293+ <list list-type="bullet">
294+ <list-item>
295+ <p>
296+ Minus 1
297+ </p>
298+ </list-item>
299+ <list-item>
300+ <p>
301+ Minus 2
302+ </p>
303+ </list-item>
304+ <list-item>
305+ <p>
306+ Minus 3
307+ </p>
308+ </list-item>
309+ </list>
310+ </sec>
311+ <sec id="ordered">
312+ <title>Ordered</title>
313+ <p>
314+ Tight:
315+ </p>
316+ <list list-type="order">
317+ <list-item>
318+ <p>
319+ First
320+ </p>
321+ </list-item>
322+ <list-item>
323+ <p>
324+ Second
325+ </p>
326+ </list-item>
327+ <list-item>
328+ <p>
329+ Third
330+ </p>
331+ </list-item>
332+ </list>
333+ <p>
334+ and:
335+ </p>
336+ <list list-type="order">
337+ <list-item>
338+ <p>
339+ One
340+ </p>
341+ </list-item>
342+ <list-item>
343+ <p>
344+ Two
345+ </p>
346+ </list-item>
347+ <list-item>
348+ <p>
349+ Three
350+ </p>
351+ </list-item>
352+ </list>
353+ <p>
354+ Loose using tabs:
355+ </p>
356+ <list list-type="order">
357+ <list-item>
358+ <p>
359+ First
360+ </p>
361+ </list-item>
362+ <list-item>
363+ <p>
364+ Second
365+ </p>
366+ </list-item>
367+ <list-item>
368+ <p>
369+ Third
370+ </p>
371+ </list-item>
372+ </list>
373+ <p>
374+ and using spaces:
375+ </p>
376+ <list list-type="order">
377+ <list-item>
378+ <p>
379+ One
380+ </p>
381+ </list-item>
382+ <list-item>
383+ <p>
384+ Two
385+ </p>
386+ </list-item>
387+ <list-item>
388+ <p>
389+ Three
390+ </p>
391+ </list-item>
392+ </list>
393+ <p>
394+ Multiple paragraphs:
395+ </p>
396+ <list list-type="order">
397+ <list-item>
398+ <p>
399+ Item 1, graf one.
400+ </p>
401+ <p>
402+ Item 1. graf two. The quick brown fox jumped over the lazy
403+ dog's back.
404+ </p>
405+ </list-item>
406+ <list-item>
407+ <p>
408+ Item 2.
409+ </p>
410+ </list-item>
411+ <list-item>
412+ <p>
413+ Item 3.
414+ </p>
415+ </list-item>
416+ </list>
417+ <p>
418+ List styles:
419+ </p>
420+ <list list-type="order"></list>
421+ <list list-type="roman-lower"></list>
422+ </sec>
423+ <sec id="nested">
424+ <title>Nested</title>
425+ <list list-type="bullet">
426+ <list-item>
427+ <p>
428+ Tab
429+ </p>
430+ <list list-type="bullet">
431+ <list-item>
432+ <p>
433+ Tab
434+ </p>
435+ <list list-type="bullet">
436+ <list-item>
437+ <p>
438+ Tab
439+ </p>
440+ </list-item>
441+ </list>
442+ </list-item>
443+ </list>
444+ </list-item>
445+ </list>
446+ <p>
447+ Here's another:
448+ </p>
449+ <list list-type="order">
450+ <list-item>
451+ <p>
452+ First
453+ </p>
454+ </list-item>
455+ <list-item>
456+ <p>
457+ Second:
458+ </p>
459+ <list list-type="bullet">
460+ <list-item>
461+ <p>
462+ Fee
463+ </p>
464+ </list-item>
465+ <list-item>
466+ <p>
467+ Fie
468+ </p>
469+ </list-item>
470+ <list-item>
471+ <p>
472+ Foe
473+ </p>
474+ </list-item>
475+ </list>
476+ </list-item>
477+ <list-item>
478+ <p>
479+ Third
480+ </p>
481+ </list-item>
482+ </list>
483+ <p>
484+ Same thing but with paragraphs:
485+ </p>
486+ <list list-type="order">
487+ <list-item>
488+ <p>
489+ First
490+ </p>
491+ </list-item>
492+ <list-item>
493+ <p>
494+ Second:
495+ </p>
496+ <list list-type="bullet">
497+ <list-item>
498+ <p>
499+ Fee
500+ </p>
501+ </list-item>
502+ <list-item>
503+ <p>
504+ Fie
505+ </p>
506+ </list-item>
507+ <list-item>
508+ <p>
509+ Foe
510+ </p>
511+ </list-item>
512+ </list>
513+ </list-item>
514+ <list-item>
515+ <p>
516+ Third
517+ </p>
518+ </list-item>
519+ </list>
520+ </sec>
521+ <sec id="tabs-and-spaces">
522+ <title>Tabs and spaces</title>
523+ <list list-type="bullet">
524+ <list-item>
525+ <p>
526+ this is a list item indented with tabs
527+ </p>
528+ </list-item>
529+ <list-item>
530+ <p>
531+ this is a list item indented with spaces
532+ </p>
533+ <list list-type="bullet">
534+ <list-item>
535+ <p>
536+ this is an example list item indented with tabs
537+ </p>
538+ </list-item>
539+ <list-item>
540+ <p>
541+ this is an example list item indented with spaces
542+ </p>
543+ </list-item>
544+ </list>
545+ </list-item>
546+ </list>
547+ </sec>
548+ <sec id="fancy-list-markers">
549+ <title>Fancy list markers</title>
550+ <p>
551+ Autonumbering:
552+ </p>
553+ <list list-type="order">
554+ <list-item>
555+ <p>
556+ Autonumber.
557+ </p>
558+ </list-item>
559+ <list-item>
560+ <p>
561+ More.
562+ </p>
563+ <list list-type="order">
564+ <list-item>
565+ <p>
566+ Nested.
567+ </p>
568+ </list-item>
569+ </list>
570+ </list-item>
571+ </list>
572+ </sec>
573+ <sec id="definition">
574+ <title>Definition</title>
575+ <def-list>
576+ <def-item>
577+ <term>
578+ Violin
579+ </term>
580+ <def>
581+ <p>
582+ Stringed musical instrument.
583+ </p>
584+ <p>
585+ Torture device.
586+ </p>
587+ </def>
588+ </def-item>
589+ <def-item>
590+ <term>
591+ Cello<break />Violoncello
592+ </term>
593+ <def>
594+ <p>
595+ Low-voiced stringed instrument.
596+ </p>
597+ </def>
598+ </def-item>
599+ </def-list>
600+ </sec>
601+</sec>
602+<sec id="inline-markup">
603+ <title>Inline Markup</title>
604+ <p>
605+ This is <italic>emphasized</italic>, and so <italic>is
606+ this</italic>.
607+ </p>
608+ <p>
609+ This is <bold role="strong">strong</bold>, and so
610+ <bold role="strong">is this</bold>.
611+ </p>
612+ <p>
613+ Empty <bold role="strong"></bold> and <italic></italic>.
614+ </p>
615+ <p>
616+ An
617+ <italic><ext-link ext-link-type="uri" xlink:href="/url">emphasized
618+ link</ext-link></italic>.
619+ </p>
620+ <p>
621+ <bold role="strong"><italic>This is strong and em.</italic></bold>
622+ </p>
623+ <p>
624+ So is <bold role="strong"><italic>this</italic></bold> word.
625+ </p>
626+ <p>
627+ <bold role="strong"><italic>This is strong and em.</italic></bold>
628+ </p>
629+ <p>
630+ So is <bold role="strong"><italic>this</italic></bold> word.
631+ </p>
632+ <p>
633+ This is code: <monospace>&gt;</monospace>, <monospace>$</monospace>,
634+ <monospace>\</monospace>, <monospace>\$</monospace>,
635+ <monospace>&lt;html&gt;</monospace>.
636+ </p>
637+ <p>
638+ This is <sc role="smallcaps">small caps</sc>.
639+ </p>
640+ <p>
641+ These are all underlined: foo and bar.
642+ </p>
643+ <p>
644+ These are all strikethrough: <strike>foo</strike>,
645+ <strike>bar</strike>, and <strike>baz</strike>.
646+ </p>
647+</sec>
648+<sec id="smart-quotes-ellipses-dashes">
649+ <title>Smart quotes, ellipses, dashes</title>
650+ <p>
651+ &quot;Hello,&quot; said the spider. &quot;'Shelob' is my name.&quot;
652+ </p>
653+ <p>
654+ 'A', 'B', and 'C' are letters.
655+ </p>
656+ <p>
657+ 'Oak,' 'elm,' and 'beech' are names of trees. So is 'pine.'
658+ </p>
659+ <p>
660+ 'He said, &quot;I want to go.&quot;' Were you alive in the 70's?
661+ </p>
662+ <p>
663+ Here is some quoted '<monospace>code</monospace>' and a
664+ &quot;<ext-link ext-link-type="uri" xlink:href="http://example.com/?foo=1&amp;bar=2">quoted
665+ link</ext-link>&quot;.
666+ </p>
667+ <p>
668+ Some dashes: one---two --- three--four -- five.
669+ </p>
670+ <p>
671+ Dashes between numbers: 5-7, 255-66, 1987-1999.
672+ </p>
673+ <p>
674+ Ellipses...and. . .and . . . .
675+ </p>
676+</sec>
677+<sec id="latex">
678+ <title>LaTeX</title>
679+ <list list-type="bullet">
680+ <list-item>
681+ <p>
682+ \cite[22-23]{smith.1899}
683+ </p>
684+ </list-item>
685+ <list-item>
686+ <p>
687+ \doublespacing
688+ </p>
689+ </list-item>
690+ <list-item>
691+ <p>
692+ $2+2=4$
693+ </p>
694+ </list-item>
695+ <list-item>
696+ <p>
697+ $x \in y$
698+ </p>
699+ </list-item>
700+ <list-item>
701+ <p>
702+ $\alpha \wedge \omega$
703+ </p>
704+ </list-item>
705+ <list-item>
706+ <p>
707+ $223$
708+ </p>
709+ </list-item>
710+ <list-item>
711+ <p>
712+ $p$-Tree
713+ </p>
714+ </list-item>
715+ <list-item>
716+ <p>
717+ $\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$
718+ </p>
719+ </list-item>
720+ <list-item>
721+ <p>
722+ Here's one that has a line break in it: $\alpha + \omega \times
723+ x^2$.
724+ </p>
725+ </list-item>
726+ </list>
727+ <p>
728+ These shouldn't be math:
729+ </p>
730+ <list list-type="bullet">
731+ <list-item>
732+ <p>
733+ To get the famous equation, write
734+ <monospace>$e = mc^2$</monospace>.
735+ </p>
736+ </list-item>
737+ <list-item>
738+ <p>
739+ $22,000 is a <italic>lot</italic> of money. So is $34,000. (It
740+ worked if &quot;lot&quot; is emphasized.)
741+ </p>
742+ </list-item>
743+ <list-item>
744+ <p>
745+ Escaped <monospace>$</monospace>: $73 <italic>this should be
746+ emphasized</italic> 23$.
747+ </p>
748+ </list-item>
749+ </list>
750+ <p>
751+ Here's a LaTeX table:
752+ </p>
753+ <p>
754+ \begin{tabular}{|l|l|}\hline Animal &amp; Number \\ \hline Dog &amp;
755+ 2 \\ Cat &amp; 1 \\ \hline \end{tabular}
756+ </p>
757+</sec>
758+<sec id="special-characters">
759+ <title>Special Characters</title>
760+ <p>
761+ Here is some unicode:
762+ </p>
763+ <list list-type="bullet">
764+ <list-item>
765+ <p>
766+ I hat: Î
767+ </p>
768+ </list-item>
769+ <list-item>
770+ <p>
771+ o umlaut: ö
772+ </p>
773+ </list-item>
774+ <list-item>
775+ <p>
776+ section: §
777+ </p>
778+ </list-item>
779+ <list-item>
780+ <p>
781+ set membership: elem
782+ </p>
783+ </list-item>
784+ <list-item>
785+ <p>
786+ copyright: ©
787+ </p>
788+ </list-item>
789+ </list>
790+ <p>
791+ AT&amp;T has an ampersand in their name.
792+ </p>
793+ <p>
794+ AT&amp;T is another way to write it.
795+ </p>
796+ <p>
797+ This &amp; that.
798+ </p>
799+ <p>
800+ 4 &lt; 5.
801+ </p>
802+ <p>
803+ 6 &gt; 5.
804+ </p>
805+ <p>
806+ Backslash: \
807+ </p>
808+ <p>
809+ Backtick: `
810+ </p>
811+ <p>
812+ Asterisk: *
813+ </p>
814+ <p>
815+ Underscore: _
816+ </p>
817+ <p>
818+ Left brace: {
819+ </p>
820+ <p>
821+ Right brace: }
822+ </p>
823+ <p>
824+ Left bracket: [
825+ </p>
826+ <p>
827+ Right bracket: ]
828+ </p>
829+ <p>
830+ Left paren: (
831+ </p>
832+ <p>
833+ Right paren: )
834+ </p>
835+ <p>
836+ Greater-than: &gt;
837+ </p>
838+ <p>
839+ Hash: #
840+ </p>
841+ <p>
842+ Period: .
843+ </p>
844+ <p>
845+ Bang: !
846+ </p>
847+ <p>
848+ Plus: +
849+ </p>
850+ <p>
851+ Minus: -
852+ </p>
853+</sec>
854+<sec id="links">
855+ <title>Links</title>
856+ <sec id="explicit">
857+ <title>Explicit</title>
858+ <p>
859+ Just a
860+ <ext-link ext-link-type="uri" xlink:href="/url/">URL</ext-link>.
861+ </p>
862+ <p>
863+ <ext-link ext-link-type="uri" xlink:href="/url/" xlink:title="title">URL
864+ and title</ext-link>.
865+ </p>
866+ <p>
867+ <ext-link ext-link-type="uri" xlink:href="/url/" xlink:title="title preceded by two spaces">URL
868+ and title</ext-link>.
869+ </p>
870+ <p>
871+ <ext-link ext-link-type="uri" xlink:href="/url/" xlink:title="title preceded by a tab">URL
872+ and title</ext-link>.
873+ </p>
874+ <p>
875+ <ext-link ext-link-type="uri" xlink:href="/url/" xlink:title="title with &quot;quotes&quot; in it">URL
876+ and title</ext-link>
877+ </p>
878+ <p>
879+ <ext-link ext-link-type="uri" xlink:href="/url/" xlink:title="title with single quotes">URL
880+ and title</ext-link>
881+ </p>
882+ <p>
883+ Email link (nobody [at] nowhere.net)
884+ </p>
885+ <p>
886+ <ext-link ext-link-type="uri" xlink:href="">Empty</ext-link>.
887+ </p>
888+ </sec>
889+ <sec id="reference">
890+ <title>Reference</title>
891+ <p>
892+ Foo
893+ <ext-link ext-link-type="uri" xlink:href="/url/">bar</ext-link>.
894+ </p>
895+ <p>
896+ Foo
897+ <ext-link ext-link-type="uri" xlink:href="/url/">bar</ext-link>.
898+ </p>
899+ <p>
900+ Foo
901+ <ext-link ext-link-type="uri" xlink:href="/url/">bar</ext-link>.
902+ </p>
903+ <p>
904+ With <ext-link ext-link-type="uri" xlink:href="/url/">embedded
905+ [brackets]</ext-link>.
906+ </p>
907+ <p>
908+ <ext-link ext-link-type="uri" xlink:href="/url/">b</ext-link> by
909+ itself should be a link.
910+ </p>
911+ <p>
912+ Indented
913+ <ext-link ext-link-type="uri" xlink:href="/url">once</ext-link>.
914+ </p>
915+ <p>
916+ Indented
917+ <ext-link ext-link-type="uri" xlink:href="/url">twice</ext-link>.
918+ </p>
919+ <p>
920+ Indented
921+ <ext-link ext-link-type="uri" xlink:href="/url">thrice</ext-link>.
922+ </p>
923+ <p>
924+ This should [not] be a link.
925+ </p>
926+ <preformat>[not]: /url</preformat>
927+ <p>
928+ Foo
929+ <ext-link ext-link-type="uri" xlink:href="/url/" xlink:title="Title with &quot;quotes&quot; inside">bar</ext-link>.
930+ </p>
931+ <p>
932+ Foo
933+ <ext-link ext-link-type="uri" xlink:href="/url/" xlink:title="Title with &quot;quote&quot; inside">biz</ext-link>.
934+ </p>
935+ </sec>
936+ <sec id="with-ampersands">
937+ <title>With ampersands</title>
938+ <p>
939+ Here's a
940+ <ext-link ext-link-type="uri" xlink:href="http://example.com/?foo=1&amp;bar=2">link
941+ with an ampersand in the URL</ext-link>.
942+ </p>
943+ <p>
944+ Here's a link with an amersand in the link text:
945+ <ext-link ext-link-type="uri" xlink:href="http://att.com/" xlink:title="AT&amp;T">AT&amp;T</ext-link>.
946+ </p>
947+ <p>
948+ Here's an
949+ <ext-link ext-link-type="uri" xlink:href="/script?foo=1&amp;bar=2">inline
950+ link</ext-link>.
951+ </p>
952+ <p>
953+ Here's an
954+ <ext-link ext-link-type="uri" xlink:href="/script?foo=1&amp;bar=2">inline
955+ link in pointy braces</ext-link>.
956+ </p>
957+ </sec>
958+ <sec id="autolinks">
959+ <title>Autolinks</title>
960+ <p>
961+ With an ampersand:
962+ <ext-link ext-link-type="uri" xlink:href="http://example.com/?foo=1&amp;bar=2">http://example.com/?foo=1&amp;bar=2</ext-link>
963+ </p>
964+ <list list-type="bullet">
965+ <list-item>
966+ <p>
967+ In a list?
968+ </p>
969+ </list-item>
970+ <list-item>
971+ <p>
972+ <ext-link ext-link-type="uri" xlink:href="http://example.com/">http://example.com/</ext-link>
973+ </p>
974+ </list-item>
975+ <list-item>
976+ <p>
977+ It should.
978+ </p>
979+ </list-item>
980+ </list>
981+ <p>
982+ An e-mail address: nobody [at] nowhere.net
983+ </p>
984+ <disp-quote>
985+ <p>
986+ Blockquoted:
987+ <ext-link ext-link-type="uri" xlink:href="http://example.com/">http://example.com/</ext-link>
988+ </p>
989+ </disp-quote>
990+ <p>
991+ Auto-links should not occur here:
992+ <monospace>&lt;http://example.com/&gt;</monospace>
993+ </p>
994+ <preformat>or here: &lt;http://example.com/&gt;</preformat>
995+ </sec>
996+</sec>
997+<sec id="images">
998+ <title>Images</title>
999+ <p>
1000+ From &quot;Voyage dans la Lune&quot; by Georges Melies (1902):
1001+ </p>
1002+ <p>
1003+ <inline-graphic mimetype="image" mime-subtype="jpeg" xlink:href="lalune.jpg" xlink:title="Voyage dans la Lune" />
1004+ </p>
1005+ <p>
1006+ Here is a movie
1007+ <inline-graphic mimetype="image" mime-subtype="jpeg" xlink:href="movie.jpg" />
1008+ icon.
1009+ </p>
1010+</sec>
1011+<sec id="footnotes">
1012+ <title>Footnotes</title>
1013+ <p>
1014+ Here is a footnote reference<xref alt="(1)" rid="note_1">(1)</xref>,
1015+ and
1016+ another<xref alt="(longnote)" rid="note_longnote">(longnote)</xref>.
1017+ This should <italic>not</italic> be a footnote reference, because it
1018+ contains a space^(my note).
1019+ </p>
1020+ <p>
1021+ <xref alt="(1)" rid="ref_1">(1)</xref> Here is the footnote. It can
1022+ go anywhere in the document, not just at the end.
1023+ </p>
1024+ <p>
1025+ <xref alt="(longnote)" rid="ref_longnote">(longnote)</xref> Here's
1026+ the other note. This one contains multiple blocks.
1027+ </p>
1028+ <p>
1029+ Caret characters are used to indicate that the blocks all belong to
1030+ a single footnote (as with block quotes).
1031+ </p>
1032+ <preformat> { &lt;code&gt; }</preformat>
1033+ <p>
1034+ If you want, you can use a caret at the beginning of every line, as
1035+ with blockquotes, but all that you need is a caret at the beginning
1036+ of the first line of the block and any preceding blank lines.
1037+ </p>
1038+ <p>
1039+ text <italic>Leading space</italic>
1040+ </p>
1041+ <p>
1042+ <italic>Trailing space</italic> text
1043+ </p>
1044+ <p>
1045+ text <italic>Leading spaces</italic>
1046+ </p>
1047+ <p>
1048+ <italic>Trailing spaces</italic> text
1049+ </p>
1050+</sec>
1051+<sec id="tables">
1052+ <title>Tables</title>
1053+ <sec id="tables-with-headers">
1054+ <title>Tables with Headers</title>
1055+ <table>
1056+ <col align="left" />
1057+ <col align="left" />
1058+ <col align="left" />
1059+ <thead>
1060+ <tr>
1061+ <th>
1062+ <p>
1063+ X
1064+ </p>
1065+ </th>
1066+ <th>
1067+ <p>
1068+ Y
1069+ </p>
1070+ </th>
1071+ <th>
1072+ <p>
1073+ Z
1074+ </p>
1075+ </th>
1076+ </tr>
1077+ </thead>
1078+ <tbody>
1079+ <tr>
1080+ <td>
1081+ <p>
1082+ 1
1083+ </p>
1084+ </td>
1085+ <td>
1086+ <p>
1087+ 2
1088+ </p>
1089+ </td>
1090+ <td>
1091+ <p>
1092+ 3
1093+ </p>
1094+ </td>
1095+ </tr>
1096+ <tr>
1097+ <td>
1098+ <p>
1099+ 4
1100+ </p>
1101+ </td>
1102+ <td>
1103+ <p>
1104+ 5
1105+ </p>
1106+ </td>
1107+ <td>
1108+ <p>
1109+ 6
1110+ </p>
1111+ </td>
1112+ </tr>
1113+ </tbody>
1114+ </table>
1115+ <table>
1116+ <col align="left" />
1117+ <col align="left" />
1118+ <col align="left" />
1119+ <thead>
1120+ <tr>
1121+ <th>
1122+ <p>
1123+ X
1124+ </p>
1125+ </th>
1126+ <th>
1127+ <p>
1128+ Y
1129+ </p>
1130+ </th>
1131+ <th>
1132+ <p>
1133+ Z
1134+ </p>
1135+ </th>
1136+ </tr>
1137+ </thead>
1138+ <tbody>
1139+ <tr>
1140+ <td>
1141+ <p>
1142+ 1
1143+ </p>
1144+ </td>
1145+ <td>
1146+ <p>
1147+ 2
1148+ </p>
1149+ </td>
1150+ <td>
1151+ <p>
1152+ 3
1153+ </p>
1154+ </td>
1155+ </tr>
1156+ <tr>
1157+ <td>
1158+ <p>
1159+ 4
1160+ </p>
1161+ </td>
1162+ <td>
1163+ <p>
1164+ 5
1165+ </p>
1166+ </td>
1167+ <td>
1168+ <p>
1169+ 6
1170+ </p>
1171+ </td>
1172+ </tr>
1173+ </tbody>
1174+ </table>
1175+ <table>
1176+ <col align="left" />
1177+ <col align="left" />
1178+ <col align="left" />
1179+ <thead>
1180+ <tr>
1181+ <th>
1182+ <p>
1183+ X
1184+ </p>
1185+ </th>
1186+ <th>
1187+ <p>
1188+ Y
1189+ </p>
1190+ </th>
1191+ <th>
1192+ <p>
1193+ Z
1194+ </p>
1195+ </th>
1196+ </tr>
1197+ </thead>
1198+ <tbody>
1199+ <tr>
1200+ <td>
1201+ <p>
1202+ 1
1203+ </p>
1204+ </td>
1205+ <td>
1206+ <p>
1207+ 2
1208+ </p>
1209+ </td>
1210+ <td>
1211+ <p>
1212+ 3
1213+ </p>
1214+ </td>
1215+ </tr>
1216+ <tr>
1217+ <td>
1218+ <p>
1219+ 4
1220+ </p>
1221+ </td>
1222+ <td>
1223+ <p>
1224+ 5
1225+ </p>
1226+ </td>
1227+ <td>
1228+ <p>
1229+ 6
1230+ </p>
1231+ </td>
1232+ </tr>
1233+ </tbody>
1234+ </table>
1235+ <table>
1236+ <col align="left" />
1237+ <col align="left" />
1238+ <col align="left" />
1239+ <thead>
1240+ <tr>
1241+ <th>
1242+ <p>
1243+ X
1244+ </p>
1245+ </th>
1246+ <th>
1247+ <p>
1248+ Y
1249+ </p>
1250+ </th>
1251+ <th>
1252+ <p>
1253+ Z
1254+ </p>
1255+ </th>
1256+ </tr>
1257+ </thead>
1258+ <tbody>
1259+ <tr>
1260+ <td>
1261+ <p>
1262+ 1
1263+ </p>
1264+ </td>
1265+ <td>
1266+ <p>
1267+ 2
1268+ </p>
1269+ </td>
1270+ <td>
1271+ <p>
1272+ 3
1273+ </p>
1274+ </td>
1275+ </tr>
1276+ <tr>
1277+ <td>
1278+ <p>
1279+ 4
1280+ </p>
1281+ </td>
1282+ <td>
1283+ <p>
1284+ 5
1285+ </p>
1286+ </td>
1287+ <td>
1288+ <p>
1289+ 6
1290+ </p>
1291+ </td>
1292+ </tr>
1293+ </tbody>
1294+ </table>
1295+ <table>
1296+ <col align="left" />
1297+ <col align="left" />
1298+ <col align="left" />
1299+ <thead>
1300+ <tr>
1301+ <th>
1302+ <p>
1303+ X
1304+ </p>
1305+ </th>
1306+ <th>
1307+ <p>
1308+ Y
1309+ </p>
1310+ </th>
1311+ <th>
1312+ <p>
1313+ Z
1314+ </p>
1315+ </th>
1316+ </tr>
1317+ </thead>
1318+ <tbody>
1319+ <tr>
1320+ <td>
1321+ <p>
1322+ 1
1323+ </p>
1324+ </td>
1325+ <td>
1326+ <p>
1327+ 2
1328+ </p>
1329+ </td>
1330+ <td>
1331+ <p>
1332+ 3
1333+ </p>
1334+ </td>
1335+ </tr>
1336+ <tr>
1337+ <td>
1338+ <p>
1339+ 4
1340+ </p>
1341+ </td>
1342+ <td>
1343+ <p>
1344+ 5
1345+ </p>
1346+ </td>
1347+ <td>
1348+ <p>
1349+ 6
1350+ </p>
1351+ </td>
1352+ </tr>
1353+ </tbody>
1354+ </table>
1355+ <table>
1356+ <col align="left" />
1357+ <col align="left" />
1358+ <col align="left" />
1359+ <thead>
1360+ <tr>
1361+ <th>
1362+ <p>
1363+ X
1364+ </p>
1365+ </th>
1366+ <th>
1367+ <p>
1368+ Y
1369+ </p>
1370+ </th>
1371+ <th>
1372+ <p>
1373+ Z
1374+ </p>
1375+ </th>
1376+ </tr>
1377+ </thead>
1378+ <tbody>
1379+ <tr>
1380+ <td>
1381+ <p>
1382+ 1
1383+ </p>
1384+ </td>
1385+ <td>
1386+ <p>
1387+ 2
1388+ </p>
1389+ </td>
1390+ <td>
1391+ <p>
1392+ 3
1393+ </p>
1394+ </td>
1395+ </tr>
1396+ <tr>
1397+ <td>
1398+ <p>
1399+ 4
1400+ </p>
1401+ </td>
1402+ <td>
1403+ <p>
1404+ 5
1405+ </p>
1406+ </td>
1407+ <td>
1408+ <p>
1409+ 6
1410+ </p>
1411+ </td>
1412+ </tr>
1413+ </tbody>
1414+ </table>
1415+ <table>
1416+ <col align="left" />
1417+ <col align="left" />
1418+ <col align="left" />
1419+ <thead>
1420+ <tr>
1421+ <th>
1422+ <p>
1423+ X
1424+ </p>
1425+ </th>
1426+ <th>
1427+ <p>
1428+ Y
1429+ </p>
1430+ </th>
1431+ <th>
1432+ <p>
1433+ Z
1434+ </p>
1435+ </th>
1436+ </tr>
1437+ </thead>
1438+ <tbody>
1439+ <tr>
1440+ <td>
1441+ <p>
1442+ 1
1443+ </p>
1444+ </td>
1445+ <td>
1446+ <p>
1447+ 2
1448+ </p>
1449+ </td>
1450+ <td>
1451+ <p>
1452+ 3
1453+ </p>
1454+ </td>
1455+ </tr>
1456+ <tr>
1457+ <td>
1458+ <p>
1459+ 4
1460+ </p>
1461+ </td>
1462+ <td>
1463+ <p>
1464+ 5
1465+ </p>
1466+ </td>
1467+ <td>
1468+ <p>
1469+ 6
1470+ </p>
1471+ </td>
1472+ </tr>
1473+ </tbody>
1474+ </table>
1475+ <table>
1476+ <col align="left" />
1477+ <col align="left" />
1478+ <col align="left" />
1479+ <thead>
1480+ <tr>
1481+ <th>
1482+ <p>
1483+ X
1484+ </p>
1485+ </th>
1486+ <th>
1487+ <p>
1488+ Y
1489+ </p>
1490+ </th>
1491+ <th>
1492+ <p>
1493+ Z
1494+ </p>
1495+ </th>
1496+ </tr>
1497+ </thead>
1498+ <tbody>
1499+ <tr>
1500+ <td>
1501+ <p>
1502+ 1
1503+ </p>
1504+ </td>
1505+ <td>
1506+ <p>
1507+ 2
1508+ </p>
1509+ </td>
1510+ <td>
1511+ <p>
1512+ 3
1513+ </p>
1514+ </td>
1515+ </tr>
1516+ <tr>
1517+ <td>
1518+ <p>
1519+ 4
1520+ </p>
1521+ </td>
1522+ <td>
1523+ <p>
1524+ 5
1525+ </p>
1526+ </td>
1527+ <td>
1528+ <p>
1529+ 6
1530+ </p>
1531+ </td>
1532+ </tr>
1533+ </tbody>
1534+ </table>
1535+ <table>
1536+ <col width="33*" align="left" />
1537+ <col width="33*" align="left" />
1538+ <col width="33*" align="left" />
1539+ <thead>
1540+ <tr>
1541+ <th>
1542+ <p>
1543+ X
1544+ </p>
1545+ </th>
1546+ <th>
1547+ <p>
1548+ Y
1549+ </p>
1550+ </th>
1551+ <th>
1552+ <p>
1553+ Z
1554+ </p>
1555+ </th>
1556+ </tr>
1557+ </thead>
1558+ <tbody>
1559+ <tr>
1560+ <td>
1561+ <p>
1562+ 1
1563+ </p>
1564+ </td>
1565+ <td>
1566+ <p>
1567+ 2
1568+ </p>
1569+ </td>
1570+ <td>
1571+ <p>
1572+ 3
1573+ </p>
1574+ </td>
1575+ </tr>
1576+ <tr>
1577+ <td>
1578+ <p>
1579+ 4
1580+ </p>
1581+ </td>
1582+ <td>
1583+ <p>
1584+ 5
1585+ </p>
1586+ </td>
1587+ <td>
1588+ <p>
1589+ 6
1590+ </p>
1591+ </td>
1592+ </tr>
1593+ </tbody>
1594+ </table>
1595+ </sec>
1596+ <sec id="tables-without-headers">
1597+ <title>Tables without Headers</title>
1598+ <table>
1599+ <col align="left" />
1600+ <col align="left" />
1601+ <col align="left" />
1602+ <tbody>
1603+ <tr>
1604+ <td>
1605+ <p>
1606+ 1
1607+ </p>
1608+ </td>
1609+ <td>
1610+ <p>
1611+ 2
1612+ </p>
1613+ </td>
1614+ <td>
1615+ <p>
1616+ 3
1617+ </p>
1618+ </td>
1619+ </tr>
1620+ <tr>
1621+ <td>
1622+ <p>
1623+ 4
1624+ </p>
1625+ </td>
1626+ <td>
1627+ <p>
1628+ 5
1629+ </p>
1630+ </td>
1631+ <td>
1632+ <p>
1633+ 6
1634+ </p>
1635+ </td>
1636+ </tr>
1637+ </tbody>
1638+ </table>
1639+ <table>
1640+ <col align="left" />
1641+ <col align="left" />
1642+ <col align="left" />
1643+ <tbody>
1644+ <tr>
1645+ <td>
1646+ <p>
1647+ 1
1648+ </p>
1649+ </td>
1650+ <td>
1651+ <p>
1652+ 2
1653+ </p>
1654+ </td>
1655+ <td>
1656+ <p>
1657+ 3
1658+ </p>
1659+ </td>
1660+ </tr>
1661+ <tr>
1662+ <td>
1663+ <p>
1664+ 4
1665+ </p>
1666+ </td>
1667+ <td>
1668+ <p>
1669+ 5
1670+ </p>
1671+ </td>
1672+ <td>
1673+ <p>
1674+ 6
1675+ </p>
1676+ </td>
1677+ </tr>
1678+ </tbody>
1679+ </table>
1680+ <table>
1681+ <col align="left" />
1682+ <col align="left" />
1683+ <col align="left" />
1684+ <tbody>
1685+ <tr>
1686+ <td>
1687+ <p>
1688+ 1
1689+ </p>
1690+ </td>
1691+ <td>
1692+ <p>
1693+ 2
1694+ </p>
1695+ </td>
1696+ <td>
1697+ <p>
1698+ 3
1699+ </p>
1700+ </td>
1701+ </tr>
1702+ <tr>
1703+ <td>
1704+ <p>
1705+ 4
1706+ </p>
1707+ </td>
1708+ <td>
1709+ <p>
1710+ 5
1711+ </p>
1712+ </td>
1713+ <td>
1714+ <p>
1715+ 6
1716+ </p>
1717+ </td>
1718+ </tr>
1719+ </tbody>
1720+ </table>
1721+ <table>
1722+ <col align="left" />
1723+ <col align="left" />
1724+ <col align="left" />
1725+ <tbody>
1726+ <tr>
1727+ <td>
1728+ <p>
1729+ 1
1730+ </p>
1731+ </td>
1732+ <td>
1733+ <p>
1734+ 2
1735+ </p>
1736+ </td>
1737+ <td>
1738+ <p>
1739+ 3
1740+ </p>
1741+ </td>
1742+ </tr>
1743+ <tr>
1744+ <td>
1745+ <p>
1746+ 4
1747+ </p>
1748+ </td>
1749+ <td>
1750+ <p>
1751+ 5
1752+ </p>
1753+ </td>
1754+ <td>
1755+ <p>
1756+ 6
1757+ </p>
1758+ </td>
1759+ </tr>
1760+ </tbody>
1761+ </table>
1762+ </sec>
1763+ <sec id="empty-tables">
1764+ <title>Empty Tables</title>
1765+ <p>
1766+ This section should be empty.
1767+ </p>
1768+ </sec>
1769+</sec>
1770+</body>
1771+<back>
1772+</back>
1773+</article>
test/test-pandoc.hs+2
@@ -11,6 +11,7 @@ import qualified Tests.Readers.Creole
1111import qualified Tests.Readers.Docx
1212import qualified Tests.Readers.EPUB
1313import qualified Tests.Readers.HTML
14+import qualified Tests.Readers.JATS
1415import qualified Tests.Readers.LaTeX
1516import qualified Tests.Readers.Markdown
1617import qualified Tests.Readers.Muse
@@ -61,6 +62,7 @@ tests = testGroup "pandoc tests" [ Tests.Command.tests
6162 [ testGroup "LaTeX" Tests.Readers.LaTeX.tests
6263 , testGroup "Markdown" Tests.Readers.Markdown.tests
6364 , testGroup "HTML" Tests.Readers.HTML.tests
65+ , testGroup "JATS" Tests.Readers.JATS.tests
6466 , testGroup "Org" Tests.Readers.Org.tests
6567 , testGroup "RST" Tests.Readers.RST.tests
6668 , testGroup "Docx" Tests.Readers.Docx.tests