git.iko.soy/typeable/pandoc
on master help sign in
Powerpoint writer: Improve image handling.

We now determine image and caption placement by getting the dimensions of the content box in a given layout. This allows for images to be correctly sized and positioned in a different template. Note that iamges without captions and headers are no longer full-screened. We can't do this dependably in different layouts, because we don't know where the header is (it could be to the side of the content, for example).

commit50b64bcf1c61e21402611d50fb23609b62b5c9c2 authorJesse Rosenthal <jrosenthal@jhu.edu> dateSat 13 Jan 2018, 15:56 (9 years ago) parent2c71604
1 file changed+224−153
src/Text/Pandoc/Writers/Powerpoint.hs+224−153
src/Text/Pandoc/Writers/Powerpoint.hs+224−153
@@ -213,26 +213,6 @@ type Pixels = Integer
213213data Presentation = Presentation [Slide]
214214 deriving (Show)
215215
216−-- data PresentationSize = PresentationSize { presSizeWidth :: Pixels
217−-- , presSizeRatio :: PresentationRatio
218−-- }
219−-- deriving (Show, Eq)
220−
221−-- data PresentationRatio = Ratio4x3
222−-- | Ratio16x9
223−-- | Ratio16x10
224−-- deriving (Show, Eq)
225−
226−-- Note that right now we're only using Ratio4x3.
227−-- getPageHeight :: PresentationSize -> Pixels
228−-- getPageHeight sz = case presSizeRatio sz of
229−-- Ratio4x3 -> floor (((fromInteger (presSizeWidth sz)) / 4) * 3 :: Double)
230−-- Ratio16x9 -> floor (((fromInteger (presSizeWidth sz)) / 16) * 9 :: Double)
231−-- Ratio16x10 -> floor (((fromInteger (presSizeWidth sz)) / 16) * 10 :: Double)
232−
233−-- instance Default PresentationSize where
234−-- def = PresentationSize 720 Ratio4x3
235−
236216data Slide = MetadataSlide { metadataSlideTitle :: [ParaElem]
237217 , metadataSlideSubtitle :: [ParaElem]
238218 , metadataSlideAuthors :: [[ParaElem]]
@@ -917,12 +897,71 @@ shapeHasName ns name element
917897 nm == name
918898 | otherwise = False
919899
900+shapeHasId :: NameSpaces -> String -> Element -> Bool
901+shapeHasId ns ident element
902+ | Just nvSpPr <- findChild (elemName ns "p" "nvSpPr") element
903+ , Just cNvPr <- findChild (elemName ns "p" "cNvPr") nvSpPr
904+ , Just nm <- findAttr (QName "id" Nothing Nothing) cNvPr =
905+ nm == ident
906+ | otherwise = False
907+
920908getContentShape :: NameSpaces -> Element -> Maybe Element
921909getContentShape ns spTreeElem
922910 | isElem ns "p" "spTree" spTreeElem =
923911 filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasName ns "Content Placeholder 2" e)) spTreeElem
924912 | otherwise = Nothing
925913
914+getShapeDimensions :: NameSpaces
915+ -> Element
916+ -> Maybe ((Integer, Integer), (Integer, Integer))
917+getShapeDimensions ns element
918+ | isElem ns "p" "sp" element = do
919+ spPr <- findChild (elemName ns "p" "spPr") element
920+ xfrm <- findChild (elemName ns "a" "xfrm") spPr
921+ off <- findChild (elemName ns "a" "off") xfrm
922+ xS <- findAttr (QName "x" Nothing Nothing) off
923+ yS <- findAttr (QName "y" Nothing Nothing) off
924+ ext <- findChild (elemName ns "a" "ext") xfrm
925+ cxS <- findAttr (QName "cx" Nothing Nothing) ext
926+ cyS <- findAttr (QName "cy" Nothing Nothing) ext
927+ (x, _) <- listToMaybe $ reads xS
928+ (y, _) <- listToMaybe $ reads yS
929+ (cx, _) <- listToMaybe $ reads cxS
930+ (cy, _) <- listToMaybe $ reads cyS
931+ return $ ((x `div` 12700, y `div` 12700), (cx `div` 12700, cy `div` 12700))
932+ | otherwise = Nothing
933+
934+
935+getMasterShapeDimensionsById :: String
936+ -> Element
937+ -> Maybe ((Integer, Integer), (Integer, Integer))
938+getMasterShapeDimensionsById ident master = do
939+ let ns = elemToNameSpaces master
940+ cSld <- findChild (elemName ns "p" "cSld") master
941+ spTree <- findChild (elemName ns "p" "spTree") cSld
942+ sp <- filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasId ns ident e)) spTree
943+ getShapeDimensions ns sp
944+
945+getContentShapeSize :: NameSpaces
946+ -> Element
947+ -> Element
948+ -> Maybe ((Integer, Integer), (Integer, Integer))
949+getContentShapeSize ns layout master
950+ | isElem ns "p" "sldLayout" layout
951+ , Just cSld <- findChild (elemName ns "p" "cSld") layout
952+ , Just spTree <- findChild (elemName ns "p" "spTree") cSld
953+ , Just sp <- getContentShape ns spTree
954+ , Just sz <- getShapeDimensions ns sp = Just sz
955+ | isElem ns "p" "sldLayout" layout
956+ , Just cSld <- findChild (elemName ns "p" "cSld") layout
957+ , Just spTree <- findChild (elemName ns "p" "spTree") cSld
958+ , Just sp <- getContentShape ns spTree
959+ , Just ident <- findChild (elemName ns "p" "nvSpPr") sp >>=
960+ findChild (elemName ns "p" "cNvPr") >>=
961+ findAttr (QName "id" Nothing Nothing)
962+ , Just sz <- getMasterShapeDimensionsById ident master = Just sz
963+ | otherwise = Nothing
964+
926965replaceNamedChildren :: NameSpaces
927966 -> String
928967 -> String
@@ -1036,26 +1075,26 @@ makeMediaEntries = do
10361075 let allInfos = mconcat $ M.elems mediaInfos
10371076 mapM makeMediaEntry allInfos
10381077
1039−-- | Scales the image to fit the page
1040−-- sizes are passed in emu
1041−fitToPage' :: (Double, Double) -- image size in emu
1042− -> Integer -- pageWidth
1043− -> Integer -- pageHeight
1044− -> (Integer, Integer) -- imagesize
1045−fitToPage' (x, y) pageWidth pageHeight
1046− -- Fixes width to the page width and scales the height
1047− | x <= fromIntegral pageWidth && y <= fromIntegral pageHeight =
1048− (floor x, floor y)
1049− | x / fromIntegral pageWidth > y / fromIntegral pageWidth =
1050− (pageWidth, floor $ ((fromIntegral pageWidth) / x) * y)
1051− | otherwise =
1052− (floor $ ((fromIntegral pageHeight) / y) * x, pageHeight)
1053−
1054−positionImage :: (Double, Double) -> Integer -> Integer -> (Integer, Integer)
1055−positionImage (x, y) pageWidth pageHeight =
1056− let (x', y') = fitToPage' (x, y) pageWidth pageHeight
1057− in
1058− ((pageWidth - x') `div` 2, (pageHeight - y') `div` 2)
1078+-- -- | Scales the image to fit the page
1079+-- -- sizes are passed in emu
1080+-- fitToPage' :: (Double, Double) -- image size in emu
1081+-- -> Integer -- pageWidth
1082+-- -> Integer -- pageHeight
1083+-- -> (Integer, Integer) -- imagesize
1084+-- fitToPage' (x, y) pageWidth pageHeight
1085+-- -- Fixes width to the page width and scales the height
1086+-- | x <= fromIntegral pageWidth && y <= fromIntegral pageHeight =
1087+-- (floor x, floor y)
1088+-- | x / fromIntegral pageWidth > y / fromIntegral pageWidth =
1089+-- (pageWidth, floor $ ((fromIntegral pageWidth) / x) * y)
1090+-- | otherwise =
1091+-- (floor $ ((fromIntegral pageHeight) / y) * x, pageHeight)
1092+
1093+-- positionImage :: (Double, Double) -> Integer -> Integer -> (Integer, Integer)
1094+-- positionImage (x, y) pageWidth pageHeight =
1095+-- let (x', y') = fitToPage' (x, y) pageWidth pageHeight
1096+-- in
1097+-- ((pageWidth - x') `div` 2, (pageHeight - y') `div` 2)
10591098
10601099getMaster :: PandocMonad m => P m Element
10611100getMaster = do
@@ -1067,52 +1106,57 @@ getMaster = do
10671106-- image goes underneath it. We only use this in a content slide if it
10681107-- has a header.
10691108
1070−getHeaderSize :: PandocMonad m => P m ((Integer, Integer), (Integer, Integer))
1071−getHeaderSize = do
1072− master <- getMaster
1073− let ns = elemToNameSpaces master
1074− sps = [master] >>=
1075− findChildren (elemName ns "p" "cSld") >>=
1076− findChildren (elemName ns "p" "spTree") >>=
1077− findChildren (elemName ns "p" "sp")
1078− mbXfrm =
1079− listToMaybe (filter (shapeHasName ns "Title Placeholder 1") sps) >>=
1080− findChild (elemName ns "p" "spPr") >>=
1081− findChild (elemName ns "a" "xfrm")
1082− xoff = mbXfrm >>=
1083− findChild (elemName ns "a" "off") >>=
1084− findAttr (QName "x" Nothing Nothing) >>=
1085− (listToMaybe . (\s -> reads s :: [(Integer, String)]))
1086− yoff = mbXfrm >>=
1087− findChild (elemName ns "a" "off") >>=
1088− findAttr (QName "y" Nothing Nothing) >>=
1089− (listToMaybe . (\s -> reads s :: [(Integer, String)]))
1090− xext = mbXfrm >>=
1091− findChild (elemName ns "a" "ext") >>=
1092− findAttr (QName "cx" Nothing Nothing) >>=
1093− (listToMaybe . (\s -> reads s :: [(Integer, String)]))
1094− yext = mbXfrm >>=
1095− findChild (elemName ns "a" "ext") >>=
1096− findAttr (QName "cy" Nothing Nothing) >>=
1097− (listToMaybe . (\s -> reads s :: [(Integer, String)]))
1098− off = case xoff of
1099− Just (xoff', _) | Just (yoff',_) <- yoff -> (xoff', yoff')
1100− _ -> (1043490, 1027664)
1101− ext = case xext of
1102− Just (xext', _) | Just (yext',_) <- yext -> (xext', yext')
1103− _ -> (7024744, 1143000)
1104− return $ (off, ext)
1105−
1109+-- getHeaderSize :: PandocMonad m => P m ((Integer, Integer), (Integer, Integer))
1110+-- getHeaderSize = do
1111+-- master <- getMaster
1112+-- let ns = elemToNameSpaces master
1113+-- sps = [master] >>=
1114+-- findChildren (elemName ns "p" "cSld") >>=
1115+-- findChildren (elemName ns "p" "spTree") >>=
1116+-- findChildren (elemName ns "p" "sp")
1117+-- mbXfrm =
1118+-- listToMaybe (filter (shapeHasName ns "Title Placeholder 1") sps) >>=
1119+-- findChild (elemName ns "p" "spPr") >>=
1120+-- findChild (elemName ns "a" "xfrm")
1121+-- xoff = mbXfrm >>=
1122+-- findChild (elemName ns "a" "off") >>=
1123+-- findAttr (QName "x" Nothing Nothing) >>=
1124+-- (listToMaybe . (\s -> reads s :: [(Integer, String)]))
1125+-- yoff = mbXfrm >>=
1126+-- findChild (elemName ns "a" "off") >>=
1127+-- findAttr (QName "y" Nothing Nothing) >>=
1128+-- (listToMaybe . (\s -> reads s :: [(Integer, String)]))
1129+-- xext = mbXfrm >>=
1130+-- findChild (elemName ns "a" "ext") >>=
1131+-- findAttr (QName "cx" Nothing Nothing) >>=
1132+-- (listToMaybe . (\s -> reads s :: [(Integer, String)]))
1133+-- yext = mbXfrm >>=
1134+-- findChild (elemName ns "a" "ext") >>=
1135+-- findAttr (QName "cy" Nothing Nothing) >>=
1136+-- (listToMaybe . (\s -> reads s :: [(Integer, String)]))
1137+-- off = case xoff of
1138+-- Just (xoff', _) | Just (yoff',_) <- yoff -> (xoff', yoff')
1139+-- _ -> (1043490, 1027664)
1140+-- ext = case xext of
1141+-- Just (xext', _) | Just (yext',_) <- yext -> (xext', yext')
1142+-- _ -> (7024744, 1143000)
1143+-- return $ (off, ext)
11061144
11071145-- Hard-coded for now
1108−captionPosition :: ((Integer, Integer), (Integer, Integer))
1109−captionPosition = ((457200, 6061972), (8229600, 527087))
1146+-- captionPosition :: ((Integer, Integer), (Integer, Integer))
1147+-- captionPosition = ((457200, 6061972), (8229600, 527087))
1148+
1149+captionHeight :: Integer
1150+captionHeight = 40
11101151
1111−createCaption :: PandocMonad m => [ParaElem] -> P m Element
1112−createCaption paraElements = do
1152+createCaption :: PandocMonad m
1153+ => ((Integer, Integer), (Integer, Integer))
1154+ -> [ParaElem]
1155+ -> P m Element
1156+createCaption contentShapeDimensions paraElements = do
11131157 let para = Paragraph def{pPropAlign = Just AlgnCenter} paraElements
11141158 elements <- mapM paragraphToElement [para]
1115− let ((x, y), (cx, cy)) = captionPosition
1159+ let ((x, y), (cx, cy)) = contentShapeDimensions
11161160 let txBody = mknode "p:txBody" [] $
11171161 [mknode "a:bodyPr" [] (), mknode "a:lstStyle" [] ()] ++ elements
11181162 return $
@@ -1123,8 +1167,10 @@ createCaption paraElements = do
11231167 ]
11241168 , mknode "p:spPr" []
11251169 [ mknode "a:xfrm" []
1126− [ mknode "a:off" [("x", show x), ("y", show y)] ()
1127− , mknode "a:ext" [("cx", show cx), ("cy", show cy)] ()
1170+ [ mknode "a:off" [("x", show $ 12700 * x),
1171+ ("y", show $ 12700 * (y + cy - captionHeight))] ()
1172+ , mknode "a:ext" [("cx", show $ 12700 * cx),
1173+ ("cy", show $ 12700 * captionHeight)] ()
11281174 ]
11291175 , mknode "a:prstGeom" [("prst", "rect")]
11301176 [ mknode "a:avLst" [] ()
@@ -1134,37 +1180,41 @@ createCaption paraElements = do
11341180 , txBody
11351181 ]
11361182
1137−-- Largely lifted from inlineToOpenXML' in T.P.W.Docx. Can't be easily
1138−-- abstracted because of some different namespaces and monads. TODO.
1139−makePicElement :: PandocMonad m
1140− => PicProps
1141− -> MediaInfo
1142− -> Text.Pandoc.Definition.Attr
1143− -> P m Element
1144−makePicElement picProps mInfo attr = do
1183+makePicElements :: PandocMonad m
1184+ => Element
1185+ -> PicProps
1186+ -> MediaInfo
1187+ -> Text.Pandoc.Definition.Attr
1188+ -> [ParaElem]
1189+ -> P m [Element]
1190+makePicElements layout picProps mInfo _ alt = do
11451191 opts <- asks envOpts
11461192 (pageWidth, pageHeight) <- asks envPresentationSize
1147− hasHeader <- asks envSlideHasHeader
1193+ -- hasHeader <- asks envSlideHasHeader
11481194 let hasCaption = mInfoCaption mInfo
11491195 (imgBytes, _) <- P.fetchItem (mInfoFilePath mInfo)
1150− -- We're not using x exts
1151− ((hXoff, hYoff), (_, hYext)) <- if hasHeader
1152− then getHeaderSize
1153− else return ((0, 0), (0, 0))
1154−
1155− let ((capX, capY), (_, _)) = if hasCaption
1156− then captionPosition
1157− else ((0,0), (0,0))
1158− let (xpt,ypt) = desiredSizeInPoints opts attr
1159− (either (const def) id (imageSize opts imgBytes))
1160− -- 12700 emu = 1 pt
1161− let (xemu,yemu) = fitToPage' (xpt * 12700, ypt * 12700)
1162− ((pageWidth * 12700) - (2 * hXoff) - (2 * capX))
1163− ((if hasCaption then capY else (pageHeight * 12700)) - (hYoff + hYext))
1164− (xoff, yoff) = positionImage (xpt * 12700, ypt * 12700) (pageWidth * 12700) (pageHeight * 12700)
1165− xoff' = if hasHeader then xoff + hXoff else xoff
1166− xoff'' = if hasCaption then xoff' + capX else xoff'
1167− yoff' = if hasHeader then hYoff + hYext else yoff
1196+ let (pxX, pxY) = case imageSize opts imgBytes of
1197+ Right sz -> sizeInPixels $ sz
1198+ Left _ -> sizeInPixels $ def
1199+ master <- getMaster
1200+ let ns = elemToNameSpaces layout
1201+ let ((x, y), (cx, cytmp)) = case getContentShapeSize ns layout master of
1202+ Just dims -> dims
1203+ Nothing -> ((0, 0), (pageWidth, pageHeight))
1204+
1205+ cy = if hasCaption then cytmp - captionHeight else cytmp
1206+
1207+ let imgRatio = fromIntegral pxX / fromIntegral pxY :: Double
1208+ boxRatio = fromIntegral cx / fromIntegral cy :: Double
1209+ (dimX, dimY) = if imgRatio > boxRatio
1210+ then (fromIntegral cx, fromIntegral cx / imgRatio)
1211+ else (fromIntegral cy * imgRatio, fromIntegral cy)
1212+
1213+ (dimX', dimY') = (round dimX * 12700, round dimY * 12700) :: (Integer, Integer)
1214+ (xoff, yoff) = (fromIntegral x + (fromIntegral cx - dimX) / 2,
1215+ fromIntegral y + (fromIntegral cy - dimY) / 2)
1216+ (xoff', yoff') = (round xoff * 12700, round yoff * 12700) :: (Integer, Integer)
1217+
11681218 let cNvPicPr = mknode "p:cNvPicPr" [] $
11691219 mknode "a:picLocks" [("noGrp","1")
11701220 ,("noChangeAspect","1")] ()
@@ -1185,9 +1235,9 @@ makePicElement picProps mInfo attr = do
11851235 , mknode "a:stretch" [] $
11861236 mknode "a:fillRect" [] () ]
11871237 let xfrm = mknode "a:xfrm" []
1188− [ mknode "a:off" [("x",show xoff''), ("y",show yoff')] ()
1189− , mknode "a:ext" [("cx",show xemu)
1190− ,("cy",show yemu)] () ]
1238+ [ mknode "a:off" [("x",show xoff'), ("y",show yoff')] ()
1239+ , mknode "a:ext" [("cx",show dimX')
1240+ ,("cy",show dimY')] () ]
11911241 let prstGeom = mknode "a:prstGeom" [("prst","rect")] $
11921242 mknode "a:avLst" [] ()
11931243 let ln = mknode "a:ln" [("w","9525")]
@@ -1196,11 +1246,17 @@ makePicElement picProps mInfo attr = do
11961246 , mknode "a:tailEnd" [] () ]
11971247 let spPr = mknode "p:spPr" [("bwMode","auto")]
11981248 [xfrm, prstGeom, mknode "a:noFill" [] (), ln]
1199− return $
1200− mknode "p:pic" []
1201− [ nvPicPr
1202− , blipFill
1203− , spPr ]
1249+
1250+ let picShape = mknode "p:pic" []
1251+ [ nvPicPr
1252+ , blipFill
1253+ , spPr ]
1254+
1255+ -- And now, maybe create the caption:
1256+ if hasCaption
1257+ then do cap <- createCaption ((x, y), (cx, cytmp)) alt
1258+ return [picShape, cap]
1259+ else return [picShape]
12041260
12051261-- Currently hardcoded, until I figure out how to make it dynamic.
12061262blockQuoteSize :: Pixels
@@ -1345,44 +1401,21 @@ shapeToElement layout (TextBox paras)
13451401 replaceNamedChildren ns "p" "txBody" [txBody] $
13461402 replaceNamedChildren ns "p" "spPr" [emptySpPr] $
13471403 sp
1348− -- XXX: TODO
1349− | otherwise = return $ mknode "p:sp" [] ()
1350−-- XXX: TODO
1351−shapeToElement layout (Pic picProps fp attr alt) = do
1352− mInfo <- registerMedia fp alt
1353− case mInfoExt mInfo of
1354− Just _ -> makePicElement picProps mInfo attr
1355− Nothing -> shapeToElement layout $ TextBox [Paragraph def alt]
1356−shapeToElement _ (GraphicFrame tbls _) = do
1357− elements <- mapM graphicToElement tbls
1358− return $ mknode "p:graphicFrame" [] $
1359− [ mknode "p:nvGraphicFramePr" [] $
1360− [ mknode "p:cNvPr" [("id", "6"), ("name", "Content Placeholder 5")] ()
1361− , mknode "p:cNvGraphicFramePr" [] $
1362− [mknode "a:graphicFrameLocks" [("noGrp", "1")] ()]
1363− , mknode "p:nvPr" [] $
1364− [mknode "p:ph" [("idx", "1")] ()]
1365− ]
1366− , mknode "p:xfrm" [] $
1367− [ mknode "a:off" [("x", "457200"), ("y", "1600200")] ()
1368− , mknode "a:ext" [("cx", "8029388"), ("cy", "3644152")] ()
1369− ]
1370− ] ++ elements
1404+-- GraphicFrame and Pic should never reach this.
1405+shapeToElement _ _ = return $ mknode "p:sp" [] ()
13711406
13721407shapeToElements :: PandocMonad m => Element -> Shape -> P m [Element]
1408+shapeToElements layout (Pic picProps fp attr alt) = do
1409+ mInfo <- registerMedia fp alt
1410+ case mInfoExt mInfo of
1411+ Just _ -> do
1412+ makePicElements layout picProps mInfo attr alt
1413+ Nothing -> shapeToElements layout $ TextBox [Paragraph def alt]
1414+shapeToElements layout (GraphicFrame tbls cptn) =
1415+ graphicFrameToElements layout tbls cptn
13731416shapeToElements layout shp = do
1374− case shp of
1375− (Pic _ _ _ alt) | (not . null) alt -> do
1376− element <- shapeToElement layout shp
1377− caption <- createCaption alt
1378− return [element, caption]
1379− (GraphicFrame _ cptn) | (not . null) cptn -> do
1380− element <- shapeToElement layout shp
1381− caption <- createCaption cptn
1382− return [element, caption]
1383− _ -> do
1384− element <- shapeToElement layout shp
1385− return [element]
1417+ element <- shapeToElement layout shp
1418+ return [element]
13861419
13871420shapesToElements :: PandocMonad m => Element -> [Shape] -> P m [Element]
13881421shapesToElements layout shps = do
@@ -1391,6 +1424,38 @@ shapesToElements layout shps = do
13911424hardcodedTableMargin :: Integer
13921425hardcodedTableMargin = 36
13931426
1427+graphicFrameToElements :: PandocMonad m => Element -> [Graphic] -> [ParaElem] -> P m [Element]
1428+graphicFrameToElements layout tbls caption = do
1429+ -- get the sizing
1430+ master <- getMaster
1431+ (pageWidth, pageHeight) <- asks envPresentationSize
1432+ let ns = elemToNameSpaces layout
1433+ let ((x, y), (cx, cytmp)) = case getContentShapeSize ns layout master of
1434+ Just dims -> dims
1435+ Nothing -> ((0, 0), (pageWidth, pageHeight))
1436+
1437+ cy = if (not $ null caption) then cytmp - captionHeight else cytmp
1438+
1439+ elements <- mapM graphicToElement tbls
1440+ let graphicFrameElts =
1441+ mknode "p:graphicFrame" [] $
1442+ [ mknode "p:nvGraphicFramePr" [] $
1443+ [ mknode "p:cNvPr" [("id", "6"), ("name", "Content Placeholder 5")] ()
1444+ , mknode "p:cNvGraphicFramePr" [] $
1445+ [mknode "a:graphicFrameLocks" [("noGrp", "1")] ()]
1446+ , mknode "p:nvPr" [] $
1447+ [mknode "p:ph" [("idx", "1")] ()]
1448+ ]
1449+ , mknode "p:xfrm" [] $
1450+ [ mknode "a:off" [("x", show $ 12700 * x), ("y", show $ 12700 * y)] ()
1451+ , mknode "a:ext" [("cx", show $ 12700 * cx), ("cy", show $ 12700 * cy)] ()
1452+ ]
1453+ ] ++ elements
1454+
1455+ if (not $ null caption)
1456+ then do capElt <- createCaption ((x, y), (cx, cytmp)) caption
1457+ return [graphicFrameElts, capElt]
1458+ else return [graphicFrameElts]
13941459
13951460graphicToElement :: PandocMonad m => Graphic -> P m Element
13961461graphicToElement (Tbl tblPr colWidths hdrCells rows) = do
@@ -1437,6 +1502,12 @@ getShapeByName ns spTreeElem name
14371502 filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasName ns name e)) spTreeElem
14381503 | otherwise = Nothing
14391504
1505+-- getShapeById :: NameSpaces -> Element -> String -> Maybe Element
1506+-- getShapeById ns spTreeElem ident
1507+-- | isElem ns "p" "spTree" spTreeElem =
1508+-- filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasId ns ident e)) spTreeElem
1509+-- | otherwise = Nothing
1510+
14401511nonBodyTextToElement :: PandocMonad m => Element -> String -> [ParaElem] -> P m Element
14411512nonBodyTextToElement layout shapeName paraElements
14421513 | ns <- elemToNameSpaces layout