git.iko.soy/typeable/pandoc
on c46f68f help sign in
7 files changed+1616−1
since splitsnapshots
unifiedsplit
pandoc.cabal+1 src/Tests/Old.hs+1−1 src/Tests/Writers/PseudoPod.hs+34 src/Text/Pandoc.hs+3 src/Text/Pandoc/Writers/PseudoPod.hs+448 src/pandoc.hs+1 tests/writer.pod+1128
pandoc.cabal+1
@@ -265,6 +265,7 @@ Library
265265 Text.Pandoc.Writers.AsciiDoc,
266266 Text.Pandoc.Writers.Textile,
267267 Text.Pandoc.Writers.MediaWiki,
268+ Text.Pandoc.Writers.PseudoPod,
268269 Text.Pandoc.Writers.RTF,
269270 Text.Pandoc.Writers.ODT,
270271 Text.Pandoc.Writers.Docx,
src/Tests/Old.hs+1−1
@@ -104,7 +104,7 @@ tests = [ testGroup "markdown"
104104 ]
105105 , testGroup "other writers" $ map (\f -> testGroup f $ writerTests f)
106106 [ "docbook", "opendocument" , "context" , "texinfo"
107− , "man" , "plain" , "mediawiki", "rtf", "org", "asciidoc"
107+ , "man" , "plain" , "mediawiki", "rtf", "org", "asciidoc", "pseudopod"
108108 ]
109109 ]
110110
src/Tests/Writers/PseudoPod.hsnew file+34
@@ -0,0 +1,34 @@
1+{-# LANGUAGE OverloadedStrings, QuasiQuotes #-}
2+module Tests.Writers.PseudoPod (tests) where
3+
4+import Test.Framework
5+import Text.Pandoc.Builder
6+import Text.Pandoc
7+import Tests.Helpers
8+import Tests.Arbitrary()
9+
10+pseudopod :: (ToString a, ToPandoc a) => a -> String
11+pseudopod = writePseudoPod defaultWriterOptions . toPandoc
12+
13+{-
14+ "my test" =: X =?> Y
15+
16+is shorthand for
17+
18+ test pseudopod "my test" $ X =?> Y
19+
20+which is in turn shorthand for
21+
22+ test pseudopod "my test" (X,Y)
23+-}
24+
25+infix 4 =:
26+(=:) :: (ToString a, ToPandoc a)
27+ => String -> (a, String) -> Test
28+(=:) = test pseudopod
29+
30+tests :: [Test]
31+tests = [ "escaped > in string"
32+ =: (para "string with > in it" )
33+ =?> "string with E<gt> in it"
34+ ]
src/Text/Pandoc.hs+3
@@ -92,6 +92,7 @@ module Text.Pandoc
9292 , writeOpenDocument
9393 , writeMan
9494 , writeMediaWiki
95+ , writePseudoPod
9596 , writeTextile
9697 , writeRTF
9798 , writeODT
@@ -139,6 +140,7 @@ import Text.Pandoc.Writers.OpenDocument
139140import Text.Pandoc.Writers.Man
140141import Text.Pandoc.Writers.RTF
141142import Text.Pandoc.Writers.MediaWiki
143+import Text.Pandoc.Writers.PseudoPod
142144import Text.Pandoc.Writers.Textile
143145import Text.Pandoc.Writers.Org
144146import Text.Pandoc.Writers.AsciiDoc
@@ -207,6 +209,7 @@ writers = [("native" , writeNative)
207209 ,("rst+lhs" , \o ->
208210 writeRST o{ writerLiterateHaskell = True })
209211 ,("mediawiki" , writeMediaWiki)
212+ ,("pseudopod" , writePseudoPod)
210213 ,("textile" , writeTextile)
211214 ,("rtf" , writeRTF)
212215 ,("org" , writeOrg)
src/Text/Pandoc/Writers/PseudoPod.hsnew file+448
@@ -0,0 +1,448 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+{-
3+Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
4+
5+This program is free software; you can redistribute it and/or modify
6+it under the terms of the GNU General Public License as published by
7+the Free Software Foundation; either version 2 of the License, or
8+(at your option) any later version.
9+
10+This program is distributed in the hope that it will be useful,
11+but WITHOUT ANY WARRANTY; without even the implied warranty of
12+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+GNU General Public License for more details.
14+
15+You should have received a copy of the GNU General Public License
16+along with this program; if not, write to the Free Software
17+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18+-}
19+
20+{- |
21+ Module : Text.Pandoc.Writers.PseudoPod
22+ Copyright : Copyright (C) 2006-2010 John MacFarlane
23+ License : GNU GPL, version 2 or above
24+
25+ Maintainer : John MacFarlane <jgm@berkeley.edu>
26+ Stability : alpha
27+ Portability : portable
28+
29+Conversion of 'Pandoc' documents to PseudoPod-formatted plain text.
30+
31+PseudoPod: <http://daringfireball.net/projects/PseudoPod/>
32+-}
33+module Text.Pandoc.Writers.PseudoPod (writePseudoPod) where
34+import Text.Pandoc.Definition
35+import Text.Pandoc.Generic
36+import Text.Pandoc.Templates (renderTemplate)
37+import Text.Pandoc.Shared
38+import Text.Pandoc.Parsing hiding (blankline)
39+import Text.ParserCombinators.Parsec ( runParser, GenParser )
40+import Data.List ( intersperse, transpose )
41+import Text.Pandoc.Pretty
42+import Control.Monad.State
43+
44+type Refs = [([Inline], Target)]
45+data WriterState = WriterState { stRefs :: Refs
46+ , stPlain :: Bool }
47+
48+-- | Convert Pandoc to PseudoPod.
49+writePseudoPod :: WriterOptions -> Pandoc -> String
50+writePseudoPod opts document =
51+ evalState (pandocToPseudoPod opts document) WriterState{stRefs = []
52+ , stPlain = False }
53+
54+-- | Return PseudoPod representation of document.
55+pandocToPseudoPod :: WriterOptions -> Pandoc -> State WriterState String
56+pandocToPseudoPod opts (Pandoc (Meta title authors date) blocks) = do
57+ title' <- inlineListToPseudoPod opts title
58+ authors' <- mapM (inlineListToPseudoPod opts) authors
59+ date' <- inlineListToPseudoPod opts date
60+ let titleblock = not $ null title && null authors && null date
61+ let headerBlocks = filter isHeaderBlock blocks
62+ let toc = if writerTableOfContents opts
63+ then tableOfContents opts headerBlocks
64+ else empty
65+ body <- blockListToPseudoPod opts blocks
66+ st' <- get -- note that the notes may contain refs
67+ refs' <- refsToPseudoPod opts (reverse $ stRefs st')
68+ let colwidth = if writerWrapText opts
69+ then Just $ writerColumns opts
70+ else Nothing
71+ let main = render colwidth $ text("=encoding utf8\n\n") <> body <>
72+ (if isEmpty refs' then empty else blankline <> refs')
73+ let context = writerVariables opts ++
74+ [ ("toc", render colwidth toc)
75+ , ("body", main)
76+ , ("title", render colwidth title')
77+ , ("date", render colwidth date')
78+ ] ++
79+ [ ("titleblock", "yes") | titleblock ] ++
80+ [ ("author", render colwidth a) | a <- authors' ]
81+ if writerStandalone opts
82+ then return $ renderTemplate context $ writerTemplate opts
83+ else return main
84+
85+-- | Return PseudoPod representation of reference key table.
86+refsToPseudoPod :: WriterOptions -> Refs -> State WriterState Doc
87+refsToPseudoPod opts refs = mapM (keyToPseudoPod opts) refs >>= return . vcat
88+
89+-- | Return PseudoPod representation of a reference key.
90+keyToPseudoPod :: WriterOptions
91+ -> ([Inline], (String, String))
92+ -> State WriterState Doc
93+keyToPseudoPod opts (label, (src, tit)) = do
94+ label' <- inlineListToPseudoPod opts label
95+ let tit' = if null tit
96+ then empty
97+ else space <> "\"" <> text tit <> "\""
98+ return $ nest 2 $ hang 2
99+ ("[" <> label' <> "]:" <> space) (text src <> tit')
100+
101+-- | Escape special characters for PseudoPod.
102+escapeString :: String -> String
103+escapeString = escapeStringUsing pseudopodEscapes
104+ where pseudopodEscapes = entityEscapes
105+
106+-- | pod-ish entity escapes, E<>
107+entityEscapes :: [(Char,String)]
108+entityEscapes = [('>', "E<gt>"), ('<', "E<lt>"), ('|', "E<verbar>"), ('/', "E<sol>")]
109+
110+-- | Construct table of contents from list of header blocks.
111+tableOfContents :: WriterOptions -> [Block] -> Doc
112+tableOfContents opts headers =
113+ let opts' = opts { writerIgnoreNotes = True }
114+ contents = BulletList $ map elementToListItem $ hierarchicalize headers
115+ in evalState (blockToPseudoPod opts' contents) WriterState{ stRefs = []
116+ , stPlain = False }
117+
118+-- | Converts an Element to a list item for a table of contents,
119+elementToListItem :: Element -> [Block]
120+elementToListItem (Blk _) = []
121+elementToListItem (Sec _ _ _ headerText subsecs) = [Plain headerText] ++
122+ if null subsecs
123+ then []
124+ else [BulletList $ map elementToListItem subsecs]
125+
126+attrsToPseudoPod :: Attr -> Doc
127+attrsToPseudoPod attribs = braces $ hsep [attribId, attribClasses, attribKeys]
128+ where attribId = case attribs of
129+ ([],_,_) -> empty
130+ (i,_,_) -> "#" <> text i
131+ attribClasses = case attribs of
132+ (_,[],_) -> empty
133+ (_,cs,_) -> hsep $
134+ map (text . ('.':))
135+ cs
136+ attribKeys = case attribs of
137+ (_,_,[]) -> empty
138+ (_,_,ks) -> hsep $
139+ map (\(k,v) -> text k
140+ <> "=\"" <> text v <> "\"") ks
141+
142+-- | Ordered list start parser for use in Para below.
143+olMarker :: GenParser Char ParserState Char
144+olMarker = do (start, style', delim) <- anyOrderedListMarker
145+ if delim == Period &&
146+ (style' == UpperAlpha || (style' == UpperRoman &&
147+ start `elem` [1, 5, 10, 50, 100, 500, 1000]))
148+ then spaceChar >> spaceChar
149+ else spaceChar
150+
151+-- | True if string begins with an ordered list marker
152+beginsWithOrderedListMarker :: String -> Bool
153+beginsWithOrderedListMarker str =
154+ case runParser olMarker defaultParserState "para start" (take 10 str) of
155+ Left _ -> False
156+ Right _ -> True
157+
158+-- | Convert Pandoc block element to PseudoPod.
159+blockToPseudoPod :: WriterOptions -- ^ Options
160+ -> Block -- ^ Block element
161+ -> State WriterState Doc
162+blockToPseudoPod _ Null = return empty
163+blockToPseudoPod opts (Plain inlines) = do
164+ contents <- inlineListToPseudoPod opts inlines
165+ return $ contents <> blankline
166+
167+
168+blockToPseudoPod opts (Para inlines) = do
169+ contents <- inlineListToPseudoPod opts inlines
170+ -- escape if para starts with ordered list marker
171+ st <- get
172+ let esc = if (not (writerStrictMarkdown opts)) &&
173+ not (stPlain st) &&
174+ beginsWithOrderedListMarker (render Nothing contents)
175+ then text "\\"
176+ else empty
177+ return $ esc <> contents <> blankline
178+
179+blockToPseudoPod _ (RawBlock f str)
180+ | f == "html" || f == "latex" || f == "tex" || f == "PseudoPod" = do
181+ st <- get
182+ if stPlain st
183+ then return empty
184+ else return $ text str <> text "\n"
185+blockToPseudoPod _ (RawBlock _ _) = return empty
186+
187+-- | No horizontal rules, leave a space
188+blockToPseudoPod _ HorizontalRule =
189+ return $ blankline <> blankline <> blankline
190+
191+-- | =headN <content> - DONE
192+blockToPseudoPod opts (Header level inlines) = do
193+ contents <- inlineListToPseudoPod opts inlines
194+ return $ "=head" <> text (show level) <> " " <> contents <> blankline
195+
196+{-
197+blockToPseudoPod opts (CodeBlock (_,classes,_) str)
198+ | "haskell" `elem` classes && "literate" `elem` classes &&
199+ writerLiterateHaskell opts =
200+ return $ prefixed "> " (text str) <> blankline
201+-}
202+
203+-- | indent 3 spaces - DONE
204+blockToPseudoPod _ (CodeBlock _ str) = return $
205+ nest 3 (text str) <> blankline
206+
207+{-
208+ if writerStrictMarkdown opts || attribs == nullAttr
209+ then nest (writerTabStop opts) (text str) <> blankline
210+ else -- use delimited code block
211+ flush (tildes <> space <> attrs <> cr <> text str <>
212+ cr <> tildes) <> blankline
213+ where tildes = text "~~~~"
214+ attrs = attrsToPseudoPod attribs
215+-}
216+
217+-- | =begin blockquote ?
218+blockToPseudoPod opts (BlockQuote blocks) = do
219+ contents <- blockListToPseudoPod opts blocks
220+ return $ "=begin blockquote" <> blankline <> contents <> blankline <> "=end blockquote" <> blankline
221+
222+-- | =begin table <caption> / =headrow / =row / =cell / =bodyrows / =row / =cell / =end table
223+blockToPseudoPod opts (Table caption _ _ headers rows) = do
224+ caption' <- inlineListToPseudoPod opts caption
225+ headers' <- mapM (blockListToPseudoPod opts) headers
226+
227+ rawRows <- mapM (mapM (blockListToPseudoPod opts)) rows
228+ let makeRow = hcat . intersperse (text("\n=cell "))
229+ let makeRowBlock = hcat . intersperse (text("\n=row\n\n=cell "))
230+
231+ let rows' = map makeRow rawRows
232+ let rows'' = makeRowBlock rows'
233+ let rows''' = "=row" <> blankline <> "=cell " <> rows''
234+
235+ let head' = makeRow headers'
236+ let head'' = "=row" <> blankline <> "=cell " <> head'
237+
238+ return $ "=begin table " <> caption' <> blankline <> "=headrow" <> blankline <> head'' <> blankline <> "=bodyrows" <> blankline <> rows''' <> blankline <> "=end table" <> blankline
239+
240+-- | =over / =item * / =back
241+blockToPseudoPod opts (BulletList items) = do
242+ contents <- mapM (bulletListItemToPseudoPod opts) items
243+ return $ "=over" <> blankline <> cat contents <> blankline <> "=back" <> blankline
244+
245+
246+-- | =over / =item N. / =back
247+blockToPseudoPod opts (OrderedList attribs items) = do
248+ let markers = orderedListMarkers attribs
249+ let markers' = map (\m -> if length m < 3
250+ then m ++ replicate (3 - length m) ' '
251+ else m) markers
252+ contents <- mapM (\(item, num) -> orderedListItemToPseudoPod opts item num) $
253+ zip markers' items
254+ return $ "=over" <> blankline <> cat contents <> blankline <> "=back" <> blankline
255+-- return $ cat contents <> blankline
256+
257+blockToPseudoPod opts (DefinitionList items) = do
258+ contents <- mapM (definitionListItemToPseudoPod opts) items
259+ return $ "=over" <> blankline <> cat contents <> blankline <> "=back" <> blankline
260+
261+-- | bullet list -> =item *
262+bulletListItemToPseudoPod :: WriterOptions -> [Block] -> State WriterState Doc
263+bulletListItemToPseudoPod opts items = do
264+ contents <- blockListToPseudoPod opts items
265+ return $ "=item *" <> blankline <> contents <> blankline
266+
267+-- | Convert ordered list item (a list of blocks) to PseudoPod.
268+orderedListItemToPseudoPod :: WriterOptions -- ^ options
269+ -> String -- ^ list item marker
270+ -> [Block] -- ^ list item (list of blocks)
271+ -> State WriterState Doc
272+orderedListItemToPseudoPod opts marker items = do
273+ contents <- blockListToPseudoPod opts items
274+ return $ "=item " <> (text marker) <> blankline <> contents <> blankline
275+
276+{-
277+ let sps = case length marker - writerTabStop opts of
278+ n | n > 0 -> text $ replicate n ' '
279+ _ -> text " "
280+ let start = text marker <> sps
281+ return $ hang (writerTabStop opts) start $ contents <> cr
282+-}
283+
284+{-
285+-- | Convert definition list item (label, list of blocks) to markdown.
286+definitionListItemToPseudoPod :: WriterOptions
287+ -> ([Inline],[[Block]])
288+ -> State WriterState Doc
289+definitionListItemToPseudoPod opts (label, defs) = do
290+ labelText <- inlineListToPseudoPod opts label
291+ let tabStop = writerTabStop opts
292+ st <- get
293+ let leader = if stPlain st then " " else " ~"
294+ let sps = case writerTabStop opts - 3 of
295+ n | n > 0 -> text $ replicate n ' '
296+ _ -> text " "
297+ defs' <- mapM (mapM (blockToPseudoPod opts)) defs
298+ let contents = vcat $ map (\d -> hang tabStop (leader <> sps) $ vcat d <> cr) defs'
299+ return $ labelText <> cr <> contents <> cr
300+-}
301+
302+-- | Convert definition list item (label, list of blocks) to PseudoPod.
303+-- | =over / =item FOO / para / =back
304+definitionListItemToPseudoPod :: WriterOptions
305+ -> ([Inline],[[Block]])
306+ -> State WriterState Doc
307+definitionListItemToPseudoPod opts (label, defs) = do
308+ labelText <- inlineListToPseudoPod opts label
309+ -- each call to definitonListItemToPseudoPod is one label, which can have multiple defintions. (Each definition is a [Block].)
310+
311+ defs' <- mapM (blockListToPseudoPod opts) defs
312+-- let contents = vcat $ map (\d -> "=item") $ vcat d <> cr) defs'
313+ return $ "=item " <> labelText <> blankline <> vcat defs' <> blankline
314+
315+
316+-- | Convert list of Pandoc block elements to PseudoPod.
317+blockListToPseudoPod :: WriterOptions -- ^ Options
318+ -> [Block] -- ^ List of block elements
319+ -> State WriterState Doc
320+blockListToPseudoPod opts blocks =
321+ mapM (blockToPseudoPod opts) (blocks) >>= return . cat
322+
323+-- | Convert list of Pandoc inline elements to PseudoPod.
324+inlineListToPseudoPod :: WriterOptions -> [Inline] -> State WriterState Doc
325+inlineListToPseudoPod opts lst =
326+ mapM (inlineToPseudoPod opts) lst >>= return . cat
327+
328+escapeSpaces :: Inline -> Inline
329+escapeSpaces (Str s) = Str $ substitute " " "\\ " s
330+escapeSpaces Space = Str "\\ "
331+escapeSpaces x = x
332+
333+-- | Convert Pandoc inline element to PseudoPod.
334+inlineToPseudoPod :: WriterOptions -> Inline -> State WriterState Doc
335+
336+-- | I< > - DONE
337+inlineToPseudoPod opts (Emph lst) = do
338+ contents <- inlineListToPseudoPod opts lst
339+ return $ "I<" <> contents <> ">"
340+
341+-- | B< > - DONE
342+inlineToPseudoPod opts (Strong lst) = do
343+ contents <- inlineListToPseudoPod opts lst
344+ return $ "B<" <> contents <> ">"
345+
346+inlineToPseudoPod opts (Strikeout lst) = inlineListToPseudoPod opts lst
347+{-
348+inlineToPseudoPod opts (Strikeout lst) = do
349+ contents <- inlineListToPseudoPod opts lst
350+ return $ "~~" <> contents <> "~~"
351+-}
352+
353+-- | G<>
354+inlineToPseudoPod opts (Superscript lst) = do
355+ let lst' = bottomUp escapeSpaces lst
356+ contents <- inlineListToPseudoPod opts lst'
357+ return $ "G<" <> contents <> ">"
358+
359+-- | H<>
360+inlineToPseudoPod opts (Subscript lst) = do
361+ let lst' = bottomUp escapeSpaces lst
362+ contents <- inlineListToPseudoPod opts lst'
363+ return $ "H<" <> contents <> ">"
364+
365+-- | FIXME - doesnt exist
366+inlineToPseudoPod opts (SmallCaps lst) = inlineListToPseudoPod opts lst
367+
368+inlineToPseudoPod opts (Quoted SingleQuote lst) = do
369+ contents <- inlineListToPseudoPod opts lst
370+ return $ "‘" <> contents <> "’"
371+inlineToPseudoPod opts (Quoted DoubleQuote lst) = do
372+ contents <- inlineListToPseudoPod opts lst
373+ return $ "“" <> contents <> "”"
374+
375+-- | C<>
376+inlineToPseudoPod opts (Code attr str) =
377+ return $ "C<< " <> text (escapeString str) <> " >>"
378+
379+inlineToPseudoPod _ (Str str) = do
380+ st <- get
381+ if stPlain st
382+ then return $ text str
383+ else return $ text $ escapeString str
384+
385+-- | No Math
386+-- inlineToPseudoPod opts (Math _ str) = inlineToPseudoPod opts Inline str
387+
388+inlineToPseudoPod _ (Math InlineMath str) =
389+ return $ "$" <> text str <> "$"
390+inlineToPseudoPod _ (Math DisplayMath str) =
391+ return $ "$$" <> text str <> "$$"
392+
393+inlineToPseudoPod _ (RawInline f str)
394+ | f == "html" || f == "latex" || f == "tex" || f == "PseudoPod" =
395+ return $ text str
396+inlineToPseudoPod _ (RawInline _ _) = return empty
397+inlineToPseudoPod opts (LineBreak) = return $
398+ if writerStrictMarkdown opts
399+ then " " <> cr
400+ else "\\" <> cr
401+inlineToPseudoPod _ Space = return space
402+inlineToPseudoPod opts (Cite (c:cs) lst)
403+ | writerCiteMethod opts == Citeproc = inlineListToPseudoPod opts lst
404+ | citationMode c == AuthorInText = do
405+ suffs <- inlineListToPseudoPod opts $ citationSuffix c
406+ rest <- mapM convertOne cs
407+ let inbr = suffs <+> joincits rest
408+ br = if isEmpty inbr then empty else char '[' <> inbr <> char ']'
409+ return $ text ("@" ++ citationId c) <+> br
410+ | otherwise = do
411+ cits <- mapM convertOne (c:cs)
412+ return $ text "[" <> joincits cits <> text "]"
413+ where
414+ joincits = hcat . intersperse (text "; ") . filter (not . isEmpty)
415+ convertOne Citation { citationId = k
416+ , citationPrefix = pinlines
417+ , citationSuffix = sinlines
418+ , citationMode = m }
419+ = do
420+ pdoc <- inlineListToPseudoPod opts pinlines
421+ sdoc <- inlineListToPseudoPod opts sinlines
422+ let k' = text (modekey m ++ "@" ++ k)
423+ r = case sinlines of
424+ Str (y:_):_ | y `elem` ",;]@" -> k' <> sdoc
425+ _ -> k' <+> sdoc
426+ return $ pdoc <+> r
427+ modekey SuppressAuthor = "-"
428+ modekey _ = ""
429+inlineToPseudoPod _ (Cite _ _) = return $ text ""
430+
431+-- | L<> - DONE
432+inlineToPseudoPod opts (Link txt (src, _)) = do
433+ label <- inlineListToPseudoPod opts txt
434+ return $ "L<" <> label <> "|" <> (text src) <> ">"
435+
436+inlineToPseudoPod opts (Image alternate (source, tit)) = do
437+ let txt = if (null alternate) || (alternate == [Str ""]) ||
438+ (alternate == [Str source]) -- to prevent autolinks
439+ then [Str "image"]
440+ else alternate
441+ linkPart <- inlineToPseudoPod opts (Link txt (source, tit))
442+ return $ "!" <> linkPart
443+
444+-- | N<>
445+inlineToPseudoPod opts (Note blocks) = do
446+-- contents <- blockListToPseudoPod opts blocks
447+ contents <- mapM (blockToPseudoPod opts) blocks
448+ return $ "N<" <> cat contents <> ">"
src/pandoc.hs+1
@@ -731,6 +731,7 @@ defaultWriterName x =
731731 ".org" -> "org"
732732 ".asciidoc" -> "asciidoc"
733733 ".pdf" -> "latex"
734+ ".pod" -> "pseudopod"
734735 ['.',y] | y `elem` ['1'..'9'] -> "man"
735736 _ -> "html"
736737
tests/writer.podnew file+1128
@@ -0,0 +1,1128 @@
1+=encoding utf8
2+
3+This is a set of tests for pandoc. Most of them are adapted from John Gruber’s
4+markdown test suite.
5+
6+=head1 Headers
7+
8+=head2 Level 2 with an L<embedded link|/url>
9+
10+=head3 Level 3 with I<emphasis>
11+
12+=head4 Level 4
13+
14+=head5 Level 5
15+
16+=head1 Level 1
17+
18+=head2 Level 2 with I<emphasis>
19+
20+=head3 Level 3
21+
22+with no blank line
23+
24+=head2 Level 2
25+
26+with no blank line
27+
28+=head1 Paragraphs
29+
30+Here’s a regular paragraph.
31+
32+In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item.
33+Because a hard-wrapped line in the middle of a paragraph looked like a list
34+item.
35+
36+Here’s one with a bullet. * criminey.
37+
38+There should be a hard line break\
39+here.
40+
41+=head1 Block Quotes
42+
43+E-mail style:
44+
45+=begin blockquote
46+
47+This is a block quote. It is pretty short.
48+
49+=end blockquote
50+
51+=begin blockquote
52+
53+Code in a block quote:
54+
55+ sub status {
56+ print "working";
57+ }
58+
59+A list:
60+
61+=over
62+
63+=item 1.
64+
65+item one
66+
67+=item 2.
68+
69+item two
70+
71+=back
72+
73+Nested block quotes:
74+
75+=begin blockquote
76+
77+nested
78+
79+=end blockquote
80+
81+=begin blockquote
82+
83+nested
84+
85+=end blockquote
86+
87+=end blockquote
88+
89+This should not be a block quote: 2 E<gt> 1.
90+
91+And a following paragraph.
92+
93+=head1 Code Blocks
94+
95+Code:
96+
97+ ---- (should be four hyphens)
98+
99+ sub status {
100+ print "working";
101+ }
102+
103+ this code block is indented by one tab
104+
105+And:
106+
107+ this code block is indented by two tabs
108+
109+ These should not be escaped: \$ \\ \> \[ \{
110+
111+=head1 Lists
112+
113+=head2 Unordered
114+
115+Asterisks tight:
116+
117+=over
118+
119+=item *
120+
121+asterisk 1
122+
123+=item *
124+
125+asterisk 2
126+
127+=item *
128+
129+asterisk 3
130+
131+=back
132+
133+Asterisks loose:
134+
135+=over
136+
137+=item *
138+
139+asterisk 1
140+
141+=item *
142+
143+asterisk 2
144+
145+=item *
146+
147+asterisk 3
148+
149+=back
150+
151+Pluses tight:
152+
153+=over
154+
155+=item *
156+
157+Plus 1
158+
159+=item *
160+
161+Plus 2
162+
163+=item *
164+
165+Plus 3
166+
167+=back
168+
169+Pluses loose:
170+
171+=over
172+
173+=item *
174+
175+Plus 1
176+
177+=item *
178+
179+Plus 2
180+
181+=item *
182+
183+Plus 3
184+
185+=back
186+
187+Minuses tight:
188+
189+=over
190+
191+=item *
192+
193+Minus 1
194+
195+=item *
196+
197+Minus 2
198+
199+=item *
200+
201+Minus 3
202+
203+=back
204+
205+Minuses loose:
206+
207+=over
208+
209+=item *
210+
211+Minus 1
212+
213+=item *
214+
215+Minus 2
216+
217+=item *
218+
219+Minus 3
220+
221+=back
222+
223+=head2 Ordered
224+
225+Tight:
226+
227+=over
228+
229+=item 1.
230+
231+First
232+
233+=item 2.
234+
235+Second
236+
237+=item 3.
238+
239+Third
240+
241+=back
242+
243+and:
244+
245+=over
246+
247+=item 1.
248+
249+One
250+
251+=item 2.
252+
253+Two
254+
255+=item 3.
256+
257+Three
258+
259+=back
260+
261+Loose using tabs:
262+
263+=over
264+
265+=item 1.
266+
267+First
268+
269+=item 2.
270+
271+Second
272+
273+=item 3.
274+
275+Third
276+
277+=back
278+
279+and using spaces:
280+
281+=over
282+
283+=item 1.
284+
285+One
286+
287+=item 2.
288+
289+Two
290+
291+=item 3.
292+
293+Three
294+
295+=back
296+
297+Multiple paragraphs:
298+
299+=over
300+
301+=item 1.
302+
303+Item 1, graf one.
304+
305+Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.
306+
307+=item 2.
308+
309+Item 2.
310+
311+=item 3.
312+
313+Item 3.
314+
315+=back
316+
317+=head2 Nested
318+
319+=over
320+
321+=item *
322+
323+Tab
324+
325+=over
326+
327+=item *
328+
329+Tab
330+
331+=over
332+
333+=item *
334+
335+Tab
336+
337+=back
338+
339+=back
340+
341+=back
342+
343+Here’s another:
344+
345+=over
346+
347+=item 1.
348+
349+First
350+
351+=item 2.
352+
353+Second:
354+
355+=over
356+
357+=item *
358+
359+Fee
360+
361+=item *
362+
363+Fie
364+
365+=item *
366+
367+Foe
368+
369+=back
370+
371+=item 3.
372+
373+Third
374+
375+=back
376+
377+Same thing but with paragraphs:
378+
379+=over
380+
381+=item 1.
382+
383+First
384+
385+=item 2.
386+
387+Second:
388+
389+=over
390+
391+=item *
392+
393+Fee
394+
395+=item *
396+
397+Fie
398+
399+=item *
400+
401+Foe
402+
403+=back
404+
405+=item 3.
406+
407+Third
408+
409+=back
410+
411+=head2 Tabs and spaces
412+
413+=over
414+
415+=item *
416+
417+this is a list item indented with tabs
418+
419+=item *
420+
421+this is a list item indented with spaces
422+
423+=over
424+
425+=item *
426+
427+this is an example list item indented with tabs
428+
429+=item *
430+
431+this is an example list item indented with spaces
432+
433+=back
434+
435+=back
436+
437+=head2 Fancy list markers
438+
439+=over
440+
441+=item (2)
442+
443+begins with 2
444+
445+=item (3)
446+
447+and now 3
448+
449+with a continuation
450+
451+=over
452+
453+=item iv.
454+
455+sublist with roman numerals, starting with 4
456+
457+=item v.
458+
459+more items
460+
461+=over
462+
463+=item (A)
464+
465+a subsublist
466+
467+=item (B)
468+
469+a subsublist
470+
471+=back
472+
473+=back
474+
475+=back
476+
477+Nesting:
478+
479+=over
480+
481+=item A.
482+
483+Upper Alpha
484+
485+=over
486+
487+=item I.
488+
489+Upper Roman.
490+
491+=over
492+
493+=item (6)
494+
495+Decimal start with 6
496+
497+=over
498+
499+=item c)
500+
501+Lower alpha with paren
502+
503+=back
504+
505+=back
506+
507+=back
508+
509+=back
510+
511+Autonumbering:
512+
513+=over
514+
515+=item 1.
516+
517+Autonumber.
518+
519+=item 2.
520+
521+More.
522+
523+=over
524+
525+=item 1.
526+
527+Nested.
528+
529+=back
530+
531+=back
532+
533+Should not be a list item:
534+
535+M.A. 2007
536+
537+B. Williams
538+
539+=head1 Definition Lists
540+
541+Tight using spaces:
542+
543+=over
544+
545+=item apple
546+
547+red fruit
548+
549+=item orange
550+
551+orange fruit
552+
553+=item banana
554+
555+yellow fruit
556+
557+=back
558+
559+Tight using tabs:
560+
561+=over
562+
563+=item apple
564+
565+red fruit
566+
567+=item orange
568+
569+orange fruit
570+
571+=item banana
572+
573+yellow fruit
574+
575+=back
576+
577+Loose:
578+
579+=over
580+
581+=item apple
582+
583+red fruit
584+
585+=item orange
586+
587+orange fruit
588+
589+=item banana
590+
591+yellow fruit
592+
593+=back
594+
595+Multiple blocks with italics:
596+
597+=over
598+
599+=item I<apple>
600+
601+red fruit
602+
603+contains seeds, crisp, pleasant to taste
604+
605+=item I<orange>
606+
607+orange fruit
608+
609+ { orange code block }
610+
611+=begin blockquote
612+
613+orange block quote
614+
615+=end blockquote
616+
617+=back
618+
619+Multiple definitions, tight:
620+
621+=over
622+
623+=item apple
624+
625+red fruit
626+
627+computer
628+
629+=item orange
630+
631+orange fruit
632+
633+bank
634+
635+=back
636+
637+Multiple definitions, loose:
638+
639+=over
640+
641+=item apple
642+
643+red fruit
644+
645+computer
646+
647+=item orange
648+
649+orange fruit
650+
651+bank
652+
653+=back
654+
655+Blank line after term, indented marker, alternate markers:
656+
657+=over
658+
659+=item apple
660+
661+red fruit
662+
663+computer
664+
665+=item orange
666+
667+orange fruit
668+
669+=over
670+
671+=item 1.
672+
673+sublist
674+
675+=item 2.
676+
677+sublist
678+
679+=back
680+
681+=back
682+
683+=head1 HTML Blocks
684+
685+Simple block on one line:
686+
687+<div>
688+foo
689+
690+</div>
691+
692+And nested without indentation:
693+
694+<div>
695+<div>
696+<div>
697+foo
698+
699+</div>
700+</div>
701+<div>
702+bar
703+
704+</div>
705+</div>
706+
707+Interpreted markdown in a table:
708+
709+<table>
710+<tr>
711+<td>
712+This is I<emphasized>
713+
714+</td>
715+<td>
716+And this is B<strong>
717+
718+</td>
719+</tr>
720+</table>
721+
722+<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>
723+
724+Here’s a simple block:
725+
726+<div>
727+
728+foo
729+
730+</div>
731+
732+This should be a code block, though:
733+
734+ <div>
735+ foo
736+ </div>
737+
738+As should this:
739+
740+ <div>foo</div>
741+
742+Now, nested:
743+
744+<div>
745+ <div>
746+ <div>
747+
748+foo
749+
750+</div>
751+ </div>
752+</div>
753+
754+This should just be an HTML comment:
755+
756+<!-- Comment -->
757+
758+Multiline:
759+
760+<!--
761+Blah
762+Blah
763+-->
764+
765+<!--
766+ This is another comment.
767+-->
768+
769+Code block:
770+
771+ <!-- Comment -->
772+
773+Just plain comment, with trailing spaces on the line:
774+
775+<!-- foo -->
776+
777+Code:
778+
779+ <hr />
780+
781+Hr’s:
782+
783+<hr>
784+
785+<hr />
786+
787+<hr />
788+
789+<hr>
790+
791+<hr />
792+
793+<hr />
794+
795+<hr class="foo" id="bar" />
796+
797+<hr class="foo" id="bar" />
798+
799+<hr class="foo" id="bar">
800+
801+=head1 Inline Markup
802+
803+This is I<emphasized>, and so I<is this>.
804+
805+This is B<strong>, and so B<is this>.
806+
807+An I<L<emphasized link|/url>>.
808+
809+B<I<This is strong and em.>>
810+
811+So is B<I<this>> word.
812+
813+B<I<This is strong and em.>>
814+
815+So is B<I<this>> word.
816+
817+This is code: C<< E<gt> >>, C<< $ >>, C<< \ >>, C<< \$ >>,
818+C<< E<lt>htmlE<gt> >>.
819+
820+This is I<strikeout>.
821+
822+Superscripts: aG<bc>d aG<I<hello>> aG<hello there>.
823+
824+Subscripts: HH<2>O, HH<23>O, HH<many of them>O.
825+
826+These should not be superscripts or subscripts, because of the unescaped
827+spaces: a^b c^d, a~b c~d.
828+
829+=head1 Smart quotes, ellipses, dashes
830+
831+“Hello,” said the spider. “‘Shelob’ is my name.”
832+
833+‘A’, ‘B’, and ‘C’ are letters.
834+
835+‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’
836+
837+‘He said, “I want to go.”’ Were you alive in the 70’s?
838+
839+Here is some quoted ‘C<< code >>’ and a “L<quoted
840+link|http://example.com/?foo=1&bar=2>”.
841+
842+Some dashes: one—two — three—four — five.
843+
844+Dashes between numbers: 5–7, 255–66, 1987–1999.
845+
846+Ellipses…and…and….
847+
848+=head1 LaTeX
849+
850+=over
851+
852+=item *
853+
854+\cite[22-23]{smith.1899}
855+
856+=item *
857+
858+$2+2=4$
859+
860+=item *
861+
862+$x \in y$
863+
864+=item *
865+
866+$\alpha \wedge \omega$
867+
868+=item *
869+
870+$223$
871+
872+=item *
873+
874+$p$-Tree
875+
876+=item *
877+
878+Here’s some display math:
879+$$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$
880+
881+=item *
882+
883+Here’s one that has a line break in it: $\alpha + \omega \times x^2$.
884+
885+=back
886+
887+These shouldn’t be math:
888+
889+=over
890+
891+=item *
892+
893+To get the famous equation, write C<< $e = mc^2$ >>.
894+
895+=item *
896+
897+$22,000 is a I<lot> of money. So is $34,000. (It worked if “lot” is
898+emphasized.)
899+
900+=item *
901+
902+Shoes ($20) and socks ($5).
903+
904+=item *
905+
906+Escaped C<< $ >>: $73 I<this should be emphasized> 23$.
907+
908+=back
909+
910+Here’s a LaTeX table:
911+
912+\begin{tabular}{|l|l|}\hline
913+Animal & Number \\ \hline
914+Dog & 2 \\
915+Cat & 1 \\ \hline
916+\end{tabular}
917+
918+=head1 Special Characters
919+
920+Here is some unicode:
921+
922+=over
923+
924+=item *
925+
926+I hat: Î
927+
928+=item *
929+
930+o umlaut: ö
931+
932+=item *
933+
934+section: §
935+
936+=item *
937+
938+set membership: ∈
939+
940+=item *
941+
942+copyright: ©
943+
944+=back
945+
946+AT&T has an ampersand in their name.
947+
948+AT&T is another way to write it.
949+
950+This & that.
951+
952+4 E<lt> 5.
953+
954+6 E<gt> 5.
955+
956+Backslash: \
957+
958+Backtick: `
959+
960+Asterisk: *
961+
962+Underscore: _
963+
964+Left brace: {
965+
966+Right brace: }
967+
968+Left bracket: [
969+
970+Right bracket: ]
971+
972+Left paren: (
973+
974+Right paren: )
975+
976+Greater-than: E<gt>
977+
978+Hash: #
979+
980+Period: .
981+
982+Bang: !
983+
984+Plus: +
985+
986+Minus: -
987+
988+=head1 Links
989+
990+=head2 Explicit
991+
992+Just a L<URL|/url/>.
993+
994+L<URL and title|/url/>.
995+
996+L<URL and title|/url/>.
997+
998+L<URL and title|/url/>.
999+
1000+L<URL and title|/url/>
1001+
1002+L<URL and title|/url/>
1003+
1004+L<with_underscore|/url/with_underscore>
1005+
1006+L<Email link|mailto:nobody@nowhere.net>
1007+
1008+L<Empty|>.
1009+
1010+=head2 Reference
1011+
1012+Foo L<bar|/url/>.
1013+
1014+Foo L<bar|/url/>.
1015+
1016+Foo L<bar|/url/>.
1017+
1018+With L<embedded [brackets]|/url/>.
1019+
1020+L<b|/url/> by itself should be a link.
1021+
1022+Indented L<once|/url>.
1023+
1024+Indented L<twice|/url>.
1025+
1026+Indented L<thrice|/url>.
1027+
1028+This should [not][] be a link.
1029+
1030+ [not]: /url
1031+
1032+Foo L<bar|/url/>.
1033+
1034+Foo L<biz|/url/>.
1035+
1036+=head2 With ampersands
1037+
1038+Here’s a L<link with an ampersand in the URL|http://example.com/?foo=1&bar=2>.
1039+
1040+Here’s a link with an amersand in the link text: L<AT&T|http://att.com/>.
1041+
1042+Here’s an L<inline link|/script?foo=1&bar=2>.
1043+
1044+Here’s an L<inline link in pointy braces|/script?foo=1&bar=2>.
1045+
1046+=head2 Autolinks
1047+
1048+With an ampersand:
1049+L<C<< http:E<sol>E<sol>example.comE<sol>?foo=1&bar=2 >>|http://example.com/?foo=1&bar=2>
1050+
1051+=over
1052+
1053+=item *
1054+
1055+In a list?
1056+
1057+=item *
1058+
1059+L<C<< http:E<sol>E<sol>example.comE<sol> >>|http://example.com/>
1060+
1061+=item *
1062+
1063+It should.
1064+
1065+=back
1066+
1067+An e-mail address: L<C<< nobody@nowhere.net >>|mailto:nobody@nowhere.net>
1068+
1069+=begin blockquote
1070+
1071+Blockquoted: L<C<< http:E<sol>E<sol>example.comE<sol> >>|http://example.com/>
1072+
1073+=end blockquote
1074+
1075+Auto-links should not occur here:
1076+C<< E<lt>http:E<sol>E<sol>example.comE<sol>E<gt> >>
1077+
1078+ or here: <http://example.com/>
1079+
1080+=head1 Images
1081+
1082+From “Voyage dans la Lune” by Georges Melies (1902):
1083+
1084+!L<lalune|lalune.jpg>
1085+
1086+Here is a movie !L<movie|movie.jpg> icon.
1087+
1088+=head1 Footnotes
1089+
1090+Here is a footnote reference,N<Here is the footnote. It can go anywhere after
1091+the footnote reference. It need not be placed at the end of the document.
1092+
1093+> and another.N<Here’s the long note. This one contains multiple blocks.
1094+
1095+Subsequent blocks are indented to show that they belong to the footnote (as
1096+with list items).
1097+
1098+ { <code> }
1099+
1100+If you want, you can indent every line, but you can also be lazy and just
1101+indent the first line of each block.
1102+
1103+> This should I<not> be a footnote reference, because it contains a space.[^my
1104+note] Here is an inline note.N<This is I<easier> to type. Inline notes may
1105+contain L<links|http://google.com> and C<< ] >> verbatim characters, as well
1106+as [bracketed text].
1107+
1108+>
1109+
1110+=begin blockquote
1111+
1112+Notes can go in quotes.N<In quote.
1113+
1114+>
1115+
1116+=end blockquote
1117+
1118+=over
1119+
1120+=item 1.
1121+
1122+And in list items.N<In list.
1123+
1124+>
1125+
1126+=back
1127+
1128+This paragraph should not be part of the note, as it is not indented.