git.iko.soy/typeable/pandoc
on master help sign in
Merge pull request #1453 from mpickering/txt2tagsfinal

Txt2Tags Reader

commit31b8a95c1dc84b9351d81b4b9122f56b29b19c6c authorJohn MacFarlane <jgm@berkeley.edu> dateSat 26 Jul 2014, 18:46 (12 years ago) parent18f44909e4604f
11 files changed+2384−40
README+2−1 pandoc.cabal+9−31 pandoc.hs+16−7 src/Text/Pandoc.hs+5 src/Text/Pandoc/Compat/Directory.hs+21 src/Text/Pandoc/Readers/Txt2Tags.hs+547 tests/Tests/Old.hs+4 tests/Tests/Readers/Txt2Tags.hs+430 tests/test-pandoc.hs+2−1 tests/txt2tags.native+551 tests/txt2tags.t2t+797
README+2−1
@@ -14,7 +14,7 @@ Pandoc is a [Haskell] library for converting from one markup format to
1414another, and a command-line tool that uses this library. It can read
1515[markdown] and (subsets of) [Textile], [reStructuredText], [HTML],
1616[LaTeX], [MediaWiki markup], [Haddock markup], [OPML], [Emacs
17−Org-mode], [DocBook], and [Word docx]; and it can write plain text,
17+Org-mode], [DocBook], [txt2tags] and [Word docx]; and it can write plain text,
1818[markdown], [reStructuredText], [XHTML], [HTML 5], [LaTeX] (including
1919[beamer] slide shows), [ConTeXt], [RTF], [OPML], [DocBook],
2020[OpenDocument], [ODT], [Word docx], [GNU Texinfo], [MediaWiki markup],
@@ -3096,3 +3096,4 @@ Rosenthal.
30963096[marc relators]: http://www.loc.gov/marc/relators/relaterm.html
30973097[RFC5646]: http://tools.ietf.org/html/rfc5646
30983098[InDesign ICML]: https://www.adobe.com/content/dam/Adobe/en/devnet/indesign/cs55-docs/IDML/idml-specification.pdf
3099+[txt2tags]: http://txt2tags.org/
pandoc.cabal+9−31
@@ -17,7 +17,7 @@ Description: 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) HTML,
1919 reStructuredText, LaTeX, DocBook, MediaWiki markup, Haddock
20− markup, OPML, Emacs Org-Mode, and Textile, and it can write
20+ markup, OPML, Emacs Org-Mode, txt2tags and Textile, and it can write
2121 markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook,
2222 OPML, OpenDocument, ODT, Word docx, RTF, MediaWiki, DokuWiki,
2323 Textile, groff man pages, plain text, Emacs Org-Mode, AsciiDoc,
@@ -94,34 +94,23 @@ Extra-Source-Files:
9494 -- tests
9595 tests/bodybg.gif,
9696 tests/docbook-reader.docbook
97− tests/docbook-reader.native
9897 tests/html-reader.html,
99− tests/html-reader.native,
10098 tests/opml-reader.opml,
101− tests/opml-reader.native,
10299 tests/haddock-reader.haddock,
103− tests/haddock-reader.native,
104100 tests/insert,
105101 tests/lalune.jpg,
106102 tests/movie.jpg,
107103 tests/latex-reader.latex,
108− tests/latex-reader.native,
109104 tests/textile-reader.textile,
110− tests/textile-reader.native,
111105 tests/markdown-reader-more.txt,
112− tests/markdown-reader-more.native,
113106 tests/markdown-citations.txt,
114− tests/markdown-citations.native,
115107 tests/textile-reader.textile,
116108 tests/mediawiki-reader.wiki,
117− tests/mediawiki-reader.native,
118− tests/rst-reader.native,
119109 tests/rst-reader.rst,
120110 tests/s5.basic.html,
121111 tests/s5.fancy.html,
122112 tests/s5.fragment.html,
123113 tests/s5.inserts.html,
124− tests/s5.native,
125114 tests/tables.context,
126115 tests/tables.docbook,
127116 tests/tables.html,
@@ -131,7 +120,6 @@ Extra-Source-Files:
131120 tests/tables.markdown,
132121 tests/tables.mediawiki,
133122 tests/tables.textile,
134− tests/tables.native,
135123 tests/tables.opendocument,
136124 tests/tables.org,
137125 tests/tables.asciidoc,
@@ -140,9 +128,7 @@ Extra-Source-Files:
140128 tests/tables.rst,
141129 tests/tables.rtf,
142130 tests/tables.txt,
143− tests/tables-rstsubset.native,
144131 tests/tables.fb2,
145− tests/testsuite.native,
146132 tests/testsuite.txt,
147133 tests/writer.latex,
148134 tests/writer.context,
@@ -153,7 +139,6 @@ Extra-Source-Files:
153139 tests/writer.plain,
154140 tests/writer.mediawiki,
155141 tests/writer.textile,
156− tests/writer.native,
157142 tests/writer.opendocument,
158143 tests/writer.org,
159144 tests/writer.asciidoc,
@@ -163,8 +148,6 @@ Extra-Source-Files:
163148 tests/writer.texinfo,
164149 tests/writer.fb2,
165150 tests/writer.opml,
166− tests/lhs-test.native,
167− tests/lhs-test-markdown.native,
168151 tests/lhs-test.markdown,
169152 tests/lhs-test.markdown+lhs,
170153 tests/lhs-test.rst,
@@ -175,7 +158,6 @@ Extra-Source-Files:
175158 tests/lhs-test.html+lhs,
176159 tests/lhs-test.fragment.html+lhs,
177160 tests/pipe-tables.txt,
178− tests/pipe-tables.native,
179161 tests/fb2.basic.markdown,
180162 tests/fb2.basic.fb2,
181163 tests/fb2.titles.markdown,
@@ -188,26 +170,18 @@ Extra-Source-Files:
188170 tests/fb2.math.fb2,
189171 tests/fb2.test-small.png,
190172 tests/fb2.test.jpg,
191− tests/docx.already_auto_ident.native,
192173 tests/docx.already_auto_ident.docx,
193174 tests/docx.block_quotes.docx,
194− tests/docx.block_quotes_parse_indent.native,
195175 tests/docx.headers.docx,
196− tests/docx.headers.native,
197176 tests/docx.image.docx,
198− tests/docx.image_no_embed.native,
199177 tests/docx.inline_formatting.docx,
200− tests/docx.inline_formatting.native,
201178 tests/docx.links.docx,
202− tests/docx.links.native,
203179 tests/docx.lists.docx,
204− tests/docx.lists.native,
205180 tests/docx.notes.docx,
206− tests/docx.notes.native,
207181 tests/docx.tables.docx,
208− tests/docx.tables.native,
209182 tests/docx.unicode.docx,
210− tests/docx.unicode.native
183+ tests/*.native,
184+ tests/txt2tags.t2t
211185Extra-Tmp-Files: man/man1/pandoc.1,
212186 man/man5/pandoc_markdown.5
213187
@@ -261,7 +235,8 @@ Library
261235 hslua >= 0.3 && < 0.4,
262236 binary >= 0.5 && < 0.8,
263237 SHA >= 1.6 && < 1.7,
264− haddock-library >= 1.1 && < 1.2
238+ haddock-library >= 1.1 && < 1.2,
239+ old-time
265240 if flag(https)
266241 Build-Depends: http-client >= 0.3.2 && < 0.4,
267242 http-client-tls >= 0.2 && < 0.3,
@@ -328,7 +303,8 @@ Library
328303 Text.Pandoc.Templates,
329304 Text.Pandoc.XML,
330305 Text.Pandoc.SelfContained,
331− Text.Pandoc.Process
306+ Text.Pandoc.Process,
307+ Text.Pandoc.Readers.Txt2Tags
332308 Other-Modules: Text.Pandoc.Readers.Docx.Lists,
333309 Text.Pandoc.Readers.Docx.Reducible,
334310 Text.Pandoc.Readers.Docx.Parse,
@@ -344,6 +320,7 @@ Library
344320 Text.Pandoc.Compat.Monoid,
345321 Text.Pandoc.Compat.Except,
346322 Text.Pandoc.Compat.TagSoupEntity,
323+ Text.Pandoc.Compat.Directory
347324 Paths_pandoc
348325
349326 Buildable: True
@@ -420,6 +397,7 @@ Test-Suite test-pandoc
420397 Tests.Readers.Org
421398 Tests.Readers.RST
422399 Tests.Readers.Docx
400+ Tests.Readers.Txt2Tags
423401 Tests.Writers.Native
424402 Tests.Writers.ConTeXt
425403 Tests.Writers.HTML
pandoc.hs+16−7
@@ -65,6 +65,9 @@ import qualified Data.Map as M
6565import Data.Yaml (decode)
6666import qualified Data.Yaml as Yaml
6767import qualified Data.Text as T
68+import Control.Applicative ((<$>))
69+import Text.Pandoc.Readers.Txt2Tags (getT2TMeta)
70+import Data.List (intersperse)
6871
6972copyrightMessage :: String
7073copyrightMessage = "\nCopyright (C) 2006-2014 John MacFarlane\n" ++
@@ -180,7 +183,7 @@ data Opt = Opt
180183 , optTeXLigatures :: Bool -- ^ Use TeX ligatures for quotes/dashes
181184 , optDefaultImageExtension :: String -- ^ Default image extension
182185 , optTrace :: Bool -- ^ Print debug information
183− , optTrackChanges :: TrackChanges -- ^ Accept or reject MS Word track-changes.
186+ , optTrackChanges :: TrackChanges -- ^ Accept or reject MS Word track-changes.
184187 }
185188
186189-- | Defaults for command-line options.
@@ -876,6 +879,7 @@ defaultReaderName fallback (x:xs) =
876879 ".native" -> "native"
877880 ".json" -> "json"
878881 ".docx" -> "docx"
882+ ".t2t" -> "t2t"
879883 _ -> defaultReaderName fallback xs
880884
881885-- Returns True if extension of first source is .lhs
@@ -1054,9 +1058,14 @@ main = do
10541058 else e
10551059 Right w -> return w
10561060
1057− reader <- case getReader readerName' of
1058− Right r -> return r
1059− Left e -> err 7 e
1061+ let concatInput = concat (intersperse ", " sources)
1062+ reader <- if "t2t" == readerName'
1063+ then (mkStringReader .
1064+ readTxt2Tags) <$>
1065+ (getT2TMeta concatInput outputFile)
1066+ else case getReader readerName' of
1067+ Right r -> return r
1068+ Left e -> err 7 e
10601069
10611070 let standalone' = standalone || not (isTextFormat writerName') || pdfOutput
10621071
@@ -1181,18 +1190,18 @@ main = do
11811190 let readFiles [] = error "Cannot read archive from stdin"
11821191 readFiles (x:_) = B.readFile x
11831192
1184− let convertTabs = tabFilter (if preserveTabs then 0 else tabStop)
1193+ let convertTabs = tabFilter (if (preserveTabs || readerName' == "t2t") then 0 else tabStop)
11851194
11861195 let handleIncludes' = if readerName' == "latex" || readerName' == "latex+lhs"
11871196 then handleIncludes
11881197 else return
11891198
11901199 doc <- case reader of
1191− StringReader r->
1200+ StringReader r->
11921201 readSources sources >>=
11931202 handleIncludes' . convertTabs . intercalate "\n" >>=
11941203 r readerOpts
1195− ByteStringReader r -> readFiles sources >>= r readerOpts
1204+ ByteStringReader r -> readFiles sources >>= r readerOpts
11961205
11971206
11981207 let doc0 = M.foldWithKey setMeta doc metadata
src/Text/Pandoc.hs+5
@@ -63,6 +63,7 @@ module Text.Pandoc
6363 , writers
6464 -- * Readers: converting /to/ Pandoc format
6565 , Reader (..)
66+ , mkStringReader
6667 , readDocx
6768 , readMarkdown
6869 , readMediaWiki
@@ -76,6 +77,8 @@ module Text.Pandoc
7677 , readHaddock
7778 , readNative
7879 , readJSON
80+ , readTxt2Tags
81+ , readTxt2TagsNoMacros
7982 -- * Writers: converting /from/ Pandoc format
8083 , Writer (..)
8184 , writeNative
@@ -130,6 +133,7 @@ import Text.Pandoc.Readers.Textile
130133import Text.Pandoc.Readers.Native
131134import Text.Pandoc.Readers.Haddock
132135import Text.Pandoc.Readers.Docx
136+import Text.Pandoc.Readers.Txt2Tags
133137import Text.Pandoc.Writers.Native
134138import Text.Pandoc.Writers.Markdown
135139import Text.Pandoc.Writers.RST
@@ -227,6 +231,7 @@ readers = [ ("native" , StringReader $ \_ s -> return $ readNative s)
227231 ,("latex" , mkStringReader readLaTeX)
228232 ,("haddock" , mkStringReader readHaddock)
229233 ,("docx" , mkBSReader readDocx)
234+ ,("t2t" , mkStringReader readTxt2TagsNoMacros)
230235 ]
231236
232237data Writer = PureStringWriter (WriterOptions -> Pandoc -> String)
src/Text/Pandoc/Compat/Directory.hsnew file+21
@@ -0,0 +1,21 @@
1+{-# LANGUAGE CPP #-}
2+module Text.Pandoc.Compat.Directory ( getModificationTime )
3+ where
4+
5+#if MIN_VERSION_directory(1,2,0)
6+import System.Directory
7+
8+
9+#else
10+import qualified System.Directory as S
11+import Data.Time.Clock (UTCTime)
12+import Data.Time.Clock.POSIX
13+import System.Time
14+
15+getModificationTime :: FilePath -> IO UTCTime
16+getModificationTime fp = convert `fmap` S.getModificationTime fp
17+ where
18+ convert (TOD x _) = posixSecondsToUTCTime (realToFrac x)
19+
20+#endif
21+
src/Text/Pandoc/Readers/Txt2Tags.hsnew file+547
@@ -0,0 +1,547 @@
1+{-# LANGUAGE ViewPatterns #-}
2+{-
3+Copyright (C) 2014 Matthew Pickering <matthewtpickering@gmail.com>
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.Readers.Txt2Tags
22+ Copyright : Copyright (C) 2014 Matthew Pickering
23+ License : GNU GPL, version 2 or above
24+
25+ Maintainer : Matthew Pickering <matthewtpickering@gmail.com>
26+
27+Conversion of txt2tags formatted plain text to 'Pandoc' document.
28+-}
29+module Text.Pandoc.Readers.Txt2Tags ( readTxt2Tags
30+ , getT2TMeta
31+ , T2TMeta (..)
32+ , readTxt2TagsNoMacros)
33+ where
34+
35+import qualified Text.Pandoc.Builder as B
36+import Text.Pandoc.Builder ( Inlines, Blocks, (<>)
37+ , trimInlines )
38+import Text.Pandoc.Definition
39+import Text.Pandoc.Options
40+import Text.Pandoc.Shared (escapeURI,compactify', compactify'DL)
41+import Text.Pandoc.Parsing hiding (space, spaces, uri, macro)
42+import Control.Applicative ((<$>), (<$), (<*>), (<*), (*>))
43+import Data.Char (toLower)
44+import Data.List (transpose, intersperse, intercalate)
45+import Data.Maybe (fromMaybe)
46+import Data.Monoid (Monoid, mconcat, mempty, mappend)
47+--import Network.URI (isURI) -- Not sure whether to use this function
48+import Control.Monad (void, guard, when)
49+import Data.Default
50+import Control.Monad.Reader (Reader, runReader, asks)
51+
52+import Data.Time.LocalTime (getZonedTime)
53+import Text.Pandoc.Compat.Directory(getModificationTime)
54+import Data.Time.Format (formatTime)
55+import System.Locale (defaultTimeLocale)
56+import System.IO.Error (catchIOError)
57+
58+type T2T = ParserT String ParserState (Reader T2TMeta)
59+
60+-- | An object for the T2T macros meta information
61+-- the contents of each field is simply substituted verbatim into the file
62+data T2TMeta = T2TMeta {
63+ date :: String -- ^ Current date
64+ , mtime :: String -- ^ Last modification time of infile
65+ , infile :: FilePath -- ^ Input file
66+ , outfile :: FilePath -- ^ Output file
67+ } deriving Show
68+
69+instance Default T2TMeta where
70+ def = T2TMeta "" "" "" ""
71+
72+-- | Get the meta information required by Txt2Tags macros
73+getT2TMeta :: FilePath -> FilePath -> IO T2TMeta
74+getT2TMeta inp out = do
75+ curDate <- formatTime defaultTimeLocale "%F" <$> getZonedTime
76+ let getModTime = formatTime defaultTimeLocale "%F"
77+ <$> getModificationTime inp
78+ curMtime <- catchIOError getModTime (const (return ""))
79+
80+ return $ T2TMeta curDate curMtime inp out
81+
82+-- | Read Txt2Tags from an input string returning a Pandoc document
83+readTxt2Tags :: T2TMeta -> ReaderOptions -> String -> Pandoc
84+readTxt2Tags t opts s = flip runReader t $ readWithM parseT2T (def {stateOptions = opts}) (s ++ "\n\n")
85+
86+-- | Read Txt2Tags (ignoring all macros) from an input string returning
87+-- a Pandoc document
88+readTxt2TagsNoMacros :: ReaderOptions -> String -> Pandoc
89+readTxt2TagsNoMacros = readTxt2Tags def
90+
91+parseT2T :: T2T Pandoc
92+parseT2T = do
93+ _ <- (Nothing <$ try blankline) <|> (Just <$> (count 3 anyLine))
94+ config <- manyTill setting (notFollowedBy setting)
95+ -- TODO: Handle settings better
96+ let settings = foldr (\(k,v) -> B.setMeta k (MetaString v)) nullMeta config
97+ updateState (\s -> s {stateMeta = settings})
98+ body <- mconcat <$> manyTill block eof
99+ return $ Pandoc mempty (B.toList body)
100+
101+type Keyword = String
102+type Value = String
103+
104+setting :: T2T (Keyword, Value)
105+setting = do
106+ string "%!"
107+ keyword <- ignoreSpacesCap (many1 alphaNum)
108+ char ':'
109+ value <- ignoreSpacesCap (manyTill anyChar (newline))
110+ return (keyword, value)
111+
112+-- Blocks
113+
114+parseBlocks :: T2T Blocks
115+parseBlocks = mconcat <$> manyTill block eof
116+
117+block :: T2T Blocks
118+block = do
119+ choice
120+ [ mempty <$ blanklines
121+ , quote
122+ , hrule -- hrule must go above title
123+ , title
124+ , commentBlock
125+ , verbatim
126+ , rawBlock
127+ , taggedBlock
128+ , list
129+ , table
130+ , para
131+ ]
132+
133+title :: T2T Blocks
134+title = try $ balancedTitle '+' <|> balancedTitle '='
135+
136+balancedTitle :: Char -> T2T Blocks
137+balancedTitle c = try $ do
138+ spaces
139+ level <- length <$> many1 (char c)
140+ guard (level <= 5) -- Max header level 5
141+ heading <- manyTill (noneOf "\n\r") (count level (char c))
142+ label <- optionMaybe (enclosed (char '[') (char ']') (alphaNum <|> oneOf "_-"))
143+ many spaceChar *> newline
144+ let attr = maybe nullAttr (\x -> (x, [], [])) label
145+ return $ B.headerWith attr level (trimInlines $ B.text heading)
146+
147+para :: T2T Blocks
148+para = try $ do
149+ ils <- parseInlines
150+ nl <- option False (True <$ newline)
151+ option (B.plain ils) (guard nl >> notFollowedBy listStart >> return (B.para ils))
152+ where
153+ listStart = try bulletListStart <|> orderedListStart
154+
155+commentBlock :: T2T Blocks
156+commentBlock = try (blockMarkupArea (anyLine) (const mempty) "%%%") <|> comment
157+
158+-- Seperator and Strong line treated the same
159+hrule :: T2T Blocks
160+hrule = try $ do
161+ spaces
162+ line <- many1 (oneOf "=-_")
163+ guard (length line >= 20)
164+ B.horizontalRule <$ blankline
165+
166+quote :: T2T Blocks
167+quote = try $ do
168+ lookAhead tab
169+ rawQuote <- many1 (tab *> optional spaces *> anyLine)
170+ contents <- parseFromString parseBlocks (intercalate "\n" rawQuote ++ "\n\n")
171+ return $ B.blockQuote contents
172+
173+commentLine :: T2T Inlines
174+commentLine = comment
175+
176+-- List Parsing code from Org Reader
177+
178+list :: T2T Blocks
179+list = choice [bulletList, orderedList, definitionList]
180+
181+bulletList :: T2T Blocks
182+bulletList = B.bulletList . compactify'
183+ <$> many1 (listItem bulletListStart parseBlocks)
184+
185+orderedList :: T2T Blocks
186+orderedList = B.orderedList . compactify'
187+ <$> many1 (listItem orderedListStart parseBlocks)
188+
189+definitionList :: T2T Blocks
190+definitionList = try $ do
191+ B.definitionList . compactify'DL <$>
192+ many1 (listItem definitionListStart definitionListEnd)
193+
194+definitionListEnd :: T2T (Inlines, [Blocks])
195+definitionListEnd = (,) <$> (mconcat <$> manyTill inline newline) <*> ((:[]) <$> parseBlocks)
196+
197+genericListStart :: T2T Char
198+ -> T2T Int
199+genericListStart listMarker = try $
200+ (2+) <$> (length <$> many spaceChar
201+ <* listMarker <* space <* notFollowedBy space)
202+
203+-- parses bullet list \start and returns its length (excl. following whitespace)
204+bulletListStart :: T2T Int
205+bulletListStart = genericListStart (char '-')
206+
207+orderedListStart :: T2T Int
208+orderedListStart = genericListStart (char '+' )
209+
210+definitionListStart :: T2T Int
211+definitionListStart = genericListStart (char ':')
212+
213+-- parse raw text for one list item, excluding start marker and continuations
214+listItem :: T2T Int
215+ -> T2T a
216+ -> T2T a
217+listItem start end = try $ do
218+ markerLength <- try start
219+ firstLine <- anyLineNewline
220+ blank <- option "" ("\n" <$ blankline)
221+ rest <- concat <$> many (listContinuation markerLength)
222+ parseFromString end $ firstLine ++ blank ++ rest
223+
224+-- continuation of a list item - indented and separated by blankline or endline.
225+-- Note: nested lists are parsed as continuations.
226+listContinuation :: Int
227+ -> T2T String
228+listContinuation markerLength = try $
229+ notFollowedBy' (blankline >> blankline)
230+ *> (mappend <$> (concat <$> many1 listLine)
231+ <*> many blankline)
232+ where listLine = try $ indentWith markerLength *> anyLineNewline
233+
234+anyLineNewline :: T2T String
235+anyLineNewline = (++ "\n") <$> anyLine
236+
237+indentWith :: Int -> T2T String
238+indentWith n = count n space
239+
240+-- Table
241+
242+table :: T2T Blocks
243+table = try $ do
244+ header <- fmap snd <$> option mempty (try headerRow)
245+ rows <- many1 (many commentLine *> tableRow)
246+ let columns = transpose rows
247+ let ncolumns = length columns
248+ let aligns = map (foldr1 findAlign) (map (map fst) columns)
249+ let rows' = map (map snd) rows
250+ let size = maximum (map length rows')
251+ let rowsPadded = map (pad size) rows'
252+ let headerPadded = if (not (null header)) then pad size header else mempty
253+ return $ B.table mempty
254+ (zip aligns (replicate ncolumns 0.0))
255+ headerPadded rowsPadded
256+
257+pad :: (Show a, Monoid a) => Int -> [a] -> [a]
258+pad n xs = xs ++ (replicate (n - length xs) mempty)
259+
260+
261+findAlign :: Alignment -> Alignment -> Alignment
262+findAlign x y
263+ | x == y = x
264+ | otherwise = AlignDefault
265+
266+headerRow :: T2T [(Alignment, Blocks)]
267+headerRow = genericRow (string "||")
268+
269+tableRow :: T2T [(Alignment, Blocks)]
270+tableRow = genericRow (char '|')
271+
272+genericRow :: T2T a -> T2T [(Alignment, Blocks)]
273+genericRow start = try $ do
274+ spaces *> start
275+ manyTill tableCell newline <?> "genericRow"
276+
277+
278+tableCell :: T2T (Alignment, Blocks)
279+tableCell = try $ do
280+ leftSpaces <- length <$> lookAhead (many1 space) -- Case of empty cell means we must lookAhead
281+ content <- (manyTill inline (try $ lookAhead (cellEnd)))
282+ rightSpaces <- length <$> many space
283+ let align =
284+ case compare leftSpaces rightSpaces of
285+ LT -> AlignLeft
286+ EQ -> AlignCenter
287+ GT -> AlignRight
288+ endOfCell
289+ return $ (align, B.plain (B.trimInlines $ mconcat content))
290+ where
291+ cellEnd = (void newline <|> (many1 space *> endOfCell))
292+
293+endOfCell :: T2T ()
294+endOfCell = try (skipMany1 $ char '|') <|> ( () <$ lookAhead newline)
295+
296+-- Raw area
297+
298+verbatim :: T2T Blocks
299+verbatim = genericBlock anyLineNewline B.codeBlock "```"
300+
301+rawBlock :: T2T Blocks
302+rawBlock = genericBlock anyLineNewline (B.para . B.str) "\"\"\""
303+
304+taggedBlock :: T2T Blocks
305+taggedBlock = do
306+ target <- getTarget
307+ genericBlock anyLineNewline (B.rawBlock target) "'''"
308+
309+-- Generic
310+
311+genericBlock :: Monoid a => T2T a -> (a -> Blocks) -> String -> T2T Blocks
312+genericBlock p f s = blockMarkupArea p f s <|> blockMarkupLine p f s
313+
314+blockMarkupArea :: Monoid a => (T2T a) -> (a -> Blocks) -> String -> T2T Blocks
315+blockMarkupArea p f s = try $ (do
316+ string s *> blankline
317+ f . mconcat <$> (manyTill p (eof <|> void (string s *> blankline))))
318+
319+blockMarkupLine :: T2T a -> (a -> Blocks) -> String -> T2T Blocks
320+blockMarkupLine p f s = try (f <$> (string s *> space *> p))
321+
322+-- Can be in either block or inline position
323+comment :: Monoid a => T2T a
324+comment = try $ do
325+ atStart
326+ notFollowedBy macro
327+ mempty <$ (char '%' *> anyLine)
328+
329+-- Inline
330+
331+parseInlines :: T2T Inlines
332+parseInlines = trimInlines . mconcat <$> many1 inline
333+
334+inline :: T2T Inlines
335+inline = do
336+ choice
337+ [ endline
338+ , macro
339+ , commentLine
340+ , whitespace
341+ , url
342+ , link
343+ , image
344+ , bold
345+ , underline
346+ , code
347+ , raw
348+ , tagged
349+ , strike
350+ , italic
351+ , code
352+ , str
353+ , symbol
354+ ]
355+
356+bold :: T2T Inlines
357+bold = inlineMarkup inline B.strong '*' (B.str)
358+
359+underline :: T2T Inlines
360+underline = inlineMarkup inline B.emph '_' (B.str)
361+
362+strike :: T2T Inlines
363+strike = inlineMarkup inline B.strikeout '-' (B.str)
364+
365+italic :: T2T Inlines
366+italic = inlineMarkup inline B.emph '/' (B.str)
367+
368+code :: T2T Inlines
369+code = inlineMarkup ((:[]) <$> anyChar) B.code '`' id
370+
371+raw :: T2T Inlines
372+raw = inlineMarkup ((:[]) <$> anyChar) B.text '"' id
373+
374+tagged :: T2T Inlines
375+tagged = do
376+ target <- getTarget
377+ inlineMarkup ((:[]) <$> anyChar) (B.rawInline target) '\'' id
378+
379+-- Parser for markup indicated by a double character.
380+-- Inline markup is greedy and glued
381+-- Greedy meaning ***a*** = Bold [Str "*a*"]
382+-- Glued meaning that markup must be tight to content
383+-- Markup can't pass newlines
384+inlineMarkup :: Monoid a
385+ => (T2T a) -- Content parser
386+ -> (a -> Inlines) -- Constructor
387+ -> Char -- Fence
388+ -> (String -> a) -- Special Case to handle ******
389+ -> T2T Inlines
390+inlineMarkup p f c special = try $ do
391+ start <- many1 (char c)
392+ let l = length start
393+ guard (l >= 2)
394+ when (l == 2) (void $ notFollowedBy space)
395+ -- We must make sure that there is no space before the start of the
396+ -- closing tags
397+ body <- optionMaybe (try $ manyTill (noneOf "\n\r") $
398+ (try $ lookAhead (noneOf " " >> string [c,c] )))
399+ case body of
400+ Just middle -> do
401+ lastChar <- anyChar
402+ end <- many1 (char c)
403+ let parser inp = parseFromString (mconcat <$> many p) inp
404+ let start' = special (drop 2 start)
405+ body' <- parser (middle ++ [lastChar])
406+ let end' = special (drop 2 end)
407+ return $ f (start' <> body' <> end')
408+ Nothing -> do -- Either bad or case such as *****
409+ guard (l >= 5)
410+ let body' = (replicate (l - 4) c)
411+ return $ f (special body')
412+
413+link :: T2T Inlines
414+link = try imageLink <|> titleLink
415+
416+-- Link with title
417+titleLink :: T2T Inlines
418+titleLink = try $ do
419+ char '['
420+ notFollowedBy space
421+ tokens <- sepBy1 (many $ noneOf " ]") space
422+ guard (length tokens >= 2)
423+ char ']'
424+ let link' = last tokens
425+ guard (length link' > 0)
426+ let tit = concat (intersperse " " (init tokens))
427+ return $ B.link link' "" (B.text tit)
428+
429+-- Link with image
430+imageLink :: T2T Inlines
431+imageLink = try $ do
432+ char '['
433+ body <- image
434+ many1 space
435+ l <- manyTill (noneOf "\n\r ") (char ']')
436+ return (B.link l "" body)
437+
438+macro :: T2T Inlines
439+macro = try $ do
440+ name <- string "%%" *> oneOfStringsCI (map fst commands)
441+ optional (try $ enclosed (char '(') (char ')') anyChar)
442+ lookAhead (spaceChar <|> oneOf specialChars <|> newline)
443+ maybe (return mempty) (\f -> B.str <$> asks f) (lookup name commands)
444+ where
445+ commands = [ ("date", date), ("mtime", mtime)
446+ , ("infile", infile), ("outfile", outfile)]
447+
448+-- raw URLs in text are automatically linked
449+url :: T2T Inlines
450+url = try $ do
451+ (rawUrl, escapedUrl) <- (try uri <|> emailAddress)
452+ return $ B.link rawUrl "" (B.str escapedUrl)
453+
454+uri :: T2T (String, String)
455+uri = try $ do
456+ address <- t2tURI
457+ return (address, escapeURI address)
458+
459+-- The definition of a URI in the T2T source differs from the
460+-- actual definition. This is a transcription of the definition in
461+-- the source of v2.6
462+--isT2TURI :: String -> Bool
463+--isT2TURI (parse t2tURI "" -> Right _) = True
464+--isT2TURI _ = False
465+
466+t2tURI :: T2T String
467+t2tURI = do
468+ start <- try ((++) <$> proto <*> urlLogin) <|> guess
469+ domain <- many1 chars
470+ sep <- many (char '/')
471+ form' <- option mempty ((:) <$> char '?' <*> many1 form)
472+ anchor' <- option mempty ((:) <$> char '#' <*> many anchor)
473+ return (start ++ domain ++ sep ++ form' ++ anchor')
474+ where
475+ protos = ["http", "https", "ftp", "telnet", "gopher", "wais"]
476+ proto = (++) <$> oneOfStrings protos <*> string "://"
477+ guess = (++) <$> (((++) <$> stringAnyCase "www" <*> option mempty ((:[]) <$> oneOf "23"))
478+ <|> stringAnyCase "ftp") <*> ((:[]) <$> char '.')
479+ login = alphaNum <|> oneOf "_.-"
480+ pass = many (noneOf " @")
481+ chars = alphaNum <|> oneOf "%._/~:,=$@&+-"
482+ anchor = alphaNum <|> oneOf "%._0"
483+ form = chars <|> oneOf ";*"
484+ urlLogin = option mempty $ try ((\x y z -> x ++ y ++ [z]) <$> many1 login <*> option mempty ((:) <$> char ':' <*> pass) <*> char '@')
485+
486+
487+image :: T2T Inlines
488+image = try $ do
489+ -- List taken from txt2tags source
490+ let extensions = [".jpg", ".jpeg", ".gif", ".png", ".eps", ".bmp"]
491+ char '['
492+ path <- manyTill (noneOf "\n\t\r ") (try $ lookAhead (oneOfStrings extensions))
493+ ext <- oneOfStrings extensions
494+ char ']'
495+ return $ B.image (path ++ ext) "" mempty
496+
497+-- Characters used in markup
498+specialChars :: String
499+specialChars = "%*-_/|:+"
500+
501+tab :: T2T Char
502+tab = char '\t'
503+
504+space :: T2T Char
505+space = char ' '
506+
507+spaces :: T2T String
508+spaces = many space
509+
510+endline :: T2T Inlines
511+endline = try $ do
512+ newline
513+ notFollowedBy blankline
514+ notFollowedBy hrule
515+ notFollowedBy title
516+ notFollowedBy verbatim
517+ notFollowedBy rawBlock
518+ notFollowedBy taggedBlock
519+ notFollowedBy quote
520+ notFollowedBy list
521+ notFollowedBy table
522+ return $ B.space
523+
524+str :: T2T Inlines
525+str = try $ do
526+ B.str <$> many1 (noneOf $ specialChars ++ "\n\r ")
527+
528+whitespace :: T2T Inlines
529+whitespace = try $ B.space <$ spaceChar
530+
531+symbol :: T2T Inlines
532+symbol = B.str . (:[]) <$> oneOf specialChars
533+
534+-- Utility
535+
536+getTarget :: T2T String
537+getTarget = do
538+ mv <- lookupMeta "target" . stateMeta <$> getState
539+ let MetaString target = fromMaybe (MetaString "html") mv
540+ return target
541+
542+atStart :: T2T ()
543+atStart = (sourceColumn <$> getPosition) >>= guard . (== 1)
544+
545+ignoreSpacesCap :: T2T String -> T2T String
546+ignoreSpacesCap p = map toLower <$> (spaces *> p <* spaces)
547+
tests/Tests/Old.hs+4
@@ -142,6 +142,10 @@ tests = [ testGroup "markdown"
142142 , test "reader" ["-r", "haddock", "-w", "native", "-s"]
143143 "haddock-reader.haddock" "haddock-reader.native"
144144 ]
145+ , testGroup "txt2tags"
146+ [ test "reader" ["-r", "t2t", "-w", "native"]
147+ "txt2tags.t2t" "txt2tags.native"
148+ ]
145149 , testGroup "other writers" $ map (\f -> testGroup f $ writerTests f)
146150 [ "opendocument" , "context" , "texinfo", "icml"
147151 , "man" , "plain" , "rtf", "org", "asciidoc"
tests/Tests/Readers/Txt2Tags.hsnew file+430
@@ -0,0 +1,430 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+module Tests.Readers.Txt2Tags (tests) where
3+
4+import Text.Pandoc.Definition
5+import Test.Framework
6+import Tests.Helpers
7+import Tests.Arbitrary()
8+import Text.Pandoc.Builder
9+import Text.Pandoc
10+import Data.List (intersperse)
11+import Data.Monoid (mempty, mconcat)
12+import Text.Pandoc.Readers.Txt2Tags
13+
14+t2t :: String -> Pandoc
15+t2t s = readTxt2Tags (T2TMeta "date" "mtime" "in" "out") def ('\n' : s)
16+
17+infix 4 =:
18+(=:) :: ToString c
19+ => String -> (String, c) -> Test
20+(=:) = test t2t
21+
22+spcSep :: [Inlines] -> Inlines
23+spcSep = mconcat . intersperse space
24+
25+simpleTable' :: Int
26+ -> [Blocks]
27+ -> [[Blocks]]
28+ -> Blocks
29+simpleTable' n = table "" (take n $ repeat (AlignCenter, 0.0))
30+
31+tests :: [Test]
32+tests =
33+ [ testGroup "Inlines" $
34+ [ "Plain String" =:
35+ "Hello, World" =?>
36+ para (spcSep [ "Hello,", "World" ])
37+
38+ , "Emphasis" =:
39+ "//Planet Punk//" =?>
40+ para (emph . spcSep $ ["Planet", "Punk"])
41+
42+ , "Strong" =:
43+ "**Cider**" =?>
44+ para (strong "Cider")
45+
46+ , "Strong Emphasis" =:
47+ "//**strength**//" =?>
48+ para (emph . strong $ "strength")
49+
50+ , "Strikeout" =:
51+ "--Kill Bill--" =?>
52+ para (strikeout . spcSep $ [ "Kill", "Bill" ])
53+
54+ , "Verbatim" =:
55+ "``Robot.rock()``" =?>
56+ para (code "Robot.rock()")
57+
58+ , "Symbol" =:
59+ "A * symbol" =?>
60+ para (str "A" <> space <> str "*" <> space <> "symbol")
61+
62+ , "No empty markup" =:
63+ "//// **** ____ ---- ```` \"\"\"\" ''''" =?>
64+ para (spcSep [ "////", "****", "____", "----", "````", "\"\"\"\"", "''''" ])
65+
66+ , "Inline markup is greedy" =:
67+ "***** ///// _____ ----- ````` \"\"\"\"\" '''''" =?>
68+ para (spcSep [strong "*", emph "/", emph "_"
69+ , strikeout "-", code "`", text "\""
70+ , rawInline "html" "'"])
71+ , "Markup must be greedy" =:
72+ "********** ////////// __________ ---------- `````````` \"\"\"\"\"\"\"\"\"\" ''''''''''" =?>
73+ para (spcSep [strong "******", emph "//////", emph "______"
74+ , strikeout "------", code "``````", text "\"\"\"\"\"\""
75+ , rawInline "html" "''''''"])
76+ , "Inlines must be glued" =:
77+ "** a** **a ** ** a **" =?>
78+ para (text "** a** **a ** ** a **")
79+
80+ , "Macros: Date" =:
81+ "%%date" =?>
82+ para "date"
83+ , "Macros: Mod Time" =:
84+ "%%mtime" =?>
85+ para "mtime"
86+ , "Macros: Infile" =:
87+ "%%infile" =?>
88+ para "in"
89+ , "Macros: Outfile" =:
90+ "%%outfile" =?>
91+ para "out"
92+ , "Autolink" =:
93+ "http://www.google.com" =?>
94+ para (link "http://www.google.com" "" (str "http://www.google.com"))
95+ , "Image" =:
96+ "[image.jpg]" =?>
97+ para (image "image.jpg" "" mempty)
98+
99+ , "Link" =:
100+ "[title http://google.com]" =?>
101+ para (link "http://google.com" "" (str "title"))
102+
103+ , "Image link" =:
104+ "[[image.jpg] abc]" =?>
105+ para (link "abc" "" (image "image.jpg" "" mempty))
106+ , "Invalid link: No trailing space" =:
107+ "[title invalid ]" =?>
108+ para (text "[title invalid ]")
109+
110+
111+ ]
112+
113+ , testGroup "Basic Blocks" $
114+ ["Paragraph, lines grouped together" =:
115+ "A paragraph\n A blank line ends the \n current paragraph\n"
116+ =?> para "A paragraph A blank line ends the current paragraph"
117+ , "Paragraph, ignore leading and trailing spaces" =:
118+ " Leading and trailing spaces are ignored. \n" =?>
119+ para "Leading and trailing spaces are ignored."
120+ , "Comment line in paragraph" =:
121+ "A comment line can be placed inside a paragraph.\n% this comment will be ignored \nIt will not affect it.\n"
122+ =?> para "A comment line can be placed inside a paragraph. It will not affect it."
123+ , "Paragraph" =:
124+ "Paragraph\n" =?>
125+ para "Paragraph"
126+
127+ , "First Level Header" =:
128+ "+ Headline +\n" =?>
129+ header 1 "Headline"
130+
131+ , "Third Level Header" =:
132+ "=== Third Level Headline ===\n" =?>
133+ header 3 ("Third" <> space <>
134+ "Level" <> space <>
135+ "Headline")
136+
137+ , "Header with label" =:
138+ "= header =[label]" =?>
139+ headerWith ("label", [], []) 1 ("header")
140+
141+ , "Invalid header, mismatched delimiters" =:
142+ "== header =" =?>
143+ para (text "== header =")
144+
145+ , "Invalid header, spaces in label" =:
146+ "== header ==[ haha ]" =?>
147+ para (text "== header ==[ haha ]")
148+
149+ , "Invalid header, invalid label character" =:
150+ "== header ==[lab/el]" =?>
151+ para (text "== header ==[lab/el]")
152+ , "Headers not preceded by a blank line" =:
153+ unlines [ "++ eat dinner ++"
154+ , "Spaghetti and meatballs tonight."
155+ , "== walk dog =="
156+ ] =?>
157+ mconcat [ header 2 ("eat" <> space <> "dinner")
158+ , para $ spcSep [ "Spaghetti", "and", "meatballs", "tonight." ]
159+ , header 2 ("walk" <> space <> "dog")
160+ ]
161+
162+ , "Paragraph starting with an equals" =:
163+ "=five" =?>
164+ para "=five"
165+
166+ , "Paragraph containing asterisk at beginning of line" =:
167+ unlines [ "lucky"
168+ , "*star"
169+ ] =?>
170+ para ("lucky" <> space <> "*star")
171+
172+ , "Horizontal Rule" =:
173+ unlines [ "before"
174+ , replicate 20 '-'
175+ , replicate 20 '='
176+ , replicate 20 '_'
177+ , "after"
178+ ] =?>
179+ mconcat [ para "before"
180+ , horizontalRule
181+ , horizontalRule
182+ , horizontalRule
183+ , para "after"
184+ ]
185+
186+ , "Comment Block" =:
187+ unlines [ "%%%"
188+ , "stuff"
189+ , "bla"
190+ , "%%%"] =?>
191+ (mempty::Blocks)
192+
193+
194+ ]
195+
196+ , testGroup "Lists" $
197+ [ "Simple Bullet Lists" =:
198+ ("- Item1\n" ++
199+ "- Item2\n") =?>
200+ bulletList [ plain "Item1"
201+ , plain "Item2"
202+ ]
203+
204+ , "Indented Bullet Lists" =:
205+ (" - Item1\n" ++
206+ " - Item2\n") =?>
207+ bulletList [ plain "Item1"
208+ , plain "Item2"
209+ ]
210+
211+
212+
213+ , "Nested Bullet Lists" =:
214+ ("- Discovery\n" ++
215+ " + One More Time\n" ++
216+ " + Harder, Better, Faster, Stronger\n" ++
217+ "- Homework\n" ++
218+ " + Around the World\n"++
219+ "- Human After All\n" ++
220+ " + Technologic\n" ++
221+ " + Robot Rock\n") =?>
222+ bulletList [ mconcat
223+ [ plain "Discovery"
224+ , orderedList [ plain ("One" <> space <>
225+ "More" <> space <>
226+ "Time")
227+ , plain ("Harder," <> space <>
228+ "Better," <> space <>
229+ "Faster," <> space <>
230+ "Stronger")
231+ ]
232+ ]
233+ , mconcat
234+ [ plain "Homework"
235+ , orderedList [ plain ("Around" <> space <>
236+ "the" <> space <>
237+ "World")
238+ ]
239+ ]
240+ , mconcat
241+ [ plain ("Human" <> space <> "After" <> space <> "All")
242+ , orderedList [ plain "Technologic"
243+ , plain ("Robot" <> space <> "Rock")
244+ ]
245+ ]
246+ ]
247+
248+ , "Simple Ordered List" =:
249+ ("+ Item1\n" ++
250+ "+ Item2\n") =?>
251+ let listStyle = (1, DefaultStyle, DefaultDelim)
252+ listStructure = [ plain "Item1"
253+ , plain "Item2"
254+ ]
255+ in orderedListWith listStyle listStructure
256+
257+
258+ , "Indented Ordered List" =:
259+ (" + Item1\n" ++
260+ " + Item2\n") =?>
261+ let listStyle = (1, DefaultStyle, DefaultDelim)
262+ listStructure = [ plain "Item1"
263+ , plain "Item2"
264+ ]
265+ in orderedListWith listStyle listStructure
266+
267+ , "Nested Ordered Lists" =:
268+ ("+ One\n" ++
269+ " + One-One\n" ++
270+ " + One-Two\n" ++
271+ "+ Two\n" ++
272+ " + Two-One\n"++
273+ " + Two-Two\n") =?>
274+ let listStyle = (1, DefaultStyle, DefaultDelim)
275+ listStructure = [ mconcat
276+ [ plain "One"
277+ , orderedList [ plain "One-One"
278+ , plain "One-Two"
279+ ]
280+ ]
281+ , mconcat
282+ [ plain "Two"
283+ , orderedList [ plain "Two-One"
284+ , plain "Two-Two"
285+ ]
286+ ]
287+ ]
288+ in orderedListWith listStyle listStructure
289+
290+ , "Ordered List in Bullet List" =:
291+ ("- Emacs\n" ++
292+ " + Org\n") =?>
293+ bulletList [ (plain "Emacs") <>
294+ (orderedList [ plain "Org"])
295+ ]
296+
297+ , "Bullet List in Ordered List" =:
298+ ("+ GNU\n" ++
299+ " - Freedom\n") =?>
300+ orderedList [ (plain "GNU") <> bulletList [ (plain "Freedom") ] ]
301+
302+ , "Definition List" =:
303+ unlines [ ": PLL"
304+ , " phase-locked loop"
305+ , ": TTL"
306+ , " transistor-transistor logic"
307+ , ": PSK"
308+ , " a digital"
309+ ] =?>
310+ definitionList [ ("PLL", [ plain $ "phase-locked" <> space <> "loop" ])
311+ , ("TTL", [ plain $ "transistor-transistor" <> space <> "logic" ])
312+ , ("PSK", [ plain $ "a" <> space <> "digital" ])
313+ ]
314+
315+
316+ , "Loose bullet list" =:
317+ unlines [ "- apple"
318+ , ""
319+ , "- orange"
320+ , ""
321+ , "- peach"
322+ ] =?>
323+ bulletList [ para "apple"
324+ , para "orange"
325+ , para "peach"
326+ ]
327+ ]
328+
329+ , testGroup "Tables"
330+ [ "Single cell table" =:
331+ "| Test " =?>
332+ simpleTable' 1 mempty [[plain "Test"]]
333+
334+ , "Multi cell table" =:
335+ "| One | Two |" =?>
336+ simpleTable' 2 mempty [ [ plain "One", plain "Two" ] ]
337+
338+ , "Multi line table" =:
339+ unlines [ "| One |"
340+ , "| Two |"
341+ , "| Three |"
342+ ] =?>
343+ simpleTable' 1 mempty
344+ [ [ plain "One" ]
345+ , [ plain "Two" ]
346+ , [ plain "Three" ]
347+ ]
348+
349+ , "Empty table" =:
350+ "| |" =?>
351+ simpleTable' 1 mempty [[mempty]]
352+
353+ , "Glider Table" =:
354+ unlines [ "| 1 | 0 | 0 |"
355+ , "| 0 | 1 | 1 |"
356+ , "| 1 | 1 | 0 |"
357+ ] =?>
358+ simpleTable' 3 mempty
359+ [ [ plain "1", plain "0", plain "0" ]
360+ , [ plain "0", plain "1", plain "1" ]
361+ , [ plain "1", plain "1", plain "0" ]
362+ ]
363+
364+
365+ , "Table with Header" =:
366+ unlines [ "|| Species | Status |"
367+ , "| cervisiae | domesticated |"
368+ , "| paradoxus | wild |"
369+ ] =?>
370+ simpleTable [ plain "Species", plain "Status" ]
371+ [ [ plain "cervisiae", plain "domesticated" ]
372+ , [ plain "paradoxus", plain "wild" ]
373+ ]
374+
375+ , "Table alignment determined by spacing" =:
376+ unlines [ "| Numbers | Text | More |"
377+ , "| 1 | One | foo |"
378+ , "| 2 | Two | bar |"
379+ ] =?>
380+ table "" (zip [AlignCenter, AlignRight, AlignDefault] [0, 0, 0])
381+ []
382+ [ [ plain "Numbers", plain "Text", plain "More" ]
383+ , [ plain "1" , plain "One" , plain "foo" ]
384+ , [ plain "2" , plain "Two" , plain "bar" ]
385+ ]
386+
387+ , "Pipe within text doesn't start a table" =:
388+ "Ceci n'est pas une | pipe " =?>
389+ para (spcSep [ "Ceci", "n'est", "pas", "une", "|", "pipe" ])
390+
391+
392+ , "Table with differing row lengths" =:
393+ unlines [ "|| Numbers | Text "
394+ , "| 1 | One | foo |"
395+ , "| 2 "
396+ ] =?>
397+ table "" (zip [AlignCenter, AlignLeft, AlignLeft] [0, 0, 0])
398+ [ plain "Numbers", plain "Text" , plain mempty ]
399+ [ [ plain "1" , plain "One" , plain "foo" ]
400+ , [ plain "2" , plain mempty , plain mempty ]
401+ ]
402+
403+ ]
404+
405+ , testGroup "Blocks and fragments"
406+ [ "Source block" =:
407+ unlines [ "```"
408+ , "main = putStrLn greeting"
409+ , " where greeting = \"moin\""
410+ , "```" ] =?>
411+ let code' = "main = putStrLn greeting\n" ++
412+ " where greeting = \"moin\"\n"
413+ in codeBlock code'
414+
415+ , "tagged block" =:
416+ unlines [ "'''"
417+ , "<aside>HTML5 is pretty nice.</aside>"
418+ , "'''"
419+ ] =?>
420+ rawBlock "html" "<aside>HTML5 is pretty nice.</aside>\n"
421+
422+ , "Quote block" =:
423+ unlines ["\t//Niemand// hat die Absicht, eine Mauer zu errichten!"
424+ ] =?>
425+ blockQuote (para (spcSep [ emph "Niemand", "hat", "die", "Absicht,"
426+ , "eine", "Mauer", "zu", "errichten!"
427+ ]))
428+
429+ ]
430+ ]
tests/test-pandoc.hs+2−1
@@ -10,6 +10,7 @@ import qualified Tests.Readers.Markdown
1010import qualified Tests.Readers.Org
1111import qualified Tests.Readers.RST
1212import qualified Tests.Readers.Docx
13+import qualified Tests.Readers.Txt2Tags
1314import qualified Tests.Writers.ConTeXt
1415import qualified Tests.Writers.LaTeX
1516import qualified Tests.Writers.HTML
@@ -40,7 +41,7 @@ tests = [ testGroup "Old" Tests.Old.tests
4041 , testGroup "Org" Tests.Readers.Org.tests
4142 , testGroup "RST" Tests.Readers.RST.tests
4243 , testGroup "Docx" Tests.Readers.Docx.tests
43−
44+ , testGroup "Txt2Tags" Tests.Readers.Txt2Tags.tests
4445 ]
4546 ]
4647
tests/txt2tags.nativenew file+551
@@ -0,0 +1,551 @@
1+[Para [Str "This",Space,Str "document",Space,Str "describes",Space,Str "all",Space,Str "the",Space,Str "details",Space,Str "about",Space,Str "each",Space,Str "txt2tags",Space,Str "mark.",Space,Str "The",Space,Str "target",Space,Str "audience",Space,Str "are",Space,Strong [Str "experienced"],Space,Str "users.",Space,Str "You",Space,Str "may",Space,Str "find",Space,Str "it",Space,Str "useful",Space,Str "if",Space,Str "you",Space,Str "want",Space,Str "to",Space,Str "master",Space,Str "the",Space,Str "marks",Space,Str "or",Space,Str "solve",Space,Str "a",Space,Str "specific",Space,Str "problem",Space,Str "about",Space,Str "a",Space,Str "mark."]
2+,Para [Str "If",Space,Str "you",Space,Str "are",Space,Str "new",Space,Str "to",Space,Str "txt2tags",Space,Str "or",Space,Str "just",Space,Str "want",Space,Str "to",Space,Str "know",Space,Str "which",Space,Str "are",Space,Str "the",Space,Str "available",Space,Str "marks,",Space,Str "please",Space,Str "read",Space,Str "the",Space,Link [Str "Markup",Space,Str "Demo"] ("MARKUPDEMO",""),Str "."]
3+,Para [Str "Note",Space,Str "1:",Space,Str "This",Space,Str "document",Space,Str "is",Space,Str "generated",Space,Str "directly",Space,Str "from",Space,Str "the",Space,Str "txt2tags",Space,Str "test-suite.",Space,Str "All",Space,Str "the",Space,Str "rules",Space,Str "mentioned",Space,Str "here",Space,Str "are",Space,Str "100%",Space,Str "in",Space,Str "sync",Space,Str "with",Space,Str "the",Space,Str "current",Space,Str "program",Space,Str "code."]
4+,Para [Str "Note",Space,Str "2:",Space,Str "A",Space,Str "good",Space,Str "practice",Space,Str "is",Space,Str "to",Space,Str "consult",Space,Link [Str "the",Space,Str "sources"] ("rules.t2t",""),Space,Str "when",Space,Str "reading,",Space,Str "to",Space,Str "see",Space,Str "how",Space,Str "the",Space,Str "texts",Space,Str "were",Space,Str "made."]
5+,Para [Str "Table",Space,Str "of",Space,Str "Contents:"]
6+,HorizontalRule
7+,Header 1 ("paragraph",[],[]) [Str "Paragraph"]
8+,Para [Str "A",Space,Str "paragraph",Space,Str "is",Space,Str "composed",Space,Str "by",Space,Str "one",Space,Str "or",Space,Str "more",Space,Str "lines.",Space,Str "A",Space,Str "blank",Space,Str "line",Space,Str "(or",Space,Str "a",Space,Str "table,",Space,Str "or",Space,Str "a",Space,Str "list)",Space,Str "ends",Space,Str "the",Space,Str "current",Space,Str "paragraph."]
9+,Para [Str "Leading",Space,Str "and",Space,Str "trailing",Space,Str "spaces",Space,Str "are",Space,Str "ignored."]
10+,Para [Str "A",Space,Str "comment",Space,Str "line",Space,Str "can",Space,Str "be",Space,Str "placed",Space,Str "inside",Space,Str "a",Space,Str "paragraph.",Space,Str "It",Space,Str "will",Space,Str "not",Space,Str "affect",Space,Str "it."]
11+,Para [Str "The",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "file",Space,Str "(EOF)",Space,Str "closes",Space,Str "the",Space,Str "currently",Space,Str "open",Space,Str "paragraph."]
12+,Header 1 ("comment",[],[]) [Str "Comment"]
13+,Para [Str "%",Space,Str "not",Space,Str "on",Space,Str "the",Space,Str "line",Space,Str "beginning",Space,Str "(at",Space,Str "column",Space,Str "2)"]
14+,Para [Str "some",Space,Str "text",Space,Str "%",Space,Str "half",Space,Str "line",Space,Str "comments",Space,Str "are",Space,Str "not",Space,Str "allowed"]
15+,Header 1 ("line",[],[]) [Str "Line"]
16+,HorizontalRule
17+,HorizontalRule
18+,HorizontalRule
19+,HorizontalRule
20+,HorizontalRule
21+,HorizontalRule
22+,HorizontalRule
23+,HorizontalRule
24+,HorizontalRule
25+,HorizontalRule
26+,HorizontalRule
27+,Para [Strikeout [Str "-----"],Space,Strikeout [Str "-------",Space,Str "--------"]]
28+,Para [Strikeout [Str "-------+--------"]]
29+,Para [Str "(",Space,Strikeout [Str "----------------"],Space,Str ")"]
30+,Header 1 ("inline",[],[]) [Str "Inline"]
31+,Para [Str "i)",Space,Strong [Str "b"],Space,Emph [Str "i"],Space,Emph [Str "u"],Space,Strikeout [Str "s"],Space,Code ("",[],[]) "m",Space,Str "r",Space,RawInline (Format "html") "t",Space,Str "i)",Space,Strong [Str "bo"],Space,Emph [Str "it"],Space,Emph [Str "un"],Space,Strikeout [Str "st"],Space,Code ("",[],[]) "mo",Space,Str "ra",Space,RawInline (Format "html") "tg",Space,Str "i)",Space,Strong [Str "bold"],Space,Emph [Str "ital"],Space,Emph [Str "undr"],Space,Strikeout [Str "strk"],Space,Code ("",[],[]) "mono",Space,Str "raw",Space,RawInline (Format "html") "tggd",Space,Str "i)",Space,Strong [Str "bo",Space,Str "ld"],Space,Emph [Str "it",Space,Str "al"],Space,Emph [Str "un",Space,Str "dr"],Space,Strikeout [Str "st",Space,Str "rk"],Space,Code ("",[],[]) "mo no",Space,Str "r",Space,Str "aw",Space,RawInline (Format "html") "tg gd",Space,Str "i)",Space,Strong [Str "bo",Space,Str "*",Space,Str "ld"],Space,Emph [Str "it",Space,Str "/",Space,Str "al"],Space,Emph [Str "un",Space,Str "_",Space,Str "dr"],Space,Strikeout [Str "st",Space,Str "-",Space,Str "rk"],Space,Code ("",[],[]) "mo ` no",Space,Str "r",Space,Str "\"",Space,Str "aw",Space,RawInline (Format "html") "tg ' gd",Space,Str "i)",Space,Strong [Str "bo",Space,Str "**ld"],Space,Emph [Str "it",Space,Str "//al"],Space,Emph [Str "un",Space,Str "__dr"],Space,Strikeout [Str "st",Space,Str "--rk"],Space,Code ("",[],[]) "mo ``no",Space,Str "r",Space,Str "\"\"aw",Space,RawInline (Format "html") "tg ''gd",Space,Str "i)",Space,Strong [Str "bo",Space,Str "**",Space,Str "ld"],Space,Emph [Str "it",Space,Str "//",Space,Str "al"],Space,Emph [Str "un",Space,Str "__",Space,Str "dr"],Space,Strikeout [Str "st",Space,Str "--",Space,Str "rk"],Space,Code ("",[],[]) "mo `` no",Space,Str "r",Space,Str "\"\"",Space,Str "aw",Space,RawInline (Format "html") "tg '' gd",Space,Str "i)",Space,Strong [Str "**bold**"],Space,Emph [Str "//ital//"],Space,Emph [Str "__undr__"],Space,Strikeout [Str "--strk--"],Space,Code ("",[],[]) "``mono``",Space,Str "\"\"raw\"\"",Space,RawInline (Format "html") "''tggd''",Space,Str "i)",Space,Strong [Str "*bold*"],Space,Emph [Str "/ital/"],Space,Emph [Str "_undr_"],Space,Strikeout [Str "-strk-"],Space,Code ("",[],[]) "`mono`",Space,Str "\"raw\"",Space,RawInline (Format "html") "'tggd'"]
32+,Para [Str "i)",Space,Strong [Str "*"],Space,Emph [Str "/"],Space,Emph [Str "_"],Space,Strikeout [Str "-"],Space,Code ("",[],[]) "`",Space,Str "\"",Space,RawInline (Format "html") "'",Space,Str "i)",Space,Strong [Str "**"],Space,Emph [Str "//"],Space,Emph [Str "__"],Space,Strikeout [Str "--"],Space,Code ("",[],[]) "``",Space,Str "\"\"",Space,RawInline (Format "html") "''",Space,Str "i)",Space,Strong [Str "***"],Space,Emph [Str "///"],Space,Emph [Str "___"],Space,Strikeout [Str "---"],Space,Code ("",[],[]) "```",Space,Str "\"\"\"",Space,RawInline (Format "html") "'''",Space,Str "i)",Space,Strong [Str "****"],Space,Emph [Str "////"],Space,Emph [Str "____"],Space,Strikeout [Str "----"],Space,Code ("",[],[]) "````",Space,Str "\"\"\"\"",Space,RawInline (Format "html") "''''",Space,Str "i)",Space,Strong [Str "*****"],Space,Emph [Str "/////"],Space,Emph [Str "_____"],Space,Strikeout [Str "-----"],Space,Code ("",[],[]) "`````",Space,Str "\"\"\"\"\"",Space,RawInline (Format "html") "'''''",Space,Str "i)",Space,Strong [Str "******"],Space,Emph [Str "//////"],Space,Emph [Str "______"],Space,Strikeout [Str "------"],Space,Code ("",[],[]) "``````",Space,Str "\"\"\"\"\"\"",Space,RawInline (Format "html") "''''''"]
33+,Para [Str "i)",Space,Str "****",Space,Str "////",Space,Str "____",Space,Str "----",Space,Str "````",Space,Str "\"\"\"\"",Space,Str "''''",Space,Str "i)",Space,Str "**",Space,Str "**",Space,Str "//",Space,Str "//",Space,Str "__",Space,Str "__",Space,Str "--",Space,Str "--",Space,Str "``",Space,Str "``",Space,Str "\"\"",Space,Str "\"\"",Space,Str "''",Space,Str "''"]
34+,Para [Str "i)",Space,Str "**",Space,Str "bold**",Space,Str "//",Space,Str "ital//",Space,Str "__",Space,Str "undr__",Space,Str "--",Space,Str "strk--",Space,Str "``",Space,Str "mono``",Space,Str "\"\"",Space,Str "raw\"\"",Space,Str "''",Space,Str "tggd''",Space,Str "i)",Space,Str "**bold",Space,Str "**",Space,Str "//ital",Space,Str "//",Space,Str "__undr",Space,Str "__",Space,Str "--strk",Space,Str "--",Space,Str "``mono",Space,Str "``",Space,Str "\"\"raw",Space,Str "\"\"",Space,Str "''tggd",Space,Str "''",Space,Str "i)",Space,Str "**",Space,Str "bold",Space,Str "**",Space,Str "//",Space,Str "ital",Space,Str "//",Space,Str "__",Space,Str "undr",Space,Str "__",Space,Str "--",Space,Str "strk",Space,Str "--",Space,Str "``",Space,Str "mono",Space,Str "``",Space,Str "\"\"",Space,Str "raw",Space,Str "\"\"",Space,Str "''",Space,Str "tggd",Space,Str "''"]
35+,Header 1 ("link",[],[]) [Str "Link"]
36+,Para [Link [Str "mailto:user@domain.com"] ("user@domain.com",""),Space,Link [Str "mailto:user@domain.com"] ("user@domain.com",""),Str ".",Space,Link [Str "mailto:user@domain.com"] ("user@domain.com",""),Str ".",Space,Str "any",Space,Str "text.",Space,Str "any",Space,Str "text:",Space,Link [Str "mailto:user@domain.com"] ("user@domain.com",""),Str ".",Space,Str "any",Space,Str "text.",Space,Link [Str "label"] ("user@domain.com",""),Space,Link [Str "mailto:user@domain.com?subject=bla"] ("user@domain.com?subject=bla",""),Space,Link [Str "mailto:user@domain.com?subject=bla"] ("user@domain.com?subject=bla",""),Str ".",Space,Link [Str "mailto:user@domain.com?subject=bla"] ("user@domain.com?subject=bla",""),Str ",",Space,Link [Str "mailto:user@domain.com?subject=bla&cc=otheruser@domain.com"] ("user@domain.com?subject=bla&cc=otheruser@domain.com",""),Space,Link [Str "mailto:user@domain.com?subject=bla&cc=otheruser@domain.com"] ("user@domain.com?subject=bla&cc=otheruser@domain.com",""),Str ".",Space,Link [Str "mailto:user@domain.com?subject=bla&cc=otheruser@domain.com"] ("user@domain.com?subject=bla&cc=otheruser@domain.com",""),Str ",",Space,Link [Str "label"] ("user@domain.com?subject=bla&cc=otheruser@domain.com",""),Str ".",Space,Link [Str "label"] ("user@domain.com?subject=bla&cc=otheruser@domain.com.",""),Str ".",Space,Link [Str "http://www.domain.com"] ("http://www.domain.com",""),Space,Link [Str "http://www.domain.com/dir/"] ("http://www.domain.com/dir/",""),Space,Link [Str "http://www.domain.com/dir///"] ("http://www.domain.com/dir///",""),Space,Link [Str "http://www.domain.com."] ("http://www.domain.com.",""),Space,Link [Str "http://www.domain.com,"] ("http://www.domain.com,",""),Space,Link [Str "http://www.domain.com."] ("http://www.domain.com.",""),Space,Str "any",Space,Str "text.",Space,Link [Str "http://www.domain.com,"] ("http://www.domain.com,",""),Space,Str "any",Space,Str "text.",Space,Link [Str "http://www.domain.com/dir/."] ("http://www.domain.com/dir/.",""),Space,Str "any",Space,Str "text.",Space,Str "any",Space,Str "text:",Space,Link [Str "http://www.domain.com."] ("http://www.domain.com.",""),Space,Str "any",Space,Str "text.",Space,Str "any",Space,Str "text:",Space,Link [Str "http://www.domain.com/dir/."] ("http://www.domain.com/dir/.",""),Space,Str "any",Space,Str "text.",Space,Str "any",Space,Str "text:",Space,Link [Str "http://www.domain.com/dir/index.html."] ("http://www.domain.com/dir/index.html.",""),Space,Str "any",Space,Str "text.",Space,Str "any",Space,Str "text:",Space,Link [Str "http://www.domain.com/dir/index.html,"] ("http://www.domain.com/dir/index.html,",""),Space,Str "any",Space,Str "text.",Space,Link [Str "http://www.domain.com/dir/#anchor"] ("http://www.domain.com/dir/#anchor",""),Space,Link [Str "http://www.domain.com/dir/index.html#anchor"] ("http://www.domain.com/dir/index.html#anchor",""),Space,Link [Str "http://www.domain.com/dir/index.html#anchor."] ("http://www.domain.com/dir/index.html#anchor.",""),Space,Link [Str "http://www.domain.com/dir/#anchor."] ("http://www.domain.com/dir/#anchor.",""),Space,Str "any",Space,Str "text.",Space,Link [Str "http://www.domain.com/dir/index.html#anchor."] ("http://www.domain.com/dir/index.html#anchor.",""),Space,Str "any",Space,Str "text.",Space,Str "any",Space,Str "text:",Space,Link [Str "http://www.domain.com/dir/#anchor."] ("http://www.domain.com/dir/#anchor.",""),Space,Str "any",Space,Str "text.",Space,Str "any",Space,Str "text:",Space,Link [Str "http://www.domain.com/dir/index.html#anchor."] ("http://www.domain.com/dir/index.html#anchor.",""),Space,Str "any",Space,Str "text.",Space,Link [Str "http://domain.com?a=a@a.a&b=a+b+c."] ("http://domain.com?a=a@a.a&b=a+b+c.",""),Space,Link [Str "http://domain.com?a=a@a.a&b=a+b+c,"] ("http://domain.com?a=a@a.a&b=a+b+c,",""),Space,Link [Str "http://domain.com/bla.cgi?a=a@a.a&b=a+b+c."] ("http://domain.com/bla.cgi?a=a@a.a&b=a+b+c.",""),Space,Link [Str "http://domain.com/bla.cgi?a=a@a.a&b=a+b+c@."] ("http://domain.com/bla.cgi?a=a@a.a&b=a+b+c@.",""),Space,Link [Str "http://domain.com?a=a@a.a&b=a+b+c.#anchor"] ("http://domain.com?a=a@a.a&b=a+b+c.#anchor",""),Space,Link [Str "http://domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor"] ("http://domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor",""),Space,Link [Str "http://domain.com/bla.cgi?a=a@a.a&b=a+b+c@.#anchor"] ("http://domain.com/bla.cgi?a=a@a.a&b=a+b+c@.#anchor",""),Space,Link [Str "http://user:password@domain.com/bla.html."] ("http://user:password@domain.com/bla.html.",""),Space,Link [Str "http://user:password@domain.com/dir/."] ("http://user:password@domain.com/dir/.",""),Space,Link [Str "http://user:password@domain.com."] ("http://user:password@domain.com.",""),Space,Link [Str "http://user:@domain.com."] ("http://user:@domain.com.",""),Space,Link [Str "http://user@domain.com."] ("http://user@domain.com.",""),Space,Link [Str "http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor"] ("http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor",""),Space,Link [Str "http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c@#anchor"] ("http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c@#anchor",""),Space,Link [Str "label"] ("www.domain.com",""),Space,Str "[",Space,Str "label",Space,Link [Str "www.domain.com"] ("www.domain.com",""),Str "]",Space,Link [Str "label",Space] ("www.domain.com",""),Space,Link [Str "anchor",Space] ("http://www.domain.com/dir/index.html#anchor.",""),Space,Link [Str "login",Space] ("http://user:password@domain.com/bla.html",""),Space,Link [Str "form",Space] ("http://www.domain.com/bla.cgi?a=a@a.a&b=a+b+c.",""),Space,Link [Str "form",Space,Str "&",Space,Str "anchor"] ("http://www.domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor",""),Space,Link [Str "login",Space,Str "&",Space,Str "form",Space] ("http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.",""),Space,Link [Str "local",Space,Str "link",Space,Str "up",Space] ("..",""),Space,Link [Str "local",Space,Str "link",Space,Str "file",Space] ("bla.html",""),Space,Link [Str "local",Space,Str "link",Space,Str "anchor",Space] ("#anchor",""),Space,Link [Str "local",Space,Str "link",Space,Str "file/anchor"] ("bla.html#anchor",""),Space,Link [Str "local",Space,Str "link",Space,Str "file/anchor"] ("bla.html#anchor.",""),Space,Link [Str "local",Space,Str "link",Space,Str "img",Space] ("abc.gif",""),Space,Link [Str "www.fake.com"] ("www.domain.com",""),Space,Link [Str "http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm"] ("http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm",""),Space,Link [Str "http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-"] ("http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-",""),Space,Link [Str "http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_"] ("http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_",""),Str "-1%.",Space,Link [Str "http://foo._user-9:pass!#$%&*()+word@domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_"] ("http://foo._user-9:pass!#$%&*()+word@domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_",""),Str "-1%.",Space,Link [Str "http://L1.com"] ("http://L1.com",""),Space,Str "!",Space,Link [Str "mailto:L2@www.com"] ("L2@www.com",""),Space,Str "!",Space,Link [Str "L3"] ("www.com",""),Space,Str "!",Space,Link [Str "L4"] ("w@ww.com",""),Space,Str "!",Space,Link [Str "www.L5.com"] ("www.L5.com",""),Space,Link [Str "www.domain.com"] ("www.domain.com",""),Space,Link [Str "www2.domain.com"] ("www2.domain.com",""),Space,Link [Str "ftp.domain.com"] ("ftp.domain.com",""),Space,Link [Str "WWW.DOMAIN.COM"] ("WWW.DOMAIN.COM",""),Space,Link [Str "FTP.DOMAIN.COM"] ("FTP.DOMAIN.COM",""),Space,Link [Str "label"] ("www.domain.com",""),Space,Link [Str "label"] ("ftp.domain.com",""),Space,Link [Str "label"] ("WWW.DOMAIN.COM",""),Space,Link [Str "label"] ("FTP.DOMAIN.COM",""),Space,Str "[label",Space,Link [Str "www.domain.com"] ("www.domain.com",""),Space,Str "]",Space,Str "[label]",Space,Link [Str "www.domain.com"] ("www.domain.com",""),Str "]"]
37+,Header 1 ("image",[],[]) [Str "Image"]
38+,Para [Image [] ("img.png","")]
39+,Para [Link [Image [] ("img.png","")] ("http://txt2tags.org","")]
40+,Para [Image [] ("img.png",""),Space,Str "Image",Space,Str "at",Space,Str "the",Space,Str "line",Space,Str "beginning."]
41+,Para [Str "Image",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Image [] ("img.png",""),Space,Str "of",Space,Str "the",Space,Str "line."]
42+,Para [Str "Image",Space,Str "at",Space,Str "the",Space,Str "line",Space,Str "end.",Space,Image [] ("img.png","")]
43+,Para [Image [] ("img.png",""),Space,Image [] ("img.png",""),Space,Image [] ("img.png","")]
44+,Para [Image [] ("img.png",""),Image [] ("img.png","")]
45+,Para [Str "Images",Space,Image [] ("img.png",""),Space,Str "mixed",Space,Image [] ("img.png",""),Space,Str "with",Space,Image [] ("img.png",""),Space,Str "text."]
46+,Para [Str "Images",Space,Str "glued",Space,Str "together:",Space,Image [] ("img.png",""),Image [] ("img.png",""),Image [] ("img.png",""),Str "."]
47+,Para [Str "[img.png",Space,Str "]"]
48+,Para [Str "[",Space,Str "img.png]"]
49+,Para [Str "[",Space,Str "img.png",Space,Str "]"]
50+,Header 1 ("numtitle",[],[]) [Str "Numbered",Space,Str "Title"]
51+,Header 1 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "1"]
52+,Header 2 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "2"]
53+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
54+,Header 4 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "4"]
55+,Header 5 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "5"]
56+,Header 1 ("lab_el-1",[],[]) [Str "Title",Space,Str "Level",Space,Str "1"]
57+,Header 2 ("lab_el-2",[],[]) [Str "Title",Space,Str "Level",Space,Str "2"]
58+,Header 3 ("lab_el-3",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
59+,Header 4 ("lab_el-4",[],[]) [Str "Title",Space,Str "Level",Space,Str "4"]
60+,Header 5 ("lab_el-5",[],[]) [Str "Title",Space,Str "Level",Space,Str "5"]
61+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
62+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
63+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
64+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
65+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
66+,Header 3 ("lab_el-9",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
67+,Para [Str "+Not",Space,Str "Title"]
68+,Para [Str "++Not",Space,Str "Title+"]
69+,Para [Str "+++Not",Space,Str "Title++++",Space,Str "++++++Not",Space,Str "Title",Space,Str "6++++++"]
70+,Para [Str "+++++++Not",Space,Str "Title",Space,Str "7+++++++",Space,Str "+Not",Space,Str "Title+",Space,Str "[label1]",Space,Str "+Not",Space,Str "Title+[",Space,Str "label",Space,Str "]",Space,Str "+Not",Space,Str "Title+[la/bel]"]
71+,Header 1 ("title",[],[]) [Str "Title"]
72+,Header 1 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "1"]
73+,Header 2 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "2"]
74+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
75+,Header 4 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "4"]
76+,Header 5 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "5"]
77+,Header 1 ("lab_el-1",[],[]) [Str "Title",Space,Str "Level",Space,Str "1"]
78+,Header 2 ("lab_el-2",[],[]) [Str "Title",Space,Str "Level",Space,Str "2"]
79+,Header 3 ("lab_el-3",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
80+,Header 4 ("lab_el-4",[],[]) [Str "Title",Space,Str "Level",Space,Str "4"]
81+,Header 5 ("lab_el-5",[],[]) [Str "Title",Space,Str "Level",Space,Str "5"]
82+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
83+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
84+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
85+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
86+,Header 3 ("",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
87+,Header 3 ("lab_el-9",[],[]) [Str "Title",Space,Str "Level",Space,Str "3"]
88+,Para [Str "=Not",Space,Str "Title"]
89+,Para [Str "==Not",Space,Str "Title="]
90+,Para [Str "===Not",Space,Str "Title====",Space,Str "======Not",Space,Str "Title",Space,Str "6======"]
91+,Para [Str "=======Not",Space,Str "Title",Space,Str "7=======",Space,Str "=Not",Space,Str "Title=",Space,Str "[label1]",Space,Str "=Not",Space,Str "Title=[",Space,Str "label",Space,Str "]",Space,Str "=Not",Space,Str "Title=[la/bel]"]
92+,Header 1 ("quote",[],[]) [Str "Quote"]
93+,BlockQuote
94+ [Para [Str "To",Space,Str "quote",Space,Str "a",Space,Str "paragraph,",Space,Str "just",Space,Str "prefix",Space,Str "it",Space,Str "by",Space,Str "a",Space,Str "TAB",Space,Str "character.",Space,Str "All",Space,Str "the",Space,Str "lines",Space,Str "of",Space,Str "the",Space,Str "paragraph",Space,Str "must",Space,Str "begin",Space,Str "with",Space,Str "a",Space,Str "TAB."]]
95+,Para [Str "Any",Space,Str "non-tabbed",Space,Str "line",Space,Str "closes",Space,Str "the",Space,Str "quote",Space,Str "block."]
96+,BlockQuote
97+ [Para [Str "The",Space,Str "number",Space,Str "of",Space,Str "leading",Space,Str "TABs",Space,Str "identifies",Space,Str "the",Space,Str "quote",Space,Str "block",Space,Str "depth.",Space,Str "This",Space,Str "is",Space,Str "quote",Space,Str "level",Space,Str "1."]
98+ ,BlockQuote
99+ [Para [Str "With",Space,Str "two",Space,Str "TABs,",Space,Str "we",Space,Str "are",Space,Str "on",Space,Str "the",Space,Str "quote",Space,Str "level",Space,Str "2."]
100+ ,BlockQuote
101+ [Para [Str "The",Space,Str "more",Space,Str "TABs,",Space,Str "more",Space,Str "deep",Space,Str "is",Space,Str "the",Space,Str "quote",Space,Str "level."]
102+ ,BlockQuote
103+ [Para [Str "There",Space,Str "isn't",Space,Str "a",Space,Str "limit."]]]]]
104+,BlockQuote
105+ [BlockQuote
106+ [BlockQuote
107+ [BlockQuote
108+ [Para [Str "This",Space,Str "quote",Space,Str "starts",Space,Str "at",Space,Str "level",Space,Str "4."]]
109+ ,Para [Str "Then",Space,Str "its",Space,Str "depth",Space,Str "is",Space,Str "decreased."]]
110+ ,Para [Str "Counting",Space,Str "down,",Space,Str "one",Space,Str "by",Space,Str "one."]]
111+ ,Para [Str "Until",Space,Str "the",Space,Str "level",Space,Str "1."]]
112+,BlockQuote
113+ [BlockQuote
114+ [BlockQuote
115+ [Para [Str "Unlike",Space,Str "lists,",Space,Str "any",Space,Str "quote",Space,Str "block",Space,Str "is",Space,Str "independent,",Space,Str "not",Space,Str "part",Space,Str "of",Space,Str "a",Space,Str "tree."]]]
116+ ,Para [Str "The",Space,Str "TAB",Space,Str "count",Space,Str "don't",Space,Str "need",Space,Str "to",Space,Str "be",Space,Str "incremental",Space,Str "by",Space,Str "one."]
117+ ,BlockQuote
118+ [BlockQuote
119+ [BlockQuote
120+ [Para [Str "The",Space,Str "nesting",Space,Str "don't",Space,Str "need",Space,Str "to",Space,Str "follow",Space,Str "any",Space,Str "rule."]]]
121+ ,Para [Str "Quotes",Space,Str "can",Space,Str "be",Space,Str "opened",Space,Str "and",Space,Str "closed",Space,Str "in",Space,Str "any",Space,Str "way."]
122+ ,BlockQuote
123+ [BlockQuote
124+ [BlockQuote
125+ [Para [Str "You",Space,Str "choose."]]]]]]
126+,BlockQuote
127+ [Para [Str "Some",Space,Str "targets",Space,Str "(as",Space,Str "sgml)",Space,Str "don't",Space,Str "support",Space,Str "the",Space,Str "nesting",Space,Str "of",Space,Str "quotes.",Space,Str "There",Space,Str "is",Space,Str "only",Space,Str "one",Space,Str "quote",Space,Str "level."]
128+ ,BlockQuote
129+ [Para [Str "In",Space,Str "this",Space,Str "case,",Space,Str "no",Space,Str "matter",Space,Str "how",Space,Str "much",Space,Str "TABs",Space,Str "are",Space,Str "used",Space,Str "to",Space,Str "define",Space,Str "the",Space,Str "quote",Space,Str "block,",Space,Str "it",Space,Str "always",Space,Str "will",Space,Str "be",Space,Str "level",Space,Str "1."]]]
130+,BlockQuote
131+ [Para [Str "Spaces",Space,Str "AFTER",Space,Str "the",Space,Str "TAB",Space,Str "character",Space,Str "are",Space,Str "allowed.",Space,Str "But",Space,Str "be",Space,Str "careful,",Space,Str "it",Space,Str "can",Space,Str "be",Space,Str "confusing."]]
132+,Para [Str "Spaces",Space,Str "BEFORE",Space,Str "the",Space,Str "TAB",Space,Str "character",Space,Str "invalidate",Space,Str "the",Space,Str "mark.",Space,Str "It's",Space,Str "not",Space,Str "quote."]
133+,BlockQuote
134+ [Para [Str "Paragraph",Space,Str "breaks",Space,Str "inside",Space,Str "a",Space,Str "quote",Space,Str "aren't",Space,Str "possible."]
135+ ,Para [Str "This",Space,Str "sample",Space,Str "are",Space,Str "two",Space,Str "separated",Space,Str "quoted",Space,Str "paragraphs,",Space,Str "not",Space,Str "a",Space,Str "quote",Space,Str "block",Space,Str "with",Space,Str "two",Space,Str "paragraphs",Space,Str "inside."]]
136+,BlockQuote
137+ [Para [Str "The",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "file",Space,Str "(EOF)",Space,Str "closes",Space,Str "the",Space,Str "currently",Space,Str "open",Space,Str "quote",Space,Str "block."]]
138+,Header 1 ("raw",[],[]) [Str "Raw"]
139+,Para [Str "A raw line.\n"]
140+,Para [Str " Another raw line, with leading spaces.\n"]
141+,Para [Str "A raw area delimited\n by lines with marks.\n"]
142+,Para [Str "Trailing spaces and TABs after the area marks\nare allowed, but not encouraged nor documented.\n"]
143+,Para [Str "\"\"\"Not",Space,Str "a",Space,Str "raw",Space,Str "line,",Space,Str "need",Space,Str "one",Space,Str "space",Space,Str "after",Space,Str "mark."]
144+,Para [Str "\"\"\"",Space,Str "Not",Space,Str "a",Space,Str "raw",Space,Str "area.",Space,Str "The",Space,Str "marks",Space,Str "must",Space,Str "be",Space,Str "at",Space,Str "the",Space,Str "line",Space,Str "beginning,",Space,Str "no",Space,Str "leading",Space,Str "spaces.",Space,Str "\"\"\""]
145+,Para [Str "The end of the file (EOF) closes\nthe currently open raw area.\n"]
146+,Header 1 ("verbatim",[],[]) [Str "Verbatim"]
147+,CodeBlock ("",[],[]) "A verbatim line.\n"
148+,CodeBlock ("",[],[]) " Another verbatim line, with leading spaces.\n"
149+,CodeBlock ("",[],[]) "A verbatim area delimited\n by lines with marks.\n"
150+,CodeBlock ("",[],[]) "Trailing spaces and TABs after the area marks\nare allowed, but not encouraged nor documented.\n"
151+,Para [Str "```Not",Space,Str "a",Space,Str "verbatim",Space,Str "line,",Space,Str "need",Space,Str "one",Space,Str "space",Space,Str "after",Space,Str "mark."]
152+,Para [Str "```",Space,Str "Not",Space,Str "a",Space,Str "verbatim",Space,Str "area.",Space,Str "The",Space,Str "marks",Space,Str "must",Space,Str "be",Space,Str "at",Space,Str "the",Space,Str "line",Space,Str "beginning,",Space,Str "no",Space,Str "leading",Space,Str "spaces.",Space,Str "```"]
153+,CodeBlock ("",[],[]) "The end of the file (EOF) closes\nthe currently open verbatim area.\n"
154+,Header 1 ("deflist",[],[]) [Str "Definition",Space,Str "List"]
155+,DefinitionList
156+ [([Str "Definition",Space,Str "list"],
157+ [[Plain [Str "A",Space,Str "list",Space,Str "with",Space,Str "terms"]]])
158+ ,([Str "Start",Space,Str "term",Space,Str "with",Space,Str "colon"],
159+ [[Plain [Str "And",Space,Str "its",Space,Str "definition",Space,Str "follows"]]])]
160+,Header 1 ("numlist",[],[]) [Str "Numbered",Space,Str "List"]
161+,Para [Str "See",Space,Link [Str "List"] ("#list",""),Str ",",Space,Str "the",Space,Str "same",Space,Str "rules",Space,Str "apply."]
162+,Header 1 ("list",[],[]) [Str "List"]
163+,BulletList
164+ [[Plain [Str "Use",Space,Str "the",Space,Str "hyphen",Space,Str "to",Space,Str "prefix",Space,Str "list",Space,Str "items."]]
165+ ,[Plain [Str "There",Space,Str "must",Space,Str "be",Space,Str "one",Space,Str "space",Space,Str "after",Space,Str "the",Space,Str "hyphen."]]
166+ ,[Plain [Str "The",Space,Str "list",Space,Str "is",Space,Str "closed",Space,Str "by",Space,Str "two",Space,Str "consecutive",Space,Str "blank",Space,Str "lines."]]]
167+,BulletList
168+ [[Plain [Str "The",Space,Str "list",Space,Str "can",Space,Str "be",Space,Str "indented",Space,Str "on",Space,Str "the",Space,Str "source",Space,Str "document."]]
169+ ,[Plain [Str "You",Space,Str "can",Space,Str "use",Space,Str "any",Space,Str "number",Space,Str "of",Space,Str "spaces."]]
170+ ,[Plain [Str "The",Space,Str "result",Space,Str "will",Space,Str "be",Space,Str "the",Space,Str "same."]]]
171+,BulletList
172+ [[Para [Str "Let",Space,Str "one",Space,Str "blank",Space,Str "line",Space,Str "between",Space,Str "the",Space,Str "list",Space,Str "items."]]
173+ ,[Para [Str "It",Space,Str "will",Space,Str "be",Space,Str "maintained",Space,Str "on",Space,Str "the",Space,Str "conversion."]]
174+ ,[Para [Str "Some",Space,Str "targets",Space,Str "don't",Space,Str "support",Space,Str "this",Space,Str "behavior."]]
175+ ,[Para [Str "This",Space,Str "one",Space,Str "was",Space,Str "separated",Space,Str "by",Space,Str "a",Space,Str "line",Space,Str "with",Space,Str "blanks.",Space,Str "You",Space,Str "can",Space,Str "also",Space,Str "put",Space,Str "a",Space,Str "blank",Space,Str "line",Space,Str "inside"]
176+ ,Para [Str "the",Space,Str "item",Space,Str "contents",Space,Str "and",Space,Str "it",Space,Str "will",Space,Str "be",Space,Str "preserved."]]]
177+,Para [Str "-This",Space,Str "is",Space,Str "not",Space,Str "a",Space,Str "list",Space,Str "(no",Space,Str "space)"]
178+,Para [Str "-",Space,Str "This",Space,Str "is",Space,Str "not",Space,Str "a",Space,Str "list",Space,Str "(more",Space,Str "than",Space,Str "one",Space,Str "space)"]
179+,Para [Str "-",Space,Str "This",Space,Str "is",Space,Str "not",Space,Str "a",Space,Str "list",Space,Str "(a",Space,Str "TAB",Space,Str "instead",Space,Str "the",Space,Str "space)"]
180+,BulletList
181+ [[BulletList
182+ [[Plain [Str "This",Space,Str "is",Space,Str "a",Space,Str "list"]]]]
183+ ,[OrderedList (1,DefaultStyle,DefaultDelim)
184+ [[Plain [Str "This",Space,Str "is",Space,Str "a",Space,Str "list"]]]]
185+ ,[DefinitionList
186+ [([Str "This",Space,Str "is",Space,Str "a",Space,Str "list"],
187+ [[]])]]]
188+,BulletList
189+ [[Plain [Str "This",Space,Str "is",Space,Str "the",Space,Str "\"mother\"",Space,Str "list",Space,Str "first",Space,Str "item."]]
190+ ,[Plain [Str "Here",Space,Str "is",Space,Str "the",Space,Str "second,",Space,Str "but",Space,Str "inside",Space,Str "this",Space,Str "item,"]
191+ ,BulletList
192+ [[Plain [Str "there",Space,Str "is",Space,Str "a",Space,Str "sublist,",Space,Str "with",Space,Str "its",Space,Str "own",Space,Str "items."]]
193+ ,[Plain [Str "Note",Space,Str "that",Space,Str "the",Space,Str "items",Space,Str "of",Space,Str "the",Space,Str "same",Space,Str "sublist"]]
194+ ,[Plain [Str "must",Space,Str "have",Space,Str "the",Space,Str "same",Space,Str "indentation."]
195+ ,BulletList
196+ [[Plain [Str "And",Space,Str "this",Space,Str "can",Space,Str "go",Space,Str "on,",Space,Str "opening",Space,Str "sublists."]
197+ ,BulletList
198+ [[Plain [Str "Just",Space,Str "add",Space,Str "leading",Space,Str "spaces",Space,Str "before",Space,Str "the"]]
199+ ,[Plain [Str "hyphen",Space,Str "and",Space,Str "sublists",Space,Str "will",Space,Str "be",Space,Str "opened."]]
200+ ,[Plain [Str "The",Space,Str "two",Space,Str "blank",Space,Str "lines",Space,Str "closes",Space,Str "them",Space,Str "all."]]]]]]]]]
201+,BulletList
202+ [[Plain [Str "When",Space,Str "nesting",Space,Str "lists,",Space,Str "the",Space,Str "additional",Space,Str "spaces",Space,Str "are",Space,Str "free."]]
203+ ,[Plain [Str "You",Space,Str "can",Space,Str "add",Space,Str "just",Space,Str "one,"]
204+ ,BulletList
205+ [[Plain [Str "or",Space,Str "many."]
206+ ,BulletList
207+ [[Plain [Str "What",Space,Str "matters",Space,Str "is",Space,Str "to",Space,Str "put",Space,Str "more",Space,Str "than",Space,Str "the",Space,Str "previous."]]
208+ ,[Plain [Str "But",Space,Str "remember",Space,Str "that",Space,Str "the",Space,Str "other",Space,Str "items",Space,Str "of",Space,Str "the",Space,Str "same",Space,Str "list"]]
209+ ,[Plain [Str "must",Space,Str "use",Space,Str "the",Space,Str "same",Space,Str "indentation."]]]]]]]
210+,BulletList
211+ [[Plain [Str "There",Space,Str "is",Space,Str "not",Space,Str "a",Space,Str "depth",Space,Str "limit,"]
212+ ,BulletList
213+ [[Plain [Str "you",Space,Str "can",Space,Str "go",Space,Str "deeper",Space,Str "and",Space,Str "deeper."]
214+ ,BulletList
215+ [[Plain [Str "But",Space,Str "some",Space,Str "targets",Space,Str "may",Space,Str "have",Space,Str "restrictions."]
216+ ,BulletList
217+ [[Plain [Str "The",Space,Str "LaTeX",Space,Str "maximum",Space,Str "is",Space,Str "here,",Space,Str "4",Space,Str "levels."]]]]]]]]]
218+,BulletList
219+ [[Plain [Str "Reverse",Space,Str "nesting",Space,Str "doesn't",Space,Str "work."]]
220+ ,[Plain [Str "Because",Space,Str "a",Space,Str "sublist",Space,Str "*must*",Space,Str "have",Space,Str "a",Space,Str "mother",Space,Str "list."]]
221+ ,[Plain [Str "It's",Space,Str "the",Space,Str "list",Space,Str "concept,",Space,Str "not",Space,Str "a",Space,Str "txt2tags",Space,Str "limitation."]]
222+ ,[Plain [Str "All",Space,Str "this",Space,Str "sublists",Space,Str "will",Space,Str "be",Space,Str "bumped",Space,Str "to",Space,Str "mother",Space,Str "lists."]]
223+ ,[Plain [Str "At",Space,Str "level",Space,Str "1,",Space,Str "like",Space,Str "this",Space,Str "one."]]]
224+,BulletList
225+ [[Plain [Str "Level",Space,Str "1"]
226+ ,BulletList
227+ [[Plain [Str "Level",Space,Str "2"]
228+ ,BulletList
229+ [[Plain [Str "Level",Space,Str "3"]
230+ ,BulletList
231+ [[Plain [Str "Level",Space,Str "4"]]]]
232+ ,[Plain [Str "Level",Space,Str "3",Space,Str "--",Space,Str "(closed",Space,Str "Level",Space,Str "4)"]]]]
233+ ,[Plain [Str "Level",Space,Str "2",Space,Str "--",Space,Str "(closed",Space,Str "Level",Space,Str "3)"]]]]
234+ ,[Plain [Str "Level",Space,Str "1",Space,Str "--",Space,Str "(closed",Space,Str "Level",Space,Str "2)"]]]
235+,BulletList
236+ [[Plain [Str "Level",Space,Str "1"]
237+ ,BulletList
238+ [[Plain [Str "Level",Space,Str "2"]
239+ ,BulletList
240+ [[Plain [Str "Level",Space,Str "3"]
241+ ,BulletList
242+ [[Plain [Str "Level",Space,Str "4"]]]]]]]]
243+ ,[Plain [Str "Level",Space,Str "1",Space,Str "--",Space,Str "(closed",Space,Str "Level",Space,Str "4,",Space,Str "Level",Space,Str "3",Space,Str "and",Space,Str "Level",Space,Str "2)"]]]
244+,BulletList
245+ [[Para [Str "Level",Space,Str "1"]
246+ ,BulletList
247+ [[Para [Str "Level",Space,Str "2",Space,Str "--",Space,Str "blank",Space,Str "BEFORE",Space,Str "and",Space,Str "AFTER",Space,Str "(in)"]
248+ ,BulletList
249+ [[Plain [Str "Level",Space,Str "3"]]]]]]]
250+,BulletList
251+ [[Plain [Str "Level",Space,Str "4"]]]
252+,BulletList
253+ [[Para [Str "Level",Space,Str "3"]]
254+ ,[Para [Str "Level",Space,Str "2",Space,Str "--",Space,Str "blank",Space,Str "BEFORE",Space,Str "and",Space,Str "AFTER",Space,Str "(out)"]]
255+ ,[Para [Str "Level",Space,Str "1"]
256+ ,BulletList
257+ [[Para [Str "Level",Space,Str "2",Space,Str "--",Space,Str "blank",Space,Str "BEFORE",Space,Str "(spaces)",Space,Str "and",Space,Str "AFTER",Space,Str "(TAB)"]
258+ ,BulletList
259+ [[Plain [Str "Level",Space,Str "3"]]]]]]]
260+,BulletList
261+ [[Plain [Str "Level",Space,Str "1"]
262+ ,BulletList
263+ [[Plain [Str "Level",Space,Str "2"]
264+ ,BulletList
265+ [[Plain [Str "Level",Space,Str "3"]
266+ ,BulletList
267+ [[Plain [Str "Level",Space,Str "4"]]
268+ ,[Plain [Str "Level",Space,Str "3.5",Space,Str "???"]]]]
269+ ,[Plain [Str "Level",Space,Str "3"]]
270+ ,[Plain [Str "Level",Space,Str "2.5",Space,Str "???"]]]]
271+ ,[Plain [Str "Level",Space,Str "2"]]
272+ ,[Plain [Str "Level",Space,Str "1.5",Space,Str "???"]]]]
273+ ,[Plain [Str "Level",Space,Str "1"]]]
274+,BulletList
275+ [[Plain [Str "This",Space,Str "list",Space,Str "is",Space,Str "closed",Space,Str "by",Space,Str "a",Space,Str "line",Space,Str "with",Space,Str "spaces",Space,Str "and",Space,Str "other",Space,Str "with",Space,Str "TABs"]]]
276+,BulletList
277+ [[Plain [Str "This",Space,Str "list",Space,Str "is",Space,Str "NOT",Space,Str "closed",Space,Str "by",Space,Str "two",Space,Str "comment",Space,Str "lines"]]]
278+,BulletList
279+ [[Plain [Str "This",Space,Str "list",Space,Str "is",Space,Str "closed",Space,Str "by",Space,Str "a",Space,Str "line",Space,Str "with",Space,Str "spaces",Space,Str "and",Space,Str "TAB,"]]
280+ ,[Plain [Str "then",Space,Str "a",Space,Str "comment",Space,Str "line,",Space,Str "then",Space,Str "an",Space,Str "empty",Space,Str "line."]]]
281+,BulletList
282+ [[Plain [Str "Level",Space,Str "1"]
283+ ,BulletList
284+ [[Plain [Str "Level",Space,Str "2"]
285+ ,BulletList
286+ [[Plain [Str "Level",Space,Str "3"]]]
287+ ,Plain [Str "-",Space,Str "Level",Space,Str "2"]]]
288+ ,Plain [Str "-",Space,Str "Level",Space,Str "1"]]]
289+,Para [Str "-"]
290+,BulletList
291+ [[Plain [Str "Empty",Space,Str "item",Space,Str "with",Space,Str "trailing",Space,Str "spaces."]]]
292+,Para [Str "-"]
293+,BulletList
294+ [[Plain [Str "Empty",Space,Str "item",Space,Str "with",Space,Str "trailing",Space,Str "TAB."]]]
295+,Para [Str "-"]
296+,BulletList
297+ [[Plain [Str "If",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "file",Space,Str "(EOF)",Space,Str "is",Space,Str "hit,"]
298+ ,BulletList
299+ [[Plain [Str "all",Space,Str "the",Space,Str "currently",Space,Str "opened",Space,Str "list",Space,Str "are",Space,Str "closed,"]
300+ ,BulletList
301+ [[Plain [Str "just",Space,Str "like",Space,Str "when",Space,Str "using",Space,Str "the",Space,Str "two",Space,Str "blank",Space,Str "lines."]]]]]]]
302+,Header 1 ("table",[],[]) [Str "Table"]
303+,Table [] [AlignRight] [0.0]
304+ []
305+ [[[Plain [Str "Cell",Space,Str "1"]]]]
306+,Table [] [AlignCenter,AlignCenter,AlignRight] [0.0,0.0,0.0]
307+ []
308+ [[[Plain [Str "Cell",Space,Str "1"]]
309+ ,[Plain [Str "Cell",Space,Str "2"]]
310+ ,[Plain [Str "Cell",Space,Str "3"]]]]
311+,Table [] [AlignCenter,AlignCenter,AlignCenter] [0.0,0.0,0.0]
312+ []
313+ [[[Plain [Str "Cell",Space,Str "1"]]
314+ ,[Plain [Str "Cell",Space,Str "2"]]
315+ ,[Plain [Str "Cell",Space,Str "3"]]]]
316+,Para [Str "||",Space,Str "Cell",Space,Str "1",Space,Str "|",Space,Str "Cell",Space,Str "2",Space,Str "|",Space,Str "Cell",Space,Str "3",Space,Str "|"]
317+,Table [] [AlignCenter,AlignCenter,AlignCenter] [0.0,0.0,0.0]
318+ []
319+ [[[Plain [Str "Cell",Space,Str "1"]]
320+ ,[Plain [Str "Cell",Space,Str "2"]]
321+ ,[Plain [Str "Cell",Space,Str "3"]]]]
322+,Table [] [AlignDefault,AlignCenter,AlignDefault] [0.0,0.0,0.0]
323+ [[Plain [Str "Heading"]]
324+ ,[Plain [Str "Heading"]]
325+ ,[Plain [Str "Heading"]]]
326+ [[[Plain [Str "<-"]]
327+ ,[Plain [Str "--"]]
328+ ,[Plain [Str "->"]]]
329+ ,[[Plain [Str "--"]]
330+ ,[Plain [Str "--"]]
331+ ,[Plain [Str "--"]]]
332+ ,[[Plain [Str "->"]]
333+ ,[Plain [Str "--"]]
334+ ,[Plain [Str "<-"]]]]
335+,Table [] [AlignDefault,AlignDefault,AlignCenter,AlignCenter] [0.0,0.0,0.0,0.0]
336+ [[Plain [Str "1"]]
337+ ,[Plain [Str "2"]]
338+ ,[Plain [Str "3+4"]]
339+ ,[]]
340+ [[[Plain [Str "1"]]
341+ ,[Plain [Str "2"]]
342+ ,[Plain [Str "3"]]
343+ ,[Plain [Str "4"]]]
344+ ,[[Plain [Str "1+2+3"]]
345+ ,[Plain [Str "4"]]
346+ ,[]
347+ ,[]]
348+ ,[[Plain [Str "1"]]
349+ ,[Plain [Str "2+3"]]
350+ ,[Plain [Str "4"]]
351+ ,[]]
352+ ,[[Plain [Str "1+2+3+4"]]
353+ ,[]
354+ ,[]
355+ ,[]]]
356+,Table [] [AlignCenter,AlignCenter,AlignCenter,AlignCenter] [0.0,0.0,0.0,0.0]
357+ []
358+ [[[Plain [Str "0"]]
359+ ,[Plain [Str "1"]]
360+ ,[Plain [Str "2"]]
361+ ,[]]
362+ ,[[Plain [Str "4"]]
363+ ,[Plain [Str "5"]]
364+ ,[]
365+ ,[Plain [Str "7"]]]
366+ ,[[Plain [Str "8"]]
367+ ,[]
368+ ,[Plain [Str "A"]]
369+ ,[Plain [Str "B"]]]
370+ ,[[]
371+ ,[Plain [Str "D"]]
372+ ,[Plain [Str "E"]]
373+ ,[Plain [Str "F"]]]]
374+,Table [] [AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter] [0.0,0.0,0.0,0.0,0.0]
375+ []
376+ [[[Plain [Str "1"]]
377+ ,[]
378+ ,[]
379+ ,[]
380+ ,[]]
381+ ,[[Plain [Str "1"]]
382+ ,[Plain [Str "2"]]
383+ ,[]
384+ ,[]
385+ ,[]]
386+ ,[[Plain [Str "1"]]
387+ ,[Plain [Str "2"]]
388+ ,[Plain [Str "3"]]
389+ ,[]
390+ ,[]]
391+ ,[[Plain [Str "1"]]
392+ ,[Plain [Str "2"]]
393+ ,[Plain [Str "3"]]
394+ ,[Plain [Str "4"]]
395+ ,[]]
396+ ,[[Plain [Str "1"]]
397+ ,[Plain [Str "2"]]
398+ ,[Plain [Str "3"]]
399+ ,[Plain [Str "4"]]
400+ ,[Plain [Str "5"]]]]
401+,Table [] [AlignDefault,AlignCenter,AlignCenter,AlignCenter,AlignCenter] [0.0,0.0,0.0,0.0,0.0]
402+ []
403+ [[[Plain [Str "Jan"]]
404+ ,[]
405+ ,[]
406+ ,[]
407+ ,[]]
408+ ,[[Plain [Str "Fev"]]
409+ ,[]
410+ ,[]
411+ ,[]
412+ ,[]]
413+ ,[[Plain [Str "Mar"]]
414+ ,[]
415+ ,[]
416+ ,[]
417+ ,[]]
418+ ,[[Plain [Str "Apr"]]
419+ ,[]
420+ ,[]
421+ ,[]
422+ ,[]]
423+ ,[[Plain [Str "May"]]
424+ ,[]
425+ ,[]
426+ ,[]
427+ ,[]]
428+ ,[[Plain [Str "20%"]]
429+ ,[Plain [Str "40%"]]
430+ ,[Plain [Str "60%"]]
431+ ,[Plain [Str "80%"]]
432+ ,[Plain [Str "100%"]]]]
433+,Table [] [AlignCenter,AlignDefault,AlignDefault,AlignCenter,AlignCenter] [0.0,0.0,0.0,0.0,0.0]
434+ []
435+ [[[]
436+ ,[]
437+ ,[Plain [Str "/"]]
438+ ,[]
439+ ,[]]
440+ ,[[]
441+ ,[Plain [Str "/",Space,Str "/",Space,Str "/",Space,Str "/",Space,Str "/"]]
442+ ,[]
443+ ,[]
444+ ,[]]
445+ ,[[Plain [Str "/",Space,Str "/",Space,Str "/",Space,Str "/",Space,Str "/",Space,Str "/",Space,Str "/",Space,Str "/",Space,Str "/"]]
446+ ,[]
447+ ,[]
448+ ,[]
449+ ,[]]
450+ ,[[]
451+ ,[Plain [Str "o"]]
452+ ,[]
453+ ,[Plain [Str "o"]]
454+ ,[]]
455+ ,[[]
456+ ,[]
457+ ,[Plain [Str "."]]
458+ ,[]
459+ ,[]]
460+ ,[[]
461+ ,[Plain [Str "=",Space,Str "=",Space,Str "=",Space,Str "="]]
462+ ,[]
463+ ,[]
464+ ,[]]]
465+,Table [] [AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter] [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
466+ []
467+ [[[Plain [Str "01"]]
468+ ,[Plain [Str "02"]]
469+ ,[]
470+ ,[]
471+ ,[Plain [Str "05"]]
472+ ,[]
473+ ,[Plain [Str "07"]]
474+ ,[]]
475+ ,[[]
476+ ,[]
477+ ,[Plain [Str "11"]]
478+ ,[]
479+ ,[Plain [Str "13"]]
480+ ,[]
481+ ,[]
482+ ,[Plain [Str "16"]]]
483+ ,[[Plain [Str "17"]]
484+ ,[]
485+ ,[Plain [Str "19"]]
486+ ,[Plain [Str "20"]]
487+ ,[]
488+ ,[]
489+ ,[Plain [Str "23"]]
490+ ,[]]
491+ ,[[Plain [Str "25"]]
492+ ,[Plain [Str "26"]]
493+ ,[]
494+ ,[]
495+ ,[Plain [Str "29"]]
496+ ,[Plain [Str "30"]]
497+ ,[]
498+ ,[Plain [Str "32"]]]
499+ ,[[]
500+ ,[]
501+ ,[Plain [Str "35"]]
502+ ,[]
503+ ,[Plain [Str "37"]]
504+ ,[]
505+ ,[Plain [Str "39"]]
506+ ,[Plain [Str "40"]]]]
507+,Table [] [AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter,AlignCenter] [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
508+ []
509+ [[[Plain [Str "0"]]
510+ ,[Plain [Str "1"]]
511+ ,[Plain [Str "2"]]
512+ ,[Plain [Str "3"]]
513+ ,[Plain [Str "4"]]
514+ ,[Plain [Str "5"]]
515+ ,[Plain [Str "6"]]
516+ ,[Plain [Str "7"]]
517+ ,[Plain [Str "8"]]
518+ ,[Plain [Str "9"]]
519+ ,[Plain [Str "A"]]
520+ ,[Plain [Str "B"]]
521+ ,[Plain [Str "C"]]
522+ ,[Plain [Str "D"]]
523+ ,[Plain [Str "E"]]
524+ ,[Plain [Str "F"]]
525+ ,[Plain [Str "0"]]
526+ ,[Plain [Str "1"]]
527+ ,[Plain [Str "2"]]
528+ ,[Plain [Str "3"]]
529+ ,[Plain [Str "4"]]
530+ ,[Plain [Str "5"]]
531+ ,[Plain [Str "6"]]
532+ ,[Plain [Str "7"]]
533+ ,[Plain [Str "8"]]
534+ ,[Plain [Str "9"]]
535+ ,[Plain [Str "A"]]
536+ ,[Plain [Str "B"]]
537+ ,[Plain [Str "C"]]
538+ ,[Plain [Str "D"]]
539+ ,[Plain [Str "E"]]
540+ ,[Plain [Str "F"]]]]
541+,Table [] [AlignCenter] [0.0]
542+ []
543+ [[[]]
544+ ,[[]]
545+ ,[[]]]
546+,Para [Str "|this|is|not|a|table|"]
547+,Para [Str "|this|",Space,Str "is|",Space,Str "not|",Space,Str "a|",Space,Str "table|"]
548+,Para [Str "|this",Space,Str "|is",Space,Str "|not",Space,Str "|a",Space,Str "|table",Space,Str "|"]
549+,Para [Str "|",Space,Str "this\t|",Space,Str "is\t|",Space,Str "not\t|",Space,Str "a\t|",Space,Str "table\t|"]
550+,HorizontalRule
551+,Para [Str "The",Space,Str "End."]]
tests/txt2tags.t2tnew file+797
@@ -0,0 +1,797 @@
1+Txt2tags Markup Rules
2+
3+
4+%!includeconf: rules.conf
5+
6+This document describes all the details about each txt2tags mark.
7+The target audience are **experienced** users. You may find it
8+useful if you want to master the marks or solve a specific problem
9+about a mark.
10+
11+If you are new to txt2tags or just want to know which are the
12+available marks, please read the [Markup Demo MARKUPDEMO].
13+
14+Note 1: This document is generated directly from the txt2tags
15+test-suite. All the rules mentioned here are 100% in sync with the
16+current program code.
17+
18+Note 2: A good practice is to consult [the sources rules.t2t] when
19+reading, to see how the texts were made.
20+
21+Table of Contents:
22+
23+%%TOC
24+
25+-------------------------------------------------------------
26+
27+= Paragraph =[paragraph]
28+
29+%INCLUDED(t2t) starts here: ../../../test/marks/paragraph.t2t
30+
31+
32+%%% Syntax: Lines grouped together
33+A paragraph is composed by one or more lines.
34+A blank line (or a table, or a list) ends the
35+current paragraph.
36+
37+%%% Syntax: Leading and trailing spaces are ignored
38+ Leading and trailing spaces are ignored.
39+
40+%%% Syntax: A comment don't close a paragraph
41+A comment line can be placed inside a paragraph.
42+% this comment will be ignored
43+It will not affect it.
44+
45+%%% Closing: EOF closes the open paragraph
46+The end of the file (EOF) closes the
47+currently open paragraph.
48+
49+= Comment =[comment]
50+
51+%INCLUDED(t2t) starts here: ../../../test/marks/comment.t2t
52+
53+
54+%%% Syntax: The % character at the line beginning (column 1)
55+%glued with the % mark
56+% separated from the % mark
57+% very distant from the % mark
58+%%%%%%% lots of % marks
59+% a blank comment, used for vertical spacing:
60+%
61+% NOTE: what matters is the first % being at the line beginning,
62+% the rest of the line is just ignored.
63+
64+%%% Syntax: Area (block)
65+%%%
66+You're not seeing this.
67+%%%
68+
69+%%% Syntax: Area (block) with trailing spaces
70+%%%
71+You're not seeing this.
72+%%%
73+
74+%%% Invalid: The % in any other position
75+ % not on the line beginning (at column 2)
76+
77+some text % half line comments are not allowed
78+
79+
80+= Line =[line]
81+
82+%INCLUDED(t2t) starts here: ../../../test/marks/line.t2t
83+
84+
85+%%% Syntax: At least 20 chars of - = _
86+--------------------
87+====================
88+____________________
89+%%% Syntax: Any kind of mixing is allowed
90+%% Free mixing is allowed to make the line,
91+%% but the first char is the identifier for
92+%% the difference between separator ( - _ )
93+%% and strong ( = ) lines.
94+=========-----------
95+-_-_-_-_-_-_-_-_-_-_
96+=-=-=-=-=-=-=-=-=-=-
97+=------------------=
98+--------====--------
99+%%% Syntax: Leading and/or trailing spaces are allowed
100+ --------------------
101+--------------------
102+ --------------------
103+%%% Invalid: Less than 20 chars (but strike matches)
104+---------
105+%%% Invalid: Strange chars (but strike matches)
106+--------- ----------
107+
108+---------+----------
109+
110+( -------------------- )
111+
112+= Inline =[inline]
113+
114+%INCLUDED(t2t) starts here: ../../../test/marks/inline.t2t
115+
116+
117+%%% Syntax: Marks are greedy and must be "glued" with contents
118+%% GLUED: The contents must be glued with the marks, no spaces
119+%% between them. Right after the opening mark there must be a
120+%% non-blank character, as well as right before the closing mark.
121+%%
122+%% GREEDY: If the contents boundary character is the same as
123+%% the mark character, it is considered contents, not mark.
124+%% So ""****bold****"" turns to ""<B>**bold**</B>"" in HTML.
125+
126+i) **b** //i// __u__ --s-- ``m`` ""r"" ''t''
127+i) **bo** //it// __un__ --st-- ``mo`` ""ra"" ''tg''
128+i) **bold** //ital// __undr__ --strk-- ``mono`` ""raw"" ''tggd''
129+i) **bo ld** //it al// __un dr__ --st rk-- ``mo no`` ""r aw"" ''tg gd''
130+i) **bo * ld** //it / al// __un _ dr__ --st - rk-- ``mo ` no`` ""r " aw"" ''tg ' gd''
131+i) **bo **ld** //it //al// __un __dr__ --st --rk-- ``mo ``no`` ""r ""aw"" ''tg ''gd''
132+i) **bo ** ld** //it // al// __un __ dr__ --st -- rk-- ``mo `` no`` ""r "" aw"" ''tg '' gd''
133+i) ****bold**** ////ital//// ____undr____ ----strk---- ````mono```` """"raw"""" ''''tggd''''
134+i) ***bold*** ///ital/// ___undr___ ---strk--- ```mono``` """raw""" '''tggd'''
135+
136+%%% Syntax: Repetition is greedy
137+%% When the mark character is repeated many times,
138+%% the contents are expanded to the largest possible.
139+%% Thats why they are greedy, the outer marks are
140+%% the ones used.
141+
142+i) ***** ///// _____ ----- ````` """"" '''''
143+i) ****** ////// ______ ------ `````` """""" ''''''
144+i) ******* /////// _______ ------- ``````` """"""" '''''''
145+i) ******** //////// ________ -------- ```````` """""""" ''''''''
146+i) ********* ///////// _________ --------- ````````` """"""""" '''''''''
147+i) ********** ////////// __________ ---------- `````````` """""""""" ''''''''''
148+
149+%%% Invalid: No contents
150+
151+i) **** //// ____ ---- ```` """" ''''
152+i) ** ** // // __ __ -- -- `` `` "" "" '' ''
153+
154+%%% Invalid: Contents not "glued" with marks
155+%% Spaces between the marks and the contents in any side
156+%% invalidate the mark.
157+
158+i) ** bold** // ital// __ undr__ -- strk-- `` mono`` "" raw"" '' tggd''
159+i) **bold ** //ital // __undr __ --strk -- ``mono `` ""raw "" ''tggd ''
160+i) ** bold ** // ital // __ undr __ -- strk -- `` mono `` "" raw "" '' tggd ''
161+
162+= Link =[link]
163+
164+%INCLUDED(t2t) starts here: ../../../test/marks/link.t2t
165+
166+
167+%%% Syntax: E-mail
168+user@domain.com
169+user@domain.com.
170+user@domain.com. any text.
171+any text: user@domain.com. any text.
172+[label user@domain.com]
173+%%% Syntax: E-mail with form data
174+user@domain.com?subject=bla
175+user@domain.com?subject=bla.
176+user@domain.com?subject=bla,
177+user@domain.com?subject=bla&cc=otheruser@domain.com
178+user@domain.com?subject=bla&cc=otheruser@domain.com.
179+user@domain.com?subject=bla&cc=otheruser@domain.com,
180+[label user@domain.com?subject=bla&cc=otheruser@domain.com].
181+[label user@domain.com?subject=bla&cc=otheruser@domain.com.].
182+%%% Syntax: URL
183+http://www.domain.com
184+http://www.domain.com/dir/
185+http://www.domain.com/dir///
186+http://www.domain.com.
187+http://www.domain.com,
188+http://www.domain.com. any text.
189+http://www.domain.com, any text.
190+http://www.domain.com/dir/. any text.
191+any text: http://www.domain.com. any text.
192+any text: http://www.domain.com/dir/. any text.
193+any text: http://www.domain.com/dir/index.html. any text.
194+any text: http://www.domain.com/dir/index.html, any text.
195+%%% Syntax: URL with anchor
196+http://www.domain.com/dir/#anchor
197+http://www.domain.com/dir/index.html#anchor
198+http://www.domain.com/dir/index.html#anchor.
199+http://www.domain.com/dir/#anchor. any text.
200+http://www.domain.com/dir/index.html#anchor. any text.
201+any text: http://www.domain.com/dir/#anchor. any text.
202+any text: http://www.domain.com/dir/index.html#anchor. any text.
203+%%% Syntax: URL with form data
204+http://domain.com?a=a@a.a&b=a+b+c.
205+http://domain.com?a=a@a.a&b=a+b+c,
206+http://domain.com/bla.cgi?a=a@a.a&b=a+b+c.
207+http://domain.com/bla.cgi?a=a@a.a&b=a+b+c@.
208+%%% Syntax: URL with form data and anchor
209+http://domain.com?a=a@a.a&b=a+b+c.#anchor
210+http://domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor
211+http://domain.com/bla.cgi?a=a@a.a&b=a+b+c@.#anchor
212+%%% Syntax: URL with login data
213+http://user:password@domain.com/bla.html.
214+http://user:password@domain.com/dir/.
215+http://user:password@domain.com.
216+http://user:@domain.com.
217+http://user@domain.com.
218+%%% Syntax: URL with login, form and anchor
219+http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor
220+http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c@#anchor
221+%%% Syntax: URL with label
222+[label www.domain.com]
223+%%% Syntax: URL with label (trailing spaces are discarded, leading are maintained)
224+%TODO normalize this behavior
225+[ label www.domain.com]
226+[label www.domain.com]
227+%%% Syntax: URL with label, stressing
228+[anchor http://www.domain.com/dir/index.html#anchor.]
229+[login http://user:password@domain.com/bla.html]
230+[form http://www.domain.com/bla.cgi?a=a@a.a&b=a+b+c.]
231+[form & anchor http://www.domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor]
232+[login & form http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.]
233+%%% Syntax: Link with label for local files
234+[local link up ..]
235+[local link file bla.html]
236+[local link anchor #anchor]
237+[local link file/anchor bla.html#anchor]
238+[local link file/anchor bla.html#anchor.]
239+[local link img abc.gif]
240+%%% Syntax: Another link as a label
241+[www.fake.com www.domain.com]
242+%%% Syntax: URL with funny chars
243+http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm
244+http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-
245+http://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_-1%.
246+http://foo._user-9:pass!#$%&*()+word@domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_-1%.
247+%%% Test: Various per line
248+http://L1.com ! L2@www.com ! [L3 www.com] ! [L4 w@ww.com] ! www.L5.com
249+%%% Feature: Guessed link, adding protocol automatically
250+www.domain.com
251+www2.domain.com
252+ftp.domain.com
253+WWW.DOMAIN.COM
254+FTP.DOMAIN.COM
255+[label www.domain.com]
256+[label ftp.domain.com]
257+[label WWW.DOMAIN.COM]
258+[label FTP.DOMAIN.COM]
259+%%% Invalid: Trailing space on link
260+[label www.domain.com ]
261+%%% Invalid: Label with ] char (use postproc)
262+[label] www.domain.com]
263+
264+= Image =[image]
265+
266+%INCLUDED(t2t) starts here: ../../../test/marks/image.t2t
267+
268+
269+%%% Syntax: Image name inside brackets: [img]
270+[img.png]
271+
272+%%% Syntax: Image pointing to a link: [[img] link]
273+[[img.png] http://txt2tags.org]
274+
275+%%% Align: Image position is preserved when inside paragraph
276+[img.png] Image at the line beginning.
277+
278+Image in the middle [img.png] of the line.
279+
280+Image at the line end. [img.png]
281+
282+%%% Align: Image alone with spaces around is aligned
283+[img.png]
284+ [img.png]
285+ [img.png]
286+
287+%%% Test: Two glued images with no spaces (left & right)
288+[img.png][img.png]
289+
290+%%% Test: Various per line
291+Images [img.png] mixed [img.png] with [img.png] text.
292+
293+Images glued together: [img.png][img.png][img.png].
294+
295+%%% Invalid: Spaces inside are not allowed
296+[img.png ]
297+
298+[ img.png]
299+
300+[ img.png ]
301+
302+% Ignored as they change every time when run
303+
304+= Numbered Title =[numtitle]
305+
306+%%% Syntax: Balanced equal signs (from 1 to 5)
307++ Title Level 1 +
308+++ Title Level 2 ++
309++++ Title Level 3 +++
310+++++ Title Level 4 ++++
311++++++ Title Level 5 +++++
312+%%% Label: Between brackets, alphanumeric [A-Za-z0-9_-]
313++ Title Level 1 +[lab_el-1]
314+++ Title Level 2 ++[lab_el-2]
315++++ Title Level 3 +++[lab_el-3]
316+++++ Title Level 4 ++++[lab_el-4]
317++++++ Title Level 5 +++++[lab_el-5]
318+%%% Syntax: Spaces around and/or inside are allowed (and ignored)
319+ +++Title Level 3+++
320+ +++ Title Level 3 +++
321+ +++ Title Level 3 +++
322++++ Title Level 3 +++
323++++ Title Level 3 +++
324+ +++ Title Level 3 +++[lab_el-9]
325+%%% Invalid: Unbalanced equal signs
326+ +Not Title
327+
328+ ++Not Title+
329+
330+ +++Not Title++++
331+%%% Invalid: Level deeper than 5
332+ ++++++Not Title 6++++++
333+
334++++++++Not Title 7+++++++
335+%%% Invalid: Space between title and label
336++Not Title+ [label1]
337+%%% Invalid: Space inside label
338++Not Title+[ label ]
339+%%% Invalid: Strange chars inside label
340++Not Title+[la/bel]
341+
342+= Title =[title]
343+
344+%INCLUDED(t2t) starts here: ../../../test/marks/title.t2t
345+
346+
347+%%% Syntax: Balanced equal signs (from 1 to 5)
348+= Title Level 1 =
349+== Title Level 2 ==
350+=== Title Level 3 ===
351+==== Title Level 4 ====
352+===== Title Level 5 =====
353+%%% Label: Between brackets, alphanumeric [A-Za-z0-9_-]
354+= Title Level 1 =[lab_el-1]
355+== Title Level 2 ==[lab_el-2]
356+=== Title Level 3 ===[lab_el-3]
357+==== Title Level 4 ====[lab_el-4]
358+===== Title Level 5 =====[lab_el-5]
359+%%% Syntax: Spaces around and/or inside are allowed (and ignored)
360+ ===Title Level 3===
361+ === Title Level 3 ===
362+ === Title Level 3 ===
363+=== Title Level 3 ===
364+=== Title Level 3 ===
365+ === Title Level 3 ===[lab_el-9]
366+%%% Invalid: Unbalanced equal signs
367+ =Not Title
368+
369+ ==Not Title=
370+
371+ ===Not Title====
372+%%% Invalid: Level deeper than 5
373+ ======Not Title 6======
374+
375+=======Not Title 7=======
376+%%% Invalid: Space between title and label
377+=Not Title= [label1]
378+%%% Invalid: Space inside label
379+=Not Title=[ label ]
380+%%% Invalid: Strange chars inside label
381+=Not Title=[la/bel]
382+
383+= Quote =[quote]
384+
385+%INCLUDED(t2t) starts here: ../../../test/marks/quote.t2t
386+
387+
388+ To quote a paragraph, just prefix it by a TAB
389+ character. All the lines of the paragraph must
390+ begin with a TAB.
391+Any non-tabbed line closes the quote block.
392+
393+%%% Nesting: Creating deeper quotes
394+ The number of leading TABs identifies the quote
395+ block depth. This is quote level 1.
396+ With two TABs, we are on the quote
397+ level 2.
398+ The more TABs, more deep is
399+ the quote level.
400+ There isn't a limit.
401+
402+%%% Nesting: Reverse nesting works
403+ This quote starts at
404+ level 4.
405+ Then its depth is decreased.
406+ Counting down, one by one.
407+ Until the level 1.
408+
409+%%% Nesting: Random count
410+ Unlike lists, any quote block is
411+ independent, not part of a tree.
412+ The TAB count don't need to be incremental
413+ by one.
414+ The nesting don't need
415+ to follow any rule.
416+ Quotes can be opened and closed
417+ in any way.
418+ You choose.
419+
420+%%% Nesting: When not supported
421+ Some targets (as sgml) don't support the
422+ nesting of quotes. There is only one quote
423+ level.
424+ In this case, no matter how much
425+ TABs are used to define the quote
426+ block, it always will be level 1.
427+
428+%%% Syntax: Spaces after TAB
429+ Spaces AFTER the TAB character are allowed.
430+ But be careful, it can be confusing.
431+
432+%%% Invalid: Spaces before TAB
433+ Spaces BEFORE the TAB character
434+ invalidate the mark. It's not quote.
435+
436+%%% Invalid: Paragraphs inside
437+ Paragraph breaks inside a quote aren't
438+ possible.
439+
440+ This sample are two separated quoted
441+ paragraphs, not a quote block with
442+ two paragraphs inside.
443+
444+%%% Closing: EOF closes the open block
445+ The end of the file (EOF) closes the
446+ currently open quote block.
447+
448+= Raw =[raw]
449+
450+%%% Syntax: A single line
451+""" A raw line.
452+
453+%%% Syntax: A single line with leading spaces
454+""" Another raw line, with leading spaces.
455+
456+%%% Syntax: Area (block)
457+"""
458+A raw area delimited
459+ by lines with marks.
460+"""
461+
462+%%% Syntax: Area (block) with trailing spaces
463+"""
464+Trailing spaces and TABs after the area marks
465+are allowed, but not encouraged nor documented.
466+"""
467+
468+%%% Invalid: No space between mark and contents
469+"""Not a raw line, need one space after mark.
470+
471+%%% Invalid: Leading spaces on block marks
472+ """
473+ Not a raw area.
474+ The marks must be at the line beginning,
475+ no leading spaces.
476+ """
477+
478+%%% Closing: EOF closes the open block
479+"""
480+The end of the file (EOF) closes
481+the currently open raw area.
482+"""
483+
484+= Verbatim =[verbatim]
485+
486+%INCLUDED(t2t) starts here: ../../../test/marks/verbatim.t2t
487+
488+
489+%%% Syntax: A single line
490+``` A verbatim line.
491+
492+%%% Syntax: A single line with leading spaces
493+``` Another verbatim line, with leading spaces.
494+
495+%%% Syntax: Area (block)
496+```
497+A verbatim area delimited
498+ by lines with marks.
499+```
500+
501+%%% Syntax: Area (block) with trailing spaces
502+```
503+Trailing spaces and TABs after the area marks
504+are allowed, but not encouraged nor documented.
505+```
506+
507+%%% Invalid: No space between mark and contents
508+```Not a verbatim line, need one space after mark.
509+
510+%%% Invalid: Leading spaces on block marks
511+ ```
512+ Not a verbatim area.
513+ The marks must be at the line beginning,
514+ no leading spaces.
515+ ```
516+
517+%%% Closing: EOF closes the open block
518+```
519+The end of the file (EOF) closes
520+the currently open verbatim area.
521+```
522+
523+= Definition List =[deflist]
524+
525+: Definition list
526+ A list with terms
527+: Start term with colon
528+ And its definition follows
529+
530+
531+= Numbered List =[numlist]
532+
533+See [List #list], the same rules apply.
534+
535+= List =[list]
536+
537+%INCLUDED(t2t) starts here: ../../../test/marks/list.t2t
538+
539+
540+%%% Items: Prefixed by hyphen
541+- Use the hyphen to prefix list items.
542+- There must be one space after the hyphen.
543+- The list is closed by two consecutive blank lines.
544+
545+
546+%%% Items: Free leading spacing (indentation)
547+ - The list can be indented on the source document.
548+ - You can use any number of spaces.
549+ - The result will be the same.
550+
551+
552+%%% Items: Vertical spacing between items
553+- Let one blank line between the list items.
554+
555+- It will be maintained on the conversion.
556+
557+- Some targets don't support this behavior.
558+
559+- This one was separated by a line with blanks.
560+ You can also put a blank line inside
561+
562+ the item contents and it will be preserved.
563+
564+
565+%%% Items: Exactly ONE space after the hyphen
566+-This is not a list (no space)
567+
568+- This is not a list (more than one space)
569+
570+- This is not a list (a TAB instead the space)
571+
572+
573+%%% Items: Catchy cases
574+- - This is a list
575+- + This is a list
576+- : This is a list
577+
578+
579+%%% Nesting: Creating sublists
580+- This is the "mother" list first item.
581+- Here is the second, but inside this item,
582+ - there is a sublist, with its own items.
583+ - Note that the items of the same sublist
584+ - must have the same indentation.
585+ - And this can go on, opening sublists.
586+ - Just add leading spaces before the
587+ - hyphen and sublists will be opened.
588+ - The two blank lines closes them all.
589+
590+
591+%%% Nesting: Free leading spacing (indentation)
592+- When nesting lists, the additional spaces are free.
593+ - You can add just one,
594+ - or many.
595+ - What matters is to put more than the previous.
596+ - But remember that the other items of the same list
597+ - must use the same indentation.
598+
599+
600+%%% Nesting: Maximum depth
601+- There is not a depth limit,
602+ - you can go deeper and deeper.
603+ - But some targets may have restrictions.
604+ - The LaTeX maximum is here, 4 levels.
605+
606+
607+%%% Nesting: Reverse doesn't work
608+ - Reverse nesting doesn't work.
609+ - Because a sublist *must* have a mother list.
610+ - It's the list concept, not a txt2tags limitation.
611+ - All this sublists will be bumped to mother lists.
612+- At level 1, like this one.
613+
614+
615+%%% Nesting: Going deeper and back
616+
617+%% When nesting back to an upper level, the previous sublist
618+%% is automatically closed.
619+- Level 1
620+ - Level 2
621+ - Level 3
622+ - Level 4
623+ - Level 3 -- (closed Level 4)
624+ - Level 2 -- (closed Level 3)
625+- Level 1 -- (closed Level 2)
626+
627+
628+%% More than one list can be closed when nesting back.
629+- Level 1
630+ - Level 2
631+ - Level 3
632+ - Level 4
633+- Level 1 -- (closed Level 4, Level 3 and Level 2)
634+
635+
636+%%% Nesting: Vertical spacing between lists
637+- Level 1
638+
639+ - Level 2 -- blank BEFORE and AFTER (in)
640+
641+ - Level 3
642+% comment lines are NOT considered blank lines
643+ - Level 4
644+% comment lines are NOT considered blank lines
645+ - Level 3
646+
647+ - Level 2 -- blank BEFORE and AFTER (out)
648+
649+- Level 1
650+
651+ - Level 2 -- blank BEFORE (spaces) and AFTER (TAB)
652+
653+ - Level 3
654+
655+
656+%%% Nesting: Messing up
657+%% Be careful when going back on the nesting,
658+%% it must be on a valid level! If not, it will
659+%% be bumped up to the previous valid level.
660+- Level 1
661+ - Level 2
662+ - Level 3
663+ - Level 4
664+ - Level 3.5 ???
665+ - Level 3
666+ - Level 2.5 ???
667+ - Level 2
668+ - Level 1.5 ???
669+- Level 1
670+
671+
672+%%% Closing: Two (not so) empty lines
673+- This list is closed by a line with spaces and other with TABs
674+
675+
676+- This list is NOT closed by two comment lines
677+% comment lines are NOT considered blank lines
678+% comment lines are NOT considered blank lines
679+- This list is closed by a line with spaces and TAB,
680+- then a comment line, then an empty line.
681+
682+% comment lines are NOT considered blank lines
683+
684+%%% Closing: Empty item closes current (sub)list
685+
686+%% The two blank lines closes ALL the lists.
687+%% To close just the current, use an empty item.
688+- Level 1
689+ - Level 2
690+ - Level 3
691+ -
692+ Level 2
693+ -
694+ Level 1
695+-
696+
697+%% The empty item can have trailing blanks.
698+- Empty item with trailing spaces.
699+-
700+
701+- Empty item with trailing TAB.
702+-
703+
704+%%% Closing: EOF closes the lists
705+- If the end of the file (EOF) is hit,
706+ - all the currently opened list are closed,
707+ - just like when using the two blank lines.
708+
709+
710+= Table =[table]
711+
712+%INCLUDED(t2t) starts here: ../../../test/marks/table.t2t
713+
714+%%% Syntax: Lines starting with a pipe |
715+| Cell 1
716+
717+%%% Syntax: Extra pipes separate cells
718+| Cell 1 | Cell 2 | Cell 3
719+
720+%%% Syntax: With a trailing pipe, make border
721+| Cell 1 | Cell 2 | Cell 3 |
722+
723+%%% Syntax: Table lines starting with double pipe are heading
724+|| Cell 1 | Cell 2 | Cell 3 |
725+
726+%%% Align: Spaces before the leading pipe centralize the table
727+ | Cell 1 | Cell 2 | Cell 3 |
728+
729+%%% Align: Spaces inside the cell denote its alignment
730+ || Heading | Heading | Heading |
731+% comments don't close an opened table
732+ | <- | -- | -> |
733+ | -- | -- | -- |
734+ | -> | -- | <- |
735+
736+%%% Span: Column span is defined by extra pipes at cell closing
737+ || 1 | 2 | 3+4 ||
738+ | 1 | 2 | 3 | 4 |
739+ | 1+2+3 ||| 4 |
740+ | 1 | 2+3 || 4 |
741+ | 1+2+3+4 ||||
742+
743+%%% Test: Empty cells are placed as expected
744+ | 0 | 1 | 2 | |
745+ | 4 | 5 | | 7 |
746+ | 8 | | A | B |
747+ | | D | E | F |
748+
749+%%% Test: Lines with different number of cells
750+ | 1 |
751+ | 1 | 2 |
752+ | 1 | 2 | 3 |
753+ | 1 | 2 | 3 | 4 |
754+ | 1 | 2 | 3 | 4 | 5 |
755+
756+%%% Test: Empty cells + Span + Messy cell number = Fun!
757+ | Jan |
758+ | Fev ||
759+ | Mar |||
760+ | Apr ||||
761+ | May |||||
762+ | 20% | 40% | 60% | 80% | 100% |
763+
764+ | | | / | | |
765+ | | / / / / / ||| |
766+ | / / / / / / / / / |||||
767+ | | o | | o | |
768+ | | | . | | |
769+ | | = = = = ||| |
770+
771+ | 01 | 02 | | | 05 | | 07 | |
772+ | | | 11 | | 13 | | | 16 |
773+ | 17 | | 19 | 20 | | | 23 | |
774+ | 25 | 26 | | | 29 | 30 | | 32 |
775+ | | | 35 | | 37 | | 39 | 40 |
776+
777+%%% Test: Lots of cells at the same line
778+| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
779+
780+%%% Test: Empty lines
781+| |
782+| |
783+| |
784+
785+%%% Invalid: There must be at least one space around the pipe
786+|this|is|not|a|table|
787+
788+|this| is| not| a| table|
789+
790+|this |is |not |a |table |
791+
792+%%% Invalid: You must use spaces, not TABs
793+| this | is | not | a | table |
794+
795+------------------------------------------------------------
796+
797+The End.