git.iko.soy/typeable/pandoc
on master help sign in
Add `empty_paragraphs` extension.
ae60e01John MacFarlane
MANUAL.txt+8−1
@@ -429,7 +429,8 @@ Reader options
429
429
430`--strip-empty-paragraphs`
430`--strip-empty-paragraphs`
431
431
432+: *Deprecated. Use the `+empty_paragraphs` extension instead.*
432−: Ignore paragraphs with non content. This option is useful
433+ Ignore paragraphs with no content. This option is useful
433 for converting word processing documents where users have
434 for converting word processing documents where users have
434 used empty paragraphs to create inter-paragraph space.
435 used empty paragraphs to create inter-paragraph space.
435
436
@@ -3817,6 +3818,12 @@ in several respects:
3817 we must either disallow lazy wrapping or require a blank line between
3818 we must either disallow lazy wrapping or require a blank line between
3818 list items.
3819 list items.
3819
3820
3821+#### Extension: `empty_paragraphs` ####
3822+
3823+Allows empty paragraphs. By default empty paragraphs are
3824+omitted. This affects the `docx` reader and writer, the
3825+`opendocument` and `odt` writer, and all HTML-based readers and writers.
3826+
3820Markdown variants
3827Markdown variants
3821-----------------
3828-----------------
3822
3829
src/Text/Pandoc/App.hs+11−8
@@ -947,7 +947,10 @@ options =
947
947
948 , Option "" ["strip-empty-paragraphs"]
948 , Option "" ["strip-empty-paragraphs"]
949 (NoArg
949 (NoArg
950+ (\opt -> do
951+ deprecatedOption "--stripEmptyParagraphs"
952+ "Use +empty_paragraphs extension."
950− (\opt -> return opt{ optStripEmptyParagraphs = True }))
953+ return opt{ optStripEmptyParagraphs = True }))
951 "" -- "Strip empty paragraphs"
954 "" -- "Strip empty paragraphs"
952
955
953 , Option "" ["indented-code-classes"]
956 , Option "" ["indented-code-classes"]
@@ -1472,7 +1475,7 @@ options =
1472 , Option "m" ["latexmathml", "asciimathml"]
1475 , Option "m" ["latexmathml", "asciimathml"]
1473 (OptArg
1476 (OptArg
1474 (\arg opt -> do
1477 (\arg opt -> do
1475− deprecatedOption "--latexmathml, --asciimathml, -m"
1478+ deprecatedOption "--latexmathml, --asciimathml, -m" ""
1476 return opt { optHTMLMathMethod = LaTeXMathML arg })
1479 return opt { optHTMLMathMethod = LaTeXMathML arg })
1477 "URL")
1480 "URL")
1478 "" -- "Use LaTeXMathML script in html output"
1481 "" -- "Use LaTeXMathML script in html output"
@@ -1480,7 +1483,7 @@ options =
1480 , Option "" ["mimetex"]
1483 , Option "" ["mimetex"]
1481 (OptArg
1484 (OptArg
1482 (\arg opt -> do
1485 (\arg opt -> do
1483− deprecatedOption "--mimetex"
1486+ deprecatedOption "--mimetex" ""
1484 let url' = case arg of
1487 let url' = case arg of
1485 Just u -> u ++ "?"
1488 Just u -> u ++ "?"
1486 Nothing -> "/cgi-bin/mimetex.cgi?"
1489 Nothing -> "/cgi-bin/mimetex.cgi?"
@@ -1491,7 +1494,7 @@ options =
1491 , Option "" ["jsmath"]
1494 , Option "" ["jsmath"]
1492 (OptArg
1495 (OptArg
1493 (\arg opt -> do
1496 (\arg opt -> do
1494− deprecatedOption "--jsmath"
1497+ deprecatedOption "--jsmath" ""
1495 return opt { optHTMLMathMethod = JsMath arg})
1498 return opt { optHTMLMathMethod = JsMath arg})
1496 "URL")
1499 "URL")
1497 "" -- "Use jsMath for HTML math"
1500 "" -- "Use jsMath for HTML math"
@@ -1499,7 +1502,7 @@ options =
1499 , Option "" ["gladtex"]
1502 , Option "" ["gladtex"]
1500 (NoArg
1503 (NoArg
1501 (\opt -> do
1504 (\opt -> do
1502− deprecatedOption "--gladtex"
1505+ deprecatedOption "--gladtex" ""
1503 return opt { optHTMLMathMethod = GladTeX }))
1506 return opt { optHTMLMathMethod = GladTeX }))
1504 "" -- "Use gladtex for HTML math"
1507 "" -- "Use gladtex for HTML math"
1505
1508
@@ -1699,9 +1702,9 @@ splitField s =
1699baseWriterName :: String -> String
1702baseWriterName :: String -> String
1700baseWriterName = takeWhile (\c -> c /= '+' && c /= '-')
1703baseWriterName = takeWhile (\c -> c /= '+' && c /= '-')
1701
1704
1702−deprecatedOption :: String -> IO ()
1705+deprecatedOption :: String -> String -> IO ()
1703−deprecatedOption o =
1706+deprecatedOption o msg =
1704− runIO (report $ Deprecated o "") >>=
1707+ runIO (report $ Deprecated o msg) >>=
1705 \r -> case r of
1708 \r -> case r of
1706 Right () -> return ()
1709 Right () -> return ()
1707 Left e -> E.throwIO e
1710 Left e -> E.throwIO e
src/Text/Pandoc/Extensions.hs+1
@@ -152,6 +152,7 @@ data Extension =
152 | Ext_old_dashes -- ^ -- = em, - before number = en
152 | Ext_old_dashes -- ^ -- = em, - before number = en
153 | Ext_spaced_reference_links -- ^ Allow space between two parts of ref link
153 | Ext_spaced_reference_links -- ^ Allow space between two parts of ref link
154 | Ext_amuse -- ^ Enable Text::Amuse extensions to Emacs Muse markup
154 | Ext_amuse -- ^ Enable Text::Amuse extensions to Emacs Muse markup
155+ | Ext_empty_paragraphs -- ^ Allow empty paragraphs
155 deriving (Show, Read, Enum, Eq, Ord, Bounded, Data, Typeable, Generic)
156 deriving (Show, Read, Enum, Eq, Ord, Bounded, Data, Typeable, Generic)
156
157
157-- | Extensions to be used with pandoc-flavored markdown.
158-- | Extensions to be used with pandoc-flavored markdown.
src/Text/Pandoc/Readers/Docx.hs+4−1
@@ -534,7 +534,10 @@ bodyPartToBlocks (Paragraph pPr parparts)
534 then do modify $ \s -> s { docxDropCap = ils' }
534 then do modify $ \s -> s { docxDropCap = ils' }
535 return mempty
535 return mempty
536 else do modify $ \s -> s { docxDropCap = mempty }
536 else do modify $ \s -> s { docxDropCap = mempty }
537+ opts <- asks docxOptions
538+ if isNull ils' && not (isEnabled Ext_empty_paragraphs opts)
539+ then return mempty
537− return $ parStyleToTransform pPr $ para ils'
540+ else return $ parStyleToTransform pPr $ para ils'
538bodyPartToBlocks (ListItem pPr numId lvl (Just levelInfo) parparts) = do
541bodyPartToBlocks (ListItem pPr numId lvl (Just levelInfo) parparts) = do
539 let
542 let
540 kvs = case levelInfo of
543 kvs = case levelInfo of
src/Text/Pandoc/Readers/HTML.hs+9−4
@@ -68,9 +68,11 @@ import Text.Pandoc.CSS (foldOrElse, pickStyleAttrProps)
68import Text.Pandoc.Definition
68import Text.Pandoc.Definition
69import Text.Pandoc.Error
69import Text.Pandoc.Error
70import Text.Pandoc.Logging
70import Text.Pandoc.Logging
71+import Text.Pandoc.Options (
71−import Text.Pandoc.Options (Extension (Ext_epub_html_exts, Ext_native_divs, Ext_native_spans, Ext_raw_html),
72+ Extension (Ext_epub_html_exts, Ext_empty_paragraphs, Ext_native_divs,
73+ Ext_native_spans, Ext_raw_html),
72− ReaderOptions (readerExtensions, readerStripComments),
74+ ReaderOptions (readerExtensions, readerStripComments),
73− extensionEnabled)
75+ extensionEnabled)
74import Text.Pandoc.Parsing hiding ((<|>))
76import Text.Pandoc.Parsing hiding ((<|>))
75import Text.Pandoc.Shared (addMetaField, crFilter, escapeURI, extractSpaces,
77import Text.Pandoc.Shared (addMetaField, crFilter, escapeURI, extractSpaces,
76 safeRead, underlineSpan)
78 safeRead, underlineSpan)
@@ -575,7 +577,10 @@ pPlain = do
575pPara :: PandocMonad m => TagParser m Blocks
577pPara :: PandocMonad m => TagParser m Blocks
576pPara = do
578pPara = do
577 contents <- trimInlines <$> pInTags "p" inline
579 contents <- trimInlines <$> pInTags "p" inline
580+ (do guardDisabled Ext_empty_paragraphs
581+ guard (B.isNull contents)
582+ return mempty)
578− return $ B.para contents
583+ <|> return (B.para contents)
579
584
580pFigure :: PandocMonad m => TagParser m Blocks
585pFigure :: PandocMonad m => TagParser m Blocks
581pFigure = try $ do
586pFigure = try $ do
src/Text/Pandoc/Writers/Docx.hs+16−13
@@ -922,19 +922,22 @@ blockToOpenXML' opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) = do
922 captionNode <- withParaProp (pCustomStyle "ImageCaption")
922 captionNode <- withParaProp (pCustomStyle "ImageCaption")
923 $ blockToOpenXML opts (Para alt)
923 $ blockToOpenXML opts (Para alt)
924 return $ mknode "w:p" [] (paraProps ++ contents) : captionNode
924 return $ mknode "w:p" [] (paraProps ++ contents) : captionNode
925−blockToOpenXML' opts (Para lst) = do
925+blockToOpenXML' opts (Para lst)
926+ | null lst && not (isEnabled Ext_empty_paragraphs opts) = return []
927+ | otherwise = do
926− isFirstPara <- gets stFirstPara
928+ isFirstPara <- gets stFirstPara
927− paraProps <- getParaProps $ case lst of
929+ paraProps <- getParaProps $ case lst of
928− [Math DisplayMath _] -> True
930+ [Math DisplayMath _] -> True
929− _ -> False
931+ _ -> False
930− bodyTextStyle <- pStyleM "Body Text"
932+ bodyTextStyle <- pStyleM "Body Text"
931− let paraProps' = case paraProps of
933+ let paraProps' = case paraProps of
934+ [] | isFirstPara -> [mknode "w:pPr" []
932− [] | isFirstPara -> [mknode "w:pPr" [] [pCustomStyle "FirstParagraph"]]
935+ [pCustomStyle "FirstParagraph"]]
933− [] -> [mknode "w:pPr" [] [bodyTextStyle]]
936+ [] -> [mknode "w:pPr" [] [bodyTextStyle]]
934− ps -> ps
937+ ps -> ps
935− modify $ \s -> s { stFirstPara = False }
938+ modify $ \s -> s { stFirstPara = False }
936− contents <- inlinesToOpenXML opts lst
939+ contents <- inlinesToOpenXML opts lst
937− return [mknode "w:p" [] (paraProps' ++ contents)]
940+ return [mknode "w:p" [] (paraProps' ++ contents)]
938blockToOpenXML' opts (LineBlock lns) = blockToOpenXML opts $ linesToPara lns
941blockToOpenXML' opts (LineBlock lns) = blockToOpenXML opts $ linesToPara lns
939blockToOpenXML' _ b@(RawBlock format str)
942blockToOpenXML' _ b@(RawBlock format str)
940 | format == Format "openxml" = return [ x | Elem x <- parseXML str ]
943 | format == Format "openxml" = return [ x | Elem x <- parseXML str ]
src/Text/Pandoc/Writers/HTML.hs+9−5
@@ -56,7 +56,7 @@ import qualified Data.Text.Lazy as TL
56import Network.HTTP (urlEncode)
56import Network.HTTP (urlEncode)
57import Network.URI (URI (..), parseURIReference, unEscapeString)
57import Network.URI (URI (..), parseURIReference, unEscapeString)
58import Numeric (showHex)
58import Numeric (showHex)
59−import Text.Blaze.Internal (customLeaf)
59+import Text.Blaze.Internal (customLeaf, MarkupM(Empty))
60import Text.Blaze.Html hiding (contents)
60import Text.Blaze.Html hiding (contents)
61import Text.Pandoc.Definition
61import Text.Pandoc.Definition
62import Text.Pandoc.Highlighting (formatHtmlBlock, formatHtmlInline, highlight,
62import Text.Pandoc.Highlighting (formatHtmlBlock, formatHtmlInline, highlight,
@@ -658,6 +658,7 @@ blockToHtml opts (Para [Image attr txt (s,'f':'i':'g':':':tit)]) =
658 figure opts attr txt (s,tit)
658 figure opts attr txt (s,tit)
659blockToHtml opts (Para lst)
659blockToHtml opts (Para lst)
660 | isEmptyRaw lst = return mempty
660 | isEmptyRaw lst = return mempty
661+ | null lst && not (isEnabled Ext_empty_paragraphs opts) = return mempty
661 | otherwise = do
662 | otherwise = do
662 contents <- inlineListToHtml opts lst
663 contents <- inlineListToHtml opts lst
663 return $ H.p contents
664 return $ H.p contents
@@ -902,8 +903,7 @@ tableItemToHtml opts tag' align' item = do
902 let tag'' = if null alignStr
903 let tag'' = if null alignStr
903 then tag'
904 then tag'
904 else tag' ! attribs
905 else tag' ! attribs
905− return $ (
906− tag'' contents) >> nl opts
906+ return $ tag'' contents >> nl opts
907
907
908toListItems :: WriterOptions -> [Html] -> [Html]
908toListItems :: WriterOptions -> [Html] -> [Html]
909toListItems opts items = map (toListItem opts) items ++ [nl opts]
909toListItems opts items = map (toListItem opts) items ++ [nl opts]
@@ -911,9 +911,13 @@ toListItems opts items = map (toListItem opts) items ++ [nl opts]
911toListItem :: WriterOptions -> Html -> Html
911toListItem :: WriterOptions -> Html -> Html
912toListItem opts item = nl opts >> H.li item
912toListItem opts item = nl opts >> H.li item
913
913
914+blockListToHtml :: PandocMonad m
914−blockListToHtml :: PandocMonad m => WriterOptions -> [Block] -> StateT WriterState m Html
915+ => WriterOptions -> [Block] -> StateT WriterState m Html
915blockListToHtml opts lst =
916blockListToHtml opts lst =
917+ (mconcat . intersperse (nl opts) . filter nonempty)
916− (mconcat . intersperse (nl opts)) <$> mapM (blockToHtml opts) lst
918+ <$> mapM (blockToHtml opts) lst
919+ where nonempty (Empty _) = False
920+ nonempty _ = True
917
921
918-- | Convert list of Pandoc inline elements to HTML.
922-- | Convert list of Pandoc inline elements to HTML.
919inlineListToHtml :: PandocMonad m => WriterOptions -> [Inline] -> StateT WriterState m Html
923inlineListToHtml :: PandocMonad m => WriterOptions -> [Inline] -> StateT WriterState m Html
src/Text/Pandoc/Writers/OpenDocument.hs+2−2
@@ -130,7 +130,6 @@ setFirstPara :: PandocMonad m => OD m ()
130setFirstPara = modify $ \s -> s { stFirstPara = True }
130setFirstPara = modify $ \s -> s { stFirstPara = True }
131
131
132inParagraphTags :: PandocMonad m => Doc -> OD m Doc
132inParagraphTags :: PandocMonad m => Doc -> OD m Doc
133−inParagraphTags d | isEmpty d = return empty
134inParagraphTags d = do
133inParagraphTags d = do
135 b <- gets stFirstPara
134 b <- gets stFirstPara
136 a <- if b
135 a <- if b
@@ -323,7 +322,8 @@ blockToOpenDocument o bs
323 else inParagraphTags =<< inlinesToOpenDocument o b
322 else inParagraphTags =<< inlinesToOpenDocument o b
324 | Para [Image attr c (s,'f':'i':'g':':':t)] <- bs
323 | Para [Image attr c (s,'f':'i':'g':':':t)] <- bs
325 = figure attr c s t
324 = figure attr c s t
326− | Para b <- bs = if null b
325+ | Para b <- bs = if null b &&
326+ not (isEnabled Ext_empty_paragraphs o)
327 then return empty
327 then return empty
328 else inParagraphTags =<< inlinesToOpenDocument o b
328 else inParagraphTags =<< inlinesToOpenDocument o b
329 | LineBlock b <- bs = blockToOpenDocument o $ linesToPara b
329 | LineBlock b <- bs = blockToOpenDocument o $ linesToPara b
test/Tests/Readers/Docx.hs+7−20
@@ -10,7 +10,6 @@ import Test.Tasty
10import Test.Tasty.HUnit
10import Test.Tasty.HUnit
11import Tests.Helpers
11import Tests.Helpers
12import Text.Pandoc
12import Text.Pandoc
13−import Text.Pandoc.Shared (stripEmptyParagraphs)
14import qualified Text.Pandoc.Class as P
13import qualified Text.Pandoc.Class as P
15import Text.Pandoc.MediaBag (MediaBag, lookupMedia, mediaDirectory)
14import Text.Pandoc.MediaBag (MediaBag, lookupMedia, mediaDirectory)
16import Text.Pandoc.UTF8 as UTF8
15import Text.Pandoc.UTF8 as UTF8
@@ -38,23 +37,20 @@ instance ToString NoNormPandoc where
38instance ToPandoc NoNormPandoc where
37instance ToPandoc NoNormPandoc where
39 toPandoc = unNoNorm
38 toPandoc = unNoNorm
40
39
41−compareOutput :: Bool
42− -> ReaderOptions
40+compareOutput :: ReaderOptions
43− -> FilePath
41+ -> FilePath
44− -> FilePath
42+ -> FilePath
45− -> IO (NoNormPandoc, NoNormPandoc)
43+ -> IO (NoNormPandoc, NoNormPandoc)
46−compareOutput strip opts docxFile nativeFile = do
44+compareOutput opts docxFile nativeFile = do
47 df <- B.readFile docxFile
45 df <- B.readFile docxFile
48 nf <- UTF8.toText <$> BS.readFile nativeFile
46 nf <- UTF8.toText <$> BS.readFile nativeFile
49 p <- runIOorExplode $ readDocx opts df
47 p <- runIOorExplode $ readDocx opts df
50 df' <- runIOorExplode $ readNative def nf
48 df' <- runIOorExplode $ readNative def nf
51− return $ (noNorm (if strip
49+ return $ (noNorm p, noNorm df')
52− then stripEmptyParagraphs p
53− else p), noNorm df')
54
50
55testCompareWithOptsIO :: ReaderOptions -> String -> FilePath -> FilePath -> IO TestTree
51testCompareWithOptsIO :: ReaderOptions -> String -> FilePath -> FilePath -> IO TestTree
56testCompareWithOptsIO opts name docxFile nativeFile = do
52testCompareWithOptsIO opts name docxFile nativeFile = do
57− (dp, np) <- compareOutput True opts docxFile nativeFile
53+ (dp, np) <- compareOutput opts docxFile nativeFile
58 return $ test id name (dp, np)
54 return $ test id name (dp, np)
59
55
60testCompareWithOpts :: ReaderOptions -> String -> FilePath -> FilePath -> TestTree
56testCompareWithOpts :: ReaderOptions -> String -> FilePath -> FilePath -> TestTree
@@ -75,11 +71,6 @@ testForWarningsWithOpts :: ReaderOptions -> String -> FilePath -> [String] -> Te
75testForWarningsWithOpts opts name docxFile expected =
71testForWarningsWithOpts opts name docxFile expected =
76 unsafePerformIO $ testForWarningsWithOptsIO opts name docxFile expected
72 unsafePerformIO $ testForWarningsWithOptsIO opts name docxFile expected
77
73
78−testCompareNoStrip :: String -> FilePath -> FilePath -> TestTree
79−testCompareNoStrip name docxFile nativeFile = unsafePerformIO $ do
80− (dp, np) <- compareOutput False defopts docxFile nativeFile
81− return $ test id name (dp, np)
82−
83-- testForWarnings :: String -> FilePath -> [String] -> TestTree
74-- testForWarnings :: String -> FilePath -> [String] -> TestTree
84-- testForWarnings = testForWarningsWithOpts defopts
75-- testForWarnings = testForWarningsWithOpts defopts
85
76
@@ -266,10 +257,6 @@ tests = [ testGroup "inlines"
266 "dropcap paragraphs"
257 "dropcap paragraphs"
267 "docx/drop_cap.docx"
258 "docx/drop_cap.docx"
268 "docx/drop_cap.native"
259 "docx/drop_cap.native"
269− , testCompareNoStrip
270− "empty paragraphs without stripping"
271− "docx/drop_cap.docx"
272− "docx/drop_cap_nostrip.native"
273 ]
260 ]
274 , testGroup "track changes"
261 , testGroup "track changes"
275 [ testCompare
262 [ testCompare
test/command/2649.md+3−6
@@ -88,20 +88,17 @@
88</tr>
88</tr>
89<tr class="even">
89<tr class="even">
90<td><p>1</p></td>
90<td><p>1</p></td>
91−<td>
92−<p><a href="Sébastien_Loeb" title="wikilink">Sébastien Loeb</a></p></td>
91+<td><p><a href="Sébastien_Loeb" title="wikilink">Sébastien Loeb</a></p></td>
93<td><p>78</p></td>
92<td><p>78</p></td>
94</tr>
93</tr>
95<tr class="odd">
94<tr class="odd">
96<td><p>2</p></td>
95<td><p>2</p></td>
97−<td>
98−<p><strong><a href="Sébastien_Ogier" title="wikilink">Sébastien Ogier</a></strong></p></td>
96+<td><p><strong><a href="Sébastien_Ogier" title="wikilink">Sébastien Ogier</a></strong></p></td>
99<td><p>38</p></td>
97<td><p>38</p></td>
100</tr>
98</tr>
101<tr class="even">
99<tr class="even">
102<td><p>10</p></td>
100<td><p>10</p></td>
103−<td>
104−<p><a href="Hannu_Mikkola" title="wikilink">Hannu Mikkola</a></p></td>
101+<td><p><a href="Hannu_Mikkola" title="wikilink">Hannu Mikkola</a></p></td>
105<td><p>18</p></td>
102<td><p>18</p></td>
106</tr>
103</tr>
107</tbody>
104</tbody>
test/command/3494.md+1−2
@@ -25,8 +25,7 @@
25<td style="text-align: left;">thank you</td>
25<td style="text-align: left;">thank you</td>
26</tr>
26</tr>
27<tr class="odd">
27<tr class="odd">
28−<td style="text-align: right;">
28+<td style="text-align: right;"><p><em>blah</em></p></td>
29−<p><em>blah</em></p></td>
30<td style="text-align: left;"><em>blah</em></td>
29<td style="text-align: left;"><em>blah</em></td>
31<td style="text-align: left;"><em>blah</em></td>
30<td style="text-align: left;"><em>blah</em></td>
32</tr>
31</tr>
test/command/empty_paragraphs.mdnew file+95
@@ -0,0 +1,95 @@
1+```
2+% pandoc -f native -t docx | pandoc -f docx -t native
3+[Para [Str "hi"], Para [], Para [], Para [Str "lo"]]
4+^D
5+[Para [Str "hi"]
6+,Para [Str "lo"]]
7+```
8+
9+```
10+% pandoc -f native -t docx+empty_paragraphs | pandoc -f docx -t native
11+[Para [Str "hi"], Para [], Para [], Para [Str "lo"]]
12+^D
13+[Para [Str "hi"]
14+,Para [Str "lo"]]
15+```
16+
17+```
18+% pandoc -f native -t docx | pandoc -f docx+empty_paragraphs -t native
19+[Para [Str "hi"], Para [], Para [], Para [Str "lo"]]
20+^D
21+[Para [Str "hi"]
22+,Para [Str "lo"]]
23+```
24+
25+```
26+% pandoc -f native -t docx+empty_paragraphs | pandoc -f docx+empty_paragraphs -t native
27+[Para [Str "hi"], Para [], Para [], Para [Str "lo"]]
28+^D
29+[Para [Str "hi"]
30+,Para []
31+,Para []
32+,Para [Str "lo"]]
33+```
34+
35+```
36+% pandoc -f native -t html5
37+[Para [Str "hi"], Para [], Para [], Para [Str "lo"]]
38+^D
39+<p>hi</p>
40+
41+
42+<p>lo</p>
43+```
44+
45+```
46+% pandoc -f native -t html5+empty_paragraphs
47+[Para [Str "hi"], Para [], Para [], Para [Str "lo"]]
48+^D
49+<p>hi</p>
50+<p></p>
51+<p></p>
52+<p>lo</p>
53+```
54+
55+```
56+% pandoc -f html+empty_paragraphs -t native
57+<p>hi</p>
58+<p></p>
59+<p></p>
60+<p>lo</p>
61+^D
62+[Para [Str "hi"]
63+,Para []
64+,Para []
65+,Para [Str "lo"]]
66+```
67+
68+```
69+% pandoc -f html -t native
70+<p>hi</p>
71+<p></p>
72+<p></p>
73+<p>lo</p>
74+^D
75+[Para [Str "hi"]
76+,Para [Str "lo"]]
77+```
78+
79+```
80+% pandoc -f native -t opendocument+empty_paragraphs
81+[Para [Str "hi"], Para [], Para [], Para [Str "lo"]]
82+^D
83+<text:p text:style-name="Text_20_body">hi</text:p>
84+<text:p text:style-name="Text_20_body"></text:p>
85+<text:p text:style-name="Text_20_body"></text:p>
86+<text:p text:style-name="Text_20_body">lo</text:p>
87+```
88+
89+```
90+% pandoc -f native -t opendocument
91+[Para [Str "hi"], Para [], Para [], Para [Str "lo"]]
92+^D
93+<text:p text:style-name="Text_20_body">hi</text:p>
94+<text:p text:style-name="Text_20_body">lo</text:p>
95+```
test/docx/0_level_headers.native+8−8
@@ -1,15 +1,15 @@
1[Table [] [AlignDefault] [0.0]
1[Table [] [AlignDefault] [0.0]
2 [[]]
2 [[]]
3− [[[Plain []]]
3+ [[[]]
4 ,[[Plain [Str "User\8217s",Space,Str "Guide"]]]
4 ,[[Plain [Str "User\8217s",Space,Str "Guide"]]]
5− ,[[Plain []]]
5+ ,[[]]
6− ,[[Plain []]]
6+ ,[[]]
7− ,[[Plain []]]
7+ ,[[]]
8 ,[[Plain [Str "11",Space,Str "August",Space,Str "2017"]]]
8 ,[[Plain [Str "11",Space,Str "August",Space,Str "2017"]]]
9− ,[[Plain []]]
9+ ,[[]]
10− ,[[Plain []]]
10+ ,[[]]
11− ,[[Plain []]]
11+ ,[[]]
12− ,[[Plain []]]]
12+ ,[[]]]
13,Para [Str "CONTENTS"]
13,Para [Str "CONTENTS"]
14,Para [Strong [Str "Section",Space,Str "Page"]]
14,Para [Strong [Str "Section",Space,Str "Page"]]
15,Para [Str "FIGURES",Space,Str "iv"]
15,Para [Str "FIGURES",Space,Str "iv"]
test/docx/comments.native+1−1
@@ -1,4 +1,4 @@
1[Para [Str "I",Space,Str "want",Space,Span ("",["comment-start"],[("id","0"),("author","Jesse Rosenthal"),("date","2016-05-09T16:13:00Z")]) [Str "I",Space,Str "left",Space,Str "a",Space,Str "comment."],Str "some",Space,Str "text",Space,Str "to",Space,Str "have",Space,Str "a",Space,Str "comment",Space,Span ("",["comment-end"],[("id","0")]) [],Str "on",Space,Str "it."]
1[Para [Str "I",Space,Str "want",Space,Span ("",["comment-start"],[("id","0"),("author","Jesse Rosenthal"),("date","2016-05-09T16:13:00Z")]) [Str "I",Space,Str "left",Space,Str "a",Space,Str "comment."],Str "some",Space,Str "text",Space,Str "to",Space,Str "have",Space,Str "a",Space,Str "comment",Space,Span ("",["comment-end"],[("id","0")]) [],Str "on",Space,Str "it."]
2,Para [Str "This",Space,Str "is",Space,Span ("",["comment-start"],[("id","1"),("author","Jesse Rosenthal"),("date","2016-05-09T16:13:00Z")]) [Str "A",Space,Str "comment",Space,Str "across",Space,Str "paragraphs."],Str "a",Space,Str "new",Space,Str "paragraph."]
2,Para [Str "This",Space,Str "is",Space,Span ("",["comment-start"],[("id","1"),("author","Jesse Rosenthal"),("date","2016-05-09T16:13:00Z")]) [Str "A",Space,Str "comment",Space,Str "across",Space,Str "paragraphs."],Str "a",Space,Str "new",Space,Str "paragraph."]
3,Para [Str "And",Space,Str "so",Span ("",["comment-end"],[("id","1")]) [],Space,Str "is",Space,Str "this."]
3,Para [Str "And",Space,Str "so",Span ("",["comment-end"],[("id","1")]) [],Space,Str "is",Space,Str "this."]
4−,Para [Str "One",Space,Span ("",["comment-start"],[("id","2"),("author","Jesse Rosenthal"),("date","2016-05-09T16:14:00Z")]) [Str "This",Space,Str "one",Space,Str "has",Space,Str "multiple",Space,Str "paragraphs.",Space,Str "\182",Space,Str "\182",Space,Str "See?"],Str "more",Span ("",["comment-end"],[("id","2")]) [],Str ".",Space,Str "And",Space,Str "this",Space,Str "is",Space,Str "one",Space,Str "with",Space,Str "a",Space,Span ("",["comment-start"],[("id","3"),("author","Jesse Rosenthal"),("date","2016-06-22T14:35:00Z")]) [Str "Do",Space,Str "something."],Span ("",["comment-start"],[("id","4"),("author","Jesse Rosenthal"),("date","2016-06-22T14:36:00Z")]) [Str "Do",Space,Str "something",Space,Str "else."],Str "comment",Space,Str "in",Space,Str "a",Space,Str "comment",Span ("",["comment-end"],[("id","3")]) [Span ("",["comment-end"],[("id","4")]) []],Str "."]]
4+,Para [Str "One",Space,Span ("",["comment-start"],[("id","2"),("author","Jesse Rosenthal"),("date","2016-05-09T16:14:00Z")]) [Str "This",Space,Str "one",Space,Str "has",Space,Str "multiple",Space,Str "paragraphs.",Space,Str "\182",Space,Str "See?"],Str "more",Span ("",["comment-end"],[("id","2")]) [],Str ".",Space,Str "And",Space,Str "this",Space,Str "is",Space,Str "one",Space,Str "with",Space,Str "a",Space,Span ("",["comment-start"],[("id","3"),("author","Jesse Rosenthal"),("date","2016-06-22T14:35:00Z")]) [Str "Do",Space,Str "something."],Span ("",["comment-start"],[("id","4"),("author","Jesse Rosenthal"),("date","2016-06-22T14:36:00Z")]) [Str "Do",Space,Str "something",Space,Str "else."],Str "comment",Space,Str "in",Space,Str "a",Space,Str "comment",Span ("",["comment-end"],[("id","3")]) [Span ("",["comment-end"],[("id","4")]) []],Str "."]]
test/docx/drop_cap_nostrip.nativedeleted−9
@@ -1,9 +0,0 @@
1−[Para [Str "Drop",Space,Str "cap."]
2−,Para []
3−,Para [Str "Next",Space,Str "paragraph."]
4−,Para []
5−,Para [Str "Drop",Space,Str "cap",Space,Str "in",Space,Str "margin."]
6−,Para []
7−,Para []
8−,Para []
9−,Para [Str "Drop",Space,Str "cap",Space,Str "(not",Space,Str "really)."]]