packages feed

pandoc 3.6.1 → 3.6.2

raw patch · 46 files changed

+1696/−152 lines, 46 filesdep ~randomdep ~texmathdep ~xml-conduitbinary-added

Dependency ranges changed: random, texmath, xml-conduit

Files

AUTHORS.md view
@@ -344,6 +344,7 @@ - Sam May - Samuel Tardieu - Saumel Lemmenmeier+- Santiago Zarate - Sascha Wilde - Scott Morrison - Sebastian Talmon@@ -365,6 +366,7 @@ - Stephan Meijer - Stephen Altamirano - Stephen Huan+- Stéphane Guillou - Sukil Etxenike - Sukka - Sumit Sahrawat
MANUAL.txt view
@@ -1,7 +1,7 @@ --- title: Pandoc User's Guide author: John MacFarlane-date: December 22, 2024+date: January 12, 2025 ---  # Synopsis@@ -266,9 +266,10 @@     - `mdoc` ([mdoc] manual page markup)     - `muse` ([Muse])     - `native` (native Haskell)-    - `odt` ([OpenOffice text document][ODT])+    - `odt` ([OpenDocument text document][ODT])     - `opml` ([OPML])     - `org` ([Emacs Org mode])+    - `pod` (Perl's [Plain Old Documentation])     - `ris` ([RIS] bibliography)     - `rtf` ([Rich Text Format])     - `rst` ([reStructuredText])@@ -338,9 +339,9 @@     - `ms` ([roff ms])     - `muse` ([Muse])     - `native` (native Haskell)-    - `odt` ([OpenOffice text document][ODT])+    - `odt` ([OpenDocument text document][ODT])     - `opml` ([OPML])-    - `opendocument` ([OpenDocument])+    - `opendocument` ([OpenDocument XML])     - `org` ([Emacs Org mode])     - `pdf` ([PDF])     - `plain` (plain text)@@ -497,8 +498,9 @@ [txt2tags]: https://txt2tags.org [EPUB]: http://idpf.org/epub [OPML]: http://dev.opml.org/spec2.html-[OpenDocument]: http://opendocument.xml.org+[OpenDocument XML]: https://www.oasis-open.org/2021/06/16/opendocument-v1-3-oasis-standard-published/ [ODT]: https://en.wikipedia.org/wiki/OpenDocument+[Plain Old Documentation]: https://perldoc.perl.org/perlpod [Textile]: https://textile-lang.com [MediaWiki markup]: https://www.mediawiki.org/wiki/Help:Formatting [DokuWiki markup]: https://www.dokuwiki.org/dokuwiki@@ -3751,11 +3753,14 @@  ### Extension: `styles` ### {#ext-styles} -When converting from docx, read all docx styles as divs (for-paragraph styles) and spans (for character styles) regardless-of whether pandoc understands the meaning of these styles.-This can be used with [docx custom styles](#custom-styles).-Disabled by default.+When converting from docx, add `custom-styles` attributes+for all docx styles, regardless of whether pandoc understands+the meanings of these styles. Because attributes cannot be+added directly to paragraphs or text in the pandoc AST,+paragraph styles will cause Divs to be created and character+styles will cause Spans to be created to hold the attributes.+(Table styles will be added to the Table elements directly.)+This extension can be used with [docx custom styles](#custom-styles).  input formats :  `docx`@@ -7352,11 +7357,11 @@ set of styles, pandoc allows you to define custom styles for blocks and text using `div`s and `span`s, respectively. -If you define a `div` or `span` with the attribute `custom-style`,-pandoc will apply your specified style to the contained elements (with-the exception of elements whose function depends on a style, like-headings, code blocks, block quotes, or links). So, for example, using-the `bracketed_spans` syntax,+If you define a Div, Span, or Table with the attribute+`custom-style`, pandoc will apply your specified style to the+contained elements (with the exception of elements whose function+depends on a style, like headings, code blocks, block quotes, or+links). So, for example, using the `bracketed_spans` syntax,      [Get out]{custom-style="Emphatically"}, he said. @@ -7398,9 +7403,10 @@  By enabling the [`styles` extension](#ext-styles) in the docx reader (`-f docx+styles`), you can produce output that maintains the styles-of the input document, using the `custom-style` class. Paragraph-styles are interpreted as divs, while character styles are interpreted-as spans.+of the input document, using the `custom-style` class. A `custom-style`+attribute will be added for each style. Divs will be created to+hold the paragraph styles, and Spans to hold the character styles.+Table styles will be applied directly to the Table.  For example, using the `custom-style-reference.docx` file in the test directory, we have the following different outputs:@@ -7566,7 +7572,7 @@ [LibreOffice][lo-pdf-export].  [word-accessible-pdfs]: https://support.microsoft.com/en-us/office/create-accessible-pdfs-064625e0-56ea-4e16-ad71-3aa33bb4b7ed-[lo-pdf-export]: https://help.libreoffice.org/7.1/en-US/text/shared/01/ref_pdf_export_general.html+[lo-pdf-export]: https://help.libreoffice.org/latest/en-US/text/shared/01/ref_pdf_export_general.html   # Running pandoc as a web server
README.md view
@@ -85,10 +85,12 @@   markup) - `muse` ([Muse](https://amusewiki.org/library/manual)) - `native` (native Haskell)-- `odt` ([OpenOffice text+- `odt` ([OpenDocument text   document](https://en.wikipedia.org/wiki/OpenDocument)) - `opml` ([OPML](http://dev.opml.org/spec2.html)) - `org` ([Emacs Org mode](https://orgmode.org))+- `pod` (Perl’s [Plain Old+  Documentation](https://perldoc.perl.org/perlpod)) - `ris` ([RIS](https://en.wikipedia.org/wiki/RIS_(file_format))   bibliography) - `rtf` ([Rich Text@@ -185,10 +187,11 @@ - `ms` ([roff ms](https://man.cx/groff_ms(7))) - `muse` ([Muse](https://amusewiki.org/library/manual)) - `native` (native Haskell)-- `odt` ([OpenOffice text+- `odt` ([OpenDocument text   document](https://en.wikipedia.org/wiki/OpenDocument)) - `opml` ([OPML](http://dev.opml.org/spec2.html))-- `opendocument` ([OpenDocument](http://opendocument.xml.org))+- `opendocument` ([OpenDocument+  XML](https://www.oasis-open.org/2021/06/16/opendocument-v1-3-oasis-standard-published/)) - `org` ([Emacs Org mode](https://orgmode.org)) - `pdf` ([PDF](https://www.adobe.com/pdf/)) - `plain` (plain text)
changelog.md view
@@ -1,5 +1,87 @@ # Revision history for pandoc +## pandoc 3.6.2 (2025-01-12)++  * New output format: `pod` (Evan Silberman). Pod ("Plain old documentation")+    is a markup languaged used principally to document Perl modules and+    programs.++  * New reader module Text.Pandoc.Readers.Pod, exporting `readPod`+    [API change].++  * Docx reader:++    + Support row heads in tables (#9495). Reader: When `w:tblLook` has+      `w:firstColumn` set (or an equivalent bit mask), we set row heads = 1+      in the AST.+    + Read table styles as custom styles when `styles` extension+      is enabled (#9603).++  * HTML reader:++    + Add size information for font awesome SVG icons (#10134).+      If the icon has class `fa-fw` or `fa-w16` or `fa-w14`, we add a width+      attribute to prevent the icon from appearing full-width in PDF or+      docx output.++  * Djot reader:++    + Use a Span with class "mark" rather than "highlighted" for+      highlighted text, for consistency with the other pandoc readers and+      writers.++  * mandoc reader:++    + Add mdoc St for C23 (Evan Silberman).++  * RST reader:++    + Fix handling of underscores (#10497). Fixes a a regression+      introduced in 3.6.++  * Docx writer:++    + Support row heads in tables (#9495). Writer: set `w:firstColumn` in+      `w:tblLook` when there are row heads. (Word only allows one, so this+      is triggered by any number of row heads > 0.)++  * Djot writer:++    + Render a Span with sole class "mark" as highlighted text.++  * Asciidoc writer:++    + Don't emit the class in a span if it's just "mark" (#10511).+      The "mark" class is used for highlighting, and Asciidoc treats+      bare `#...#` with no attributes as highlighted text.+    + Improve escaping (#10385, #2337, #6424).++  * EPUB v2 writer:++    + Fix cover image (#10505).  This is a regression introduced in 3.6.++  * Typst writer:++    + Fix handling of pixel image dimensions (#9945).+      These are now converted to inches as in the LaTeX writer.++  * Improve error message given when users specify `asciidoc` as input+    format (#8416, Santiago Zarate).++  * Allow random 1.3.++  * Use texmath 0.12.8.13 (typst improvements).++  * `lua-filters.md`: document `system.os` return values (#10523).++  * `MANUAL.txt`:++    + Improve manual's coverage of custom styles.+    + Replace LibreOffice PDF documentation link to latest so it links+      to the latest major release rather than a specific major release+      (which there are two of every year) (Stéphane Guillou).+    + Improve links and descriptions for `odt`, `opendocument` (#10518).+ ## pandoc 3.6.1 (2024-12-23)    * Allow YAML bibliographies to be arrays of references (#10452).
pandoc.cabal view
@@ -1,6 +1,6 @@ cabal-version:   2.4 name:            pandoc-version:         3.6.1+version:         3.6.2 build-type:      Simple license:         GPL-2.0-or-later license-file:    COPYING.md@@ -12,7 +12,8 @@ homepage:        https://pandoc.org category:        Text tested-with:     GHC == 8.10.7, GHC == 9.0.2,-                 GHC == 9.2.5, GHC == 9.4.4, GHC == 9.6.3+                 GHC == 9.2.5, GHC == 9.4.4, GHC == 9.6.3,+                 GHC == 9.8.2, GHC == 9.10.1 synopsis:        Conversion between markup formats description:     Pandoc is a Haskell library for converting from one markup                  format to another.  The formats it can handle include@@ -218,6 +219,7 @@                  test/command/9391.docx                  test/command/9358.docx                  test/command/9002.docx+                 test/command/9603.docx                  test/command/biblio.bib                  test/command/averroes.bib                  test/command/A.txt@@ -424,6 +426,7 @@                  test/odt/odt/*.odt                  test/odt/markdown/*.md                  test/odt/native/*.native+                 test/pod-reader.pod source-repository head   type:          git   location:      git://github.com/jgm/pandoc.git@@ -521,7 +524,7 @@                  pretty                >= 1.1      && < 1.2,                  pretty-show           >= 1.10     && < 1.11,                  process               >= 1.2.3    && < 1.7,-                 random                >= 1        && < 1.3,+                 random                >= 1        && < 1.4,                  safe                  >= 0.3.18   && < 0.4,                  scientific            >= 0.3      && < 0.4,                  skylighting           >= 0.14.5   && < 0.15,@@ -530,7 +533,7 @@                  syb                   >= 0.1      && < 0.8,                  tagsoup               >= 0.14.6   && < 0.15,                  temporary             >= 1.1      && < 1.4,-                 texmath               >= 0.12.8.12 && < 0.13,+                 texmath               >= 0.12.8.13 && < 0.13,                  text                  >= 1.1.1.0  && < 2.2,                  text-conversions      >= 0.3      && < 0.4,                  time                  >= 1.5      && < 1.15,@@ -604,6 +607,7 @@                    Text.Pandoc.Readers.RTF,                    Text.Pandoc.Readers.Typst,                    Text.Pandoc.Readers.Djot,+                   Text.Pandoc.Readers.Pod,                    Text.Pandoc.Writers,                    Text.Pandoc.Writers.Native,                    Text.Pandoc.Writers.DocBook,@@ -837,6 +841,7 @@                   Tests.Readers.Man                   Tests.Readers.Mdoc                   Tests.Readers.FB2+                  Tests.Readers.Pod                   Tests.Readers.DokuWiki                   Tests.Writers.Native                   Tests.Writers.ConTeXt
src/Text/Pandoc/Error.hs view
@@ -124,6 +124,7 @@                  "\nTry using Word to save your DOC file as DOCX," <>                  " and convert that with pandoc."         "pdf" -> "\nPandoc can convert to PDF, but not from PDF."+        "asciidoc" -> "\nPandoc can convert to asciidoc, but not from asciidoc."         _     -> ""     PandocUnknownWriterError w ->        "Unknown output format " <> w <>
src/Text/Pandoc/Format.hs view
@@ -208,6 +208,9 @@     ".opml"     -> defFlavor "opml"     ".org"      -> defFlavor "org"     ".pdf"      -> defFlavor "pdf"  -- so we get an "unknown reader" error+    ".pl"       -> defFlavor "pod"+    ".pm"       -> defFlavor "pod"+    ".pod"      -> defFlavor "pod"     ".pptx"     -> defFlavor "pptx"     ".ris"      -> defFlavor "ris"     ".roff"     -> defFlavor "ms"
src/Text/Pandoc/Readers.hs view
@@ -64,6 +64,7 @@   , readRTF   , readTypst   , readDjot+  , readPod   -- * Miscellaneous   , getReader   , getDefaultExtensions@@ -100,6 +101,7 @@ import Text.Pandoc.Readers.ODT import Text.Pandoc.Readers.OPML import Text.Pandoc.Readers.Org+import Text.Pandoc.Readers.Pod import Text.Pandoc.Readers.RST import Text.Pandoc.Readers.Textile import Text.Pandoc.Readers.TikiWiki@@ -171,6 +173,7 @@           ,("typst"        , TextReader readTypst)           ,("djot"         , TextReader readDjot)           ,("mdoc"         , TextReader readMdoc)+          ,("pod"          , TextReader readPod)           ]  -- | Retrieve reader, extensions based on format spec (format+extensions).
src/Text/Pandoc/Readers/Djot.hs view
@@ -189,7 +189,7 @@     D.Str bs -> pure $ str (UTF8.toText bs)     D.Emph ils -> emph <$> convertInlines ils     D.Strong ils -> strong <$> convertInlines ils-    D.Highlight ils -> spanWith ("",["highlighted"],[]) <$> convertInlines ils+    D.Highlight ils -> spanWith ("",["mark"],[]) <$> convertInlines ils     D.Insert ils -> spanWith ("",["inserted"],[]) <$> convertInlines ils     D.Delete ils -> spanWith ("",["deleted"],[]) <$> convertInlines ils     D.Subscript ils -> subscript <$> convertInlines ils
src/Text/Pandoc/Readers/Docx.hs view
@@ -807,14 +807,16 @@     [Para im@[Image{}]]       -> pure $ singleton $ Figure nullAttr capt [Plain im]     _ -> pure captContents-bodyPartToBlocks (Tbl _ _ _ []) =+bodyPartToBlocks (Tbl _ _ _ _ []) =   return mempty-bodyPartToBlocks (Tbl cap grid look parts) = do+bodyPartToBlocks (Tbl mbsty cap grid look parts) = do   let fullCaption = if T.null cap then mempty else plain (text cap)   let shortCaption = if T.null cap then Nothing else Just (toList (text cap))       cap' = caption shortCaption fullCaption       (hdr, rows) = splitHeaderRows (firstRowFormatting look) parts +  let rowHeadCols = if firstColumnFormatting look then 1 else 0+   let width = maybe 0 maximum $ nonEmpty $ map rowLength parts       rowLength :: Docx.Row -> Int       rowLength (Docx.Row _ c) = sum (fmap (\(Docx.Cell _ gridSpan _ _) -> fromIntegral gridSpan) c)@@ -831,10 +833,14 @@       totalWidth = sum grid       widths = (\w -> ColWidth (fromInteger w / fromInteger totalWidth)) <$> grid -  return $ table cap'+  extStylesEnabled <- asks (isEnabled Ext_styles . docxOptions)+  let attr = case mbsty of+                Just sty | extStylesEnabled -> ("", [], [("custom-style", sty)])+                _ -> nullAttr+  return $ tableWith attr cap'                  (zip alignments widths)                  (TableHead nullAttr headerCells)-                 [TableBody nullAttr 0 [] bodyCells]+                 [TableBody nullAttr (RowHeadColumns rowHeadCols) [] bodyCells]                  (TableFoot nullAttr []) bodyPartToBlocks HRule = pure Pandoc.horizontalRule 
src/Text/Pandoc/Readers/Docx/Parse.hs view
@@ -287,18 +287,22 @@               | Heading Int ParaStyleName ParagraphStyle T.Text T.Text (Maybe Level)                  [ParPart]               | ListItem ParagraphStyle T.Text T.Text (Maybe Level) [ParPart]-              | Tbl T.Text TblGrid TblLook [Row]+              | Tbl (Maybe T.Text) T.Text TblGrid TblLook [Row]               | Captioned ParagraphStyle [ParPart] BodyPart               | HRule               deriving Show  type TblGrid = [Integer] -newtype TblLook = TblLook {firstRowFormatting::Bool}+data TblLook = TblLook { firstRowFormatting ::Bool+                       , firstColumnFormatting :: Bool+                       }               deriving Show  defaultTblLook :: TblLook-defaultTblLook = TblLook{firstRowFormatting = False}+defaultTblLook = TblLook{ firstRowFormatting = False+                        , firstColumnFormatting = False+                        }  data Row = Row TblHeader [Cell] deriving Show @@ -691,17 +695,25 @@  elemToTblLook :: NameSpaces -> Element -> D TblLook elemToTblLook ns element | isElem ns "w" "tblLook" element =-  let firstRow = findAttrByName ns "w" "firstRow" element-      val = findAttrByName ns "w" "val" element+  let val = findAttrByName ns "w" "val" element       firstRowFmt =-        case firstRow of+        case findAttrByName ns "w" "firstRow" element of           Just "1" -> True           Just  _  -> False           Nothing -> case val of             Just bitMask -> testBitMask bitMask 0x020             Nothing      -> False+      firstColFmt =+        case findAttrByName ns "w" "firstColumn" element of+          Just "1" -> True+          Just  _  -> False+          Nothing -> case val of+            Just bitMask -> testBitMask bitMask 0x080+            Nothing      -> False   in-   return TblLook{firstRowFormatting = firstRowFmt}+   return TblLook{ firstRowFormatting = firstRowFmt+                 , firstColumnFormatting = firstColFmt+                 } elemToTblLook _ _ = throwError WrongElem  elemToRow :: NameSpaces -> Element -> D Row@@ -855,6 +867,9 @@         description = fromMaybe "" $ tblProperties                        >>= findChildByName ns "w" "tblDescription"                        >>= findAttrByName ns "w" "val"+        mbstyle = tblProperties+                       >>= findChildByName ns "w" "tblStyle"+                       >>= findAttrByName ns "w" "val"         grid' = case findChildByName ns "w" "tblGrid" element of           Just g  -> elemToTblGrid ns g           Nothing -> return []@@ -867,7 +882,7 @@     grid <- grid'     tblLook <- tblLook'     rows <- mapD (elemToRow ns) (elChildren element)-    return $ Tbl (caption <> description) grid tblLook rows+    return $ Tbl mbstyle (caption <> description) grid tblLook rows elemToBodyPart _ _ = throwError WrongElem  lookupRelationship :: DocumentLocation -> RelId -> [Relationship] -> Maybe Target
src/Text/Pandoc/Readers/HTML.hs view
@@ -837,7 +837,10 @@   let rawText = T.strip $ renderTags' (opent : contents ++ [closet])   let svgData = "data:image/svg+xml;base64," <>                    UTF8.toText (encode $ UTF8.fromText rawText)-  return $ B.imageWith (ident,cls,[]) svgData mempty mempty+  let kvs = [("width", "1em") | "fa-w-14" `elem` cls ||+                                "fa-w-16" `elem` cls ||+                                "fa-fw" `elem` cls] -- #10134+  return $ B.imageWith (ident,cls,kvs) svgData mempty mempty  pCodeWithClass :: PandocMonad m => Text -> Text -> TagParser m Inlines pCodeWithClass name class' = try $ do
src/Text/Pandoc/Readers/Mdoc/Standards.hs view
@@ -43,6 +43,7 @@   ("-isoC-tcor2",    "ISO/IEC 9899/TCOR2:1995 (“ISO C90, Technical Corrigendum 2”)"),   ("-isoC-99",       "ISO/IEC 9899:1999 (“ISO C99”)"),   ("-isoC-2011",     "ISO/IEC 9899:2011 (“ISO C11”)"),+  ("-isoC-2023",     "ISO/IEC 9899:2024 (“ISO C23”)"),   ("-iso9945-1-90",  "ISO/IEC 9945-1:1990 (“POSIX.1”)"),   ("-iso9945-1-96",  "ISO/IEC 9945-1:1996 (“POSIX.1”)"),   ("-iso9945-2-93",  "ISO/IEC 9945-2:1993 (“POSIX.2”)"),
+ src/Text/Pandoc/Readers/Pod.hs view
@@ -0,0 +1,441 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE TypeApplications #-}+{- |+   Module      : Text.Pandoc.Readers.Pod+   Copyright   : © 2024 Evan Silberman+   License     : GNU GPL, version 2 or above++   Maintainer  : Evan Silberman <evan@jklol.net>+   Stability   : WIP+   Portability : portable++Conversion of Pod to 'Pandoc' documents+-}+module Text.Pandoc.Readers.Pod (readPod) where++import Control.Monad (void)+import Control.Monad.Except (throwError)+import Data.Char (isAsciiUpper, digitToInt)+import Data.Default (Default)+import Text.Pandoc.Logging+import Text.Pandoc.Options+import Text.Pandoc.Parsing+import Text.Pandoc.Parsing.General (isSpaceChar)+import Text.Pandoc.XML (lookupEntity)+import Text.Pandoc.Class.PandocMonad (PandocMonad(..))+import Text.Pandoc.Definition (Pandoc)+import Text.Pandoc.Error+import Text.Pandoc.Builder (Blocks, Inlines)+import qualified Text.Pandoc.Builder as B+import qualified Data.Text as T+import qualified Data.Text.Read as TR+import Text.Pandoc.Shared (stringify, textToIdentifier, tshow)+import Data.Set (Set)+import Data.Functor (($>))+import Data.Maybe (listToMaybe, fromMaybe)+import Numeric (readOct)++data PodState = PodState+  { logMessages :: [LogMessage]+  , headerIds :: Set T.Text+  , options :: ReaderOptions+} deriving (Show)++instance HasLogMessages PodState where+  addLogMessage msg st = st{ logMessages = msg : logMessages st }+  getLogMessages st = reverse $ logMessages st++instance HasIdentifierList PodState where+  extractIdentifierList = headerIds+  updateIdentifierList f st = st{headerIds = f (headerIds st)}++instance HasReaderOptions PodState where+  extractReaderOptions = options++instance Default PodState where+  def = PodState+    { logMessages = []+    , headerIds = mempty+    , options = def+    }++data PodLinkDestination = LinkUrl Inlines T.Text+                        | LinkMan Inlines (Maybe Inlines)+                        | LinkInternal Inlines+                        deriving (Show)++defaultLinkName :: PodLinkDestination -> Inlines+defaultLinkName (LinkUrl inl _) = inl+defaultLinkName (LinkMan nm (Just sec)) = B.doubleQuoted sec <> " in " <> nm+defaultLinkName (LinkMan nm Nothing) = nm+defaultLinkName (LinkInternal sec) = B.doubleQuoted sec++type PodParser m = ParsecT Sources PodState m++readPod :: (PandocMonad m, ToSources a)+        => ReaderOptions+        -> a+        -> m Pandoc+readPod _ s = do+  let sources = toSources s+  p <- readWithM parsePod def sources+  case p of+    Right result -> return result+    Left e       -> throwError e++parsePod :: PandocMonad m => PodParser m Pandoc+parsePod = do+  -- We don't actually start processing Pod until we encounter a Pod command.+  -- If we never encounter a Pod command, the document is still valid Pod, it+  -- just contains no content.+  notPod+  bs <- manyTill block eof+  reportLogMessages+  return $ B.doc $ mconcat bs++block :: PandocMonad m => PodParser m Blocks+block = verbatim  <|> paragraph <|> command <?> "Pod paragraph"++command :: PandocMonad m => PodParser m Blocks+command = do+    try (char '=' >> notFollowedBy (string "item" <|> string "back" <|> string "end"))+    header <|> pod <|> cut <|> over <|> for <|> begin <|> encoding <?> "Pod command"++cmd :: PandocMonad m => T.Text -> PodParser m ()+cmd nm = do+  textStr nm+  notFollowedBy nonspaceChar+  void $ many spaceChar++encoding :: PandocMonad m => PodParser m Blocks+encoding = do+  cmd "encoding"+  anyLine+  logMessage $ IgnoredElement "=encoding; Pandoc requires UTF-8 input"+  return mempty++header :: PandocMonad m => PodParser m Blocks+header = do+  string "head"+  dig <- oneOf "123456"+  void blankline <|> skipMany1 spaceChar+  ins <- inlines+  attrs <- registerHeader B.nullAttr ins+  optional blanklines+  return $ B.headerWith attrs (digitToInt dig) ins++pod :: PandocMonad m => PodParser m Blocks+pod = do+  cmd "pod"+  optional (try inlines)+  optional blanklines+  return mempty++cut :: PandocMonad m => PodParser m Blocks+cut = cmd "cut" *> notPod++notPod :: PandocMonad m => PodParser m Blocks+notPod = do+  manyTill anyLine (eof <|> void (try (lookAhead (char '=' *> letter))))+  return mempty++over :: PandocMonad m => PodParser m Blocks+over = do+  cmd "over"+  anyLine+  blanklines+  optional $ try (char '=' *> cut)+  bs <- list <|> blockquote+  string "=back" <* blanklines+  return bs++list :: PandocMonad m => PodParser m Blocks+list = try bulletList <|> try orderedList <|> definitionList++bulletList :: PandocMonad m => PodParser m Blocks+bulletList = B.bulletList <$> many1 (item (many spaceChar *> optional (char '*')))++orderedList :: PandocMonad m => PodParser m Blocks+orderedList = do+  start <- item1+  more <- many orderedItem+  return $ B.orderedList (start : more)+  where+    item1 = item $ spaces *> char '1' *> optional (char '.')+    orderedItem = item $ spaces *> many digit *> optional (char '.')++item :: PandocMonad m => PodParser m () -> PodParser m Blocks+item p = do+  try (cmd "=item")+  p+  blanklines+  mconcat <$> many block <?> "runaway item"++definitionList :: PandocMonad m => PodParser m Blocks+definitionList = B.definitionList <$> many1 dlItem+  where+    dlItem = do+      try (cmd "=item")+      spaces+      term <- inlines+      blanklines+      -- perlpodspec sez the /section part of a link can refer to either+      -- a header or a dl item, hence treating it as a "header" here+      attrs <- registerHeader B.nullAttr term+      defn <- mconcat <$> many block <?> "runaway dlitem"+      return (B.spanWith attrs term, [defn])++blockquote :: PandocMonad m => PodParser m Blocks+blockquote = B.blockQuote . mconcat <$> many block <?> "runaway blockquote"++paragraph :: PandocMonad m => PodParser m Blocks+paragraph = do+  try (notFollowedBy (char '=' *> letter))+  inl <- inlines+  optional blanklines+  return $ B.para $ B.trimInlines inl++inlines :: PandocMonad m => PodParser m Inlines+inlines = mconcat <$> many1 (format <|> whitespace <|> str)++-- perlpodspec sez:+--   If a Pod processor sees any formatting code other than the ones listed,+--   that processor must by default treat this as an error.+format :: PandocMonad m => PodParser m Inlines+format = try $ do+  ctrl <- satisfy isAsciiUpper+  p <- getPosition+  lookAhead (char '<')+  case ctrl of+    'B' -> B.strong <$> argument+    'C' -> B.code . stringify <$> argument+    'F' -> B.spanWith (mempty, ["filename"], mempty) <$> argument+    'I' -> B.emph <$> argument+    'S' -> argument  -- TODO map nbsps+    'X' -> argument $> mempty+    'Z' -> argument $> mempty++    'E' -> do+      a <- stringify <$> argument+      case entity a of+             -- per spec:+             --   Pod parsers, when faced with some unknown "E<identifier>" code,+             --   shouldn't simply replace it with nullstring (by default, at+             --   least), but may pass it through as a string consisting of the+             --   literal characters E, less-than, identifier, greater-than.+             Nothing -> do+               logMessage $ SkippedContent ("unknown entity " <> a) p+               return $ B.str $ "E<" <> a <> ">"+             Just e -> return $ B.str e++    'L' -> link++    x -> throwError $ PandocParseError $ T.snoc "unknown Pod formatting code " x+  where+    argument = try expandedArg <|> compactArg <?> "argument"+    innerStr =  B.str <$> many1Char (podCharLess ">")+    compactArg = do+      char '<'+      mconcat <$> manyTill (format <|> whitespace <|> innerStr) (char '>')+    expandedArg = do+      openLen <- length <$> many1 (char '<')+      let close = T.pack $ replicate openLen '>'+      skipMany1 spaceChar <|> void blankline+      arg <- mconcat <$> many (format <|> try (whitespace <* notFollowedBy (textStr close)) <|> str)+      many1 spaceChar+      textStr close+      return arg+    -- Some legacy entity names are required to be parsed by Pod formatters+    oct = listToMaybe . readOct @Integer+    entity "apos" = Just "'"+    entity "sol" = Just "/"+    entity "verbar" = Just "|"+    entity "lchevron" = Just "«"+    entity "rchevron" = Just "»"+    entity (T.stripPrefix "0x" -> Just suf) = lookupEntity $ "#x" <> suf+    entity (T.stripPrefix "0" -> Just suf)+        | Just (n, "") <- oct (T.unpack suf) = lookupEntity $ "#" <> tshow n+    entity (TR.decimal @Integer -> Right (x, "")) = lookupEntity $ "#" <> tshow x+    entity x = lookupEntity x++-- god knows there must be a higher order way of writing this thing, where we+-- have multiple different possible parser states within the link argument+-- varying depending on whether the link is expanded or not, but at least I+-- understand what I've done. This would be less wacky with a lexing step.+link :: PandocMonad m => PodParser m Inlines+link = do+  identifier <- textToIdentifier <$> getOption readerExtensions+  (name, dest) <- try expandedLinkArg <|> compactLinkArg+  return $ mkLink identifier name dest+  where+    compactLinkArg = do+      char '<'+      name <- linkName whitespace ">"+      dest <- linkDest whitespace (char '>') ">"+      char '>'+      return (mconcat <$> name, dest)+    expandedLinkArg = do+      openLen <- length <$> many1 (char '<')+      let closeStr = textStr (T.pack $ replicate openLen '>')+      let close = skipMany1 spaceChar *> closeStr+      let sp = try $ many1 spaceChar *> notFollowedBy closeStr $> B.space+      many1 spaceChar+      name <- linkName sp ""+      dest <- linkDest sp close ""+      close+      return (mconcat <$> name, dest)+    mkLink identifier name dest =+      let name' = fromMaybe (defaultLinkName dest) name in+          case dest of+            LinkUrl _ href -> B.link href "" name'+            LinkMan nm Nothing ->  B.linkWith (mempty, mempty, [("manual", stringify nm)]) "" "" name'+            LinkMan nm (Just sc) -> B.linkWith (mempty, mempty, [("manual", stringify nm), ("section", stringify sc)]) "" "" name'+            LinkInternal sc -> B.link ("#" <> identifier (stringify sc)) "" name'++    linkName sp ex = optionMaybe $ try $ many+        (try format+         <|> sp+         <|> B.str <$> many1Char (podCharLess ('|':ex))) <* char '|'+    linkDest sp close ex = try (url ex) <|> internal sp close ex <|> man sp close ex+    -- perlpodspec sez:+    --    Note that you can distinguish URL-links from anything else by the+    --    fact that they match m/\A\w+:[^:\s]\S*\z/.+    -- This is obviously not an RFC-compliant matcher for a URI scheme, but+    -- this is what the specification and the canonical implementation (Pod::Simple)+    -- do for deciding that a link target "looks like" a URL, as opposed to a+    -- manual page reference, so what we are doing here is roughly equivalent+    -- even though it is nonsense+    url ex = do+      scheme <- many1Char (letter <|> digit <|> char '_')+      colon <- T.singleton <$> char ':' <* notFollowedBy (char ':')+      rst <- many (format <|> B.str <$> many1Char (podCharLess ex))+      return $ LinkUrl+                 (B.str scheme <> B.str colon <> mconcat rst)+                 (scheme <> colon <> stringify rst)+    quotedSection sp close ex = do+      let mystr = B.str <$> many1Char (podCharLess ('\"':ex) <|> try (char '"' <* notFollowedBy close))+      char '"'+      ins <- mconcat <$> many1 (format <|> sp <|> mystr)+      char '"'+      return ins+    section sp close ex = try (quotedSection sp close ex) <|> mconcat <$> many1 (format <|> sp <|> B.str <$> many1Char (podCharLess ex))+    internal sp close ex = do+      char '/'+      LinkInternal <$> section sp close ex+    notSlash sp ex = format <|> sp <|> B.str <$> many1Char (podCharLess ('/':ex))+    man sp close ex = do+      page <- mconcat <$> many (notSlash sp ex)+      sec <- optionMaybe $ char '/' *> section sp close ex+      return $ LinkMan page sec++whitespace :: PandocMonad m => PodParser m Inlines+whitespace = try $ do+  many1 spaceChar *> optional newline <|> many spaceChar *> void newline+  notFollowedBy blankline+  return B.space++podCharLess :: PandocMonad m => String -> PodParser m Char+podCharLess exclude = try (satisfy isAsciiUpper <* notFollowedBy (char '<'))+                <|> satisfy (\c -> not (isSpaceChar c || isAsciiUpper c || elem c exclude))++podChar :: PandocMonad m => PodParser m Char+podChar = try (satisfy isAsciiUpper <* notFollowedBy (char '<'))+                <|> satisfy (\c -> not (isSpaceChar c || isAsciiUpper c))++str :: PandocMonad m => PodParser m Inlines+str = B.str <$> many1Char podChar++nonEmptyLine :: PandocMonad m => PodParser m T.Text+nonEmptyLine = try $ do+  pre <- manyChar spaceChar+  something <- T.singleton <$> nonspaceChar+  post <- anyLineNewline+  return $ pre <> something <> post++verbatim :: PandocMonad m => PodParser m Blocks+verbatim = do+  start <- startVerbatimLine+  lns <- many (nonEmptyLine <|>+                     try (do b <- blanklines+                             l <- startVerbatimLine+                             return $ b <> l))+  optional blanklines+  return $ B.codeBlock $ mconcat $ start:lns+  where+    startVerbatimLine = many1Char spaceChar <> nonEmptyLine++-- =begin/=end/=for and data paragraphs+-- The =begin/=end (and single-paragraph =for variant) markers in Pod are+-- designed as an extension point for specific formatters+--+-- this doesn't strictly match the intent of "=begin :ident" pod blocks, which+-- are still meant to be processed specially by the formatter, and only land in+-- the output upon request, i.e. pod2html will process "=begin :html" blocks as+-- Pod and include them in the regular output. Since the regions contain Pod+-- markup it seems to me that the best thing to do is parse the markup and put+-- a classname on it, allowing users to respond as desired with filters.+-- Pandoc doesn't have a built-in concept of parsed Divs that are only rendered+-- to certain formats, just raw blocks.+--+-- perlpodspec allows nesting of =begin/=end regions but we currently don't+-- because it would be annoying and we have something somewhat useful we+-- can do with these blocks which is treat them as RawBlocks, which matches+-- the intent reasonably well, and that gets weirder if we parse a nested+-- structure. It seems unlikely this would be encountered in the wild.++regionIdentifier :: PandocMonad m => PodParser m T.Text+regionIdentifier = many1Char (alphaNum <|> oneOf "-_")++for :: PandocMonad m => PodParser m Blocks+for = do+  string "for"+  many1 spaceChar+  forDiv <|> forData++forDiv :: PandocMonad m => PodParser m Blocks+forDiv = do+  char ':'+  cls <- regionIdentifier+  many1 spaceChar+  B.divWith (mempty, [cls], mempty) <$> paragraph++forData :: PandocMonad m => PodParser m Blocks+forData = do+  fmt <- regionIdentifier+  ln1 <- anyLineNewline+  lns <- many nonEmptyLine+  optional blanklines+  return $ B.rawBlock fmt (T.concat (ln1 : lns))++begin :: PandocMonad m => PodParser m Blocks+begin = do+  cmd "begin"+  beginDiv <|> beginData++beginDiv :: PandocMonad m => PodParser m Blocks+beginDiv = do+  char ':'+  cls <- regionIdentifier+  anyLine  -- "parameters" may appear in this position+  blanklines+  bs <- mconcat <$> many block+  textStr ("=end :" <> cls) <* blanklines+  return $ B.divWith (mempty, [cls], mempty) bs++beginData :: PandocMonad m => PodParser m Blocks+beginData = do+  fmt <- regionIdentifier+  anyLine+  blanklines+  lns <- mconcat <$> many (try rawCut <|> rawLine)+  textStr ("=end " <> fmt) <* blanklines+  return $ B.rawBlock fmt lns+  where+    rawCut = do+      char '=' *> cut+      pod <?> "=pod to close =cut within =begin/=end"+      return mempty+    rawLine = do+      try (notFollowedBy (char '=' *> letter))+      anyLineNewline
src/Text/Pandoc/Readers/RST.hs view
@@ -1286,6 +1286,7 @@ anonymousKey :: PandocMonad m => RSTParser m () anonymousKey = try $ do   oneOfStrings [".. __:", "__"]+  skipMany1 spaceChar   src <- targetURI   -- we need to ensure that the keys are ordered by occurrence in   -- the document.@@ -1462,15 +1463,14 @@ --  inline :: PandocMonad m => RSTParser m Inlines-inline = choice [ note          -- can start with whitespace, so try before ws-                , link-                , inlineAnchor-                , strong-                , emph-                , code-                , subst-                , interpretedRole-                , inlineContent ] <?> "inline"+inline =+  (note          -- can start with whitespace, so try before ws+    <|> do notAfterString >>= guard+           (link <|> inlineAnchor <|> strong <|> emph)+    <|> code+    <|> subst+    <|> interpretedRole+    <|> inlineContent) <?> "inline"  -- strings, spaces and other characters that can appear either by -- themselves or within inline markup@@ -1730,6 +1730,7 @@ referenceLink = try $ do   ref <- (referenceName <|> citationName) <* char '_'   isAnonymous <- (True <$ char '_') <|> pure False+  eof <|> notFollowedBy alphaNum   let ref' = if isAnonymous                 then "_"                 else ref@@ -1797,7 +1798,7 @@ smart = smartPunctuation inline  inlineAnchor :: PandocMonad m => RSTParser m Inlines-inlineAnchor = do+inlineAnchor = try $ do   char '_'   name <- quotedReferenceName <|> simpleReferenceName   let ident = textToIdentifier mempty name
src/Text/Pandoc/Writers/AsciiDoc.hs view
@@ -118,19 +118,46 @@        Nothing  -> main        Just tpl -> renderTemplate tpl context +data EscContext = Normal | InTable+  deriving (Show, Eq)+ -- | Escape special characters for AsciiDoc.-escapeString :: PandocMonad m => Text -> ADW m (Doc Text)-escapeString t = do-  parentTableLevel <- gets tableNestingLevel-  let needsEscape '{' = True-      needsEscape '|' = parentTableLevel > 0-      needsEscape _   = False-  let escChar c | needsEscape c = "\\" <> T.singleton c-                | otherwise     = T.singleton c-  if T.any needsEscape t-     then return $ literal $ T.concatMap escChar t-     else return $ literal t+escapeString :: EscContext -> Text -> Doc Text+escapeString context t+  | T.any needsEscape t+  = literal $+      case T.foldl' go (False, mempty) t of+        (True, x) -> x <> "++" -- close passthrough context+        (False, x) -> x+  | otherwise = literal t+ where+  -- Bool is True when we are in a ++ passthrough context+  go :: (Bool, Text) -> Char -> (Bool, Text)+  go (True, x) '+' = (False, x <> "++" <> "{plus}") -- close context+  go (False, x) '+' = (False, x <> "{plus}")+  go (True, x) '|'+    | context == InTable = (False, x <> "++" <> "{vbar}") -- close context+  go (False, x) '|'+    | context == InTable = (False, x <> "{vbar}")+  go (True, x) c+    | needsEscape c = (True, T.snoc x c)+    | otherwise = (False, T.snoc (x <> "++") c)+  go (False, x) c+    | needsEscape c = (True, x <> "++" <> T.singleton c)+    | otherwise = (False, T.snoc x c) +  needsEscape '{' = True+  needsEscape '+' = True+  needsEscape '`' = True+  needsEscape '*' = True+  needsEscape '_' = True+  needsEscape '<' = True+  needsEscape '>' = True+  needsEscape '[' = True+  needsEscape ']' = True+  needsEscape '\\' = True+  needsEscape '|' = True+  needsEscape _ = False  -- | Ordered list start parser for use in Para below. olMarker :: Parsec Text ParserState Char@@ -393,11 +420,11 @@ -- | Convert a list item containing text starting with @U+2610 BALLOT BOX@ -- or @U+2612 BALLOT BOX WITH X@ to asciidoctor checkbox syntax (e.g. @[x]@). taskListItemToAsciiDoc :: [Block] -> [Block]-taskListItemToAsciiDoc = handleTaskListItem toOrg listExt+taskListItemToAsciiDoc = handleTaskListItem toAd listExt   where-    toOrg (Str "☐" : Space : is) = Str "[ ]" : Space : is-    toOrg (Str "☒" : Space : is) = Str "[x]" : Space : is-    toOrg is = is+    toAd (Str "☐" : Space : is) = RawInline (Format "asciidoc") "[ ]" : Space : is+    toAd (Str "☒" : Space : is) = RawInline (Format "asciidoc") "[x]" : Space : is+    toAd is = is     listExt = extensionsFromList [Ext_task_lists]  addBlock :: PandocMonad m@@ -543,24 +570,27 @@ inlineToAsciiDoc opts (SmallCaps lst) = inlineListToAsciiDoc opts lst inlineToAsciiDoc opts (Quoted qt lst) = do   isLegacy <- gets legacy-  inlineListToAsciiDoc opts $-    case qt of-      SingleQuote-        | isLegacy     -> [Str "`"] ++ lst ++ [Str "'"]-        | otherwise    -> [Str "'`"] ++ lst ++ [Str "`'"]-      DoubleQuote-        | isLegacy     -> [Str "``"] ++ lst ++ [Str "''"]-        | otherwise    -> [Str "\"`"] ++ lst ++ [Str "`\""]+  contents <- inlineListToAsciiDoc opts lst+  pure $ case qt of+    SingleQuote+      | isLegacy     -> "`" <> contents <> "'"+      | otherwise    -> "'`" <> contents <> "`'"+    DoubleQuote+      | isLegacy     -> "``" <> contents <> "''"+      | otherwise    -> "\"`" <> contents <> "`\"" inlineToAsciiDoc _ (Code _ str) = do   isLegacy <- gets legacy   let escChar '`' = "\\'"       escChar c   = T.singleton c-  let contents = literal (T.concatMap escChar str)-  return $-    if isLegacy-       then text "`"  <> contents <> "`"-       else text "`+" <> contents <> "+`"-inlineToAsciiDoc _ (Str str) = escapeString str+  parentTableLevel <- gets tableNestingLevel+  let content+       | isLegacy = literal (T.concatMap escChar str)+       | otherwise = escapeString+                       (if parentTableLevel > 0 then InTable else Normal) str+  return $ text "`" <> content <> "`"+inlineToAsciiDoc _ (Str str) = do+  parentTableLevel <- gets tableNestingLevel+  pure $ escapeString (if parentTableLevel > 0 then InTable else Normal) str inlineToAsciiDoc _ (Math InlineMath str) = do   isLegacy <- gets legacy   modify $ \st -> st{ hasMath = True }@@ -640,9 +670,10 @@   contents <- inlineListToAsciiDoc opts ils   isIntraword <- gets intraword   let marker = if isIntraword then "##" else "#"-  if T.null ident && null classes-     then return contents-     else do+  case classes of+    [] | T.null ident -> return contents+    ["mark"] | T.null ident -> return $ marker <> contents <> marker+    _ -> do        let modifier = brackets $ literal $ T.unwords $             [ "#" <> ident | not (T.null ident)] ++ map ("." <>) classes        return $ modifier <> marker <> contents <> marker
src/Text/Pandoc/Writers/Djot.hs view
@@ -212,6 +212,7 @@ inlineToDjot (Strikeout ils) = D.delete <$> inlinesToDjot ils inlineToDjot (Subscript ils) = D.subscript <$> inlinesToDjot ils inlineToDjot (Superscript ils) = D.superscript <$> inlinesToDjot ils+inlineToDjot (Span ("",["mark"],[]) ils) = D.highlight <$> inlinesToDjot ils inlineToDjot (Span attr@(ident,cls,kvs) ils)   | Just "1" <- lookup "wrapper" kvs     = fmap (D.addAttr
src/Text/Pandoc/Writers/Docx/Table.hs view
@@ -63,6 +63,7 @@ import qualified Data.Text as T import qualified Text.Pandoc.Translations as Term import qualified Text.Pandoc.Writers.GridTable as Grid+import Data.Bits ((.|.))  tableToOpenXML :: PandocMonad m                => WriterOptions@@ -71,7 +72,7 @@                -> WS m [Content] tableToOpenXML opts blocksToOpenXML gridTable = do   setFirstPara-  let (Grid.Table (ident,_,tableAttr) caption colspecs _rowheads thead tbodies tfoot) =+  let (Grid.Table (ident,_,tableAttr) caption colspecs rowheads thead tbodies tfoot) =         gridTable   let (Caption _maybeShortCaption captionBlocks) = caption   tablenum <- gets stNextTableNum@@ -106,7 +107,8 @@   -- 0×0100  Apply last column conditional formatting   -- 0×0200  Do not apply row banding conditional formatting   -- 0×0400  Do not apply column banding conditional formattin-  let tblLookVal = if hasHeader then (0x20 :: Int) else 0+  let tblLookVal = (if hasHeader then (0x20 :: Int) else 0) .|.+                   (if rowheads > 0 then (0x80 :: Int) else 0)   let (gridCols, tblWattr) = tableLayout (elems colspecs)   listLevel <- asks envListLevel   let tblStyle =  fromMaybe "Table" (lookup "custom-style" tableAttr)@@ -122,7 +124,7 @@             [ mknode "w:tblLayout" [("w:type", "fixed")] () | hasWidths ] ++             [ mknode "w:tblLook" [("w:firstRow",if hasHeader then "1" else "0")                                  ,("w:lastRow",if hasFooter then "1" else "0")-                                 ,("w:firstColumn","0")+                                 ,("w:firstColumn",if rowheads > 0 then "1" else "0")                                  ,("w:lastColumn","0")                                  ,("w:noHBand","0")                                  ,("w:noVBand","0")
src/Text/Pandoc/Writers/EPUB.hs view
@@ -522,7 +522,8 @@                   , writerWrapText = WrapAuto }    -- cover page-  (cpgEntry, cpicEntry) <- createCoverPage meta metadata opts' vars cssvars writeHtml plainTitle+  (cpgEntry, cpicEntry, mbCoverImageName) <-+    createCoverPage meta metadata opts' vars cssvars writeHtml plainTitle    -- title page   tpContent <- lift $ writeHtml opts'{@@ -642,7 +643,7 @@            [("xml:lang", epubLanguage metadata) | version == EPUB3] ++            [("unique-identifier","epub-id-1")] ++            [("prefix","ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/") | version == EPUB3]) $-          [ metadataElement version metadata currentTime+          [ metadataElement version metadata mbCoverImageName currentTime           , unode "manifest" $              [ unode "item" ! [("id","ncx"), ("href","toc.ncx")                               ,("media-type","application/x-dtbncx+xml")] $ ()@@ -742,6 +743,7 @@ -- | Function used during conversion from pandoc to EPUB to create the cover page. -- The first Entry list is for the cover while the second one is for the cover image. -- If no cover images are specified, empty lists will be returned.+-- The third value of the returned tuple is the cover image name. createCoverPage :: PandocMonad m =>                    Meta                    -> EPUBMetadata@@ -750,10 +752,10 @@                    -> (Bool -> Context Text)                    -> (WriterOptions -> Pandoc -> m B8.ByteString)                    -> Text-                   -> StateT EPUBState m ([Entry], [Entry])+                   -> StateT EPUBState m ([Entry], [Entry], Maybe FilePath) createCoverPage meta metadata opts' vars cssvars writeHtml plainTitle =     case epubCoverImage metadata of-        Nothing   -> return ([],[])+        Nothing   -> return ([],[], Nothing)         Just img  -> do           let fp = takeFileName img           -- retrieve cover image file@@ -785,7 +787,7 @@           coverImageEntry <- mkEntry ("media/" ++ coverImageName)                                 imgContent -          return ( [ coverEntry ], [ coverImageEntry ] )+          return ( [ coverEntry ], [ coverImageEntry ], Just coverImageName )  -- | Converts the given chapters to entries using the writeHtml function -- and the various provided options@@ -992,8 +994,9 @@   -- Return   mkEntry "nav.xhtml" navData -metadataElement :: EPUBVersion -> EPUBMetadata -> UTCTime -> Element-metadataElement version md currentTime =+metadataElement :: EPUBVersion -> EPUBMetadata -> Maybe FilePath -> UTCTime+                -> Element+metadataElement version md mbCoverImage currentTime =   unode "metadata" ! [("xmlns:dc","http://purl.org/dc/elements/1.1/")                      ,("xmlns:opf","http://www.idpf.org/2007/opf")] $ mdNodes   where mdNodes = identifierNodes ++ titleNodes ++ dateNodes@@ -1048,7 +1051,7 @@             (\img -> [unode "meta" !  [(metaprop,"cover"),                                        ("content",toId img)] $ ()                         | version == EPUB2])-            $ epubCoverImage md+            $ mbCoverImage         modifiedNodes = [ unode "meta" ! [(metaprop, "dcterms:modified")] $                showDateTimeISO8601 currentTime | version == EPUB3 ]         belongsToCollectionNodes =
src/Text/Pandoc/Writers/Typst.hs view
@@ -18,6 +18,8 @@   ) where import Text.Pandoc.Definition import Text.Pandoc.Class ( PandocMonad)+import Text.Pandoc.ImageSize ( dimension, Dimension(Pixel), Direction(..),+                               showInInch ) import Text.Pandoc.Options ( WriterOptions(..), WrapOption(..), isEnabled,                              CaptionPosition(..) ) import Data.Text (Text)@@ -309,12 +311,13 @@           $$ blankline     Figure (ident,_,_) (Caption _mbshort capt) blocks -> do       caption <- blocksToTypst capt+      opts <-  gets stOptions       contents <- case blocks of                      -- don't need #box around block-level image-                     [Para [Image (_,_,kvs) _ (src, _)]]-                       -> pure $ mkImage False src kvs-                     [Plain [Image (_,_,kvs) _ (src, _)]]-                       -> pure $ mkImage False src kvs+                     [Para [Image attr _ (src, _)]]+                       -> pure $ mkImage opts False src attr+                     [Plain [Image attr _ (src, _)]]+                       -> pure $ mkImage opts False src attr                      _ -> brackets <$> blocksToTypst blocks       let lab = toLabel FreestandingLabel ident       return $ "#figure(" <> nest 2 ((contents <> ",")@@ -433,23 +436,29 @@                     (if inlines == [Str src]                           then mempty                           else nowrap $ brackets contents) <> endCode-    Image (_,_,kvs) _inlines (src,_tit) -> pure $ mkImage True src kvs+    Image attr _inlines (src,_tit) -> do+      opts <-  gets stOptions+      pure $ mkImage opts True src attr     Note blocks -> do       contents <- blocksToTypst blocks       return $ "#footnote" <> brackets (chomp contents) <> endCode  -- see #9104; need box or image is treated as block-level-mkImage :: Bool -> Text -> [(Text, Text)] -> Doc Text-mkImage useBox src kvs+mkImage :: WriterOptions -> Bool -> Text -> Attr -> Doc Text+mkImage opts useBox src attr   | useBox = "#box" <> parens coreImage   | otherwise = coreImage  where   src' = T.pack $ unEscapeString $ T.unpack src -- #9389-  toDimAttr k =-     case lookup k kvs of-       Just v -> ", " <> literal k <> ": " <> literal v-       Nothing -> mempty-  dimAttrs = mconcat $ map toDimAttr ["height", "width"]+  showDim (Pixel a) = literal (showInInch opts (Pixel a) <> "in")+  showDim dim = text (show dim)+  dimAttrs =+     (case dimension Height attr of+        Nothing -> mempty+        Just dim -> ", height: " <> showDim dim) <>+     (case dimension Width attr of+        Nothing -> mempty+        Just dim -> ", width: " <> showDim dim)   isData = "data:" `T.isPrefixOf` src'   dataSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><image xlink:href=\"" <> src' <> "\" /></svg>"   coreImage
test/Tests/Old.hs view
@@ -246,6 +246,10 @@       [ test' "ansi" ["-f", "markdown", "-t", "ansi"]         "ansi-test.txt" "ansi-test.ansi"       ]+  , testGroup "pod"+      [ test' "pod" ["-f", "pod", "-t", "native"]+        "pod-reader.pod" "pod-reader.native"+      ]   ]  where     test'           = test pandocPath
+ test/Tests/Readers/Pod.hs view
@@ -0,0 +1,175 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Tests.Readers.Pod+   Copyright   : © 2024 Evan Silberman+   License     : GNU GPL, version 2 or above++   Maintainer  : +   Stability   : alpha+   Portability : portable++Tests for the Pod reader.+-}++module Tests.Readers.Pod (tests) where++import Data.Text (Text, pack)+import Test.Tasty+import Test.Tasty.HUnit (HasCallStack)+import Tests.Helpers+import Text.Pandoc+import Text.Pandoc.Arbitrary ()+import Text.Pandoc.Builder++pod :: Text -> Pandoc+pod t = (purely $ readPod def) ("=pod\n\n" <> t <> "\n\n=cut\n")++manLink :: Text -> Maybe Text -> Inlines -> Inlines+manLink nm Nothing = linkWith (mempty, mempty, [("manual", nm)]) "" ""+manLink nm (Just sc) = linkWith (mempty, mempty, [("manual", nm), ("section", sc)]) "" ""++bogusEntity :: String -> TestTree+bogusEntity t = t =: "E<" <> pack t <> ">" =?> para ("E<" <> str (pack t) <> ">")++infix 4 =:+(=:) :: (ToString c, HasCallStack)+     => String -> (Text, c) -> TestTree+(=:) = test pod++tests :: [TestTree]+tests = [+  testGroup "inlines"+    [ "code with nested inlines" =:+        "C</I<A> (*PRUNE) I<B>/>" =?>+        para (code "/A (*PRUNE) B/")+    , "compact in compact" =:+        "I<B<strong> emphasis>" =?>+        para (emph $ (strong "strong") <> " emphasis")+    , "expanded in compact" =:+        "I<B<< strong >> emphasis>" =?>+        para (emph $ (strong "strong") <> " emphasis")+    , "compact in expanded" =:+        "I<<< B<strong> emphasis >>>" =?>+        para (emph $ (strong "strong") <> " emphasis")+    , "expanded in expanded" =:+        "I<<< B<<< strong >>> emphasis >>>" =?>+        para (emph $ (strong "strong") <> " emphasis")+    ]+  , testGroup "links"+    [ testGroup "compact"+      [ "URL" =:+          "L<https://example.org>" =?>+          para (link "https://example.org" "" "https://example.org")+      , "URL with link text" =:+          "L<link|https://example.org/index.html>" =?>+          para (link "https://example.org/index.html" "" "link")+      , "perl manual" =:+          "L<Foo::Bar>" =?>+          para (manLink "Foo::Bar" Nothing "Foo::Bar")+      , "manual with quoted section" =:+          "L<crontab(5)/\"DESCRIPTION\">" =?>+          para (manLink "crontab(5)" (Just "DESCRIPTION") (doubleQuoted "DESCRIPTION" <> " in crontab(5)"))+      , "manual with section and formatted link text" =:+          "L<B<< extravagant >> link|HTTP::Simple/is_info>" =?>+          para (manLink "HTTP::Simple" (Just "is_info") (strong "extravagant" <> " link"))+      , "internal link" =:+          "L</section name>" =?>+          para (link "#section-name" "" (doubleQuoted "section name"))+      , "internal link with formatting" =:+          "L</The C<pod2html> command>" =?>+          para (link "#the-pod2html-command" "" (doubleQuoted ("The " <> code "pod2html" <> " command")))+      , "link with angle bracket" =:+          "L<m<>" =?>+          para (manLink "m<" Nothing "m<")+      , "empty name" =:+          "L<|https://example.org>" =?>+          para (link "https://example.org" "" mempty)+      ]+    , testGroup "expanded"+      [ "URL" =:+          "L<< https://example.org >>" =?>+          para (link "https://example.org" "" "https://example.org")+      , "URL with link text" =:+          "L<< link|https://example.org/index.html >>" =?>+          para (link "https://example.org/index.html" "" "link")+      , "perl manual" =:+          "L<<< Foo::Bar >>>" =?>+          para (manLink "Foo::Bar" Nothing "Foo::Bar")+      , "manual with quoted section" =:+          "L<< crontab(5)/\"DESCRIPTION\"     >>" =?>+          para (manLink "crontab(5)" (Just "DESCRIPTION") (doubleQuoted "DESCRIPTION" <> " in crontab(5)"))+      , "manual with section and formatted link text" =:+          "L<< B<< extravagant >> link|HTTP::Simple/is_info >>" =?>+          para (manLink "HTTP::Simple" (Just "is_info") (strong "extravagant" <> " link"))+      , "internal link" =:+          "L<<   /section name  >>" =?>+          para (link "#section-name" "" (doubleQuoted "section name"))+      , "internal link with formatting" =:+          "L<<<<<          /The C<pod2html> command    >>>>>" =?>+          para (link "#the-pod2html-command" "" (doubleQuoted ("The " <> code "pod2html" <> " command")))+      , "link with angle bracket" =:+          "L<< m< >>" =?>+          para (manLink "m<" Nothing "m<")+      , "empty name" =:+          "L<< |https://example.org >>" =?>+          para (link "https://example.org" "" mempty)+      ]+    ]+  , testGroup "entities"+      [ testGroup "required"+        [ "quot" =:+            "E<quot>" =?>+          para "\""+        , "amp" =:+            "E<amp>" =?>+            para "&"+        , "apos" =:+            "E<apos>" =?>+            para "'"+        , "lt" =:+            "E<lt>" =?>+            para "<"+        , "gt" =:+            "E<gt>" =?>+            para ">"+        , "sol" =:+            "E<sol>" =?>+            para "/"+        , "verbar" =:+            "E<verbar>" =?>+            para "|"+        , "lchevron" =:+            "E<lchevron>" =?>+            para "«"+        , "rchevron" =:+            "E<rchevron>" =?>+            para "»"+        ]+      , testGroup "numeric"+        [ "decimal" =:+            "E<162>" =?>+            para "¢"+        , "octal" =:+            "E<0242>" =?>+            para "¢"+        , "hexadecimal" =:+            "E<0xA2>" =?>+            para "¢"+        , "hexadecimal variant" =:+            "E<0x00A2>" =?>+            para "¢"+        , "actually decimal" =:+            "E<099>" =?>+            para "c"+        ]+      , testGroup "bogus"+        [ bogusEntity "0XA2"+        , bogusEntity "not a real entity"+        , bogusEntity "162 1"+        , bogusEntity "99 bottles of beer"+        , bogusEntity "0xhh"+        , bogusEntity "077x"+        , bogusEntity "0x63 skidoo"+        ]+      ]+    ]
test/Tests/Writers/AsciiDoc.hs view
@@ -36,7 +36,7 @@                  "__foo__bar"           , testAsciidoc "emph quoted" $                para (doubleQuoted (emph (text "foo"))) =?>-                 "``__foo__''"+                 "``_foo_''"           , testAsciidoc "strong word before" $                para (text "foo" <> strong (text "bar")) =?>                  "foo**bar**"@@ -45,7 +45,7 @@                  "**foo**bar"           , testAsciidoc "strong quoted" $                para (singleQuoted (strong (text "foo"))) =?>-                 "`**foo**'"+                 "`*foo*'"           ]         , testGroup "blocks"           [ testAsciidoc "code block without line numbers" $
+ test/command/10385.md view
@@ -0,0 +1,22 @@+````+% pandoc -t asciidoc+C+ C++ C+++ `++`++`` ` `` \`hi\`++`hi\there`` ok`++```+++`+```+^D+C{plus} C{plus}{plus} C{plus}{plus}{plus} `{plus}{plus}`++`++`++` ++`++hi++`++++`hi++\++there++``++ ok`++....+++`+....+````
+ test/command/10497.md view
@@ -0,0 +1,13 @@+```+% pandoc -f rst+a.__b__++a__b__++__foo__+^D+<p>a.__b__</p>+<p>a__b__</p>+<p>__foo__</p>+```+
+ test/command/2337.md view
@@ -0,0 +1,6 @@+```+% pandoc -t asciidoc -f html+<a href="http://example.com">][</a>+^D+http://example.com[++][++]+```
test/command/4545.md view
@@ -8,7 +8,7 @@ ^D Test 1 -{empty}[my text]+++[++my text++]++  Test 2 ```
+ test/command/6424.md view
@@ -0,0 +1,6 @@+```+% pandoc -t asciidoc+test^[this is a note\]. and more]+^D+testfootnote:[this is a note++]++. and more]+```
test/command/8665.md view
@@ -24,6 +24,6 @@ [cols=",",options="header",] |=== |h1 |h2-|!@#$%^&*()\{}\|~?+-',."<>[]\` |col 2+|!@#$%^&++*++()++{++}{vbar}~?{plus}-',."++<>[]\`++ |col 2 |=== ```
test/command/9358.docx view

