git.iko.soy/typeable/pandoc
on master help sign in
Docx writer: Clean up and streamline RTL behavior
be27c9cJesse Rosenthal
src/Text/Pandoc/Writers/Docx.hs+77−71
@@ -264,8 +264,14 @@ writeDocx opts doc@(Pandoc meta _) = do
264 , stTocTitle = tocTitle
264 , stTocTitle = tocTitle
265 }
265 }
266
266
267+ let isRTLmeta = case lookupMeta "dir" meta of
268+ Just (MetaString "rtl") -> True
269+ Just (MetaInlines [Str "rtl"]) -> True
270+ _ -> False
271+
267 let env = defaultWriterEnv {
272 let env = defaultWriterEnv {
273+ envRTL = isRTLmeta
268− envChangesAuthor = fromMaybe "unknown" username
274+ , envChangesAuthor = fromMaybe "unknown" username
269 , envChangesDate = formatTime defaultTimeLocale "%FT%XZ" utctime
275 , envChangesDate = formatTime defaultTimeLocale "%FT%XZ" utctime
270 }
276 }
271
277
@@ -722,11 +728,6 @@ makeTOC _ = return []
722-- OpenXML elements (the main document and footnotes).
728-- OpenXML elements (the main document and footnotes).
723writeOpenXML :: WriterOptions -> Pandoc -> WS ([Element], [Element])
729writeOpenXML :: WriterOptions -> Pandoc -> WS ([Element], [Element])
724writeOpenXML opts (Pandoc meta blocks) = do
730writeOpenXML opts (Pandoc meta blocks) = do
725− let isRTL = case lookupMeta "dir" meta of
726− Just (MetaString "rtl") -> True
727− Just (MetaInlines [Str "rtl"]) -> True
728− _ -> False
729− (if isRTL then setRTL else id) $ do
730 let tit = docTitle meta ++ case lookupMeta "subtitle" meta of
731 let tit = docTitle meta ++ case lookupMeta "subtitle" meta of
731 Just (MetaBlocks [Plain xs]) -> LineBreak : xs
732 Just (MetaBlocks [Plain xs]) -> LineBreak : xs
732 _ -> []
733 _ -> []
@@ -792,25 +793,30 @@ dynamicStyleKey = "custom-style"
792
793
793-- | Convert a Pandoc block element to OpenXML.
794-- | Convert a Pandoc block element to OpenXML.
794blockToOpenXML :: WriterOptions -> Block -> WS [Element]
795blockToOpenXML :: WriterOptions -> Block -> WS [Element]
796+blockToOpenXML opts blk = withDirection $ blockToOpenXML' opts blk
797+
798+blockToOpenXML' :: WriterOptions -> Block -> WS [Element]
795−blockToOpenXML _ Null = return []
799+blockToOpenXML' _ Null = return []
796−blockToOpenXML opts (Div (ident,classes,kvs) bs)
800+blockToOpenXML' opts (Div (ident,classes,kvs) bs)
797 | Just sty <- lookup dynamicStyleKey kvs = do
801 | Just sty <- lookup dynamicStyleKey kvs = do
798 modify $ \s -> s{stDynamicParaProps = sty : (stDynamicParaProps s)}
802 modify $ \s -> s{stDynamicParaProps = sty : (stDynamicParaProps s)}
799 withParaPropM (pStyleM sty) $ blocksToOpenXML opts bs
803 withParaPropM (pStyleM sty) $ blocksToOpenXML opts bs
800 | Just "rtl" <- lookup "dir" kvs = do
804 | Just "rtl" <- lookup "dir" kvs = do
801 let kvs' = filter (("dir", "rtl")/=) kvs
805 let kvs' = filter (("dir", "rtl")/=) kvs
806+ local (\env -> env { envRTL = True }) $
802− setRTL $ blockToOpenXML opts (Div (ident,classes,kvs') bs)
807+ blockToOpenXML opts (Div (ident,classes,kvs') bs)
803 | Just "ltr" <- lookup "dir" kvs = do
808 | Just "ltr" <- lookup "dir" kvs = do
804 let kvs' = filter (("dir", "ltr")/=) kvs
809 let kvs' = filter (("dir", "ltr")/=) kvs
810+ local (\env -> env { envRTL = False }) $
805− setLTR $ blockToOpenXML opts (Div (ident,classes,kvs') bs)
811+ blockToOpenXML opts (Div (ident,classes,kvs') bs)
806−blockToOpenXML opts (Div (_,["references"],_) bs) = do
812+blockToOpenXML' opts (Div (_,["references"],_) bs) = do
807 let (hs, bs') = span isHeaderBlock bs
813 let (hs, bs') = span isHeaderBlock bs
808 header <- blocksToOpenXML opts hs
814 header <- blocksToOpenXML opts hs
809 -- We put the Bibliography style on paragraphs after the header
815 -- We put the Bibliography style on paragraphs after the header
810 rest <- withParaPropM (pStyleM "Bibliography") $ blocksToOpenXML opts bs'
816 rest <- withParaPropM (pStyleM "Bibliography") $ blocksToOpenXML opts bs'
811 return (header ++ rest)
817 return (header ++ rest)
812−blockToOpenXML opts (Div _ bs) = blocksToOpenXML opts bs
818+blockToOpenXML' opts (Div _ bs) = blocksToOpenXML opts bs
813−blockToOpenXML opts (Header lev (ident,_,_) lst) = do
819+blockToOpenXML' opts (Header lev (ident,_,_) lst) = do
814 setFirstPara
820 setFirstPara
815 paraProps <- withParaPropM (pStyleM ("Heading "++show lev)) $
821 paraProps <- withParaPropM (pStyleM ("Heading "++show lev)) $
816 getParaProps False
822 getParaProps False
@@ -825,10 +831,10 @@ blockToOpenXML opts (Header lev (ident,_,_) lst) = do
825 ,("w:name",bookmarkName)] ()
831 ,("w:name",bookmarkName)] ()
826 let bookmarkEnd = mknode "w:bookmarkEnd" [("w:id", id')] ()
832 let bookmarkEnd = mknode "w:bookmarkEnd" [("w:id", id')] ()
827 return [mknode "w:p" [] (paraProps ++ [bookmarkStart, bookmarkEnd] ++ contents)]
833 return [mknode "w:p" [] (paraProps ++ [bookmarkStart, bookmarkEnd] ++ contents)]
828−blockToOpenXML opts (Plain lst) = withParaProp (pCustomStyle "Compact")
834+blockToOpenXML' opts (Plain lst) = withParaProp (pCustomStyle "Compact")
829 $ blockToOpenXML opts (Para lst)
835 $ blockToOpenXML opts (Para lst)
830-- title beginning with fig: indicates that the image is a figure
836-- title beginning with fig: indicates that the image is a figure
831−blockToOpenXML opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) = do
837+blockToOpenXML' opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) = do
832 setFirstPara
838 setFirstPara
833 let prop = pCustomStyle $
839 let prop = pCustomStyle $
834 if null alt
840 if null alt
@@ -840,8 +846,8 @@ blockToOpenXML opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) = do
840 $ blockToOpenXML opts (Para alt)
846 $ blockToOpenXML opts (Para alt)
841 return $ mknode "w:p" [] (paraProps ++ contents) : captionNode
847 return $ mknode "w:p" [] (paraProps ++ contents) : captionNode
842-- fixDisplayMath sometimes produces a Para [] as artifact
848-- fixDisplayMath sometimes produces a Para [] as artifact
843−blockToOpenXML _ (Para []) = return []
849+blockToOpenXML' _ (Para []) = return []
844−blockToOpenXML opts (Para lst) = do
850+blockToOpenXML' opts (Para lst) = do
845 isFirstPara <- gets stFirstPara
851 isFirstPara <- gets stFirstPara
846 paraProps <- getParaProps $ case lst of
852 paraProps <- getParaProps $ case lst of
847 [Math DisplayMath _] -> True
853 [Math DisplayMath _] -> True
@@ -854,25 +860,25 @@ blockToOpenXML opts (Para lst) = do
854 modify $ \s -> s { stFirstPara = False }
860 modify $ \s -> s { stFirstPara = False }
855 contents <- inlinesToOpenXML opts lst
861 contents <- inlinesToOpenXML opts lst
856 return [mknode "w:p" [] (paraProps' ++ contents)]
862 return [mknode "w:p" [] (paraProps' ++ contents)]
857−blockToOpenXML _ (RawBlock format str)
863+blockToOpenXML' _ (RawBlock format str)
858 | format == Format "openxml" = return [ x | Elem x <- parseXML str ]
864 | format == Format "openxml" = return [ x | Elem x <- parseXML str ]
859 | otherwise = return []
865 | otherwise = return []
860−blockToOpenXML opts (BlockQuote blocks) = do
866+blockToOpenXML' opts (BlockQuote blocks) = do
861 p <- withParaPropM (pStyleM "Block Text") $ blocksToOpenXML opts blocks
867 p <- withParaPropM (pStyleM "Block Text") $ blocksToOpenXML opts blocks
862 setFirstPara
868 setFirstPara
863 return p
869 return p
864−blockToOpenXML opts (CodeBlock attrs str) = do
870+blockToOpenXML' opts (CodeBlock attrs str) = do
865 p <- withParaProp (pCustomStyle "SourceCode") (blockToOpenXML opts $ Para [Code attrs str])
871 p <- withParaProp (pCustomStyle "SourceCode") (blockToOpenXML opts $ Para [Code attrs str])
866 setFirstPara
872 setFirstPara
867 return p
873 return p
868−blockToOpenXML _ HorizontalRule = do
874+blockToOpenXML' _ HorizontalRule = do
869 setFirstPara
875 setFirstPara
870 return [
876 return [
871 mknode "w:p" [] $ mknode "w:r" [] $ mknode "w:pict" []
877 mknode "w:p" [] $ mknode "w:r" [] $ mknode "w:pict" []
872 $ mknode "v:rect" [("style","width:0;height:1.5pt"),
878 $ mknode "v:rect" [("style","width:0;height:1.5pt"),
873 ("o:hralign","center"),
879 ("o:hralign","center"),
874 ("o:hrstd","t"),("o:hr","t")] () ]
880 ("o:hrstd","t"),("o:hr","t")] () ]
875−blockToOpenXML opts (Table caption aligns widths headers rows) = do
881+blockToOpenXML' opts (Table caption aligns widths headers rows) = do
876 setFirstPara
882 setFirstPara
877 let captionStr = stringify caption
883 let captionStr = stringify caption
878 caption' <- if null caption
884 caption' <- if null caption
@@ -920,21 +926,21 @@ blockToOpenXML opts (Table caption aligns widths headers rows) = do
920 : [ mkrow True headers' | hasHeader ] ++
926 : [ mkrow True headers' | hasHeader ] ++
921 map (mkrow False) rows'
927 map (mkrow False) rows'
922 )]
928 )]
923−blockToOpenXML opts (BulletList lst) = do
929+blockToOpenXML' opts (BulletList lst) = do
924 let marker = BulletMarker
930 let marker = BulletMarker
925 addList marker
931 addList marker
926 numid <- getNumId
932 numid <- getNumId
927 l <- asList $ concat `fmap` mapM (listItemToOpenXML opts numid) lst
933 l <- asList $ concat `fmap` mapM (listItemToOpenXML opts numid) lst
928 setFirstPara
934 setFirstPara
929 return l
935 return l
930−blockToOpenXML opts (OrderedList (start, numstyle, numdelim) lst) = do
936+blockToOpenXML' opts (OrderedList (start, numstyle, numdelim) lst) = do
931 let marker = NumberMarker numstyle numdelim start
937 let marker = NumberMarker numstyle numdelim start
932 addList marker
938 addList marker
933 numid <- getNumId
939 numid <- getNumId
934 l <- asList $ concat `fmap` mapM (listItemToOpenXML opts numid) lst
940 l <- asList $ concat `fmap` mapM (listItemToOpenXML opts numid) lst
935 setFirstPara
941 setFirstPara
936 return l
942 return l
937−blockToOpenXML opts (DefinitionList items) = do
943+blockToOpenXML' opts (DefinitionList items) = do
938 l <- concat `fmap` mapM (definitionListItemToOpenXML opts) items
944 l <- concat `fmap` mapM (definitionListItemToOpenXML opts) items
939 setFirstPara
945 setFirstPara
940 return l
946 return l
@@ -1027,10 +1033,13 @@ setFirstPara = modify $ \s -> s { stFirstPara = True }
1027
1033
1028-- | Convert an inline element to OpenXML.
1034-- | Convert an inline element to OpenXML.
1029inlineToOpenXML :: WriterOptions -> Inline -> WS [Element]
1035inlineToOpenXML :: WriterOptions -> Inline -> WS [Element]
1036+inlineToOpenXML opts il = withDirection $ inlineToOpenXML' opts il
1037+
1038+inlineToOpenXML' :: WriterOptions -> Inline -> WS [Element]
1030−inlineToOpenXML _ (Str str) = formattedString str
1039+inlineToOpenXML' _ (Str str) = formattedString str
1031−inlineToOpenXML opts Space = inlineToOpenXML opts (Str " ")
1040+inlineToOpenXML' opts Space = inlineToOpenXML opts (Str " ")
1032−inlineToOpenXML opts SoftBreak = inlineToOpenXML opts (Str " ")
1041+inlineToOpenXML' opts SoftBreak = inlineToOpenXML opts (Str " ")
1033−inlineToOpenXML opts (Span (ident,classes,kvs) ils)
1042+inlineToOpenXML' opts (Span (ident,classes,kvs) ils)
1034 | Just sty <- lookup dynamicStyleKey kvs = do
1043 | Just sty <- lookup dynamicStyleKey kvs = do
1035 let kvs' = filter ((dynamicStyleKey, sty)/=) kvs
1044 let kvs' = filter ((dynamicStyleKey, sty)/=) kvs
1036 modify $ \s -> s{stDynamicTextProps = sty : (stDynamicTextProps s)}
1045 modify $ \s -> s{stDynamicTextProps = sty : (stDynamicTextProps s)}
@@ -1038,10 +1047,12 @@ inlineToOpenXML opts (Span (ident,classes,kvs) ils)
1038 inlineToOpenXML opts (Span (ident,classes,kvs') ils)
1047 inlineToOpenXML opts (Span (ident,classes,kvs') ils)
1039 | Just "rtl" <- lookup "dir" kvs = do
1048 | Just "rtl" <- lookup "dir" kvs = do
1040 let kvs' = filter (("dir", "rtl")/=) kvs
1049 let kvs' = filter (("dir", "rtl")/=) kvs
1050+ local (\env -> env { envRTL = True }) $
1041− setRTL $ inlineToOpenXML opts (Span (ident,classes,kvs') ils)
1051+ inlineToOpenXML opts (Span (ident,classes,kvs') ils)
1042 | Just "ltr" <- lookup "dir" kvs = do
1052 | Just "ltr" <- lookup "dir" kvs = do
1043 let kvs' = filter (("dir", "ltr")/=) kvs
1053 let kvs' = filter (("dir", "ltr")/=) kvs
1054+ local (\env -> env { envRTL = False }) $
1044− setLTR $ inlineToOpenXML opts (Span (ident,classes,kvs') ils)
1055+ inlineToOpenXML opts (Span (ident,classes,kvs') ils)
1045 | "insertion" `elem` classes = do
1056 | "insertion" `elem` classes = do
1046 defaultAuthor <- asks envChangesAuthor
1057 defaultAuthor <- asks envChangesAuthor
1047 defaultDate <- asks envChangesDate
1058 defaultDate <- asks envChangesDate
@@ -1072,32 +1083,32 @@ inlineToOpenXML opts (Span (ident,classes,kvs) ils)
1072 (if "csl-no-strong" `elem` classes then off "w:b" else id) .
1083 (if "csl-no-strong" `elem` classes then off "w:b" else id) .
1073 (if "csl-no-smallcaps" `elem` classes then off "w:smallCaps" else id))
1084 (if "csl-no-smallcaps" `elem` classes then off "w:smallCaps" else id))
1074 $ inlinesToOpenXML opts ils
1085 $ inlinesToOpenXML opts ils
1075−inlineToOpenXML opts (Strong lst) =
1086+inlineToOpenXML' opts (Strong lst) =
1076 withTextProp (mknode "w:b" [] ()) $ inlinesToOpenXML opts lst
1087 withTextProp (mknode "w:b" [] ()) $ inlinesToOpenXML opts lst
1077−inlineToOpenXML opts (Emph lst) =
1088+inlineToOpenXML' opts (Emph lst) =
1078 withTextProp (mknode "w:i" [] ()) $ inlinesToOpenXML opts lst
1089 withTextProp (mknode "w:i" [] ()) $ inlinesToOpenXML opts lst
1079−inlineToOpenXML opts (Subscript lst) =
1090+inlineToOpenXML' opts (Subscript lst) =
1080 withTextProp (mknode "w:vertAlign" [("w:val","subscript")] ())
1091 withTextProp (mknode "w:vertAlign" [("w:val","subscript")] ())
1081 $ inlinesToOpenXML opts lst
1092 $ inlinesToOpenXML opts lst
1082−inlineToOpenXML opts (Superscript lst) =
1093+inlineToOpenXML' opts (Superscript lst) =
1083 withTextProp (mknode "w:vertAlign" [("w:val","superscript")] ())
1094 withTextProp (mknode "w:vertAlign" [("w:val","superscript")] ())
1084 $ inlinesToOpenXML opts lst
1095 $ inlinesToOpenXML opts lst
1085−inlineToOpenXML opts (SmallCaps lst) =
1096+inlineToOpenXML' opts (SmallCaps lst) =
1086 withTextProp (mknode "w:smallCaps" [] ())
1097 withTextProp (mknode "w:smallCaps" [] ())
1087 $ inlinesToOpenXML opts lst
1098 $ inlinesToOpenXML opts lst
1088−inlineToOpenXML opts (Strikeout lst) =
1099+inlineToOpenXML' opts (Strikeout lst) =
1089 withTextProp (mknode "w:strike" [] ())
1100 withTextProp (mknode "w:strike" [] ())
1090 $ inlinesToOpenXML opts lst
1101 $ inlinesToOpenXML opts lst
1091−inlineToOpenXML _ LineBreak = return [br]
1102+inlineToOpenXML' _ LineBreak = return [br]
1092−inlineToOpenXML _ (RawInline f str)
1103+inlineToOpenXML' _ (RawInline f str)
1093 | f == Format "openxml" = return [ x | Elem x <- parseXML str ]
1104 | f == Format "openxml" = return [ x | Elem x <- parseXML str ]
1094 | otherwise = return []
1105 | otherwise = return []
1095−inlineToOpenXML opts (Quoted quoteType lst) =
1106+inlineToOpenXML' opts (Quoted quoteType lst) =
1096 inlinesToOpenXML opts $ [Str open] ++ lst ++ [Str close]
1107 inlinesToOpenXML opts $ [Str open] ++ lst ++ [Str close]
1097 where (open, close) = case quoteType of
1108 where (open, close) = case quoteType of
1098 SingleQuote -> ("\x2018", "\x2019")
1109 SingleQuote -> ("\x2018", "\x2019")
1099 DoubleQuote -> ("\x201C", "\x201D")
1110 DoubleQuote -> ("\x201C", "\x201D")
1100−inlineToOpenXML opts (Math mathType str) = do
1111+inlineToOpenXML' opts (Math mathType str) = do
1101 let displayType = if mathType == DisplayMath
1112 let displayType = if mathType == DisplayMath
1102 then DisplayBlock
1113 then DisplayBlock
1103 else DisplayInline
1114 else DisplayInline
@@ -1105,8 +1116,8 @@ inlineToOpenXML opts (Math mathType str) = do
1105 case writeOMML displayType <$> readTeX str of
1116 case writeOMML displayType <$> readTeX str of
1106 Right r -> return [r]
1117 Right r -> return [r]
1107 Left _ -> inlinesToOpenXML opts (texMathToInlines mathType str)
1118 Left _ -> inlinesToOpenXML opts (texMathToInlines mathType str)
1108−inlineToOpenXML opts (Cite _ lst) = inlinesToOpenXML opts lst
1119+inlineToOpenXML' opts (Cite _ lst) = inlinesToOpenXML opts lst
1109−inlineToOpenXML opts (Code attrs str) = do
1120+inlineToOpenXML' opts (Code attrs str) = do
1110 let unhighlighted = intercalate [br] `fmap`
1121 let unhighlighted = intercalate [br] `fmap`
1111 (mapM formattedString $ lines str)
1122 (mapM formattedString $ lines str)
1112 formatOpenXML _fmtOpts = intercalate [br] . map (map toHlTok)
1123 formatOpenXML _fmtOpts = intercalate [br] . map (map toHlTok)
@@ -1120,7 +1131,7 @@ inlineToOpenXML opts (Code attrs str) = do
1120 Nothing -> unhighlighted
1131 Nothing -> unhighlighted
1121 Just h -> return h
1132 Just h -> return h
1122 else unhighlighted
1133 else unhighlighted
1123−inlineToOpenXML opts (Note bs) = do
1134+inlineToOpenXML' opts (Note bs) = do
1124 notes <- gets stFootnotes
1135 notes <- gets stFootnotes
1125 notenum <- getUniqueId
1136 notenum <- getUniqueId
1126 footnoteStyle <- rStyleM "Footnote Reference"
1137 footnoteStyle <- rStyleM "Footnote Reference"
@@ -1143,11 +1154,11 @@ inlineToOpenXML opts (Note bs) = do
1143 [ mknode "w:rPr" [] footnoteStyle
1154 [ mknode "w:rPr" [] footnoteStyle
1144 , mknode "w:footnoteReference" [("w:id", notenum)] () ] ]
1155 , mknode "w:footnoteReference" [("w:id", notenum)] () ] ]
1145-- internal link:
1156-- internal link:
1146−inlineToOpenXML opts (Link _ txt ('#':xs,_)) = do
1157+inlineToOpenXML' opts (Link _ txt ('#':xs,_)) = do
1147 contents <- withTextPropM (rStyleM "Hyperlink") $ inlinesToOpenXML opts txt
1158 contents <- withTextPropM (rStyleM "Hyperlink") $ inlinesToOpenXML opts txt
1148 return [ mknode "w:hyperlink" [("w:anchor",xs)] contents ]
1159 return [ mknode "w:hyperlink" [("w:anchor",xs)] contents ]
1149-- external link:
1160-- external link:
1150−inlineToOpenXML opts (Link _ txt (src,_)) = do
1161+inlineToOpenXML' opts (Link _ txt (src,_)) = do
1151 contents <- withTextPropM (rStyleM "Hyperlink") $ inlinesToOpenXML opts txt
1162 contents <- withTextPropM (rStyleM "Hyperlink") $ inlinesToOpenXML opts txt
1152 extlinks <- gets stExternalLinks
1163 extlinks <- gets stExternalLinks
1153 id' <- case M.lookup src extlinks of
1164 id' <- case M.lookup src extlinks of
@@ -1158,7 +1169,7 @@ inlineToOpenXML opts (Link _ txt (src,_)) = do
1158 M.insert src i extlinks }
1169 M.insert src i extlinks }
1159 return i
1170 return i
1160 return [ mknode "w:hyperlink" [("r:id",id')] contents ]
1171 return [ mknode "w:hyperlink" [("r:id",id')] contents ]
1161−inlineToOpenXML opts (Image attr alt (src, _)) = do
1172+inlineToOpenXML' opts (Image attr alt (src, _)) = do
1162 -- first, check to see if we've already done this image
1173 -- first, check to see if we've already done this image
1163 pageWidth <- gets stPrintWidth
1174 pageWidth <- gets stPrintWidth
1164 imgs <- gets stImages
1175 imgs <- gets stImages
@@ -1269,28 +1280,23 @@ fitToPage (x, y) pageWidth
1269 (pageWidth, floor $ ((fromIntegral pageWidth) / x) * y)
1280 (pageWidth, floor $ ((fromIntegral pageWidth) / x) * y)
1270 | otherwise = (floor x, floor y)
1281 | otherwise = (floor x, floor y)
1271
1282
1272−setRTL :: WS a -> WS a
1283+withDirection :: WS a -> WS a
1273−setRTL x = do
1284+withDirection x = do
1274− isRTL <- asks envRTL
1285+ isDir <- asks envRTL
1275− if isRTL
1286+ paraProps <- asks envParaProperties
1287+ textProps <- asks envTextProperties
1288+ -- we have to do this because we don't want to accumulate these
1289+ -- properties if we have it set while the environment is already
1290+ -- active.
1291+ let paraProps' = filter (\e -> (qName . elName) e /= "bidi") paraProps
1292+ textProps' = filter (\e -> (qName . elName) e /= "rtl") textProps
1293+ if isDir
1276− then x
1294+ then flip local x $
1295+ \env -> env { envParaProperties = (mknode "w:bidi" [] ()) : paraProps'
1296+ , envTextProperties = (mknode "w:rtl" [] ()) : textProps'
1297+ }
1277− else flip local x $ \env -> env {
1298+ else flip local x $ \env -> env { envParaProperties = paraProps'
1278− envRTL = True
1279− , envParaProperties = (mknode "w:bidi" [] ()) : envParaProperties env
1280− , envTextProperties = (mknode "w:rtl" [] ()) : envTextProperties env
1299+ , envTextProperties = textProps'
1281− }
1300+ }
1282−
1301+
1283
1302
1284−setLTR :: WS a -> WS a
1285−setLTR x = do
1286− isRTL <- asks envRTL
1287− if isRTL
1288− then do paraProps <- asks envParaProperties
1289− textProps <- asks envTextProperties
1290− let paraProps' = filter (\e -> (qName . elName) e /= "bidi") paraProps
1291− textProps' = filter (\e -> (qName . elName) e /= "rtl") textProps
1292− flip local x $ \env -> env { envRTL = False
1293− , envParaProperties = paraProps'
1294− , envTextProperties = textProps'
1295− }
1296− else x