packages feed

asciidoc (empty) → 0.1

raw patch · 273 files changed

+12439/−0 lines, 273 filesdep +aesondep +asciidocdep +attoparsec

Dependencies added: aeson, asciidoc, attoparsec, base, bytestring, containers, directory, filepath, mtl, optparse-applicative, pretty-show, process, tagsoup, tasty, tasty-golden, tasty-hunit, text

Files

+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# Revision history for asciidoc-hs++## 0.1 -- 2025-11-30++* Initial release.+
+ LICENSE view
@@ -0,0 +1,56 @@+Copyright (c) 2025, John MacFarlane++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of the copyright holder nor the names of its+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++--++The asciidoc content of the test cases in `test/asciidoctor`+comes from https://github.com/asciidoctor/asciidoctor-doctest.+It is governed by this license:++The MIT License++Copyright 2014-present Jakub Jirutka <jakub@jirutka.cz> and the Asciidoctor Project.++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ app/Main.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE OverloadedStrings #-}++module Main where++import Data.Aeson (encode)+import Options.Applicative+import qualified Data.Text.IO as TIO+import System.Exit (exitFailure)+import Text.Show.Pretty (ppShow)+import AsciiDoc.Parse (parseDocument)+import qualified Data.ByteString.Lazy as B+import System.IO (hPutStrLn, stderr)++data OutputFormat+  = AST    -- ^ Show the parsed AST in Haskell notation+  | JSON   -- ^ Show the parsed AST in JSON serialization+  deriving (Show, Eq)++-- | Command line options+data Options = Options+  { optInputFiles :: [FilePath]+  , optOutputFormat :: OutputFormat+  } deriving (Show)++-- | Parser for output format+outputFormatParser :: ReadM OutputFormat+outputFormatParser = eitherReader $ \s ->+  case s of+    "ast"  -> Right AST+    "json" -> Right JSON+    _      -> Left $ "Invalid output format: " ++ s ++ ". Use 'ast' or 'json'."++-- | Command line options parser+optionsParser :: Parser Options+optionsParser = Options+  <$> many (argument str+      ( metavar "FILE"+     <> help "Input files (omit to read from stdin)"+      ))+  <*> option outputFormatParser+      ( long "to"+     <> metavar "FORMAT"+     <> value AST+     <> help "Output format (ast*|json)"+      )++-- | Program description+opts :: ParserInfo Options+opts = info (optionsParser <**> helper)+  ( fullDesc+ <> progDesc "Parse AsciiDoc and output an AST"+ <> header "hasciidoc - AsciiDoc parser in Haskell"+  )+++main :: IO ()+main = do+  options <- execParser opts++  let raiseError fp pos msg = do+        hPutStrLn stderr $ "Parse error at " <> show fp <>+                           " position " <> show pos <> ": " <> msg+        exitFailure++  -- Parse the document+  doc <- case optInputFiles options of+          [] -> TIO.getContents >>=+                  parseDocument TIO.readFile raiseError "stdin"+          fs -> mconcat <$> mapM (\fp ->+                  TIO.readFile fp >>= parseDocument TIO.readFile raiseError fp)+                fs+  case optOutputFormat options of+    AST -> putStrLn $ ppShow doc+    JSON -> do+      B.putStr $ encode doc+      B.putStr "\n"
+ asciidoc.cabal view
@@ -0,0 +1,76 @@+cabal-version:      3.4+name:               asciidoc+version:            0.1+synopsis:           AsciiDoc parser.+description:        A parser for AsciiDoc syntax.+license:            BSD-3-Clause+license-file:       LICENSE+author:             John MacFarlane+maintainer:         jgm@berkeley.edu+copyright:          (C) 2025 by John MacFarlane+category:           Text+build-type:         Simple+extra-doc-files:    CHANGELOG.md+extra-source-files: test/asciidoctor/**/*.test+                    test/feature/**/*.test+                    test/feature/include/**/*.adoc++Source-repository head+  type:              git+  location:          https://github.com/jgm/asciidoc-hs.git++common warnings+    ghc-options: -Wall++library+    import:           warnings+    exposed-modules:  AsciiDoc+                    , AsciiDoc.AST+                    , AsciiDoc.Generic+                    , AsciiDoc.Parse+    build-depends:    base >=4.14 && <5+                    , text+                    , mtl+                    , attoparsec+                    , filepath+                    , containers+                    , tagsoup+                    , aeson+    hs-source-dirs:   src+    default-language: Haskell2010++executable hasciidoc+    import:           warnings+    main-is:          Main.hs+    build-depends:+        base >=4.14 && <5,+        asciidoc,+        mtl,+        text,+        pretty-show,+        aeson,+        bytestring,+        optparse-applicative++    hs-source-dirs:   app+    default-language: Haskell2010++test-suite asciidoc-hs-test+    import:           warnings+    default-language: Haskell2010+    type:             exitcode-stdio-1.0+    hs-source-dirs:   test+    main-is:          Main.hs+    build-depends:+        base >=4.14 && <5,+        asciidoc,+        tasty,+        tasty-hunit,+        tasty-golden,+        text,+        bytestring,+        pretty-show,+        containers,+        directory,+        filepath,+        process
+ src/AsciiDoc.hs view
@@ -0,0 +1,10 @@+module AsciiDoc (+  module AsciiDoc.AST,+  module AsciiDoc.Parse,+  module AsciiDoc.Generic+) where++import AsciiDoc.AST+import AsciiDoc.Parse+import AsciiDoc.Generic+
+ src/AsciiDoc/AST.hs view
@@ -0,0 +1,492 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}++module AsciiDoc.AST+  ( Document(..)+  , Meta(..)+  , Author(..)+  , Revision(..)+  , Block(..)+  , BlockType(..)+  , BlockTitle(..)+  , Inline(..)+  , InlineType(..)+  , ListType(..)+  , ListItem(..)+  , CheckboxState(..)+  , ColumnSpec(..)+  , CellStyle(..)+  , TableRow(..)+  , TableCell(..)+  , HorizAlign(..)+  , VertAlign(..)+  , AdmonitionType(..)+  , Target(..)+  , LinkType(..)+  , MathType(..)+  , Attr(..)+  , attrNull+  , Level(..)+  , Language(..)+  , Attribution(..)+  , AltText(..)+  , Width(..)+  , Height(..)+  , FootnoteId(..)+  , AttributeName(..)+  , Callout(..)+  , IndexTerm(..)+  , SourceLine(..)+  , CounterType(..)+  ) where++import Control.Monad+import Data.Text (Text)+import Data.Data (Data)+import Data.Typeable (Typeable)+import GHC.Generics (Generic)+import qualified Data.Map.Strict as Map+import Data.Map.Strict (Map)+import Data.Aeson (ToJSON(..), FromJSON(..), genericToEncoding, defaultOptions)++-- | A complete AsciiDoc document+data Document = Document+  { docMeta :: Meta+  , docBlocks :: [Block]+  } deriving (Show, Eq, Generic, Data, Typeable)++instance Semigroup Document where+  d1 <> d2 = Document { docMeta = docMeta d1 <> docMeta d2+                      , docBlocks = docBlocks d1 <> docBlocks d2+                      }++instance Monoid Document where+  mappend = (<>)+  mempty = Document mempty mempty++instance ToJSON Document where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Document++-- | Author information+data Author = Author+  { authorName :: Text+  , authorEmail :: Maybe Text+  } deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON Author where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Author++-- | Revision information+data Revision = Revision+  { revVersion :: Text+  , revDate :: Maybe Text+  , revRemark :: Maybe Text+  } deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON Revision where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Revision++-- | Document metadata+data Meta = Meta+  { docTitle :: [Inline]+  , docTitleAttributes :: Maybe Attr+  , docAuthors :: [Author]+  , docRevision :: Maybe Revision+  , docAttributes :: Map Text Text+  } deriving (Eq, Generic, Data, Typeable)++instance Show Meta where+  show x | x == mempty = "Meta mempty"+  show (Meta title titleAttr authors revision attributes) =+    "Meta{ docTitle = " <> show title <>+    ", docTitleAttributes = " <> show titleAttr <>+    ", docAuthors = " <> show authors <>+    ", docRevision = " <> show revision <>+    ", docAttributes = " <> show attributes+    <> "}"++instance ToJSON Meta where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Meta++instance Semigroup Meta where  -- left-biased+  m1 <> m2 = Meta { docTitle = case docTitle m1 of+                                 [] -> docTitle m2+                                 ils -> ils+                  , docTitleAttributes =+                               case docTitle m1 of+                                 [] -> docTitleAttributes m2+                                 _ -> docTitleAttributes m2+                  , docAuthors = docAuthors m1 <> docAuthors m2+                  , docRevision = docRevision m1 `mplus` docRevision m2+                  , docAttributes = docAttributes m1 <> docAttributes m2+                  }++instance Monoid Meta where+  mappend = (<>)+  mempty = Meta [] Nothing [] Nothing mempty++-- | Attributes attached to an element.+-- The first parameter stores positional attributes in order.+-- The second parameter stores named attributes (including special keys+-- like id/role/options) in a map.+data Attr = Attr [Text] (Map Text Text)+  deriving (Eq, Generic, Data, Typeable)++instance Show Attr where+  show (Attr pos m)+    | null pos && Map.null m = "mempty"+    | otherwise = "Attr " ++ show (pos, m)++instance Semigroup Attr where+  Attr p1 m1 <> Attr p2 m2 =+    let m = m2 <> m1 -- left-biased, favor m2+        m' = (case (Map.lookup "role" m1, Map.lookup "role" m2) of+                (Just x1, Just x2) -> Map.insert "role" (x1 <> " " <> x2)+                _ -> id) .+             (case (Map.lookup "options" m1, Map.lookup "options" m2) of+                (Just x1, Just x2) -> Map.insert "options" (x1 <> "," <> x2)+                _ -> id) $ m+    in  Attr (p1 <> p2) m'++instance Monoid Attr where+  mempty = Attr [] Map.empty+  mappend = (<>)++instance ToJSON Attr where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Attr++attrNull :: Attr -> Bool+attrNull (Attr pos m) = null pos && Map.null m++-- | Nesting or section level+newtype Level = Level Int+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON Level where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Level++-- | Programming or markup language identifier+newtype Language = Language Text+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON Language where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Language++-- | Attribution for quotes+newtype Attribution = Attribution Text+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON Attribution where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Attribution++-- | Alternative text for images+newtype AltText = AltText Text+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON AltText where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON AltText++-- | Width specification in pixels+newtype Width = Width Int+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON Width where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Width++-- | Height specification in pixels+newtype Height = Height Int+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON Height where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Height++-- | Footnote identifier+newtype FootnoteId = FootnoteId Text+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON FootnoteId where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON FootnoteId++-- | Attribute name+newtype AttributeName = AttributeName Text+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON AttributeName where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON AttributeName++-- | Source line callout+newtype Callout = Callout Int+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON Callout where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Callout++-- | Source line with possible annotation+data SourceLine =+    SourceLine Text [Callout]+  deriving (Show, Eq, Ord, Generic, Data, Typeable)++instance ToJSON SourceLine where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON SourceLine++-- | Block-level element with attributes+data Block = Block Attr (Maybe BlockTitle) BlockType+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON Block where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Block++-- | Block-level element types+data BlockType+  = Section Level [Inline] [Block]+  | DiscreteHeading Level [Inline]+  | Paragraph [Inline]+  | Verse (Maybe Attribution) [Block]+  | LiteralBlock Text+  | Listing (Maybe Language) [SourceLine]+  | IncludeListing (Maybe Language) FilePath (Maybe [SourceLine])+  | ExampleBlock [Block]+  | QuoteBlock (Maybe Attribution) [Block]+  | Sidebar [Block]+  | OpenBlock [Block]+  | PassthroughBlock Text+  | MathBlock (Maybe MathType) Text+  | List ListType [ListItem]+  | DefinitionList [([Inline], [Block])]+  | Table [ColumnSpec] (Maybe [TableRow]) [TableRow] (Maybe [TableRow])+  | BlockImage Target (Maybe AltText) (Maybe Width) (Maybe Height)+  | BlockAudio Target+  | BlockVideo Target+  | TOC+  | Admonition AdmonitionType [Block]+  | PageBreak+  | ThematicBreak+  | Include FilePath (Maybe [Block])+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON BlockType where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON BlockType++newtype BlockTitle = BlockTitle [Inline]+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON BlockTitle where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON BlockTitle++-- | Types of admonitions+data AdmonitionType+  = Note+  | Tip+  | Important+  | Caution+  | Warning+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON AdmonitionType where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON AdmonitionType++data IndexTerm =+    TermInText Text+  | TermConcealed [Text]+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON IndexTerm where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON IndexTerm++-- | List types+data ListType+  = BulletList Level+  | OrderedList Level (Maybe Int)+  | CheckList+  | CalloutList+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON ListType where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON ListType++-- | A list item+data ListItem = ListItem (Maybe CheckboxState) [Block]+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON ListItem where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON ListItem++-- | Checkbox state for checklists+data CheckboxState+  = Checked+  | Unchecked+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON CheckboxState where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON CheckboxState++-- | Column specification+data ColumnSpec = ColumnSpec+  { colHorizAlign :: Maybe HorizAlign+  , colVertAlign :: Maybe VertAlign+  , colWidth :: Maybe Int+  , colStyle :: Maybe CellStyle+  } deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON ColumnSpec where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON ColumnSpec++-- | Defines how cell contents are parsed+data CellStyle =+    AsciiDocStyle+  | DefaultStyle+  | EmphasisStyle+  | LiteralStyle+  | HeaderStyle+  | MonospaceStyle+  | StrongStyle+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON CellStyle where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON CellStyle++-- | Table row+newtype TableRow = TableRow [TableCell]+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON TableRow where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON TableRow++-- | Table cell+data TableCell = TableCell+  { cellContent :: [Block]+  , cellHorizAlign :: Maybe HorizAlign+  , cellVertAlign :: Maybe VertAlign+  , cellColspan :: Int+  , cellRowspan :: Int+  } deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON TableCell where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON TableCell++-- | Cell alignment+data HorizAlign+  = AlignLeft+  | AlignCenter+  | AlignRight+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON HorizAlign where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON HorizAlign++data VertAlign+  = AlignTop+  | AlignMiddle+  | AlignBottom+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON VertAlign where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON VertAlign++-- | Inline element with attributes+data Inline = Inline Attr InlineType+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON Inline where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Inline++-- | Inline element types+data InlineType+  = Str Text+  | HardBreak+  | Bold [Inline]+  | Italic [Inline]+  | Monospace [Inline]+  | Superscript [Inline]+  | Subscript [Inline]+  | Highlight [Inline]+  | Strikethrough [Inline]+  | DoubleQuoted [Inline]+  | SingleQuoted [Inline]+  | Math (Maybe MathType) Text+  | Icon Text+  | Button Text+  | Kbd [Text]+  | Menu [Text]+  | Link LinkType Target [Inline]+  | InlineImage Target (Maybe AltText) (Maybe Width) (Maybe Height)+  | Footnote (Maybe FootnoteId) [Inline]+  | InlineAnchor Text [Inline]+  | BibliographyAnchor Text [Inline]+  | CrossReference Text (Maybe [Inline])+  | AttributeReference AttributeName+  | Span [Inline]+  | IndexEntry IndexTerm+  | Counter Text CounterType Int+  | Passthrough Text+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON InlineType where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON InlineType++data MathType+  = AsciiMath+  | LaTeXMath+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON MathType where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON MathType++-- | Link types+data LinkType+  = URLLink+  | EmailLink+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON LinkType where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON LinkType++-- | Link or image target+newtype Target = Target Text+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON Target where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON Target++data CounterType =+  DecimalCounter | UpperAlphaCounter | LowerAlphaCounter+  deriving (Show, Eq, Generic, Data, Typeable)++instance ToJSON CounterType where+    toEncoding = genericToEncoding defaultOptions+instance FromJSON CounterType
+ src/AsciiDoc/Generic.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}++module AsciiDoc.Generic+  ( HasInlines(..)+  , HasBlocks(..)+  ) where++import GHC.Generics hiding (Meta)+import AsciiDoc.AST+import Control.Monad++class GHasInlines f where+  gfoldInlines :: Monoid m => (Inline -> m) -> f p -> m+  gmapInlines :: Monad m => (Inline -> m Inline) -> f p -> m (f p)++instance GHasInlines U1 where+  gfoldInlines _ _ = mempty+  gmapInlines _ _ = pure mempty++instance (GHasInlines f, GHasInlines g) => GHasInlines (f :*: g) where+  gfoldInlines f (x :*: y) = gfoldInlines f x <> gfoldInlines f y+  gmapInlines f (x :*: y) = liftM2 (:*:) (gmapInlines f x) (gmapInlines f y)++instance (GHasInlines f, GHasInlines g) => GHasInlines (f :+: g) where+  gfoldInlines f (L1 x) = gfoldInlines f x+  gfoldInlines f (R1 y) = gfoldInlines f y+  gmapInlines f (L1 x) = L1 <$> gmapInlines f x+  gmapInlines f (R1 y) = R1 <$> gmapInlines f y++instance GHasInlines f => GHasInlines (M1 i c f) where+  gfoldInlines f (M1 x) = gfoldInlines f x+  gmapInlines f (M1 x) = M1 <$> gmapInlines f x++class HasInlines a where+  foldInlines :: Monoid m => (Inline -> m) -> a -> m+  mapInlines :: Monad m => (Inline -> m Inline) -> a -> m a++  default foldInlines :: (Generic a, GHasInlines (Rep a), Monoid m)+                      => (Inline -> m) -> a -> m+  foldInlines f = gfoldInlines f . from++  default mapInlines :: (Generic a, GHasInlines (Rep a), Monad m)+                      => (Inline -> m Inline) -> a -> m a+  mapInlines f x = to <$> gmapInlines f (from x)++-- Field: delegate to HasInlines of the field type+instance HasInlines a => GHasInlines (K1 i a) where+  gfoldInlines f (K1 x) = foldInlines f x+  gmapInlines f (K1 x) = K1 <$> mapInlines f x++instance {-# OVERLAPPABLE #-} HasInlines a where+  foldInlines _ _ = mempty+  mapInlines _ = pure++instance (HasInlines a, Traversable t, Foldable t) => HasInlines (t a) where+  foldInlines f = foldMap (foldInlines f)+  mapInlines f = mapM (mapInlines f)++instance HasInlines Inline where+  foldInlines f i@(Inline _ ty) =+    f i <> foldInlines f ty+  mapInlines f (Inline attr ty) =+    mapInlines f ty >>= f . Inline attr++instance HasInlines Document+instance HasInlines Meta+instance HasInlines Author+instance HasInlines Block+instance HasInlines BlockType+instance HasInlines BlockTitle+instance HasInlines ListItem+instance HasInlines TableRow+instance HasInlines TableCell+instance HasInlines InlineType++class GHasBlocks f where+  gfoldBlocks :: Monoid m => (Block -> m) -> f p -> m+  gmapBlocks :: Monad m => (Block -> m Block) -> f p -> m (f p)++instance GHasBlocks U1 where+  gfoldBlocks _ _ = mempty+  gmapBlocks _ _ = pure mempty++instance (GHasBlocks f, GHasBlocks g) => GHasBlocks (f :*: g) where+  gfoldBlocks f (x :*: y) = gfoldBlocks f x <> gfoldBlocks f y+  gmapBlocks f (x :*: y) = liftM2 (:*:) (gmapBlocks f x) (gmapBlocks f y)++instance (GHasBlocks f, GHasBlocks g) => GHasBlocks (f :+: g) where+  gfoldBlocks f (L1 x) = gfoldBlocks f x+  gfoldBlocks f (R1 y) = gfoldBlocks f y+  gmapBlocks f (L1 x) = L1 <$> gmapBlocks f x+  gmapBlocks f (R1 y) = R1 <$> gmapBlocks f y++instance GHasBlocks f => GHasBlocks (M1 i c f) where+  gfoldBlocks f (M1 x) = gfoldBlocks f x+  gmapBlocks f (M1 x) = M1 <$> gmapBlocks f x++class HasBlocks a where+  foldBlocks :: Monoid m => (Block -> m) -> a -> m+  mapBlocks :: Monad m => (Block -> m Block) -> a -> m a++  default foldBlocks :: (Generic a, GHasBlocks (Rep a), Monoid m)+                      => (Block -> m) -> a -> m+  foldBlocks f = gfoldBlocks f . from++  default mapBlocks :: (Generic a, GHasBlocks (Rep a), Monad m)+                      => (Block -> m Block) -> a -> m a+  mapBlocks f x = to <$> gmapBlocks f (from x)++-- Field: delegate to HasBlocks of the field type+instance HasBlocks a => GHasBlocks (K1 i a) where+  gfoldBlocks f (K1 x) = foldBlocks f x+  gmapBlocks f (K1 x) = K1 <$> mapBlocks f x++instance {-# OVERLAPPABLE #-} HasBlocks a where+  foldBlocks _ _ = mempty+  mapBlocks _ = pure++instance (HasBlocks a, Traversable t, Foldable t) => HasBlocks (t a) where+  foldBlocks f = foldMap (foldBlocks f)+  mapBlocks f = mapM (mapBlocks f)++instance HasBlocks Block where+  foldBlocks f i@(Block _ _ ty) =+    f i <> foldBlocks f ty+  mapBlocks f (Block attr mbtit ty) =+    mapBlocks f ty >>= f . Block attr mbtit++instance HasBlocks Document+instance HasBlocks Meta+instance HasBlocks Inline+instance HasBlocks InlineType+instance HasBlocks ListItem+instance HasBlocks TableRow+instance HasBlocks TableCell+instance HasBlocks BlockType+ 
+ src/AsciiDoc/Parse.hs view
@@ -0,0 +1,1784 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}++module AsciiDoc.Parse+  ( parseDocument+  ) where++import Prelude hiding (takeWhile)+import Text.HTML.TagSoup.Entity (lookupNamedEntity)+import Data.Maybe (isNothing, listToMaybe, fromMaybe)+import Data.Bifunctor (first)+import Data.Either (lefts, rights)+import qualified Data.Map as M+import qualified Data.Text as T+import qualified Data.Text.Read as TR+import Data.Text (Text)+import Data.List (foldl', intersperse)+import qualified Data.Attoparsec.Text as A+import System.FilePath+import Control.Applicative+import Control.Monad+import Control.Monad.State+import Control.Monad.Reader+import Data.Char (isAlphaNum, isAscii, isSpace, isLetter, isPunctuation, chr, isDigit,+                  isUpper, isLower, ord)+import AsciiDoc.AST+import AsciiDoc.Generic+-- import Debug.Trace++-- | Parse an AsciiDoc document into an AST.+parseDocument :: Monad m+              => (FilePath -> m Text)+                  -- ^ Get contents of an included file+              -> (FilePath -> Int -> String -> m Document)+                  -- ^ Raise an error given source pos and message+              -> FilePath+                  -- ^ Path of file containing the text+              -> Text -- ^ Text to convert+              -> m Document+parseDocument getFileContents raiseError path t =+   handleResult (parse pDocument path t) >>= handleIncludes+     >>= resolveAttributeReferences . addIdentifiers+     >>= resolveCrossReferences+ where+  handleResult (Left err) =+    raiseError path (errorPosition err) (errorMessage err)+  handleResult (Right r) = pure r++  toAnchorMap d =+    foldBlocks blockAnchor d <> foldInlines inlineAnchor d++  blockAnchor (Block (Attr _ kvs) _ (Section _ ils _))+    | Just ident <- M.lookup "id" kvs = M.singleton ident ils+  blockAnchor _ = mempty++  inlineAnchor (Inline _ (InlineAnchor ident ils)) = M.singleton ident ils+  inlineAnchor (Inline _ (BibliographyAnchor ident ils)) = M.singleton ident ils+  inlineAnchor _ = mempty++  resolveCrossReferences d = mapInlines (resolveCrossReference (toAnchorMap d)) d+  resolveCrossReference anchorMap+   x@(Inline attr (CrossReference ident Nothing)) =+    let ident' = T.takeWhileEnd (/= '#') ident -- strip off file part+    in case M.lookup ident' anchorMap of+        Just ils -> pure $ Inline attr (CrossReference ident' (Just ils))+        _ -> pure x+  resolveCrossReference _ x = pure x++  resolveAttributeReferences doc =+    mapInlines (goAttref (docAttributes (docMeta doc))) doc++  goAttref atts il@(Inline attr (AttributeReference (AttributeName at))) =+     case M.lookup at atts of+       Nothing -> return il+       Just x -> return $ Inline attr (Str x)+  goAttref _ il = return il++  handleIncludes = mapBlocks handleIncludeBlock++  handleIncludeBlock (Block attr mbtitle (Include fp Nothing)) =+    (do contents <- getFileContents fp+        Block attr mbtitle . Include fp . Just . docBlocks <$>+          handleResult (parse pDocument fp contents))+      >>= mapBlocks handleIncludeBlock+  handleIncludeBlock (Block attr mbtitle+                         (IncludeListing mblang fp Nothing)) =+    (do contents <- getFileContents fp+        pure $ Block attr mbtitle $ IncludeListing mblang fp+             $ Just (map (`SourceLine` []) (T.lines contents)))+      >>= mapBlocks handleIncludeBlock+  handleIncludeBlock x = pure x++-- | Make a relative path relative to a parent's directory.+-- Leaves absolute paths alone.+resolvePath :: FilePath -> FilePath -> FilePath+resolvePath parentPath fp+  | isRelative fp =+      normalise (takeDirectory parentPath </> fp)+  | otherwise = fp++--- Wrapped parser type:++newtype P a = P { unP :: ReaderT ParserConfig (StateT ParserState A.Parser) a }+  deriving (Functor, Applicative, Alternative, Monad, MonadPlus,+            MonadFail, MonadReader ParserConfig, MonadState ParserState)++newtype ParserState = ParserState+                     { counterMap :: M.Map Text (CounterType, Int)+                     }+        deriving (Show)++data ParserConfig = ParserConfig+                    { filePath :: FilePath+                    , blockContexts :: [BlockContext]+                    , hardBreaks :: Bool+                    } deriving (Show)++data ParseError = ParseError { errorPosition :: Int+                             , errorMessage :: String+                             } deriving (Show)++parse :: P a -> FilePath -> T.Text -> Either ParseError a+parse p fp = parse' (ParserConfig{ filePath = fp+                                 , blockContexts = []+                                 , hardBreaks = False+                                 })+                    (ParserState { counterMap = mempty })+                    p++parse' :: ParserConfig -> ParserState+       -> P a -> T.Text -> Either ParseError a+parse' cfg st p t =+  go $ A.parse (evalStateT ( runReaderT (unP p) cfg ) st) t+ where+  go (A.Fail i _ msg) = Left $ ParseError (T.length t - T.length i) msg+  go (A.Partial continue) = go (continue "")+  go (A.Done _i r) = Right r++localP :: (ParserConfig -> ParserConfig) -> P a -> P a+localP f (P p) = P (local f p)++withBlockContext :: BlockContext -> P a -> P a+withBlockContext bc =+  localP (\conf -> conf{ blockContexts = bc : blockContexts conf })++withHardBreaks :: P a -> P a+withHardBreaks = localP (\conf -> conf{ hardBreaks = True })++liftP :: A.Parser a -> P a+liftP = P . lift . lift++vchar :: Char -> P ()+vchar = liftP . void . A.char++char :: Char -> P Char+char = liftP . A.char++peekChar :: P (Maybe Char)+peekChar = liftP A.peekChar++peekChar' :: P Char+peekChar' = liftP A.peekChar'++anyChar :: P Char+anyChar = liftP A.anyChar++satisfy :: (Char -> Bool) -> P Char+satisfy = liftP . A.satisfy++space :: P Char+space = liftP A.space++isEndOfLine :: Char -> Bool+isEndOfLine = A.isEndOfLine++match :: P a -> P (T.Text, a)+match p = P $ do+  parseInfo <- ask+  parserState <- get+  lift . lift $ A.match (evalStateT (runReaderT (unP p) parseInfo) parserState)++string :: T.Text -> P T.Text+string = liftP . A.string++decimal :: Integral a => P a+decimal = liftP A.decimal++endOfInput :: P ()+endOfInput = liftP A.endOfInput++endOfLine :: P ()+endOfLine = liftP A.endOfLine++takeWhile :: (Char -> Bool) -> P T.Text+takeWhile f = liftP (A.takeWhile f)++takeWhile1 :: (Char -> Bool) -> P T.Text+takeWhile1 f = liftP (A.takeWhile1 f)++skipWhile :: (Char -> Bool) -> P ()+skipWhile f = liftP (A.skipWhile f)++skipMany :: P a -> P ()+skipMany = A.skipMany++option :: Alternative f => a -> f a -> f a+option = A.option++choice :: [P a] -> P a+choice = A.choice++count :: Int -> P a -> P [a]+count = A.count++manyTill :: P a -> P b  -> P [a]+manyTill = A.manyTill++sepBy :: P a -> P b -> P [a]+sepBy = A.sepBy++sepBy1 :: P a -> P b -> P [a]+sepBy1 = A.sepBy1++--- Block parsing:++data BlockContext =+    SectionContext Int+  | ListContext Char Int+  | DelimitedContext Char Int+  deriving (Show, Eq)+++pDocument :: P Document+pDocument = do+  meta <- pDocumentHeader+  let minSectionLevel = case M.lookup "doctype" (docAttributes meta) of+                          Just "book" -> 0+                          _ -> 1+  bs <- (case M.lookup "hardbreaks-option" (docAttributes meta) of+            Just "" -> withHardBreaks+            _ -> id) $+        withBlockContext (SectionContext (minSectionLevel - 1)) (many pBlock)+  skipWhile isSpace+  endOfInput+  pure $ Document { docMeta = meta , docBlocks = bs }++pDocumentHeader :: P Meta+pDocumentHeader = do+  let handleAttr m (Left k) = M.delete k m+      handleAttr m (Right (k,v)) = M.insert k v m+  let defaultDocAttrs = M.insert "sectids" "" mempty+  skipBlankLines+  topattrs <- foldl' handleAttr defaultDocAttrs <$> many pDocAttribute+  skipBlankLines+  (title, titleAttr) <- option ([], Nothing) $ do+    (_,titleAttr) <- pTitlesAndAttributes+    title <- pDocumentTitle+    pure (title, case titleAttr of+                   Attr [] kv | M.null kv -> Nothing+                   _ -> Just titleAttr)+  authors <- if null title+                then pure []+                else option [] pDocumentAuthors+  revision <- if null title+                 then pure Nothing+                 else optional pDocumentRevision+  attrs <- foldl' handleAttr topattrs <$> many pDocAttribute+  pure $ Meta{ docTitle = title+             , docTitleAttributes = titleAttr+             , docAuthors = authors+             , docRevision = revision+             , docAttributes = attrs }++pDocumentTitle :: P [Inline]+pDocumentTitle = do+  (vchar '=' <|> vchar '#') <* some (char ' ')+  pLine >>= parseInlines++pDocumentAuthors :: P [Author]+pDocumentAuthors = do+  mbc <- peekChar+  case mbc of+    Just c | isSpace c || c == ':' -> mzero+    _ -> parseAuthors <$> pLine++parseAuthors :: Text -> [Author]+parseAuthors =+  map (parseAuthor . T.strip) . T.split (== ';')++parseAuthor :: Text -> Author+parseAuthor t =+  Author { authorName = T.strip name+         , authorEmail = email }+ where+  (name, rest) = T.break (== '<') t+  email = case T.uncons rest of+            Just ('<', rest') -> Just $ T.takeWhile (/='>') rest'+            _ -> Nothing++pDocumentRevision :: P Revision+pDocumentRevision = do+  vprefix <- option False (True <$ vchar 'v')+  version <- takeWhile1 (\c -> not (isEndOfLine c) && c /= ',')+  date <- optional (T.strip <$> (vchar ',' *> space+               *> takeWhile1 (\c -> not (isEndOfLine c) && c /= ':')))+  remark <- optional+            (T.strip <$> (vchar ':' *>  space *> takeWhile (not . isEndOfLine)))+  endOfLine+  when (isNothing date && isNothing remark) $ guard vprefix+  pure  Revision { revVersion = version+                 , revDate = date+                 , revRemark = remark+                 }++pLine :: P Text+pLine = takeWhile (not . isEndOfLine) <* (endOfLine <|> endOfInput)+++-- Left key unsets key+-- Right (key, val) sets key+pDocAttribute :: P (Either Text (Text, Text))+pDocAttribute = do+  vchar ':'+  unset <- option False $ True <$ vchar '!'+  k <- pDocAttributeName+  vchar ':'+  v <- pLineWithEscapes+  pure $ if unset+            then Left k+            else Right (k,v)++pDocAttributeName :: P Text+pDocAttributeName = do+  c <- satisfy (\d -> isAscii d && (isAlphaNum d || d == '_'))+  cs <- many $+          satisfy (\d -> isAscii d && (isAlphaNum d || d == '_' || d == '-'))+  pure $ T.pack (c:cs)++pLineWithEscapes :: P Text+pLineWithEscapes = do+  _ <- takeWhile (== ' ')+  t <- takeWhile isLineEndChar+  endOfLine+  case T.stripSuffix "\\" t of+    Nothing -> pure t+    Just t' -> do+      case T.stripSuffix " +" t' of+        Nothing -> (t' <>) <$> pLineWithEscapes+        Just t'' -> ((t'' <> "\n") <>) <$> pLineWithEscapes++isLineEndChar :: Char -> Bool+isLineEndChar '\r' = False+isLineEndChar '\n' = False+isLineEndChar _ = True++skipBlankLines :: P ()+skipBlankLines = do+  contexts <- asks blockContexts+  case contexts of+    ListContext{} : _ -> void $ many $ vchar '+' *> pBlankLine+    _ -> void $ many pBlankLine++pBlankLine :: P ()+pBlankLine = takeWhile (\c -> c == ' ' || c == '\t') *> (pLineComment <|> endOfLine)++parseWith :: P a -> Text -> P a+parseWith p t = do+  cfg <- ask+  st <- get+  let result = parse' cfg st ((,) <$> p <*> get) t+  case result of+    Left e -> fail $ errorMessage e+    Right (x, newst) -> do+      put newst+      pure x++parseBlocks :: Text -> P [Block]+parseBlocks = parseWith (many pBlock) . (<> "\n") . T.strip++parseAsciidoc :: Text -> P Document+parseAsciidoc = parseWith pDocument . (<> "\n") . T.strip++parseParagraphs :: Text -> P [Block]+parseParagraphs = parseWith (many pParagraph) . (<> "\n") . T.strip+ where+  pParagraph = do+    skipBlankLines+    (mbtitle, attr@(Attr _ kvs)) <- pTitlesAndAttributes+    let hardbreaks = M.lookup "options" kvs == Just "hardbreaks"+    skipMany (pCommentBlock attr)+    (if hardbreaks then withHardBreaks else id) $ Block attr mbtitle <$> pPara++parseInlines :: Text -> P [Inline]+parseInlines = parseWith pInlines . T.strip++pBlock :: P Block+pBlock = do+  contexts <- asks blockContexts+  skipBlankLines+  (mbtitle, attr) <- pTitlesAndAttributes+  case contexts of+    ListContext{} : _ -> skipWhile (== ' ')+    _ -> pure ()+  skipMany (pCommentBlock attr)+  let hardbreaks =+       case attr of+          Attr _ kvs+            | Just opts <- M.lookup "options" kvs+              -> "hardbreaks" `T.isInfixOf` opts+          _ -> False+  (if hardbreaks then withHardBreaks else id) $+        pBlockMacro mbtitle attr+    <|> pDiscreteHeading mbtitle attr+    <|> pExampleBlock mbtitle attr+    <|> pSidebar mbtitle attr+    <|> pLiteralBlock mbtitle attr+    <|> pListing mbtitle attr+    <|> pFenced mbtitle attr+    <|> pVerse mbtitle attr+    <|> pQuoteBlock mbtitle attr+    <|> pPassBlock mbtitle attr+    <|> pOpenBlock mbtitle attr+    <|> pTable mbtitle attr+    <|> Block attr mbtitle <$>+          choice+            [ pSection+            , pThematicBreak+            , pPageBreak+            , pList+            , pDefinitionList+            , pIndentedLiteral+            , pPara+            ]+++pIndentedLiteral :: P BlockType+pIndentedLiteral = do+  xs <- some pIndentedLine+  let minIndent = minimum (map fst xs)+  let xs' = map (first (\x -> x - minIndent)) xs+  let t = T.unlines $ map (\(ind, x) -> T.replicate ind " " <> x) xs'+  pure $ LiteralBlock t++pIndentedLine :: P (Int, Text)+pIndentedLine = do+  ind <- length <$> some (vchar ' ')+  t <- pLine+  pure (ind, t)++pPageBreak :: P BlockType+pPageBreak = PageBreak <$ (string "<<<" <* pBlankLine)++pThematicBreak :: P BlockType+pThematicBreak = ThematicBreak <$+  (pThematicBreakAsciidoc <|> pThematicBreakMarkdown '-' <|> pThematicBreakMarkdown '*')+ where+   pThematicBreakAsciidoc = string "'''" *> pBlankLine+   pThematicBreakMarkdown c = count 3 (vchar c *> many (vchar ' ')) *> pBlankLine++pCommentBlock :: Attr -> P ()+pCommentBlock attr = pDelimitedCommentBlock <|> pAlternateCommentBlock+ where+  pDelimitedCommentBlock = void $ pDelimitedLiteralBlock '/' 4+  pAlternateCommentBlock = do+    case attr of+      Attr ["comment"] _ ->+        void (pDelimitedLiteralBlock '-' 2) <|>+                void (match (withBlockContext (SectionContext (-1)) pPara))+      _ -> mzero++pBlockMacro :: Maybe BlockTitle -> Attr -> P Block+pBlockMacro mbtitle attr = do+  (name, target) <- pBlockMacro'+  handleBlockMacro mbtitle attr name target++pBlockMacro' :: P (Text, Text)+pBlockMacro' = do+  name <- choice (map (\n -> string n <* string "::") (M.keys blockMacros))+  let targetChars = mconcat <$> some+        (takeWhile1 (\c -> not (isSpace c) && c /= '[' && c /= '+')+         <|>+         (vchar '\\' *> (T.singleton <$> satisfy (\c -> c == '[' || c == '+')))+         <|>+         (do Inline _ (Str t) <- pInMatched False '+' mempty (pure . Str)+             pure t))+  target <- mconcat <$> many targetChars+  pure (name, target)++handleBlockMacro :: Maybe BlockTitle -> Attr -> Text -> Text -> P Block+handleBlockMacro mbtitle attr name target =+  case M.lookup name blockMacros of+    Nothing -> mzero+    Just f -> f mbtitle attr target++blockMacros :: M.Map Text (Maybe BlockTitle -> Attr -> Text -> P Block)+blockMacros = M.fromList+  [ ("image", \mbtitle attr target -> do+        (Attr ps kvs) <- pAttributes+        let (mbalt, mbw, mbh) =+              case ps of+                (x:y:z:_) -> (Just (AltText x),+                              Width <$> readDecimal y, Height <$> readDecimal z)+                [x,y] -> (Just (AltText x), Width <$> readDecimal y, Nothing)+                [x] -> (Just (AltText x), Nothing, Nothing)+                [] -> (Nothing, Nothing, Nothing)+        pure $ Block (Attr mempty kvs <> attr) mbtitle+             $ BlockImage (Target target) mbalt mbw mbh)+  , ("video", \mbtitle attr target -> do+        attr' <- pAttributes+        pure $ Block (attr' <> attr) mbtitle+             $ BlockVideo (Target target))+  , ("audio", \mbtitle attr target -> do+        attr' <- pAttributes+        pure $ Block (attr' <> attr) mbtitle+             $ BlockAudio (Target target))+  , ("toc", \mbtitle attr _target -> do+        attr' <- pAttributes+        pure $ Block (attr' <> attr) mbtitle TOC)+  , ("include", \mbtitle attr target -> do+        attr' <- pAttributes+        fp <- asks filePath+        let path = resolvePath fp (T.unpack target)+        pure $ Block (attr' <> attr) mbtitle $ Include path Nothing)+  ]++pSection :: P BlockType+pSection = do+  contexts <- asks blockContexts+  case contexts of+    SectionContext sectionLevel : _ -> do+      lev <- (\x -> length x - 1) <$> (some (vchar '=') <|> some (vchar '#'))+      guard (lev > sectionLevel && lev >= 0 && lev <= 5)+      vchar ' '+      title <- pLine >>= parseInlines+      contents <- withBlockContext (SectionContext lev) $ many pBlock+      -- note: we use sectionLevel, not lev, so in improperly nested content, e.g.,+      -- == foo+      -- ==== bar+      -- ==== baz+      -- bar is a level-3 section and will contain baz!+      pure $ Section (Level (sectionLevel + 1)) title contents+    _ -> mzero++pDiscreteHeading :: Maybe BlockTitle -> Attr -> P Block+pDiscreteHeading mbtitle attr = do+  let (Attr ps kvs) = attr+  guard $ case ps of+            ("discrete":_) -> True+            _ -> False+  lev <- (\x -> length x - 1) <$> (some (vchar '=') <|> some (vchar '#'))+  guard (lev >= 0 && lev <= 5)+  vchar ' '+  title <- pLine >>= parseInlines+  pure $ Block (Attr (drop 1 ps) kvs) mbtitle $ DiscreteHeading (Level lev) title++pTitlesAndAttributes :: P (Maybe BlockTitle, Attr)+pTitlesAndAttributes = do+  items <- many pTitleOrAttribute+  let title = listToMaybe $ lefts items+  let attr = mconcat $ rights items+  pure (title, attr)++pTitleOrAttribute :: P (Either BlockTitle Attr)+pTitleOrAttribute =+  ((Left <$> pTitle)+    <|> (Right <$> (pAnchor <* endOfLine))+    <|> (Right <$> (pAttributes <* endOfLine))+  ) <* skipMany pBlankLine++pAnchor :: P Attr+pAnchor = do+  void $ string "[["  -- [[anchor]] can set id+  anchor <- takeWhile1 (\c -> not (isEndOfLine c || c == ']' || isSpace c))+  void $ string "]]"+  pure (Attr mempty (M.singleton "id" anchor))++pTitle :: P BlockTitle+pTitle = BlockTitle <$>+           (do vchar '.'+               mbc <- peekChar+               guard $ case mbc of+                         Just ' ' -> False+                         Just '.' -> False+                         _ -> True+               pLineWithEscapes >>= parseInlines)++pDefinitionList :: P BlockType+pDefinitionList =+  DefinitionList <$> some pDefinitionListItem++pDefinitionListItem :: P ([Inline],[Block])+pDefinitionListItem = do+  contexts <- asks blockContexts+  let marker = (do t <- takeWhile1 (== ':')+                   case contexts of+                       ListContext ':' n : _ -> guard (T.length t == n + 2)+                       _ -> guard (T.length t == 2))+  skipWhile (== ' ')+  term <- manyTill (takeWhile1 (\c -> not (isEndOfLine c || c == ':'))+                              <|> takeWhile1 (==':')) marker+                    >>= parseInlines . mconcat+  skipWhile (== ' ')+  option () endOfLine+  skipWhile (== ' ')+  let newContext = case contexts of+                      ListContext ':' n : _ -> ListContext ':' (n + 1)+                      _ -> ListContext ':' 1+  defn <- withBlockContext newContext (many pBlock)+  void $ many pBlankLine+  pure (term, defn)++pList :: P BlockType+pList = do+  (c, lev, mbStart, mbCheckboxState) <- pAnyListItemStart+  let guardContext ctx =+       case ctx of+         ListContext c' lev' -> guard $ c /= c' || lev > lev'+         _ -> pure ()+  asks blockContexts >>= mapM_ guardContext+  ListItem _ bs <- withBlockContext (ListContext c lev) pListItem+  let x = ListItem mbCheckboxState bs+  xs <- many (pListItemStart c lev *> withBlockContext (ListContext c lev) pListItem)+  let listType+        | c == '-'+        , Just _ <- mbCheckboxState+          = CheckList+        | c == '.' || c == '1' = OrderedList (Level lev) mbStart+        | c == '<' = CalloutList+        | otherwise = BulletList (Level lev)+  pure $ List listType (x:xs)++pAnyListItemStart :: P (Char, Int, Maybe Int, Maybe CheckboxState)+pAnyListItemStart = (do+  skipWhile (== ' ')+  c <- satisfy (\c -> c == '*' || c == '.' || c == '-' || c == '<')+  lev <- if c == '<'+            then pure 1+            else (+ 1) . T.length <$> takeWhile (== c)+  when (c == '<') $ do  -- callout list <1> or <.>+    void $ string "." <|> takeWhile1 isDigit+    vchar '>'+  vchar ' '+  mbCheck <- if c == '-' || c == '*'+                then optional pCheckbox+                else pure Nothing+  pure (c, lev, Nothing, mbCheck))+ <|> (do d <- decimal+         vchar '.'+         vchar ' '+         pure ('1', 1, Just d, Nothing))+++pCheckbox :: P CheckboxState+pCheckbox = do+  skipWhile (==' ')+  vchar '['+  c <- char ' ' <|> char 'x' <|> char '*'+  vchar ']'+  vchar ' '+  pure $ if c == ' '+            then Unchecked+            else Checked++pListItemStart :: Char -> Int -> P ()+pListItemStart c lev = do+  skipWhile (== ' ')+  case c of+    '<' -> vchar '<' *> (string "." <|> takeWhile1 isDigit) *> vchar '>'+    '1' -> do guard (lev == 1)+              void (decimal :: P Int)+              vchar '.'+    _ -> void $ count lev (vchar c)+  vchar ' '++pListItem :: P ListItem+pListItem = do+  mbCheckboxState <- optional pCheckbox+  skipWhile (==' ')+  bs <- many pBlock+  pure $ ListItem mbCheckboxState bs++pDelimitedLiteralBlock :: Char -> Int -> P [T.Text]+pDelimitedLiteralBlock c minimumNumber = do+  len <- length <$> some (vchar c) <* pBlankLine+  guard $ len >= minimumNumber+  let endFence = count len (vchar c) *> pBlankLine+  manyTill pLine endFence++pDelimitedBlock :: Char -> Int -> P [Block]+pDelimitedBlock c minimumNumber = do+  len <- length <$> some (vchar c) <* pBlankLine+  guard $ len >= minimumNumber+  let endFence = count len (vchar c) *> pBlankLine+  withBlockContext (DelimitedContext c len) $+    manyTill pBlock endFence++pPassBlock :: Maybe BlockTitle -> Attr -> P Block+pPassBlock mbtitle attr = do+  t <- T.unlines <$> pDelimitedLiteralBlock '+' 4+  case attr of+    Attr ("stem":ps) kvs ->+      pure $ Block (Attr ps kvs) mbtitle $ MathBlock Nothing t+    Attr ("asciimath":ps) kvs ->+      pure $ Block (Attr ps kvs) mbtitle $ MathBlock (Just AsciiMath) t+    Attr ("latexmath":ps) kvs ->+      pure $ Block (Attr ps kvs) mbtitle $ MathBlock (Just LaTeXMath) t+    _ -> pure $ Block attr mbtitle $ PassthroughBlock t++pLiteralBlock :: Maybe BlockTitle -> Attr -> P Block+pLiteralBlock mbtitle attr =+  (Block attr mbtitle . LiteralBlock . T.unlines <$> pDelimitedLiteralBlock '.' 4)+  <|>+  case attr of+    Attr ("literal":ps) kvs -> do+      t <- T.unlines <$> manyTill pLine (pBlankLine <|> endOfInput)+      pure $ Block (Attr ps kvs) mbtitle $ LiteralBlock t+    _ -> mzero++pFenced :: Maybe BlockTitle -> Attr -> P Block+pFenced mbtitle attr = do+  ticks <- takeWhile1 (== '`')+  guard $ T.length ticks >= 3+  lang' <- pLine+  let mblang = case T.strip lang' of+                 "" -> Nothing+                 l -> Just (Language l)+  lns <- toSourceLines <$> manyTill pLine (string ticks)+  pure $ Block attr mbtitle $ Listing mblang lns++pListing :: Maybe BlockTitle -> Attr -> P Block+pListing mbtitle attr = (do+  let (mbLang, attr') =+        case attr of+          Attr (_:lang:ps) kvs -> (Just (Language lang), Attr ps kvs)+          Attr ["source"] kvs -> (Nothing, Attr [] kvs)+          _ -> (Nothing, attr)+  lns <- toSourceLines <$> pDelimitedLiteralBlock '-' 4+  fp <- asks filePath+  pure $ Block attr' mbtitle $+    case lns of+      [SourceLine x []] | "include::" `T.isPrefixOf` x+          , Right ("include", target) <- parse pBlockMacro' fp x+          -> IncludeListing mbLang (resolvePath fp (T.unpack target)) Nothing+      _ -> Listing mbLang lns)+ <|>+  (case attr of+    Attr ("listing":ps) kvs -> do+      lns <- toSourceLines <$> manyTill pLine (pBlankLine <|> endOfInput)+      pure $ Block (Attr ps kvs) mbtitle $ Listing Nothing lns+    Attr ("source":lang:ps) kvs -> do+      lns <- toSourceLines <$> manyTill pLine (pBlankLine <|> endOfInput)+      pure $ Block (Attr ps kvs) mbtitle+           $ Listing (Just (Language lang)) lns+    Attr ["source"] kvs -> do+      lns <- toSourceLines <$> manyTill pLine (pBlankLine <|> endOfInput)+      pure $ Block (Attr [] kvs) mbtitle $ Listing Nothing lns+    _ -> mzero)++-- parse out callouts+toSourceLines :: [T.Text] -> [SourceLine]+toSourceLines = go 1+ where+   go _ [] = []+   go nextnum (t:ts) =+     let (t', callouts) = getCallouts [] t+         (nextnum'', callouts') =+                    foldl' (\(nextnum', cs) c ->+                               case c of+                                 Nothing -> (nextnum' + 1, Callout nextnum' : cs)+                                 Just i -> (i + 1, Callout i : cs))+                       (nextnum, []) callouts+     in SourceLine t' (reverse callouts') : go nextnum'' ts+   getCallouts callouts t =+    case T.breakOnAll "<" t of+      [] -> (t, callouts)+      xs@(_:_) ->+        let (t', rest) = last xs+            (ds, rest') = T.span (\c -> isDigit c || c == '.') (T.drop 1 rest)+         in if T.strip rest' == ">" && (T.all isDigit ds || ds == ".")+               then+                 if ds == "."+                    then getCallouts (Nothing : callouts) (T.stripEnd t')+                    else case readDecimal ds of+                           Just num -> getCallouts (Just num : callouts) (T.stripEnd t')+                           Nothing -> (t, callouts)+               else (t, callouts)++pExampleBlock :: Maybe BlockTitle -> Attr -> P Block+pExampleBlock mbtitle attr = do+  bs <- pDelimitedBlock '=' 4+  pure $ case attr of+    Attr (p:ps) kvs |+      Just adm <- parseAdmonitionType p ->+        Block (Attr ps kvs) mbtitle $ Admonition adm bs+    _ -> Block attr mbtitle $ ExampleBlock bs++pSidebar :: Maybe BlockTitle -> Attr -> P Block+pSidebar mbtitle attr =+  Block attr mbtitle . Sidebar <$> pDelimitedBlock '*' 4++pVerse :: Maybe BlockTitle -> Attr -> P Block+pVerse mbtitle (Attr ("verse":xs) kvs) = do+  let attribution = T.intercalate ", " xs+  let mbAttribution = if T.null attribution+                         then Nothing+                         else Just (Attribution attribution)+  bs <- withHardBreaks $+           pDelimitedBlock '-' 2+       <|> pDelimitedBlock '_' 4+       <|> ((:[]) . Block mempty Nothing <$> pPara)+  pure $ Block (Attr [] kvs) mbtitle $ Verse mbAttribution bs+pVerse _ _ = mzero++pQuoteBlock :: Maybe BlockTitle -> Attr -> P Block+pQuoteBlock mbtitle (Attr ("quote":xs) kvs) = do+  let attribution = T.intercalate ", " xs+  let mbAttribution = if T.null attribution+                         then Nothing+                         else Just (Attribution attribution)+  bs <-    pDelimitedBlock '_' 4+       <|> pDelimitedBlock '-' 2+       <|> ((:[]) . Block mempty Nothing <$> pPara)+  pure $ Block (Attr [] kvs) mbtitle $ QuoteBlock mbAttribution bs+pQuoteBlock _ _ = mzero++pOpenBlock :: Maybe BlockTitle -> Attr -> P Block+pOpenBlock mbtitle attr = Block attr mbtitle <$>+  ((OpenBlock <$> pDelimitedBlock '-' 2)+   <|>+  (QuoteBlock Nothing <$>+     (pDelimitedBlock '-' 2 <|> pDelimitedBlock '_' 4)))++parseAdmonitionType :: T.Text -> Maybe AdmonitionType+parseAdmonitionType t =+  case t of+    "NOTE" -> Just Note+    "TIP" -> Just Tip+    "IMPORTANT" -> Just Important+    "CAUTION" -> Just Caution+    "WARNING" -> Just Warning+    _ -> Nothing++pPara :: P BlockType+pPara = do+  t' <- pNormalLine+  contexts <- asks blockContexts+  case contexts of+    SectionContext{} : _ | not (T.null t') -> do+      case T.head t' of+        c | c == '=' || c == '#' -> do+          let eqs = T.length $ T.takeWhile (==c) t'+          let after = T.take 1 $ T.dropWhile (==c) t'+          guard $ eqs < 1 || eqs > 6 || after /= " " -- section heading+        _ -> pure ()+    _ -> pure ()+  let (a,b) = T.break (== ':') t'+  let (t, mbAdmonition)+        = if ": " `T.isPrefixOf` b+          then+            let newt = T.drop 2 b+            in  case parseAdmonitionType a of+                 Just adm -> (newt, Just adm)+                 Nothing -> (t', Nothing)+          else (t', Nothing)+  ts <- many pNormalLine+  hardbreaks <- asks hardBreaks+  ils <- (if hardbreaks+             then newlinesToHardbreaks+             else id) <$> parseInlines (T.unlines (t:ts))+  pure $ case mbAdmonition of+           Nothing -> Paragraph ils+           Just admonType -> Admonition admonType+                  [Block mempty Nothing (Paragraph ils)]++newlinesToHardbreaks :: [Inline] -> [Inline]+newlinesToHardbreaks [] = []+newlinesToHardbreaks (Inline attr (Str t) : xs) | T.any (=='\n') t =+  intersperse (Inline attr HardBreak)+    (map (Inline attr . Str) (T.lines t)) ++ newlinesToHardbreaks xs+newlinesToHardbreaks (x : xs) = x : newlinesToHardbreaks xs++pNormalLine :: P Text+pNormalLine = do+  t <- pLine+  fp <- asks filePath+  guard $ not $ T.all (\c -> c == ' ' || c == '\t') t+  guard $ T.take 1 t /= "[" ||+          case parse (pAttributes *> skipWhile isSpace *> endOfInput)+                     fp t of+                Left _ -> True+                _ -> False+  let t' = T.stripEnd t+  contexts <- asks blockContexts+  let delims = [(c, num) | DelimitedContext c num <- contexts]+  mapM_ (\(c, num) -> guard (not (T.all (== c) t' && T.length t' == num)))+        delims+  case contexts of+    ListContext{} : _ -> do+      guard $ t' /= "+"+      guard $ not $ "::" `T.isInfixOf` t'+      guard $ case parse pAnyListItemStart fp (T.strip t) of+                Left _ -> True+                _ -> False+    _ -> pure ()+  pure t+++--- Table parsing:++pTableBorder :: P TableSyntax+pTableBorder = do+  syntax <- (PSV <$ vchar '|') <|> (DSV <$ vchar ':') <|> (CSV <$ vchar ',')+  void $ string "==="+  skipWhile (=='=')+  pBlankLine+  skipMany pBlankLine+  pure syntax++pTable :: Maybe BlockTitle -> Attr -> P Block+pTable mbtitle (Attr ps kvs) = do+  syntax' <- pTableBorder+  mbcolspecs <- maybe (pure Nothing) (fmap Just . parseColspecs)+                  (M.lookup "cols" kvs)+  let options = maybe [] T.words $ M.lookup "options" kvs+  let syntax = case M.lookup "format" kvs of+                 Just "psv" -> PSV+                 Just "csv" -> CSV+                 Just "dsv" -> DSV+                 Just "tsv" -> TSV+                 _ -> syntax'+  let mbsep = case M.lookup "separator" kvs of+                 Just sep ->+                   case T.uncons sep of+                     Just (c,_) -> Just c+                     _ -> Nothing+                 _ -> Nothing+  let tableOpts = TableOpts { tableSyntax = syntax+                            , tableSeparator = mbsep+                            , tableHeader = "header" `elem` options ||+                                "noheader" `notElem` options+                            , tableFooter = "footer" `elem` options ||+                                "nofooter" `notElem` options+                            }+  let getRows mbspecs rowspans = (([],[]) <$ pTableBorder) <|>+         do -- for this row, we modify the specs based on rowspans+            -- if there are rowspans from rows above, we need to skip some:+            let mbspecs' = case mbspecs of+                             Nothing -> Nothing+                             Just specs' -> Just [s | (s,0) <- zip specs' rowspans]+            row@(TableRow cells) <- pTableRow tableOpts mbspecs'+            let numcols = sum (map cellColspan cells)+            let specs = fromMaybe (replicate numcols defaultColumnSpec) mbspecs+            -- now, update rowspans in light of new row+            let updateRowspans [] rs = rs+                updateRowspans (c:cs) rs =+                  map (+ (cellRowspan c - 1)) (take (cellColspan c) rs)+                  ++ updateRowspans cs (drop (cellColspan c) rs)+            let rowspans' = updateRowspans cells rowspans+            (\(rows, colspecs') -> (row:rows, case rows of+                                                 [] -> specs+                                                 _ -> colspecs'))+                                     <$> getRows (Just specs) rowspans'+  (rows, colspecs') <- getRows mbcolspecs (repeat (0 :: Int))+  let attr' = Attr ps $ M.delete "format" .+                        M.delete "separator" .+                        M.delete "cols" .+                        M.delete "options" $ kvs+  let (mbHead, rest)+        | tableHeader tableOpts = (Just (take 1 rows), drop 1 rows)+        | otherwise = (Nothing, rows)+  let (mbFoot, bodyRows)+        | tableFooter tableOpts+        , not (null rest) = (Just (drop (length rest - 1) rest),+                             take (length rest - 1) rest)+        | otherwise = (Nothing, rest)+  pure $ Block attr' mbtitle $ Table colspecs' mbHead bodyRows mbFoot++parseColspecs :: T.Text -> P [ColumnSpec]+parseColspecs t = do+  fp <- asks filePath+  case parse pColspecs fp t of+    Left e -> fail $ errorMessage e+    Right cs -> pure cs++pColspecs :: P [ColumnSpec]+pColspecs = mconcat <$> sepBy pColspecPart pComma <* option () pComma++pColspecPart :: P [ColumnSpec]+pColspecPart = do+  multiplier <- option 1 pMultiplier+  replicate multiplier <$> pColspec++pMultiplier :: P Int+pMultiplier = decimal <* vchar '*'++pColspec :: P ColumnSpec+pColspec = ColumnSpec <$> optional pHorizAlign+                      <*> optional pVertAlign+                      <*> (pWidth <|> pure Nothing)+                      <*> (toCellStyle <$> satisfy (A.inClass "adehlms")+                             <|> pure Nothing)++pHorizAlign :: P HorizAlign+pHorizAlign =+  (AlignLeft <$ vchar '<') <|> (AlignCenter <$ vchar '^') <|> (AlignRight <$ vchar '>')++pVertAlign :: P VertAlign+pVertAlign = do+  vchar '.'+  (AlignTop <$ vchar '<') <|> (AlignMiddle <$ vchar '^') <|> (AlignBottom <$ vchar '>')++pWidth :: P (Maybe Int)+pWidth = (Just <$> (decimal <* option () (vchar '%'))) <|> (Nothing <$ vchar '~')++data TableSyntax =+    PSV+  | CSV+  | TSV+  | DSV+  deriving (Show)++data TableOpts =+  TableOpts { tableSyntax :: TableSyntax+            , tableSeparator :: Maybe Char+            , tableHeader :: Bool+            , tableFooter :: Bool+            }+  deriving (Show)++pTableRow :: TableOpts -> Maybe [ColumnSpec] -> P TableRow+pTableRow opts mbcolspecs = TableRow <$>+  case tableSyntax opts of+       PSV+         | Just colspecs <- mbcolspecs  ->+             let getCell :: [ColumnSpec] -> P [TableCell]+                 getCell [] = pure []+                 getCell colspecs' = do+                   xs <- pTableCellPSV (tableSeparator opts) True colspecs'+                   skipMany pBlankLine+                   (xs ++) <$> getCell (drop (sum (map cellColspan xs)) colspecs')+             in  getCell colspecs+         | otherwise -> mconcat <$>+               some (pTableCellPSV (tableSeparator opts)+                       False (repeat defaultColumnSpec))+                     <* skipMany pBlankLine+       CSV -> pCSVTableRow (fromMaybe ',' $ tableSeparator opts) mbcolspecs+       TSV -> pCSVTableRow (fromMaybe '\t' $ tableSeparator opts) mbcolspecs+       DSV -> pDSVTableRow (fromMaybe ':' $ tableSeparator opts) mbcolspecs++defaultColumnSpec :: ColumnSpec+defaultColumnSpec = ColumnSpec Nothing Nothing Nothing Nothing++-- Note: AsciiDoc weirdly gobbles cells for rows even across CSV+-- row boundaries. We're not going to do that.++-- allows "; escape this as ""; delim can't be escaped+pCSVTableRow :: Char -> Maybe [ColumnSpec] -> P [TableCell]+pCSVTableRow delim mbcolspecs = do+  let colspecs = fromMaybe [] mbcolspecs+  as <- sepBy (pCSVCell delim) (vchar delim)+  pBlankLine *> skipMany pBlankLine+  zipWithM toBasicCell as (colspecs ++ repeat defaultColumnSpec)++pCSVCell :: Char -> P T.Text+pCSVCell delim = do+  skipWhile (== ' ')+  mbc <- peekChar+  case mbc of+    Just '"'+      -> vchar '"' *>+          (T.pack <$>+            manyTill (satisfy (/='"') <|> ('"' <$ string "\"\"")) (vchar '"'))+    _ -> T.strip . T.replace "\"\"" "\"" <$>+           takeWhile1 (\c -> c /= delim && not (isEndOfLine c))++-- no "; escape delim with backslash+pDSVTableRow:: Char -> Maybe [ColumnSpec] -> P [TableCell]+pDSVTableRow delim mbcolspecs = do+  let colspecs = fromMaybe [] mbcolspecs+  as <- sepBy (pDSVCell delim) (vchar delim)+  pBlankLine *> skipMany pBlankLine+  zipWithM toBasicCell as (colspecs ++ repeat defaultColumnSpec)++pDSVCell :: Char -> P T.Text+pDSVCell delim =+  T.strip . mconcat <$>+    many (takeWhile1 (\c -> c /= delim && c /= '\\' && not (isEndOfLine c))+       <|> (vchar '\\' *> ((\c -> "\\" <> T.singleton c) <$> anyChar)))++toBasicCell :: T.Text -> ColumnSpec -> P TableCell+toBasicCell t colspec = do+  bs <- parseCellContents (fromMaybe DefaultStyle (colStyle colspec)) t+  pure TableCell+         { cellContent = bs+         , cellHorizAlign = Nothing+         , cellVertAlign = Nothing+         , cellColspan = 1+         , cellRowspan = 1+         }+++pTableCellPSV :: Maybe Char -> Bool -> [ColumnSpec] -> P [TableCell]+pTableCellPSV mbsep allowNewlines colspecs = do+  let sep = fromMaybe '|' mbsep+  cellData <- pCellSep sep+  t <- T.pack <$>+         many+          (notFollowedBy (void (pCellSep sep) <|> void pTableBorder) *>+           ((vchar '\\' *> char sep)+             <|> satisfy (not . isEndOfLine)+             <|> if allowNewlines+                    then satisfy isEndOfLine+                    else satisfy isEndOfLine <* notFollowedBy (pCellSep sep)))+  let cell' = TableCell+               { cellContent = []+               , cellHorizAlign = cHorizAlign cellData+               , cellVertAlign = cVertAlign cellData+               , cellColspan = fromMaybe 1 $ cColspan cellData+               , cellRowspan = fromMaybe 1 $ cRowspan cellData+               }+  let rawcells = replicate (cDuplicate cellData) (cell', t)+  reverse . fst <$> foldM (\(cells, specs) (cell, rawtext) -> do+                        let defsty = case specs of+                                       spec:_ -> colStyle spec+                                       _ -> Nothing+                        let sty = fromMaybe DefaultStyle $ cStyle cellData <|> defsty+                        bs <- parseCellContents sty rawtext+                        pure (cell{ cellContent = bs } : cells,+                              drop (cellColspan cell) specs))+                ([],colspecs)+                rawcells+++parseCellContents :: CellStyle -> T.Text -> P [Block]+parseCellContents sty t =+  case sty of+    AsciiDocStyle -> docBlocks <$> parseAsciidoc t+    DefaultStyle -> parseParagraphs t+    LiteralStyle -> pure [Block mempty Nothing $ LiteralBlock t]+    EmphasisStyle -> map (surroundPara Italic) <$> parseBlocks t+    StrongStyle -> map (surroundPara Bold) <$> parseBlocks t+    MonospaceStyle -> map (surroundPara Monospace) <$> parseBlocks t+    HeaderStyle -> parseBlocks t+ where+   surroundPara :: ([Inline] -> InlineType) -> Block -> Block+   surroundPara bt (Block attr mbtitle (Paragraph ils)) =+     Block attr mbtitle (Paragraph [Inline mempty $ bt ils])+   surroundPara _ b = b+++data CellData =+  CellData+  { cDuplicate :: Int+  , cHorizAlign :: Maybe HorizAlign+  , cVertAlign :: Maybe VertAlign+  , cColspan :: Maybe Int+  , cRowspan :: Maybe Int+  , cStyle :: Maybe CellStyle }+  deriving (Show)++toCellStyle :: Char -> Maybe CellStyle+toCellStyle 'a' = Just AsciiDocStyle+toCellStyle 'd' = Just DefaultStyle+toCellStyle 'e' = Just EmphasisStyle+toCellStyle 'h' = Just HeaderStyle+toCellStyle 'l' = Just LiteralStyle+toCellStyle 'm' = Just MonospaceStyle+toCellStyle 's' = Just StrongStyle+toCellStyle _   = Nothing++-- 2+| colspan 2+-- 3.+| rowspan 3+-- 2.3+| colspan 2, rowspan 3+-- 2*| duplicate cell twice+-- 2*.3+^.>s| duplicate 2x, rowspan 3, top align, right align, s style+pCellSep :: Char -> P CellData+pCellSep sep = do+  mult <- option 1 pMultiplier+  (colspan, rowspan) <- option (Nothing, Nothing) $ do+    a <- optional decimal+    b <- optional $ vchar '.' *> decimal+    guard $ not (isNothing a && isNothing b)+    vchar '+'+    pure (a, b)+  halign <- optional pHorizAlign+  valign <- optional pVertAlign+  sty <- (toCellStyle <$> satisfy (A.inClass "adehlms")) <|> pure Nothing+  notFollowedBy pTableBorder <* vchar sep+  pure $ CellData+    { cDuplicate = mult+    , cHorizAlign = halign+    , cVertAlign = valign+    , cColspan = colspan+    , cRowspan = rowspan+    , cStyle = sty+    }+++--- Inline parsing:++pInlines :: P [Inline]+pInlines = pInlines' []++pComma :: P ()+pComma = vchar ',' <* skipWhile isSpace++pFormattedTextAttributes :: P Attr+pFormattedTextAttributes = do+  vchar '['+  as <- pShorthandAttributes+  ps <- option []+         (do unless (as == mempty) pComma+             sepBy1 pAttributeValue pComma <* option () pComma)+  vchar ']'+  if as == mempty+     then+       case ps of+         [] -> pure mempty+         (x:_) -> pure $ Attr [] (M.fromList [("role",x)])+     else pure as++pAttributes :: P Attr+pAttributes = do+  vchar '['+  (xs, as) <- option ([], mempty) $ do+    x <- takeWhile (\c -> isAlphaNum c || c == '-' || c == '_')+    as <- pShorthandAttributes+    case as of+       Attr [] m | M.null m -> mzero+       _ -> pure ([x | not (T.null x)] , as)+  bs <- option []+         (do unless (as == mempty) pComma+             sepBy pAttribute pComma <* option () pComma)+  vchar ']'+  let positional = xs ++ lefts bs+  let kvs = rights bs+  pure $ as <> Attr positional (M.fromList kvs)++pAttribute :: P (Either Text (Text,Text))+pAttribute = (Right <$> pKeyValue) <|> (Left <$> pPositional)++pKeyValue :: P (Text, Text)+pKeyValue = do+  k <- takeWhile1 (\c -> c /= ',' && c /= ']' && c /= '=')+  vchar '=' *> ((k,) <$> pAttributeValue)++pPositional :: P Text+pPositional = do+  v <- pAttributeValue+  mbc <- peekChar+  case mbc of+    Just ',' -> pure ()+    _ -> guard $ not $ T.null v+  pure v++pAttributeValue :: P Text+pAttributeValue = pQuotedAttr <|> pBareAttributeValue+ where+   pBareAttributeValue =+     T.strip <$> takeWhile (\c -> c /= ',' && c /= ']')+   pQuotedAttr = do+     vchar '"'+     result <- many (satisfy (/='"') <|> (vchar '\\' *> satisfy (/='"')))+     vchar '"'+     pure $ T.pack result++pInlines' :: [Char] -> P [Inline]+pInlines' cs =+  (do il' <- pInline cs+      let il = case il' of+                 Inline (Attr ps kvs) (Span ils)+                   | Nothing <- M.lookup "role" kvs+                   -> Inline (Attr ps kvs) (Highlight ils)+                 _ -> il'+      addStr . (il:) <$> pInlines' [])+  <|> (do c <- anyChar+          pInlines' (c:cs))+  <|> (addStr [] <$ endOfInput)+ where+  addStr = case cs of+              [] -> id+              _  -> (Inline mempty (Str (T.pack (replaceChars $ reverse cs))):)++replaceChars :: [Char] -> [Char]+replaceChars [] = []+replaceChars ('(':'C':')':cs) = '\169':replaceChars cs+replaceChars ('(':'R':')':cs) = '\174':replaceChars cs+replaceChars ('(':'T':'M':')':cs) = '\8482':replaceChars cs+replaceChars (x:'-':'-':y:cs)+  | x == ' ', y == ' ' = '\8201':'\8212':'\8201':replaceChars cs+  | isAlphaNum x, isAlphaNum y = x:'\8212':'\8203':replaceChars (y:cs)+  | otherwise = x:'-':'-':replaceChars (y:cs)+replaceChars ('.':'.':'.':cs) = '\8230':replaceChars cs+replaceChars ('-':'>':cs) = '\8594':replaceChars cs+replaceChars ('=':'>':cs) = '\8658':replaceChars cs+replaceChars ('<':'-':cs) = '\8592':replaceChars cs+replaceChars ('<':'=':cs) = '\8656':replaceChars cs+replaceChars ('\'':cs) = '\8217':replaceChars cs+replaceChars (c:cs) = c:replaceChars cs++pShorthandAttributes :: P Attr+pShorthandAttributes = do+  attr <- mconcat <$>+          many (skipWhile isSpace *>+                (Attr [] . uncurry M.singleton <$> pShorthandAttribute))+  skipWhile isSpace+  pure attr++pShorthandAttribute :: P (Text,Text)+pShorthandAttribute = do+  let isSpecial c = c == '.' || c == '#' || c == '%' || c == ']' || c ==','+  c <- satisfy (\c -> c == '.' || c == '#' || c == '%')+  val <- T.strip <$> takeWhile (not . isSpecial)+  key <- case c of+           '.' -> pure "role"+           '#' -> pure "id"+           '%' -> pure "options"+           _ -> mzero+  pure (key, val)++pInline :: [Char] -> P Inline+pInline prevChars = do+  let maybeUnconstrained = case prevChars of+                              (d:_) -> isSpace d || isPunctuation d+                              [] -> True+  let inMatched = pInMatched maybeUnconstrained+  skipMany pLineComment+  (do attr <- pFormattedTextAttributes <|> pure mempty+      c <- peekChar'+      case c of+        '*' -> inMatched '*' attr (fmap Bold . parseInlines)+        '_' -> inMatched '_' attr (fmap Italic . parseInlines)+        '`' -> inMatched '`' attr (fmap Monospace . parseInlines)+        '#' -> inMatched '#' attr (fmap Span . parseInlines)+        '~' -> pInSingleMatched '~' attr (fmap Subscript . parseInlines)+        '^' -> pInSingleMatched '^' attr (fmap Superscript . parseInlines)+        '+' -> pTriplePassthrough <|> inMatched '+' attr (pure . Str)+        '"' -> pQuoted '"' attr DoubleQuoted+        '\'' -> pQuoted '\'' attr SingleQuoted+        '(' -> pIndexEntry attr+        _ -> mzero)+     <|> (do c <- peekChar'+             case c of+               '\'' -> pApostrophe '\''+               '+' -> pHardBreak+               '{' -> pCounter <|> pAttributeReference+               '\\' -> pEscape+               '<' -> pBracedAutolink <|> pCrossReference+               '&' -> pCharacterReference+               '[' -> pBibAnchor <|> pInlineAnchor+               _ | isLetter c -> pInlineMacro <|> pAutolink <|> pEmailAutolink+                 | otherwise -> mzero)++pIndexEntry :: Attr -> P Inline+pIndexEntry attr = do+  void $ string "(("+  concealed <- option False $ True <$ vchar '('+  terms <- takeWhile1 (/= ')')+  Inline attr <$>+    if concealed+       then IndexEntry (TermConcealed (map T.strip (T.split (==',') terms)))+                         <$ string ")))"+       else IndexEntry (TermInText terms) <$ string "))"++pTriplePassthrough :: P Inline+pTriplePassthrough = Inline mempty . Passthrough . T.pack+    <$> (string "+++" *> manyTill anyChar (string "+++"))++pLineComment :: P ()+pLineComment = string "//" *> skipWhile (== ' ') *> void pLine++pCrossReference :: P Inline+pCrossReference = do+  void $ string "<<"+  t <- T.pack <$> manyTill (satisfy (not . isEndOfLine)) (void (string ">>"))+  let ts = T.split (==',') t+  case ts of+    [] -> mzero+    [x] -> pure $ Inline mempty $ CrossReference x Nothing+    (x:xs) -> Inline mempty . CrossReference x . Just+                       <$> parseInlines (T.intercalate "," xs)++data MatchState = Backslash | OneDelim | Regular+  deriving Show++-- used for super/subscript, which can't accept spaces but take single delims+pInSingleMatched :: Char -> Attr -> (Text -> P InlineType) -> P Inline+pInSingleMatched delim attr toInlineType = do+  vchar delim+  cs <- manyTill (satisfy (not . isSpace)) (vchar delim)+  guard $ not $ null cs+  Inline attr <$> toInlineType (T.pack cs)++pInMatched :: Bool -> Char -> Attr -> (Text -> P InlineType) -> P Inline+pInMatched maybeUnconstrained delim attr toInlineType = do+  vchar delim+  isDoubled <- option False (True <$ vchar delim)+  followedBySpace <- maybe True isSpace <$> peekChar+  guard $ isDoubled || (maybeUnconstrained && not followedBySpace)+  cs <- manyTill ( (vchar '\\' *> char delim) <|> anyChar )+                   (if isDoubled+                       then vchar delim *> vchar delim+                       else vchar delim)+  guard $ not $ null cs+  when (not isDoubled && maybeUnconstrained) $ do+    mbc <- peekChar+    case mbc of+      Nothing -> pure ()+      Just c -> guard $ isSpace c || isPunctuation c+  Inline attr <$> toInlineType (T.pack cs)++pInlineAnchor :: P Inline+pInlineAnchor = do+  void $ string "[["+  contents <- T.pack <$> manyTill anyChar (string "]]")+  let (anchorId, xrefLabel) =+        case T.split (==',') contents of+          [] -> (mempty, mempty)+          (x:ys) -> (x, mconcat ys)+  Inline mempty . InlineAnchor anchorId <$> parseInlines xrefLabel++pBibAnchor :: P Inline+pBibAnchor = do+  void $ string "[[["+  contents <- T.pack <$> manyTill anyChar (string "]]]")+  let (anchorId, xrefLabel) =+        case T.split (==',') contents of+          [] -> (mempty, mempty)+          (x:ys) -> (x, mconcat ys)+  skipWhile (== ' ')+  Inline mempty . BibliographyAnchor anchorId <$> parseInlines xrefLabel++pCharacterReference :: P Inline+pCharacterReference =+  vchar '&' *> (pNumericCharacterReference <|> pCharacterEntityReference)++pNumericCharacterReference :: P Inline+pNumericCharacterReference =+  vchar '#' *> (((vchar 'x' <|> vchar 'X') *> pHexReference) <|> pDecimalReference)+ where+  pHexReference =+    Inline mempty . Str . T.singleton . chr <$> (liftP A.hexadecimal <* vchar ';')+  pDecimalReference =+    Inline mempty . Str . T.singleton . chr <$> (decimal <* vchar ';')++pCharacterEntityReference :: P Inline+pCharacterEntityReference = do+  xs <- manyTill (satisfy isAlphaNum) (char ';' <|> space)+  case lookupNamedEntity xs of+    Just s -> pure $ Inline mempty (Str (T.pack s))+    Nothing -> mzero++pQuoted :: Char -> Attr -> ([Inline] -> InlineType) -> P Inline+pQuoted c attr constructor = do+  vchar c+  result <- pInMatched True '`' attr (fmap constructor . parseInlines)+  vchar c+  return result++pApostrophe :: Char -> P Inline+pApostrophe '`' = Inline mempty (Str "’") <$ string "`'"+pApostrophe _ = mzero++pInlineMacro :: P Inline+pInlineMacro = do+  name <- choice (map (\n -> string n <* vchar ':') (M.keys inlineMacros))+  let targetChars = mconcat <$> some+       ( (string "pass:" *> vchar '[' *> takeWhile1 (/=']') <* vchar ']')+         <|>+         takeWhile1 (\c -> not (isSpace c) && c /= '[' && c /= '+')+         <|>+         (vchar '\\' *> (T.singleton <$> satisfy (\c -> c == '[' || c == '+')))+         <|>+        (do Inline _ (Str t) <- pInMatched False '+' mempty (pure . Str)+            pure t)+       )+  target <- mconcat <$> many targetChars+  handleInlineMacro name target++handleInlineMacro :: Text -> Text -> P Inline+handleInlineMacro name target =+  case M.lookup name inlineMacros of+    Nothing -> mzero+    Just f -> f target++inlineMacros :: M.Map Text (Text -> P Inline)+inlineMacros = M.fromList+  [ ("kbd", \_ -> do+       attr <- pAttributes+       let (description, attr') = extractDescription attr+       pure $ Inline attr' $ Kbd (map T.strip (T.split (=='+') description)))+  , ("menu", \target -> do+       attr <- pAttributes+       let (description, attr') = extractDescription attr+       pure $ Inline attr' $ Menu (target : filter (not . T.null)+                                    (map T.strip (T.split (=='>') description))))+  , ("btn", \_ -> do+       attr <- pAttributes+       let (description, attr') = extractDescription attr+       pure $ Inline attr' $ Button description)+  , ("icon", \target -> do+        attr <- pAttributes+        pure $ Inline attr $ Icon target)+  , ("anchor", \target -> do+        attr <- pAttributes+        let (anchorId, xrefLabel) =+              case T.split (==',') target of+                [] -> (mempty, mempty)+                (x:ys) -> (x, mconcat ys)+        Inline attr . InlineAnchor anchorId <$> parseInlines xrefLabel)+  , ("pass", \_ -> do+       attr <- pAttributes+       let (description, attr') = extractDescription attr+       pure $ Inline attr' $ Passthrough description)+  , ("link", \target -> do+      attr <- pAttributes+      let (description, attr') = extractDescription attr+      Inline attr' . Link URLLink (Target target)+          <$> (if T.null description+                  then pure [Inline mempty (Str target)]+                  else parseInlines description))+  , ("mailto", \target -> do+      attr <- pAttributes+      let (description, attr') = extractDescription attr+      Inline attr' . Link EmailLink (Target target)+             <$> if T.null description+                    then pure [Inline mempty (Str target)]+                    else parseInlines description)+  , ("footnote", \target -> do+      attr <- pAttributes+      let (contents, attr') = extractDescription attr+          fnid = if target == mempty+                    then Nothing+                    else Just (FootnoteId target)+      Inline attr' . Footnote fnid <$> parseInlines contents)+  , ("footnoteref", \_ -> do+      (Attr ps kvs) <- pAttributes+      (target, contents) <- case ps of+                                 (t:c:_) -> pure (t,c)+                                 [t] -> pure (t,mempty)+                                 _ -> mzero+      let fnid = if target == mempty+                  then Nothing+                  else Just (FootnoteId target)+      Inline (Attr mempty kvs) . Footnote fnid <$> parseInlines contents)+  , ("xref", \target -> do+        ils <- pBracketedText >>= parseInlines+        let mbtext = if null ils then Nothing else Just ils+        pure $ Inline mempty $ CrossReference target mbtext)+  , ("image", \target -> do+        (Attr ps kvs) <- pAttributes+        let (mbalt, mbw, mbh) =+              case ps of+                (x:y:z:_) -> (Just (AltText x), Width <$> readDecimal y,+                              Height <$> readDecimal z)+                [x,y] -> (Just (AltText x), Width <$> readDecimal y, Nothing)+                [x] -> (Just (AltText x), Nothing, Nothing)+                [] -> (Nothing, Nothing, Nothing)+        pure $ Inline (Attr mempty kvs) $ InlineImage (Target target) mbalt mbw mbh)+  , ("latexmath", \_ ->+      Inline mempty . Math (Just LaTeXMath) <$> pBracketedText)+  , ("asciimath", \_ ->+      Inline mempty . Math (Just AsciiMath) <$> pBracketedText)+  , ("stem", \_ ->+      Inline mempty . Math Nothing <$> pBracketedText)+  , ("indexterm", \_ ->+      Inline mempty . IndexEntry . TermConcealed .+        map T.strip . T.split (==',') <$> pBracketedText)+  , ("indexterm2", \_ ->+      Inline mempty . IndexEntry . TermInText <$> pBracketedText)+  ]++pBracketedText :: P Text+pBracketedText =+  vchar '[' *>+    (mconcat <$> many+         (T.pack <$> some ((vchar '\\' *> char ']') <|>+                 satisfy (\c -> c /= ']' && not (isEndOfLine c)) <|>+                 (' ' <$ (vchar '\\' <* endOfLine)))+          <|> ((\x -> "[" <> x <> "]") <$> pBracketedText)))+    <* vchar ']'++extractDescription :: Attr -> (Text, Attr)+extractDescription (Attr ps kvs) =+  let description = case ps of+                      (x:_) -> x+                      _ -> ""+  in (description, Attr (drop 1 ps) kvs)+++pEmailAutolink :: P Inline+pEmailAutolink = do+  a <- takeWhile1 (\c -> isAlphaNum c || c == '_' || c == '.' || c == '+')+  vchar '@'+  b <- takeWhile1 isLetter+  vchar '.'+  c <- takeWhile1 isLetter+  guard $ let lc = T.length c in lc >= 2 && lc <= 5+  let email = a <> "@" <> b <> "." <> c+  attr <- pAttributes <|> pure mempty+  let (description, attr') = extractDescription attr+  Inline attr' . Link EmailLink (Target email)+           <$> if T.null description+                  then pure [Inline mempty (Str email)]+                  else parseInlines description++pAutolink :: P Inline+pAutolink = do+  scheme <- choice (map string+               ["http:", "https:", "irc:", "ftp:", "mailto:"])+  let isSpecialPunct ',' = True+      isSpecialPunct '.' = True+      isSpecialPunct '?' = True+      isSpecialPunct '!' = True+      isSpecialPunct ':' = True+      isSpecialPunct ';' = True+      isSpecialPunct ')' = True+      isSpecialPunct _ = False+  let urlChunk = T.pack <$>+        some (satisfy (\c -> not (isSpace c) && c /= '[' && c /= '>'+                               && not (isSpecialPunct c))+             <|> (do c <- satisfy isSpecialPunct+                     mbd <- peekChar+                     case mbd of+                       Nothing -> mzero+                       Just d | isSpace d || isSpecialPunct d -> mzero+                       _ -> pure c))+  url <- (scheme <>) . mconcat <$> some+          (urlChunk <|> (do Inline _ (Str t) <- pInMatched False '+' mempty (pure . Str)+                            pure t))+  attr <- pAttributes <|> pure mempty+  let (description, attr') = extractDescription attr+  Inline attr' . Link URLLink (Target url)+             <$> if T.null description+                    then pure [Inline mempty (Str url)]+                    else parseInlines description++pBracedAutolink :: P Inline+pBracedAutolink = vchar '<' *> pAutolink <* vchar '>'++pEscape :: P Inline+pEscape =+  -- we allow letters to be escaped to handle escapes of macros+  -- though this also leads to differences from asciidoc+  vchar '\\' *>+   (Inline mempty . Str . T.singleton <$>+      satisfy (\c -> isPunctuation c || isLetter c))++pCounter :: P Inline+pCounter = do+  vchar '{' <* string "counter:"+  name <- pDocAttributeName+  mbvalue <- optional (vchar ':' *> pCounterValue)+  vchar '}'+  cmap <- gets counterMap+  let (ctype, val) =+        case M.lookup name cmap of+          Just (ctype', val') -> (ctype', val' + 1)+          Nothing ->+            case mbvalue of+              Nothing -> (DecimalCounter, 1)+              Just (ctype', val') -> (ctype', val')+  modify $ \st -> st{ counterMap =+                       M.insert name (ctype, val) (counterMap st) }+  pure $ Inline mempty $ Counter name ctype val++pCounterValue :: P (CounterType, Int)+pCounterValue = pUpperValue <|> pLowerValue <|> pDecimalValue+ where+   pUpperValue = do+     c <- satisfy (\c -> isAscii c && isUpper c)+     pure (UpperAlphaCounter, 1 + (ord c - ord 'A'))+   pLowerValue = do+     c <- satisfy (\c -> isAscii c && isLower c)+     pure (UpperAlphaCounter, 1 + (ord c - ord 'a'))+   pDecimalValue = do+     n <- decimal+     pure (DecimalCounter, n)++pAttributeReference :: P Inline+pAttributeReference = do+  vchar '{'+  name <- pDocAttributeName+  vchar '}'+  case M.lookup name replacements of+    Just r -> pure $ Inline mempty (Str r)+    Nothing -> pure $ Inline mempty $ AttributeReference (AttributeName name)++replacements :: M.Map Text Text+replacements = M.fromList+  [ ("blank", "")+  , ("empty", "")+  , ("sp", " ")+  , ("nbsp", "\160")+  , ("zwsp", "\8203")+  , ("wj", "\8288")+  , ("apos", "\39")+  , ("lsquo", "\8216")+  , ("rsquo", "\8217")+  , ("ldquo", "\8220")+  , ("rdquo", "\8221")+  , ("deg", "\176")+  , ("plus", "+")+  , ("brvbar", "\166")+  , ("vbar", "|")+  , ("amp", "&")+  , ("lt", "<")+  , ("gt", ">")+  , ("startsb", "[")+  , ("endsb", "]")+  , ("caret", "^")+  , ("asterisk", "*")+  , ("tilde", "~")+  , ("backslash", "\\")+  , ("backtick", "`")+  , ("two-colons", "::")+  , ("two-semicolons", ";;")+  , ("cpp", "C++")+  , ("cxx", "C++")+  , ("pp", "++")+  ]++pHardBreak :: P Inline+pHardBreak = do+  vchar '+'+  _ <- takeWhile1 (\c -> c == '\r' || c == '\n')+  pure $ Inline mempty HardBreak++--- Utility functions:++readDecimal :: Text -> Maybe Int+readDecimal t =+  case TR.decimal t of+    Left _ -> Nothing+    Right (x,_) -> Just x++notFollowedBy :: P a -> P ()+notFollowedBy p = optional p >>= guard . isNothing++-- Generate auto-identifiers for sections.++addIdentifiers :: Document -> Document+addIdentifiers doc =+  case M.lookup "sectids" docattr of+    Just _ -> evalState (mapBlocks (addIdentifier prefix idsep) doc) mempty+    Nothing -> doc+ where+  docattr = docAttributes (docMeta doc)+  prefix = fromMaybe "_" $ M.lookup "idprefix" docattr+  idsep = fromMaybe "_" $ M.lookup "idseparator" docattr++addIdentifier :: Text -> Text -> Block -> State (M.Map Text Int) Block+addIdentifier prefix idsep (Block (Attr ps kvs) mbtitle (Section lev ils bs))+  | Nothing <- M.lookup "id" kvs+  = do+      usedIds <- get+      let (ident, usedIds') = generateIdentifier prefix idsep usedIds ils+      put usedIds'+      pure $ Block (Attr ps (M.insert "id" ident kvs)) mbtitle+                     (Section lev ils bs)+addIdentifier _ _ x = pure x++generateIdentifier :: Text -> Text -> M.Map Text Int -> [Inline]+                   -> (Text, M.Map Text Int)+generateIdentifier prefix idsep usedIds ils =+  case M.lookup s usedIds of+    Nothing -> (s, M.insert s 1 usedIds)+    Just n -> (s <> idsep <> T.pack (show (n + 1)), M.insert s (n + 1) usedIds)+ where+  s = prefix <> makeSeps (T.toLower (toString ils))+  makeSeps = T.intercalate idsep . T.words .+               T.map (\case+                       '.' -> ' '+                       '-' -> ' '+                       c | isSpace c -> ' '+                         | otherwise -> c)+  toString = foldInlines getStr+  getStr (Inline _ (Str t)) = t+  getStr _ = ""
+ test/Main.hs view
@@ -0,0 +1,196 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+import Test.Tasty+import Test.Tasty.Golden+import Test.Tasty.HUnit+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.IO as TIO+import qualified Data.Text.Encoding as TE+import qualified Data.Text.Lazy.Encoding as TEL+import qualified Data.ByteString.Lazy as BL+import Data.List (sort)+import System.Directory (listDirectory)+import System.FilePath ((</>), takeBaseName, takeExtension)+import qualified Data.ByteString.Char8 as B+import AsciiDoc+import Text.Show.Pretty (ppShow)++main :: IO ()+main = do+  asciidoctorTests <- goldenTests "asciidoctor"+  featureTests <- goldenTests "feature"+  defaultMain $ testGroup "Tests"+    [ testGroup "Asciidoctor" asciidoctorTests+    , testGroup "Feature" featureTests+    , testGroup "Generic"+       [ foldInlineTest+       , foldBlockTest+       , mapInlineTest+       , mapBlockTest+       ]+    ]++goldenTests :: FilePath -> IO [TestTree]+goldenTests fp = do+  files <- findTestFiles ("test" </> fp)+  pure $ map (\(category, fs) ->+          testGroup category (map toGoldenTest fs)) files++-- Find all .test files in a directory+findTestFiles :: FilePath -> IO [(FilePath, [FilePath])]+findTestFiles baseDir = do+  categories <- listDirectory baseDir+  let go f = do+        xs <- map ((baseDir </> f) </>) <$> listDirectory (baseDir </> f)+        return (f, sort $ filter ((== ".test") . takeExtension) xs)+  mapM go categories++toGoldenTest :: FilePath -> TestTree+toGoldenTest fp =+  goldenVsStringDiff (takeBaseName fp) diff fp getTested+ where+  diff ref new = ["diff", "-u", ref, new]++  constructGoldenTest :: (T.Text, T.Text) -> IO BL.ByteString+  constructGoldenTest (inText, outText) =+    return $ TEL.encodeUtf8 $ TL.fromStrict $+      inText <> ">>>" <>+      "\n" <> ensureFinalNewline outText++  getTested = do+    (inText,_) <- readGoldenTest fp+    result <- convert inText+    constructGoldenTest (inText, result)++  raiseError path pos msg =+    error $ "Parse error at " <> show path <>+             " position " <> show pos <> ": " <> msg++  convert inText =+    T.pack . ppShow <$> parseDocument TIO.readFile raiseError fp inText++  readGoldenTest :: FilePath -> IO (T.Text, T.Text)+  readGoldenTest fp' = do+    lns <- B.lines <$> B.readFile fp'+    case break (B.isPrefixOf ">>>") lns of+      (inlines,outlines) -> return (TE.decodeUtf8 (B.unlines inlines),+                                    TE.decodeUtf8 (B.unlines $ drop 1outlines))+++ensureFinalNewline :: T.Text -> T.Text+ensureFinalNewline xs = case T.unsnoc xs of+  Nothing        -> xs+  Just (_, '\n') -> xs+  _              -> xs <> "\n"+++testDoc :: Document+testDoc = Document+  { docMeta = Meta [] Nothing [] Nothing mempty+  , docBlocks =+      [ Block mempty Nothing+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem Nothing+                 [ Block mempty Nothing+                     (Paragraph+                        [ Inline mempty (Str "nested ")+                        , Inline mempty+                            (Bold+                               [ Inline mempty (Str "inline ")+                               , Inline mempty (Italic [ Inline mempty (Str "and block") ])+                               ])+                        ])+                 , Block mempty Nothing+                     (List+                        (OrderedList (Level 2) Nothing)+                        [ ListItem Nothing+                            [ Block mempty (Just (BlockTitle [Inline mempty (Str "The title")]))+                                (Paragraph+                                   [ Inline mempty (Bold [ Inline mempty (Str "contents") ]) ])+                            ]+                        ])+                 ]+             ])+      ]+  }++foldInlineTest :: TestTree+foldInlineTest = testCase "foldInline" $ do+  foldInlines (\case+                  (Inline _ (Str s)) -> s+                  _ -> "") testDoc+    @?= "nested inline and blockThe titlecontents"++foldBlockTest :: TestTree+foldBlockTest = testCase "foldBlock" $ do+  foldBlocks (\case+                  Block _ (Just t) _ -> [t]+                  _ -> []) testDoc+    @?= [BlockTitle [Inline mempty (Str "The title")]]++mapInlineTest :: TestTree+mapInlineTest = testCase "mapInlines" $ do+  d <- mapInlines+              (\case+                 Inline _ (Str _) -> pure $ Inline mempty (Str "X")+                 x -> pure x) testDoc+  d @?= Document+      { docMeta = Meta [] Nothing [] Nothing mempty+      , docBlocks =+          [ Block mempty Nothing+              (List+                 (OrderedList (Level 1) Nothing)+                 [ ListItem Nothing+                     [ Block mempty Nothing+                         (Paragraph+                            [ Inline mempty (Str "X")+                            , Inline mempty+                                (Bold+                                   [ Inline mempty (Str "X")+                                   , Inline mempty (Italic [ Inline mempty (Str "X") ])+                                   ])+                            ])+                     , Block mempty Nothing+                         (List+                            (OrderedList (Level 2) Nothing)+                            [ ListItem Nothing+                                [ Block mempty (Just (BlockTitle [Inline mempty (Str "X")]))+                                    (Paragraph+                                       [ Inline mempty (Bold [ Inline mempty (Str "X") ]) ])+                                ]+                            ])+                     ]+                 ])+          ]+      }+++mapBlockTest :: TestTree+mapBlockTest = testCase "mapBlocks" $ do+  d <- mapBlocks+            (\case+               Block attr mbtitle (Paragraph _) ->+                 pure $ Block attr mbtitle ThematicBreak+               x -> pure x) testDoc+  d @?= Document+      { docMeta = Meta [] Nothing [] Nothing mempty+      , docBlocks =+          [ Block mempty Nothing+              (List+                 (OrderedList (Level 1) Nothing)+                 [ ListItem Nothing+                     [ Block mempty Nothing ThematicBreak+                     , Block mempty Nothing+                         (List+                            (OrderedList (Level 2) Nothing)+                            [ ListItem Nothing+                                [ Block mempty (Just (BlockTitle [Inline mempty (Str "The title")]))+                                    ThematicBreak+                                ]+                            ])+                     ]+                 ])+          ]+      }
+ test/asciidoctor/admonition/caution-block.test view
@@ -0,0 +1,43 @@+[CAUTION]+====+This is a caution with complex content.++* It contains a list.+====+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Caution+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is a caution with complex content.") ])+             , Block+                 mempty+                 Nothing+                 (List+                    (BulletList (Level 1))+                    [ ListItem+                        Nothing+                        [ Block+                            mempty+                            Nothing+                            (Paragraph [ Inline mempty (Str "It contains a list.") ])+                        ]+                    ])+             ])+      ]+  }
+ test/asciidoctor/admonition/caution-with-id-and-role.test view
@@ -0,0 +1,27 @@+[#caution-1.red]+CAUTION: This is a caution with id and role.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "caution-1" ) , ( "role" , "red" ) ] )+          Nothing+          (Admonition+             Caution+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is a caution with id and role.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/caution-with-title.test view
@@ -0,0 +1,25 @@+.Title of caution+CAUTION: This is a caution with title.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Title of caution") ]))+          (Admonition+             Caution+             [ Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "This is a caution with title.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/caution.test view
@@ -0,0 +1,24 @@+CAUTION: This is a caution.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Caution+             [ Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "This is a caution.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/important-block.test view
@@ -0,0 +1,45 @@+[IMPORTANT]+====+This is an important notice with complex content.++* It contains a list.+====+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Important+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty (Str "This is an important notice with complex content.")+                    ])+             , Block+                 mempty+                 Nothing+                 (List+                    (BulletList (Level 1))+                    [ ListItem+                        Nothing+                        [ Block+                            mempty+                            Nothing+                            (Paragraph [ Inline mempty (Str "It contains a list.") ])+                        ]+                    ])+             ])+      ]+  }
+ test/asciidoctor/admonition/important-with-id-and-role.test view
@@ -0,0 +1,29 @@+[#important-1.red]+IMPORTANT: This is an important notice with id and role.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "important-1" ) , ( "role" , "red" ) ] )+          Nothing+          (Admonition+             Important+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty (Str "This is an important notice with id and role.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/admonition/important-with-title.test view
@@ -0,0 +1,27 @@+.Title of important notice+IMPORTANT: This is an important notice with title.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just+             (BlockTitle [ Inline mempty (Str "Title of important notice") ]))+          (Admonition+             Important+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is an important notice with title.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/important.test view
@@ -0,0 +1,24 @@+IMPORTANT: This is an important notice.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Important+             [ Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "This is an important notice.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/note-block.test view
@@ -0,0 +1,43 @@+[NOTE]+====+This is a note with complex content.++* It contains a list.+====+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Note+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is a note with complex content.") ])+             , Block+                 mempty+                 Nothing+                 (List+                    (BulletList (Level 1))+                    [ ListItem+                        Nothing+                        [ Block+                            mempty+                            Nothing+                            (Paragraph [ Inline mempty (Str "It contains a list.") ])+                        ]+                    ])+             ])+      ]+  }
+ test/asciidoctor/admonition/note-with-id-and-role.test view
@@ -0,0 +1,27 @@+[#note-1.yellow]+NOTE: This is a note with id and role.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "note-1" ) , ( "role" , "yellow" ) ] )+          Nothing+          (Admonition+             Note+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is a note with id and role.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/note-with-title.test view
@@ -0,0 +1,25 @@+.Title of note+NOTE: This is a note with title.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Title of note") ]))+          (Admonition+             Note+             [ Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "This is a note with title.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/note.test view
@@ -0,0 +1,24 @@+NOTE: This is a note.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Note+             [ Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "This is a note.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/tip-block.test view
@@ -0,0 +1,43 @@+[TIP]+====+This is a tip with complex content.++* It contains a list.+====+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Tip+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is a tip with complex content.") ])+             , Block+                 mempty+                 Nothing+                 (List+                    (BulletList (Level 1))+                    [ ListItem+                        Nothing+                        [ Block+                            mempty+                            Nothing+                            (Paragraph [ Inline mempty (Str "It contains a list.") ])+                        ]+                    ])+             ])+      ]+  }
+ test/asciidoctor/admonition/tip-with-id-and-role.test view
@@ -0,0 +1,27 @@+[#tip-1.blue]+TIP: This is a tip with id and role.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "tip-1" ) , ( "role" , "blue" ) ] )+          Nothing+          (Admonition+             Tip+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is a tip with id and role.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/tip-with-title.test view
@@ -0,0 +1,25 @@+.Title of tip+TIP: This is a tip with title.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Title of tip") ]))+          (Admonition+             Tip+             [ Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "This is a tip with title.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/tip.test view
@@ -0,0 +1,22 @@+TIP: This is a tip.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Tip+             [ Block+                 mempty Nothing (Paragraph [ Inline mempty (Str "This is a tip.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/warning-block.test view
@@ -0,0 +1,43 @@+[WARNING]+====+This is a warning with complex content.++* It contains a list.+====+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Warning+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is a warning with complex content.") ])+             , Block+                 mempty+                 Nothing+                 (List+                    (BulletList (Level 1))+                    [ ListItem+                        Nothing+                        [ Block+                            mempty+                            Nothing+                            (Paragraph [ Inline mempty (Str "It contains a list.") ])+                        ]+                    ])+             ])+      ]+  }
+ test/asciidoctor/admonition/warning-with-id-and-role.test view
@@ -0,0 +1,27 @@+[#warning-1.red]+WARNING: This is a warning with id and role.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "warning-1" ) , ( "role" , "red" ) ] )+          Nothing+          (Admonition+             Warning+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is a warning with id and role.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/warning-with-title.test view
@@ -0,0 +1,25 @@+.Title of warning+WARNING: This is a warning with title.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Title of warning") ]))+          (Admonition+             Warning+             [ Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "This is a warning with title.") ])+             ])+      ]+  }
+ test/asciidoctor/admonition/warning.test view
@@ -0,0 +1,24 @@+WARNING: This is a warning.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Admonition+             Warning+             [ Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "This is a warning.") ])+             ])+      ]+  }
+ test/asciidoctor/audio/basic.test view
@@ -0,0 +1,14 @@+audio::ocean_waves.mp3[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block mempty Nothing (BlockAudio (Target "ocean_waves.mp3")) ]+  }
+ test/asciidoctor/audio/with-all-options.test view
@@ -0,0 +1,19 @@+audio::ocean_waves.mp3[options="autoplay, nocontrols, loop"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "options" , "autoplay, nocontrols, loop" ) ] )+          Nothing+          (BlockAudio (Target "ocean_waves.mp3"))+      ]+  }
+ test/asciidoctor/audio/with-id-and-role.test view
@@ -0,0 +1,20 @@+[#ocean.wave]+audio::ocean_waves.mp3[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "ocean" ) , ( "role" , "wave" ) ] )+          Nothing+          (BlockAudio (Target "ocean_waves.mp3"))+      ]+  }
+ test/asciidoctor/audio/with-title.test view
@@ -0,0 +1,19 @@+.Waves!+audio::ocean_waves.mp3[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Waves!") ]))+          (BlockAudio (Target "ocean_waves.mp3"))+      ]+  }
+ test/asciidoctor/colist/basic.test view
@@ -0,0 +1,60 @@+// This example should assert only callouts list below the code listing.+// For callouts inside the listing is responsible inline_callout.+[source, ruby]+----+require 'sinatra' // <1>++get '/hi' do  # <2>+  "Hello World!" ;; <3>+end+----+<1> Library import+<2> URL mapping+<3> Content for response+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             (Just (Language "ruby"))+             [ SourceLine "require 'sinatra' //" [ Callout 1 ]+             , SourceLine "" []+             , SourceLine "get '/hi' do  #" [ Callout 2 ]+             , SourceLine "  \"Hello World!\" ;;" [ Callout 3 ]+             , SourceLine "end" []+             ])+      , Block+          mempty+          Nothing+          (List+             CalloutList+             [ ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "Library import") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "URL mapping") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Content for response") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/colist/with-id-and-role.test view
@@ -0,0 +1,62 @@+// This example should assert only callouts list below the code listing.+// For callouts inside the listing is responsible inline_callout.+[source, ruby]+----+require 'sinatra' // <1>++get '/hi' do  # <2>+  "Hello World!" ;; <3>+end+----+[#call.sinatra]+<1> Library import+<2> URL mapping+<3> Content for response+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             (Just (Language "ruby"))+             [ SourceLine "require 'sinatra' //" [ Callout 1 ]+             , SourceLine "" []+             , SourceLine "get '/hi' do  #" [ Callout 2 ]+             , SourceLine "  \"Hello World!\" ;;" [ Callout 3 ]+             , SourceLine "end" []+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "call" ) , ( "role" , "sinatra" ) ] )+          Nothing+          (List+             CalloutList+             [ ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "Library import") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "URL mapping") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Content for response") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/colist/with-title.test view
@@ -0,0 +1,61 @@+// This example should assert only callouts list below the code listing.+// For callouts inside the listing is responsible inline_callout.+[source, ruby]+----+require 'sinatra' // <1>++get '/hi' do  # <2>+  "Hello World!" ;; <3>+end+----+.Description+<1> Library import+<2> URL mapping+<3> Content for response+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             (Just (Language "ruby"))+             [ SourceLine "require 'sinatra' //" [ Callout 1 ]+             , SourceLine "" []+             , SourceLine "get '/hi' do  #" [ Callout 2 ]+             , SourceLine "  \"Hello World!\" ;;" [ Callout 3 ]+             , SourceLine "end" []+             ])+      , Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Description") ]))+          (List+             CalloutList+             [ ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "Library import") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "URL mapping") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Content for response") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/dlist/basic-block.test view
@@ -0,0 +1,74 @@+About::+* An implementation of the AsciiDoc processor in Ruby.+* Fast text processor and publishing toolchain.++Authors::+Asciidoctor is lead by Dan Allen and Sarah White and has received contributions+from many other individuals in Asciidoctor’s awesome community.+++AsciiDoc was started by Stuart Rackham.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "About") ]+               , [ Block+                     mempty+                     Nothing+                     (List+                        (BulletList (Level 1))+                        [ ListItem+                            Nothing+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Str "An implementation of the AsciiDoc processor in Ruby.")+                                   ])+                            ]+                        , ListItem+                            Nothing+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty (Str "Fast text processor and publishing toolchain.")+                                   ])+                            ]+                        ])+                 ]+               )+             , ( [ Inline mempty (Str "Authors") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Asciidoctor is lead by Dan Allen and Sarah White and has received contributions\nfrom many other individuals in Asciidoctor\8217s awesome community.")+                        ])+                 , Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline mempty (Str "AsciiDoc was started by Stuart Rackham.") ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/basic-missing-description.test view
@@ -0,0 +1,22 @@+Definition without a description::+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "Definition without a description") ]+               , []+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/basic-with-id-and-role.test view
@@ -0,0 +1,25 @@+[#licenses.open]+License:: MIT+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "licenses" ) , ( "role" , "open" ) ] )+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "License") ]+               , [ Block mempty Nothing (Paragraph [ Inline mempty (Str "MIT") ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/basic-with-title.test view
@@ -0,0 +1,24 @@+.Asciidoctor+License:: MIT+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Asciidoctor") ]))+          (DefinitionList+             [ ( [ Inline mempty (Str "License") ]+               , [ Block mempty Nothing (Paragraph [ Inline mempty (Str "MIT") ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/basic.test view
@@ -0,0 +1,44 @@+Asciidoctor:: An implementation of the AsciiDoc processor in Ruby.+Asciidoc::+  A text document format for writing notes, documentation, articles, books,+  ebooks, slideshows, web pages, man pages and blogs.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "Asciidoctor") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty (Str "An implementation of the AsciiDoc processor in Ruby.")+                        ])+                 ]+               )+             , ( [ Inline mempty (Str "Asciidoc") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "A text document format for writing notes, documentation, articles, books,\n  ebooks, slideshows, web pages, man pages and blogs.")+                        ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/horizontal-with-dimensions.test view
@@ -0,0 +1,47 @@+[horizontal, labelwidth="20", itemwidth="50%"]+Hard drive:: Permanent storage for operating system and/or user files.+RAM:: Temporarily stores information the CPU uses during operation.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "horizontal" ]+          , fromList [ ( "itemwidth" , "50%" ) , ( "labelwidth" , "20" ) ]+          )+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "Hard drive") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str "Permanent storage for operating system and/or user files.")+                        ])+                 ]+               )+             , ( [ Inline mempty (Str "RAM") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Temporarily stores information the CPU uses during operation.")+                        ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/horizontal-with-id-and-role.test view
@@ -0,0 +1,47 @@+[horizontal, id=computer, role=terms]+Hard drive:: Permanent storage for operating system and/or user files.+RAM:: Temporarily stores information the CPU uses during operation.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "horizontal" ]+          , fromList [ ( "id" , "computer" ) , ( "role" , "terms" ) ]+          )+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "Hard drive") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str "Permanent storage for operating system and/or user files.")+                        ])+                 ]+               )+             , ( [ Inline mempty (Str "RAM") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Temporarily stores information the CPU uses during operation.")+                        ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/horizontal-with-title.test view
@@ -0,0 +1,48 @@+[horizontal]+.Computer terminology for noobs+Hard drive:: Permanent storage for operating system and/or user files.+RAM:: Temporarily stores information the CPU uses during operation.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "horizontal" ] , fromList [] )+          (Just+             (BlockTitle+                [ Inline mempty (Str "Computer terminology for noobs") ]))+          (DefinitionList+             [ ( [ Inline mempty (Str "Hard drive") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str "Permanent storage for operating system and/or user files.")+                        ])+                 ]+               )+             , ( [ Inline mempty (Str "RAM") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Temporarily stores information the CPU uses during operation.")+                        ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/horizontal.test view
@@ -0,0 +1,45 @@+[horizontal]+Hard drive:: Permanent storage for operating system and/or user files.+RAM:: Temporarily stores information the CPU uses during operation.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "horizontal" ] , fromList [] )+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "Hard drive") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str "Permanent storage for operating system and/or user files.")+                        ])+                 ]+               )+             , ( [ Inline mempty (Str "RAM") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Temporarily stores information the CPU uses during operation.")+                        ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/mixed.test view
@@ -0,0 +1,177 @@+Operating Systems::+  Linux:::+    . Fedora+      * Desktop+    . Ubuntu+      * Desktop+      * Server+  BSD:::+    . FreeBSD+    . NetBSD++Cloud Providers::+  PaaS:::+    . OpenShift+    . CloudBees+  IaaS:::+    . Amazon EC2+    . Rackspace+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "Operating Systems") ]+               , [ Block+                     mempty+                     Nothing+                     (DefinitionList+                        [ ( [ Inline mempty (Str "Linux") ]+                          , [ Block+                                mempty+                                Nothing+                                (List+                                   (OrderedList (Level 1) Nothing)+                                   [ ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "Fedora") ])+                                       , Block+                                           mempty+                                           Nothing+                                           (List+                                              (BulletList (Level 1))+                                              [ ListItem+                                                  Nothing+                                                  [ Block+                                                      mempty+                                                      Nothing+                                                      (Paragraph [ Inline mempty (Str "Desktop") ])+                                                  ]+                                              ])+                                       ]+                                   , ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "Ubuntu") ])+                                       , Block+                                           mempty+                                           Nothing+                                           (List+                                              (BulletList (Level 1))+                                              [ ListItem+                                                  Nothing+                                                  [ Block+                                                      mempty+                                                      Nothing+                                                      (Paragraph [ Inline mempty (Str "Desktop") ])+                                                  ]+                                              , ListItem+                                                  Nothing+                                                  [ Block+                                                      mempty+                                                      Nothing+                                                      (Paragraph [ Inline mempty (Str "Server") ])+                                                  ]+                                              ])+                                       ]+                                   ])+                            ]+                          )+                        , ( [ Inline mempty (Str "BSD") ]+                          , [ Block+                                mempty+                                Nothing+                                (List+                                   (OrderedList (Level 1) Nothing)+                                   [ ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "FreeBSD") ])+                                       ]+                                   , ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "NetBSD") ])+                                       ]+                                   ])+                            ]+                          )+                        ])+                 ]+               )+             , ( [ Inline mempty (Str "Cloud Providers") ]+               , [ Block+                     mempty+                     Nothing+                     (DefinitionList+                        [ ( [ Inline mempty (Str "PaaS") ]+                          , [ Block+                                mempty+                                Nothing+                                (List+                                   (OrderedList (Level 1) Nothing)+                                   [ ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "OpenShift") ])+                                       ]+                                   , ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "CloudBees") ])+                                       ]+                                   ])+                            ]+                          )+                        , ( [ Inline mempty (Str "IaaS") ]+                          , [ Block+                                mempty+                                Nothing+                                (List+                                   (OrderedList (Level 1) Nothing)+                                   [ ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "Amazon EC2") ])+                                       ]+                                   , ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "Rackspace") ])+                                       ]+                                   ])+                            ]+                          )+                        ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/qanda-block.test view
@@ -0,0 +1,76 @@+[qanda]+What is Asciidoctor?::+* An implementation of the AsciiDoc processor in Ruby.+* Fast text processor and publishing toolchain.++Who is behind Asciidoctor?::+Asciidoctor is lead by Dan Allen and Sarah White and has received contributions+from many other individuals in Asciidoctor’s awesome community.+++AsciiDoc was started by Stuart Rackham.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "qanda" ] , fromList [] )+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "What is Asciidoctor?") ]+               , [ Block+                     mempty+                     Nothing+                     (List+                        (BulletList (Level 1))+                        [ ListItem+                            Nothing+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Str "An implementation of the AsciiDoc processor in Ruby.")+                                   ])+                            ]+                        , ListItem+                            Nothing+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty (Str "Fast text processor and publishing toolchain.")+                                   ])+                            ]+                        ])+                 ]+               )+             , ( [ Inline mempty (Str "Who is behind Asciidoctor?") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Asciidoctor is lead by Dan Allen and Sarah White and has received contributions\nfrom many other individuals in Asciidoctor\8217s awesome community.")+                        ])+                 , Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline mempty (Str "AsciiDoc was started by Stuart Rackham.") ])+                 ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/qanda-missing-answer.test view
@@ -0,0 +1,21 @@+[qanda]+Who knows the answer?::+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "qanda" ] , fromList [] )+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "Who knows the answer?") ] , [] ) ])+      ]+  }
+ test/asciidoctor/dlist/qanda-with-id-and-role.test view
@@ -0,0 +1,28 @@+[qanda, id=faq, role=galaxy]+What is the answer to the Ultimate Question?:: 42+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "qanda" ]+          , fromList [ ( "id" , "faq" ) , ( "role" , "galaxy" ) ]+          )+          Nothing+          (DefinitionList+             [ ( [ Inline+                     mempty (Str "What is the answer to the Ultimate Question?")+                 ]+               , [ Block mempty Nothing (Paragraph [ Inline mempty (Str "42") ]) ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/qanda-with-title.test view
@@ -0,0 +1,29 @@+[qanda]+.The most important questions+What is the answer to the Ultimate Question?:: 42+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "qanda" ] , fromList [] )+          (Just+             (BlockTitle+                [ Inline mempty (Str "The most important questions") ]))+          (DefinitionList+             [ ( [ Inline+                     mempty (Str "What is the answer to the Ultimate Question?")+                 ]+               , [ Block mempty Nothing (Paragraph [ Inline mempty (Str "42") ]) ]+               )+             ])+      ]+  }
+ test/asciidoctor/dlist/qanda.test view
@@ -0,0 +1,38 @@+[qanda]+What is Asciidoctor?::+  An implementation of the AsciiDoc processor in Ruby.+What is the answer to the Ultimate Question?:: 42+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "qanda" ] , fromList [] )+          Nothing+          (DefinitionList+             [ ( [ Inline mempty (Str "What is Asciidoctor?") ]+               , [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty (Str "An implementation of the AsciiDoc processor in Ruby.")+                        ])+                 ]+               )+             , ( [ Inline+                     mempty (Str "What is the answer to the Ultimate Question?")+                 ]+               , [ Block mempty Nothing (Paragraph [ Inline mempty (Str "42") ]) ]+               )+             ])+      ]+  }
+ test/asciidoctor/document/footnotes.test view
@@ -0,0 +1,48 @@+The hail-and-rainbow protocol can be initiated at five levels: double, tertiary, supernumerary,+supermassive, and apocalyptic party.footnote:[The double hail-and-rainbow level makes my toes tingle.]+A bold statement.footnoteref:[disclaimer,Opinions are my own.]++Another outrageous statement.footnoteref:[disclaimer]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "The hail-and-rainbow protocol can be initiated at five levels: double, tertiary, supernumerary,\nsupermassive, and apocalyptic party.")+             , Inline+                 mempty+                 (Footnote+                    Nothing+                    [ Inline+                        mempty+                        (Str "The double hail-and-rainbow level makes my toes tingle.")+                    ])+             , Inline mempty (Str "\nA bold statement.")+             , Inline+                 mempty+                 (Footnote+                    (Just (FootnoteId "disclaimer"))+                    [ Inline mempty (Str "Opinions are my own.") ])+             ])+      , Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "Another outrageous statement.")+             , Inline mempty (Footnote (Just (FootnoteId "disclaimer")) [])+             ])+      ]+  }
+ test/asciidoctor/document/title-with-author-no-email.test view
@@ -0,0 +1,20 @@+= The Dangerous and Thrilling Documentation Chronicles+Kismet Rainbow Chameleon+>>>+Document+  { docMeta =+      Meta+        { docTitle =+            [ Inline+                mempty (Str "The Dangerous and Thrilling Documentation Chronicles")+            ]+        , docTitleAttributes = Nothing+        , docAuthors =+            [ Author+                { authorName = "Kismet Rainbow Chameleon" , authorEmail = Nothing }+            ]+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks = []+  }
+ test/asciidoctor/document/title-with-author.test view
@@ -0,0 +1,22 @@+= The Dangerous and Thrilling Documentation Chronicles+Kismet Rainbow Chameleon <kismet@asciidoctor.org>+>>>+Document+  { docMeta =+      Meta+        { docTitle =+            [ Inline+                mempty (Str "The Dangerous and Thrilling Documentation Chronicles")+            ]+        , docTitleAttributes = Nothing+        , docAuthors =+            [ Author+                { authorName = "Kismet Rainbow Chameleon"+                , authorEmail = Just "kismet@asciidoctor.org"+                }+            ]+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks = []+  }
+ test/asciidoctor/document/title-with-multiple-authors.test view
@@ -0,0 +1,26 @@+= The Dangerous and Thrilling Documentation Chronicles+Kismet Rainbow Chameleon <kismet@asciidoctor.org>; Lazarus het_Draeke <lazarus@asciidoctor.org>+>>>+Document+  { docMeta =+      Meta+        { docTitle =+            [ Inline+                mempty (Str "The Dangerous and Thrilling Documentation Chronicles")+            ]+        , docTitleAttributes = Nothing+        , docAuthors =+            [ Author+                { authorName = "Kismet Rainbow Chameleon"+                , authorEmail = Just "kismet@asciidoctor.org"+                }+            , Author+                { authorName = "Lazarus het_Draeke"+                , authorEmail = Just "lazarus@asciidoctor.org"+                }+            ]+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks = []+  }
+ test/asciidoctor/document/title-with-revdate.test view
@@ -0,0 +1,24 @@+= Document Title+Kismet Chameleon+v1.0, 2013-10-02+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors =+            [ Author+                { authorName = "Kismet Chameleon" , authorEmail = Nothing }+            ]+        , docRevision =+            Just+              Revision+                { revVersion = "1.0"+                , revDate = Just "2013-10-02"+                , revRemark = Nothing+                }+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks = []+  }
+ test/asciidoctor/document/title-with-revnumber.test view
@@ -0,0 +1,21 @@+= Document Title+Kismet Chameleon+v1.0+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors =+            [ Author+                { authorName = "Kismet Chameleon" , authorEmail = Nothing }+            ]+        , docRevision =+            Just+              Revision+                { revVersion = "1.0" , revDate = Nothing , revRemark = Nothing }+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks = []+  }
+ test/asciidoctor/document/title-with-revremark.test view
@@ -0,0 +1,24 @@+= Document Title+Kismet Chameleon+v1.0, October 2, 2013: First incarnation+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors =+            [ Author+                { authorName = "Kismet Chameleon" , authorEmail = Nothing }+            ]+        , docRevision =+            Just+              Revision+                { revVersion = "1.0"+                , revDate = Just "October 2, 2013"+                , revRemark = Just "First incarnation"+                }+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks = []+  }
+ test/asciidoctor/document/title.test view
@@ -0,0 +1,17 @@+= The Dangerous and Thrilling Documentation Chronicles+>>>+Document+  { docMeta =+      Meta+        { docTitle =+            [ Inline+                mempty (Str "The Dangerous and Thrilling Documentation Chronicles")+            ]+        , docTitleAttributes = Nothing+        , docAuthors =+            [ Author { authorName = "" , authorEmail = Nothing } ]+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks = []+  }
+ test/asciidoctor/document/toc-title.test view
@@ -0,0 +1,28 @@+= Document Title+:toc:+:toc-title: Table of Adventures++== Cavern Glow+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList+              [ ( "sectids" , "" )+              , ( "toc" , "" )+              , ( "toc-title" , "Table of Adventures" )+              ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_cavern_glow" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Cavern Glow") ] [])+      ]+  }
+ test/asciidoctor/document/toc.test view
@@ -0,0 +1,22 @@+= Document Title+:toc:++== Cavern Glow+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) , ( "toc" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_cavern_glow" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Cavern Glow") ] [])+      ]+  }
+ test/asciidoctor/embedded/footnotes.test view
@@ -0,0 +1,48 @@+The hail-and-rainbow protocol can be initiated at five levels: double, tertiary, supernumerary,+supermassive, and apocalyptic party.footnote:[The double hail-and-rainbow level makes my toes tingle.]+A bold statement.footnoteref:[disclaimer,Opinions are my own.]++Another outrageous statement.footnoteref:[disclaimer]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "The hail-and-rainbow protocol can be initiated at five levels: double, tertiary, supernumerary,\nsupermassive, and apocalyptic party.")+             , Inline+                 mempty+                 (Footnote+                    Nothing+                    [ Inline+                        mempty+                        (Str "The double hail-and-rainbow level makes my toes tingle.")+                    ])+             , Inline mempty (Str "\nA bold statement.")+             , Inline+                 mempty+                 (Footnote+                    (Just (FootnoteId "disclaimer"))+                    [ Inline mempty (Str "Opinions are my own.") ])+             ])+      , Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "Another outrageous statement.")+             , Inline mempty (Footnote (Just (FootnoteId "disclaimer")) [])+             ])+      ]+  }
+ test/asciidoctor/embedded/title.test view
@@ -0,0 +1,19 @@+:showtitle:+= The Dangerous and Thrilling Documentation Chronicles+>>>+Document+  { docMeta =+      Meta+        { docTitle =+            [ Inline+                mempty (Str "The Dangerous and Thrilling Documentation Chronicles")+            ]+        , docTitleAttributes = Nothing+        , docAuthors =+            [ Author { authorName = "" , authorEmail = Nothing } ]+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "showtitle" , "" ) ]+        }+  , docBlocks = []+  }
+ test/asciidoctor/embedded/toc-title.test view
@@ -0,0 +1,28 @@+= Document Title+:toc:+:toc-title: Table of Adventures++== Cavern Glow+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList+              [ ( "sectids" , "" )+              , ( "toc" , "" )+              , ( "toc-title" , "Table of Adventures" )+              ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_cavern_glow" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Cavern Glow") ] [])+      ]+  }
+ test/asciidoctor/embedded/toc.test view
@@ -0,0 +1,24 @@+// Actual TOC content is rendered in the outline template, this template+// usually renders just a "border".+= Document Title+:toc:++== Cavern Glow+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) , ( "toc" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_cavern_glow" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Cavern Glow") ] [])+      ]+  }
+ test/asciidoctor/example/basic.test view
@@ -0,0 +1,31 @@+====+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor+incididunt ut labore et dolore magna aliqua.+====+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (ExampleBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\nincididunt ut labore et dolore magna aliqua.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/example/with-id-and-role.test view
@@ -0,0 +1,33 @@+[#lorem.ipsum]+====+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor+incididunt ut labore et dolore magna aliqua.+====+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "lorem" ) , ( "role" , "ipsum" ) ] )+          Nothing+          (ExampleBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\nincididunt ut labore et dolore magna aliqua.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/example/with-title.test view
@@ -0,0 +1,41 @@+.Sample document+====+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor+incididunt ut labore et dolore magna aliqua.++The document header is useful, but not required.+====+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Sample document") ]))+          (ExampleBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\nincididunt ut labore et dolore magna aliqua.")+                    ])+             , Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty (Str "The document header is useful, but not required.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/fenced/basic.test view
@@ -0,0 +1,21 @@+```ruby+test = 3 <1>+```+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             (Just (Language "ruby")) [ SourceLine "test = 3" [ Callout 1 ] ])+      ]+  }
+ test/asciidoctor/floating_title/level1.test view
@@ -0,0 +1,20 @@+[discrete]+== Discrete Title Level 1+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DiscreteHeading+             (Level 1) [ Inline mempty (Str "Discrete Title Level 1") ])+      ]+  }
+ test/asciidoctor/floating_title/level2.test view
@@ -0,0 +1,20 @@+[discrete]+=== Discrete Title Level 2+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DiscreteHeading+             (Level 2) [ Inline mempty (Str "Discrete Title Level 2") ])+      ]+  }
+ test/asciidoctor/floating_title/level3.test view
@@ -0,0 +1,20 @@+[discrete]+==== Discrete Title Level 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DiscreteHeading+             (Level 3) [ Inline mempty (Str "Discrete Title Level 3") ])+      ]+  }
+ test/asciidoctor/floating_title/level4.test view
@@ -0,0 +1,20 @@+[discrete]+===== Discrete Title Level 4+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DiscreteHeading+             (Level 4) [ Inline mempty (Str "Discrete Title Level 4") ])+      ]+  }
+ test/asciidoctor/floating_title/level5.test view
@@ -0,0 +1,20 @@+[discrete]+====== Discrete Title Level 5+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (DiscreteHeading+             (Level 5) [ Inline mempty (Str "Discrete Title Level 5") ])+      ]+  }
+ test/asciidoctor/floating_title/with-custom-id.test view
@@ -0,0 +1,21 @@+[discrete, id=flying]+== Discrete Title Level 1+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "flying" ) ] )+          Nothing+          (DiscreteHeading+             (Level 1) [ Inline mempty (Str "Discrete Title Level 1") ])+      ]+  }
+ test/asciidoctor/floating_title/with-roles.test view
@@ -0,0 +1,21 @@+[discrete.flying.circus]+=== Discrete Title Level 2+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "role" , "flying circus" ) ] )+          Nothing+          (DiscreteHeading+             (Level 2) [ Inline mempty (Str "Discrete Title Level 2") ])+      ]+  }
+ test/asciidoctor/image/basic.test view
@@ -0,0 +1,18 @@+image::sunset.jpg[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (BlockImage (Target "sunset.jpg") Nothing Nothing Nothing)+      ]+  }
+ test/asciidoctor/image/with-align.test view
@@ -0,0 +1,19 @@+image::sunset.jpg[align="center"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "align" , "center" ) ] )+          Nothing+          (BlockImage (Target "sunset.jpg") Nothing Nothing Nothing)+      ]+  }
+ test/asciidoctor/image/with-alt-text.test view
@@ -0,0 +1,22 @@+image::sunset.jpg[Shining sun]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (BlockImage+             (Target "sunset.jpg")+             (Just (AltText "Shining sun"))+             Nothing+             Nothing)+      ]+  }
+ test/asciidoctor/image/with-dimensions.test view
@@ -0,0 +1,22 @@+image::sunset.jpg[Shining sun, 300, 200]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (BlockImage+             (Target "sunset.jpg")+             (Just (AltText "Shining sun"))+             (Just (Width 300))+             (Just (Height 200)))+      ]+  }
+ test/asciidoctor/image/with-float.test view
@@ -0,0 +1,19 @@+image::sunset.jpg[float="right"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "float" , "right" ) ] )+          Nothing+          (BlockImage (Target "sunset.jpg") Nothing Nothing Nothing)+      ]+  }
+ test/asciidoctor/image/with-id.test view
@@ -0,0 +1,20 @@+[[img-sunset]]+image::sunset.jpg[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "img-sunset" ) ] )+          Nothing+          (BlockImage (Target "sunset.jpg") Nothing Nothing Nothing)+      ]+  }
+ test/asciidoctor/image/with-link.test view
@@ -0,0 +1,22 @@+image::sunset.jpg[link="http://www.flickr.com/photos/javh/5448336655"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( []+          , fromList+              [ ( "link" , "http://www.flickr.com/photos/javh/5448336655" ) ]+          )+          Nothing+          (BlockImage (Target "sunset.jpg") Nothing Nothing Nothing)+      ]+  }
+ test/asciidoctor/image/with-roles.test view
@@ -0,0 +1,19 @@+image::sunset.jpg[role="right text-center"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "role" , "right text-center" ) ] )+          Nothing+          (BlockImage (Target "sunset.jpg") Nothing Nothing Nothing)+      ]+  }
+ test/asciidoctor/image/with-title.test view
@@ -0,0 +1,19 @@+.A mountain sunset+image::sunset.jpg[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "A mountain sunset") ]))+          (BlockImage (Target "sunset.jpg") Nothing Nothing Nothing)+      ]+  }
+ test/asciidoctor/inline_anchor/bibref-with-text.test view
@@ -0,0 +1,36 @@+// Supported since Asciidoctor 1.5.6.+// This is an item (anchor) in the bibliography, not a link to it.+[bibliography]+* [[[prag, 1]]] Andy Hunt & Dave Thomas. The Pragmatic Programmer+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "bibliography" ] , fromList [] )+          Nothing+          (List+             (BulletList (Level 1))+             [ ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty (BibliographyAnchor "prag" [ Inline mempty (Str "1") ])+                        , Inline+                            mempty (Str "Andy Hunt & Dave Thomas. The Pragmatic Programmer")+                        ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/inline_anchor/bibref.test view
@@ -0,0 +1,34 @@+// This is an item (anchor) in the bibliography, not a link to it.+[bibliography]+* [[[prag]]] Andy Hunt & Dave Thomas. The Pragmatic Programmer+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "bibliography" ] , fromList [] )+          Nothing+          (List+             (BulletList (Level 1))+             [ ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline mempty (BibliographyAnchor "prag" [])+                        , Inline+                            mempty (Str "Andy Hunt & Dave Thomas. The Pragmatic Programmer")+                        ])+                 ]+             ])+      ]+  }
@@ -0,0 +1,28 @@+:linkattrs:+http://discuss.asciidoctor.org/[*mailing list*, role="green"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "linkattrs" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "green" ) ] )+                 (Link+                    URLLink+                    (Target "http://discuss.asciidoctor.org/")+                    [ Inline mempty (Bold [ Inline mempty (Str "mailing list") ]) ])+             ])+      ]+  }
@@ -0,0 +1,25 @@+link:view-source:asciidoctor.org[Asciidoctor homepage^]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Link+                    URLLink+                    (Target "view-source:asciidoctor.org")+                    [ Inline mempty (Str "Asciidoctor homepage^") ])+             ])+      ]+  }
@@ -0,0 +1,25 @@+irc://irc.freenode.org/#asciidoctor[Asciidoctor IRC channel]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Link+                    URLLink+                    (Target "irc://irc.freenode.org/#asciidoctor")+                    [ Inline mempty (Str "Asciidoctor IRC channel") ])+             ])+      ]+  }
+ test/asciidoctor/inline_anchor/link.test view
@@ -0,0 +1,25 @@+http://www.asciidoctor.org+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Link+                    URLLink+                    (Target "http://www.asciidoctor.org")+                    [ Inline mempty (Str "http://www.asciidoctor.org") ])+             ])+      ]+  }
+ test/asciidoctor/inline_anchor/ref.test view
@@ -0,0 +1,23 @@+[[bookmark-a]] Inline anchors make arbitrary content referenceable.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (InlineAnchor "bookmark-a" [])+             , Inline+                 mempty+                 (Str " Inline anchors make arbitrary content referenceable.")+             ])+      ]+  }
+ test/asciidoctor/inline_anchor/xref-interdoc.test view
@@ -0,0 +1,22 @@+The section <<manual.adoc#page-break>> describes how to add a page break.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "The section ")+             , Inline mempty (CrossReference "manual.adoc#page-break" Nothing)+             , Inline mempty (Str " describes how to add a page break.")+             ])+      ]+  }
+ test/asciidoctor/inline_anchor/xref-reftext.test view
@@ -0,0 +1,36 @@+Refer to <<install>>.++[#install, reftext="Installation Procedure"]+== Installation+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "Refer to ")+             , Inline+                 mempty+                 (CrossReference+                    "install" (Just [ Inline mempty (Str "Installation") ]))+             , Inline mempty (Str ".")+             ])+      , Block+          Attr+          ( []+          , fromList+              [ ( "id" , "install" ) , ( "reftext" , "Installation Procedure" ) ]+          )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Installation") ] [])+      ]+  }
+ test/asciidoctor/inline_anchor/xref-resolved-text.test view
@@ -0,0 +1,29 @@+Refer to <<Section A>>.++== Section A+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "Refer to ")+             , Inline mempty (CrossReference "Section A" Nothing)+             , Inline mempty (Str ".")+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_section_a" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section A") ] [])+      ]+  }
+ test/asciidoctor/inline_anchor/xref-with-text.test view
@@ -0,0 +1,25 @@+The section <<page-break, Page break>> describes how to add a page break.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "The section ")+             , Inline+                 mempty+                 (CrossReference+                    "page-break" (Just [ Inline mempty (Str "Page break") ]))+             , Inline mempty (Str " describes how to add a page break.")+             ])+      ]+  }
+ test/asciidoctor/inline_anchor/xref-xrefstyle.test view
@@ -0,0 +1,43 @@+// Supported since Asciidoctor 1.5.6.+:sectnums:+:section-refsig: Sec.+:xrefstyle: short+Refer to <<install>>.++[[install]]+== Installation+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList+              [ ( "sectids" , "" )+              , ( "section-refsig" , "Sec." )+              , ( "sectnums" , "" )+              , ( "xrefstyle" , "short" )+              ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "Refer to ")+             , Inline+                 mempty+                 (CrossReference+                    "install" (Just [ Inline mempty (Str "Installation") ]))+             , Inline mempty (Str ".")+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "install" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Installation") ] [])+      ]+  }
+ test/asciidoctor/inline_anchor/xref.test view
@@ -0,0 +1,22 @@+The section <<page-break>> describes how to add a page break.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "The section ")+             , Inline mempty (CrossReference "page-break" Nothing)+             , Inline mempty (Str " describes how to add a page break.")+             ])+      ]+  }
+ test/asciidoctor/inline_break/hardbreaks.test view
@@ -0,0 +1,25 @@+[%hardbreaks]+Ruby is red.+Java is black.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "options" , "hardbreaks" ) ] )+          Nothing+          (Paragraph+             [ Inline mempty (Str "Ruby is red.")+             , Inline mempty HardBreak+             , Inline mempty (Str "Java is black.")+             ])+      ]+  }
+ test/asciidoctor/inline_break/plus-sign.test view
@@ -0,0 +1,23 @@+Rubies are red, ++Topazes are blue.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "Rubies are red, ")+             , Inline mempty HardBreak+             , Inline mempty (Str "Topazes are blue.")+             ])+      ]+  }
+ test/asciidoctor/inline_button/basic.test view
@@ -0,0 +1,17 @@+:experimental:+btn:[OK]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "experimental" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block mempty Nothing (Paragraph [ Inline mempty (Button "OK") ])+      ]+  }
+ test/asciidoctor/inline_callout/basic.test view
@@ -0,0 +1,22 @@+[source]+----+"Hello world!" // <1>+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             Nothing [ SourceLine "\"Hello world!\" //" [ Callout 1 ] ])+      ]+  }
+ test/asciidoctor/inline_footnote/basic.test view
@@ -0,0 +1,28 @@+Apocalyptic party.footnote:[The double hail-and-rainbow level makes my toes tingle.]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "Apocalyptic party.")+             , Inline+                 mempty+                 (Footnote+                    Nothing+                    [ Inline+                        mempty+                        (Str "The double hail-and-rainbow level makes my toes tingle.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/inline_footnote/xref-unresolved.test view
@@ -0,0 +1,21 @@+A bold statement.footnoteref:[foobar]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "A bold statement.")+             , Inline mempty (Footnote (Just (FootnoteId "foobar")) [])+             ])+      ]+  }
+ test/asciidoctor/inline_footnote/xref.test view
@@ -0,0 +1,28 @@+A bold statement.footnoteref:[disclaimer,Opinions are my own.]+Another outrageous statement.footnoteref:[disclaimer]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "A bold statement.")+             , Inline+                 mempty+                 (Footnote+                    (Just (FootnoteId "disclaimer"))+                    [ Inline mempty (Str "Opinions are my own.") ])+             , Inline mempty (Str "\nAnother outrageous statement.")+             , Inline mempty (Footnote (Just (FootnoteId "disclaimer")) [])+             ])+      ]+  }
+ test/asciidoctor/inline_image/icon-no-icons.test view
@@ -0,0 +1,15 @@+icon:tags[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block mempty Nothing (Paragraph [ Inline mempty (Icon "tags") ])+      ]+  }
+ test/asciidoctor/inline_image/icon-with-dimensions.test view
@@ -0,0 +1,25 @@+:icons:+icon:tags[height=25, width=35]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "icons" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "height" , "25" ) , ( "width" , "35" ) ] )+                 (Icon "tags")+             ])+      ]+  }
+ test/asciidoctor/inline_image/icon-with-float.test view
@@ -0,0 +1,23 @@+:icons:+icon:heart[float="right"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "icons" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr ( [] , fromList [ ( "float" , "right" ) ] ) (Icon "heart")+             ])+      ]+  }
+ test/asciidoctor/inline_image/icon-with-link.test view
@@ -0,0 +1,31 @@+:icons:+icon:download[link="http://rubygems.org/downloads/asciidoctor-1.5.2.gem"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "icons" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( []+                 , fromList+                     [ ( "link"+                       , "http://rubygems.org/downloads/asciidoctor-1.5.2.gem"+                       )+                     ]+                 )+                 (Icon "download")+             ])+      ]+  }
+ test/asciidoctor/inline_image/icon-with-role.test view
@@ -0,0 +1,23 @@+:icons:+icon:tags[role="blue"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "icons" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr ( [] , fromList [ ( "role" , "blue" ) ] ) (Icon "tags")+             ])+      ]+  }
+ test/asciidoctor/inline_image/icon-with-title.test view
@@ -0,0 +1,25 @@+:icons:+icon:heart[title="I <3 Asciidoctor"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "icons" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "title" , "I <3 Asciidoctor" ) ] )+                 (Icon "heart")+             ])+      ]+  }
+ test/asciidoctor/inline_image/icon.test view
@@ -0,0 +1,17 @@+:icons:+icon:tags[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "icons" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block mempty Nothing (Paragraph [ Inline mempty (Icon "tags") ])+      ]+  }
+ test/asciidoctor/inline_image/image-with-alt-text.test view
@@ -0,0 +1,23 @@+image:linux.svg[Tux]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (InlineImage+                    (Target "linux.svg") (Just (AltText "Tux")) Nothing Nothing)+             ])+      ]+  }
+ test/asciidoctor/inline_image/image-with-dimensions.test view
@@ -0,0 +1,26 @@+image:linux.svg[Tux, 25, 35]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (InlineImage+                    (Target "linux.svg")+                    (Just (AltText "Tux"))+                    (Just (Width 25))+                    (Just (Height 35)))+             ])+      ]+  }
+ test/asciidoctor/inline_image/image-with-float.test view
@@ -0,0 +1,23 @@+image:linux.svg[float="right"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "float" , "right" ) ] )+                 (InlineImage (Target "linux.svg") Nothing Nothing Nothing)+             ])+      ]+  }
+ test/asciidoctor/inline_image/image-with-link.test view
@@ -0,0 +1,26 @@+image:linux.svg[link="http://inkscape.org/doc/examples/tux.svg"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( []+                 , fromList+                     [ ( "link" , "http://inkscape.org/doc/examples/tux.svg" ) ]+                 )+                 (InlineImage (Target "linux.svg") Nothing Nothing Nothing)+             ])+      ]+  }
+ test/asciidoctor/inline_image/image-with-role.test view
@@ -0,0 +1,23 @@+image:linux.svg[role="black"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "black" ) ] )+                 (InlineImage (Target "linux.svg") Nothing Nothing Nothing)+             ])+      ]+  }
+ test/asciidoctor/inline_image/image.test view
@@ -0,0 +1,21 @@+image:linux.svg[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty (InlineImage (Target "linux.svg") Nothing Nothing Nothing)+             ])+      ]+  }
+ test/asciidoctor/inline_kbd/basic.test view
@@ -0,0 +1,18 @@+:experimental:+kbd:[F11]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "experimental" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty Nothing (Paragraph [ Inline mempty (Kbd [ "F11" ]) ])+      ]+  }
+ test/asciidoctor/inline_kbd/keyseq.test view
@@ -0,0 +1,20 @@+:experimental:+kbd:[Ctrl+Shift+N]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "experimental" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph [ Inline mempty (Kbd [ "Ctrl" , "Shift" , "N" ]) ])+      ]+  }
+ test/asciidoctor/inline_menu/menu.test view
@@ -0,0 +1,18 @@+:experimental:+menu:File[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "experimental" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty Nothing (Paragraph [ Inline mempty (Menu [ "File" ]) ])+      ]+  }
+ test/asciidoctor/inline_menu/menuitem.test view
@@ -0,0 +1,20 @@+:experimental:+menu:File[Save]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "experimental" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph [ Inline mempty (Menu [ "File" , "Save" ]) ])+      ]+  }
+ test/asciidoctor/inline_menu/submenu.test view
@@ -0,0 +1,20 @@+:experimental:+menu:View[Zoom > Reset]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "experimental" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph [ Inline mempty (Menu [ "View" , "Zoom" , "Reset" ]) ])+      ]+  }
+ test/asciidoctor/inline_quoted/asciimath.test view
@@ -0,0 +1,18 @@+asciimath:[sqrt(4) = 2]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph [ Inline mempty (Math (Just AsciiMath) "sqrt(4) = 2") ])+      ]+  }
+ test/asciidoctor/inline_quoted/basic.test view
@@ -0,0 +1,23 @@+[why]#chunky bacon#+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "why" ) ] )+                 (Span [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/double-with-role.test view
@@ -0,0 +1,23 @@+[why]"`chunky bacon`"+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "why" ) ] )+                 (DoubleQuoted [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/double.test view
@@ -0,0 +1,21 @@+"`chunky bacon`"+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty (DoubleQuoted [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/emphasis-with-role.test view
@@ -0,0 +1,23 @@+[why]_chunky bacon_+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "why" ) ] )+                 (Italic [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/emphasis.test view
@@ -0,0 +1,19 @@+_chunky bacon_+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Italic [ Inline mempty (Str "chunky bacon") ]) ])+      ]+  }
+ test/asciidoctor/inline_quoted/latexmath.test view
@@ -0,0 +1,23 @@+latexmath:[C = \alpha + \beta Y^{\gamma} + \epsilon]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Math+                    (Just LaTeXMath) "C = \\alpha + \\beta Y^{\\gamma} + \\epsilon")+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/mark.test view
@@ -0,0 +1,20 @@+#chunky bacon#+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Highlight [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/mixed-monospace-bold-italic.test view
@@ -0,0 +1,39 @@+`*_monospace bold italic phrase_*` and le``**__tt__**``ers+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Monospace+                    [ Inline+                        mempty+                        (Bold+                           [ Inline+                               mempty+                               (Italic [ Inline mempty (Str "monospace bold italic phrase") ])+                           ])+                    ])+             , Inline mempty (Str " and le")+             , Inline+                 mempty+                 (Monospace+                    [ Inline+                        mempty+                        (Bold [ Inline mempty (Italic [ Inline mempty (Str "tt") ]) ])+                    ])+             , Inline mempty (Str "ers")+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/monospaced-with-role.test view
@@ -0,0 +1,23 @@+[why]`hello world!`+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "why" ) ] )+                 (Monospace [ Inline mempty (Str "hello world!") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/monospaced.test view
@@ -0,0 +1,20 @@+`hello world!`+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Monospace [ Inline mempty (Str "hello world!") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/single-with-role.test view
@@ -0,0 +1,23 @@+[why]'`chunky bacon`'+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "why" ) ] )+                 (SingleQuoted [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/single.test view
@@ -0,0 +1,21 @@+'`chunky bacon`'+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty (SingleQuoted [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/strong-with-role.test view
@@ -0,0 +1,23 @@+[why]*chunky bacon*+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "why" ) ] )+                 (Bold [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/strong.test view
@@ -0,0 +1,19 @@+*chunky bacon*+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Bold [ Inline mempty (Str "chunky bacon") ]) ])+      ]+  }
+ test/asciidoctor/inline_quoted/subscript-with-role.test view
@@ -0,0 +1,24 @@+[why]~sub~chunky bacon+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "why" ) ] )+                 (Subscript [ Inline mempty (Str "sub") ])+             , Inline mempty (Str "chunky bacon")+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/subscript.test view
@@ -0,0 +1,21 @@+~sub~chunky bacon+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Subscript [ Inline mempty (Str "sub") ])+             , Inline mempty (Str "chunky bacon")+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/superscript-with-role.test view
@@ -0,0 +1,24 @@+[why]^super^chunky bacon+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "role" , "why" ) ] )+                 (Superscript [ Inline mempty (Str "super") ])+             , Inline mempty (Str "chunky bacon")+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/superscript.test view
@@ -0,0 +1,21 @@+^super^chunky bacon+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Superscript [ Inline mempty (Str "super") ])+             , Inline mempty (Str "chunky bacon")+             ])+      ]+  }
+ test/asciidoctor/inline_quoted/with-id.test view
@@ -0,0 +1,23 @@+[#why]_chunky bacon_+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 Attr+                 ( [] , fromList [ ( "id" , "why" ) ] )+                 (Italic [ Inline mempty (Str "chunky bacon") ])+             ])+      ]+  }
+ test/asciidoctor/listing/basic-nowrap.test view
@@ -0,0 +1,27 @@+[options="nowrap"]+----+ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "options" , "nowrap" ) ] )+          Nothing+          (Listing+             Nothing+             [ SourceLine+                 "ruby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\""+                 []+             ])+      ]+  }
+ test/asciidoctor/listing/basic-with-id-and-role.test view
@@ -0,0 +1,29 @@+[#code.example]+----+echo -n "Please enter your name: "+read name+echo "Hello, $name!"+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "code" ) , ( "role" , "example" ) ] )+          Nothing+          (Listing+             Nothing+             [ SourceLine "echo -n \"Please enter your name: \"" []+             , SourceLine "read name" []+             , SourceLine "echo \"Hello, $name!\"" []+             ])+      ]+  }
+ test/asciidoctor/listing/basic-with-title.test view
@@ -0,0 +1,28 @@+.Reading user input+----+echo -n "Please enter your name: "+read name+echo "Hello, $name!"+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Reading user input") ]))+          (Listing+             Nothing+             [ SourceLine "echo -n \"Please enter your name: \"" []+             , SourceLine "read name" []+             , SourceLine "echo \"Hello, $name!\"" []+             ])+      ]+  }
+ test/asciidoctor/listing/basic.test view
@@ -0,0 +1,27 @@+----+echo -n "Please enter your name: "+read name+echo "Hello, $name!"+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             Nothing+             [ SourceLine "echo -n \"Please enter your name: \"" []+             , SourceLine "read name" []+             , SourceLine "echo \"Hello, $name!\"" []+             ])+      ]+  }
+ test/asciidoctor/listing/source-nowrap.test view
@@ -0,0 +1,51 @@+[source, java, options="nowrap"]+----+public class ApplicationConfigurationProvider extends HttpConfigurationProvider {++   public Configuration getConfiguration(ServletContext context) {+      return ConfigurationBuilder.begin()+               .addRule()+               .when(Direction.isInbound().and(Path.matches("/{path}")))+               .perform(Log.message(Level.INFO, "Client requested path: {path}"))+               .where("path").matches(".*");+   }+}+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "options" , "nowrap" ) ] )+          Nothing+          (Listing+             (Just (Language "java"))+             [ SourceLine+                 "public class ApplicationConfigurationProvider extends HttpConfigurationProvider {"+                 []+             , SourceLine "" []+             , SourceLine+                 "   public Configuration getConfiguration(ServletContext context) {"+                 []+             , SourceLine "      return ConfigurationBuilder.begin()" []+             , SourceLine "               .addRule()" []+             , SourceLine+                 "               .when(Direction.isInbound().and(Path.matches(\"/{path}\")))"+                 []+             , SourceLine+                 "               .perform(Log.message(Level.INFO, \"Client requested path: {path}\"))"+                 []+             , SourceLine "               .where(\"path\").matches(\".*\");" []+             , SourceLine "   }" []+             , SourceLine "}" []+             ])+      ]+  }
+ test/asciidoctor/listing/source-with-language.test view
@@ -0,0 +1,28 @@+[source, ruby]+----+5.times do+  print "Odelay!"+end+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             (Just (Language "ruby"))+             [ SourceLine "5.times do" []+             , SourceLine "  print \"Odelay!\"" []+             , SourceLine "end" []+             ])+      ]+  }
+ test/asciidoctor/listing/source-with-title.test view
@@ -0,0 +1,29 @@+[source]+.Odelay!+----+5.times do+  print "Odelay!"+end+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Odelay!") ]))+          (Listing+             Nothing+             [ SourceLine "5.times do" []+             , SourceLine "  print \"Odelay!\"" []+             , SourceLine "end" []+             ])+      ]+  }
+ test/asciidoctor/listing/source.test view
@@ -0,0 +1,28 @@+[source]+----+5.times do+  print "Odelay!"+end+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             Nothing+             [ SourceLine "5.times do" []+             , SourceLine "  print \"Odelay!\"" []+             , SourceLine "end" []+             ])+      ]+  }
+ test/asciidoctor/literal/basic.test view
@@ -0,0 +1,23 @@+....+error: The requested operation returned error: 1954 Forbidden search for defensive operations manual+absolutely fatal: operation initiation lost in the dodecahedron of doom+would you like to die again? y/n+....+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (LiteralBlock+             "error: The requested operation returned error: 1954 Forbidden search for defensive operations manual\nabsolutely fatal: operation initiation lost in the dodecahedron of doom\nwould you like to die again? y/n\n")+      ]+  }
+ test/asciidoctor/literal/indented.test view
@@ -0,0 +1,19 @@+ $ gem install foo+ $ gem --version+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (LiteralBlock "$ gem install foo\n$ gem --version\n")+      ]+  }
+ test/asciidoctor/literal/labeled.test view
@@ -0,0 +1,18 @@+[literal]+gem install foobar+gem --version+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty Nothing (LiteralBlock "gem install foobar\ngem --version\n")+      ]+  }
+ test/asciidoctor/literal/nowrap.test view
@@ -0,0 +1,25 @@+[options="nowrap"]+....+error: The requested operation returned error: 1954 Forbidden search for defensive operations manual+absolutely fatal: operation initiation lost in the dodecahedron of doom+would you like to die again? y/n+....+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "options" , "nowrap" ) ] )+          Nothing+          (LiteralBlock+             "error: The requested operation returned error: 1954 Forbidden search for defensive operations manual\nabsolutely fatal: operation initiation lost in the dodecahedron of doom\nwould you like to die again? y/n\n")+      ]+  }
+ test/asciidoctor/literal/with-id-and-role.test view
@@ -0,0 +1,25 @@+[#error.fatal]+....+error: The requested operation returned error: 1954 Forbidden search for defensive operations manual+absolutely fatal: operation initiation lost in the dodecahedron of doom+would you like to die again? y/n+....+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "error" ) , ( "role" , "fatal" ) ] )+          Nothing+          (LiteralBlock+             "error: The requested operation returned error: 1954 Forbidden search for defensive operations manual\nabsolutely fatal: operation initiation lost in the dodecahedron of doom\nwould you like to die again? y/n\n")+      ]+  }
+ test/asciidoctor/literal/with-title.test view
@@ -0,0 +1,24 @@+.Die again?+....+error: The requested operation returned error: 1954 Forbidden search for defensive operations manual+absolutely fatal: operation initiation lost in the dodecahedron of doom+would you like to die again? y/n+....+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Die again?") ]))+          (LiteralBlock+             "error: The requested operation returned error: 1954 Forbidden search for defensive operations manual\nabsolutely fatal: operation initiation lost in the dodecahedron of doom\nwould you like to die again? y/n\n")+      ]+  }
+ test/asciidoctor/olist/basic.test view
@@ -0,0 +1,34 @@+. Step 1+. Step 2+. Step 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 1") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 2") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 3") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/olist/complex-content.test view
@@ -0,0 +1,79 @@+. Every list item has at least one paragraph of content,+  which may be wrapped, even using a hanging indent.+++Additional paragraphs or blocks are adjoined by putting+a list continuation on a line adjacent to both blocks.+++list continuation:: a plus sign (`{plus}`) on a line by itself++. A literal paragraph does not require a list continuation.++ $ gem install asciidoctor+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Every list item has at least one paragraph of content,\n  which may be wrapped, even using a hanging indent.")+                        ])+                 , Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Additional paragraphs or blocks are adjoined by putting\na list continuation on a line adjacent to both blocks.")+                        ])+                 , Block+                     mempty+                     Nothing+                     (DefinitionList+                        [ ( [ Inline mempty (Str "list continuation") ]+                          , [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline mempty (Str "a plus sign (")+                                   , Inline mempty (Monospace [ Inline mempty (Str "+") ])+                                   , Inline mempty (Str ") on a line by itself")+                                   ])+                            ]+                          )+                        ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str "A literal paragraph does not require a list continuation.")+                        ])+                 ]+             ])+      , Block mempty Nothing (LiteralBlock "$ gem install asciidoctor\n")+      ]+  }
+ test/asciidoctor/olist/max-nesting.test view
@@ -0,0 +1,87 @@+. level 1+.. level 2+... level 3+.... level 4+..... level 5+.. level 2+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "level 1") ])+                 , Block+                     mempty+                     Nothing+                     (List+                        (OrderedList (Level 2) Nothing)+                        [ ListItem+                            Nothing+                            [ Block+                                mempty Nothing (Paragraph [ Inline mempty (Str "level 2") ])+                            , Block+                                mempty+                                Nothing+                                (List+                                   (OrderedList (Level 3) Nothing)+                                   [ ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "level 3") ])+                                       , Block+                                           mempty+                                           Nothing+                                           (List+                                              (OrderedList (Level 4) Nothing)+                                              [ ListItem+                                                  Nothing+                                                  [ Block+                                                      mempty+                                                      Nothing+                                                      (Paragraph [ Inline mempty (Str "level 4") ])+                                                  , Block+                                                      mempty+                                                      Nothing+                                                      (List+                                                         (OrderedList (Level 5) Nothing)+                                                         [ ListItem+                                                             Nothing+                                                             [ Block+                                                                 mempty+                                                                 Nothing+                                                                 (Paragraph+                                                                    [ Inline mempty (Str "level 5")+                                                                    ])+                                                             ]+                                                         ])+                                                  ]+                                              ])+                                       ]+                                   ])+                            ]+                        , ListItem+                            Nothing+                            [ Block+                                mempty Nothing (Paragraph [ Inline mempty (Str "level 2") ])+                            ]+                        ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/olist/with-id-and-role.test view
@@ -0,0 +1,36 @@+[#steps.green]+. Step 1+. Step 2+. Step 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "steps" ) , ( "role" , "green" ) ] )+          Nothing+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 1") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 2") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 3") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/olist/with-numeration-styles.test view
@@ -0,0 +1,91 @@+[decimal]+. level 1+[upperalpha]+.. level 2+[loweralpha]+... level 3+[lowerroman]+.... level 4+[lowergreek]+..... level 5+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "decimal" ] , fromList [] )+          Nothing+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "level 1") ])+                 , Block+                     Attr+                     ( [ "upperalpha" ] , fromList [] )+                     Nothing+                     (List+                        (OrderedList (Level 2) Nothing)+                        [ ListItem+                            Nothing+                            [ Block+                                mempty Nothing (Paragraph [ Inline mempty (Str "level 2") ])+                            , Block+                                Attr+                                ( [ "loweralpha" ] , fromList [] )+                                Nothing+                                (List+                                   (OrderedList (Level 3) Nothing)+                                   [ ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "level 3") ])+                                       , Block+                                           Attr+                                           ( [ "lowerroman" ] , fromList [] )+                                           Nothing+                                           (List+                                              (OrderedList (Level 4) Nothing)+                                              [ ListItem+                                                  Nothing+                                                  [ Block+                                                      mempty+                                                      Nothing+                                                      (Paragraph [ Inline mempty (Str "level 4") ])+                                                  , Block+                                                      Attr+                                                      ( [ "lowergreek" ] , fromList [] )+                                                      Nothing+                                                      (List+                                                         (OrderedList (Level 5) Nothing)+                                                         [ ListItem+                                                             Nothing+                                                             [ Block+                                                                 mempty+                                                                 Nothing+                                                                 (Paragraph+                                                                    [ Inline mempty (Str "level 5")+                                                                    ])+                                                             ]+                                                         ])+                                                  ]+                                              ])+                                       ]+                                   ])+                            ]+                        ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/olist/with-reversed.test view
@@ -0,0 +1,36 @@+[%reversed]+. Step 1+. Step 2+. Step 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "options" , "reversed" ) ] )+          Nothing+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 1") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 2") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 3") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/olist/with-start.test view
@@ -0,0 +1,36 @@+[start=6]+. Step 1+. Step 2+. Step 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "start" , "6" ) ] )+          Nothing+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 1") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 2") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 3") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/olist/with-title.test view
@@ -0,0 +1,35 @@+.Steps+. Step 1+. Step 2+. Step 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Steps") ]))+          (List+             (OrderedList (Level 1) Nothing)+             [ ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 1") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 2") ])+                 ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "Step 3") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/open/abstract-with-id-and-role.test view
@@ -0,0 +1,35 @@+[abstract, id="open", role="example"]+--+This is an abstract quote block.+Who knows what it really means?+--+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "abstract" ]+          , fromList [ ( "id" , "open" ) , ( "role" , "example" ) ]+          )+          Nothing+          (OpenBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "This is an abstract quote block.\nWho knows what it really means?")+                    ])+             ])+      ]+  }
+ test/asciidoctor/open/abstract-with-title.test view
@@ -0,0 +1,35 @@+[abstract]+.Abstract title is abstract+--+This is an abstract quote block.+Who knows what it really means?+--+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "abstract" ] , fromList [] )+          (Just+             (BlockTitle [ Inline mempty (Str "Abstract title is abstract") ]))+          (OpenBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "This is an abstract quote block.\nWho knows what it really means?")+                    ])+             ])+      ]+  }
+ test/asciidoctor/open/abstract.test view
@@ -0,0 +1,28 @@+[abstract]+--+This is an abstract quote block.+--+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [ "abstract" ] , fromList [] )+          Nothing+          (OpenBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "This is an abstract quote block.") ])+             ])+      ]+  }
+ test/asciidoctor/open/basic-with-id-and-role.test view
@@ -0,0 +1,33 @@+[#open.example]+--+An open block can be an anonymous container,+or it can masquerade as any other block.+--+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "open" ) , ( "role" , "example" ) ] )+          Nothing+          (OpenBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "An open block can be an anonymous container,\nor it can masquerade as any other block.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/open/basic-with-title.test view
@@ -0,0 +1,32 @@+.An open block+--+An open block can be an anonymous container,+or it can masquerade as any other block.+--+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "An open block") ]))+          (OpenBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "An open block can be an anonymous container,\nor it can masquerade as any other block.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/open/basic.test view
@@ -0,0 +1,31 @@+--+An open block can be an anonymous container,+or it can masquerade as any other block.+--+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (OpenBlock+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "An open block can be an anonymous container,\nor it can masquerade as any other block.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/outline/basic.test view
@@ -0,0 +1,56 @@+= Document Title+:toc:++== Section 1++== Section 2++=== Section 2.1++==== Section 2.1.1++== Section 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) , ( "toc" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_1" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section 1") ] [])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_section_2" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Section 2") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_section_2_1" ) ] )+                 Nothing+                 (Section+                    (Level 2)+                    [ Inline mempty (Str "Section 2.1") ]+                    [ Block+                        Attr+                        ( [] , fromList [ ( "id" , "_section_2_1_1" ) ] )+                        Nothing+                        (Section (Level 3) [ Inline mempty (Str "Section 2.1.1") ] [])+                    ])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_section_3" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section 3") ] [])+      ]+  }
+ test/asciidoctor/outline/numbered.test view
@@ -0,0 +1,70 @@+= Document Title+:toc:+:numbered:++== Section 1++:numbered!:++== Unnumbered Section++:numbered:++== Section 2++=== Section 2.1++== Section 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList+              [ ( "numbered" , "" ) , ( "sectids" , "" ) , ( "toc" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_1" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Section 1") ]+             [ Block+                 mempty Nothing (Paragraph [ Inline mempty (Str ":numbered!:") ])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_unnumbered_section" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Unnumbered Section") ]+             [ Block+                 mempty Nothing (Paragraph [ Inline mempty (Str ":numbered:") ])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_section_2" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Section 2") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_section_2_1" ) ] )+                 Nothing+                 (Section (Level 2) [ Inline mempty (Str "Section 2.1") ] [])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_section_3" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section 3") ] [])+      ]+  }
+ test/asciidoctor/outline/sectnumlevels.test view
@@ -0,0 +1,59 @@+= Document Title+:toc:+:toclevels: 3+:numbered:+:sectnumlevels: 1++== Section 1++=== Section 1.1++==== Section 1.1.1++== Section 2+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList+              [ ( "numbered" , "" )+              , ( "sectids" , "" )+              , ( "sectnumlevels" , "1" )+              , ( "toc" , "" )+              , ( "toclevels" , "3" )+              ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_1" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Section 1") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_section_1_1" ) ] )+                 Nothing+                 (Section+                    (Level 2)+                    [ Inline mempty (Str "Section 1.1") ]+                    [ Block+                        Attr+                        ( [] , fromList [ ( "id" , "_section_1_1_1" ) ] )+                        Nothing+                        (Section (Level 3) [ Inline mempty (Str "Section 1.1.1") ] [])+                    ])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_section_2" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section 2") ] [])+      ]+  }
+ test/asciidoctor/outline/toclevels.test view
@@ -0,0 +1,52 @@+= Document Title+:toc:+:toclevels: 1++== Section 1++=== Section 1.1++==== Section 1.1.1++== Section 2+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList+              [ ( "sectids" , "" ) , ( "toc" , "" ) , ( "toclevels" , "1" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_1" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Section 1") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_section_1_1" ) ] )+                 Nothing+                 (Section+                    (Level 2)+                    [ Inline mempty (Str "Section 1.1") ]+                    [ Block+                        Attr+                        ( [] , fromList [ ( "id" , "_section_1_1_1" ) ] )+                        Nothing+                        (Section (Level 3) [ Inline mempty (Str "Section 1.1.1") ] [])+                    ])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_section_2" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section 2") ] [])+      ]+  }
+ test/asciidoctor/page_break/basic.test view
@@ -0,0 +1,25 @@+Text on the first page++<<<++was breaked!+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph [ Inline mempty (Str "Text on the first page") ])+      , Block mempty Nothing PageBreak+      , Block+          mempty Nothing (Paragraph [ Inline mempty (Str "was breaked!") ])+      ]+  }
+ test/asciidoctor/paragraph/basic.test view
@@ -0,0 +1,35 @@+Paragraphs don't require any special markup in AsciiDoc.+A paragraph is just one or more lines of consecutive text.++To begin a new paragraph, separate it by at least one blank line.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "Paragraphs don\8217t require any special markup in AsciiDoc.\nA paragraph is just one or more lines of consecutive text.")+             ])+      , Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "To begin a new paragraph, separate it by at least one blank line.")+             ])+      ]+  }
+ test/asciidoctor/paragraph/with-id-and-role.test view
@@ -0,0 +1,26 @@+[#para-1.red]+Paragraphs don't require any special markup in AsciiDoc.+A paragraph is just one or more lines of consecutive text.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "para-1" ) , ( "role" , "red" ) ] )+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "Paragraphs don\8217t require any special markup in AsciiDoc.\nA paragraph is just one or more lines of consecutive text.")+             ])+      ]+  }
+ test/asciidoctor/paragraph/with-title.test view
@@ -0,0 +1,36 @@+.Paragraphs+Paragraphs don't require any special markup in AsciiDoc.+A paragraph is just one or more lines of consecutive text.++To begin a new paragraph, separate it by at least one blank line.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Paragraphs") ]))+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "Paragraphs don\8217t require any special markup in AsciiDoc.\nA paragraph is just one or more lines of consecutive text.")+             ])+      , Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "To begin a new paragraph, separate it by at least one blank line.")+             ])+      ]+  }
+ test/asciidoctor/pass/basic.test view
@@ -0,0 +1,21 @@++++++<p>Allons-y!</p>+image:tiger.png[]++++++>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (PassthroughBlock "<p>Allons-y!</p>\nimage:tiger.png[]\n")+      ]+  }
+ test/asciidoctor/preamble/basic.test view
@@ -0,0 +1,48 @@+= The Dangerous and Thrilling Documentation Chronicles++This journey begins on a bleary Monday morning.+Our intrepid team is in desperate need of double shot mochas, but the milk expired eight days ago.++== Cavern Glow+The river rages through the cavern, rattling its content.+>>>+Document+  { docMeta =+      Meta+        { docTitle =+            [ Inline+                mempty (Str "The Dangerous and Thrilling Documentation Chronicles")+            ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "This journey begins on a bleary Monday morning.\nOur intrepid team is in desperate need of double shot mochas, but the milk expired eight days ago.")+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_cavern_glow" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Cavern Glow") ]+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str "The river rages through the cavern, rattling its content.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/preamble/toc-placement-preamble.test view
@@ -0,0 +1,50 @@+= The Dangerous and Thrilling Documentation Chronicles+:toc: preamble++This journey begins on a bleary Monday morning.+Our intrepid team is in desperate need of double shot mochas, but the milk expired eight days ago.++== Cavern Glow+The river rages through the cavern, rattling its content.+>>>+Document+  { docMeta =+      Meta+        { docTitle =+            [ Inline+                mempty (Str "The Dangerous and Thrilling Documentation Chronicles")+            ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "toc" , "preamble" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline+                 mempty+                 (Str+                    "This journey begins on a bleary Monday morning.\nOur intrepid team is in desperate need of double shot mochas, but the milk expired eight days ago.")+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_cavern_glow" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Cavern Glow") ]+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str "The river rages through the cavern, rattling its content.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/quote/basic.test view
@@ -0,0 +1,31 @@+[quote]+Four score and seven years ago our fathers brought forth+on this continent a new nation...+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (QuoteBlock+             Nothing+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "Four score and seven years ago our fathers brought forth\non this continent a new nation\8230")+                    ])+             ])+      ]+  }
+ test/asciidoctor/quote/block.test view
@@ -0,0 +1,48 @@+____+Dennis: Come and see the violence inherent in the system. Help! Help! I'm being repressed!++King Arthur: Bloody peasant!++Dennis: Oh, what a giveaway! Did you hear that? Did you hear that, eh? That's what I'm on about! Did you see him repressing me? You saw him, Didn't you?+____+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (QuoteBlock+             Nothing+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "Dennis: Come and see the violence inherent in the system. Help! Help! I\8217m being repressed!")+                    ])+             , Block+                 mempty+                 Nothing+                 (Paragraph [ Inline mempty (Str "King Arthur: Bloody peasant!") ])+             , Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "Dennis: Oh, what a giveaway! Did you hear that? Did you hear that, eh? That\8217s what I\8217m on about! Did you see him repressing me? You saw him, Didn\8217t you?")+                    ])+             ])+      ]+  }
+ test/asciidoctor/quote/with-attribution-and-citetitle.test view
@@ -0,0 +1,28 @@+[quote, Captain James T. Kirk, Star Trek IV: The Voyage Home]+Everybody remember where we parked.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (QuoteBlock+             (Just+                (Attribution+                   "Captain James T. Kirk, Star Trek IV: The Voyage Home"))+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "Everybody remember where we parked.") ])+             ])+      ]+  }
+ test/asciidoctor/quote/with-attribution.test view
@@ -0,0 +1,29 @@+[quote, Albert Einstein]+A person who never made a mistake never tried anything new.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (QuoteBlock+             (Just (Attribution "Albert Einstein"))+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str "A person who never made a mistake never tried anything new.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/quote/with-id-and-role.test view
@@ -0,0 +1,29 @@+[quote, id="parking", role="startrek"]+Everybody remember where we parked.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( []+          , fromList [ ( "id" , "parking" ) , ( "role" , "startrek" ) ]+          )+          Nothing+          (QuoteBlock+             Nothing+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "Everybody remember where we parked.") ])+             ])+      ]+  }
+ test/asciidoctor/quote/with-title.test view
@@ -0,0 +1,33 @@+.After landing the cloaked Klingon bird of prey in Golden Gate park:+[quote]+Everybody remember where we parked.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just+             (BlockTitle+                [ Inline+                    mempty+                    (Str+                       "After landing the cloaked Klingon bird of prey in Golden Gate park:")+                ]))+          (QuoteBlock+             Nothing+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "Everybody remember where we parked.") ])+             ])+      ]+  }
+ test/asciidoctor/section/book-part-title.test view
@@ -0,0 +1,34 @@+// Subsequent level-0 titles are allowed only for doctype book.+= Document Title+:doctype: book++= Part Title++== Section Level 1+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "doctype" , "book" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_part_title" ) ] )+          Nothing+          (Section+             (Level 0)+             [ Inline mempty (Str "Part Title") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_section_level_1" ) ] )+                 Nothing+                 (Section (Level 1) [ Inline mempty (Str "Section Level 1") ] [])+             ])+      ]+  }
+ test/asciidoctor/section/level1.test view
@@ -0,0 +1,19 @@+== Section Level 1+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_level_1" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section Level 1") ] [])+      ]+  }
+ test/asciidoctor/section/level2.test view
@@ -0,0 +1,19 @@+=== Section Level 2+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_level_2" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section Level 2") ] [])+      ]+  }
+ test/asciidoctor/section/level3.test view
@@ -0,0 +1,19 @@+==== Section Level 3+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_level_3" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section Level 3") ] [])+      ]+  }
+ test/asciidoctor/section/level4.test view
@@ -0,0 +1,19 @@+===== Section Level 4+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_level_4" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section Level 4") ] [])+      ]+  }
+ test/asciidoctor/section/level5.test view
@@ -0,0 +1,19 @@+====== Section Level 5+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_level_5" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section Level 5") ] [])+      ]+  }
+ test/asciidoctor/section/max-nesting.test view
@@ -0,0 +1,67 @@+== Section Level 1++=== Section Level 2++==== Section Level 3++===== Section Level 4++====== Section Level 5++=== Section Level 2+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_section_level_1" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Section Level 1") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_section_level_2" ) ] )+                 Nothing+                 (Section+                    (Level 2)+                    [ Inline mempty (Str "Section Level 2") ]+                    [ Block+                        Attr+                        ( [] , fromList [ ( "id" , "_section_level_3" ) ] )+                        Nothing+                        (Section+                           (Level 3)+                           [ Inline mempty (Str "Section Level 3") ]+                           [ Block+                               Attr+                               ( [] , fromList [ ( "id" , "_section_level_4" ) ] )+                               Nothing+                               (Section+                                  (Level 4)+                                  [ Inline mempty (Str "Section Level 4") ]+                                  [ Block+                                      Attr+                                      ( [] , fromList [ ( "id" , "_section_level_5" ) ] )+                                      Nothing+                                      (Section+                                         (Level 5) [ Inline mempty (Str "Section Level 5") ] [])+                                  ])+                           ])+                    ])+             , Block+                 Attr+                 ( [] , fromList [ ( "id" , "_section_level_2_2" ) ] )+                 Nothing+                 (Section (Level 2) [ Inline mempty (Str "Section Level 2") ] [])+             ])+      ]+  }
+ test/asciidoctor/section/numbered-sectnumlevels-1.test view
@@ -0,0 +1,73 @@+:numbered:+:sectnumlevels: 1+== Introduction to Asciidoctor++== Quick Starts++=== Usage++==== Using the Command Line Interface++=== Syntax++== Terms and Concepts+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList+              [ ( "numbered" , "" )+              , ( "sectids" , "" )+              , ( "sectnumlevels" , "1" )+              ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_introduction_to_asciidoctor" ) ] )+          Nothing+          (Section+             (Level 1) [ Inline mempty (Str "Introduction to Asciidoctor") ] [])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_quick_starts" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Quick Starts") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_usage" ) ] )+                 Nothing+                 (Section+                    (Level 2)+                    [ Inline mempty (Str "Usage") ]+                    [ Block+                        Attr+                        ( []+                        , fromList [ ( "id" , "_using_the_command_line_interface" ) ]+                        )+                        Nothing+                        (Section+                           (Level 3)+                           [ Inline mempty (Str "Using the Command Line Interface") ]+                           [])+                    ])+             , Block+                 Attr+                 ( [] , fromList [ ( "id" , "_syntax" ) ] )+                 Nothing+                 (Section (Level 2) [ Inline mempty (Str "Syntax") ] [])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_terms_and_concepts" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Terms and Concepts") ] [])+      ]+  }
+ test/asciidoctor/section/numbered.test view
@@ -0,0 +1,76 @@+:numbered:+== Introduction to Asciidoctor++== Quick Starts++=== Usage++==== Using the Command Line Interface++===== Processing Your Content++=== Syntax++== Terms and Concepts+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "numbered" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_introduction_to_asciidoctor" ) ] )+          Nothing+          (Section+             (Level 1) [ Inline mempty (Str "Introduction to Asciidoctor") ] [])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_quick_starts" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Quick Starts") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_usage" ) ] )+                 Nothing+                 (Section+                    (Level 2)+                    [ Inline mempty (Str "Usage") ]+                    [ Block+                        Attr+                        ( []+                        , fromList [ ( "id" , "_using_the_command_line_interface" ) ]+                        )+                        Nothing+                        (Section+                           (Level 3)+                           [ Inline mempty (Str "Using the Command Line Interface") ]+                           [ Block+                               Attr+                               ( [] , fromList [ ( "id" , "_processing_your_content" ) ] )+                               Nothing+                               (Section+                                  (Level 4) [ Inline mempty (Str "Processing Your Content") ] [])+                           ])+                    ])+             , Block+                 Attr+                 ( [] , fromList [ ( "id" , "_syntax" ) ] )+                 Nothing+                 (Section (Level 2) [ Inline mempty (Str "Syntax") ] [])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_terms_and_concepts" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Terms and Concepts") ] [])+      ]+  }
+ test/asciidoctor/section/sectanchors-and-sectlinks.test view
@@ -0,0 +1,27 @@+:sectanchors:+:sectlinks:+== Linked title with anchor+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList+              [ ( "sectanchors" , "" )+              , ( "sectids" , "" )+              , ( "sectlinks" , "" )+              ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_linked_title_with_anchor" ) ] )+          Nothing+          (Section+             (Level 1) [ Inline mempty (Str "Linked title with anchor") ] [])+      ]+  }
+ test/asciidoctor/section/sectanchors.test view
@@ -0,0 +1,21 @@+:sectanchors:+== Title with anchor+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectanchors" , "" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_title_with_anchor" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Title with anchor") ] [])+      ]+  }
+ test/asciidoctor/section/sectlinks.test view
@@ -0,0 +1,21 @@+:sectlinks:+== Linked title+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "sectlinks" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_linked_title" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Linked title") ] [])+      ]+  }
+ test/asciidoctor/section/with-custom-id.test view
@@ -0,0 +1,20 @@+[#foo]+== Section Title+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "foo" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section Title") ] [])+      ]+  }
+ test/asciidoctor/section/with-roles.test view
@@ -0,0 +1,23 @@+[.center.red]+== Section Title+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( []+          , fromList+              [ ( "id" , "_section_title" ) , ( "role" , "center red" ) ]+          )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Section Title") ] [])+      ]+  }
+ test/asciidoctor/sidebar/basic.test view
@@ -0,0 +1,32 @@+****+AsciiDoc was first released in Nov 2002 by Stuart Rackham.+It was designed from the start to be a shorthand syntax+for producing professional documents like DocBook and LaTeX.+****+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Sidebar+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "AsciiDoc was first released in Nov 2002 by Stuart Rackham.\nIt was designed from the start to be a shorthand syntax\nfor producing professional documents like DocBook and LaTeX.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/sidebar/with-id-and-role.test view
@@ -0,0 +1,34 @@+[#origin.center]+****+AsciiDoc was first released in Nov 2002 by Stuart Rackham.+It was designed from the start to be a shorthand syntax+for producing professional documents like DocBook and LaTeX.+****+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "origin" ) , ( "role" , "center" ) ] )+          Nothing+          (Sidebar+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "AsciiDoc was first released in Nov 2002 by Stuart Rackham.\nIt was designed from the start to be a shorthand syntax\nfor producing professional documents like DocBook and LaTeX.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/sidebar/with-title.test view
@@ -0,0 +1,33 @@+.AsciiDoc history+****+AsciiDoc was first released in Nov 2002 by Stuart Rackham.+It was designed from the start to be a shorthand syntax+for producing professional documents like DocBook and LaTeX.+****+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "AsciiDoc history") ]))+          (Sidebar+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty+                        (Str+                           "AsciiDoc was first released in Nov 2002 by Stuart Rackham.\nIt was designed from the start to be a shorthand syntax\nfor producing professional documents like DocBook and LaTeX.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/stem/asciimath.test view
@@ -0,0 +1,19 @@+:stem: asciimath+[stem]++++++sqrt(4) = 2++++++>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "stem" , "asciimath" ) ]+        }+  , docBlocks =+      [ Block mempty Nothing (MathBlock Nothing "sqrt(4) = 2\n") ]+  }
+ test/asciidoctor/stem/latexmath.test view
@@ -0,0 +1,24 @@+:stem: latexmath+[stem]++++++C = \alpha + \beta Y^{\gamma} + \epsilon++++++>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "stem" , "latexmath" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (MathBlock+             Nothing "C = \\alpha + \\beta Y^{\\gamma} + \\epsilon\n")+      ]+  }
+ test/asciidoctor/stem/with-id-and-role.test view
@@ -0,0 +1,23 @@+:stem:+[stem, id="sqrt", role="right"]++++++sqrt(4) = 2++++++>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) , ( "stem" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "sqrt" ) , ( "role" , "right" ) ] )+          Nothing+          (MathBlock Nothing "sqrt(4) = 2\n")+      ]+  }
+ test/asciidoctor/stem/with-title.test view
@@ -0,0 +1,23 @@+:stem:+[stem]+.Equation++++++sqrt(4) = 2++++++>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) , ( "stem" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Equation") ]))+          (MathBlock Nothing "sqrt(4) = 2\n")+      ]+  }
+ test/asciidoctor/table/aligns-per-cell.test view
@@ -0,0 +1,195 @@+[cols="3"]+|===+^|Prefix the +{vbar}+ with +{caret}+ to center content horizontally+<|Prefix the +{vbar}+ with +<+ to align the content to the left horizontally+>|Prefix the +{vbar}+ with +>+ to align the content to the right horizontally++.^|Prefix the +{vbar}+ with a +.+ and +{caret}+ to center the content in the cell vertically+.<|Prefix the +{vbar}+ with a +.+ and +<+ to align the content to the top of the cell+.>|Prefix the +{vbar}+ with a +.+ and +>+ to align the content to the bottom of the cell++3+^.^|This content spans three columns (+3{plus}+) and is centered horizontally (+{caret}+) and vertically (+.{caret}+) within the cell.++|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Just 3+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline mempty (Str "Prefix the ")+                                   , Inline mempty (Str "{vbar}")+                                   , Inline mempty (Str " with ")+                                   , Inline mempty (Str "{caret}")+                                   , Inline mempty (Str " to center content horizontally")+                                   ])+                            ]+                        , cellHorizAlign = Just AlignCenter+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             [ TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph+                                [ Inline mempty (Str "Prefix the ")+                                , Inline mempty (Str "{vbar}")+                                , Inline mempty (Str " with ")+                                , Inline mempty (Str "<")+                                , Inline+                                    mempty (Str " to align the content to the left horizontally")+                                ])+                         ]+                     , cellHorizAlign = Just AlignLeft+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             , TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph+                                [ Inline mempty (Str "Prefix the ")+                                , Inline mempty (Str "{vbar}")+                                , Inline mempty (Str " with ")+                                , Inline mempty (Str ">")+                                , Inline+                                    mempty (Str " to align the content to the right horizontally")+                                ])+                         ]+                     , cellHorizAlign = Just AlignRight+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             , TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph+                                [ Inline mempty (Str "Prefix the ")+                                , Inline mempty (Str "{vbar}")+                                , Inline mempty (Str " with a ")+                                , Inline mempty (Str ".")+                                , Inline mempty (Str " and ")+                                , Inline mempty (Str "{caret}")+                                , Inline+                                    mempty (Str " to center the content in the cell vertically")+                                ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Just AlignMiddle+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             , TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph+                                [ Inline mempty (Str "Prefix the ")+                                , Inline mempty (Str "{vbar}")+                                , Inline mempty (Str " with a ")+                                , Inline mempty (Str ".")+                                , Inline mempty (Str " and ")+                                , Inline mempty (Str "<")+                                , Inline+                                    mempty (Str " to align the content to the top of the cell")+                                ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Just AlignTop+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             , TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph+                                [ Inline mempty (Str "Prefix the ")+                                , Inline mempty (Str "{vbar}")+                                , Inline mempty (Str " with a ")+                                , Inline mempty (Str ".")+                                , Inline mempty (Str " and ")+                                , Inline mempty (Str ">")+                                , Inline+                                    mempty (Str " to align the content to the bottom of the cell")+                                ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Just AlignBottom+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline mempty (Str "This content spans three columns (")+                                   , Inline mempty (Str "3{plus}")+                                   , Inline mempty (Str ") and is centered horizontally (")+                                   , Inline mempty (Str "{caret}")+                                   , Inline mempty (Str ") and vertically (")+                                   , Inline mempty (Str ".{caret}")+                                   , Inline mempty (Str ") within the cell.")+                                   ])+                            ]+                        , cellHorizAlign = Just AlignCenter+                        , cellVertAlign = Just AlignMiddle+                        , cellColspan = 3+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }
+ test/asciidoctor/table/basic.test view
@@ -0,0 +1,91 @@+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+| Cell in column 1, row 2 | Cell in column 2, row 2+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 2") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 2") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }
+ test/asciidoctor/table/cell-with-paragraphs.test view
@@ -0,0 +1,69 @@+|===++|Single paragraph on row 1++|First paragraph on row 2++Second paragraph on row 2+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Single paragraph on row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "First paragraph on row 2") ])+                            , Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Second paragraph on row 2") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }
+ test/asciidoctor/table/colspan.test view
@@ -0,0 +1,116 @@+|===++| Cell in column 1, row 1 | Cell in column 2, row 1 | Cell in column 3, row 1++2+|Content in a single cell that spans columns 1 and 3 | Cell in column 3, row 1++|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 3, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Str "Content in a single cell that spans columns 1 and 3")+                                   ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 2+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 3, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }
+ test/asciidoctor/table/insane-cells-formatting.test view
@@ -0,0 +1,200 @@+|===++2*>m|This content is duplicated across two columns.++It is aligned right horizontally.++And it is monospaced.++.3+^.>s|This cell spans 3 rows. The content is centered horizontally, aligned to the bottom of the cell, and strong.+e|This content is emphasized.++.^l|This content is aligned to the top of the cell and literal.++a|+[source]+puts "This is a source block!"++|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Monospace+                                          [ Inline+                                              mempty+                                              (Str "This content is duplicated across two columns.")+                                          ])+                                   ])+                            , Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Monospace+                                          [ Inline mempty (Str "It is aligned right horizontally.")+                                          ])+                                   ])+                            , Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Monospace [ Inline mempty (Str "And it is monospaced.") ])+                                   ])+                            ]+                        , cellHorizAlign = Just AlignRight+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Monospace+                                          [ Inline+                                              mempty+                                              (Str "This content is duplicated across two columns.")+                                          ])+                                   ])+                            , Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Monospace+                                          [ Inline mempty (Str "It is aligned right horizontally.")+                                          ])+                                   ])+                            , Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty+                                       (Monospace [ Inline mempty (Str "And it is monospaced.") ])+                                   ])+                            ]+                        , cellHorizAlign = Just AlignRight+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             [ TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph+                                [ Inline+                                    mempty+                                    (Bold+                                       [ Inline+                                           mempty+                                           (Str+                                              "This cell spans 3 rows. The content is centered horizontally, aligned to the bottom of the cell, and strong.")+                                       ])+                                ])+                         ]+                     , cellHorizAlign = Just AlignCenter+                     , cellVertAlign = Just AlignBottom+                     , cellColspan = 1+                     , cellRowspan = 3+                     }+                 , TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph+                                [ Inline+                                    mempty+                                    (Italic [ Inline mempty (Str "This content is emphasized.") ])+                                ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             , TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (LiteralBlock+                                "This content is aligned to the top of the cell and literal.\n\n")+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Just AlignMiddle+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Listing+                                   Nothing [ SourceLine "puts \"This is a source block!\"" [] ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }
+ test/asciidoctor/table/rowspan.test view
@@ -0,0 +1,156 @@+|===++| Cell in column 1, row 1 | Cell in column 2, row 1 | Cell in column 3, row 1++.2+|Content in a single cell that spans rows 2 and 3++| Cell in column 2, row 2 | Cell in column 3, row 2++| Cell in column 2, row 3 | Cell in column 3, row 3+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 3, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             [ TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph+                                [ Inline+                                    mempty (Str "Content in a single cell that spans rows 2 and 3")+                                ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 2+                     }+                 , TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph [ Inline mempty (Str "Cell in column 2, row 2") ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 , TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph [ Inline mempty (Str "Cell in column 3, row 2") ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 3") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 3, row 3") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }
+ test/asciidoctor/table/with-autowidth-and-width.test view
@@ -0,0 +1,65 @@+[options="autowidth", width=80]+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "width" , "80" ) ] )+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-autowidth.test view
@@ -0,0 +1,64 @@+[options="autowidth"]+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-cols-halign.test view
@@ -0,0 +1,84 @@+[cols="<,^,>"]+|===+|Cell in column 1, row 1+|Cell in column 2, row 1+|Cell in column 3, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Just AlignLeft+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Just AlignCenter+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Just AlignRight+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 3, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-cols-styles.test view
@@ -0,0 +1,148 @@+[cols="a,e,h,l,m,s"]+|===+|image::sunset.jpg[AsciiDoc content]+|Emphasized text+|Styled like a header+|Literal block+|Monospaced text+|Strong text+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Just AsciiDocStyle+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Just EmphasisStyle+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Just HeaderStyle+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Just LiteralStyle+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Just MonospaceStyle+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Just StrongStyle+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (BlockImage+                                   (Target "sunset.jpg")+                                   (Just (AltText "AsciiDoc content"))+                                   Nothing+                                   Nothing)+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty (Italic [ Inline mempty (Str "Emphasized text") ])+                                   ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Styled like a header") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block mempty Nothing (LiteralBlock "Literal block\n") ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline+                                       mempty (Monospace [ Inline mempty (Str "Monospaced text") ])+                                   ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline mempty (Bold [ Inline mempty (Str "Strong text") ]) ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-cols-valign.test view
@@ -0,0 +1,84 @@+[cols=".<,.^,.>"]+|===+|Cell in column 1, row 1+|Cell in column 2, row 1+|Cell in column 3, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Just AlignTop+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Just AlignMiddle+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Just AlignBottom+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 3, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-cols-width.test view
@@ -0,0 +1,84 @@+[cols="50,20,30"]+|===+|Cell in column 1, row 1+|Cell in column 2, row 1+|Cell in column 3, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Just 50+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Just 20+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Just 30+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 3, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-float.test view
@@ -0,0 +1,65 @@+[float=left]+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "float" , "left" ) ] )+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-footer.test view
@@ -0,0 +1,119 @@+[options="footer"]+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+| Cell in column 1, row 2 | Cell in column 2, row 2+| Footer in column 1, row 3 | Footer in column 2, row 3+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             [ TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph [ Inline mempty (Str "Cell in column 1, row 2") ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 , TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph [ Inline mempty (Str "Cell in column 2, row 2") ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Footer in column 1, row 3") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Footer in column 2, row 3") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }
+ test/asciidoctor/table/with-frame-sides.test view
@@ -0,0 +1,65 @@+[frame=sides]+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "frame" , "sides" ) ] )+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-grid-cols.test view
@@ -0,0 +1,65 @@+[grid=cols]+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "grid" , "cols" ) ] )+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-header.test view
@@ -0,0 +1,120 @@+[options="header"]+|===+| Name of Column 1 | Name of Column 2++| Cell in column 1, row 1 | Cell in column 2, row 1+| Cell in column 1, row 2 | Cell in column 2, row 2+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Name of Column 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Name of Column 2") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             [ TableRow+                 [ TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 , TableCell+                     { cellContent =+                         [ Block+                             mempty+                             Nothing+                             (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                         ]+                     , cellHorizAlign = Nothing+                     , cellVertAlign = Nothing+                     , cellColspan = 1+                     , cellRowspan = 1+                     }+                 ]+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 2") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 2") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }
+ test/asciidoctor/table/with-id-and-role.test view
@@ -0,0 +1,65 @@+[#tabular.center]+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "tabular" ) , ( "role" , "center" ) ] )+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-title.test view
@@ -0,0 +1,64 @@+.Table FTW!+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Table FTW!") ]))+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/table/with-width.test view
@@ -0,0 +1,65 @@+[width=80]+|===+| Cell in column 1, row 1 | Cell in column 2, row 1+|===+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "width" , "80" ) ] )+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 1, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block+                                mempty+                                Nothing+                                (Paragraph [ Inline mempty (Str "Cell in column 2, row 1") ])+                            ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             Nothing)+      ]+  }
+ test/asciidoctor/thematic_break/basic.test view
@@ -0,0 +1,13 @@+'''+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks = [ Block mempty Nothing ThematicBreak ]+  }
+ test/asciidoctor/toc/doc-without-sections.test view
@@ -0,0 +1,17 @@+= Document Title+:toc: macro++toc::[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "toc" , "macro" ) ]+        }+  , docBlocks = [ Block mempty Nothing TOC ]+  }
+ test/asciidoctor/toc/in-preamble.test view
@@ -0,0 +1,37 @@+= Document Title+:toc: macro++toc::[]++== The Ravages of Writing++=== A Recipe for Potion+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "toc" , "macro" ) ]+        }+  , docBlocks =+      [ Block mempty Nothing TOC+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_the_ravages_of_writing" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "The Ravages of Writing") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_a_recipe_for_potion" ) ] )+                 Nothing+                 (Section+                    (Level 2) [ Inline mempty (Str "A Recipe for Potion") ] [])+             ])+      ]+  }
+ test/asciidoctor/toc/in-section.test view
@@ -0,0 +1,49 @@+// The toc node is used only with toc::[] macro!+// Actual TOC content is rendered in the outline template, this template+// usually renders just a "border".+= Document Title+:toc: macro++== Introduction++toc::[]++== The Ravages of Writing++=== A Recipe for Potion+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "toc" , "macro" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_introduction" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Introduction") ]+             [ Block mempty Nothing TOC ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_the_ravages_of_writing" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "The Ravages of Writing") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_a_recipe_for_potion" ) ] )+                 Nothing+                 (Section+                    (Level 2) [ Inline mempty (Str "A Recipe for Potion") ] [])+             ])+      ]+  }
+ test/asciidoctor/toc/with-id-and-role.test view
@@ -0,0 +1,41 @@+= Document Title+:toc: macro++== Introduction++toc::[id="mytoc", role="taco"]++== The Ravages of Writing+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "toc" , "macro" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_introduction" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Introduction") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "mytoc" ) , ( "role" , "taco" ) ] )+                 Nothing+                 TOC+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_the_ravages_of_writing" ) ] )+          Nothing+          (Section+             (Level 1) [ Inline mempty (Str "The Ravages of Writing") ] [])+      ]+  }
+ test/asciidoctor/toc/with-levels.test view
@@ -0,0 +1,47 @@+= Document Title+:toc: macro++== Introduction++toc::[levels=1]++== The Ravages of Writing++=== A Recipe for Potion+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "toc" , "macro" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_introduction" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Introduction") ]+             [ Block Attr ( [] , fromList [ ( "levels" , "1" ) ] ) Nothing TOC+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_the_ravages_of_writing" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "The Ravages of Writing") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_a_recipe_for_potion" ) ] )+                 Nothing+                 (Section+                    (Level 2) [ Inline mempty (Str "A Recipe for Potion") ] [])+             ])+      ]+  }
+ test/asciidoctor/toc/with-title.test view
@@ -0,0 +1,41 @@+= Document Title+:toc: macro++== Introduction++toc::[title="Table of Adventures"]++== The Ravages of Writing+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Document Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "sectids" , "" ) , ( "toc" , "macro" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_introduction" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Introduction") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "title" , "Table of Adventures" ) ] )+                 Nothing+                 TOC+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_the_ravages_of_writing" ) ] )+          Nothing+          (Section+             (Level 1) [ Inline mempty (Str "The Ravages of Writing") ] [])+      ]+  }
+ test/asciidoctor/ulist/basic.test view
@@ -0,0 +1,41 @@+* Edgar Allen Poe+* Sheri S. Tepper+* Bill Bryson+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             (BulletList (Level 1))+             [ ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Edgar Allen Poe") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Sheri S. Tepper") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "Bill Bryson") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/ulist/checklist.test view
@@ -0,0 +1,45 @@+- [*] checked+- [x] also checked+- [ ] not checked+-     normal list item+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             CheckList+             [ ListItem+                 (Just Checked)+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "checked") ])+                 ]+             , ListItem+                 (Just Checked)+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "also checked") ])+                 ]+             , ListItem+                 (Just Unchecked)+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "not checked") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "normal list item") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/ulist/complex-content.test view
@@ -0,0 +1,79 @@+* Every list item has at least one paragraph of content,+  which may be wrapped, even using a hanging indent.+++Additional paragraphs or blocks are adjoined by putting+a list continuation on a line adjacent to both blocks.+++list continuation:: a plus sign (`{plus}`) on a line by itself++* A literal paragraph does not require a list continuation.++ $ gem install asciidoctor+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             (BulletList (Level 1))+             [ ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Every list item has at least one paragraph of content,\n  which may be wrapped, even using a hanging indent.")+                        ])+                 , Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str+                               "Additional paragraphs or blocks are adjoined by putting\na list continuation on a line adjacent to both blocks.")+                        ])+                 , Block+                     mempty+                     Nothing+                     (DefinitionList+                        [ ( [ Inline mempty (Str "list continuation") ]+                          , [ Block+                                mempty+                                Nothing+                                (Paragraph+                                   [ Inline mempty (Str "a plus sign (")+                                   , Inline mempty (Monospace [ Inline mempty (Str "+") ])+                                   , Inline mempty (Str ") on a line by itself")+                                   ])+                            ]+                          )+                        ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph+                        [ Inline+                            mempty+                            (Str "A literal paragraph does not require a list continuation.")+                        ])+                 ]+             ])+      , Block mempty Nothing (LiteralBlock "$ gem install asciidoctor\n")+      ]+  }
+ test/asciidoctor/ulist/max-nesting.test view
@@ -0,0 +1,87 @@+* level 1+** level 2+*** level 3+**** level 4+***** level 5+** level 2+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             (BulletList (Level 1))+             [ ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "level 1") ])+                 , Block+                     mempty+                     Nothing+                     (List+                        (BulletList (Level 2))+                        [ ListItem+                            Nothing+                            [ Block+                                mempty Nothing (Paragraph [ Inline mempty (Str "level 2") ])+                            , Block+                                mempty+                                Nothing+                                (List+                                   (BulletList (Level 3))+                                   [ ListItem+                                       Nothing+                                       [ Block+                                           mempty+                                           Nothing+                                           (Paragraph [ Inline mempty (Str "level 3") ])+                                       , Block+                                           mempty+                                           Nothing+                                           (List+                                              (BulletList (Level 4))+                                              [ ListItem+                                                  Nothing+                                                  [ Block+                                                      mempty+                                                      Nothing+                                                      (Paragraph [ Inline mempty (Str "level 4") ])+                                                  , Block+                                                      mempty+                                                      Nothing+                                                      (List+                                                         (BulletList (Level 5))+                                                         [ ListItem+                                                             Nothing+                                                             [ Block+                                                                 mempty+                                                                 Nothing+                                                                 (Paragraph+                                                                    [ Inline mempty (Str "level 5")+                                                                    ])+                                                             ]+                                                         ])+                                                  ]+                                              ])+                                       ]+                                   ])+                            ]+                        , ListItem+                            Nothing+                            [ Block+                                mempty Nothing (Paragraph [ Inline mempty (Str "level 2") ])+                            ]+                        ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/ulist/with-id-and-role.test view
@@ -0,0 +1,43 @@+[#authors.green]+* Edgar Allen Poe+* Sheri S. Tepper+* Bill Bryson+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "authors" ) , ( "role" , "green" ) ] )+          Nothing+          (List+             (BulletList (Level 1))+             [ ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Edgar Allen Poe") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Sheri S. Tepper") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "Bill Bryson") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/ulist/with-title.test view
@@ -0,0 +1,42 @@+.Writers+* Edgar Allen Poe+* Sheri S. Tepper+* Bill Bryson+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Writers") ]))+          (List+             (BulletList (Level 1))+             [ ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Edgar Allen Poe") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty+                     Nothing+                     (Paragraph [ Inline mempty (Str "Sheri S. Tepper") ])+                 ]+             , ListItem+                 Nothing+                 [ Block+                     mempty Nothing (Paragraph [ Inline mempty (Str "Bill Bryson") ])+                 ]+             ])+      ]+  }
+ test/asciidoctor/verse/basic-with-attribution-and-citetitle.test view
@@ -0,0 +1,30 @@+[verse, Carl Sandburg, two lines from the poem Fog]+The fog comes+on little cat feet.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Verse+             (Just (Attribution "Carl Sandburg, two lines from the poem Fog"))+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "The fog comes")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "on little cat feet.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/verse/basic-with-attribution.test view
@@ -0,0 +1,30 @@+[verse, Carl Sandburg]+The fog comes+on little cat feet.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Verse+             (Just (Attribution "Carl Sandburg"))+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "The fog comes")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "on little cat feet.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/verse/basic-with-id-and-role.test view
@@ -0,0 +1,31 @@+[verse, id="sandburg", role="center"]+The fog comes+on little cat feet.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "sandburg" ) , ( "role" , "center" ) ] )+          Nothing+          (Verse+             Nothing+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "The fog comes")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "on little cat feet.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/verse/basic-with-title.test view
@@ -0,0 +1,31 @@+[verse]+.Poetry+The fog comes+on little cat feet.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Poetry") ]))+          (Verse+             Nothing+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "The fog comes")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "on little cat feet.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/verse/basic.test view
@@ -0,0 +1,30 @@+[verse]+The fog comes+on little cat feet.+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Verse+             Nothing+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "The fog comes")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "on little cat feet.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/verse/block.test view
@@ -0,0 +1,49 @@+[verse]+____+The fog comes+on little cat feet.++It sits looking+over harbor and city+on silent haunches+and then moves on.+____+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Verse+             Nothing+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "The fog comes")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "on little cat feet.")+                    ])+             , Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "It sits looking")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "over harbor and city")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "on silent haunches")+                    , Inline mempty HardBreak+                    , Inline mempty (Str "and then moves on.")+                    ])+             ])+      ]+  }
+ test/asciidoctor/video/basic.test view
@@ -0,0 +1,14 @@+video::video_file.mp4[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block mempty Nothing (BlockVideo (Target "video_file.mp4")) ]+  }
+ test/asciidoctor/video/with-dimensions.test view
@@ -0,0 +1,19 @@+video::video_file.mp4[width=640, height=480]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "height" , "480" ) , ( "width" , "640" ) ] )+          Nothing+          (BlockVideo (Target "video_file.mp4"))+      ]+  }
+ test/asciidoctor/video/with-end.test view
@@ -0,0 +1,19 @@+video::video_file.mp4[end=60]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "end" , "60" ) ] )+          Nothing+          (BlockVideo (Target "video_file.mp4"))+      ]+  }
+ test/asciidoctor/video/with-id-and-role.test view
@@ -0,0 +1,19 @@+video::video_file.mp4[id="lindsey", role="watch"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "lindsey" ) , ( "role" , "watch" ) ] )+          Nothing+          (BlockVideo (Target "video_file.mp4"))+      ]+  }
+ test/asciidoctor/video/with-options.test view
@@ -0,0 +1,19 @@+video::video_file.mp4[options="autoplay, loop, nocontrols"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "options" , "autoplay, loop, nocontrols" ) ] )+          Nothing+          (BlockVideo (Target "video_file.mp4"))+      ]+  }
+ test/asciidoctor/video/with-poster.test view
@@ -0,0 +1,19 @@+video::video_file.mp4[poster="sunset.jpg"]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "poster" , "sunset.jpg" ) ] )+          Nothing+          (BlockVideo (Target "video_file.mp4"))+      ]+  }
+ test/asciidoctor/video/with-start.test view
@@ -0,0 +1,19 @@+video::video_file.mp4[start=10]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "start" , "10" ) ] )+          Nothing+          (BlockVideo (Target "video_file.mp4"))+      ]+  }
+ test/asciidoctor/video/with-title.test view
@@ -0,0 +1,19 @@+.Must watch!+video::video_file.mp4[]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just (BlockTitle [ Inline mempty (Str "Must watch!") ]))+          (BlockVideo (Target "video_file.mp4"))+      ]+  }
+ test/feature/attrefs/basic.test view
@@ -0,0 +1,26 @@+= Title+:foo: 333++{foo} and *{foo}*+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes =+            fromList [ ( "foo" , "333" ) , ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Str "333")+             , Inline mempty (Str " and ")+             , Inline mempty (Bold [ Inline mempty (Str "333") ])+             ])+      ]+  }
+ test/feature/callouts/multiple.test view
@@ -0,0 +1,30 @@+[,ruby]+----+import mylib <1> <2> <.>+def foo+  return 42 <.> <5>+end+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Listing+             (Just (Language "ruby"))+             [ SourceLine "import mylib" [ Callout 1 , Callout 2 , Callout 3 ]+             , SourceLine "def foo" []+             , SourceLine "  return 42" [ Callout 4 , Callout 5 ]+             , SourceLine "end" []+             ])+      ]+  }
+ test/feature/counter/basic.test view
@@ -0,0 +1,64 @@+.Theorem {counter:theorem:A}+3 is odd.        ++.Theorem {counter:theorem}+4 is even.++{counter:new} {counter:new}+ +{counter:new:15} should be 3.++{counter:special:4} should be 4.+and now {counter:special}+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          (Just+             (BlockTitle+                [ Inline mempty (Str "Theorem ")+                , Inline mempty (Counter "theorem" UpperAlphaCounter 1)+                ]))+          (Paragraph [ Inline mempty (Str "3 is odd.") ])+      , Block+          mempty+          (Just+             (BlockTitle+                [ Inline mempty (Str "Theorem ")+                , Inline mempty (Counter "theorem" UpperAlphaCounter 2)+                ]))+          (Paragraph [ Inline mempty (Str "4 is even.") ])+      , Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Counter "new" DecimalCounter 1)+             , Inline mempty (Str " ")+             , Inline mempty (Counter "new" DecimalCounter 2)+             ])+      , Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Counter "new" DecimalCounter 3)+             , Inline mempty (Str " should be 3.")+             ])+      , Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (Counter "special" DecimalCounter 4)+             , Inline mempty (Str " should be 4.\nand now ")+             , Inline mempty (Counter "special" DecimalCounter 5)+             ])+      ]+  }
+ test/feature/crossref/basic.test view
@@ -0,0 +1,49 @@+[#mysec]+== My section++In <<mysec>>, and in <<myanch>>++[[myanch,My anchor]]+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "mysec" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "My section") ]+             [ Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline mempty (Str "In ")+                    , Inline+                        mempty+                        (CrossReference+                           "mysec" (Just [ Inline mempty (Str "My section") ]))+                    , Inline mempty (Str ", and in ")+                    , Inline+                        mempty+                        (CrossReference+                           "myanch" (Just [ Inline mempty (Str "My anchor") ]))+                    ])+             , Block+                 mempty+                 Nothing+                 (Paragraph+                    [ Inline+                        mempty (InlineAnchor "myanch" [ Inline mempty (Str "My anchor") ])+                    ])+             ])+      ]+  }
+ test/feature/example/long.test view
@@ -0,0 +1,21 @@+======+hi+======+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (ExampleBlock+             [ Block mempty Nothing (Paragraph [ Inline mempty (Str "hi") ]) ])+      ]+  }
+ test/feature/include/basic.test view
@@ -0,0 +1,29 @@+include::inc/baz.adoc[]++and more+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Include+             "test/feature/include/inc/baz.adoc"+             (Just+                [ Block+                    mempty+                    Nothing+                    (Paragraph [ Inline mempty (Bold [ Inline mempty (Str "baz") ]) ])+                ]))+      , Block+          mempty Nothing (Paragraph [ Inline mempty (Str "and more") ])+      ]+  }
+ test/feature/include/foo.adoc view
@@ -0,0 +1,3 @@+foo++include::inc/bar.adoc[]
+ test/feature/include/inc/bar.adoc view
@@ -0,0 +1,3 @@+bar++include::baz.adoc[]
+ test/feature/include/inc/baz.adoc view
@@ -0,0 +1,1 @@+*baz*
+ test/feature/include/listing.test view
@@ -0,0 +1,28 @@+[,asciidoc]+----+include::foo.adoc[]+----+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (IncludeListing+             (Just (Language "asciidoc"))+             "test/feature/include/foo.adoc"+             (Just+                [ SourceLine "foo" []+                , SourceLine "" []+                , SourceLine "include::inc/bar.adoc[]" []+                ]))+      ]+  }
+ test/feature/include/nested.test view
@@ -0,0 +1,46 @@+include::foo.adoc[]++and more+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Include+             "test/feature/include/foo.adoc"+             (Just+                [ Block mempty Nothing (Paragraph [ Inline mempty (Str "foo") ])+                , Block+                    mempty+                    Nothing+                    (Include+                       "test/feature/include/inc/bar.adoc"+                       (Just+                          [ Block mempty Nothing (Paragraph [ Inline mempty (Str "bar") ])+                          , Block+                              mempty+                              Nothing+                              (Include+                                 "test/feature/include/inc/baz.adoc"+                                 (Just+                                    [ Block+                                        mempty+                                        Nothing+                                        (Paragraph+                                           [ Inline mempty (Bold [ Inline mempty (Str "baz") ]) ])+                                    ]))+                          ]))+                ]))+      , Block+          mempty Nothing (Paragraph [ Inline mempty (Str "and more") ])+      ]+  }
+ test/feature/index/basic.test view
@@ -0,0 +1,39 @@+(((Weapon, Sword)))+indexterm2:[Lancelot] was a knight.+Heindexterm:[knight, Knight of the Round Table, Lancelot] did brave deeds.+I, ((Arthur)), am a king.+My sword is Excalibur(((Sword, Broadsword, Excalibur)))+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Paragraph+             [ Inline mempty (IndexEntry (TermConcealed [ "Weapon" , "Sword" ]))+             , Inline mempty (Str "\n")+             , Inline mempty (IndexEntry (TermInText "Lancelot"))+             , Inline mempty (Str " was a knight.\nHe")+             , Inline+                 mempty+                 (IndexEntry+                    (TermConcealed+                       [ "knight" , "Knight of the Round Table" , "Lancelot" ]))+             , Inline mempty (Str " did brave deeds.\nI, ")+             , Inline mempty (IndexEntry (TermInText "Arthur"))+             , Inline mempty (Str ", am a king.\nMy sword is Excalibur")+             , Inline+                 mempty+                 (IndexEntry+                    (TermConcealed [ "Sword" , "Broadsword" , "Excalibur" ]))+             ])+      ]+  }
+ test/feature/list/indented.test view
@@ -0,0 +1,31 @@+  * a+  * b+    * c+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             (BulletList (Level 1))+             [ ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "a") ]) ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "b") ]) ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "c") ]) ]+             ])+      ]+  }
+ test/feature/list/ordered_with_num.test view
@@ -0,0 +1,27 @@+3. a+4. b+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (List+             (OrderedList (Level 1) (Just 3))+             [ ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "a") ]) ]+             , ListItem+                 Nothing+                 [ Block mempty Nothing (Paragraph [ Inline mempty (Str "b") ]) ]+             ])+      ]+  }
+ test/feature/sectids/basic.test view
@@ -0,0 +1,62 @@+= Title++== Foo++[#foobar]+== Foo++=== Foo++==== Foobar++== Hello *there*, section!+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          Attr+          ( [] , fromList [ ( "id" , "_foo" ) ] )+          Nothing+          (Section (Level 1) [ Inline mempty (Str "Foo") ] [])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "foobar" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Foo") ]+             [ Block+                 Attr+                 ( [] , fromList [ ( "id" , "_foo_2" ) ] )+                 Nothing+                 (Section+                    (Level 2)+                    [ Inline mempty (Str "Foo") ]+                    [ Block+                        Attr+                        ( [] , fromList [ ( "id" , "_foobar" ) ] )+                        Nothing+                        (Section (Level 3) [ Inline mempty (Str "Foobar") ] [])+                    ])+             ])+      , Block+          Attr+          ( [] , fromList [ ( "id" , "_hello_there,_section!" ) ] )+          Nothing+          (Section+             (Level 1)+             [ Inline mempty (Str "Hello ")+             , Inline mempty (Bold [ Inline mempty (Str "there") ])+             , Inline mempty (Str ", section!")+             ]+             [])+      ]+  }
+ test/feature/sectids/nosectid.test view
@@ -0,0 +1,21 @@+= Title+:!sectids:++== My section+>>>+Document+  { docMeta =+      Meta+        { docTitle = [ Inline mempty (Str "Title") ]+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList []+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Section (Level 1) [ Inline mempty (Str "My section") ] [])+      ]+  }
+ test/feature/table/longborder.test view
@@ -0,0 +1,75 @@+|======+| a | b+| c | d+|======+>>>+Document+  { docMeta =+      Meta+        { docTitle = []+        , docTitleAttributes = Nothing+        , docAuthors = []+        , docRevision = Nothing+        , docAttributes = fromList [ ( "sectids" , "" ) ]+        }+  , docBlocks =+      [ Block+          mempty+          Nothing+          (Table+             [ ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             , ColumnSpec+                 { colHorizAlign = Nothing+                 , colVertAlign = Nothing+                 , colWidth = Nothing+                 , colStyle = Nothing+                 }+             ]+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block mempty Nothing (Paragraph [ Inline mempty (Str "a") ]) ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block mempty Nothing (Paragraph [ Inline mempty (Str "b") ]) ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ])+             []+             (Just+                [ TableRow+                    [ TableCell+                        { cellContent =+                            [ Block mempty Nothing (Paragraph [ Inline mempty (Str "c") ]) ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    , TableCell+                        { cellContent =+                            [ Block mempty Nothing (Paragraph [ Inline mempty (Str "d") ]) ]+                        , cellHorizAlign = Nothing+                        , cellVertAlign = Nothing+                        , cellColspan = 1+                        , cellRowspan = 1+                        }+                    ]+                ]))+      ]+  }