binary file changed (13439 → 13427 bytes)

+ test/command/9495.md view
@@ -0,0 +1,98 @@+```+% pandoc -f native -t docx -o - | pandoc -f docx -t native+[ Table+    ( "" , [] , [] )+    (Caption Nothing [])+    [ ( AlignDefault , ColWidth 0.5 )+    , ( AlignDefault , ColWidth 0.5 )+    ]+    (TableHead+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "2" ] ]+           ]+       ])+    [ TableBody+        ( "" , [] , [] )+        (RowHeadColumns 1)+        []+        [ Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "3" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "4" ] ]+            ]+        ]+    ]+    (TableFoot ( "" , [] , [] ) [])+]+^D+[ Table+    ( "" , [] , [] )+    (Caption Nothing [])+    [ ( AlignDefault , ColWidth 0.5 )+    , ( AlignDefault , ColWidth 0.5 )+    ]+    (TableHead+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "2" ] ]+           ]+       ])+    [ TableBody+        ( "" , [] , [] )+        (RowHeadColumns 1)+        []+        [ Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "3" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "4" ] ]+            ]+        ]+    ]+    (TableFoot ( "" , [] , [] ) [])+]+```
+ test/command/9603.docx view

binary file changed (absent → 13816 bytes)

+ test/command/9603.md view
@@ -0,0 +1,23 @@+```+% pandoc command/9603.docx -t html -f docx+styles+^D+<p>A table with a contemporary style:</p>+<table data-custom-style="TableContemporary">+<colgroup>+<col style="width: 50%" />+<col style="width: 50%" />+</colgroup>+<thead>+<tr>+<th>Test</th>+<th>Column</th>+</tr>+</thead>+<tbody>+<tr>+<td>1</td>+<td>2</td>+</tr>+</tbody>+</table>+```
+ test/command/9945.md view
@@ -0,0 +1,28 @@+```+% pandoc -t typst --dpi 300+![](image.jpg){width=300 height=300}+^D+#box(image("image.jpg", height: 1in, width: 1in))+```++```+% pandoc -t typst --dpi 600+![](image.jpg){width=300px height=300px}+^D+#box(image("image.jpg", height: 0.5in, width: 0.5in))+```++```+% pandoc -t typst --dpi 600+![](image.jpg){width=1in height=3cm}+^D+#box(image("image.jpg", height: 3cm, width: 1in))+```+++```+% pandoc -t typst --dpi 600+![](image.jpg){.foo .bar baz=3}+^D+#box(image("image.jpg"))+```
test/docx/table_captions_no_field.docx view

