git.iko.soy/typeable/pandoc
on master help sign in
more support for Textile reader (explicit links, images), tests and cabal entries
commita7da0672dc9bc9e362f62a4de5ab14bffd0e86bc authorPaul Rivier <paul.r.ml@gmail.com> dateSun 3 Oct 2010, 20:55 (16 years ago) parentcfc7086
5 files changed+326−18
pandoc.cabal+3−1 src/Text/Pandoc/Readers/Textile.hs+44−17 tests/RunTests.hs+3 tests/textile-reader.native+120 tests/textile-reader.textile+156
pandoc.cabal+3−1
@@ -16,7 +16,7 @@ Synopsis: Conversion between markup formats
1616Description: Pandoc is a Haskell library for converting from one markup
1717 format to another, and a command-line tool that uses
1818 this library. It can read markdown and (subsets of)
19− reStructuredText, HTML, and LaTeX, and it can write
19+ reStructuredText, HTML, LaTeX and Textile, and it can write
2020 markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook,
2121 OpenDocument, ODT, RTF, MediaWiki, Textile, groff man pages,
2222 EPUB, and S5 and Slidy HTML slide shows.
@@ -79,6 +79,7 @@ Extra-Source-Files:
7979 tests/latex-reader.native,
8080 tests/markdown-reader-more.txt,
8181 tests/markdown-reader-more.native,
82+ tests/textile-reader.textile,
8283 tests/rst-reader.native,
8384 tests/rst-reader.rst,
8485 tests/s5.basic.html,
@@ -193,6 +194,7 @@ Library
193194 Text.Pandoc.Readers.Markdown,
194195 Text.Pandoc.Readers.RST,
195196 Text.Pandoc.Readers.TeXMath,
197+ Text.Pandoc.Readers.Textile,
196198 Text.Pandoc.Writers.Native,
197199 Text.Pandoc.Writers.Docbook,
198200 Text.Pandoc.Writers.HTML,
src/Text/Pandoc/Readers/Textile.hs+44−17
@@ -25,15 +25,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2525 Stability : alpha
2626 Portability : portable
2727
28−Conversion from Textile to 'Pandoc' document.
28+Conversion from Textile to 'Pandoc' document, based on the spec
29+available at http://redcloth.org/hobix.com/textile/
2930
3031Implemented :
3132 - Paragraphs
3233 - Code blocks
3334 - Lists
3435 - blockquote
35− - Inlines : strong, emph, cite, code, deleted, inserted, superscript, subscript
36−
36+ - Inlines : strong, emph, cite, code, deleted, inserted, superscript,
37+ subscript, links
3738
3839Not implemented :
3940 - HTML-specific and CSS-specific inlines
@@ -189,6 +190,7 @@ tableRow :: GenParser Char ParserState [TableCell]
189190tableRow = try $ do
190191 char '|'
191192 cells <- endBy1 tableCell (char '|')
193+ -- TODO : don't eat the last newline
192194 newline
193195 return cells
194196
@@ -206,25 +208,27 @@ tableHeaders = try $ do
206208 newline
207209 return headers
208210
209−-- | A table with an optional header
211+-- | A table with an optional header. Current implementation can
212+-- handle tables with and without header, but will parse cells
213+-- alignment attributes as content.
210214table :: GenParser Char ParserState Block
211215table = try $ do
212216 headers <- option [] tableHeaders
213217 rows <- tableRows
218+ let nbOfCols = max (length headers) (length $ head rows)
214219 return $ Table []
215− (replicate (length headers) AlignDefault)
216− (replicate (length headers) 0.0)
220+ (replicate nbOfCols AlignDefault)
221+ (replicate nbOfCols 0.0)
217222 headers
218223 rows
219224
220225
226+
221227----------
222228-- Inlines
223229----------
224230
225231
226−
227−
228232-- | Any inline element
229233inline :: GenParser Char ParserState Inline
230234inline = choice inlineParsers <?> "inline"
@@ -248,10 +252,10 @@ inlineParsers = [ str
248252 , simpleInline (char '+') Inserted
249253 , simpleInline (char '^') Superscript
250254 , simpleInline (char '~') Subscript
251− -- , link
252− -- , image
253− -- , math
254− -- , autoLink
255+ , link
256+ , autoLink
257+ , image
258+ , image
255259 , symbol
256260 ]
257261
@@ -270,6 +274,29 @@ endline = try $ do
270274 newline >> notFollowedBy blankline
271275 return Space
272276
277+link :: GenParser Char ParserState Inline
278+link = try $ do
279+ name <- surrounded (char '"') inline
280+ char ':'
281+ url <- manyTill (anyChar) (lookAhead $ (space <|> try (oneOf ".;," >> (space <|> newline))))
282+ return $ Link name (url, "")
283+
284+-- | Detect plain links to http or email.
285+autoLink :: GenParser Char ParserState Inline
286+autoLink = do
287+ (orig, src) <- uri -- (try uri <|> try emailAddress)
288+ return $ Link [Str orig] (src, "")
289+
290+-- | image embedding
291+image :: GenParser Char ParserState Inline
292+image = try $ do
293+ char '!' >> notFollowedBy space
294+ src <- manyTill anyChar (lookAhead $ oneOf "!(")
295+ alt <- option "" (try $ (char '(' >> manyTill anyChar (char ')')))
296+ char '!'
297+ return $ Image [Str alt] (src, alt)
298+
299+
273300-- | Any special symbol defined in specialChars
274301symbol :: GenParser Char ParserState Inline
275302symbol = do
@@ -297,9 +324,9 @@ simpleInline border construct = surrounded border inline >>=
297324
298325-- TODO
299326--
300−-- - Pandoc Meta Information
327+-- - Pandoc Meta Information (title, author, date)
301328-- - footnotes
302−-- - hyperlink "label":target
303−-- - tables alignments
304−-- - tests
305−-- - Inserted inline handling in writers
329+-- - autolink is not called
330+-- - should autolink be shared through Parsing.hs ?
331+-- - Inserted inline handling in writers
332+-- - table parser is a bit too greedy and require a double newline after tables
tests/RunTests.hs+3
@@ -105,6 +105,8 @@ main = do
105105 "html-reader.html" "html-reader.native"
106106 r10 <- runTest "latex reader" ["-r", "latex", "-w", "native", "-s", "-R"]
107107 "latex-reader.latex" "latex-reader.native"
108+ rTextile1 <- runTest "textile reader" ["-r", "textile", "-w", "native", "-s", "-R"]
109+ "textile-reader.textile" "textile-reader.native"
108110 r11 <- runTest "native reader" ["-r", "native", "-w", "native", "-s"]
109111 "testsuite.native" "testsuite.native"
110112 r12s <- if runLhsTests
@@ -119,6 +121,7 @@ main = do
119121 , r8, r8a -- rst
120122 , r9 -- html
121123 , r10 -- latex
124+ , rTextile1 -- textile
122125 , r11 -- native
123126 ] ++ r12s ++ r13s
124127 if all id results
tests/textile-reader.nativenew file+120
@@ -0,0 +1,120 @@
1+Pandoc (Meta {docTitle = [Str ""], docAuthors = [[Str ""]], docDate = [Str ""]})
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",Space,Str "Gruber",Str "'",Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite."]
3+, Para [Strikeout [Str "-"],Str "-",Str "-"]
4+, Header 1 [Str "Headers"]
5+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embeded",Space,Str "link"] ("http://www.example.com","")]
6+, Header 3 [Str "Level",Space,Str "3",Space,Str "with",Space,Strong [Str "emphasis"]]
7+, Header 4 [Str "Level",Space,Str "4"]
8+, Header 5 [Str "Level",Space,Str "5"]
9+, Header 6 [Str "Level",Space,Str "6"]
10+, Header 1 [Str "Paragraphs"]
11+, Para [Str "Here",Str "'",Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]
12+, Para [Str "Line",Space,Str "break",Space,Str "are",Space,Str "not",Space,Str "paragraph",Space,Str "break",Space,Str "in",Space,Str "textile,",Space,Str "so",Space,Str "you",Space,Str "can",Space,Str "wrap",Space,Str "your",Space,Str "very",Space,Str "long",Space,Str "paragraph",Space,Str "with",Space,Str "your",Space,Str "favourite",Space,Str "text",Space,Str "editor,",Space,Str "it",Space,Str "will",Space,Str "be",Space,Str "rendered",Space,Str "as",Space,Str "a",Space,Str "single",Space,Str "one."]
13+, Para [Str "Here",Str "'",Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet."]
14+, BulletList
15+ [ [ Plain [Str "criminey."] ]
16+ ]
17+, Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break"]
18+, Para [Str "here."]
19+, Header 1 [Str "Block",Space,Str "Quotes"]
20+, BlockQuote
21+ [ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "famous",Space,Str "quote",Space,Str "from",Space,Str "somebody.",Space,Str "He",Space,Str "had",Space,Str "a",Space,Str "lot",Space,Str "of",Space,Str "things",Space,Str "to",Space,Str "say,",Space,Str "so",Space,Str "the",Space,Str "text",Space,Str "is",Space,Str "really",Space,Str "really",Space,Str "long",Space,Str "and",Space,Str "spans",Space,Str "on",Space,Str "multiple",Space,Str "lines."] ]
22+
23+, Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph."]
24+, Header 1 [Str "Code",Space,Str "Blocks"]
25+, Para [Str "Code",Str ":"]
26+, CodeBlock ("",[],[]) "\n ---- (should be four hyphens)\n\n sub status {\n print \"working\";\n }\n\n this code block is indented by one tab\n"
27+, Para [Str "And",Str ":"]
28+, CodeBlock ("",[],[]) "\n this code block is indented by two tabs\n\n These should not be escaped: \\$ \\\\ \\> \\[ \\{\n"
29+, Header 1 [Str "Lists"]
30+, Header 2 [Str "Unordered"]
31+, Para [Str "Asterisks",Space,Str "tight",Str ":"]
32+, BulletList
33+ [ [ Plain [Str "asterisk",Space,Str "1"] ]
34+ , [ Plain [Str "asterisk",Space,Str "2"] ]
35+ , [ Plain [Str "asterisk",Space,Str "3"] ] ]
36+, Header 2 [Str "Ordered"]
37+, Para [Str "Tight",Str ":"]
38+, OrderedList (1,DefaultStyle,DefaultDelim)
39+ [ [ Plain [Str "First"] ]
40+ , [ Plain [Str "Second"] ]
41+ , [ Plain [Str "Third"] ] ]
42+, Header 2 [Str "Nested"]
43+, BulletList
44+ [ [ Plain [Str "ui",Space,Str "1"]
45+ , BulletList
46+ [ [ Plain [Str "ui",Space,Str "1.1"]
47+ , OrderedList (1,DefaultStyle,DefaultDelim)
48+ [ [ Plain [Str "oi",Space,Str "1.1.1"] ]
49+ , [ Plain [Str "oi",Space,Str "1.1.2"] ] ] ], [ Plain [Str "ui",Space,Str "1.2"] ] ] ], [ Plain [Str "ui",Space,Str "2"]
50+ , OrderedList (1,DefaultStyle,DefaultDelim)
51+ [ [ Plain [Str "oi",Space,Str "2.1"]
52+ , BulletList
53+ [ [ Plain [Str "ui",Space,Str "2.1.1"] ]
54+ , [ Plain [Str "ui",Space,Str "2.1.2"] ] ] ] ] ] ]
55+, Header 1 [Str "Inline",Space,Str "Markup"]
56+, Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str "."]
57+, Para [Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",Space,Strong [Str "is",Space,Str "this"],Str "."]
58+, Para [Str "A",Space,Link [Strong [Str "strong",Space,Str "link"]] ("http://www.foobar.com",""),Str "."]
59+, Para [Emph [Strong [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]
60+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word",Space,Str "and",Space,Emph [Strong [Str "that",Space,Str "one"]],Str "."]
61+, Para [Strikeout [Str "This",Space,Str "is",Space,Str "strikeout",Space,Str "and",Space,Strong [Str "strong"]]]
62+, Para [Str "Superscripts",Str ":",Space,Str "a",Superscript [Str "bc"],Str "d",Space,Str "a",Superscript [Strong [Str "hello"]],Space,Str "a",Superscript [Str "hello",Space,Str "there"],Str "."]
63+, Para [Str "Subscripts",Str ":",Space,Str "H",Subscript [Str "2"],Str "O,",Space,Str "H",Subscript [Str "23"],Str "O,",Space,Str "H",Subscript [Str "many",Space,Str "of",Space,Str "them"],Str "O."]
64+, Header 1 [Str "Links"]
65+, Header 2 [Str "Explicit"]
66+, Para [Str "Just",Space,Str "a",Space,Link [Str "url"] ("http://www.url.com","")]
67+, Para [Link [Str "Email",Space,Str "link"] ("mailto:nobody@nowhere.net","")]
68+, Para [Str "Automatic",Space,Str "linking",Space,Str "to",Space,Str "http",Str ":",Str "//www.example.com",Space,Str "and",Space,Str "foobar",Str "@",Str "example.com."]
69+, Header 1 [Str "Tables"]
70+, Para [Str "Textile",Space,Str "allows",Space,Str "tables",Space,Str "with",Space,Str "and",Space,Str "without",Space,Str "headers",Space,Str ":"]
71+, Header 2 [Str "Without",Space,Str "headers"]
72+, Table [] [AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0]
73+ [
74+ ] [
75+ [ [ Plain [Str "name"] ]
76+ , [ Plain [Str "age"] ]
77+ , [ Plain [Str "sex"] ] ],
78+ [ [ Plain [Str "joan"] ]
79+ , [ Plain [Str "24"] ]
80+ , [ Plain [Str "f"] ] ],
81+ [ [ Plain [Str "archie"] ]
82+ , [ Plain [Str "29"] ]
83+ , [ Plain [Str "m"] ] ],
84+ [ [ Plain [Str "bella"] ]
85+ , [ Plain [Str "45"] ]
86+ , [ Plain [Str "f"] ] ] ]
87+, Para [Str "And",Space,Str "some",Space,Str "text",Space,Str "..."]
88+, Table [] [AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0]
89+ [
90+ ] [
91+ [ [ Plain [Str "name"] ]
92+ , [ Plain [Str "age"] ]
93+ , [ Plain [Str "sex"] ] ],
94+ [ [ Plain [Str "joan"] ]
95+ , [ Plain [Str "24"] ]
96+ , [ Plain [Str "f"] ] ],
97+ [ [ Plain [Str "archie"] ]
98+ , [ Plain [Str "29"] ]
99+ , [ Plain [Str "m"] ] ],
100+ [ [ Plain [Str "bella"] ]
101+ , [ Plain [Str "45"] ]
102+ , [ Plain [Str "f"] ] ] ]
103+, Para []
104+, Header 2 [Str "With",Space,Str "headers"]
105+, Table [] [AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0]
106+ [ [ Plain [Str "name"] ]
107+ , [ Plain [Str "age"] ]
108+ , [ Plain [Str "sex"] ] ] [
109+ [ [ Plain [Str "joan"] ]
110+ , [ Plain [Str "24"] ]
111+ , [ Plain [Str "f"] ] ],
112+ [ [ Plain [Str "archie"] ]
113+ , [ Plain [Str "29"] ]
114+ , [ Plain [Str "m"] ] ],
115+ [ [ Plain [Str "bella"] ]
116+ , [ Plain [Str "45"] ]
117+ , [ Plain [Str "f"] ] ] ]
118+, Para []
119+, Header 1 [Str "Images"]
120+, Para [Str "Textile",Space,Str "inline",Space,Str "image",Space,Str "syntax,",Space,Str "like",Space,Str "here",Space,Image [Str "this is the alt text"] ("this_is_an_image.png","this is the alt text"),Space,Str "and",Space,Str "here",Space,Image [Str ""] ("this_is_an_image.png",""),Str "."] ]
tests/textile-reader.textilenew file+156
@@ -0,0 +1,156 @@
1+This is a set of tests for pandoc. Most of them are adapted from John
2+Gruber's markdown test suite.
3+
4+-----
5+
6+h1. Headers
7+
8+h2. Level 2 with an "embeded link":http://www.example.com
9+
10+h3. Level 3 with *emphasis*
11+
12+h4. Level 4
13+
14+h5. Level 5
15+
16+h6. Level 6
17+
18+
19+h1. Paragraphs
20+
21+Here's a regular paragraph.
22+
23+Line break are not paragraph break in textile, so you can wrap your
24+very long paragraph with your favourite text editor, it will be
25+rendered as a single one.
26+
27+Here's one with a bullet.
28+
29+* criminey.
30+
31+There should be a hard line break
32+
33+here.
34+
35+h1. Block Quotes
36+
37+bq. This is a famous quote from somebody. He had a lot of things to
38+say, so the text is really really long and spans on multiple lines.
39+
40+And a following paragraph.
41+
42+h1. Code Blocks
43+
44+Code:
45+
46+<pre>
47+ ---- (should be four hyphens)
48+
49+ sub status {
50+ print "working";
51+ }
52+
53+ this code block is indented by one tab
54+</pre>
55+
56+And:
57+
58+<pre>
59+ this code block is indented by two tabs
60+
61+ These should not be escaped: \$ \\ \> \[ \{
62+</pre>
63+
64+
65+h1. Lists
66+
67+h2. Unordered
68+
69+Asterisks tight:
70+
71+* asterisk 1
72+* asterisk 2
73+* asterisk 3
74+
75+h2. Ordered
76+
77+Tight:
78+
79+# First
80+# Second
81+# Third
82+
83+h2. Nested
84+
85+* ui 1
86+** ui 1.1
87+### oi 1.1.1
88+### oi 1.1.2
89+** ui 1.2
90+* ui 2
91+## oi 2.1
92+*** ui 2.1.1
93+*** ui 2.1.2
94+
95+
96+h1. Inline Markup
97+
98+This is _emphasized_, and so __is this__.
99+
100+This is *strong*, and so **is this**.
101+
102+A "*strong link*":http://www.foobar.com.
103+
104+_*This is strong and em.*_
105+
106+So is *_this_* word and __**that one**__.
107+
108+-This is strikeout and *strong*-
109+
110+Superscripts: a^bc^d a^*hello*^ a^hello there^.
111+
112+Subscripts: H~2~O, H~23~O, H~many of them~O.
113+
114+
115+h1. Links
116+
117+h2. Explicit
118+
119+Just a "url":http://www.url.com
120+
121+"Email link":mailto:nobody@nowhere.net
122+
123+Automatic linking to http://www.example.com and foobar@example.com.
124+
125+h1. Tables
126+
127+Textile allows tables with and without headers :
128+
129+h2. Without headers
130+
131+| name | age | sex |
132+| joan | 24 | f |
133+| archie | 29 | m |
134+| bella | 45 | f |
135+
136+And some text ...
137+
138+| name | age | sex |
139+| joan | 24 | f |
140+| archie| 29 | m |
141+| bella | 45 | f |
142+
143+
144+h2. With headers
145+
146+|_. name |_. age |_. sex |
147+| joan | 24 | f |
148+| archie | 29 | m |
149+| bella | 45 | f |
150+
151+
152+h1. Images
153+
154+Textile inline image syntax, like
155+here !this_is_an_image.png(this is the alt text)!
156+and here !this_is_an_image.png!.