git.iko.soy/typeable/pandoc
on master help sign in
Merge pull request #1453 from mpickering/txt2tagsfinal
31b8a95John MacFarlane
README+2−1
@@ -14,7 +14,7 @@ Pandoc is a [Haskell] library for converting from one markup format to
14another, and a command-line tool that uses this library. It can read
14another, and a command-line tool that uses this library. It can read
15[markdown] and (subsets of) [Textile], [reStructuredText], [HTML],
15[markdown] and (subsets of) [Textile], [reStructuredText], [HTML],
16[LaTeX], [MediaWiki markup], [Haddock markup], [OPML], [Emacs
16[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,
18[markdown], [reStructuredText], [XHTML], [HTML 5], [LaTeX] (including
18[markdown], [reStructuredText], [XHTML], [HTML 5], [LaTeX] (including
19[beamer] slide shows), [ConTeXt], [RTF], [OPML], [DocBook],
19[beamer] slide shows), [ConTeXt], [RTF], [OPML], [DocBook],
20[OpenDocument], [ODT], [Word docx], [GNU Texinfo], [MediaWiki markup],
20[OpenDocument], [ODT], [Word docx], [GNU Texinfo], [MediaWiki markup],
@@ -3096,3 +3096,4 @@ Rosenthal.
3096[marc relators]: http://www.loc.gov/marc/relators/relaterm.html
3096[marc relators]: http://www.loc.gov/marc/relators/relaterm.html
3097[RFC5646]: http://tools.ietf.org/html/rfc5646
3097[RFC5646]: http://tools.ietf.org/html/rfc5646
3098[InDesign ICML]: https://www.adobe.com/content/dam/Adobe/en/devnet/indesign/cs55-docs/IDML/idml-specification.pdf
3098[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
17 format to another, and a command-line tool that uses
17 format to another, and a command-line tool that uses
18 this library. It can read markdown and (subsets of) HTML,
18 this library. It can read markdown and (subsets of) HTML,
19 reStructuredText, LaTeX, DocBook, MediaWiki markup, Haddock
19 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
21 markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook,
21 markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook,
22 OPML, OpenDocument, ODT, Word docx, RTF, MediaWiki, DokuWiki,
22 OPML, OpenDocument, ODT, Word docx, RTF, MediaWiki, DokuWiki,
23 Textile, groff man pages, plain text, Emacs Org-Mode, AsciiDoc,
23 Textile, groff man pages, plain text, Emacs Org-Mode, AsciiDoc,
@@ -94,34 +94,23 @@ Extra-Source-Files:
94 -- tests
94 -- tests
95 tests/bodybg.gif,
95 tests/bodybg.gif,
96 tests/docbook-reader.docbook
96 tests/docbook-reader.docbook
97− tests/docbook-reader.native
98 tests/html-reader.html,
97 tests/html-reader.html,
99− tests/html-reader.native,
100 tests/opml-reader.opml,
98 tests/opml-reader.opml,
101− tests/opml-reader.native,
102 tests/haddock-reader.haddock,
99 tests/haddock-reader.haddock,
103− tests/haddock-reader.native,
104 tests/insert,
100 tests/insert,
105 tests/lalune.jpg,
101 tests/lalune.jpg,
106 tests/movie.jpg,
102 tests/movie.jpg,
107 tests/latex-reader.latex,
103 tests/latex-reader.latex,
108− tests/latex-reader.native,
109 tests/textile-reader.textile,
104 tests/textile-reader.textile,
110− tests/textile-reader.native,
111 tests/markdown-reader-more.txt,
105 tests/markdown-reader-more.txt,
112− tests/markdown-reader-more.native,
113 tests/markdown-citations.txt,
106 tests/markdown-citations.txt,
114− tests/markdown-citations.native,
115 tests/textile-reader.textile,
107 tests/textile-reader.textile,
116 tests/mediawiki-reader.wiki,
108 tests/mediawiki-reader.wiki,
117− tests/mediawiki-reader.native,
118− tests/rst-reader.native,
119 tests/rst-reader.rst,
109 tests/rst-reader.rst,
120 tests/s5.basic.html,
110 tests/s5.basic.html,
121 tests/s5.fancy.html,
111 tests/s5.fancy.html,
122 tests/s5.fragment.html,
112 tests/s5.fragment.html,
123 tests/s5.inserts.html,
113 tests/s5.inserts.html,
124− tests/s5.native,
125 tests/tables.context,
114 tests/tables.context,
126 tests/tables.docbook,
115 tests/tables.docbook,
127 tests/tables.html,
116 tests/tables.html,
@@ -131,7 +120,6 @@ Extra-Source-Files:
131 tests/tables.markdown,
120 tests/tables.markdown,
132 tests/tables.mediawiki,
121 tests/tables.mediawiki,
133 tests/tables.textile,
122 tests/tables.textile,
134− tests/tables.native,
135 tests/tables.opendocument,
123 tests/tables.opendocument,
136 tests/tables.org,
124 tests/tables.org,
137 tests/tables.asciidoc,
125 tests/tables.asciidoc,
@@ -140,9 +128,7 @@ Extra-Source-Files:
140 tests/tables.rst,
128 tests/tables.rst,
141 tests/tables.rtf,
129 tests/tables.rtf,
142 tests/tables.txt,
130 tests/tables.txt,
143− tests/tables-rstsubset.native,
144 tests/tables.fb2,
131 tests/tables.fb2,
145− tests/testsuite.native,
146 tests/testsuite.txt,
132 tests/testsuite.txt,
147 tests/writer.latex,
133 tests/writer.latex,
148 tests/writer.context,
134 tests/writer.context,
@@ -153,7 +139,6 @@ Extra-Source-Files:
153 tests/writer.plain,
139 tests/writer.plain,
154 tests/writer.mediawiki,
140 tests/writer.mediawiki,
155 tests/writer.textile,
141 tests/writer.textile,
156− tests/writer.native,
157 tests/writer.opendocument,
142 tests/writer.opendocument,
158 tests/writer.org,
143 tests/writer.org,
159 tests/writer.asciidoc,
144 tests/writer.asciidoc,
@@ -163,8 +148,6 @@ Extra-Source-Files:
163 tests/writer.texinfo,
148 tests/writer.texinfo,
164 tests/writer.fb2,
149 tests/writer.fb2,
165 tests/writer.opml,
150 tests/writer.opml,
166− tests/lhs-test.native,
167− tests/lhs-test-markdown.native,
168 tests/lhs-test.markdown,
151 tests/lhs-test.markdown,
169 tests/lhs-test.markdown+lhs,
152 tests/lhs-test.markdown+lhs,
170 tests/lhs-test.rst,
153 tests/lhs-test.rst,
@@ -175,7 +158,6 @@ Extra-Source-Files:
175 tests/lhs-test.html+lhs,
158 tests/lhs-test.html+lhs,
176 tests/lhs-test.fragment.html+lhs,
159 tests/lhs-test.fragment.html+lhs,
177 tests/pipe-tables.txt,
160 tests/pipe-tables.txt,
178− tests/pipe-tables.native,
179 tests/fb2.basic.markdown,
161 tests/fb2.basic.markdown,
180 tests/fb2.basic.fb2,
162 tests/fb2.basic.fb2,
181 tests/fb2.titles.markdown,
163 tests/fb2.titles.markdown,
@@ -188,26 +170,18 @@ Extra-Source-Files:
188 tests/fb2.math.fb2,
170 tests/fb2.math.fb2,
189 tests/fb2.test-small.png,
171 tests/fb2.test-small.png,
190 tests/fb2.test.jpg,
172 tests/fb2.test.jpg,
191− tests/docx.already_auto_ident.native,
192 tests/docx.already_auto_ident.docx,
173 tests/docx.already_auto_ident.docx,
193 tests/docx.block_quotes.docx,
174 tests/docx.block_quotes.docx,
194− tests/docx.block_quotes_parse_indent.native,
195 tests/docx.headers.docx,
175 tests/docx.headers.docx,
196− tests/docx.headers.native,
197 tests/docx.image.docx,
176 tests/docx.image.docx,
198− tests/docx.image_no_embed.native,
199 tests/docx.inline_formatting.docx,
177 tests/docx.inline_formatting.docx,
200− tests/docx.inline_formatting.native,
201 tests/docx.links.docx,
178 tests/docx.links.docx,
202− tests/docx.links.native,
203 tests/docx.lists.docx,
179 tests/docx.lists.docx,
204− tests/docx.lists.native,
205 tests/docx.notes.docx,
180 tests/docx.notes.docx,
206− tests/docx.notes.native,
207 tests/docx.tables.docx,
181 tests/docx.tables.docx,
208− tests/docx.tables.native,
209 tests/docx.unicode.docx,
182 tests/docx.unicode.docx,
210− tests/docx.unicode.native
183+ tests/*.native,
184+ tests/txt2tags.t2t
211Extra-Tmp-Files: man/man1/pandoc.1,
185Extra-Tmp-Files: man/man1/pandoc.1,
212 man/man5/pandoc_markdown.5
186 man/man5/pandoc_markdown.5
213
187
@@ -261,7 +235,8 @@ Library
261 hslua >= 0.3 && < 0.4,
235 hslua >= 0.3 && < 0.4,
262 binary >= 0.5 && < 0.8,
236 binary >= 0.5 && < 0.8,
263 SHA >= 1.6 && < 1.7,
237 SHA >= 1.6 && < 1.7,
264− haddock-library >= 1.1 && < 1.2
238+ haddock-library >= 1.1 && < 1.2,
239+ old-time
265 if flag(https)
240 if flag(https)
266 Build-Depends: http-client >= 0.3.2 && < 0.4,
241 Build-Depends: http-client >= 0.3.2 && < 0.4,
267 http-client-tls >= 0.2 && < 0.3,
242 http-client-tls >= 0.2 && < 0.3,
@@ -328,7 +303,8 @@ Library
328 Text.Pandoc.Templates,
303 Text.Pandoc.Templates,
329 Text.Pandoc.XML,
304 Text.Pandoc.XML,
330 Text.Pandoc.SelfContained,
305 Text.Pandoc.SelfContained,
331− Text.Pandoc.Process
306+ Text.Pandoc.Process,
307+ Text.Pandoc.Readers.Txt2Tags
332 Other-Modules: Text.Pandoc.Readers.Docx.Lists,
308 Other-Modules: Text.Pandoc.Readers.Docx.Lists,
333 Text.Pandoc.Readers.Docx.Reducible,
309 Text.Pandoc.Readers.Docx.Reducible,
334 Text.Pandoc.Readers.Docx.Parse,
310 Text.Pandoc.Readers.Docx.Parse,
@@ -344,6 +320,7 @@ Library
344 Text.Pandoc.Compat.Monoid,
320 Text.Pandoc.Compat.Monoid,
345 Text.Pandoc.Compat.Except,
321 Text.Pandoc.Compat.Except,
346 Text.Pandoc.Compat.TagSoupEntity,
322 Text.Pandoc.Compat.TagSoupEntity,
323+ Text.Pandoc.Compat.Directory
347 Paths_pandoc
324 Paths_pandoc
348
325
349 Buildable: True
326 Buildable: True
@@ -420,6 +397,7 @@ Test-Suite test-pandoc
420 Tests.Readers.Org
397 Tests.Readers.Org
421 Tests.Readers.RST
398 Tests.Readers.RST
422 Tests.Readers.Docx
399 Tests.Readers.Docx
400+ Tests.Readers.Txt2Tags
423 Tests.Writers.Native
401 Tests.Writers.Native
424 Tests.Writers.ConTeXt
402 Tests.Writers.ConTeXt
425 Tests.Writers.HTML
403 Tests.Writers.HTML
pandoc.hs+16−7
@@ -65,6 +65,9 @@ import qualified Data.Map as M
65import Data.Yaml (decode)
65import Data.Yaml (decode)
66import qualified Data.Yaml as Yaml
66import qualified Data.Yaml as Yaml
67import qualified Data.Text as T
67import qualified Data.Text as T
68+import Control.Applicative ((<$>))
69+import Text.Pandoc.Readers.Txt2Tags (getT2TMeta)
70+import Data.List (intersperse)
68
71
69copyrightMessage :: String
72copyrightMessage :: String
70copyrightMessage = "\nCopyright (C) 2006-2014 John MacFarlane\n" ++
73copyrightMessage = "\nCopyright (C) 2006-2014 John MacFarlane\n" ++
@@ -180,7 +183,7 @@ data Opt = Opt
180 , optTeXLigatures :: Bool -- ^ Use TeX ligatures for quotes/dashes
183 , optTeXLigatures :: Bool -- ^ Use TeX ligatures for quotes/dashes
181 , optDefaultImageExtension :: String -- ^ Default image extension
184 , optDefaultImageExtension :: String -- ^ Default image extension
182 , optTrace :: Bool -- ^ Print debug information
185 , 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.
184 }
187 }
185
188
186-- | Defaults for command-line options.
189-- | Defaults for command-line options.
@@ -876,6 +879,7 @@ defaultReaderName fallback (x:xs) =
876 ".native" -> "native"
879 ".native" -> "native"
877 ".json" -> "json"
880 ".json" -> "json"
878 ".docx" -> "docx"
881 ".docx" -> "docx"
882+ ".t2t" -> "t2t"
879 _ -> defaultReaderName fallback xs
883 _ -> defaultReaderName fallback xs
880
884
881-- Returns True if extension of first source is .lhs
885-- Returns True if extension of first source is .lhs
@@ -1054,9 +1058,14 @@ main = do
1054 else e
1058 else e
1055 Right w -> return w
1059 Right w -> return w
1056
1060
1061+ let concatInput = concat (intersperse ", " sources)
1062+ reader <- if "t2t" == readerName'
1063+ then (mkStringReader .
1064+ readTxt2Tags) <$>
1065+ (getT2TMeta concatInput outputFile)
1057− reader <- case getReader readerName' of
1066+ else case getReader readerName' of
1058− Right r -> return r
1067+ Right r -> return r
1059− Left e -> err 7 e
1068+ Left e -> err 7 e
1060
1069
1061 let standalone' = standalone || not (isTextFormat writerName') || pdfOutput
1070 let standalone' = standalone || not (isTextFormat writerName') || pdfOutput
1062
1071
@@ -1181,18 +1190,18 @@ main = do
1181 let readFiles [] = error "Cannot read archive from stdin"
1190 let readFiles [] = error "Cannot read archive from stdin"
1182 readFiles (x:_) = B.readFile x
1191 readFiles (x:_) = B.readFile x
1183
1192
1184− let convertTabs = tabFilter (if preserveTabs then 0 else tabStop)
1193+ let convertTabs = tabFilter (if (preserveTabs || readerName' == "t2t") then 0 else tabStop)
1185
1194
1186 let handleIncludes' = if readerName' == "latex" || readerName' == "latex+lhs"
1195 let handleIncludes' = if readerName' == "latex" || readerName' == "latex+lhs"
1187 then handleIncludes
1196 then handleIncludes
1188 else return
1197 else return
1189
1198
1190 doc <- case reader of
1199 doc <- case reader of
1191− StringReader r->
1200+ StringReader r->
1192 readSources sources >>=
1201 readSources sources >>=
1193 handleIncludes' . convertTabs . intercalate "\n" >>=
1202 handleIncludes' . convertTabs . intercalate "\n" >>=
1194 r readerOpts
1203 r readerOpts
1195− ByteStringReader r -> readFiles sources >>= r readerOpts
1204+ ByteStringReader r -> readFiles sources >>= r readerOpts
1196
1205
1197
1206
1198 let doc0 = M.foldWithKey setMeta doc metadata
1207 let doc0 = M.foldWithKey setMeta doc metadata
src/Text/Pandoc.hs+5
@@ -63,6 +63,7 @@ module Text.Pandoc
63 , writers
63 , writers
64 -- * Readers: converting /to/ Pandoc format
64 -- * Readers: converting /to/ Pandoc format
65 , Reader (..)
65 , Reader (..)
66+ , mkStringReader
66 , readDocx
67 , readDocx
67 , readMarkdown
68 , readMarkdown
68 , readMediaWiki
69 , readMediaWiki
@@ -76,6 +77,8 @@ module Text.Pandoc
76 , readHaddock
77 , readHaddock
77 , readNative
78 , readNative
78 , readJSON
79 , readJSON
80+ , readTxt2Tags
81+ , readTxt2TagsNoMacros
79 -- * Writers: converting /from/ Pandoc format
82 -- * Writers: converting /from/ Pandoc format
80 , Writer (..)
83 , Writer (..)
81 , writeNative
84 , writeNative
@@ -130,6 +133,7 @@ import Text.Pandoc.Readers.Textile
130import Text.Pandoc.Readers.Native
133import Text.Pandoc.Readers.Native
131import Text.Pandoc.Readers.Haddock
134import Text.Pandoc.Readers.Haddock
132import Text.Pandoc.Readers.Docx
135import Text.Pandoc.Readers.Docx
136+import Text.Pandoc.Readers.Txt2Tags
133import Text.Pandoc.Writers.Native
137import Text.Pandoc.Writers.Native
134import Text.Pandoc.Writers.Markdown
138import Text.Pandoc.Writers.Markdown
135import Text.Pandoc.Writers.RST
139import Text.Pandoc.Writers.RST
@@ -227,6 +231,7 @@ readers = [ ("native" , StringReader $ \_ s -> return $ readNative s)
227 ,("latex" , mkStringReader readLaTeX)
231 ,("latex" , mkStringReader readLaTeX)
228 ,("haddock" , mkStringReader readHaddock)
232 ,("haddock" , mkStringReader readHaddock)
229 ,("docx" , mkBSReader readDocx)
233 ,("docx" , mkBSReader readDocx)
234+ ,("t2t" , mkStringReader readTxt2TagsNoMacros)
230 ]
235 ]
231
236
232data Writer = PureStringWriter (WriterOptions -> Pandoc -> String)
237data 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"
142 , test "reader" ["-r", "haddock", "-w", "native", "-s"]
142 , test "reader" ["-r", "haddock", "-w", "native", "-s"]
143 "haddock-reader.haddock" "haddock-reader.native"
143 "haddock-reader.haddock" "haddock-reader.native"
144 ]
144 ]
145+ , testGroup "txt2tags"
146+ [ test "reader" ["-r", "t2t", "-w", "native"]
147+ "txt2tags.t2t" "txt2tags.native"
148+ ]
145 , testGroup "other writers" $ map (\f -> testGroup f $ writerTests f)
149 , testGroup "other writers" $ map (\f -> testGroup f $ writerTests f)
146 [ "opendocument" , "context" , "texinfo", "icml"
150 [ "opendocument" , "context" , "texinfo", "icml"
147 , "man" , "plain" , "rtf", "org", "asciidoc"
151 , "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
10import qualified Tests.Readers.Org
10import qualified Tests.Readers.Org
11import qualified Tests.Readers.RST
11import qualified Tests.Readers.RST
12import qualified Tests.Readers.Docx
12import qualified Tests.Readers.Docx
13+import qualified Tests.Readers.Txt2Tags
13import qualified Tests.Writers.ConTeXt
14import qualified Tests.Writers.ConTeXt
14import qualified Tests.Writers.LaTeX
15import qualified Tests.Writers.LaTeX
15import qualified Tests.Writers.HTML
16import qualified Tests.Writers.HTML
@@ -40,7 +41,7 @@ tests = [ testGroup "Old" Tests.Old.tests
40 , testGroup "Org" Tests.Readers.Org.tests
41 , testGroup "Org" Tests.Readers.Org.tests
41 , testGroup "RST" Tests.Readers.RST.tests
42 , testGroup "RST" Tests.Readers.RST.tests
42 , testGroup "Docx" Tests.Readers.Docx.tests
43 , testGroup "Docx" Tests.Readers.Docx.tests
43−
44+ , testGroup "Txt2Tags" Tests.Readers.Txt2Tags.tests
44 ]
45 ]
45 ]
46 ]
46
47
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.