Skip to content

Commit 6592dfb

Browse files
authored
pptx writer: Handle reference doc without slides (#11310)
An empty `sldIdLst` is now added if the reference doc is missing one so that `modifySldIdLst` can replace it. To ensure PowerPoint doesn't say that the file will need fixing, the `sldIdLst` has to be placed after the `sldMasterIdLst`. I also added a test to ensure that if there are notes, they will be placed between the `sldMasterIdLst` and `sldIdLst`. Otherwise PowerPoint wouldn't show the slide of a note when viewing Notes Pages. Closes #7536.
1 parent 176d9be commit 6592dfb

File tree

7 files changed

+129
-14
lines changed

7 files changed

+129
-14
lines changed

src/Text/Pandoc/Writers/Powerpoint/Output.hs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,7 @@ getDefaultTableStyle = do
14171417
graphicToElement :: PandocMonad m => Integer -> Graphic -> P m Element
14181418
graphicToElement tableWidth (Tbl widths tblPr hdrCells rows) = do
14191419
let totalWidth = sum widths
1420-
let colWidths = if any (== 0.0) widths
1420+
let colWidths = if 0.0 `elem` widths
14211421
then if null hdrCells
14221422
then case rows of
14231423
r@(_:_) : _ -> replicate (length r) $
@@ -2444,7 +2444,10 @@ presentationToSldIdLst ::
24442444
P m Element
24452445
presentationToSldIdLst minimumSlideRId (Presentation _ slides) = do
24462446
ids <- mapM (slideToSldIdElement minimumSlideRId) slides
2447-
return $ mknode "p:sldIdLst" [] ids
2447+
return $ mkNodeSldIdLst ids
2448+
2449+
mkNodeSldIdLst :: [Element] -> Element
2450+
mkNodeSldIdLst = mknode "p:sldIdLst" []
24482451

24492452
presentationToPresentationElement ::
24502453
PandocMonad m =>
@@ -2459,10 +2462,9 @@ presentationToPresentationElement presentationUpdateRIdData pres = do
24592462
sldIdLst <- presentationToSldIdLst minSlideRId pres
24602463

24612464
let modifySldIdLst :: Content -> Content
2462-
modifySldIdLst (Elem e) = case elName e of
2463-
(QName "sldIdLst" _ _) -> Elem sldIdLst
2464-
_ -> Elem e
2465-
modifySldIdLst ct = ct
2465+
modifySldIdLst ct = if isSldIdLst ct
2466+
then Elem sldIdLst
2467+
else ct
24662468

24672469
notesMasterRId = maxSlideRId
24682470

@@ -2488,15 +2490,9 @@ presentationToPresentationElement presentationUpdateRIdData pres = do
24882490
removeUnwantedMaster :: [Content] -> [Content]
24892491
removeUnwantedMaster = concatMap removeUnwantedMaster'
24902492

2491-
insertNotesMaster' :: Content -> [Content]
2492-
insertNotesMaster' (Elem e) = case elName e of
2493-
(QName "sldMasterIdLst" _ _) -> [Elem e, Elem notesMasterElem]
2494-
_ -> [Elem e]
2495-
insertNotesMaster' ct = [ct]
2496-
24972493
insertNotesMaster :: [Content] -> [Content]
24982494
insertNotesMaster = if presHasSpeakerNotes pres
2499-
then concatMap insertNotesMaster'
2495+
then insertAfterSldMasterIdLst notesMasterElem
25002496
else id
25012497

25022498
updateRIds :: Content -> Content
@@ -2516,10 +2512,33 @@ presentationToPresentationElement presentationUpdateRIdData pres = do
25162512
let newValue = updatePresentationRId presentationUpdateRIdData oldValue
25172513
pure attr {attrVal = "rId" <> T.pack (show newValue)}
25182514

2515+
-- if there is no sldIdLst in the presentation.xml file, add an empty one
2516+
-- after the sldMasterIdLst so modifySldIdLst can replace it.
2517+
2518+
insertSldIdListIfMissing :: [Content] -> [Content]
2519+
insertSldIdListIfMissing contentList = if any isSldIdLst contentList
2520+
then contentList
2521+
else insertAfterSldMasterIdLst (mkNodeSldIdLst []) contentList
2522+
2523+
insertAfterSldMasterIdLst' :: Content -> Content -> [Content]
2524+
insertAfterSldMasterIdLst' newElement ct = if isElemName "sldMasterIdLst" ct
2525+
then [ct, newElement]
2526+
else [ct]
2527+
2528+
insertAfterSldMasterIdLst :: Element -> [Content] -> [Content]
2529+
insertAfterSldMasterIdLst newElement = concatMap $ insertAfterSldMasterIdLst' $ Elem newElement
2530+
2531+
isElemName :: T.Text -> Content -> Bool
2532+
isElemName name (Elem e) = qName (elName e) == name
2533+
isElemName _ _ = False
2534+
2535+
isSldIdLst :: Content -> Bool
2536+
isSldIdLst = isElemName "sldIdLst"
2537+
25192538
newContent = insertNotesMaster $
25202539
removeUnwantedMaster $
25212540
(modifySldIdLst . updateRIds) <$>
2522-
elContent element
2541+
insertSldIdListIfMissing (elContent element)
25232542

25242543
return $ element{elContent = newContent}
25252544

test/Tests/Writers/Powerpoint.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,5 +276,17 @@ tests = let
276276
def {writerReferenceDoc = Just "pptx/reference-deleted-layouts.pptx"}
277277
"pptx/layouts/input.native"
278278
"pptx/layouts/deleted.pptx"
279+
, ooxmlTest
280+
writePowerpoint
281+
"Slides can be missing from the reference doc"
282+
def {writerReferenceDoc = Just "pptx/reference-no-slides.pptx"}
283+
"pptx/reference-no-slides/add-slides/input.native"
284+
"pptx/reference-no-slides/add-slides/output.pptx"
285+
, ooxmlTest
286+
writePowerpoint
287+
"Notes are placed at the right position with a reference doc without slides"
288+
def {writerReferenceDoc = Just "pptx/reference-no-slides.pptx"}
289+
"pptx/reference-no-slides/with-notes/input.native"
290+
"pptx/reference-no-slides/with-notes/output.pptx"
279291
]
280292
in regularTests <> referenceSpecificTests

