git.iko.soy/typeable/pandoc
on master help sign in
Committed novalazy's initial patch for texinfo output,

including tests for texinfo writer. git-svn-id: https://pandoc.googlecode.com/svn/trunk@1243 788f1e2b-df1e-0410-8736-df70ead52e1b

commit49e0e507b72c51da39882f37e405747101213353 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateSun 24 Feb 2008, 05:48 (19 years ago) parent270eb7b
7 files changed+1541−1
Main.hs+1 Text/Pandoc.hs+2 Text/Pandoc/Writers/Texinfo.hs+461 tests/generate.sh+1 tests/runtests.pl+1−1 tests/tables.texinfo+124 tests/writer.texinfo+951
Main.hs+1
@@ -83,6 +83,7 @@ writers = [("native" , (writeDoc, ""))
8383 ,("docbook" , (writeDocbook, defaultDocbookHeader))
8484 ,("latex" , (writeLaTeX, defaultLaTeXHeader))
8585 ,("context" , (writeConTeXt, defaultConTeXtHeader))
86+ ,("texinfo" , (writeTexinfo, ""))
8687 ,("man" , (writeMan, ""))
8788 ,("markdown" , (writeMarkdown, ""))
8889 ,("rst" , (writeRST, ""))
Text/Pandoc.hs+2
@@ -68,6 +68,7 @@ module Text.Pandoc
6868 , writeRST
6969 , writeLaTeX
7070 , writeConTeXt
71+ , writeTexinfo
7172 , writeHtml
7273 , writeHtmlString
7374 , writeS5
@@ -96,6 +97,7 @@ import Text.Pandoc.Writers.Markdown
9697import Text.Pandoc.Writers.RST
9798import Text.Pandoc.Writers.LaTeX
9899import Text.Pandoc.Writers.ConTeXt
100+import Text.Pandoc.Writers.Texinfo
99101import Text.Pandoc.Writers.HTML
100102import Text.Pandoc.Writers.S5
101103import Text.Pandoc.Writers.Docbook
Text/Pandoc/Writers/Texinfo.hsnew file+461
@@ -0,0 +1,461 @@
1+{-
2+Copyright (C) 2008 John MacFarlane and Peter Wang
3+
4+This program is free software; you can redistribute it and/or modify
5+it under the terms of the GNU General Public License as published by
6+the Free Software Foundation; either version 2 of the License, or
7+(at your option) any later version.
8+
9+This program is distributed in the hope that it will be useful,
10+but WITHOUT ANY WARRANTY; without even the implied warranty of
11+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+GNU General Public License for more details.
13+
14+You should have received a copy of the GNU General Public License
15+along with this program; if not, write to the Free Software
16+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17+-}
18+
19+{- |
20+ Module : Text.Pandoc.Writers.Texinfo
21+ Copyright : Copyright (C) 2008 John MacFarlane and Peter Wang
22+ License : GNU GPL, version 2 or above
23+
24+ Maintainer : John MacFarlane <jgm@berkeley.edu>
25+ Stability : alpha
26+ Portability : portable
27+
28+Conversion of 'Pandoc' format into Texinfo.
29+-}
30+module Text.Pandoc.Writers.Texinfo ( writeTexinfo ) where
31+import Text.Pandoc.Definition
32+import Text.Pandoc.Shared
33+import Text.Printf ( printf )
34+import Data.List ( (\\), isSuffixOf )
35+import Data.Char ( toLower, chr, ord )
36+import qualified Data.Set as S
37+import Control.Monad.State
38+import Text.PrettyPrint.HughesPJ hiding ( Str )
39+
40+data WriterState =
41+ WriterState { stIncludes :: S.Set String -- strings to include in header
42+ }
43+
44+{- TODO:
45+ - internal cross references a la HTML
46+ - generated .texi files don't work when run through texi2dvi
47+ -}
48+
49+-- | Add line to header.
50+addToHeader :: String -> State WriterState ()
51+addToHeader str = do
52+ st <- get
53+ let includes = stIncludes st
54+ put st {stIncludes = S.insert str includes}
55+
56+-- | Convert Pandoc to Texinfo.
57+writeTexinfo :: WriterOptions -> Pandoc -> String
58+writeTexinfo options document =
59+ render $ evalState (pandocToTexinfo options $ wrapTop document) $
60+ WriterState { stIncludes = S.empty }
61+
62+-- | Add a "Top" node around the document, needed by Texinfo.
63+wrapTop (Pandoc (Meta title authors date) blocks) =
64+ Pandoc (Meta title authors date) (Header 0 title : blocks)
65+
66+pandocToTexinfo :: WriterOptions -> Pandoc -> State WriterState Doc
67+pandocToTexinfo options (Pandoc meta blocks) = do
68+ main <- blockListToTexinfo blocks
69+ head <- if writerStandalone options
70+ then texinfoHeader options meta
71+ else return empty
72+ let before = if null (writerIncludeBefore options)
73+ then empty
74+ else text (writerIncludeBefore options)
75+ let after = if null (writerIncludeAfter options)
76+ then empty
77+ else text (writerIncludeAfter options)
78+ let body = before $$ main $$ after
79+ -- XXX toc untested
80+ let toc = if writerTableOfContents options
81+ then text "@contents"
82+ else empty
83+ let foot = if writerStandalone options
84+ then text "@bye"
85+ else empty
86+ return $ head $$ toc $$ body $$ foot
87+
88+-- | Insert bibliographic information into Texinfo header.
89+texinfoHeader :: WriterOptions -- ^ Options, including Texinfo header
90+ -> Meta -- ^ Meta with bibliographic information
91+ -> State WriterState Doc
92+texinfoHeader options (Meta title authors date) = do
93+ titletext <- if null title
94+ then return empty
95+ else do
96+ t <- inlineListToTexinfo title
97+ return $ text "@title " <> t
98+ headerIncludes <- get >>= return . S.toList . stIncludes
99+ let extras = text $ unlines headerIncludes
100+ let authorstext = map makeAuthor authors
101+ let datetext = if date == ""
102+ then empty
103+ else text $ stringToTexinfo date
104+
105+ let baseHeader = text $ writerHeader options
106+ let header = baseHeader $$ extras
107+ return $ text "\\input texinfo" $$
108+ header $$
109+ text "@ifnottex" $$
110+ text "@paragraphindent 0" $$
111+ text "@end ifnottex" $$
112+ text "@titlepage" $$
113+ titletext $$ vcat authorstext $$
114+ datetext $$
115+ text "@end titlepage"
116+
117+makeAuthor author = text $ "@author " ++ (stringToTexinfo author)
118+
119+-- | Escape things as needed for Texinfo.
120+stringToTexinfo :: String -> String
121+stringToTexinfo = escapeStringUsing texinfoEscapes
122+ where texinfoEscapes = [ ('{', "@{")
123+ , ('}', "@}")
124+ , ('@', "@@")
125+ , (',', "@comma{}") -- only needed in argument lists
126+ ]
127+
128+-- | Puts contents into Texinfo command.
129+inCmd :: String -> Doc -> Doc
130+inCmd cmd contents = char '@' <> text cmd <> braces contents
131+
132+-- | Remove all code elements from list of inline elements
133+-- (because it's illegal to have verbatim inside some command arguments)
134+-- XXX not sure about this
135+deVerb :: [Inline] -> [Inline]
136+deVerb [] = []
137+deVerb ((Code str):rest) = (Code $ stringToTexinfo str):(deVerb rest)
138+deVerb (other:rest) = other:(deVerb rest)
139+
140+-- | Convert Pandoc block element to Texinfo.
141+blockToTexinfo :: Block -- ^ Block to convert
142+ -> State WriterState Doc
143+
144+blockToTexinfo Null = return empty
145+
146+blockToTexinfo (Plain lst) =
147+ inlineListToTexinfo lst
148+
149+blockToTexinfo (Para lst) = do
150+ result <- inlineListToTexinfo lst
151+ return $ result <> char '\n'
152+
153+blockToTexinfo (BlockQuote lst) = do
154+ contents <- blockListToTexinfo lst
155+ return $ text "@quotation" $$
156+ contents $$
157+ text "@end quotation"
158+
159+blockToTexinfo (CodeBlock _ str) = do
160+ -- XXX a paragraph followed by verbatim looks better if there is no blank
161+ -- line between the paragraph and verbatim, otherwise there is extra blank
162+ -- line in makeinfo output.
163+ return $ text "@verbatim" $$
164+ vcat (map text (lines str)) $$
165+ text "@end verbatim\n"
166+
167+blockToTexinfo (RawHtml str) = return empty
168+
169+blockToTexinfo (BulletList lst) = do
170+ items <- mapM listItemToTexinfo lst
171+ return $ text "@itemize" $$
172+ vcat items $$
173+ text "@end itemize\n"
174+
175+blockToTexinfo (OrderedList (start, numstyle, numdelim) lst) = do
176+ items <- mapM listItemToTexinfo lst
177+ return $ text "@enumerate " <> exemplar $$
178+ vcat items $$
179+ text "@end enumerate"
180+ where
181+ exemplar = case numstyle of
182+ DefaultStyle -> decimal
183+ Decimal -> decimal
184+ UpperRoman -> decimal -- Roman numerals not supported
185+ LowerRoman -> decimal
186+ UpperAlpha -> upperAlpha
187+ LowerAlpha -> lowerAlpha
188+ decimal = if start == 1
189+ then empty
190+ else text (show start)
191+ upperAlpha = text [chr $ ord 'A' + start - 1]
192+ lowerAlpha = text [chr $ ord 'a' + start - 1]
193+
194+blockToTexinfo (DefinitionList lst) = do
195+ items <- mapM defListItemToTexinfo lst
196+ return $ text "@table @asis" $$
197+ vcat items $$
198+ text "@end table"
199+
200+blockToTexinfo HorizontalRule =
201+ -- XXX can't get the equivalent from LaTeX.hs to work
202+ return $ text "@iftex" $$
203+ text "@bigskip@hrule@bigskip" $$
204+ text "@end iftex" $$
205+ text "@ifnottex" $$
206+ text (take 72 $ repeat '-') $$
207+ text "@end ifnottex"
208+
209+blockToTexinfo (Header 0 lst) = do
210+ txt <- if null lst
211+ then return $ text "Top"
212+ else inlineListToTexinfo (deVerb lst)
213+ return $ text "@node Top" $$
214+ text "@top " <> txt <> char '\n'
215+
216+blockToTexinfo (Header level lst) = do
217+ node <- inlineListForNode (deVerb lst)
218+ txt <- inlineListToTexinfo (deVerb lst)
219+ return $ if (level > 0) && (level <= 4)
220+ then text "\n@node " <> node <> char '\n' <>
221+ text (seccmd level) <> txt
222+ else txt
223+ where
224+ seccmd 1 = "@chapter "
225+ seccmd 2 = "@section "
226+ seccmd 3 = "@subsection "
227+ seccmd 4 = "@subsubsection "
228+
229+blockToTexinfo (Table caption aligns widths heads rows) = do
230+ headers <- tableHeadToTexinfo aligns heads
231+ captionText <- inlineListToTexinfo (deVerb caption)
232+ rowsText <- mapM (tableRowToTexinfo aligns) rows
233+ let colWidths = map (printf "%.2f ") widths
234+ let colDescriptors = concat colWidths
235+ let tableBody = text ("@multitable @columnfractions " ++ colDescriptors) $$
236+ headers $$
237+ vcat rowsText $$
238+ text "@end multitable"
239+ return $ if isEmpty captionText
240+ then tableBody <> char '\n'
241+ else text "@float" $$
242+ tableBody $$
243+ inCmd "caption" captionText $$
244+ text "@end float"
245+
246+tableHeadToTexinfo = tableAnyRowToTexinfo "@headitem "
247+
248+tableRowToTexinfo = tableAnyRowToTexinfo "@item "
249+
250+tableAnyRowToTexinfo :: String
251+ -> [Alignment]
252+ -> [[Block]]
253+ -> State WriterState Doc
254+tableAnyRowToTexinfo itemtype aligns cols =
255+ zipWithM alignedBlock aligns cols >>=
256+ return . (text itemtype $$) . foldl (\row item -> row $$
257+ (if isEmpty row then empty else text " @tab ") <> item) empty
258+
259+alignedBlock :: Alignment
260+ -> [Block]
261+ -> State WriterState Doc
262+-- XXX @flushleft and @flushright text won't get word wrapped. Since word
263+-- wrapping is more important than alignment, we ignore the alignment.
264+alignedBlock _ = blockListToTexinfo
265+{-
266+alignedBlock AlignLeft col = do
267+ b <- blockListToTexinfo col
268+ return $ text "@flushleft" $$ b $$ text "@end flushleft"
269+alignedBlock AlignRight col = do
270+ b <- blockListToTexinfo col
271+ return $ text "@flushright" $$ b $$ text "@end flushright"
272+alignedBlock _ col = blockListToTexinfo col
273+-}
274+
275+-- | Convert Pandoc block elements to Texinfo.
276+blockListToTexinfo :: [Block]
277+ -> State WriterState Doc
278+blockListToTexinfo [] = return $ empty
279+blockListToTexinfo (x:xs) = do
280+ x' <- blockToTexinfo x
281+ case x of
282+ (Header level _) -> do
283+ -- We need need to insert a menu for this node.
284+ let (before, after) = break isHeader xs
285+ before' <- blockListToTexinfo before
286+ let menu = if level < 4
287+ then collectNodes (level + 1) after
288+ else []
289+ lines <- mapM makeMenuLine menu
290+ let menu' = if null lines
291+ then empty
292+ else text "@menu" $$
293+ vcat lines $$
294+ text "@end menu"
295+ after' <- blockListToTexinfo after
296+ return $ x' $$ before' $$ menu' $$ after'
297+ _ -> do
298+ xs' <- blockListToTexinfo xs
299+ return $ x' $$ xs'
300+
301+isHeader (Header _ _) = True
302+isHeader _ = False
303+
304+collectNodes level [] = []
305+collectNodes level (x:xs) =
306+ case x of
307+ (Header hl _) ->
308+ if hl < level
309+ then []
310+ else if hl == level
311+ then x : collectNodes level xs
312+ else collectNodes level xs
313+ _ ->
314+ collectNodes level xs
315+
316+makeMenuLine :: Block
317+ -> State WriterState Doc
318+makeMenuLine (Header _ lst) = do
319+ txt <- inlineListForNode (deVerb lst)
320+ return $ text "* " <> txt <> text "::"
321+
322+listItemToTexinfo :: [Block]
323+ -> State WriterState Doc
324+listItemToTexinfo lst = blockListToTexinfo lst >>=
325+ return . (text "@item" $$)
326+
327+defListItemToTexinfo :: ([Inline], [Block])
328+ -> State WriterState Doc
329+defListItemToTexinfo (term, def) = do
330+ term' <- inlineListToTexinfo $ deVerb term
331+ def' <- blockListToTexinfo def
332+ return $ text "@item " <> term' <> text "\n" $$ def'
333+
334+-- | Convert list of inline elements to Texinfo.
335+inlineListToTexinfo :: [Inline] -- ^ Inlines to convert
336+ -> State WriterState Doc
337+inlineListToTexinfo lst = mapM inlineToTexinfo lst >>= return . hcat
338+
339+-- | Convert list of inline elements to Texinfo acceptable for a node name.
340+inlineListForNode :: [Inline] -- ^ Inlines to convert
341+ -> State WriterState Doc
342+inlineListForNode lst = mapM inlineForNode lst >>= return . hcat
343+
344+inlineForNode (Str str) = return $ text $ filter (not.disallowedInNode) str
345+inlineForNode (Emph lst) = inlineListForNode (deVerb lst)
346+inlineForNode (Strong lst) = inlineListForNode (deVerb lst)
347+inlineForNode (Strikeout lst) = inlineListForNode (deVerb lst)
348+inlineForNode (Superscript lst) = inlineListForNode (deVerb lst)
349+inlineForNode (Subscript lst) = inlineListForNode (deVerb lst)
350+inlineForNode (Quoted _ lst) = inlineListForNode (deVerb lst)
351+inlineForNode (Code str) = inlineForNode (Str str)
352+inlineForNode Space = return $ char ' '
353+inlineForNode EmDash = return $ text "---"
354+inlineForNode EnDash = return $ text "--"
355+inlineForNode Apostrophe = return $ char '\''
356+inlineForNode Ellipses = return $ text "..."
357+inlineForNode LineBreak = return empty
358+inlineForNode (Math _) = return empty
359+inlineForNode (TeX _) = return empty
360+inlineForNode (HtmlInline _) = return empty
361+inlineForNode (Link lst _) = inlineListForNode (deVerb lst)
362+inlineForNode (Image lst _) = inlineListForNode (deVerb lst)
363+inlineForNode (Note _) = return empty
364+
365+-- XXX not sure what the complete set of illegal characters is.
366+disallowedInNode '.' = True
367+disallowedInNode ',' = True
368+disallowedInNode _ = False
369+
370+-- | Convert inline element to Texinfo
371+inlineToTexinfo :: Inline -- ^ Inline to convert
372+ -> State WriterState Doc
373+
374+inlineToTexinfo (Emph lst) =
375+ inlineListToTexinfo (deVerb lst) >>= return . inCmd "emph"
376+
377+inlineToTexinfo (Strong lst) =
378+ inlineListToTexinfo (deVerb lst) >>= return . inCmd "strong"
379+
380+inlineToTexinfo (Strikeout lst) = do
381+ addToHeader $ "@macro textstrikeout{text}\n" ++
382+ "~~\\text\\~~\n" ++
383+ "@end macro\n"
384+ contents <- inlineListToTexinfo $ deVerb lst
385+ return $ text "@textstrikeout{" <> contents <> text "}"
386+
387+inlineToTexinfo (Superscript lst) = do
388+ addToHeader $ "@macro textsuperscript{text}\n" ++
389+ "@iftex\n" ++
390+ "@textsuperscript{\\text\\}\n" ++
391+ "@end iftex\n" ++
392+ "@ifnottex\n" ++
393+ "^@{\\text\\@}\n" ++
394+ "@end ifnottex\n" ++
395+ "@end macro\n"
396+ contents <- inlineListToTexinfo $ deVerb lst
397+ return $ text "@textsuperscript{" <> contents <> char '}'
398+
399+inlineToTexinfo (Subscript lst) = do
400+ addToHeader $ "@macro textsubscript{text}\n" ++
401+ "@iftex\n" ++
402+ "@textsubscript{\\text\\}\n" ++
403+ "@end iftex\n" ++
404+ "@ifnottex\n" ++
405+ "_@{\\text\\@}\n" ++
406+ "@end ifnottex\n" ++
407+ "@end macro\n"
408+ contents <- inlineListToTexinfo $ deVerb lst
409+ return $ text "@textsubscript{" <> contents <> char '}'
410+
411+inlineToTexinfo (Code str) = do
412+ let chr = ((enumFromTo '!' '~') \\ str) !! 0
413+ return $ text $ "@verb{" ++ [chr] ++ str ++ [chr] ++ "}"
414+
415+inlineToTexinfo (Quoted SingleQuote lst) = do
416+ contents <- inlineListToTexinfo lst
417+ return $ char '`' <> contents <> char '\''
418+
419+inlineToTexinfo (Quoted DoubleQuote lst) = do
420+ contents <- inlineListToTexinfo lst
421+ return $ text "``" <> contents <> text "''"
422+
423+inlineToTexinfo Apostrophe = return $ char '\''
424+inlineToTexinfo EmDash = return $ text "---"
425+inlineToTexinfo EnDash = return $ text "--"
426+inlineToTexinfo Ellipses = return $ text "@dots{}"
427+inlineToTexinfo (Str str) = return $ text (stringToTexinfo str)
428+inlineToTexinfo (Math str) = return $ inCmd "math" $ text str
429+inlineToTexinfo (TeX str) = return $ text "@tex" $$ text str $$ text "@end tex"
430+inlineToTexinfo (HtmlInline str) = return empty
431+inlineToTexinfo (LineBreak) = return $ text "@*"
432+inlineToTexinfo Space = return $ char ' '
433+
434+inlineToTexinfo (Link txt (src, _)) = do
435+ case txt of
436+ [Code x] | x == src -> -- autolink
437+ do return $ text $ "@url{" ++ x ++ "}"
438+ _ -> do contents <- inlineListToTexinfo $ deVerb txt
439+ let src1 = stringToTexinfo src
440+ return $ text ("@uref{" ++ src1 ++ ",") <> contents <>
441+ char '}'
442+
443+inlineToTexinfo (Image alternate (source, tit)) = do
444+ content <- inlineListToTexinfo $ deVerb alternate
445+ return $ text ("@image{" ++ base ++ ",,,") <> content <> text "," <>
446+ text (ext ++ "}")
447+ where
448+ (revext, revbase) = break (=='.') (reverse source)
449+ ext = reverse revext
450+ base = case revbase of
451+ ('.' : rest) -> reverse rest
452+ _ -> reverse revbase
453+
454+inlineToTexinfo (Note contents) = do
455+ contents' <- blockListToTexinfo contents
456+ let rawnote = stripTrailingNewlines $ render contents'
457+ let optNewline = "@end verbatim" `isSuffixOf` rawnote
458+ return $ text "@footnote{" <>
459+ text rawnote <>
460+ (if optNewline then char '\n' else empty) <>
461+ char '}'
tests/generate.sh+1
@@ -5,6 +5,7 @@
55../pandoc -r native -s -w rst testsuite.native > writer.rst
66../pandoc -r native -s -w html testsuite.native > writer.html
77../pandoc -r native -s -w latex testsuite.native > writer.latex
8+../pandoc -r native -s -w texinfo testsuite.native > writer.texinfo
89../pandoc -r native -s -w rtf testsuite.native > writer.rtf
910../pandoc -r native -s -w man testsuite.native > writer.man
1011sed -e '/^, Header 1 \[Str "HTML",Space,Str "Blocks"\]/,/^, HorizontalRule/d' testsuite.native | ../pandoc -r native -w docbook -s > writer.docbook
tests/runtests.pl+1−1
@@ -14,7 +14,7 @@ unless (-x $script) { die "$script is not executable.\n"; }
1414
1515print "Writer tests:\n";
1616
17−my @writeformats = ("html", "latex", "rst", "rtf", "markdown", "man", "native"); # docbook, context, and s5 handled separately
17+my @writeformats = ("html", "latex", "texinfo", "rst", "rtf", "markdown", "man", "native"); # docbook, context, and s5 handled separately
1818my $source = "testsuite.native";
1919
2020sub test_results
tests/tables.texinfonew file+124
@@ -0,0 +1,124 @@
1+@node Top
2+@top Top
3+
4+Simple table with caption:
5+
6+@float
7+@multitable @columnfractions 0.15 0.09 0.16 0.13
8+@headitem
9+Right
10+ @tab Left
11+ @tab Center
12+ @tab Default
13+@item
14+12
15+ @tab 12
16+ @tab 12
17+ @tab 12
18+@item
19+123
20+ @tab 123
21+ @tab 123
22+ @tab 123
23+@item
24+1
25+ @tab 1
26+ @tab 1
27+ @tab 1
28+@end multitable
29+@caption{Demonstration of simple table syntax.}
30+@end float
31+Simple table without caption:
32+
33+@multitable @columnfractions 0.15 0.09 0.16 0.13
34+@headitem
35+Right
36+ @tab Left
37+ @tab Center
38+ @tab Default
39+@item
40+12
41+ @tab 12
42+ @tab 12
43+ @tab 12
44+@item
45+123
46+ @tab 123
47+ @tab 123
48+ @tab 123
49+@item
50+1
51+ @tab 1
52+ @tab 1
53+ @tab 1
54+@end multitable
55+
56+Simple table indented two spaces:
57+
58+@float
59+@multitable @columnfractions 0.15 0.09 0.16 0.13
60+@headitem
61+Right
62+ @tab Left
63+ @tab Center
64+ @tab Default
65+@item
66+12
67+ @tab 12
68+ @tab 12
69+ @tab 12
70+@item
71+123
72+ @tab 123
73+ @tab 123
74+ @tab 123
75+@item
76+1
77+ @tab 1
78+ @tab 1
79+ @tab 1
80+@end multitable
81+@caption{Demonstration of simple table syntax.}
82+@end float
83+Multiline table with caption:
84+
85+@float
86+@multitable @columnfractions 0.15 0.14 0.16 0.34
87+@headitem
88+Centered Header
89+ @tab Left Aligned
90+ @tab Right Aligned
91+ @tab Default aligned
92+@item
93+First
94+ @tab row
95+ @tab 12.0
96+ @tab Example of a row that spans multiple lines.
97+@item
98+Second
99+ @tab row
100+ @tab 5.0
101+ @tab Here's another one. Note the blank line between rows.
102+@end multitable
103+@caption{Here's the caption. It may span multiple lines.}
104+@end float
105+Multiline table without caption:
106+
107+@multitable @columnfractions 0.15 0.14 0.16 0.34
108+@headitem
109+Centered Header
110+ @tab Left Aligned
111+ @tab Right Aligned
112+ @tab Default aligned
113+@item
114+First
115+ @tab row
116+ @tab 12.0
117+ @tab Example of a row that spans multiple lines.
118+@item
119+Second
120+ @tab row
121+ @tab 5.0
122+ @tab Here's another one. Note the blank line between rows.
123+@end multitable
124+
tests/writer.texinfonew file+951
@@ -0,0 +1,951 @@
1+\input texinfo
2+
3+@macro textstrikeout{text}
4+~~\text\~~
5+@end macro
6+
7+@macro textsubscript{text}
8+@iftex
9+@textsubscript{\text\}
10+@end iftex
11+@ifnottex
12+_@{\text\@}
13+@end ifnottex
14+@end macro
15+
16+@macro textsuperscript{text}
17+@iftex
18+@textsuperscript{\text\}
19+@end iftex
20+@ifnottex
21+^@{\text\@}
22+@end ifnottex
23+@end macro
24+
25+
26+@ifnottex
27+@paragraphindent 0
28+@end ifnottex
29+@titlepage
30+@title Pandoc Test Suite
31+@author John MacFarlane
32+@author Anonymous
33+July 17@comma{} 2006
34+@end titlepage
35+@node Top
36+@top Pandoc Test Suite
37+
38+This is a set of tests for pandoc. Most of them are adapted from John Gruber's markdown test suite.
39+
40+@iftex
41+@bigskip@hrule@bigskip
42+@end iftex
43+@ifnottex
44+------------------------------------------------------------------------
45+@end ifnottex
46+@menu
47+* Headers::
48+* Level 1::
49+* Paragraphs::
50+* Block Quotes::
51+* Code Blocks::
52+* Lists::
53+* Definition Lists::
54+* HTML Blocks::
55+* Inline Markup::
56+* Smart quotes ellipses dashes::
57+* LaTeX::
58+* Special Characters::
59+* Links::
60+* Images::
61+* Footnotes::
62+@end menu
63+
64+@node Headers
65+@chapter Headers
66+@menu
67+* Level 2 with an embedded link::
68+@end menu
69+
70+@node Level 2 with an embedded link
71+@section Level 2 with an @uref{/url,embedded link}
72+@menu
73+* Level 3 with emphasis::
74+@end menu
75+
76+@node Level 3 with emphasis
77+@subsection Level 3 with @emph{emphasis}
78+@menu
79+* Level 4::
80+@end menu
81+
82+@node Level 4
83+@subsubsection Level 4
84+Level 5
85+
86+@node Level 1
87+@chapter Level 1
88+@menu
89+* Level 2 with emphasis::
90+* Level 2::
91+@end menu
92+
93+@node Level 2 with emphasis
94+@section Level 2 with @emph{emphasis}
95+@menu
96+* Level 3::
97+@end menu
98+
99+@node Level 3
100+@subsection Level 3
101+with no blank line
102+
103+
104+@node Level 2
105+@section Level 2
106+with no blank line
107+
108+@iftex
109+@bigskip@hrule@bigskip
110+@end iftex
111+@ifnottex
112+------------------------------------------------------------------------
113+@end ifnottex
114+
115+@node Paragraphs
116+@chapter Paragraphs
117+Here's a regular paragraph.
118+
119+In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.
120+
121+Here's one with a bullet. * criminey.
122+
123+There should be a hard line break@*here.
124+
125+@iftex
126+@bigskip@hrule@bigskip
127+@end iftex
128+@ifnottex
129+------------------------------------------------------------------------
130+@end ifnottex
131+
132+@node Block Quotes
133+@chapter Block Quotes
134+E-mail style:
135+
136+@quotation
137+This is a block quote. It is pretty short.
138+
139+@end quotation
140+@quotation
141+Code in a block quote:
142+
143+@verbatim
144+sub status {
145+ print "working";
146+}
147+@end verbatim
148+
149+A list:
150+
151+@enumerate
152+@item
153+item one
154+@item
155+item two
156+@end enumerate
157+Nested block quotes:
158+
159+@quotation
160+nested
161+
162+@end quotation
163+@quotation
164+nested
165+
166+@end quotation
167+@end quotation
168+This should not be a block quote: 2 > 1.
169+
170+And a following paragraph.
171+
172+@iftex
173+@bigskip@hrule@bigskip
174+@end iftex
175+@ifnottex
176+------------------------------------------------------------------------
177+@end ifnottex
178+
179+@node Code Blocks
180+@chapter Code Blocks
181+Code:
182+
183+@verbatim
184+---- (should be four hyphens)
185+
186+sub status {
187+ print "working";
188+}
189+
190+this code block is indented by one tab
191+@end verbatim
192+
193+And:
194+
195+@verbatim
196+ this code block is indented by two tabs
197+
198+These should not be escaped: \$ \\ \> \[ \{
199+@end verbatim
200+
201+@iftex
202+@bigskip@hrule@bigskip
203+@end iftex
204+@ifnottex
205+------------------------------------------------------------------------
206+@end ifnottex
207+
208+@node Lists
209+@chapter Lists
210+@menu
211+* Unordered::
212+* Ordered::
213+* Nested::
214+* Tabs and spaces::
215+* Fancy list markers::
216+@end menu
217+
218+@node Unordered
219+@section Unordered
220+Asterisks tight:
221+
222+@itemize
223+@item
224+asterisk 1
225+@item
226+asterisk 2
227+@item
228+asterisk 3
229+@end itemize
230+
231+Asterisks loose:
232+
233+@itemize
234+@item
235+asterisk 1
236+
237+@item
238+asterisk 2
239+
240+@item
241+asterisk 3
242+
243+@end itemize
244+
245+Pluses tight:
246+
247+@itemize
248+@item
249+Plus 1
250+@item
251+Plus 2
252+@item
253+Plus 3
254+@end itemize
255+
256+Pluses loose:
257+
258+@itemize
259+@item
260+Plus 1
261+
262+@item
263+Plus 2
264+
265+@item
266+Plus 3
267+
268+@end itemize
269+
270+Minuses tight:
271+
272+@itemize
273+@item
274+Minus 1
275+@item
276+Minus 2
277+@item
278+Minus 3
279+@end itemize
280+
281+Minuses loose:
282+
283+@itemize
284+@item
285+Minus 1
286+
287+@item
288+Minus 2
289+
290+@item
291+Minus 3
292+
293+@end itemize
294+
295+
296+@node Ordered
297+@section Ordered
298+Tight:
299+
300+@enumerate
301+@item
302+First
303+@item
304+Second
305+@item
306+Third
307+@end enumerate
308+and:
309+
310+@enumerate
311+@item
312+One
313+@item
314+Two
315+@item
316+Three
317+@end enumerate
318+Loose using tabs:
319+
320+@enumerate
321+@item
322+First
323+
324+@item
325+Second
326+
327+@item
328+Third
329+
330+@end enumerate
331+and using spaces:
332+
333+@enumerate
334+@item
335+One
336+
337+@item
338+Two
339+
340+@item
341+Three
342+
343+@end enumerate
344+Multiple paragraphs:
345+
346+@enumerate
347+@item
348+Item 1@comma{} graf one.
349+
350+Item 1. graf two. The quick brown fox jumped over the lazy dog's back.
351+
352+@item
353+Item 2.
354+
355+@item
356+Item 3.
357+
358+@end enumerate
359+
360+@node Nested
361+@section Nested
362+@itemize
363+@item
364+Tab
365+@itemize
366+@item
367+Tab
368+@itemize
369+@item
370+Tab
371+@end itemize
372+
373+@end itemize
374+
375+@end itemize
376+
377+Here's another:
378+
379+@enumerate
380+@item
381+First
382+@item
383+Second:
384+@itemize
385+@item
386+Fee
387+@item
388+Fie
389+@item
390+Foe
391+@end itemize
392+
393+@item
394+Third
395+@end enumerate
396+Same thing but with paragraphs:
397+
398+@enumerate
399+@item
400+First
401+
402+@item
403+Second:
404+
405+@itemize
406+@item
407+Fee
408+@item
409+Fie
410+@item
411+Foe
412+@end itemize
413+
414+@item
415+Third
416+
417+@end enumerate
418+
419+@node Tabs and spaces
420+@section Tabs and spaces
421+@itemize
422+@item
423+this is a list item indented with tabs
424+
425+@item
426+this is a list item indented with spaces
427+
428+@itemize
429+@item
430+this is an example list item indented with tabs
431+
432+@item
433+this is an example list item indented with spaces
434+
435+@end itemize
436+
437+@end itemize
438+
439+
440+@node Fancy list markers
441+@section Fancy list markers
442+@enumerate 2
443+@item
444+begins with 2
445+@item
446+and now 3
447+
448+with a continuation
449+
450+@enumerate 4
451+@item
452+sublist with roman numerals@comma{} starting with 4
453+@item
454+more items
455+@enumerate A
456+@item
457+a subsublist
458+@item
459+a subsublist
460+@end enumerate
461+@end enumerate
462+@end enumerate
463+Nesting:
464+
465+@enumerate A
466+@item
467+Upper Alpha
468+@enumerate
469+@item
470+Upper Roman.
471+@enumerate 6
472+@item
473+Decimal start with 6
474+@enumerate c
475+@item
476+Lower alpha with paren
477+@end enumerate
478+@end enumerate
479+@end enumerate
480+@end enumerate
481+Autonumbering:
482+
483+@enumerate
484+@item
485+Autonumber.
486+@item
487+More.
488+@enumerate
489+@item
490+Nested.
491+@end enumerate
492+@end enumerate
493+Should not be a list item:
494+
495+M.A. 2007
496+
497+B. Williams
498+
499+@iftex
500+@bigskip@hrule@bigskip
501+@end iftex
502+@ifnottex
503+------------------------------------------------------------------------
504+@end ifnottex
505+
506+@node Definition Lists
507+@chapter Definition Lists
508+Tight using spaces:
509+
510+@table @asis
511+@item apple
512+
513+red fruit
514+@item orange
515+
516+orange fruit
517+@item banana
518+
519+yellow fruit
520+@end table
521+Tight using tabs:
522+
523+@table @asis
524+@item apple
525+
526+red fruit
527+@item orange
528+
529+orange fruit
530+@item banana
531+
532+yellow fruit
533+@end table
534+Loose:
535+
536+@table @asis
537+@item apple
538+
539+red fruit
540+
541+@item orange
542+
543+orange fruit
544+
545+@item banana
546+
547+yellow fruit
548+
549+@end table
550+Multiple blocks with italics:
551+
552+@table @asis
553+@item @emph{apple}
554+
555+red fruit
556+
557+contains seeds@comma{} crisp@comma{} pleasant to taste
558+
559+@item @emph{orange}
560+
561+orange fruit
562+
563+@verbatim
564+{ orange code block }
565+@end verbatim
566+
567+@quotation
568+orange block quote
569+
570+@end quotation
571+@end table
572+
573+@node HTML Blocks
574+@chapter HTML Blocks
575+Simple block on one line:
576+
577+foo
578+And nested without indentation:
579+
580+foo
581+bar
582+Interpreted markdown in a table:
583+
584+This is @emph{emphasized}
585+And this is @strong{strong}
586+Here's a simple block:
587+
588+foo
589+This should be a code block@comma{} though:
590+
591+@verbatim
592+<div>
593+ foo
594+</div>
595+@end verbatim
596+
597+As should this:
598+
599+@verbatim
600+<div>foo</div>
601+@end verbatim
602+
603+Now@comma{} nested:
604+
605+foo
606+This should just be an HTML comment:
607+
608+Multiline:
609+
610+Code block:
611+
612+@verbatim
613+<!-- Comment -->
614+@end verbatim
615+
616+Just plain comment@comma{} with trailing spaces on the line:
617+
618+Code:
619+
620+@verbatim
621+<hr />
622+@end verbatim
623+
624+Hr's:
625+
626+@iftex
627+@bigskip@hrule@bigskip
628+@end iftex
629+@ifnottex
630+------------------------------------------------------------------------
631+@end ifnottex
632+
633+@node Inline Markup
634+@chapter Inline Markup
635+This is @emph{emphasized}@comma{} and so @emph{is this}.
636+
637+This is @strong{strong}@comma{} and so @strong{is this}.
638+
639+An @emph{@uref{/url,emphasized link}}.
640+
641+@strong{@emph{This is strong and em.}}
642+
643+So is @strong{@emph{this}} word.
644+
645+@strong{@emph{This is strong and em.}}
646+
647+So is @strong{@emph{this}} word.
648+
649+This is code: @verb{!>!}@comma{} @verb{!$!}@comma{} @verb{!\!}@comma{} @verb{!\$!}@comma{} @verb{!<html>!}.
650+
651+@textstrikeout{This is @emph{strikeout}.}
652+
653+Superscripts: a@textsuperscript{bc}d a@textsuperscript{@emph{hello}} a@textsuperscript{hello there}.
654+
655+Subscripts: H@textsubscript{2}O@comma{} H@textsubscript{23}O@comma{} H@textsubscript{many of them}O.
656+
657+These should not be superscripts or subscripts@comma{} because of the unescaped spaces: a^b c^d@comma{} a~b c~d.
658+
659+@iftex
660+@bigskip@hrule@bigskip
661+@end iftex
662+@ifnottex
663+------------------------------------------------------------------------
664+@end ifnottex
665+
666+@node Smart quotes ellipses dashes
667+@chapter Smart quotes@comma{} ellipses@comma{} dashes
668+``Hello@comma{}'' said the spider. ```Shelob' is my name.''
669+
670+`A'@comma{} `B'@comma{} and `C' are letters.
671+
672+`Oak@comma{}' `elm@comma{}' and `beech' are names of trees. So is `pine.'
673+
674+`He said@comma{} ``I want to go.''' Were you alive in the 70's?
675+
676+Here is some quoted `@verb{!code!}' and a ``@uref{http://example.com/?foo=1&bar=2,quoted link}''.
677+
678+Some dashes: one---two---three---four---five.
679+
680+Dashes between numbers: 5--7@comma{} 255--66@comma{} 1987--1999.
681+
682+Ellipses@dots{}and@dots{}and@dots{}.
683+
684+@iftex
685+@bigskip@hrule@bigskip
686+@end iftex
687+@ifnottex
688+------------------------------------------------------------------------
689+@end ifnottex
690+
691+@node LaTeX
692+@chapter LaTeX
693+@itemize
694+@item
695+@tex
696+\cite[22-23]{smith.1899}
697+@end tex
698+@item
699+@tex
700+\doublespacing
701+@end tex
702+@item
703+@math{2+2=4}
704+@item
705+@math{x \in y}
706+@item
707+@math{\alpha \wedge \omega}
708+@item
709+@math{223}
710+@item
711+@math{p}-Tree
712+@item
713+@math{\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}}
714+@item
715+Here's one that has a line break in it: @math{\alpha + \omega \times x^2}.
716+@end itemize
717+
718+These shouldn't be math:
719+
720+@itemize
721+@item
722+To get the famous equation@comma{} write @verb{!$e = mc^2$!}.
723+@item
724+$22@comma{}000 is a @emph{lot} of money. So is $34@comma{}000. (It worked if ``lot'' is emphasized.)
725+@item
726+Escaped @verb{!$!}: $73 @emph{this should be emphasized} 23$.
727+@end itemize
728+
729+Here's a LaTeX table:
730+
731+@tex
732+\begin{tabular}{|l|l|}\hline
733+Animal & Number \\ \hline
734+Dog & 2 \\
735+Cat & 1 \\ \hline
736+\end{tabular}
737+@end tex
738+
739+@iftex
740+@bigskip@hrule@bigskip
741+@end iftex
742+@ifnottex
743+------------------------------------------------------------------------
744+@end ifnottex
745+
746+@node Special Characters
747+@chapter Special Characters
748+Here is some unicode:
749+
750+@itemize
751+@item
752+I hat: Î
753+@item
754+o umlaut: ö
755+@item
756+section: §
757+@item
758+set membership: ∈
759+@item
760+copyright: ©
761+@end itemize
762+
763+AT&T has an ampersand in their name.
764+
765+AT&T is another way to write it.
766+
767+This & that.
768+
769+4 < 5.
770+
771+6 > 5.
772+
773+Backslash: \
774+
775+Backtick: `
776+
777+Asterisk: *
778+
779+Underscore: _
780+
781+Left brace: @{
782+
783+Right brace: @}
784+
785+Left bracket: [
786+
787+Right bracket: ]
788+
789+Left paren: (
790+
791+Right paren: )
792+
793+Greater-than: >
794+
795+Hash: #
796+
797+Period: .
798+
799+Bang: !
800+
801+Plus: +
802+
803+Minus: -
804+
805+@iftex
806+@bigskip@hrule@bigskip
807+@end iftex
808+@ifnottex
809+------------------------------------------------------------------------
810+@end ifnottex
811+
812+@node Links
813+@chapter Links
814+@menu
815+* Explicit::
816+* Reference::
817+* With ampersands::
818+* Autolinks::
819+@end menu
820+
821+@node Explicit
822+@section Explicit
823+Just a @uref{/url/,URL}.
824+
825+@uref{/url/,URL and title}.
826+
827+@uref{/url/,URL and title}.
828+
829+@uref{/url/,URL and title}.
830+
831+@uref{/url/,URL and title}
832+
833+@uref{/url/,URL and title}
834+
835+@uref{/url/with_underscore,with_underscore}
836+
837+@uref{mailto:nobody@@nowhere.net,Email link}
838+
839+@uref{,Empty}.
840+
841+
842+@node Reference
843+@section Reference
844+Foo @uref{/url/,bar}.
845+
846+Foo @uref{/url/,bar}.
847+
848+Foo @uref{/url/,bar}.
849+
850+With @uref{/url/,embedded [brackets]}.
851+
852+@uref{/url/,b} by itself should be a link.
853+
854+Indented @uref{/url,once}.
855+
856+Indented @uref{/url,twice}.
857+
858+Indented @uref{/url,thrice}.
859+
860+This should [not][] be a link.
861+
862+@verbatim
863+[not]: /url
864+@end verbatim
865+
866+Foo @uref{/url/,bar}.
867+
868+Foo @uref{/url/,biz}.
869+
870+
871+@node With ampersands
872+@section With ampersands
873+Here's a @uref{http://example.com/?foo=1&bar=2,link with an ampersand in the URL}.
874+
875+Here's a link with an amersand in the link text: @uref{http://att.com/,AT&T}.
876+
877+Here's an @uref{/script?foo=1&bar=2,inline link}.
878+
879+Here's an @uref{/script?foo=1&bar=2,inline link in pointy braces}.
880+
881+
882+@node Autolinks
883+@section Autolinks
884+With an ampersand: @url{http://example.com/?foo=1&bar=2}
885+
886+@itemize
887+@item
888+In a list?
889+@item
890+@url{http://example.com/}
891+@item
892+It should.
893+@end itemize
894+
895+An e-mail address: @uref{mailto:nobody@@nowhere.net,@verb{!nobody@@nowhere.net!}}
896+
897+@quotation
898+Blockquoted: @url{http://example.com/}
899+
900+@end quotation
901+Auto-links should not occur here: @verb{!<http://example.com/>!}
902+
903+@verbatim
904+or here: <http://example.com/>
905+@end verbatim
906+
907+@iftex
908+@bigskip@hrule@bigskip
909+@end iftex
910+@ifnottex
911+------------------------------------------------------------------------
912+@end ifnottex
913+
914+@node Images
915+@chapter Images
916+From ``Voyage dans la Lune'' by Georges Melies (1902):
917+
918+@image{lalune,,,lalune,jpg}
919+
920+Here is a movie @image{movie,,,movie,jpg} icon.
921+
922+@iftex
923+@bigskip@hrule@bigskip
924+@end iftex
925+@ifnottex
926+------------------------------------------------------------------------
927+@end ifnottex
928+
929+@node Footnotes
930+@chapter Footnotes
931+Here is a footnote reference@comma{}@footnote{Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.} and another.@footnote{Here's the long note. This one contains multiple blocks.
932+
933+Subsequent blocks are indented to show that they belong to the footnote (as with list items).
934+
935+@verbatim
936+ { <code> }
937+@end verbatim
938+
939+If you want@comma{} you can indent every line@comma{} but you can also be lazy and just indent the first line of each block.} This should @emph{not} be a footnote reference@comma{} because it contains a space.[^my note] Here is an inline note.@footnote{This is @emph{easier} to type. Inline notes may contain @uref{http://google.com,links} and @verb{!]!} verbatim characters@comma{} as well as [bracketed text].}
940+
941+@quotation
942+Notes can go in quotes.@footnote{In quote.}
943+
944+@end quotation
945+@enumerate
946+@item
947+And in list items.@footnote{In list.}
948+@end enumerate
949+This paragraph should not be part of the note@comma{} as it is not indented.
950+
951+@bye