binary file changed (40487 → 40487 bytes)

test/docx/table_captions_with_field.docx view

binary file changed (41091 → 41069 bytes)

test/docx/table_header_rowspan.docx view

binary file changed (15826 → 15690 bytes)

test/docx/table_one_header_row.docx view

binary file changed (12185 → 12214 bytes)

test/docx/table_one_row.docx view

binary file changed (12148 → 12178 bytes)

test/docx/table_variable_width.docx view

binary file changed (10006 → 9882 bytes)

test/docx/table_with_list_cell.docx view

binary file changed (19028 → 19073 bytes)

+ test/pod-reader.native view
@@ -0,0 +1,394 @@+[ Header+    1+    ( "" , [] , [] )+    [ Str "POD" , Space , Str "TEST" , Space , Str "SUITE" ]+, Para+    [ Str "This"+    , Space+    , Str "is"+    , Space+    , Str "a"+    , Space+    , Str "test"+    , Space+    , Link+        ( "" , [] , [] )+        [ Str "Pod" ]+        ( "https://perldoc.pl/perlpod" , "" )+    , Space+    , Str "document"+    , Space+    , Str "for"+    , Space+    , Str "pandoc."+    ]+, Para+    [ Str "=head2" , Space , Str "Head" , Space , Str "2" ]+, Header+    3+    ( "" , [] , [] )+    [ Str "Head"+    , Space+    , Str "3:"+    , Space+    , Emph [ Str "The>" , Space , Str "<Return" ]+    ]+, Header+    4+    ( "" , [] , [] )+    [ Str "How"+    , Space+    , Str "to"+    , Space+    , Str "use"+    , Space+    , Str "the"+    , Space+    , Link+        ( "" , [] , [ ( "manual" , "ls(1)" ) ] )+        [ Str "ls(1)" ]+        ( "" , "" )+    , Space+    , Str "command,"+    , Space+    , Str "an"+    , Space+    , Str "introduction"+    ]+, Header+    5+    ( "" , [] , [] )+    [ Code ( "" , [] , [] ) "Ricky Jay"+    , Space+    , Str "and"+    , Space+    , Str "his"+    , Space+    , Str "52"+    , Space+    , Str "assistants"+    ]+, Header+    6+    ( "" , [] , [] )+    [ Str "The"+    , Space+    , Str "=head5"+    , Space+    , Str "and"+    , Space+    , Str "=head6"+    , Space+    , Str "commands"+    , Space+    , Str "are"+    , Space+    , Str "newer"+    , Space+    , Str "and"+    , Space+    , Str "my"+    , Space+    , Str "syntax"+    , Space+    , Str "highlighting"+    , Space+    , Str "doesn't"+    , Space+    , Str "recognize"+    , Space+    , Str "them."+    , Space+    , Str "In"+    , Space+    , Str "any"+    , Space+    , Str "case,"+    , Space+    , Str "it"+    , Space+    , Str "should"+    , Space+    , Str "be"+    , Space+    , Str "possible"+    , Space+    , Str "to"+    , Space+    , Str "have"+    , Space+    , Str "a"+    , Space+    , Str "very"+    , Space+    , Str "long"+    , Space+    , Str "paragraph"+    , Space+    , Str "in"+    , Space+    , Str "the"+    , Space+    , Str "heading."+    ]+, Header+    6+    ( "" , [] , [] )+    [ Str "It"+    , Space+    , Str "should"+    , Space+    , Str "also"+    , Space+    , Str "be"+    , Space+    , Str "possible"+    , Space+    , Str "to"+    , Space+    , Str "start"+    , Space+    , Str "the"+    , Space+    , Str "heading"+    , Space+    , Str "paragraph"+    , Space+    , Str "on"+    , Space+    , Str "the"+    , Space+    , Str "next"+    , Space+    , Str "line"+    ]+, RawBlock+    (Format "html")+    "<strong>This is a raw block destined for the HTML format</strong>\n\n"+, BulletList+    [ [ Para [ Str "Bulleted" , Space , Str "list" ] ]+    , [ Para [ Str "Ordered" , Space , Str "list" ]+      , OrderedList+          ( 1 , DefaultStyle , DefaultDelim )+          [ [ Para+                [ Str "Here's"+                , Space+                , Str "a"+                , Space+                , Str "verbatim"+                , Space+                , Str "paragraph"+                , Space+                , Str "in"+                , Space+                , Str "this"+                , Space+                , Str "list"+                , Space+                , Str "item:"+                ]+            , CodeBlock+                ( "" , [] , [] )+                "    this is a code block\nthis is still part of the code block\n  so is this.\nIt seems that the prefixed spaces in verbatim blocks in pod don't get stripped.\n\n This should continue the previous code block despite the intervening blank\n line, because the first line starts with a space\n\n\n\n    the above blank lines with varying numbers of spaces should also be in\n the code block\n    pod formatters should (but not must) expand tabs by default\nso we're not special casing pandoc's behavior there in any way\n"+            , Para+                [ Str "Wow,"+                , Space+                , Str "that"+                , Space+                , Str "was"+                , Space+                , Str "fun."+                ]+            ]+          , [ Para [ Str "Definition" , Space , Str "list" ]+            , DefinitionList+                [ ( [ Span+                        ( "" , [] , [] )+                        [ Str "Marvin"+                        , Space+                        , Str "the"+                        , Space+                        , Str "Martian"+                        ]+                    ]+                  , [ [ Para+                          [ Str "A"+                          , Space+                          , Str "cartoon"+                          , Space+                          , Str "alien"+                          ]+                      ]+                    ]+                  )+                , ( [ Span+                        ( "" , [] , [] )+                        [ Emph+                            [ Str "The"+                            , Space+                            , Str "Sun"+                            , Space+                            , Str "Also"+                            , Space+                            , Str "Rises"+                            ]+                        ]+                    ]+                  , [ [ Para+                          [ Str "A"+                          , Space+                          , Str "novel"+                          , Space+                          , Str "by"+                          , Space+                          , Str "Ernest"+                          , Space+                          , Str "Hemingway"+                          ]+                      ]+                    ]+                  )+                , ( [ Span+                        ( "" , [] , [] )+                        [ Code ( "" , [] , [] ) "undefined" ]+                    ]+                  , [ [] ]+                  )+                , ( [ Span+                        ( "" , [] , [] )+                        [ Str "And"+                        , Space+                        , Str "now,"+                        , Space+                        , Str "a"+                        , Space+                        , Str "quotation"+                        ]+                    ]+                  , [ [ BlockQuote+                          [ Para+                              [ Str "Where's"+                              , Space+                              , Str "my"+                              , Space+                              , Str "space"+                              , Space+                              , Str "modulator?"+                              ]+                          ]+                      ]+                    ]+                  )+                ]+            ]+          , [ Para+                [ Str "And"+                , Space+                , Str "the"+                , Space+                , Str "list"+                , Space+                , Str "continues."+                ]+            ]+          ]+      ]+    , [ Para+          [ Str "And"+          , Space+          , Str "so"+          , Space+          , Str "does"+          , Space+          , Str "the"+          , Space+          , Str "other"+          , Space+          , Str "one,"+          , Space+          , Str "even"+          , Space+          , Str "if"+          , Space+          , Str "I"+          , Space+          , Str "forget"+          , Space+          , Str "the"+          , Space+          , Str "asterisk."+          ]+      ]+    ]+, Div+    ( "" , [ "neat" ] , [] )+    [ Para+        [ Str "This"+        , Space+        , Str "is"+        , Space+        , Str "a"+        , Space+        , Str "div"+        , Space+        , Str "for"+        , Space+        , Str "our"+        , Space+        , Str "purposes."+        ]+    , Para+        [ Str "It"+        , Space+        , Str "should"+        , Space+        , Str "parse"+        , Space+        , Strong [ Str "content" ]+        , Space+        , Str "inside"+        , Space+        , Str "of"+        , Space+        , Str "it."+        ]+    , BulletList+        [ [ Para [ Str "Like" , Space , Str "this" ] ] ]+    ]+, Div+    ( "" , [ "excitement" ] , [] )+    [ Para+        [ Str "this"+        , Space+        , Str "is"+        , Space+        , Str "its"+        , Space+        , Str "own"+        , Space+        , Str "div"+        ]+    ]+, RawBlock+    (Format "html") " <p>and this is its own raw block</p>\n"+, RawBlock (Format "html") "\n<p>so is this</p>\n"+, Header+    2+    ( "" , [] , [] )+    [ Code ( "" , [] , [] ) "=cut"+    , Space+    , Str "before"+    , Space+    , Str "any"+    , Space+    , Code ( "" , [] , [] ) "=item"+    , Space+    , Str "in"+    , Space+    , Code ( "" , [] , [] ) "=over"+    ]+, BulletList+    [ [ Para [ Str "a" ] , Para [ Str "b" ] ]+    , [ Para [ Str "c" ] ]+    ]+]
+ test/pod-reader.pod view
@@ -0,0 +1,155 @@+text before any Pod commands is not parsed, which is unusual for formats+supported by pandoc, but ++=head1 POD TEST SUITE++This is a test L<Pod|https://perldoc.pl/perlpod> document for pandoc.++=encoding utf8++=head2 Head 2++=head3 Head 3: I<< The> <Return >>++=head4 How to use the L<ls(1)> command,+an introduction++=head5 C<Ricky Jay> and his 52 assistants++=head6 The =head5 and =head6 commands are newer and my syntax highlighting+doesn't recognize them. In any case, it should be possible to have a very long+paragraph in the heading.++=head6+It should also be possible to start the heading paragraph on the next line++=cut++This doesn't get parsed at all.++=begin html++<strong>This is a raw block destined for the HTML format</strong>++=end html++=over++=item *++Bulleted list++=item *++Ordered list++=over++=item 1.++Here's a verbatim paragraph in this list item:++    this is a code block+this is still part of the code block+  so is this.+It seems that the prefixed spaces in verbatim blocks in pod don't get stripped.++ This should continue the previous code block despite the intervening blank+ line, because the first line starts with a space+    ++ +    the above blank lines with varying numbers of spaces should also be in+ the code block+	pod formatters should (but not must) expand tabs by default+so we're not special casing pandoc's behavior there in any way++Wow, that was fun.++=item 2.++Definition list++=over++=item Marvin the MZ<>artian++A cartoon alien++=item I<The Sun+Also Rises>++A novel by Ernest Hemingway++=item C<undefined>++=item And now, a quotation++=over++Where's my space modulator?++=back++=back++=item 3.++And the list continues.++=back++=item++And so does the other one, even if I forget the asterisk.++=back++=begin :neat++This is a div for our purposes.++It should parse B<< content >> inside of it.++=over++=item++Like this++=back++=end :neat++=for :excitement this is its own div++=for html <p>and this is its own raw block</p>++=for html+<p>so is this</p>++=head2 C<=cut> before any C<=item> in C<=over>++=over++=cut++blah++=item *++a++=cut++blah blah++=pod++b++=item *++c++=back
test/test-pandoc.hs view
@@ -30,6 +30,7 @@ import qualified Tests.Readers.Txt2Tags import qualified Tests.Readers.Man import qualified Tests.Readers.Mdoc+import qualified Tests.Readers.Pod import qualified Tests.Shared import qualified Tests.Writers.AsciiDoc import qualified Tests.Writers.ConTeXt@@ -101,6 +102,7 @@           , testGroup "Mdoc" Tests.Readers.Mdoc.tests           , testGroup "FB2" Tests.Readers.FB2.tests           , testGroup "DokuWiki" Tests.Readers.DokuWiki.tests+          , testGroup "Pod" Tests.Readers.Pod.tests           ]         ] 
test/writer.asciidoc view
@@ -40,7 +40,7 @@ Because a hard-wrapped line in the middle of a paragraph looked like a list item. -Here’s one with a bullet. * criminey.+Here’s one with a bullet. ++*++ criminey.  There should be a hard line break + here.@@ -84,7 +84,7 @@ -- ____ -This should not be a block quote: 2 > 1.+This should not be a block quote: 2 ++>++ 1.  And a following paragraph. @@ -424,7 +424,7 @@  So is *_this_* word. -This is code: `+>+`, `+$+`, `+\+`, `+\$+`, `+<html>+`.+This is code: `++>++`, `$`, `++\++`, `++\++$`, `++<++html++>++`.  [line-through]#This is _strikeout_.# @@ -447,7 +447,7 @@  '`He said, "`I want to go.`"`' Were you alive in the 70’s? -Here is some quoted '``+code+``' and a "`http://example.com/?foo=1&bar=2[quoted+Here is some quoted '``code``' and a "`http://example.com/?foo=1&bar=2[quoted link]`".  Some dashes: one—two — three—four — five.@@ -477,11 +477,11 @@  These shouldn’t be math: -* To get the famous equation, write `+$e = mc^2$+`.+* To get the famous equation, write `$e = mc^2$`. * $22,000 is a _lot_ of money. So is $34,000. (It worked if "`lot`" is emphasized.) * Shoes ($20) and socks ($5).-* Escaped `+$+`: $73 _this should be emphasized_ 23$.+* Escaped `$`: $73 _this should be emphasized_ 23$.  Here’s a LaTeX table: @@ -503,31 +503,31 @@  This & that. -4 < 5.+4 ++<++ 5. -6 > 5.+6 ++>++ 5. -Backslash: \+Backslash: ++\++ -Backtick: `+Backtick: ++`++ -Asterisk: *+Asterisk: ++*++ -Underscore: _+Underscore: ++_++ -Left brace: \{+Left brace: ++{++  Right brace: } -Left bracket: [+Left bracket: ++[++ -Right bracket: ]+Right bracket: ++]++  Left paren: (  Right paren: ) -Greater-than: >+Greater-than: ++>++  Hash: # @@ -535,7 +535,7 @@  Bang: ! -Plus: ++Plus: {plus}  Minus: - @@ -557,7 +557,7 @@  link:/url/[URL and title] -link:/url/with_underscore[with_underscore]+link:/url/with_underscore[with++_++underscore]  mailto:nobody@nowhere.net[Email link] @@ -567,7 +567,7 @@  Foo link:/url/[bar]. -With link:/url/[embedded [brackets]].+With link:/url/[embedded ++[++brackets++]++].  link:/url/[b] by itself should be a link. @@ -577,7 +577,7 @@  Indented link:/url[thrice]. -This should [not][] be a link.+This should ++[++not++][]++ be a link.  .... [not]: /url@@ -611,7 +611,7 @@ Blockquoted: http://example.com/ ____ -Auto-links should not occur here: `+<http://example.com/>+`+Auto-links should not occur here: `++<++http://example.com/++>++`  .... or here: <http://example.com/>@@ -635,10 +635,10 @@ Here is a footnote reference,footnote:[Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.] and another.[multiblock footnote omitted] This should _not_ be a footnote-reference, because it contains a space.[^my note] Here is an inline+reference, because it contains a space.++[++^my note++]++ Here is an inline note.footnote:[This is _easier_ to type. Inline notes may contain-http://google.com[links] and `+]+` verbatim characters, as well as [bracketed-text].]+http://google.com[links] and `++]++` verbatim characters, as well as+++[++bracketed text++]++.]  ____ Notes can go in quotes.footnote:[In quote.]
test/writer.asciidoc_legacy view
@@ -39,7 +39,7 @@ Because a hard-wrapped line in the middle of a paragraph looked like a list item. -Here’s one with a bullet. * criminey.+Here’s one with a bullet. ++*++ criminey.  There should be a hard line break + here.@@ -83,7 +83,7 @@ -- ____ -This should not be a block quote: 2 > 1.+This should not be a block quote: 2 ++>++ 1.  And a following paragraph. @@ -502,31 +502,31 @@  This & that. -4 < 5.+4 ++<++ 5. -6 > 5.+6 ++>++ 5. -Backslash: \+Backslash: ++\++ -Backtick: `+Backtick: ++`++ -Asterisk: *+Asterisk: ++*++ -Underscore: _+Underscore: ++_++ -Left brace: \{+Left brace: ++{++  Right brace: } -Left bracket: [+Left bracket: ++[++ -Right bracket: ]+Right bracket: ++]++  Left paren: (  Right paren: ) -Greater-than: >+Greater-than: ++>++  Hash: # @@ -534,7 +534,7 @@  Bang: ! -Plus: ++Plus: {plus}  Minus: - @@ -556,7 +556,7 @@  link:/url/[URL and title] -link:/url/with_underscore[with_underscore]+link:/url/with_underscore[with++_++underscore]  mailto:nobody@nowhere.net[Email link] @@ -566,7 +566,7 @@  Foo link:/url/[bar]. -With link:/url/[embedded [brackets]].+With link:/url/[embedded ++[++brackets++]++].  link:/url/[b] by itself should be a link. @@ -576,7 +576,7 @@  Indented link:/url[thrice]. -This should [not][] be a link.+This should ++[++not++][]++ be a link.  .... [not]: /url@@ -634,10 +634,10 @@ Here is a footnote reference,footnote:[Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.] and another.[multiblock footnote omitted] This should _not_ be a footnote-reference, because it contains a space.[^my note] Here is an inline+reference, because it contains a space.++[++^my note++]++ Here is an inline note.footnote:[This is _easier_ to type. Inline notes may contain-http://google.com[links] and `]` verbatim characters, as well as [bracketed-text].]+http://google.com[links] and `]` verbatim characters, as well as ++[++bracketed+text++]++.]  ____ Notes can go in quotes.footnote:[In quote.]