test/pptx/reference-no-slides.pptx

30.3 KB
Binary file not shown.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[ Header
2+
2
3+
( "first-slide" , [] , [] )
4+
[ Str "First" , Space , Str "Slide" ]
5+
, Para [ Str "Title" ]
6+
, Header
7+
2
8+
( "second-slide" , [] , [] )
9+
[ Str "Second" , Space , Str "Slide" ]
10+
, BulletList
11+
[ [ Plain [ Str "First" , Space , Str "item" ] ]
12+
, [ Plain [ Str "Second" , Space , Str "item" ] ]
13+
]
14+
]
28.2 KB
Binary file not shown.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
[ Header
2+
2
3+
( "first-slide" , [] , [] )
4+
[ Str "First" , Space , Str "Slide" ]
5+
, Para
6+
[ Str "First"
7+
, Space
8+
, Str "slide"
9+
, Space
10+
, Str "with"
11+
, Space
12+
, Str "notes"
13+
]
14+
, Div
15+
( "" , [ "notes" ] , [] )
16+
[ Para
17+
[ Str "Notes"
18+
, Space
19+
, Str "for"
20+
, Space
21+
, Str "the"
22+
, Space
23+
, Str "first"
24+
, Space
25+
, Str "slide"
26+
]
27+
]
28+
, Header
29+
2
30+
( "second-slide" , [] , [] )
31+
[ Str "Second" , Space , Str "Slide" ]
32+
, Para
33+
[ Str "Slide"
34+
, Space
35+
, Str "without"
36+
, Space
37+
, Str "notes"
38+
]
39+
, Header
40+
2
41+
( "third-slide" , [] , [] )
42+
[ Str "Third" , Space , Str "Slide" ]
43+
, Para
44+
[ Str "Slide"
45+
, Space
46+
, Str "with"
47+
, Space
48+
, Str "notes"
49+
, Space
50+
, Str "again"
51+
]
52+
, BulletList
53+
[ [ Plain [ Str "First" , Space , Str "item" ] ]
54+
, [ Plain [ Str "Second" , Space , Str "item" ] ]
55+
]
56+
, Div
57+
( "" , [ "notes" ] , [] )
58+
[ Para
59+
[ Str "Notes"
60+
, Space
61+
, Str "for"
62+
, Space
63+
, Str "the"
64+
, Space
65+
, Str "third"
66+
, Space
67+
, Str "slides"
68+
]
69+
]
70+
]
33.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)