diff --git a/MANUAL.txt b/MANUAL.txt index 1f9f04362226..cc39bf916990 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -5389,7 +5389,7 @@ from being interpreted as Markdown. ### Extension: `native_divs` ### -Use native pandoc `Div` blocks for content inside `
` tags with attributes are processed, by wrapping them in `Div` blocks to better preserve their attributes during conversion. For the most part this should give the same output as `markdown_in_html_blocks`, but it makes it easier to write pandoc filters to manipulate groups of blocks. diff --git a/src/Text/Pandoc/Extensions.hs b/src/Text/Pandoc/Extensions.hs index f1c9c0f379fe..7ff9c13c2937 100644 --- a/src/Text/Pandoc/Extensions.hs +++ b/src/Text/Pandoc/Extensions.hs @@ -109,6 +109,7 @@ data Extension = | Ext_ntb -- ^ ConTeXt Natural Tables | Ext_old_dashes -- ^ -- = em, - before number = en | Ext_pandoc_title_block -- ^ Pandoc title block + | Ext_paragraph_attributes -- ^ Allow paragraph attributes in HTML | Ext_pipe_tables -- ^ Pipe tables (as in PHP markdown extra) | Ext_raw_attribute -- ^ Allow explicit raw blocks/inlines | Ext_raw_html -- ^ Allow raw HTML @@ -598,6 +599,7 @@ getAllExtensions f = universalExtensions <> getAll f , Ext_literate_haskell , Ext_epub_html_exts , Ext_smart + , Ext_paragraph_attributes ] getAll "html4" = getAll "html" getAll "html5" = getAll "html" diff --git a/src/Text/Pandoc/Readers/HTML.hs b/src/Text/Pandoc/Readers/HTML.hs index fcc1147ca376..09d9ab51bd35 100644 --- a/src/Text/Pandoc/Readers/HTML.hs +++ b/src/Text/Pandoc/Readers/HTML.hs @@ -623,13 +623,38 @@ pPlain = do then return mempty else return $ B.plain contents -pPara :: PandocMonad m => TagParser m Blocks -pPara = do +-- Helper function for pPara when significant attributes are present +pParaWithWrapper :: PandocMonad m => Attr -> TagParser m Blocks +pParaWithWrapper (ident, classes, kvs) = do + guardEnabled Ext_native_divs -- Ensure native_divs is enabled for this behavior + contents <- trimInlines <$> pInTags "p" inline + (do guardDisabled Ext_empty_paragraphs + guard (null contents) + return mempty) <|> do + let wrapperAttr = ("wrapper", "1") + let finalKVs = wrapperAttr : kvs + let finalAttrs = (ident, classes, finalKVs) + return $ B.divWith finalAttrs (B.para contents) + +-- Helper function for pPara when no significant attributes are present +pParaSimple :: PandocMonad m => TagParser m Blocks +pParaSimple = do contents <- trimInlines <$> pInTags "p" inline (do guardDisabled Ext_empty_paragraphs guard (null contents) - return mempty) - <|> return (B.para contents) + return mempty) <|> + return (B.para contents) + +pPara :: PandocMonad m => TagParser m Blocks +pPara = do + TagOpen _ attr' <- lookAhead $ pSatisfy (matchTagOpen "p" []) + let attr@(ident, classes, kvs) = toAttr attr' + -- "Significant" attributes are any id, class, or key-value pair. + let hasSignificantAttributes = not (T.null ident) || not (null classes) || not (null kvs) + + if hasSignificantAttributes + then pParaWithWrapper attr + else pParaSimple pFigure :: PandocMonad m => TagParser m Blocks pFigure = do diff --git a/src/Text/Pandoc/Writers/AsciiDoc.hs b/src/Text/Pandoc/Writers/AsciiDoc.hs index fb0ce0db1fde..43308479ffe3 100644 --- a/src/Text/Pandoc/Writers/AsciiDoc.hs +++ b/src/Text/Pandoc/Writers/AsciiDoc.hs @@ -377,34 +377,38 @@ blockToAsciiDoc opts (DefinitionList items) = do return $ mconcat contents <> blankline -- convert admonition and sidebar divs to asicidoc -blockToAsciiDoc opts (Div (ident,classes,_) bs) = do - let identifier = if T.null ident then empty else "[[" <> literal ident <> "]]" - let admonition_classes = ["attention","caution","danger","error","hint", - "important","note","tip","warning"] - let sidebar_class = "sidebar" - - contents <- - case classes of - (l:_) | l `elem` admonition_classes || T.toLower l == sidebar_class -> do - let (titleBs, bodyBs) = - case bs of - (Div (_,["title"],_) ts : rest) -> (ts, rest) - _ -> ([], bs) - let fence = if l == "sidebar" then "****" else "====" - elemTitle <- if null titleBs || - -- If title matches class, omit - (T.toLower (T.strip (stringify titleBs))) == l - then return mempty - else ("." <>) <$> - blockListToAsciiDoc opts titleBs - elemBody <- blockListToAsciiDoc opts bodyBs - return $ "[" <> literal (T.toUpper l) <> "]" $$ - chomp elemTitle $$ - fence $$ - chomp elemBody $$ - fence - _ -> blockListToAsciiDoc opts bs - return $ identifier $$ contents $$ blankline +blockToAsciiDoc opts divBlock@(Div (ident,classes,_) bs) = do + -- First try to unwrap wrapper divs + case unwrapWrapperDiv divBlock of + Para inlines -> blockToAsciiDoc opts (Para inlines) + _ -> do + let identifier = if T.null ident then empty else "[[" <> literal ident <> "]]" + let admonition_classes = ["attention","caution","danger","error","hint", + "important","note","tip","warning"] + let sidebar_class = "sidebar" + + contents <- + case classes of + (l:_) | l `elem` admonition_classes || T.toLower l == sidebar_class -> do + let (titleBs, bodyBs) = + case bs of + (Div (_,["title"],_) ts : rest) -> (ts, rest) + _ -> ([], bs) + let fence = if l == "sidebar" then "****" else "====" + elemTitle <- if null titleBs || + -- If title matches class, omit + (T.toLower (T.strip (stringify titleBs))) == l + then return mempty + else ("." <>) <$> + blockListToAsciiDoc opts titleBs + elemBody <- blockListToAsciiDoc opts bodyBs + return $ "[" <> literal (T.toUpper l) <> "]" $$ + chomp elemTitle $$ + fence $$ + chomp elemBody $$ + fence + _ -> blockListToAsciiDoc opts bs + return $ identifier $$ contents $$ blankline -- | Convert bullet list item (list of blocks) to asciidoc. bulletListItemToAsciiDoc :: PandocMonad m diff --git a/src/Text/Pandoc/Writers/ConTeXt.hs b/src/Text/Pandoc/Writers/ConTeXt.hs index 65a0fa9ddaae..4a13eed3e5bb 100644 --- a/src/Text/Pandoc/Writers/ConTeXt.hs +++ b/src/Text/Pandoc/Writers/ConTeXt.hs @@ -38,7 +38,7 @@ import Text.Pandoc.Shared import Text.Pandoc.URI (isURI) import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Walk (query) -import Text.Pandoc.Writers.Shared +import Text.Pandoc.Writers.Shared (unwrapWrapperDiv, defField, getField, resetField, lookupMetaString, metaToContext, getLang) import Text.Printf (printf) import qualified Data.List.NonEmpty as NonEmpty @@ -187,37 +187,40 @@ toLabel z = T.concatMap go z -- | Convert Pandoc block element to ConTeXt. blockToConTeXt :: PandocMonad m => Block -> WM m (Doc Text) -blockToConTeXt (Div attr@(_,"section":_,_) +blockToConTeXt block = blockToConTeXt' (unwrapWrapperDiv block) + +blockToConTeXt' :: PandocMonad m => Block -> WM m (Doc Text) +blockToConTeXt' (Div attr@(_,"section":_,_) (Header level _ title' : xs)) = do header' <- sectionHeader attr level title' SectionHeading footer' <- sectionFooter attr level innerContents <- blockListToConTeXt xs return $ header' $$ innerContents $$ footer' -blockToConTeXt (Plain lst) = do +blockToConTeXt' (Plain lst) = do opts <- gets stOptions contents <- inlineListToConTeXt lst return $ if isEnabled Ext_tagging opts then "\\bpar{}" <> contents <> "\\epar{}" else contents -blockToConTeXt (Para lst) = do +blockToConTeXt' (Para lst) = do opts <- gets stOptions contents <- inlineListToConTeXt lst return $ if isEnabled Ext_tagging opts then "\\bpar" $$ contents $$ "\\epar" <> blankline else contents <> blankline -blockToConTeXt (LineBlock lns) = do +blockToConTeXt' (LineBlock lns) = do let emptyToBlankline doc = if isEmpty doc then blankline else doc doclines <- mapM inlineListToConTeXt lns let contextLines = vcat . map emptyToBlankline $ doclines return $ "\\startlines" $$ contextLines $$ "\\stoplines" <> blankline -blockToConTeXt (BlockQuote lst) = do +blockToConTeXt' (BlockQuote lst) = do contents <- blockListToConTeXt lst return $ "\\startblockquote" $$ nest 0 contents $$ "\\stopblockquote" <> blankline -blockToConTeXt (CodeBlock (_ident, classes, kv) str) = do +blockToConTeXt' (CodeBlock (_ident, classes, kv) str) = do opts <- gets stOptions let syntaxMap = writerSyntaxMap opts let attr' = ("", classes, kv) @@ -236,15 +239,15 @@ blockToConTeXt (CodeBlock (_ident, classes, kv) str) = do if null classes || isNothing (writerHighlightStyle opts) then pure unhighlighted else highlighted -blockToConTeXt b@(RawBlock f str) +blockToConTeXt' b@(RawBlock f str) | f == Format "context" || f == Format "tex" = return $ literal str <> blankline | otherwise = empty <$ report (BlockNotRendered b) -blockToConTeXt (Div ("refs",classes,_) bs) = do +blockToConTeXt' (Div ("refs",classes,_) bs) = do modify $ \st -> st{ stHasCslRefs = True , stCslHangingIndent = "hanging-indent" `elem` classes } inner <- blockListToConTeXt bs return $ "\\startcslreferences" $$ inner $$ "\\stopcslreferences" -blockToConTeXt (Div (ident,_,kvs) bs) = do +blockToConTeXt' (Div (ident,_,kvs) bs) = do let align dir txt = "\\startalignment[" <> dir <> "]" $$ txt $$ "\\stopalignment" mblang <- fromBCP47 (lookup "lang" kvs) let wrapRef txt = if T.null ident @@ -261,13 +264,13 @@ blockToConTeXt (Div (ident,_,kvs) bs) = do Nothing -> txt wrapBlank txt = blankline <> txt <> blankline wrapBlank . wrapLang . wrapDir . wrapRef <$> blockListToConTeXt bs -blockToConTeXt (BulletList lst) = do +blockToConTeXt' (BulletList lst) = do contents <- mapM listItemToConTeXt lst return $ ("\\startitemize" <> if isTightList lst then brackets "packed" else empty) $$ vcat contents $$ literal "\\stopitemize" <> blankline -blockToConTeXt (OrderedList (start, style', delim) lst) = do +blockToConTeXt' (OrderedList (start, style', delim) lst) = do st <- get let level = stOrderedListLevel st put st {stOrderedListLevel = level + 1} @@ -295,15 +298,15 @@ blockToConTeXt (OrderedList (start, style', delim) lst) = do let specs = T.pack style'' <> specs2 return $ "\\startenumerate" <> literal specs $$ vcat contents $$ "\\stopenumerate" <> blankline -blockToConTeXt (DefinitionList lst) = +blockToConTeXt' (DefinitionList lst) = liftM vcat $ mapM defListItemToConTeXt lst -blockToConTeXt HorizontalRule = return $ "\\thinrule" <> blankline +blockToConTeXt' HorizontalRule = return $ "\\thinrule" <> blankline -- If this is ever executed, provide a default for the reference identifier. -blockToConTeXt (Header level attr lst) = +blockToConTeXt' (Header level attr lst) = sectionHeader attr level lst NonSectionHeading -blockToConTeXt (Table attr caption colspecs thead tbody tfoot) = +blockToConTeXt' (Table attr caption colspecs thead tbody tfoot) = tableToConTeXt (Ann.toTable attr caption colspecs thead tbody tfoot) -blockToConTeXt (Figure (ident, _, _) (Caption cshort clong) body) = do +blockToConTeXt' (Figure (ident, _, _) (Caption cshort clong) body) = do title <- inlineListToConTeXt (blocksToInlines clong) list <- maybe (pure empty) inlineListToConTeXt cshort content <- blockListToConTeXt body diff --git a/src/Text/Pandoc/Writers/DocBook.hs b/src/Text/Pandoc/Writers/DocBook.hs index 775a92befa33..6de8052fe2eb 100644 --- a/src/Text/Pandoc/Writers/DocBook.hs +++ b/src/Text/Pandoc/Writers/DocBook.hs @@ -204,10 +204,11 @@ blockToDocBook opts (Div (id',"section":_classes,divattrs) title' <- inlinesToDocBook opts ils contents <- blocksToDocBook opts bs return $ inTags True tag attribs $ inTagsSimple "title" title' $$ contents -blockToDocBook opts (Div (ident,classes,_) bs) = do +blockToDocBook opts (Div (ident,classes,_kvs) bs) = do version <- ask let identAttribs = [(idName version, ident) | not (T.null ident)] admonitions = ["caution","danger","important","note","tip","warning"] + case classes of (l:_) | l `elem` admonitions -> do let (mTitleBs, bodyBs) = @@ -219,13 +220,15 @@ blockToDocBook opts (Div (ident,classes,_) bs) = do _ -> (Nothing, bs) admonitionTitle <- case mTitleBs of Nothing -> return mempty - -- id will be attached to the admonition so let’s pass empty identAttrs. + -- id will be attached to the admonition so let's pass empty identAttrs. Just titleBs -> inTagsSimple "title" <$> titleBs admonitionBody <- handleDivBody [] bodyBs return (inTags True l identAttribs (admonitionTitle $$ admonitionBody)) _ -> handleDivBody identAttribs bs where handleDivBody identAttribs [Para lst] = + -- For wrapper divs with single Para, apply attributes to para + -- For normal divs with single Para, also apply attributes to para (original behavior) if hasLineBreaks lst then flush . nowrap . inTags False "literallayout" identAttribs <$> inlinesToDocBook opts lst diff --git a/src/Text/Pandoc/Writers/Docx/OpenXML.hs b/src/Text/Pandoc/Writers/Docx/OpenXML.hs index 0b76153f4b1c..a57c5c0ac777 100644 --- a/src/Text/Pandoc/Writers/Docx/OpenXML.hs +++ b/src/Text/Pandoc/Writers/Docx/OpenXML.hs @@ -227,6 +227,8 @@ writeOpenXML :: PandocMonad m -> WS m (Text, [Element], [Element]) writeOpenXML opts (Pandoc meta blocks) = do setupTranslations meta + -- Apply unwrapWrapperDiv to all blocks + let blocks' = walk unwrapWrapperDiv blocks let includeTOC = writerTableOfContents opts || lookupMetaBool "toc" meta let includeLOF = writerListOfFigures opts || lookupMetaBool "lof" meta let includeLOT = writerListOfTables opts || lookupMetaBool "lot" meta @@ -252,7 +254,7 @@ writeOpenXML opts (Pandoc meta blocks) = do (fmap (hcat . map (literal . showContent)) . inlinesToOpenXML opts) (docAuthors meta) - doc' <- setFirstPara >> blocksToOpenXML opts blocks + doc' <- setFirstPara >> blocksToOpenXML opts blocks' let body = vcat $ map (literal . showContent) doc' notes' <- gets (reverse . stFootnotes) comments <- gets (reverse . stComments) diff --git a/src/Text/Pandoc/Writers/DokuWiki.hs b/src/Text/Pandoc/Writers/DokuWiki.hs index 34ea2e3bd76e..4840ee6cb922 100644 --- a/src/Text/Pandoc/Writers/DokuWiki.hs +++ b/src/Text/Pandoc/Writers/DokuWiki.hs @@ -41,7 +41,7 @@ import Text.Pandoc.Shared (figureDiv, linesToPara, removeFormatting, trimr) import Text.Pandoc.URI (escapeURI, isURI) import Text.Pandoc.Templates (renderTemplate) import Text.DocLayout (render, literal) -import Text.Pandoc.Writers.Shared (defField, metaToContext, toLegacyTable) +import Text.Pandoc.Writers.Shared (defField, metaToContext, toLegacyTable, unwrapWrapperDiv) import Data.Maybe (fromMaybe) import qualified Data.Map as M @@ -101,7 +101,7 @@ blockToDokuWiki :: PandocMonad m -> DokuWiki m Text blockToDokuWiki opts (Div _attrs bs) = do - contents <- blockListToDokuWiki opts bs + contents <- blockListToDokuWiki opts (map unwrapWrapperDiv bs) indent <- asks stIndent return $ contents <> if T.null indent then "\n" else "" diff --git a/src/Text/Pandoc/Writers/EPUB.hs b/src/Text/Pandoc/Writers/EPUB.hs index f1d4bb95e0a6..3d771b842fd1 100644 --- a/src/Text/Pandoc/Writers/EPUB.hs +++ b/src/Text/Pandoc/Writers/EPUB.hs @@ -35,7 +35,7 @@ import qualified Data.Text.Lazy as TL import System.FilePath (takeExtension, takeFileName, makeRelative) import Text.HTML.TagSoup (Tag (TagOpen), fromAttrib, parseTags) import Text.Pandoc.Builder (fromList, setMeta) -import Text.Pandoc.Writers.Shared (ensureValidXmlIdentifiers) +import Text.Pandoc.Writers.Shared (ensureValidXmlIdentifiers, unwrapWrapperDiv) import Data.Tree (Tree(..)) import Text.Pandoc.Class (PandocMonad, report) import qualified Text.Pandoc.Class.PandocPure as P @@ -1211,7 +1211,7 @@ transformBlock (RawBlock fmt raw) let tags = parseTags raw tags' <- mapM transformTag tags return $ RawBlock fmt (renderTags' tags') -transformBlock b = return b +transformBlock b = return $ unwrapWrapperDiv b transformInline :: PandocMonad m => WriterOptions diff --git a/src/Text/Pandoc/Writers/FB2.hs b/src/Text/Pandoc/Writers/FB2.hs index fd4e01d4697e..ffc756c235d8 100644 --- a/src/Text/Pandoc/Writers/FB2.hs +++ b/src/Text/Pandoc/Writers/FB2.hs @@ -41,7 +41,7 @@ import Text.Pandoc.Shared (blocksToInlines, capitalize, orderedListMarkers, makeSections, tshow, stringify) import Text.Pandoc.Walk (walk) import Text.Pandoc.Writers.Shared (lookupMetaString, toLegacyTable, - ensureValidXmlIdentifiers) + ensureValidXmlIdentifiers, unwrapWrapperDiv) import Data.Generics (everywhere, mkT) -- | Data to be written at the end of the document: @@ -315,7 +315,7 @@ blockToXml (RawBlock f str) = Left msg -> throwError $ PandocXMLError "" msg Right nds -> return nds else return [] -blockToXml (Div _ bs) = cMapM blockToXml bs +blockToXml (Div _ bs) = cMapM blockToXml (map unwrapWrapperDiv bs) blockToXml (BlockQuote bs) = list . el "cite" <$> cMapM blockToXml bs blockToXml (LineBlock lns) = list . el "poem" <$> mapM stanza (split null lns) diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs index bb54f0f82e10..a67efa8d7692 100644 --- a/src/Text/Pandoc/Writers/HTML.hs +++ b/src/Text/Pandoc/Writers/HTML.hs @@ -750,6 +750,19 @@ blockToHtmlInner opts (Para lst) = do blockToHtmlInner opts (LineBlock lns) = do htmlLines <- inlineListToHtml opts $ intercalate [LineBreak] lns return $ H.div ! A.class_ "line-block" $ htmlLines +blockToHtmlInner opts (Div (ident, classes, kvs) [Para pans]) | Just "1" <- lookup "wrapper" kvs = do + -- This is a paragraph that was wrapped in a Div by the reader + -- Unwrap it back to a
tag, with extension-controlled attribute handling + inner <- inlineListToHtml opts pans + if isEnabled Ext_paragraph_attributes opts + then do + -- Extension enabled: preserve all attributes except wrapper + let pKVs = filter (\(k,_) -> k /= "wrapper") kvs + let pAttr = (ident, classes, pKVs) + addAttrs opts pAttr (H.p inner) + else + -- Extension disabled: remove all attributes + return (H.p inner) blockToHtmlInner opts (Div (ident, "section":dclasses, dkvs) (Header level hattr@(hident,hclasses,hkvs) ils : xs)) = do diff --git a/src/Text/Pandoc/Writers/Haddock.hs b/src/Text/Pandoc/Writers/Haddock.hs index 6330259b0f0b..af47316e26cd 100644 --- a/src/Text/Pandoc/Writers/Haddock.hs +++ b/src/Text/Pandoc/Writers/Haddock.hs @@ -93,62 +93,64 @@ blockToHaddock :: PandocMonad m => WriterOptions -- ^ Options -> Block -- ^ Block element -> StateT WriterState m (Doc Text) -blockToHaddock opts (Div _ ils) = do - contents <- blockListToHaddock opts ils - return $ contents <> blankline -blockToHaddock opts (Plain inlines) = do - contents <- inlineListToHaddock opts inlines - return $ contents <> cr -blockToHaddock opts (Para inlines) = - -- TODO: if it contains linebreaks, we need to use a @...@ block - (<> blankline) `fmap` blockToHaddock opts (Plain inlines) -blockToHaddock opts (LineBlock lns) = - blockToHaddock opts $ linesToPara lns -blockToHaddock _ b@(RawBlock f str) - | f == "haddock" = - return $ literal str <> text "\n" - | otherwise = do - report $ BlockNotRendered b - return empty -blockToHaddock opts HorizontalRule = - return $ blankline <> text (replicate (writerColumns opts) '_') <> blankline -blockToHaddock opts (Header level (ident,_,_) inlines) = do - contents <- inlineListToHaddock opts inlines - let attr' = if T.null ident - then empty - else cr <> text "#" <> literal ident <> text "#" - return $ nowrap (text (replicate level '=') <> space <> contents) - <> attr' <> blankline -blockToHaddock _ (CodeBlock (_,_,_) str) = - return $ prefixed "> " (literal str) <> blankline --- Nothing in haddock corresponds to block quotes: -blockToHaddock opts (BlockQuote blocks) = - blockListToHaddock opts blocks -blockToHaddock opts (Table _ blkCapt specs thead tbody tfoot) = do - let Caption _ caption = blkCapt - caption' <- blockListToHaddock opts caption - let caption'' = if null caption - then empty - else blankline <> caption' <> blankline - tbl <- gridTable opts blockListToHaddock specs thead tbody tfoot - return $ (tbl $$ blankline $$ caption'') $$ blankline -blockToHaddock opts (BulletList items) = do - contents <- mapM (bulletListItemToHaddock opts) items - return $ (if isTightList items then vcat else vsep) contents <> blankline -blockToHaddock opts (OrderedList (start,_,delim) items) = do - let attribs = (start, Decimal, delim) - let markers = orderedListMarkers attribs - let markers' = map (\m -> if T.length m < 3 - then m <> T.replicate (3 - T.length m) " " - else m) markers - contents <- zipWithM (orderedListItemToHaddock opts) markers' items - return $ (if isTightList items then vcat else vsep) contents <> blankline -blockToHaddock opts (DefinitionList items) = do - contents <- mapM (definitionListItemToHaddock opts) items - return $ vcat contents <> blankline -blockToHaddock opts (Figure _ (Caption _ longcapt) body) = - -- Haddock has no concept of figures, floats, or captions. - fmap (<> blankline) (blockListToHaddock opts (body ++ longcapt)) +blockToHaddock opts block = case unwrapWrapperDiv block of + Para inlines -> do + -- TODO: if it contains linebreaks, we need to use a @...@ block + contents <- inlineListToHaddock opts inlines + return $ contents <> blankline + Div _ ils -> do + contents <- blockListToHaddock opts ils + return $ contents <> blankline + Plain inlines -> do + contents <- inlineListToHaddock opts inlines + return $ contents <> cr + LineBlock lns -> + blockToHaddock opts $ linesToPara lns + b@(RawBlock f str) + | f == "haddock" -> + return $ literal str <> text "\n" + | otherwise -> do + report $ BlockNotRendered b + return empty + HorizontalRule -> + return $ blankline <> text (replicate (writerColumns opts) '_') <> blankline + Header level (ident,_,_) inlines -> do + contents <- inlineListToHaddock opts inlines + let attr' = if T.null ident + then empty + else cr <> text "#" <> literal ident <> text "#" + return $ nowrap (text (replicate level '=') <> space <> contents) + <> attr' <> blankline + CodeBlock (_,_,_) str -> + return $ prefixed "> " (literal str) <> blankline + -- Nothing in haddock corresponds to block quotes: + BlockQuote blocks -> + blockListToHaddock opts blocks + Table _ blkCapt specs thead tbody tfoot -> do + let Caption _ caption = blkCapt + caption' <- blockListToHaddock opts caption + let caption'' = if null caption + then empty + else blankline <> caption' <> blankline + tbl <- gridTable opts blockListToHaddock specs thead tbody tfoot + return $ (tbl $$ blankline $$ caption'') $$ blankline + BulletList items -> do + contents <- mapM (bulletListItemToHaddock opts) items + return $ (if isTightList items then vcat else vsep) contents <> blankline + OrderedList (start,_,delim) items -> do + let attribs = (start, Decimal, delim) + let markers = orderedListMarkers attribs + let markers' = map (\m -> if T.length m < 3 + then m <> T.replicate (3 - T.length m) " " + else m) markers + contents <- zipWithM (orderedListItemToHaddock opts) markers' items + return $ (if isTightList items then vcat else vsep) contents <> blankline + DefinitionList items -> do + contents <- mapM (definitionListItemToHaddock opts) items + return $ vcat contents <> blankline + Figure _ (Caption _ longcapt) body -> + -- Haddock has no concept of figures, floats, or captions. + fmap (<> blankline) (blockListToHaddock opts (body ++ longcapt)) -- | Convert bullet list item (list of blocks) to haddock bulletListItemToHaddock :: PandocMonad m diff --git a/src/Text/Pandoc/Writers/ICML.hs b/src/Text/Pandoc/Writers/ICML.hs index 1d766ab13072..d7d476dd02b4 100644 --- a/src/Text/Pandoc/Writers/ICML.hs +++ b/src/Text/Pandoc/Writers/ICML.hs @@ -383,9 +383,13 @@ blockToICML opts style (Table attr blkCapt specs thead tbody tfoot) = , ("ColumnCount", tshow nrCols) ] (colDescs $$ cells) liftM2 ($$) tableDoc $ parStyle opts (tableCaptionName:style) "" caption -blockToICML opts style (Div (_ident, _, kvs) lst) = - let dynamicStyle = maybeToList $ lookup dynamicStyleKey kvs - in blocksToICML opts (dynamicStyle <> style) lst +blockToICML opts style block@(Div (_, _, kvs) lst) = + case unwrapWrapperDiv block of + Para inlines -> blockToICML opts style (Para inlines) + Div {} -> + let dynamicStyle = maybeToList $ lookup dynamicStyleKey kvs + in blocksToICML opts (dynamicStyle <> style) lst + other -> blockToICML opts style other blockToICML opts style (Figure attr capt@(Caption _ longcapt) body) = case body of [Plain [img@(Image {})]] -> do diff --git a/src/Text/Pandoc/Writers/JATS.hs b/src/Text/Pandoc/Writers/JATS.hs index d7975bff3d6b..8b32e8923aa1 100644 --- a/src/Text/Pandoc/Writers/JATS.hs +++ b/src/Text/Pandoc/Writers/JATS.hs @@ -358,13 +358,17 @@ blockToJATS opts (Div (ident,[cls],kvs) bs) | cls `elem` ["fig", "caption", "tab [(k,v) | (k,v) <- kvs, k `elem` ["specific-use", "content-type", "orientation", "position"]] return $ inTags True cls attr contents -blockToJATS opts (Div (ident,_,kvs) bs) = do - contents <- blocksToJATS opts bs - let attr = [("id", escapeNCName ident) | not (T.null ident)] ++ - [("xml:lang",l) | ("lang",l) <- kvs] ++ - [(k,v) | (k,v) <- kvs, k `elem` ["specific-use", - "content-type", "orientation", "position"]] - return $ inTags True "boxed-text" attr contents +blockToJATS opts (Div (ident,classes,kvs) bs) = do + -- First try to unwrap wrapper divs + case unwrapWrapperDiv (Div (ident,classes,kvs) bs) of + Para inlines -> blockToJATS opts (Para inlines) + _ -> do + contents <- blocksToJATS opts bs + let attr = [("id", escapeNCName ident) | not (T.null ident)] ++ + [("xml:lang",l) | ("lang",l) <- kvs] ++ + [(k,v) | (k,v) <- kvs, k `elem` ["specific-use", + "content-type", "orientation", "position"]] + return $ inTags True "boxed-text" attr contents blockToJATS opts (Header _ _ title) = do title' <- inlinesToJATS opts (map fixLineBreak title) return $ inTagsSimple "title" title' diff --git a/src/Text/Pandoc/Writers/Jira.hs b/src/Text/Pandoc/Writers/Jira.hs index ad0640eb7ccb..b2de757c7b76 100644 --- a/src/Text/Pandoc/Writers/Jira.hs +++ b/src/Text/Pandoc/Writers/Jira.hs @@ -28,7 +28,7 @@ import Text.Pandoc.Options (WriterOptions (writerTemplate, writerWrapText), import Text.Pandoc.Shared (linesToPara, stringify) import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Math (texMathToInlines) -import Text.Pandoc.Writers.Shared (defField, metaToContext, toLegacyTable) +import Text.Pandoc.Writers.Shared (defField, metaToContext, toLegacyTable, unwrapWrapperDiv) import Text.DocLayout (literal, render) import qualified Data.Text as T import qualified Text.Jira.Markup as Jira @@ -93,7 +93,9 @@ toJiraBlocks blocks = do <$> toJiraItems items CodeBlock attr cs -> toJiraCode attr cs DefinitionList items -> toJiraDefinitionList items - Div attr bs -> toJiraPanel attr bs + Div attr bs -> case unwrapWrapperDiv (Div attr bs) of + Para inlines -> singleton . Jira.Para <$> toJiraInlines inlines + _ -> toJiraPanel attr bs Header lvl attr xs -> toJiraHeader lvl attr xs HorizontalRule -> return . singleton $ Jira.HorizontalRule LineBlock xs -> toJiraBlocks [linesToPara xs] diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs index f9261eb877c4..7627c4ae168a 100644 --- a/src/Text/Pandoc/Writers/LaTeX.hs +++ b/src/Text/Pandoc/Writers/LaTeX.hs @@ -374,42 +374,46 @@ blockToLaTeX (Div (identifier@(T.uncons -> Just (_,_)),dclasses,dkvs) -- move identifier from div to header blockToLaTeX (Div ("",dclasses,dkvs) (Header lvl (identifier,hclasses,hkvs) ils : bs)) -blockToLaTeX (Div (identifier,classes,kvs) bs) = do - beamer <- gets stBeamer - oldIncremental <- gets stIncremental - if beamer && "incremental" `elem` classes - then modify $ \st -> st{ stIncremental = True } - else when (beamer && "nonincremental" `elem` classes) $ - modify $ \st -> st { stIncremental = False } - result <- if (identifier == "refs" || -- <- for backwards compatibility - "csl-bib-body" `elem` classes) && - (not (null bs)) - then do - modify $ \st -> st{ stHasCslRefs = True } - inner <- blockListToLaTeX bs - return $ ("\\begin{CSLReferences}" - <> braces - (if "hanging-indent" `elem` classes - then "1" - else "0") - <> braces - (maybe "1" literal (lookup "entry-spacing" kvs))) - $$ inner - $+$ "\\end{CSLReferences}" - else blockListToLaTeX bs - modify $ \st -> st{ stIncremental = oldIncremental } - let wrap txt - | beamer && "notes" `elem` classes - = pure ("\\note" <> braces txt) -- speaker notes - | "ref-" `T.isPrefixOf` identifier - = do - lab <- toLabel identifier - pure $ ("\\bibitem" <> brackets "\\citeproctext" - <> braces (literal lab)) $$ txt - | otherwise = do - linkAnchor <- hypertarget identifier - pure $ linkAnchor $$ txt - wrapDiv (identifier,classes,kvs) result >>= wrap +blockToLaTeX divBlock@(Div (identifier,classes,kvs) bs) = do + -- First try to unwrap wrapper divs + case unwrapWrapperDiv divBlock of + Para inlines -> blockToLaTeX (Para inlines) + _ -> do + beamer <- gets stBeamer + oldIncremental <- gets stIncremental + if beamer && "incremental" `elem` classes + then modify $ \st -> st{ stIncremental = True } + else when (beamer && "nonincremental" `elem` classes) $ + modify $ \st -> st { stIncremental = False } + result <- if (identifier == "refs" || -- <- for backwards compatibility + "csl-bib-body" `elem` classes) && + (not (null bs)) + then do + modify $ \st -> st{ stHasCslRefs = True } + inner <- blockListToLaTeX bs + return $ ("\\begin{CSLReferences}" + <> braces + (if "hanging-indent" `elem` classes + then "1" + else "0") + <> braces + (maybe "1" literal (lookup "entry-spacing" kvs))) + $$ inner + $+$ "\\end{CSLReferences}" + else blockListToLaTeX bs + modify $ \st -> st{ stIncremental = oldIncremental } + let wrap txt + | beamer && "notes" `elem` classes + = pure ("\\note" <> braces txt) -- speaker notes + | "ref-" `T.isPrefixOf` identifier + = do + lab <- toLabel identifier + pure $ ("\\bibitem" <> brackets "\\citeproctext" + <> braces (literal lab)) $$ txt + | otherwise = do + linkAnchor <- hypertarget identifier + pure $ linkAnchor $$ txt + wrapDiv (identifier,classes,kvs) result >>= wrap blockToLaTeX (Plain lst) = inlineListToLaTeX lst -- . . . indicates pause in beamer slides diff --git a/src/Text/Pandoc/Writers/Man.hs b/src/Text/Pandoc/Writers/Man.hs index 23eff037fc79..c549c841e5f9 100644 --- a/src/Text/Pandoc/Writers/Man.hs +++ b/src/Text/Pandoc/Writers/Man.hs @@ -113,7 +113,7 @@ blockToMan :: PandocMonad m => WriterOptions -- ^ Options -> Block -- ^ Block element -> StateT WriterState m (Doc Text) -blockToMan opts (Div _ bs) = blockListToMan opts bs +blockToMan opts (Div _ bs) = blockListToMan opts (map unwrapWrapperDiv bs) blockToMan opts (Plain inlines) = splitSentences <$> inlineListToMan opts inlines blockToMan opts (Para inlines) = do diff --git a/src/Text/Pandoc/Writers/Markdown.hs b/src/Text/Pandoc/Writers/Markdown.hs index 476b54286821..76c9c318959c 100644 --- a/src/Text/Pandoc/Writers/Markdown.hs +++ b/src/Text/Pandoc/Writers/Markdown.hs @@ -386,43 +386,48 @@ blockToMarkdown' opts (Div attrs@(_,classes,_) bs) "important" -> "[!IMPORTANT]\n" _ -> "[!NOTE]\n") : ils)) : bs' | otherwise = do - contents <- blockListToMarkdown opts bs - variant <- asks envVariant - return $ - case () of - _ | variant == Markua -> - case () of - () | "blurb" `elem` classes' - -> prefixed "B> " contents <> blankline - | "aside" `elem` classes' - -> prefixed "A> " contents <> blankline - -- necessary to enable option to create a bibliography - | (take 3 (T.unpack id')) == "ref" - -> contents <> blankline - | otherwise -> contents <> blankline - | isEnabled Ext_fenced_divs opts -> - let attrsToMd = if variant == Commonmark - then attrsToMarkdown opts - else classOrAttrsToMarkdown opts - divNesting = computeDivNestingLevel bs - numcolons = 3 + divNesting - colons = literal $ T.replicate numcolons ":" - in nowrap (colons <+> attrsToMd attrs) $$ - chomp contents $$ - colons <> blankline - | isEnabled Ext_native_divs opts || - (isEnabled Ext_raw_html opts && - (variant == Commonmark || - isEnabled Ext_markdown_in_html_blocks opts)) -> - tagWithAttrs "div" attrs <> blankline <> - contents <> blankline <> "
This is a paragraph.
" =?> + doc (divWith ("mypara", ["important"], [("wrapper", "1")]) (para (text "This is a paragraph."))) + , test htmlNativeDivs "paragraph with id only" $ + "This is a paragraph.
" =?> + doc (divWith ("mypara", [], [("wrapper", "1")]) (para (text "This is a paragraph."))) + , test htmlNativeDivs "paragraph with class only" $ + "This is a paragraph.
" =?> + doc (divWith ("", ["important"], [("wrapper", "1")]) (para (text "This is a paragraph."))) + , test htmlNativeDivs "paragraph with multiple classes" $ + "This is a paragraph.
" =?> + doc (divWith ("", ["important", "urgent"], [("wrapper", "1")]) (para (text "This is a paragraph."))) + , test htmlNativeDivs "paragraph with key-value attributes" $ + "This is a paragraph.
" =?> + doc (divWith ("", [], [("wrapper", "1"), ("foo", "bar")]) (para (text "This is a paragraph."))) + , test htmlNativeDivs "paragraph without attributes" $ + "This is a normal paragraph.
" =?> + doc (para (text "This is a normal paragraph.")) + , test htmlNativeDivs "paragraph with align only (center)" $ + "Aligned paragraph.
" =?> + doc (divWith ("", [], [("wrapper", "1"), ("align", "center")]) (para (text "Aligned paragraph."))) + , test htmlNativeDivs "paragraph with align only (right)" $ + "Aligned paragraph.
" =?> + doc (divWith ("", [], [("wrapper", "1"), ("align", "right")]) (para (text "Aligned paragraph."))) + , test htmlNativeDivs "paragraph with align and id" $ + "Aligned paragraph with id.
" =?> + doc (divWith ("foo", [], [("wrapper", "1"), ("align", "left")]) (para (text "Aligned paragraph with id."))) + , test htmlNativeDivs "paragraph with align and class" $ + "" =?> + doc (divWith ("", ["bar"], [("wrapper", "1"), ("align", "justify")]) (para (text "Aligned paragraph with class."))) + , test htmlNativeDivs "paragraph with invalid align" $ + "Invalid align.
" =?> + doc (divWith ("", [], [("wrapper", "1"), ("align", "invalid")]) (para (text "Invalid align."))) + , test htmlNativeDivs "paragraph with invalid align and id" $ + "Invalid align with id.
" =?> + doc (divWith ("baz", [], [("wrapper", "1"), ("align", "invalid")]) (para (text "Invalid align with id."))) + ] , askOption $ \(QuickCheckTests numtests) -> testProperty "Round trip" $ withMaxSuccess (if QuickCheckTests numtests == defaultValue diff --git a/test/Tests/Writers/HTML.hs b/test/Tests/Writers/HTML.hs index ea313b862ea7..1342d082656f 100644 --- a/test/Tests/Writers/HTML.hs +++ b/test/Tests/Writers/HTML.hs @@ -16,11 +16,17 @@ htmlWithOpts opts = unpack . purely (writeHtml4String opts{ writerWrapText = Wra html :: (ToPandoc a) => a -> String html = htmlWithOpts def +htmlWithParaAttrs :: (ToPandoc a) => a -> String +htmlWithParaAttrs = htmlWithOpts def{ writerExtensions = enableExtension Ext_paragraph_attributes (writerExtensions def) } + htmlQTags :: (ToPandoc a) => a -> String htmlQTags = unpack . purely (writeHtml4String def{ writerWrapText = WrapNone, writerHtmlQTags = True }) . toPandoc +html5WithParaAttrs :: (ToPandoc a) => a -> String +html5WithParaAttrs = unpack . purely (writeHtml5String def{ writerWrapText = WrapNone, writerExtensions = enableExtension Ext_paragraph_attributes (writerExtensions def) }) . toPandoc + {- "my test" =: X =?> Y @@ -208,6 +214,35 @@ tests = , "" ] ] + , testGroup "paragraph attributes" + [ test htmlWithParaAttrs "paragraph with id and class" $ + (divWith ("mypara", ["important"], [("wrapper", "1")]) (para (text "This is a paragraph.")) + , "This is a paragraph.
" :: String) + , test htmlWithParaAttrs "paragraph with id only" $ + (divWith ("mypara", [], [("wrapper", "1")]) (para (text "This is a paragraph.")) + , "This is a paragraph.
" :: String) + , test htmlWithParaAttrs "paragraph with class only" $ + (divWith ("", ["important"], [("wrapper", "1")]) (para (text "This is a paragraph.")) + , "This is a paragraph.
" :: String) + , test htmlWithParaAttrs "paragraph with multiple classes" $ + (divWith ("", ["important", "urgent"], [("wrapper", "1")]) (para (text "This is a paragraph.")) + , "This is a paragraph.
" :: String) + , test html5WithParaAttrs "paragraph with key-value attributes" $ + (divWith ("", [], [("wrapper", "1"), ("foo", "bar")]) (para (text "This is a paragraph.")) + , "This is a paragraph.
" :: String) + , "paragraph without wrapper attribute" =: + divWith ("mydiv", ["someclass"], []) (para (text "This is a div, not a p.")) + =?> "This is a div, not a p.
\nThis is a paragraph.
" :: String) + , test htmlWithParaAttrs "paragraph with wrapper and align" $ + (divWith ("mypara", [], [("wrapper", "1"), ("align", "center")]) (para (text "Aligned paragraph.")) + , "Aligned paragraph.
" :: String) + , test html "paragraph with wrapper (extension disabled)" $ + (divWith ("mypara", ["important"], [("wrapper", "1")]) (para (text "This is a paragraph.")) + , "This is a paragraph.
" :: String) + ] ] where tQ :: (ToString a, ToPandoc a) diff --git a/test/command/10768/asciidoc.md b/test/command/10768/asciidoc.md new file mode 100644 index 000000000000..37979814db7d --- /dev/null +++ b/test/command/10768/asciidoc.md @@ -0,0 +1,89 @@ +Test for AsciiDoc writer - HTML with attributed paragraph should unwrap wrapper div: + +``` +% pandoc -f html -t asciidoc + +^D +This is a paragraph with attributes. + +``` + +Test for AsciiDoc writer - Native AST with wrapper div should unwrap to simple paragraph: + +``` +% pandoc -f native -t asciidoc +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D +This is a paragraph with attributes. + +``` + +Test for AsciiDoc writer - wrapper div with multiple blocks should not be unwrapped: + +``` +% pandoc -f native -t asciidoc +[ Div + ( "test" + , [ "foo" ] + , [ ( "wrapper" , "1" ) ] + ) + [ Para + [ Str "First" + , Space + , Str "paragraph" + ] + , Para + [ Str "Second" + , Space + , Str "paragraph" + ] + ] +] +^D +[[test]] +First paragraph + +Second paragraph + +``` + +Test for AsciiDoc writer - normal div without wrapper attribute should not be unwrapped: + +``` +% pandoc -f native -t asciidoc +[ Div + ( "test" + , [ "foo" ] + , [ ( "custom" , "value" ) ] + ) + [ Para + [ Str "Not" + , Space + , Str "a" + , Space + , Str "wrapper" + ] + ] +] +^D +[[test]] +Not a wrapper diff --git a/test/command/10768/basic.md b/test/command/10768/basic.md new file mode 100644 index 000000000000..922aa6d69403 --- /dev/null +++ b/test/command/10768/basic.md @@ -0,0 +1,196 @@ +% pandoc -f html -t native + +^D +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +``` + +``` +% pandoc -f native -t html+paragraph_attributes +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D + +``` + +``` +% pandoc -f html+paragraph_attributes -t html+paragraph_attributes + +^D + +``` + +``` +% pandoc -f html+paragraph_attributes -t html5+paragraph_attributes + +^D + +``` + +``` +% pandoc --list-extensions=html | grep paragraph_attributes +^D +-paragraph_attributes +``` + +``` +% pandoc --list-extensions=html5 | grep paragraph_attributes +^D +-paragraph_attributes +``` + +``` +% pandoc --list-extensions | grep paragraph_attributes +^D +=> 1 +``` + +``` +% pandoc --list-extensions=markdown | grep paragraph_attributes +^D +=> 1 +``` + +``` +% pandoc -f native -t html+paragraph_attributes +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D + +``` + +``` +% pandoc -f native -t html-paragraph_attributes +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D +This is a paragraph with attributes.
+``` + +``` +% pandoc -f native -t html5+paragraph_attributes +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D + +``` + +``` +% pandoc -f native -t html5-paragraph_attributes +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D +This is a paragraph with attributes.
diff --git a/test/command/10768/commonmark.md b/test/command/10768/commonmark.md new file mode 100644 index 000000000000..9a518b98fc2a --- /dev/null +++ b/test/command/10768/commonmark.md @@ -0,0 +1,92 @@ +Test for CommonMark writer - HTML with attributed paragraph should unwrap wrapper div: + +``` +% pandoc -f html -t commonmark + +^D +This is a paragraph with attributes. +``` + +Test for CommonMark writer - Native AST with wrapper div should unwrap to simple paragraph: + +``` +% pandoc -f native -t commonmark +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D +This is a paragraph with attributes. +``` + +Test for CommonMark writer - wrapper div with multiple blocks should not be unwrapped: + +``` +% pandoc -f native -t commonmark +[ Div + ( "test" + , [ "foo" ] + , [ ( "wrapper" , "1" ) ] + ) + [ Para + [ Str "First" + , Space + , Str "paragraph" + ] + , Para + [ Str "Second" + , Space + , Str "paragraph" + ] + ] +] +^D +This is a paragraph with attributes.
This is a paragraph with attributes.
First paragraph
Second paragraph
Not a wrapper
Normal paragraph
+``` + +``` +% pandoc -f native -t html +[ Div + ( "test" + , [ "foo" ] + , [ ( "custom" , "value" ) ] + ) + [ Para + [ Str "Not" + , Space + , Str "a" + , Space + , Str "wrapper" + ] + ] +] +^D +Not a wrapper
+First paragraph
+Second paragraph
+This is a paragraph with attributes.
+``` + +Test for JATS writer - Native AST with wrapper div should unwrap to simple paragraph: + +``` +% pandoc -f native -t jats +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D +This is a paragraph with attributes.
+``` + +Test for JATS writer - wrapper div with multiple blocks should not be unwrapped: + +``` +% pandoc -f native -t jats +[ Div + ( "test" + , [ "foo" ] + , [ ( "wrapper" , "1" ) ] + ) + [ Para + [ Str "First" + , Space + , Str "paragraph" + ] + , Para + [ Str "Second" + , Space + , Str "paragraph" + ] + ] +] +^D +First paragraph
+Second paragraph
+Not a wrapper
+This is a paragraph with attributes.
+``` + +Test for TEI writer - Native AST with wrapper div should unwrap to simple paragraph: + +``` +% pandoc -f native -t tei +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D +This is a paragraph with attributes.
+``` + +Test for TEI writer - wrapper div with multiple blocks should not be unwrapped: + +``` +% pandoc -f native -t tei +[ Div + ( "test" + , [ "foo" ] + , [ ( "wrapper" , "1" ) ] + ) + [ Para + [ Str "First" + , Space + , Str "paragraph" + ] + , Para + [ Str "Second" + , Space + , Str "paragraph" + ] + ] +] +^D +First paragraph
+Second paragraph
+``` + +Test for TEI writer - normal div without wrapper attribute should not be unwrapped: + +``` +% pandoc -f native -t tei +[ Div + ( "test" + , [ "foo" ] + , [ ( "custom" , "value" ) ] + ) + [ Para + [ Str "Not" + , Space + , Str "a" + , Space + , Str "wrapper" + ] + ] +] +^D +Not a wrapper
diff --git a/test/command/10768/texinfo.md b/test/command/10768/texinfo.md new file mode 100644 index 000000000000..5110b4c30145 --- /dev/null +++ b/test/command/10768/texinfo.md @@ -0,0 +1,96 @@ +Test for Texinfo writer - HTML with attributed paragraph should unwrap wrapper div: + +``` +% pandoc -f html -t texinfo + +^D +@node Top +@top Top + +This is a paragraph with attributes. +``` + +Test for Texinfo writer - Native AST with wrapper div should unwrap to simple paragraph: + +``` +% pandoc -f native -t texinfo +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D +@node Top +@top Top + +This is a paragraph with attributes. +``` + +Test for Texinfo writer - wrapper div with multiple blocks should not be unwrapped: + +``` +% pandoc -f native -t texinfo +[ Div + ( "test" + , [ "foo" ] + , [ ( "wrapper" , "1" ) ] + ) + [ Para + [ Str "First" + , Space + , Str "paragraph" + ] + , Para + [ Str "Second" + , Space + , Str "paragraph" + ] + ] +] +^D +@node Top +@top Top + +First paragraph + +Second paragraph +``` + +Test for Texinfo writer - normal div without wrapper attribute should not be unwrapped: + +``` +% pandoc -f native -t texinfo +[ Div + ( "test" + , [ "foo" ] + , [ ( "custom" , "value" ) ] + ) + [ Para + [ Str "Not" + , Space + , Str "a" + , Space + , Str "wrapper" + ] + ] +] +^D +@node Top +@top Top + +Not a wrapper diff --git a/test/command/10768/textile.md b/test/command/10768/textile.md new file mode 100644 index 000000000000..015778d8e965 --- /dev/null +++ b/test/command/10768/textile.md @@ -0,0 +1,89 @@ +Test for Textile writer - HTML with attributed paragraph should unwrap wrapper div: + +``` +% pandoc -f html -t textile + +^D +This is a paragraph with attributes. +``` + +Test for Textile writer - Native AST with wrapper div should unwrap to simple paragraph: + +``` +% pandoc -f native -t textile +[ Div + ( "test" + , [ "foo" , "bar" ] + , [ ( "wrapper" , "1" ) , ( "custom" , "value" ) ] + ) + [ Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "a" + , Space + , Str "paragraph" + , Space + , Str "with" + , Space + , Str "attributes." + ] + ] +] +^D +This is a paragraph with attributes. +``` + +Test for Textile writer - wrapper div with multiple blocks should be unwrapped: + +``` +% pandoc -f native -t textile +[ Div + ( "test" + , [ "foo" ] + , [ ( "wrapper" , "1" ) ] + ) + [ Para + [ Str "First" + , Space + , Str "paragraph" + ] + , Para + [ Str "Second" + , Space + , Str "paragraph" + ] + ] +] +^D +First paragraph + +Second paragraph +``` + +Test for Textile writer - normal div without wrapper attribute should not be unwrapped: + +``` +% pandoc -f native -t textile +[ Div + ( "test" + , [ "foo" ] + , [ ( "custom" , "value" ) ] + ) + [ Para + [ Str "Not" + , Space + , Str "a" + , Space + , Str "wrapper" + ] + ] +] +^D +