Apply linter suggestions. Add fix_spacing to lint target in Makefile.

This commit is contained in:
John MacFarlane 2020-02-07 08:32:47 -08:00
parent 6cd77d4c63
commit 4c3db9273f
51 changed files with 247 additions and 279 deletions

View file

@ -1,6 +1,6 @@
version?=$(shell grep '^[Vv]ersion:' pandoc.cabal | awk '{print $$2;}') version?=$(shell grep '^[Vv]ersion:' pandoc.cabal | awk '{print $$2;}')
pandoc=$(shell find dist -name pandoc -type f -exec ls -t {} \; | head -1) pandoc=$(shell find dist -name pandoc -type f -exec ls -t {} \; | head -1)
SOURCEFILES?=$(shell find pandoc.hs src test -name '*.hs') SOURCEFILES?=$(shell git ls-tree -r master --name-only | grep "\.hs$$")
BRANCH?=master BRANCH?=master
RESOLVER?=lts-13 RESOLVER?=lts-13
GHCOPTS=-fdiagnostics-color=always GHCOPTS=-fdiagnostics-color=always
@ -45,8 +45,14 @@ weigh:
reformat: reformat:
for f in $(SOURCEFILES); do echo $$f; stylish-haskell -i $$f ; done for f in $(SOURCEFILES); do echo $$f; stylish-haskell -i $$f ; done
lint: lint: hlint fix_spacing
for f in $(SOURCEFILES); do echo $$f; hlint --verbose --refactor --refactor-options='-i -s' $$f; done
hlint:
for f in $(SOURCEFILES); do echo $$f; hlint --verbose --refactor --refactor-options='-s -o -' $$f; done
fix_spacing:
# Fix trailing newlines and spaces at ends of lines
for f in $(SOURCEFILES); do printf '%s\n' "`cat $$f`" | sed -e 's/ *$$//' > $$f.tmp; mv $$f.tmp $$f; done
changes_github: changes_github:
pandoc --filter tools/extract-changes.hs changelog.md -t gfm --wrap=none | sed -e 's/\\#/#/g' | pbcopy pandoc --filter tools/extract-changes.hs changelog.md -t gfm --wrap=none | sed -e 's/\\#/#/g' | pbcopy
@ -142,4 +148,4 @@ update-website:
clean: clean:
stack clean stack clean
.PHONY: deps quick full haddock install clean test bench changes_github macospkg dist prof download_stats reformat lint weigh doc/lua-filters.md packages pandoc-templates trypandoc update-website debpkg macospkg winpkg checkdocs ghcid ghci .PHONY: deps quick full haddock install clean test bench changes_github macospkg dist prof download_stats reformat lint weigh doc/lua-filters.md packages pandoc-templates trypandoc update-website debpkg macospkg winpkg checkdocs ghcid ghci fix_spacing hlint

View file

@ -48,5 +48,3 @@ weighReader doc name reader = do
let inp = either (error . show) id $ runPure $ writer def{ writerWrapText = WrapAuto} doc let inp = either (error . show) id $ runPure $ writer def{ writerWrapText = WrapAuto} doc
in func (unpack $ name <> " reader") reader inp in func (unpack $ name <> " reader") reader inp
_ -> return () -- no writer for reader _ -> return () -- no writer for reader

View file

@ -149,7 +149,7 @@ convertWithOpts opts = do
let pdfOutput = map toLower (takeExtension outputFile) == ".pdf" let pdfOutput = map toLower (takeExtension outputFile) == ".pdf"
when (pdfOutput && readerName == "latex") $ when (pdfOutput && readerName == "latex") $
case (optInputFiles opts) of case optInputFiles opts of
Just (inputFile:_) -> report $ UnusualConversion $ T.pack $ Just (inputFile:_) -> report $ UnusualConversion $ T.pack $
"to convert a .tex file to PDF, you get better results by using pdflatex " "to convert a .tex file to PDF, you get better results by using pdflatex "
<> "(or lualatex or xelatex) directly, try `pdflatex " <> inputFile <> "(or lualatex or xelatex) directly, try `pdflatex " <> inputFile

View file

@ -189,10 +189,10 @@ doOpt (k',v) = do
parseYAML v >>= \x -> return (\o -> o{ optMetadata = optMetadata o <> parseYAML v >>= \x -> return (\o -> o{ optMetadata = optMetadata o <>
contextToMeta x }) contextToMeta x })
"metadata-files" -> "metadata-files" ->
(parseYAML v >>= \x -> parseYAML v >>= \x ->
return (\o -> o{ optMetadataFiles = return (\o -> o{ optMetadataFiles =
optMetadataFiles o <> optMetadataFiles o <>
map unpack x })) map unpack x })
"metadata-file" -> -- allow either a list or a single value "metadata-file" -> -- allow either a list or a single value
(parseYAML v >>= \x -> return (\o -> o{ optMetadataFiles = (parseYAML v >>= \x -> return (\o -> o{ optMetadataFiles =
optMetadataFiles o <> optMetadataFiles o <>

View file

@ -23,4 +23,3 @@ import Text.Pandoc.Lua.Filter (runFilterFile)
import Text.Pandoc.Lua.Global (Global (..), setGlobals) import Text.Pandoc.Lua.Global (Global (..), setGlobals)
import Text.Pandoc.Lua.Init (LuaException (..), runLua) import Text.Pandoc.Lua.Init (LuaException (..), runLua)
import Text.Pandoc.Lua.Marshaling () import Text.Pandoc.Lua.Marshaling ()

View file

@ -29,4 +29,3 @@ instance (TemplateTarget a, Pushable a) => Pushable (Val a) where
push (MapVal ctx) = Lua.push ctx push (MapVal ctx) = Lua.push ctx
push (ListVal xs) = Lua.push xs push (ListVal xs) = Lua.push xs
push (SimpleVal d) = Lua.push $ render Nothing d push (SimpleVal d) = Lua.push $ render Nothing d

View file

@ -154,4 +154,3 @@ must_be_at_least actual expected optMsg = do
Lua.push (showVersion actual) Lua.push (showVersion actual)
Lua.call 3 1 Lua.call 3 1
Lua.error Lua.error

View file

@ -679,7 +679,7 @@ mathInlineWith op cl = try $ do
where where
inBalancedBraces :: Stream s m Char => Int -> Text -> ParserT s st m Text inBalancedBraces :: Stream s m Char => Int -> Text -> ParserT s st m Text
inBalancedBraces n = fmap T.pack . inBalancedBraces' n . T.unpack inBalancedBraces n = fmap T.pack . inBalancedBraces' n . T.unpack
inBalancedBraces' :: Stream s m Char => Int -> String -> ParserT s st m String inBalancedBraces' :: Stream s m Char => Int -> String -> ParserT s st m String
inBalancedBraces' 0 "" = do inBalancedBraces' 0 "" = do
c <- anyChar c <- anyChar

View file

@ -1,6 +1,6 @@
{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
{- | {- |
Module : Text.Pandoc.Readers.RST Module : Text.Pandoc.Readers.RST
@ -42,4 +42,3 @@ readCSV _opts s =
widths = replicate numcols 0 widths = replicate numcols 0
Right [] -> return $ B.doc mempty Right [] -> return $ B.doc mempty
Left e -> throwError $ PandocParsecError s e Left e -> throwError $ PandocParsecError s e

View file

@ -1106,9 +1106,8 @@ equation e constructor =
readMath :: (Element -> Bool) -> (Element -> b) -> [b] readMath :: (Element -> Bool) -> (Element -> b) -> [b]
readMath childPredicate fromElement = readMath childPredicate fromElement =
( map (fromElement . everywhere (mkT removePrefix)) map (fromElement . everywhere (mkT removePrefix))
$ filterChildren childPredicate e $ filterChildren childPredicate e
)
-- | Get the actual text stored in a CData block. 'showContent' -- | Get the actual text stored in a CData block. 'showContent'
-- returns the text still surrounded by the [[CDATA]] tags. -- returns the text still surrounded by the [[CDATA]] tags.

View file

@ -42,7 +42,7 @@ escapedQuote = string "\\\"" $> "\\\""
inQuotes :: Parser T.Text inQuotes :: Parser T.Text
inQuotes = inQuotes =
(try escapedQuote) <|> (anyChar >>= (\c -> return $ T.singleton c)) try escapedQuote <|> (anyChar >>= (\c -> return $ T.singleton c))
quotedString :: Parser T.Text quotedString :: Parser T.Text
quotedString = do quotedString = do
@ -50,7 +50,7 @@ quotedString = do
T.concat <$> manyTill inQuotes (try (char '"')) T.concat <$> manyTill inQuotes (try (char '"'))
unquotedString :: Parser T.Text unquotedString :: Parser T.Text
unquotedString = T.pack <$> manyTill anyChar (try $ lookAhead space *> return () <|> eof) unquotedString = T.pack <$> manyTill anyChar (try $ lookAhead space Data.Functor.$> () <|> eof)
fieldArgument :: Parser T.Text fieldArgument :: Parser T.Text
fieldArgument = quotedString <|> unquotedString fieldArgument = quotedString <|> unquotedString

View file

@ -403,8 +403,8 @@ pDiv = try $ do
pRawHtmlBlock :: PandocMonad m => TagParser m Blocks pRawHtmlBlock :: PandocMonad m => TagParser m Blocks
pRawHtmlBlock = do pRawHtmlBlock = do
raw <- (pHtmlBlock "script" <|> pHtmlBlock "style" <|> pHtmlBlock "textarea" raw <- pHtmlBlock "script" <|> pHtmlBlock "style" <|> pHtmlBlock "textarea"
<|> pRawTag) <|> pRawTag
exts <- getOption readerExtensions exts <- getOption readerExtensions
if extensionEnabled Ext_raw_html exts && not (T.null raw) if extensionEnabled Ext_raw_html exts && not (T.null raw)
then return $ B.rawBlock "html" raw then return $ B.rawBlock "html" raw
@ -976,7 +976,7 @@ isSpecial '\8221' = True
isSpecial _ = False isSpecial _ = False
pSymbol :: PandocMonad m => InlinesParser m Inlines pSymbol :: PandocMonad m => InlinesParser m Inlines
pSymbol = satisfy isSpecial >>= return . B.str . T.singleton pSymbol = B.str . T.singleton <$> satisfy isSpecial
isBad :: Char -> Bool isBad :: Char -> Bool
isBad c = c >= '\128' && c <= '\159' -- not allowed in HTML isBad c = c >= '\128' && c <= '\159' -- not allowed in HTML

View file

@ -21,10 +21,9 @@ import Prelude
import Control.Monad import Control.Monad
import Control.Monad.Except (throwError) import Control.Monad.Except (throwError)
import Data.Char (isAlphaNum, isPunctuation, isSpace) import Data.Char (isAlphaNum, isPunctuation, isSpace)
import Data.List (sortBy, transpose, elemIndex) import Data.List (transpose, elemIndex, sortOn)
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe import Data.Maybe
import Data.Ord (comparing)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Text (Text) import Data.Text (Text)
import qualified Data.Text as T import qualified Data.Text as T
@ -247,7 +246,7 @@ yamlMetaBlock = try $ do
newMetaF <- yamlBsToMeta parseBlocks newMetaF <- yamlBsToMeta parseBlocks
$ UTF8.fromTextLazy $ TL.fromStrict rawYaml $ UTF8.fromTextLazy $ TL.fromStrict rawYaml
-- Since `<>` is left-biased, existing values are not touched: -- Since `<>` is left-biased, existing values are not touched:
updateState $ \st -> st{ stateMeta' = (stateMeta' st) <> newMetaF } updateState $ \st -> st{ stateMeta' = stateMeta' st <> newMetaF }
return mempty return mempty
stopLine :: PandocMonad m => MarkdownParser m () stopLine :: PandocMonad m => MarkdownParser m ()
@ -1107,7 +1106,7 @@ rawHtmlBlocks = do
return (return (B.rawBlock "html" $ stripMarkdownAttribute raw) <> return (return (B.rawBlock "html" $ stripMarkdownAttribute raw) <>
contents <> contents <>
return (B.rawBlock "html" rawcloser))) return (B.rawBlock "html" rawcloser)))
<|> (return (return (B.rawBlock "html" raw) <> contents)) <|> return (return (B.rawBlock "html" raw) <> contents)
updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock } updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock }
return result return result
@ -1170,7 +1169,7 @@ simpleTableHeader headless = try $ do
else rawHeads else rawHeads
heads <- fmap sequence heads <- fmap sequence
$ $
mapM ((parseFromString' (mconcat <$> many plain)).trim) rawHeads' mapM (parseFromString' (mconcat <$> many plain).trim) rawHeads'
return (heads, aligns, indices) return (heads, aligns, indices)
-- Returns an alignment type for a table, based on a list of strings -- Returns an alignment type for a table, based on a list of strings
@ -1183,7 +1182,7 @@ alignType [] _ = AlignDefault
alignType strLst len = alignType strLst len =
let nonempties = filter (not . T.null) $ map trimr strLst let nonempties = filter (not . T.null) $ map trimr strLst
(leftSpace, rightSpace) = (leftSpace, rightSpace) =
case sortBy (comparing T.length) nonempties of case sortOn T.length nonempties of
(x:_) -> (T.head x `elem` [' ', 't'], T.length x < len) (x:_) -> (T.head x `elem` [' ', 't'], T.length x < len)
[] -> (False, False) [] -> (False, False)
in case (leftSpace, rightSpace) of in case (leftSpace, rightSpace) of
@ -1287,7 +1286,7 @@ multilineTableHeader headless = try $ do
then replicate (length dashes) "" then replicate (length dashes) ""
else map (T.unlines . map trim) rawHeadsList else map (T.unlines . map trim) rawHeadsList
heads <- fmap sequence $ heads <- fmap sequence $
mapM ((parseFromString' (mconcat <$> many plain)).trim) rawHeads mapM (parseFromString' (mconcat <$> many plain).trim) rawHeads
return (heads, aligns, indices') return (heads, aligns, indices')
-- Parse a grid table: starts with row of '-' on top, then header -- Parse a grid table: starts with row of '-' on top, then header

View file

@ -40,8 +40,8 @@ yamlBsToMeta :: PandocMonad m
yamlBsToMeta pBlocks bstr = do yamlBsToMeta pBlocks bstr = do
pos <- getPosition pos <- getPosition
case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
Right ((YAML.Doc (YAML.Mapping _ _ o)):_) Right (YAML.Doc (YAML.Mapping _ _ o):_)
-> (fmap Meta) <$> yamlMap pBlocks o -> fmap Meta <$> yamlMap pBlocks o
Right [] -> return . return $ mempty Right [] -> return . return $ mempty
Right [YAML.Doc (YAML.Scalar _ YAML.SNull)] Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
-> return . return $ mempty -> return . return $ mempty
@ -84,12 +84,10 @@ toMetaValue pBlocks x =
asBlocks p = MetaBlocks . B.toList <$> p asBlocks p = MetaBlocks . B.toList <$> p
checkBoolean :: Text -> Maybe Bool checkBoolean :: Text -> Maybe Bool
checkBoolean t = checkBoolean t
if t == T.pack "true" || t == T.pack "True" || t == T.pack "TRUE" | t == T.pack "true" || t == T.pack "True" || t == T.pack "TRUE" = Just True
then Just True | t == T.pack "false" || t == T.pack "False" || t == T.pack "FALSE" = Just False
else if t == T.pack "false" || t == T.pack "False" || t == T.pack "FALSE" | otherwise = Nothing
then Just False
else Nothing
yamlToMetaValue :: PandocMonad m yamlToMetaValue :: PandocMonad m
=> ParserT Text ParserState m (F Blocks) => ParserT Text ParserState m (F Blocks)
@ -133,4 +131,3 @@ yamlMap pBlocks o = do
return $ do return $ do
v' <- fv v' <- fv
return (k, v') return (k, v')

View file

@ -183,14 +183,14 @@ a >>?! f = a >>> right f
=> FallibleArrow a x f (b,b') => FallibleArrow a x f (b,b')
-> (b -> b' -> c) -> (b -> b' -> c)
-> FallibleArrow a x f c -> FallibleArrow a x f c
a >>?% f = a >>?^ (uncurry f) a >>?% f = a >>?^ uncurry f
--- ---
(^>>?%) :: (ArrowChoice a) (^>>?%) :: (ArrowChoice a)
=> (x -> Either f (b,b')) => (x -> Either f (b,b'))
-> (b -> b' -> c) -> (b -> b' -> c)
-> FallibleArrow a x f c -> FallibleArrow a x f c
a ^>>?% f = arr a >>?^ (uncurry f) a ^>>?% f = arr a >>?^ uncurry f
--- ---
(>>?%?) :: (ArrowChoice a) (>>?%?) :: (ArrowChoice a)

View file

@ -792,7 +792,7 @@ read_frame_title = matchingElement NsSVG "title" (matchChildContent [] read_plai
image_attributes :: Maybe T.Text -> Maybe T.Text -> Attr image_attributes :: Maybe T.Text -> Maybe T.Text -> Attr
image_attributes x y = image_attributes x y =
( "", [], (dim "width" x) ++ (dim "height" y)) ( "", [], dim "width" x ++ dim "height" y)
where where
dim _ (Just "") = [] dim _ (Just "") = []
dim name (Just v) = [(name, v)] dim name (Just v) = [(name, v)]

View file

@ -163,7 +163,7 @@ swapStack' state stack
pushElement :: XML.Element pushElement :: XML.Element
-> XMLConverterState nsID extraState -> XMLConverterState nsID extraState
-> XMLConverterState nsID extraState -> XMLConverterState nsID extraState
pushElement e state = state { parentElements = e:(parentElements state) } pushElement e state = state { parentElements = e:parentElements state }
-- | Pop the top element from the call stack, unless it is the last one. -- | Pop the top element from the call stack, unless it is the last one.
popElement :: XMLConverterState nsID extraState popElement :: XMLConverterState nsID extraState
@ -605,8 +605,8 @@ executeInSub nsID name a = keepingTheValue
(findChild nsID name) (findChild nsID name)
>>> ignoringState liftFailure >>> ignoringState liftFailure
>>? switchingTheStack a >>? switchingTheStack a
where liftFailure (_, (Left f)) = Left f where liftFailure (_, Left f) = Left f
liftFailure (x, (Right e)) = Right (x, e) liftFailure (x, Right e) = Right (x, e)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Iterating over children -- Iterating over children
@ -702,7 +702,7 @@ prepareMatchersC :: (NameSpaceID nsID)
=> [(nsID, ElementName, FallibleXMLConverter nsID extraState x x)] => [(nsID, ElementName, FallibleXMLConverter nsID extraState x x)]
-> ContentMatchConverter nsID extraState x -> ContentMatchConverter nsID extraState x
--prepareMatchersC = foldSs . (map $ uncurry3 makeMatcherC) --prepareMatchersC = foldSs . (map $ uncurry3 makeMatcherC)
prepareMatchersC = reverseComposition . (map $ uncurry3 makeMatcherC) prepareMatchersC = reverseComposition . map (uncurry3 makeMatcherC)
-- | Takes a list of element-data - converter groups and -- | Takes a list of element-data - converter groups and
-- * Finds all content of the current element -- * Finds all content of the current element

View file

@ -120,7 +120,7 @@ fontPitchReader = executeInSub NsOffice "font-face-decls" (
lookupDefaultingAttr NsStyle "font-pitch" lookupDefaultingAttr NsStyle "font-pitch"
)) ))
>>?^ ( M.fromList . foldl accumLegalPitches [] ) >>?^ ( M.fromList . foldl accumLegalPitches [] )
) `ifFailedDo` (returnV (Right M.empty)) ) `ifFailedDo` returnV (Right M.empty)
where accumLegalPitches ls (Nothing,_) = ls where accumLegalPitches ls (Nothing,_) = ls
accumLegalPitches ls (Just n,p) = (n,p):ls accumLegalPitches ls (Just n,p) = (n,p):ls

View file

@ -166,10 +166,8 @@ parseRST = do
blocks <- B.toList <$> parseBlocks blocks <- B.toList <$> parseBlocks
citations <- (sort . M.toList . stateCitations) <$> getState citations <- (sort . M.toList . stateCitations) <$> getState
citationItems <- mapM parseCitation citations citationItems <- mapM parseCitation citations
let refBlock = if null citationItems let refBlock = [Div ("citations",[],[]) $
then [] B.toList $ B.definitionList citationItems | not (null citationItems)]
else [Div ("citations",[],[]) $
B.toList $ B.definitionList citationItems]
standalone <- getOption readerStandalone standalone <- getOption readerStandalone
state <- getState state <- getState
let meta = stateMeta state let meta = stateMeta state
@ -225,7 +223,7 @@ rawFieldListItem minIndent = try $ do
first <- anyLine first <- anyLine
rest <- option "" $ try $ do lookAhead (count indent (char ' ') >> spaceChar) rest <- option "" $ try $ do lookAhead (count indent (char ' ') >> spaceChar)
indentedBlock indentedBlock
let raw = (if T.null first then "" else (first <> "\n")) <> rest <> "\n" let raw = (if T.null first then "" else first <> "\n") <> rest <> "\n"
return (name, raw) return (name, raw)
fieldListItem :: PandocMonad m => Int -> RSTParser m (Inlines, [Blocks]) fieldListItem :: PandocMonad m => Int -> RSTParser m (Inlines, [Blocks])
@ -706,7 +704,7 @@ directive' = do
tit <- B.para . B.strong <$> parseInlineFromText tit <- B.para . B.strong <$> parseInlineFromText
(trim top <> if T.null subtit (trim top <> if T.null subtit
then "" then ""
else (": " <> subtit)) else ": " <> subtit)
bod <- parseFromString' parseBlocks body' bod <- parseFromString' parseBlocks body'
return $ B.divWith (name,"sidebar":classes,keyvals) $ tit <> bod return $ B.divWith (name,"sidebar":classes,keyvals) $ tit <> bod
"topic" -> "topic" ->
@ -1446,14 +1444,14 @@ roleAfter = try $ do
unmarkedInterpretedText :: PandocMonad m => RSTParser m Text unmarkedInterpretedText :: PandocMonad m => RSTParser m Text
unmarkedInterpretedText = try $ do unmarkedInterpretedText = try $ do
atStart (char '`') atStart (char '`')
contents <- mconcat <$> (many1 contents <- mconcat <$> many1
( many1 (noneOf "`\\\n") ( many1 (noneOf "`\\\n")
<|> (char '\\' >> ((\c -> ['\\',c]) <$> noneOf "\n")) <|> (char '\\' >> ((\c -> ['\\',c]) <$> noneOf "\n"))
<|> (string "\n" <* notFollowedBy blankline) <|> (string "\n" <* notFollowedBy blankline)
<|> try (string "`" <* <|> try (string "`" <*
notFollowedBy (() <$ roleMarker) <* notFollowedBy (() <$ roleMarker) <*
lookAhead (satisfy isAlphaNum)) lookAhead (satisfy isAlphaNum))
)) )
char '`' char '`'
return $ T.pack contents return $ T.pack contents

View file

@ -55,7 +55,7 @@ type TikiWikiParser = ParserT Text ParserState
-- --
tryMsg :: Text -> TikiWikiParser m a -> TikiWikiParser m a tryMsg :: Text -> TikiWikiParser m a -> TikiWikiParser m a
tryMsg msg p = try p <?> (T.unpack msg) tryMsg msg p = try p <?> T.unpack msg
skip :: TikiWikiParser m a -> TikiWikiParser m () skip :: TikiWikiParser m a -> TikiWikiParser m ()
skip parser = Control.Monad.void parser skip parser = Control.Monad.void parser

View file

@ -147,7 +147,7 @@ header = try $ do
contents <- trimInlines . mconcat <$> manyTill inline (try $ spaceChar contents <- trimInlines . mconcat <$> manyTill inline (try $ spaceChar
>> string eqs >> many spaceChar >> newline) >> string eqs >> many spaceChar >> newline)
attr <- registerHeader (makeId contents, attr <- registerHeader (makeId contents,
if sp == "" then [] else ["justcenter"], []) contents ["justcenter" | not (null sp)], []) contents
return $ B.headerWith attr lev contents return $ B.headerWith attr lev contents
para :: PandocMonad m => VwParser m Blocks para :: PandocMonad m => VwParser m Blocks

View file

@ -69,7 +69,7 @@ convertTags (t@(TagOpen tagname as):ts)
enc <- getDataURI (fromAttrib "type" t) y enc <- getDataURI (fromAttrib "type" t) y
return (x, enc) return (x, enc)
else return (x,y) else return (x,y)
convertTags (t@(TagOpen "script" as):TagClose "script":ts) = convertTags (t@(TagOpen "script" as):TagClose "script":ts) =
case fromAttrib "src" t of case fromAttrib "src" t of
"" -> (t:) <$> convertTags ts "" -> (t:) <$> convertTags ts
src -> do src -> do

View file

@ -466,7 +466,7 @@ compactify items =
let (others, final) = (init items, last items) let (others, final) = (init items, last items)
in case reverse (B.toList final) of in case reverse (B.toList final) of
(Para a:xs) (Para a:xs)
| null [Para x | Para x <- (xs ++ concatMap B.toList others)] | null [Para x | Para x <- xs ++ concatMap B.toList others]
-> others ++ [B.fromList (reverse (Plain a : xs))] -> others ++ [B.fromList (reverse (Plain a : xs))]
_ | null [Para x | Para x <- concatMap B.toList items] _ | null [Para x | Para x <- concatMap B.toList items]
-> items -> items
@ -682,9 +682,9 @@ isTightList = all (\item -> firstIsPlain item || null item)
taskListItemFromAscii :: Extensions -> [Block] -> [Block] taskListItemFromAscii :: Extensions -> [Block] -> [Block]
taskListItemFromAscii = handleTaskListItem fromMd taskListItemFromAscii = handleTaskListItem fromMd
where where
fromMd (Str "[" : Space : Str "]" : Space : is) = (Str "") : Space : is fromMd (Str "[" : Space : Str "]" : Space : is) = Str "" : Space : is
fromMd (Str "[x]" : Space : is) = (Str "") : Space : is fromMd (Str "[x]" : Space : is) = Str "" : Space : is
fromMd (Str "[X]" : Space : is) = (Str "") : Space : is fromMd (Str "[X]" : Space : is) = Str "" : Space : is
fromMd is = is fromMd is = is
-- | Convert a list item containing text starting with @U+2610 BALLOT BOX@ -- | Convert a list item containing text starting with @U+2610 BALLOT BOX@
@ -787,19 +787,19 @@ splitSentences xs =
-- strip out ANSI escape sequences from CodeBlocks (see #5633). -- strip out ANSI escape sequences from CodeBlocks (see #5633).
filterIpynbOutput :: Maybe Format -> Pandoc -> Pandoc filterIpynbOutput :: Maybe Format -> Pandoc -> Pandoc
filterIpynbOutput mode = walk go filterIpynbOutput mode = walk go
where go (Div (ident, ("output":os), kvs) bs) = where go (Div (ident, "output":os, kvs) bs) =
case mode of case mode of
Nothing -> Div (ident, ("output":os), kvs) [] Nothing -> Div (ident, "output":os, kvs) []
-- "best" for ipynb includes all formats: -- "best" for ipynb includes all formats:
Just fmt Just fmt
| fmt == Format "ipynb" | fmt == Format "ipynb"
-> Div (ident, ("output":os), kvs) bs -> Div (ident, "output":os, kvs) bs
| otherwise -> Div (ident, ("output":os), kvs) $ | otherwise -> Div (ident, "output":os, kvs) $
walk removeANSI $ walk removeANSI $
take 1 $ sortOn rank bs take 1 $ sortOn rank bs
where where
rank (RawBlock (Format "html") _) rank (RawBlock (Format "html") _)
| fmt == Format "html" = (1 :: Int) | fmt == Format "html" = 1 :: Int
| fmt == Format "markdown" = 2 | fmt == Format "markdown" = 2
| otherwise = 3 | otherwise = 3
rank (RawBlock (Format "latex") _) rank (RawBlock (Format "latex") _)

View file

@ -263,7 +263,7 @@ blockToAsciiDoc opts (OrderedList (start, sty, _delim) items) = do
Decimal -> ["arabic"] Decimal -> ["arabic"]
Example -> [] Example -> []
_ -> [T.toLower (tshow sty)] _ -> [T.toLower (tshow sty)]
let listStart = if start == 1 then [] else ["start=" <> tshow start] let listStart = ["start=" <> tshow start | not (start == 1)]
let listoptions = case T.intercalate ", " (listStyle ++ listStart) of let listoptions = case T.intercalate ", " (listStyle ++ listStart) of
"" -> empty "" -> empty
x -> brackets (literal x) x -> brackets (literal x)

View file

@ -45,9 +45,7 @@ writeCommonMark opts (Pandoc meta blocks) = do
else return mempty else return mempty
let (blocks', notes) = runState (walkM processNotes blocks) [] let (blocks', notes) = runState (walkM processNotes blocks) []
notes' = if null notes notes' = [OrderedList (1, Decimal, Period) $ reverse notes | not (null notes)]
then []
else [OrderedList (1, Decimal, Period) $ reverse notes]
main <- blocksToCommonMark opts (blocks' ++ notes') main <- blocksToCommonMark opts (blocks' ++ notes')
metadata <- metaToContext opts metadata <- metaToContext opts
(fmap (literal . T.stripEnd) . blocksToCommonMark opts) (fmap (literal . T.stripEnd) . blocksToCommonMark opts)
@ -241,13 +239,11 @@ inlineToNodes opts SoftBreak
| otherwise = (node SOFTBREAK [] :) | otherwise = (node SOFTBREAK [] :)
inlineToNodes opts (Emph xs) = (node EMPH (inlinesToNodes opts xs) :) inlineToNodes opts (Emph xs) = (node EMPH (inlinesToNodes opts xs) :)
inlineToNodes opts (Strong xs) = (node STRONG (inlinesToNodes opts xs) :) inlineToNodes opts (Strong xs) = (node STRONG (inlinesToNodes opts xs) :)
inlineToNodes opts (Strikeout xs) = inlineToNodes opts (Strikeout xs)
if isEnabled Ext_strikeout opts | isEnabled Ext_strikeout opts = (node (CUSTOM_INLINE "~~" "~~") (inlinesToNodes opts xs) :)
then (node (CUSTOM_INLINE "~~" "~~") (inlinesToNodes opts xs) :) | isEnabled Ext_raw_html opts = ((node (HTML_INLINE (T.pack "<s>")) [] : inlinesToNodes opts xs ++
else if isEnabled Ext_raw_html opts [node (HTML_INLINE (T.pack "</s>")) []]) ++ )
then ((node (HTML_INLINE (T.pack "<s>")) [] : inlinesToNodes opts xs ++ | otherwise = (inlinesToNodes opts xs ++)
[node (HTML_INLINE (T.pack "</s>")) []]) ++ )
else (inlinesToNodes opts xs ++)
inlineToNodes opts (Superscript xs) = inlineToNodes opts (Superscript xs) =
if isEnabled Ext_raw_html opts if isEnabled Ext_raw_html opts
then ((node (HTML_INLINE (T.pack "<sup>")) [] : inlinesToNodes opts xs ++ then ((node (HTML_INLINE (T.pack "<sup>")) [] : inlinesToNodes opts xs ++

View file

@ -409,9 +409,5 @@ isMathML _ = False
idAndRole :: Attr -> [(Text, Text)] idAndRole :: Attr -> [(Text, Text)]
idAndRole (id',cls,_) = ident <> role idAndRole (id',cls,_) = ident <> role
where where
ident = if T.null id' ident = [("id", id') | not (T.null id')]
then [] role = [("role", T.unwords cls) | not (null cls)]
else [("id", id')]
role = if null cls
then []
else [("role", T.unwords cls)]

View file

@ -130,9 +130,7 @@ description meta' = do
booktitle :: PandocMonad m => Meta -> FBM m [Content] booktitle :: PandocMonad m => Meta -> FBM m [Content]
booktitle meta' = do booktitle meta' = do
t <- cMapM toXml . docTitle $ meta' t <- cMapM toXml . docTitle $ meta'
return $ if null t return $ [el "book-title" t | not (null t)]
then []
else [ el "book-title" t ]
authors :: Meta -> [Content] authors :: Meta -> [Content]
authors meta' = cMap author (docAuthors meta') authors meta' = cMap author (docAuthors meta')
@ -156,9 +154,7 @@ docdate :: PandocMonad m => Meta -> FBM m [Content]
docdate meta' = do docdate meta' = do
let ss = docDate meta' let ss = docDate meta'
d <- cMapM toXml ss d <- cMapM toXml ss
return $ if null d return $ [el "date" d | not (null d)]
then []
else [el "date" d]
-- | Divide the stream of blocks into sections and convert to XML -- | Divide the stream of blocks into sections and convert to XML
-- representation. -- representation.

View file

@ -663,8 +663,8 @@ blockToHtml opts (Div (ident, "section":dclasses, dkvs)
let fragmentClass = case slideVariant of let fragmentClass = case slideVariant of
RevealJsSlides -> "fragment" RevealJsSlides -> "fragment"
_ -> "incremental" _ -> "incremental"
let inDiv zs = (RawBlock (Format "html") ("<div class=\"" let inDiv zs = RawBlock (Format "html") ("<div class=\""
<> fragmentClass <> "\">")) : <> fragmentClass <> "\">") :
(zs ++ [RawBlock (Format "html") "</div>"]) (zs ++ [RawBlock (Format "html") "</div>"])
let (titleBlocks, innerSecs) = let (titleBlocks, innerSecs) =
if titleSlide if titleSlide
@ -723,8 +723,8 @@ blockToHtml opts (Div attr@(ident, classes, kvs') bs) = do
html5 <- gets stHtml5 html5 <- gets stHtml5
slideVariant <- gets stSlideVariant slideVariant <- gets stSlideVariant
let kvs = [(k,v) | (k,v) <- kvs', k /= "width"] ++ let kvs = [(k,v) | (k,v) <- kvs', k /= "width"] ++
[("style", "width:" <> w <> ";") [("style", "width:" <> w <> ";") | "column" `elem` classes,
| ("width",w) <- kvs', "column" `elem` classes] ++ ("width", w) <- kvs'] ++
[("role", "doc-bibliography") | ident == "refs" && html5] ++ [("role", "doc-bibliography") | ident == "refs" && html5] ++
[("role", "doc-biblioentry") [("role", "doc-biblioentry")
| "ref-item" `T.isPrefixOf` ident && html5] | "ref-item" `T.isPrefixOf` ident && html5]

View file

@ -156,7 +156,7 @@ writeICML opts (Pandoc meta blocks) = do
-- | Auxiliary functions for parStylesToDoc and charStylesToDoc. -- | Auxiliary functions for parStylesToDoc and charStylesToDoc.
contains :: Text -> (Text, (Text, Text)) -> [(Text, Text)] contains :: Text -> (Text, (Text, Text)) -> [(Text, Text)]
contains s rule = contains s rule =
[snd rule | (fst rule) `Text.isInfixOf` s] [snd rule | fst rule `Text.isInfixOf` s]
-- | The monospaced font to use as default. -- | The monospaced font to use as default.
monospacedFont :: Doc Text monospacedFont :: Doc Text

View file

@ -644,9 +644,7 @@ blockToLaTeX (CodeBlock (identifier,classes,keyvalAttr) str) = do
key `notElem` ["exports", "tangle", "results"] key `notElem` ["exports", "tangle", "results"]
-- see #4889 -- see #4889
] ++ ] ++
(if identifier == "" ["label=" <> ref | not (T.null identifier)]
then []
else [ "label=" <> ref ])
else [] else []
printParams printParams
@ -1131,7 +1129,7 @@ inlineToLaTeX (Span (id',classes,kvs) ils) = do
["LR" | ("dir", "ltr") `elem` kvs] ++ ["LR" | ("dir", "ltr") `elem` kvs] ++
(case lang of (case lang of
Just lng -> let (l, o) = toPolyglossia lng Just lng -> let (l, o) = toPolyglossia lng
ops = if T.null o then "" else ("[" <> o <> "]") ops = if T.null o then "" else "[" <> o <> "]"
in ["text" <> l <> ops] in ["text" <> l <> ops]
Nothing -> []) Nothing -> [])
contents <- inlineListToLaTeX ils contents <- inlineListToLaTeX ils

View file

@ -88,8 +88,7 @@ notesToMan :: PandocMonad m => WriterOptions -> [[Block]] -> StateT WriterState
notesToMan opts notes = notesToMan opts notes =
if null notes if null notes
then return empty then return empty
else zipWithM (noteToMan opts) [1..] notes >>= else (text ".SH NOTES" $$) . vcat <$> zipWithM (noteToMan opts) [1..] notes
return . (text ".SH NOTES" $$) . vcat
-- | Return man representation of a note. -- | Return man representation of a note.
noteToMan :: PandocMonad m => WriterOptions -> Int -> [Block] -> StateT WriterState m (Doc Text) noteToMan :: PandocMonad m => WriterOptions -> Int -> [Block] -> StateT WriterState m (Doc Text)

View file

@ -53,4 +53,3 @@ convertMath writer mt str =
where dt = case mt of where dt = case mt of
DisplayMath -> DisplayBlock DisplayMath -> DisplayBlock
InlineMath -> DisplayInline InlineMath -> DisplayInline

View file

@ -16,6 +16,7 @@ MediaWiki: <http://www.mediawiki.org/wiki/MediaWiki>
-} -}
module Text.Pandoc.Writers.MediaWiki ( writeMediaWiki, highlightingLangs ) where module Text.Pandoc.Writers.MediaWiki ( writeMediaWiki, highlightingLangs ) where
import Prelude import Prelude
import Control.Applicative
import Control.Monad.Reader import Control.Monad.Reader
import Control.Monad.State.Strict import Control.Monad.State.Strict
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
@ -166,7 +167,8 @@ blockToMediaWiki (Table capt aligns widths headers rows') = do
return $ "{|\n" <> caption <> tableBody <> "|}\n" return $ "{|\n" <> caption <> tableBody <> "|}\n"
blockToMediaWiki x@(BulletList items) = do blockToMediaWiki x@(BulletList items) = do
tags <- fmap (|| not (isSimpleList x)) $ asks useTags tags <-
(|| not (isSimpleList x)) Control.Applicative.<$> asks useTags
if tags if tags
then do then do
contents <- local (\ s -> s { useTags = True }) $ mapM listItemToMediaWiki items contents <- local (\ s -> s { useTags = True }) $ mapM listItemToMediaWiki items
@ -177,7 +179,8 @@ blockToMediaWiki x@(BulletList items) = do
return $ vcat contents <> if null lev then "\n" else "" return $ vcat contents <> if null lev then "\n" else ""
blockToMediaWiki x@(OrderedList attribs items) = do blockToMediaWiki x@(OrderedList attribs items) = do
tags <- fmap (|| not (isSimpleList x)) $ asks useTags tags <-
(|| not (isSimpleList x)) Control.Applicative.<$> asks useTags
if tags if tags
then do then do
contents <- local (\s -> s { useTags = True }) $ mapM listItemToMediaWiki items contents <- local (\s -> s { useTags = True }) $ mapM listItemToMediaWiki items
@ -188,7 +191,8 @@ blockToMediaWiki x@(OrderedList attribs items) = do
return $ vcat contents <> if null lev then "\n" else "" return $ vcat contents <> if null lev then "\n" else ""
blockToMediaWiki x@(DefinitionList items) = do blockToMediaWiki x@(DefinitionList items) = do
tags <- fmap (|| not (isSimpleList x)) $ asks useTags tags <-
(|| not (isSimpleList x)) Control.Applicative.<$> asks useTags
if tags if tags
then do then do
contents <- local (\s -> s { useTags = True }) $ mapM definitionListItemToMediaWiki items contents <- local (\s -> s { useTags = True }) $ mapM definitionListItemToMediaWiki items
@ -342,7 +346,7 @@ blockListToMediaWiki :: PandocMonad m
=> [Block] -- ^ List of block elements => [Block] -- ^ List of block elements
-> MediaWikiWriter m Text -> MediaWikiWriter m Text
blockListToMediaWiki blocks = blockListToMediaWiki blocks =
fmap vcat $ mapM blockToMediaWiki blocks vcat Control.Applicative.<$> mapM blockToMediaWiki blocks
-- | Convert list of Pandoc inline elements to MediaWiki. -- | Convert list of Pandoc inline elements to MediaWiki.
inlineListToMediaWiki :: PandocMonad m => [Inline] -> MediaWikiWriter m Text inlineListToMediaWiki :: PandocMonad m => [Inline] -> MediaWikiWriter m Text
@ -355,8 +359,8 @@ inlineListToMediaWiki lst =
, isLinkOrImage x = , isLinkOrImage x =
Str t : RawInline (Format "mediawiki") "<nowiki/>" : x : fixup xs Str t : RawInline (Format "mediawiki") "<nowiki/>" : x : fixup xs
fixup (x:xs) = x : fixup xs fixup (x:xs) = x : fixup xs
isLinkOrImage (Link{}) = True isLinkOrImage Link{} = True
isLinkOrImage (Image{}) = True isLinkOrImage Image{} = True
isLinkOrImage _ = False isLinkOrImage _ = False
-- | Convert Pandoc inline element to MediaWiki. -- | Convert Pandoc inline element to MediaWiki.

View file

@ -492,7 +492,7 @@ fixOrEscape b (Str s) = fixOrEscapeStr b s
_ -> (sp && (startsWithMarker isDigit s || _ -> (sp && (startsWithMarker isDigit s ||
startsWithMarker isAsciiLower s || startsWithMarker isAsciiLower s ||
startsWithMarker isAsciiUpper s)) startsWithMarker isAsciiUpper s))
|| stringStartsWithSpace s || stringStartsWithSpace s
fixOrEscape _ Space = True fixOrEscape _ Space = True
fixOrEscape _ SoftBreak = True fixOrEscape _ SoftBreak = True
fixOrEscape _ _ = False fixOrEscape _ _ = False

View file

@ -101,7 +101,7 @@ pandocToODT opts doc@(Pandoc meta _) = do
$ fromStringLazy $ render Nothing $ fromStringLazy $ render Nothing
$ text "<?xml version=\"1.0\" encoding=\"utf-8\"?>" $ text "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
$$ $$
(inTags True "manifest:manifest" inTags True "manifest:manifest"
[("xmlns:manifest","urn:oasis:names:tc:opendocument:xmlns:manifest:1.0") [("xmlns:manifest","urn:oasis:names:tc:opendocument:xmlns:manifest:1.0")
,("manifest:version","1.2")] ( selfClosingTag "manifest:file-entry" ,("manifest:version","1.2")] ( selfClosingTag "manifest:file-entry"
[("manifest:media-type","application/vnd.oasis.opendocument.text") [("manifest:media-type","application/vnd.oasis.opendocument.text")
@ -109,7 +109,6 @@ pandocToODT opts doc@(Pandoc meta _) = do
$$ vcat ( map toFileEntry files ) $$ vcat ( map toFileEntry files )
$$ vcat ( map toFileEntry formulas ) $$ vcat ( map toFileEntry formulas )
) )
)
let archive' = addEntryToArchive manifestEntry archive let archive' = addEntryToArchive manifestEntry archive
-- create meta.xml -- create meta.xml
let userDefinedMetaFields = [k | k <- Map.keys (unMeta meta) let userDefinedMetaFields = [k | k <- Map.keys (unMeta meta)
@ -129,7 +128,7 @@ pandocToODT opts doc@(Pandoc meta _) = do
$ fromStringLazy $ render Nothing $ fromStringLazy $ render Nothing
$ text "<?xml version=\"1.0\" encoding=\"utf-8\"?>" $ text "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
$$ $$
(inTags True "office:document-meta" inTags True "office:document-meta"
[("xmlns:office","urn:oasis:names:tc:opendocument:xmlns:office:1.0") [("xmlns:office","urn:oasis:names:tc:opendocument:xmlns:office:1.0")
,("xmlns:xlink","http://www.w3.org/1999/xlink") ,("xmlns:xlink","http://www.w3.org/1999/xlink")
,("xmlns:dc","http://purl.org/dc/elements/1.1/") ,("xmlns:dc","http://purl.org/dc/elements/1.1/")
@ -163,7 +162,6 @@ pandocToODT opts doc@(Pandoc meta _) = do
vcat userDefinedMeta vcat userDefinedMeta
) )
) )
)
-- make sure mimetype is first -- make sure mimetype is first
let mimetypeEntry = toEntry "mimetype" epochtime let mimetypeEntry = toEntry "mimetype" epochtime
$ fromStringLazy "application/vnd.oasis.opendocument.text" $ fromStringLazy "application/vnd.oasis.opendocument.text"
@ -241,7 +239,7 @@ transformPicMath _ (Math t math) = do
Right r -> do Right r -> do
let conf = useShortEmptyTags (const False) defaultConfigPP let conf = useShortEmptyTags (const False) defaultConfigPP
let mathml = ppcTopElement conf r let mathml = ppcTopElement conf r
epochtime <- floor `fmap` (lift P.getPOSIXTime) epochtime <- floor `fmap` lift P.getPOSIXTime
let dirname = "Formula-" ++ show (length entries) ++ "/" let dirname = "Formula-" ++ show (length entries) ++ "/"
let fname = dirname ++ "content.xml" let fname = dirname ++ "content.xml"
let entry = toEntry fname epochtime (fromStringLazy mathml) let entry = toEntry fname epochtime (fromStringLazy mathml)
@ -269,12 +267,12 @@ documentSettings :: Bool -> B.ByteString
documentSettings isTextMode = fromStringLazy $ render Nothing documentSettings isTextMode = fromStringLazy $ render Nothing
$ text "<?xml version=\"1.0\" encoding=\"utf-8\"?>" $ text "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
$$ $$
(inTags True "office:document-settings" inTags True "office:document-settings"
[("xmlns:office","urn:oasis:names:tc:opendocument:xmlns:office:1.0") [("xmlns:office","urn:oasis:names:tc:opendocument:xmlns:office:1.0")
,("xmlns:xlink","http://www.w3.org/1999/xlink") ,("xmlns:xlink","http://www.w3.org/1999/xlink")
,("xmlns:config","urn:oasis:names:tc:opendocument:xmlns:config:1.0") ,("xmlns:config","urn:oasis:names:tc:opendocument:xmlns:config:1.0")
,("xmlns:ooo","http://openoffice.org/2004/office") ,("xmlns:ooo","http://openoffice.org/2004/office")
,("office:version","1.2")] $ ,("office:version","1.2")] (
inTagsSimple "office:settings" $ inTagsSimple "office:settings" $
inTags False "config:config-item-set" inTags False "config:config-item-set"
[("config:name", "ooo:configuration-settings")] $ [("config:name", "ooo:configuration-settings")] $

View file

@ -19,7 +19,7 @@ import Prelude
import Control.Arrow ((***), (>>>)) import Control.Arrow ((***), (>>>))
import Control.Monad.State.Strict hiding (when) import Control.Monad.State.Strict hiding (when)
import Data.Char (chr) import Data.Char (chr)
import Data.List (sortBy, foldl') import Data.List (sortOn, sortBy, foldl')
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.Ord (comparing) import Data.Ord (comparing)
@ -163,7 +163,7 @@ inTextStyle d = do
[("style:name", styleName) [("style:name", styleName)
,("style:family", "text")] ,("style:family", "text")]
$ selfClosingTag "style:text-properties" $ selfClosingTag "style:text-properties"
(sortBy (comparing fst) . Map.toList (sortOn fst . Map.toList
$ foldl' textStyleAttr mempty (Set.toList at))) $ foldl' textStyleAttr mempty (Set.toList at)))
return $ inTags False return $ inTags False
"text:span" [("text:style-name",styleName)] d "text:span" [("text:style-name",styleName)] d

View file

@ -41,7 +41,7 @@ import Text.Pandoc.MIME
import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy as BL
import Text.Pandoc.Writers.OOXML import Text.Pandoc.Writers.OOXML
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe (mapMaybe, listToMaybe, fromMaybe, maybeToList, catMaybes, isNothing) import Data.Maybe (mapMaybe, listToMaybe, fromMaybe, maybeToList, catMaybes, isJust)
import Text.Pandoc.ImageSize import Text.Pandoc.ImageSize
import Control.Applicative ((<|>)) import Control.Applicative ((<|>))
import System.FilePath.Glob import System.FilePath.Glob
@ -254,7 +254,7 @@ presentationToArchiveP p@(Presentation docProps slides) = do
(throwError $ (throwError $
PandocSomeError $ PandocSomeError $
"The following required files are missing:\n" <> "The following required files are missing:\n" <>
(T.unlines $ map (T.pack . (" " <>)) missingFiles) T.unlines (map (T.pack . (" " <>)) missingFiles)
) )
newArch' <- foldM copyFileToArchive emptyArchive filePaths newArch' <- foldM copyFileToArchive emptyArchive filePaths
@ -291,11 +291,12 @@ presentationToArchiveP p@(Presentation docProps slides) = do
makeSlideIdMap :: Presentation -> M.Map SlideId Int makeSlideIdMap :: Presentation -> M.Map SlideId Int
makeSlideIdMap (Presentation _ slides) = makeSlideIdMap (Presentation _ slides) =
M.fromList $ (map slideId slides) `zip` [1..] M.fromList $ map slideId slides `zip` [1..]
makeSpeakerNotesMap :: Presentation -> M.Map Int Int makeSpeakerNotesMap :: Presentation -> M.Map Int Int
makeSpeakerNotesMap (Presentation _ slides) = makeSpeakerNotesMap (Presentation _ slides) =
M.fromList $ (mapMaybe f $ slides `zip` [1..]) `zip` [1..] M.fromList $
mapMaybe f (slides `zip` [1..]) `zip` [1..]
where f (Slide _ _ notes, n) = if notes == mempty where f (Slide _ _ notes, n) = if notes == mempty
then Nothing then Nothing
else Just n else Just n
@ -350,10 +351,10 @@ curSlideHasSpeakerNotes =
getLayout :: PandocMonad m => Layout -> P m Element getLayout :: PandocMonad m => Layout -> P m Element
getLayout layout = do getLayout layout = do
let layoutpath = case layout of let layoutpath = case layout of
(MetadataSlide _ _ _ _) -> "ppt/slideLayouts/slideLayout1.xml" (MetadataSlide{}) -> "ppt/slideLayouts/slideLayout1.xml"
(TitleSlide _) -> "ppt/slideLayouts/slideLayout3.xml" (TitleSlide _) -> "ppt/slideLayouts/slideLayout3.xml"
(ContentSlide _ _) -> "ppt/slideLayouts/slideLayout2.xml" (ContentSlide _ _) -> "ppt/slideLayouts/slideLayout2.xml"
(TwoColumnSlide _ _ _) -> "ppt/slideLayouts/slideLayout4.xml" (TwoColumnSlide{}) -> "ppt/slideLayouts/slideLayout4.xml"
refArchive <- asks envRefArchive refArchive <- asks envRefArchive
distArchive <- asks envDistArchive distArchive <- asks envDistArchive
parseXml refArchive distArchive layoutpath parseXml refArchive distArchive layoutpath
@ -409,7 +410,7 @@ getMasterShapeDimensionsById ident master = do
let ns = elemToNameSpaces master let ns = elemToNameSpaces master
cSld <- findChild (elemName ns "p" "cSld") master cSld <- findChild (elemName ns "p" "cSld") master
spTree <- findChild (elemName ns "p" "spTree") cSld spTree <- findChild (elemName ns "p" "spTree") cSld
sp <- filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasId ns ident e)) spTree sp <- filterChild (\e -> isElem ns "p" "sp" e && shapeHasId ns ident e) spTree
getShapeDimensions ns sp getShapeDimensions ns sp
getContentShapeSize :: PandocMonad m getContentShapeSize :: PandocMonad m
@ -457,7 +458,7 @@ replaceNamedChildren ns prefix name newKids element =
where where
fun :: Bool -> [Content] -> [[Content]] fun :: Bool -> [Content] -> [[Content]]
fun _ [] = [] fun _ [] = []
fun switch ((Elem e) : conts) | isElem ns prefix name e = fun switch (Elem e : conts) | isElem ns prefix name e =
if switch if switch
then map Elem newKids : fun False conts then map Elem newKids : fun False conts
else fun False conts else fun False conts
@ -522,9 +523,7 @@ registerMedia fp caption = do
Just Emf -> Just ".emf" Just Emf -> Just ".emf"
Nothing -> Nothing Nothing -> Nothing
let newGlobalId = case M.lookup fp globalIds of let newGlobalId = fromMaybe (maxGlobalId + 1) (M.lookup fp globalIds)
Just ident -> ident
Nothing -> maxGlobalId + 1
let newGlobalIds = M.insert fp newGlobalId globalIds let newGlobalIds = M.insert fp newGlobalId globalIds
@ -550,10 +549,9 @@ makeMediaEntry :: PandocMonad m => MediaInfo -> P m Entry
makeMediaEntry mInfo = do makeMediaEntry mInfo = do
epochtime <- (floor . utcTimeToPOSIXSeconds) <$> asks envUTCTime epochtime <- (floor . utcTimeToPOSIXSeconds) <$> asks envUTCTime
(imgBytes, _) <- P.fetchItem (T.pack $ mInfoFilePath mInfo) (imgBytes, _) <- P.fetchItem (T.pack $ mInfoFilePath mInfo)
let ext = case mInfoExt mInfo of let ext = fromMaybe "" (mInfoExt mInfo)
Just e -> e let fp = "ppt/media/image" <>
Nothing -> "" show (mInfoGlobalId mInfo) <> T.unpack ext
let fp = "ppt/media/image" <> (show $ mInfoGlobalId mInfo) <> T.unpack ext
return $ toEntry fp epochtime $ BL.fromStrict imgBytes return $ toEntry fp epochtime $ BL.fromStrict imgBytes
makeMediaEntries :: PandocMonad m => P m [Entry] makeMediaEntries :: PandocMonad m => P m [Entry]
@ -717,7 +715,8 @@ makePicElements layout picProps mInfo alt = do
, cNvPicPr , cNvPicPr
, mknode "p:nvPr" [] ()] , mknode "p:nvPr" [] ()]
let blipFill = mknode "p:blipFill" [] let blipFill = mknode "p:blipFill" []
[ mknode "a:blip" [("r:embed", "rId" <> (show $ mInfoLocalId mInfo))] () [ mknode "a:blip" [("r:embed", "rId" <>
show (mInfoLocalId mInfo))] ()
, mknode "a:stretch" [] $ , mknode "a:stretch" [] $
mknode "a:fillRect" [] () ] mknode "a:fillRect" [] () ]
let xfrm = mknode "a:xfrm" [] let xfrm = mknode "a:xfrm" []
@ -750,9 +749,12 @@ paraElemToElements Break = return [mknode "a:br" [] ()]
paraElemToElements (Run rpr s) = do paraElemToElements (Run rpr s) = do
sizeAttrs <- fontSizeAttributes rpr sizeAttrs <- fontSizeAttributes rpr
let attrs = sizeAttrs <> let attrs = sizeAttrs <>
(if rPropBold rpr then [("b", "1")] else []) <> (
(if rPropItalics rpr then [("i", "1")] else []) <> [("b", "1") | rPropBold rpr]) <>
(if rPropUnderline rpr then [("u", "sng")] else []) <> (
[("i", "1") | rPropItalics rpr]) <>
(
[("u", "sng") | rPropUnderline rpr]) <>
(case rStrikethrough rpr of (case rStrikethrough rpr of
Just NoStrike -> [("strike", "noStrike")] Just NoStrike -> [("strike", "noStrike")]
Just SingleStrike -> [("strike", "sngStrike")] Just SingleStrike -> [("strike", "sngStrike")]
@ -796,9 +798,8 @@ paraElemToElements (Run rpr s) = do
_ -> [] _ -> []
Nothing -> [] Nothing -> []
codeFont <- monospaceFont codeFont <- monospaceFont
let codeContents = if rPropCode rpr let codeContents =
then [mknode "a:latin" [("typeface", T.unpack codeFont)] ()] [mknode "a:latin" [("typeface", T.unpack codeFont)] () | rPropCode rpr]
else []
let propContents = linkProps <> colorContents <> codeContents let propContents = linkProps <> colorContents <> codeContents
return [mknode "a:r" [] [ mknode "a:rPr" attrs propContents return [mknode "a:r" [] [ mknode "a:rPr" attrs propContents
, mknode "a:t" [] $ T.unpack s , mknode "a:t" [] $ T.unpack s
@ -817,7 +818,7 @@ paraElemToElements (RawOOXMLParaElem str) = return [ x | Elem x <- parseXML str
-- step at a time. -- step at a time.
addMathInfo :: Element -> Element addMathInfo :: Element -> Element
addMathInfo element = addMathInfo element =
let mathspace = Attr { attrKey = (QName "m" Nothing (Just "xmlns")) let mathspace = Attr { attrKey = QName "m" Nothing (Just "xmlns")
, attrVal = "http://schemas.openxmlformats.org/officeDocument/2006/math" , attrVal = "http://schemas.openxmlformats.org/officeDocument/2006/math"
} }
in add_attr mathspace element in add_attr mathspace element
@ -920,7 +921,7 @@ graphicFrameToElements layout tbls caption = do
`catchError` `catchError`
(\_ -> return ((0, 0), (pageWidth, pageHeight))) (\_ -> return ((0, 0), (pageWidth, pageHeight)))
let cy = if (not $ null caption) then cytmp - captionHeight else cytmp let cy = if not $ null caption then cytmp - captionHeight else cytmp
elements <- mapM (graphicToElement cx) tbls elements <- mapM (graphicToElement cx) tbls
let graphicFrameElts = let graphicFrameElts =
@ -938,7 +939,7 @@ graphicFrameToElements layout tbls caption = do
] ]
] <> elements ] <> elements
if (not $ null caption) if not $ null caption
then do capElt <- createCaption ((x, y), (cx, cytmp)) caption then do capElt <- createCaption ((x, y), (cx, cytmp)) caption
return [graphicFrameElts, capElt] return [graphicFrameElts, capElt]
else return [graphicFrameElts] else return [graphicFrameElts]
@ -1079,9 +1080,7 @@ contentToElement layout hdrShape shapes
, Just cSld <- findChild (elemName ns "p" "cSld") layout , Just cSld <- findChild (elemName ns "p" "cSld") layout
, Just spTree <- findChild (elemName ns "p" "spTree") cSld = do , Just spTree <- findChild (elemName ns "p" "spTree") cSld = do
element <- nonBodyTextToElement layout [PHType "title"] hdrShape element <- nonBodyTextToElement layout [PHType "title"] hdrShape
let hdrShapeElements = if null hdrShape let hdrShapeElements = [element | not (null hdrShape)]
then []
else [element]
contentElements <- local contentElements <- local
(\env -> env {envContentType = NormalContent}) (\env -> env {envContentType = NormalContent})
(shapesToElements layout shapes) (shapesToElements layout shapes)
@ -1094,9 +1093,7 @@ twoColumnToElement layout hdrShape shapesL shapesR
, Just cSld <- findChild (elemName ns "p" "cSld") layout , Just cSld <- findChild (elemName ns "p" "cSld") layout
, Just spTree <- findChild (elemName ns "p" "spTree") cSld = do , Just spTree <- findChild (elemName ns "p" "spTree") cSld = do
element <- nonBodyTextToElement layout [PHType "title"] hdrShape element <- nonBodyTextToElement layout [PHType "title"] hdrShape
let hdrShapeElements = if null hdrShape let hdrShapeElements = [element | not (null hdrShape)]
then []
else [element]
contentElementsL <- local contentElementsL <- local
(\env -> env {envContentType =TwoColumnLeftContent}) (\env -> env {envContentType =TwoColumnLeftContent})
(shapesToElements layout shapesL) (shapesToElements layout shapesL)
@ -1115,9 +1112,7 @@ titleToElement layout titleElems
, Just cSld <- findChild (elemName ns "p" "cSld") layout , Just cSld <- findChild (elemName ns "p" "cSld") layout
, Just spTree <- findChild (elemName ns "p" "spTree") cSld = do , Just spTree <- findChild (elemName ns "p" "spTree") cSld = do
element <- nonBodyTextToElement layout [PHType "title", PHType "ctrTitle"] titleElems element <- nonBodyTextToElement layout [PHType "title", PHType "ctrTitle"] titleElems
let titleShapeElements = if null titleElems let titleShapeElements = [element | not (null titleElems)]
then []
else [element]
return $ buildSpTree ns spTree titleShapeElements return $ buildSpTree ns spTree titleShapeElements
titleToElement _ _ = return $ mknode "p:sp" [] () titleToElement _ _ = return $ mknode "p:sp" [] ()
@ -1395,12 +1390,10 @@ presentationToRels :: PandocMonad m => Presentation -> P m [Relationship]
presentationToRels pres@(Presentation _ slides) = do presentationToRels pres@(Presentation _ slides) = do
mySlideRels <- mapM slideToPresRel slides mySlideRels <- mapM slideToPresRel slides
let notesMasterRels = let notesMasterRels =
if presHasSpeakerNotes pres [Relationship { relId = length mySlideRels + 2
then [Relationship { relId = length mySlideRels + 2 , relType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster"
, relType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster" , relTarget = "notesMasters/notesMaster1.xml"
, relTarget = "notesMasters/notesMaster1.xml" } | presHasSpeakerNotes pres]
}]
else []
insertedRels = mySlideRels <> notesMasterRels insertedRels = mySlideRels <> notesMasterRels
rels <- getRels rels <- getRels
-- we remove the slide rels and the notesmaster (if it's -- we remove the slide rels and the notesmaster (if it's
@ -1459,7 +1452,8 @@ topLevelRelsEntry :: PandocMonad m => P m Entry
topLevelRelsEntry = elemToEntry "_rels/.rels" $ relsToElement topLevelRels topLevelRelsEntry = elemToEntry "_rels/.rels" $ relsToElement topLevelRels
relToElement :: Relationship -> Element relToElement :: Relationship -> Element
relToElement rel = mknode "Relationship" [ ("Id", "rId" <> (show $ relId rel)) relToElement rel = mknode "Relationship" [ ("Id", "rId" <>
show (relId rel))
, ("Type", T.unpack $ relType rel) , ("Type", T.unpack $ relType rel)
, ("Target", relTarget rel) ] () , ("Target", relTarget rel) ] ()
@ -1502,7 +1496,8 @@ slideToSpeakerNotesEntry slide = do
slideToSpeakerNotesRelElement :: PandocMonad m => Slide -> P m (Maybe Element) slideToSpeakerNotesRelElement :: PandocMonad m => Slide -> P m (Maybe Element)
slideToSpeakerNotesRelElement (Slide _ _ (SpeakerNotes [])) = return Nothing slideToSpeakerNotesRelElement (Slide _ _ (SpeakerNotes [])) = return Nothing
slideToSpeakerNotesRelElement slide@(Slide _ _ _) = do slideToSpeakerNotesRelElement slide@(
Slide{}) = do
idNum <- slideNum slide idNum <- slideNum slide
return $ Just $ return $ Just $
mknode "Relationships" mknode "Relationships"
@ -1559,13 +1554,13 @@ linkRelElements mp = mapM linkRelElement (M.toList mp)
mediaRelElement :: MediaInfo -> Element mediaRelElement :: MediaInfo -> Element
mediaRelElement mInfo = mediaRelElement mInfo =
let ext = case mInfoExt mInfo of let ext = fromMaybe "" (mInfoExt mInfo)
Just e -> e
Nothing -> ""
in in
mknode "Relationship" [ ("Id", "rId" <> (show $ mInfoLocalId mInfo)) mknode "Relationship" [ ("Id", "rId" <>
show (mInfoLocalId mInfo))
, ("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") , ("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image")
, ("Target", "../media/image" <> (show $ mInfoGlobalId mInfo) <> T.unpack ext) , ("Target", "../media/image" <>
show (mInfoGlobalId mInfo) <> T.unpack ext)
] () ] ()
speakerNotesSlideRelElement :: PandocMonad m => Slide -> P m (Maybe Element) speakerNotesSlideRelElement :: PandocMonad m => Slide -> P m (Maybe Element)
@ -1586,10 +1581,10 @@ slideToSlideRelElement :: PandocMonad m => Slide -> P m Element
slideToSlideRelElement slide = do slideToSlideRelElement slide = do
idNum <- slideNum slide idNum <- slideNum slide
let target = case slide of let target = case slide of
(Slide _ (MetadataSlide _ _ _ _) _) -> "../slideLayouts/slideLayout1.xml" (Slide _ (MetadataSlide{}) _) -> "../slideLayouts/slideLayout1.xml"
(Slide _ (TitleSlide _) _) -> "../slideLayouts/slideLayout3.xml" (Slide _ (TitleSlide _) _) -> "../slideLayouts/slideLayout3.xml"
(Slide _ (ContentSlide _ _) _) -> "../slideLayouts/slideLayout2.xml" (Slide _ (ContentSlide _ _) _) -> "../slideLayouts/slideLayout2.xml"
(Slide _ (TwoColumnSlide _ _ _) _) -> "../slideLayouts/slideLayout4.xml" (Slide _ (TwoColumnSlide{}) _) -> "../slideLayouts/slideLayout4.xml"
speakerNotesRels <- maybeToList <$> speakerNotesSlideRelElement slide speakerNotesRels <- maybeToList <$> speakerNotesSlideRelElement slide
@ -1696,15 +1691,15 @@ docPropsElement docProps = do
,("xmlns:dcterms","http://purl.org/dc/terms/") ,("xmlns:dcterms","http://purl.org/dc/terms/")
,("xmlns:dcmitype","http://purl.org/dc/dcmitype/") ,("xmlns:dcmitype","http://purl.org/dc/dcmitype/")
,("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance")] ,("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance")]
$ (mknode "dc:title" [] $ maybe "" T.unpack $ dcTitle docProps) $
: (mknode "dc:creator" [] $ maybe "" T.unpack $ dcCreator docProps) mknode "dc:title" [] (maybe "" T.unpack $ dcTitle docProps)
: (mknode "cp:keywords" [] $ T.unpack keywords) :
: (if isNothing (dcSubject docProps) then [] else mknode "dc:creator" [] (maybe "" T.unpack $ dcCreator docProps)
[mknode "dc:subject" [] $ maybe "" T.unpack $ dcSubject docProps]) :
<> (if isNothing (dcDescription docProps) then [] else mknode "cp:keywords" [] (T.unpack keywords)
[mknode "dc:description" [] $ maybe "" T.unpack $ dcDescription docProps]) : ( [mknode "dc:subject" [] $ maybe "" T.unpack $ dcSubject docProps | isJust (dcSubject docProps)])
<> (if isNothing (cpCategory docProps) then [] else <> ( [mknode "dc:description" [] $ maybe "" T.unpack $ dcDescription docProps | isJust (dcDescription docProps)])
[mknode "cp:category" [] $ maybe "" T.unpack $ cpCategory docProps]) <> ( [mknode "cp:category" [] $ maybe "" T.unpack $ cpCategory docProps | isJust (cpCategory docProps)])
<> (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x <> (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x
, mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x , mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x
]) (formatTime defaultTimeLocale "%FT%XZ" utctime) ]) (formatTime defaultTimeLocale "%FT%XZ" utctime)
@ -1739,7 +1734,8 @@ viewPropsElement = do
viewPrElement <- parseXml refArchive distArchive "ppt/viewProps.xml" viewPrElement <- parseXml refArchive distArchive "ppt/viewProps.xml"
-- remove "lastView" if it exists: -- remove "lastView" if it exists:
let notLastView :: Text.XML.Light.Attr -> Bool let notLastView :: Text.XML.Light.Attr -> Bool
notLastView attr = (qName $ attrKey attr) /= "lastView" notLastView attr =
qName (attrKey attr) /= "lastView"
return $ return $
viewPrElement {elAttribs = filter notLastView (elAttribs viewPrElement)} viewPrElement {elAttribs = filter notLastView (elAttribs viewPrElement)}
@ -1765,8 +1761,9 @@ contentTypesToElement ct =
let ns = "http://schemas.openxmlformats.org/package/2006/content-types" let ns = "http://schemas.openxmlformats.org/package/2006/content-types"
in in
mknode "Types" [("xmlns", ns)] $ mknode "Types" [("xmlns", ns)] $
(map defaultContentTypeToElem $ contentTypesDefaults ct) <>
(map overrideContentTypeToElem $ contentTypesOverrides ct) map defaultContentTypeToElem (contentTypesDefaults ct) <>
map overrideContentTypeToElem (contentTypesOverrides ct)
data DefaultContentType = DefaultContentType data DefaultContentType = DefaultContentType
{ defContentTypesExt :: T.Text { defContentTypesExt :: T.Text
@ -1789,16 +1786,14 @@ contentTypesToEntry :: PandocMonad m => ContentTypes -> P m Entry
contentTypesToEntry ct = elemToEntry "[Content_Types].xml" $ contentTypesToElement ct contentTypesToEntry ct = elemToEntry "[Content_Types].xml" $ contentTypesToElement ct
pathToOverride :: FilePath -> Maybe OverrideContentType pathToOverride :: FilePath -> Maybe OverrideContentType
pathToOverride fp = OverrideContentType ("/" <> fp) <$> (getContentType fp) pathToOverride fp = OverrideContentType ("/" <> fp) <$> getContentType fp
mediaFileContentType :: FilePath -> Maybe DefaultContentType mediaFileContentType :: FilePath -> Maybe DefaultContentType
mediaFileContentType fp = case takeExtension fp of mediaFileContentType fp = case takeExtension fp of
'.' : ext -> Just $ '.' : ext -> Just $
DefaultContentType { defContentTypesExt = T.pack ext DefaultContentType { defContentTypesExt = T.pack ext
, defContentTypesType = , defContentTypesType =
case getMimeType fp of fromMaybe "application/octet-stream" (getMimeType fp)
Just mt -> mt
Nothing -> "application/octet-stream"
} }
_ -> Nothing _ -> Nothing
@ -1808,9 +1803,7 @@ mediaContentType mInfo
, Just ('.', ext) <- T.uncons t = , Just ('.', ext) <- T.uncons t =
Just $ DefaultContentType { defContentTypesExt = ext Just $ DefaultContentType { defContentTypesExt = ext
, defContentTypesType = , defContentTypesType =
case mInfoMimeType mInfo of fromMaybe "application/octet-stream" (mInfoMimeType mInfo)
Just mt -> mt
Nothing -> "application/octet-stream"
} }
| otherwise = Nothing | otherwise = Nothing
@ -1842,7 +1835,7 @@ presentationToContentTypes p@(Presentation _ slides) = do
let slideOverrides = mapMaybe let slideOverrides = mapMaybe
(\fp -> pathToOverride $ "ppt/slides/" <> fp) (\fp -> pathToOverride $ "ppt/slides/" <> fp)
relativePaths relativePaths
speakerNotesOverrides <- (mapMaybe pathToOverride) <$> getSpeakerNotesFilePaths speakerNotesOverrides <- mapMaybe pathToOverride <$> getSpeakerNotesFilePaths
return $ ContentTypes return $ ContentTypes
(defaults <> mediaDefaults) (defaults <> mediaDefaults)
(inheritedOverrides <> createdOverrides <> slideOverrides <> speakerNotesOverrides) (inheritedOverrides <> createdOverrides <> slideOverrides <> speakerNotesOverrides)
@ -1862,22 +1855,22 @@ getContentType fp
| fp == "docProps/core.xml" = Just "application/vnd.openxmlformats-package.core-properties+xml" | fp == "docProps/core.xml" = Just "application/vnd.openxmlformats-package.core-properties+xml"
| fp == "docProps/custom.xml" = Just "application/vnd.openxmlformats-officedocument.custom-properties+xml" | fp == "docProps/custom.xml" = Just "application/vnd.openxmlformats-officedocument.custom-properties+xml"
| fp == "docProps/app.xml" = Just $ noPresML <> ".extended-properties+xml" | fp == "docProps/app.xml" = Just $ noPresML <> ".extended-properties+xml"
| "ppt" : "slideMasters" : f : [] <- splitDirectories fp | ["ppt", "slideMasters", f] <- splitDirectories fp
, (_, ".xml") <- splitExtension f = , (_, ".xml") <- splitExtension f =
Just $ presML <> ".slideMaster+xml" Just $ presML <> ".slideMaster+xml"
| "ppt" : "slides" : f : [] <- splitDirectories fp | ["ppt", "slides", f] <- splitDirectories fp
, (_, ".xml") <- splitExtension f = , (_, ".xml") <- splitExtension f =
Just $ presML <> ".slide+xml" Just $ presML <> ".slide+xml"
| "ppt" : "notesMasters" : f : [] <- splitDirectories fp | ["ppt", "notesMasters", f] <- splitDirectories fp
, (_, ".xml") <- splitExtension f = , (_, ".xml") <- splitExtension f =
Just $ presML <> ".notesMaster+xml" Just $ presML <> ".notesMaster+xml"
| "ppt" : "notesSlides" : f : [] <- splitDirectories fp | ["ppt", "notesSlides", f] <- splitDirectories fp
, (_, ".xml") <- splitExtension f = , (_, ".xml") <- splitExtension f =
Just $ presML <> ".notesSlide+xml" Just $ presML <> ".notesSlide+xml"
| "ppt" : "theme" : f : [] <- splitDirectories fp | ["ppt", "theme", f] <- splitDirectories fp
, (_, ".xml") <- splitExtension f = , (_, ".xml") <- splitExtension f =
Just $ noPresML <> ".theme+xml" Just $ noPresML <> ".theme+xml"
| "ppt" : "slideLayouts" : _ : [] <- splitDirectories fp= | ["ppt", "slideLayouts", _] <- splitDirectories fp=
Just $ presML <> ".slideLayout+xml" Just $ presML <> ".slideLayout+xml"
| otherwise = Nothing | otherwise = Nothing
@ -1886,9 +1879,7 @@ autoNumAttrs :: ListAttributes -> [(String, String)]
autoNumAttrs (startNum, numStyle, numDelim) = autoNumAttrs (startNum, numStyle, numDelim) =
numAttr <> typeAttr numAttr <> typeAttr
where where
numAttr = if startNum == 1 numAttr = [("startAt", show startNum) | startNum /= 1]
then []
else [("startAt", show startNum)]
typeAttr = [("type", typeString <> delimString)] typeAttr = [("type", typeString <> delimString)]
typeString = case numStyle of typeString = case numStyle of
Decimal -> "arabic" Decimal -> "arabic"

View file

@ -580,15 +580,15 @@ isImage (Link _ (Image{} : _) _) = True
isImage _ = False isImage _ = False
splitBlocks' :: [Block] -> [[Block]] -> [Block] -> Pres [[Block]] splitBlocks' :: [Block] -> [[Block]] -> [Block] -> Pres [[Block]]
splitBlocks' cur acc [] = return $ acc ++ (if null cur then [] else [cur]) splitBlocks' cur acc [] = return $ acc ++ ([cur | not (null cur)])
splitBlocks' cur acc (HorizontalRule : blks) = splitBlocks' cur acc (HorizontalRule : blks) =
splitBlocks' [] (acc ++ (if null cur then [] else [cur])) blks splitBlocks' [] (acc ++ ([cur | not (null cur)])) blks
splitBlocks' cur acc (h@(Header n _ _) : blks) = do splitBlocks' cur acc (h@(Header n _ _) : blks) = do
slideLevel <- asks envSlideLevel slideLevel <- asks envSlideLevel
let (nts, blks') = span isNotesDiv blks let (nts, blks') = span isNotesDiv blks
case compare n slideLevel of case compare n slideLevel of
LT -> splitBlocks' [] (acc ++ (if null cur then [] else [cur]) ++ [h : nts]) blks' LT -> splitBlocks' [] (acc ++ ([cur | not (null cur)]) ++ [h : nts]) blks'
EQ -> splitBlocks' (h:nts) (acc ++ (if null cur then [] else [cur])) blks' EQ -> splitBlocks' (h:nts) (acc ++ ([cur | not (null cur)])) blks'
GT -> splitBlocks' (cur ++ (h:nts)) acc blks' GT -> splitBlocks' (cur ++ (h:nts)) acc blks'
-- `blockToParagraphs` treats Plain and Para the same, so we can save -- `blockToParagraphs` treats Plain and Para the same, so we can save
-- some code duplication by treating them the same here. -- some code duplication by treating them the same here.
@ -604,7 +604,7 @@ splitBlocks' cur acc (Para (il:ils) : blks) | isImage il = do
(acc ++ [cur ++ [Para [il]] ++ nts]) (acc ++ [cur ++ [Para [il]] ++ nts])
(if null ils then blks' else Para ils : blks') (if null ils then blks' else Para ils : blks')
_ -> splitBlocks' [] _ -> splitBlocks' []
(acc ++ (if null cur then [] else [cur]) ++ [[Para [il]] ++ nts]) (acc ++ ([cur | not (null cur)]) ++ [Para [il] : nts])
(if null ils then blks' else Para ils : blks') (if null ils then blks' else Para ils : blks')
splitBlocks' cur acc (tbl@Table{} : blks) = do splitBlocks' cur acc (tbl@Table{} : blks) = do
slideLevel <- asks envSlideLevel slideLevel <- asks envSlideLevel
@ -612,14 +612,14 @@ splitBlocks' cur acc (tbl@Table{} : blks) = do
case cur of case cur of
[Header n _ _] | n == slideLevel -> [Header n _ _] | n == slideLevel ->
splitBlocks' [] (acc ++ [cur ++ [tbl] ++ nts]) blks' splitBlocks' [] (acc ++ [cur ++ [tbl] ++ nts]) blks'
_ -> splitBlocks' [] (acc ++ (if null cur then [] else [cur]) ++ [[tbl] ++ nts]) blks' _ -> splitBlocks' [] (acc ++ ([cur | not (null cur)]) ++ [tbl : nts]) blks'
splitBlocks' cur acc (d@(Div (_, classes, _) _): blks) | "columns" `elem` classes = do splitBlocks' cur acc (d@(Div (_, classes, _) _): blks) | "columns" `elem` classes = do
slideLevel <- asks envSlideLevel slideLevel <- asks envSlideLevel
let (nts, blks') = span isNotesDiv blks let (nts, blks') = span isNotesDiv blks
case cur of case cur of
[Header n _ _] | n == slideLevel -> [Header n _ _] | n == slideLevel ->
splitBlocks' [] (acc ++ [cur ++ [d] ++ nts]) blks' splitBlocks' [] (acc ++ [cur ++ [d] ++ nts]) blks'
_ -> splitBlocks' [] (acc ++ (if null cur then [] else [cur]) ++ [[d] ++ nts]) blks' _ -> splitBlocks' [] (acc ++ ([cur | not (null cur)]) ++ [d : nts]) blks'
splitBlocks' cur acc (blk : blks) = splitBlocks' (cur ++ [blk]) acc blks splitBlocks' cur acc (blk : blks) = splitBlocks' (cur ++ [blk]) acc blks
splitBlocks :: [Block] -> Pres [[Block]] splitBlocks :: [Block] -> Pres [[Block]]
@ -692,7 +692,7 @@ blockToSpeakerNotes _ = return mempty
handleSpeakerNotes :: Block -> Pres () handleSpeakerNotes :: Block -> Pres ()
handleSpeakerNotes blk = do handleSpeakerNotes blk = do
spNotes <- blockToSpeakerNotes blk spNotes <- blockToSpeakerNotes blk
modify $ \st -> st{stSpeakerNotes = (stSpeakerNotes st) <> spNotes} modify $ \st -> st{stSpeakerNotes = stSpeakerNotes st <> spNotes}
handleAndFilterSpeakerNotes' :: [Block] -> Pres [Block] handleAndFilterSpeakerNotes' :: [Block] -> Pres [Block]
handleAndFilterSpeakerNotes' blks = do handleAndFilterSpeakerNotes' blks = do
@ -763,7 +763,7 @@ getMetaSlide = do
mempty mempty
addSpeakerNotesToMetaSlide :: Slide -> [Block] -> Pres (Slide, [Block]) addSpeakerNotesToMetaSlide :: Slide -> [Block] -> Pres (Slide, [Block])
addSpeakerNotesToMetaSlide (Slide sldId layout@(MetadataSlide _ _ _ _) spkNotes) blks = addSpeakerNotesToMetaSlide (Slide sldId layout@(MetadataSlide{}) spkNotes) blks =
do let (ntsBlks, blks') = span isNotesDiv blks do let (ntsBlks, blks') = span isNotesDiv blks
spkNotes' <- mconcat <$> mapM blockToSpeakerNotes ntsBlks spkNotes' <- mconcat <$> mapM blockToSpeakerNotes ntsBlks
return (Slide sldId layout (spkNotes <> spkNotes'), blks') return (Slide sldId layout (spkNotes <> spkNotes'), blks')
@ -877,7 +877,7 @@ emptyLayout layout = case layout of
all emptyShape shapes2 all emptyShape shapes2
emptySlide :: Slide -> Bool emptySlide :: Slide -> Bool
emptySlide (Slide _ layout notes) = (notes == mempty) && (emptyLayout layout) emptySlide (Slide _ layout notes) = (notes == mempty) && emptyLayout layout
blocksToPresentationSlides :: [Block] -> Pres [Slide] blocksToPresentationSlides :: [Block] -> Pres [Slide]
blocksToPresentationSlides blks = do blocksToPresentationSlides blks = do

View file

@ -103,7 +103,8 @@ pandocToRST (Pandoc meta blocks) = do
-- | Return RST representation of reference key table. -- | Return RST representation of reference key table.
refsToRST :: PandocMonad m => Refs -> RST m (Doc Text) refsToRST :: PandocMonad m => Refs -> RST m (Doc Text)
refsToRST refs = mapM keyToRST refs >>= return . vcat refsToRST refs =
vcat <$> mapM keyToRST refs
-- | Return RST representation of a reference key. -- | Return RST representation of a reference key.
keyToRST :: PandocMonad m => ([Inline], (Text, Text)) -> RST m (Doc Text) keyToRST :: PandocMonad m => ([Inline], (Text, Text)) -> RST m (Doc Text)
@ -117,8 +118,7 @@ keyToRST (label, (src, _)) = do
-- | Return RST representation of notes. -- | Return RST representation of notes.
notesToRST :: PandocMonad m => [[Block]] -> RST m (Doc Text) notesToRST :: PandocMonad m => [[Block]] -> RST m (Doc Text)
notesToRST notes = notesToRST notes =
zipWithM noteToRST [1..] notes >>= vsep <$> zipWithM noteToRST [1..] notes
return . vsep
-- | Return RST representation of a note. -- | Return RST representation of a note.
noteToRST :: PandocMonad m => Int -> [Block] -> RST m (Doc Text) noteToRST :: PandocMonad m => Int -> [Block] -> RST m (Doc Text)
@ -131,7 +131,8 @@ noteToRST num note = do
pictRefsToRST :: PandocMonad m pictRefsToRST :: PandocMonad m
=> [([Inline], (Attr, Text, Text, Maybe Text))] => [([Inline], (Attr, Text, Text, Maybe Text))]
-> RST m (Doc Text) -> RST m (Doc Text)
pictRefsToRST refs = mapM pictToRST refs >>= return . vcat pictRefsToRST refs =
vcat <$> mapM pictToRST refs
-- | Return RST representation of a picture substitution reference. -- | Return RST representation of a picture substitution reference.
pictToRST :: PandocMonad m pictToRST :: PandocMonad m
@ -507,11 +508,11 @@ flatten outer
(Span ("",[],[]) _, _) -> keep f i (Span ("",[],[]) _, _) -> keep f i
(_, Span ("",[],[]) _) -> keep f i (_, Span ("",[],[]) _) -> keep f i
-- inlineToRST handles this case properly so it's safe to keep -- inlineToRST handles this case properly so it's safe to keep
(Link _ _ _, Image _ _ _) -> keep f i ( Link{}, Image{}) -> keep f i
-- parent inlines would prevent links from being correctly -- parent inlines would prevent links from being correctly
-- parsed, in this case we prioritise the content over the -- parsed, in this case we prioritise the content over the
-- style -- style
(_, Link _ _ _) -> emerge f i (_, Link{}) -> emerge f i
-- always give priority to strong text over emphasis -- always give priority to strong text over emphasis
(Emph _, Strong _) -> emerge f i (Emph _, Strong _) -> emerge f i
-- drop all other nested styles -- drop all other nested styles
@ -567,7 +568,8 @@ inlineListToRST = writeInlines . walk transformInlines
-- | Convert list of Pandoc inline elements to RST. -- | Convert list of Pandoc inline elements to RST.
writeInlines :: PandocMonad m => [Inline] -> RST m (Doc Text) writeInlines :: PandocMonad m => [Inline] -> RST m (Doc Text)
writeInlines lst = mapM inlineToRST lst >>= return . hcat writeInlines lst =
hcat <$> mapM inlineToRST lst
-- | Convert Pandoc inline element to RST. -- | Convert Pandoc inline element to RST.
inlineToRST :: PandocMonad m => Inline -> RST m (Doc Text) inlineToRST :: PandocMonad m => Inline -> RST m (Doc Text)

View file

@ -282,7 +282,7 @@ inlineToTEI opts (Link attr txt (src, _))
linktext <- inlinesToTEI opts txt linktext <- inlinesToTEI opts txt
return $ linktext <+> char '(' <> emailLink <> char ')' return $ linktext <+> char '(' <> emailLink <> char ')'
| otherwise = | otherwise =
(inTags False "ref" $ ("target", src) : idFromAttr opts attr) inTags False "ref" (("target", src) : idFromAttr opts attr)
<$> inlinesToTEI opts txt <$> inlinesToTEI opts txt
inlineToTEI opts (Image attr description (src, tit)) = do inlineToTEI opts (Image attr description (src, tit)) = do
let titleDoc = if T.null tit let titleDoc = if T.null tit
@ -300,6 +300,4 @@ inlineToTEI opts (Note contents) =
idFromAttr :: WriterOptions -> Attr -> [(Text, Text)] idFromAttr :: WriterOptions -> Attr -> [(Text, Text)]
idFromAttr opts (id',_,_) = idFromAttr opts (id',_,_) =
if T.null id' [("xml:id", writerIdentifierPrefix opts <> id') | not (T.null id')]
then []
else [("xml:id", writerIdentifierPrefix opts <> id')]

View file

@ -272,9 +272,8 @@ tableAnyRowToTexinfo :: PandocMonad m
-> [[Block]] -> [[Block]]
-> TI m (Doc Text) -> TI m (Doc Text)
tableAnyRowToTexinfo itemtype aligns cols = tableAnyRowToTexinfo itemtype aligns cols =
zipWithM alignedBlock aligns cols >>= (literal itemtype $$) . foldl (\row item -> row $$
return . (literal itemtype $$) . foldl (\row item -> row $$ (if isEmpty row then empty else text " @tab ") <> item) empty <$> zipWithM alignedBlock aligns cols
(if isEmpty row then empty else text " @tab ") <> item) empty
alignedBlock :: PandocMonad m alignedBlock :: PandocMonad m
=> Alignment => Alignment

View file

@ -71,7 +71,7 @@ genAnchor id' = if Text.null id'
blockListToXWiki :: PandocMonad m => [Block] -> XWikiReader m Text blockListToXWiki :: PandocMonad m => [Block] -> XWikiReader m Text
blockListToXWiki blocks = blockListToXWiki blocks =
fmap vcat $ mapM blockToXWiki blocks vcat <$> mapM blockToXWiki blocks
blockToXWiki :: PandocMonad m => Block -> XWikiReader m Text blockToXWiki :: PandocMonad m => Block -> XWikiReader m Text
@ -79,7 +79,7 @@ blockToXWiki Null = return ""
blockToXWiki (Div (id', _, _) blocks) = do blockToXWiki (Div (id', _, _) blocks) = do
content <- blockListToXWiki blocks content <- blockListToXWiki blocks
return $ (genAnchor id') <> content return $ genAnchor id' <> content
blockToXWiki (Plain inlines) = blockToXWiki (Plain inlines) =
inlineListToXWiki inlines inlineListToXWiki inlines
@ -100,7 +100,7 @@ blockToXWiki HorizontalRule = return "\n----\n"
blockToXWiki (Header level (id', _, _) inlines) = do blockToXWiki (Header level (id', _, _) inlines) = do
contents <- inlineListToXWiki inlines contents <- inlineListToXWiki inlines
let eqs = Text.replicate level "=" let eqs = Text.replicate level "="
return $ eqs <> " " <> contents <> " " <> (genAnchor id') <> eqs <> "\n" return $ eqs <> " " <> contents <> " " <> genAnchor id' <> eqs <> "\n"
-- XWiki doesn't appear to differentiate between inline and block-form code, so we delegate -- XWiki doesn't appear to differentiate between inline and block-form code, so we delegate
-- We do amend the text to ensure that the code markers are on their own lines, since this is a block -- We do amend the text to ensure that the code markers are on their own lines, since this is a block
@ -211,8 +211,8 @@ inlineToXWiki il@(RawInline frmt str)
inlineToXWiki (Link (id', _, _) txt (src, _)) = do inlineToXWiki (Link (id', _, _) txt (src, _)) = do
label <- inlineListToXWiki txt label <- inlineListToXWiki txt
case txt of case txt of
[Str s] | isURI src && escapeURI s == src -> return $ src <> (genAnchor id') [Str s] | isURI src && escapeURI s == src -> return $ src <> genAnchor id'
_ -> return $ "[[" <> label <> ">>" <> src <> "]]" <> (genAnchor id') _ -> return $ "[[" <> label <> ">>" <> src <> "]]" <> genAnchor id'
inlineToXWiki (Image _ alt (source, tit)) = do inlineToXWiki (Image _ alt (source, tit)) = do
alt' <- inlineListToXWiki alt alt' <- inlineListToXWiki alt
@ -225,12 +225,12 @@ inlineToXWiki (Image _ alt (source, tit)) = do
inlineToXWiki (Note contents) = do inlineToXWiki (Note contents) = do
contents' <- blockListToXWiki contents contents' <- blockListToXWiki contents
return $ "{{footnote}}" <> (Text.strip contents') <> "{{/footnote}}" return $ "{{footnote}}" <> Text.strip contents' <> "{{/footnote}}"
-- TODO: support attrs other than id (anchor) -- TODO: support attrs other than id (anchor)
inlineToXWiki (Span (id', _, _) contents) = do inlineToXWiki (Span (id', _, _) contents) = do
contents' <- inlineListToXWiki contents contents' <- inlineListToXWiki contents
return $ (genAnchor id') <> contents' return $ genAnchor id' <> contents'
-- Utility method since (for now) all lists are handled the same way -- Utility method since (for now) all lists are handled the same way
blockToXWikiList :: PandocMonad m => Text -> [[Block]] -> XWikiReader m Text blockToXWikiList :: PandocMonad m => Text -> [[Block]] -> XWikiReader m Text
@ -244,7 +244,7 @@ listItemToXWiki :: PandocMonad m => [Block] -> XWikiReader m Text
listItemToXWiki contents = do listItemToXWiki contents = do
marker <- asks listLevel marker <- asks listLevel
contents' <- blockListToXWiki contents contents' <- blockListToXWiki contents
return $ marker <> ". " <> (Text.strip contents') return $ marker <> ". " <> Text.strip contents'
-- | Convert definition list item (label, list of blocks) to MediaWiki. -- | Convert definition list item (label, list of blocks) to MediaWiki.
@ -256,7 +256,7 @@ definitionListItemToMediaWiki (label, items) = do
contents <- mapM blockListToXWiki items contents <- mapM blockListToXWiki items
marker <- asks listLevel marker <- asks listLevel
return $ marker <> " " <> labelText <> "\n" <> return $ marker <> " " <> labelText <> "\n" <>
intercalate "\n" (map (\d -> (Text.init marker) <> ": " <> d) contents) intercalate "\n" (map (\d -> Text.init marker <> ": " <> d) contents)
-- Escape the escape character, as well as formatting pairs -- Escape the escape character, as well as formatting pairs
escapeXWikiString :: Text -> Text escapeXWikiString :: Text -> Text

View file

@ -18,7 +18,6 @@ import Data.Algorithm.Diff
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import qualified Data.Text as T import qualified Data.Text as T
import Data.List (isSuffixOf) import Data.List (isSuffixOf)
import Prelude hiding (readFile)
import System.Directory import System.Directory
import System.Exit import System.Exit
import System.FilePath (joinPath, splitDirectories, takeDirectory, (</>)) import System.FilePath (joinPath, splitDirectories, takeDirectory, (</>))

View file

@ -91,7 +91,7 @@ testForWarningsWithOpts opts name docxFile expected =
getMedia :: FilePath -> FilePath -> IO (Maybe B.ByteString) getMedia :: FilePath -> FilePath -> IO (Maybe B.ByteString)
getMedia archivePath mediaPath = do getMedia archivePath mediaPath = do
zf <- B.readFile archivePath >>= return . toArchive zf <- toArchive <$> B.readFile archivePath
return $ findEntryByPath ("word/" ++ mediaPath) zf >>= (Just . fromEntry) return $ findEntryByPath ("word/" ++ mediaPath) zf >>= (Just . fromEntry)
compareMediaPathIO :: FilePath -> MediaBag -> FilePath -> IO Bool compareMediaPathIO :: FilePath -> MediaBag -> FilePath -> IO Bool

View file

@ -95,14 +95,14 @@ tests = [ testGroup "base tag"
] ]
, testGroup "samp" , testGroup "samp"
[ [
test html "inline samp block" $ test html "inline samp block" $
"<samp>Answer is 42</samp>" =?> "<samp>Answer is 42</samp>" =?>
plain (codeWith ("",["sample"],[]) "Answer is 42") plain (codeWith ("",["sample"],[]) "Answer is 42")
] ]
, testGroup "var" , testGroup "var"
[ [
test html "inline var block" $ test html "inline var block" $
"<var>result</var>" =?> "<var>result</var>" =?>
plain (codeWith ("",["variable"],[]) "result") plain (codeWith ("",["variable"],[]) "result")
] ]
, askOption $ \(QuickCheckTests numtests) -> , askOption $ \(QuickCheckTests numtests) ->

View file

@ -51,13 +51,13 @@ tests = [
=?> header 2 (text "The header 2") =?> header 2 (text "The header 2")
, "Macro args" =: , "Macro args" =:
".B \"single arg with \"\"Q\"\"\"" ".B \"single arg with \"\"Q\"\"\""
=?> (para $ strong $ text "single arg with \"Q\"") =?>para (strong $ text "single arg with \"Q\"")
, "Argument from next line" =: , "Argument from next line" =:
".B\nsingle arg with \"Q\"" ".B\nsingle arg with \"Q\""
=?> (para $ strong $ text "single arg with \"Q\"") =?>para (strong $ text "single arg with \"Q\"")
, "comment" =: , "comment" =:
".\\\"bla\naaa" ".\\\"bla\naaa"
=?> (para $ str "aaa") =?>para (str "aaa")
, "link" =: , "link" =:
".BR aa (1)" ".BR aa (1)"
=?> para (strong (str "aa") <> str "(1)") =?> para (strong (str "aa") <> str "(1)")
@ -65,7 +65,7 @@ tests = [
testGroup "Escapes" [ testGroup "Escapes" [
"fonts" =: "fonts" =:
"aa\\fIbb\\fRcc" "aa\\fIbb\\fRcc"
=?> (para $ str "aa" <> (emph $ str "bb") <> str "cc") =?>para (str "aa" <> (emph $ str "bb") <> str "cc")
, "nested fonts" =: , "nested fonts" =:
"\\f[BI]hi\\f[I] there\\f[R]" "\\f[BI]hi\\f[I] there\\f[R]"
=?> para (emph (strong (text "hi") <> text " there")) =?> para (emph (strong (text "hi") <> text " there"))
@ -75,26 +75,26 @@ tests = [
text " ok") text " ok")
, "skip" =: , "skip" =:
"a\\%\\\n\\:b\\0" "a\\%\\\n\\:b\\0"
=?> (para $ str "ab\8199") =?>para (str "ab\8199")
, "replace" =: , "replace" =:
"\\-\\ \\\\\\[lq]\\[rq]\\[em]\\[en]\\*(lq\\*(rq" "\\-\\ \\\\\\[lq]\\[rq]\\[em]\\[en]\\*(lq\\*(rq"
=?> (para $ text "- \\“”—–“”") =?>para (text "- \\“”—–“”")
, "replace2" =: , "replace2" =:
"\\t\\e\\`\\^\\|\\'" =?> (para $ text "\\`\8202\8198`") "\\t\\e\\`\\^\\|\\'" =?>para (text "\\`\8202\8198`")
, "comment with \\\"" =: , "comment with \\\"" =:
"Foo \\\" bar\n" =?> (para $ text "Foo") "Foo \\\" bar\n" =?>para (text "Foo")
, "comment with \\#" =: , "comment with \\#" =:
"Foo\\#\nbar\n" =?> (para $ text "Foobar") "Foo\\#\nbar\n" =?>para (text "Foobar")
, "two letter escapes" =: , "two letter escapes" =:
"\\(oA\\(~O" =?> (para $ text "ÅÕ") "\\(oA\\(~O" =?>para (text "ÅÕ")
, "bracketed escapes" =: , "bracketed escapes" =:
"\\[oA]\\[~O]\\[Do]\\[Ye]\\[product]\\[ul]" =?> (para $ text "ÅÕ$¥∏_") "\\[oA]\\[~O]\\[Do]\\[Ye]\\[product]\\[ul]" =?>para (text "ÅÕ$¥∏_")
, "unicode escapes" =: , "unicode escapes" =:
"\\[u2020]" =?> (para $ text "") "\\[u2020]" =?>para (text "")
, "unicode escapes (combined)" =: , "unicode escapes (combined)" =:
"\\[u0075_u0301]" =?> (para $ text "\250") "\\[u0075_u0301]" =?>para (text "\250")
, "unknown escape (#5034)" =: , "unknown escape (#5034)" =:
"\\9" =?> (para $ text "9") "\\9" =?>para (text "9")
], ],
testGroup "Lists" [ testGroup "Lists" [
"bullet" =: "bullet" =:
@ -108,7 +108,7 @@ tests = [
=?> orderedListWith (1,UpperAlpha,OneParen) [para $ str "first", para $ str "second"] =?> orderedListWith (1,UpperAlpha,OneParen) [para $ str "first", para $ str "second"]
, "nested" =: , "nested" =:
".IP \"\\[bu]\"\nfirst\n.RS\n.IP \"\\[bu]\"\n1a\n.IP \"\\[bu]\"\n1b\n.RE" ".IP \"\\[bu]\"\nfirst\n.RS\n.IP \"\\[bu]\"\n1a\n.IP \"\\[bu]\"\n1b\n.RE"
=?> bulletList [(para $ str "first") <> (bulletList [para $ str "1a", para $ str "1b"])] =?> bulletList [para (str "first") <> bulletList [para $ str "1a", para $ str "1b"]]
, "change in list style" =: , "change in list style" =:
".IP \\[bu]\nfirst\n.IP 1\nsecond" ".IP \\[bu]\nfirst\n.IP 1\nsecond"
=?> bulletList [para (str "first")] <> =?> bulletList [para (str "first")] <>

View file

@ -199,6 +199,6 @@ tests =
, "#+pandoc-emphasis-post:" , "#+pandoc-emphasis-post:"
, "[/noemph/]" , "[/noemph/]"
] =?> ] =?>
para ("[/noemph/]") para "[/noemph/]"
] ]
] ]

View file

@ -311,14 +311,14 @@ tests =
, "Ordered List in Bullet List" =: , "Ordered List in Bullet List" =:
("- Emacs\n" <> ("- Emacs\n" <>
" + Org\n") =?> " + Org\n") =?>
bulletList [ (plain "Emacs") <> bulletList [ plain "Emacs" <>
(orderedList [ plain "Org"]) orderedList [ plain "Org"]
] ]
, "Bullet List in Ordered List" =: , "Bullet List in Ordered List" =:
("+ GNU\n" <> ("+ GNU\n" <>
" - Freedom\n") =?> " - Freedom\n") =?>
orderedList [ (plain "GNU") <> bulletList [ (plain "Freedom") ] ] orderedList [ plain "GNU" <> bulletList [ plain "Freedom" ] ]
, "Definition List" =: , "Definition List" =:
T.unlines [ ": PLL" T.unlines [ ": PLL"

View file

@ -74,13 +74,13 @@ tests = [ testGroup "inline code"
, testGroup "sample with style" , testGroup "sample with style"
[ "samp should wrap highlighted code" =: [ "samp should wrap highlighted code" =:
codeWith ("",["sample","haskell"],[]) ">>=" codeWith ("",["sample","haskell"],[]) ">>="
=?> ("<samp><code class=\"sourceCode haskell\">" ++ =?> ("<samp><code class=\"sourceCode haskell\">" ++
"<span class=\"op\">&gt;&gt;=</span></code></samp>") "<span class=\"op\">&gt;&gt;=</span></code></samp>")
] ]
, testGroup "variable with style" , testGroup "variable with style"
[ "var should wrap highlighted code" =: [ "var should wrap highlighted code" =:
codeWith ("",["haskell","variable"],[]) ">>=" codeWith ("",["haskell","variable"],[]) ">>="
=?> ("<var><code class=\"sourceCode haskell\">" ++ =?> ("<var><code class=\"sourceCode haskell\">" ++
"<span class=\"op\">&gt;&gt;=</span></code></var>") "<span class=\"op\">&gt;&gt;=</span></code></var>")
] ]
] ]

View file

@ -93,7 +93,7 @@ noteTests = testGroup "note and reference location"
[ test (markdownWithOpts defopts) [ test (markdownWithOpts defopts)
"footnotes at the end of a document" $ "footnotes at the end of a document" $
noteTestDoc =?> noteTestDoc =?>
(unlines [ "First Header" unlines [ "First Header"
, "============" , "============"
, "" , ""
, "This is a footnote.[^1] And this is a [link](https://www.google.com)." , "This is a footnote.[^1] And this is a [link](https://www.google.com)."
@ -110,11 +110,11 @@ noteTests = testGroup "note and reference location"
, "[^1]: Down here." , "[^1]: Down here."
, "" , ""
, "[^2]: The second note." , "[^2]: The second note."
]) ]
, test (markdownWithOpts defopts{writerReferenceLocation=EndOfBlock}) , test (markdownWithOpts defopts{writerReferenceLocation=EndOfBlock})
"footnotes at the end of blocks" $ "footnotes at the end of blocks" $
noteTestDoc =?> noteTestDoc =?>
(unlines [ "First Header" unlines [ "First Header"
, "============" , "============"
, "" , ""
, "This is a footnote.[^1] And this is a [link](https://www.google.com)." , "This is a footnote.[^1] And this is a [link](https://www.google.com)."
@ -131,11 +131,11 @@ noteTests = testGroup "note and reference location"
, "=============" , "============="
, "" , ""
, "Some more text." , "Some more text."
]) ]
, test (markdownWithOpts defopts{writerReferenceLocation=EndOfBlock, writerReferenceLinks=True}) , test (markdownWithOpts defopts{writerReferenceLocation=EndOfBlock, writerReferenceLinks=True})
"footnotes and reference links at the end of blocks" $ "footnotes and reference links at the end of blocks" $
noteTestDoc =?> noteTestDoc =?>
(unlines [ "First Header" unlines [ "First Header"
, "============" , "============"
, "" , ""
, "This is a footnote.[^1] And this is a [link]." , "This is a footnote.[^1] And this is a [link]."
@ -154,11 +154,11 @@ noteTests = testGroup "note and reference location"
, "=============" , "============="
, "" , ""
, "Some more text." , "Some more text."
]) ]
, test (markdownWithOpts defopts{writerReferenceLocation=EndOfSection}) , test (markdownWithOpts defopts{writerReferenceLocation=EndOfSection})
"footnotes at the end of section" $ "footnotes at the end of section" $
noteTestDoc =?> noteTestDoc =?>
(unlines [ "First Header" unlines [ "First Header"
, "============" , "============"
, "" , ""
, "This is a footnote.[^1] And this is a [link](https://www.google.com)." , "This is a footnote.[^1] And this is a [link](https://www.google.com)."
@ -175,7 +175,7 @@ noteTests = testGroup "note and reference location"
, "=============" , "============="
, "" , ""
, "Some more text." , "Some more text."
]) ]
] ]
@ -191,24 +191,24 @@ shortcutLinkRefsTests =
=: para (link "/url" "title" "foo") =: para (link "/url" "title" "foo")
=?> "[foo]\n\n [foo]: /url \"title\"" =?> "[foo]\n\n [foo]: /url \"title\""
, "Followed by another link (unshortcutable)" , "Followed by another link (unshortcutable)"
=: para ((link "/url1" "title1" "first") =: para (link "/url1" "title1" "first"
<> (link "/url2" "title2" "second")) <> link "/url2" "title2" "second")
=?> unlines [ "[first][][second]" =?> unlines [ "[first][][second]"
, "" , ""
, " [first]: /url1 \"title1\"" , " [first]: /url1 \"title1\""
, " [second]: /url2 \"title2\"" , " [second]: /url2 \"title2\""
] ]
, "Followed by space and another link (unshortcutable)" , "Followed by space and another link (unshortcutable)"
=: para ((link "/url1" "title1" "first") <> " " =: para (link "/url1" "title1" "first" <> " "
<> (link "/url2" "title2" "second")) <> link "/url2" "title2" "second")
=?> unlines [ "[first][] [second]" =?> unlines [ "[first][] [second]"
, "" , ""
, " [first]: /url1 \"title1\"" , " [first]: /url1 \"title1\""
, " [second]: /url2 \"title2\"" , " [second]: /url2 \"title2\""
] ]
, "Reference link is used multiple times (unshortcutable)" , "Reference link is used multiple times (unshortcutable)"
=: para ((link "/url1" "" "foo") <> (link "/url2" "" "foo") =: para (link "/url1" "" "foo" <> link "/url2" "" "foo"
<> (link "/url3" "" "foo")) <> link "/url3" "" "foo")
=?> unlines [ "[foo][][foo][1][foo][2]" =?> unlines [ "[foo][][foo][1][foo][2]"
, "" , ""
, " [foo]: /url1" , " [foo]: /url1"
@ -216,8 +216,8 @@ shortcutLinkRefsTests =
, " [2]: /url3" , " [2]: /url3"
] ]
, "Reference link is used multiple times (unshortcutable)" , "Reference link is used multiple times (unshortcutable)"
=: para ((link "/url1" "" "foo") <> " " <> (link "/url2" "" "foo") =: para (link "/url1" "" "foo" <> " " <> link "/url2" "" "foo"
<> " " <> (link "/url3" "" "foo")) <> " " <> link "/url3" "" "foo")
=?> unlines [ "[foo][] [foo][1] [foo][2]" =?> unlines [ "[foo][] [foo][1] [foo][2]"
, "" , ""
, " [foo]: /url1" , " [foo]: /url1"
@ -225,43 +225,43 @@ shortcutLinkRefsTests =
, " [2]: /url3" , " [2]: /url3"
] ]
, "Reference link is followed by text in brackets" , "Reference link is followed by text in brackets"
=: para ((link "/url" "" "link") <> "[text in brackets]") =: para (link "/url" "" "link" <> "[text in brackets]")
=?> unlines [ "[link][]\\[text in brackets\\]" =?> unlines [ "[link][]\\[text in brackets\\]"
, "" , ""
, " [link]: /url" , " [link]: /url"
] ]
, "Reference link is followed by space and text in brackets" , "Reference link is followed by space and text in brackets"
=: para ((link "/url" "" "link") <> " [text in brackets]") =: para (link "/url" "" "link" <> " [text in brackets]")
=?> unlines [ "[link][] \\[text in brackets\\]" =?> unlines [ "[link][] \\[text in brackets\\]"
, "" , ""
, " [link]: /url" , " [link]: /url"
] ]
, "Reference link is followed by RawInline" , "Reference link is followed by RawInline"
=: para ((link "/url" "" "link") <> rawInline "markdown" "[rawText]") =: para (link "/url" "" "link" <> rawInline "markdown" "[rawText]")
=?> unlines [ "[link][][rawText]" =?> unlines [ "[link][][rawText]"
, "" , ""
, " [link]: /url" , " [link]: /url"
] ]
, "Reference link is followed by space and RawInline" , "Reference link is followed by space and RawInline"
=: para ((link "/url" "" "link") <> space <> rawInline "markdown" "[rawText]") =: para (link "/url" "" "link" <> space <> rawInline "markdown" "[rawText]")
=?> unlines [ "[link][] [rawText]" =?> unlines [ "[link][] [rawText]"
, "" , ""
, " [link]: /url" , " [link]: /url"
] ]
, "Reference link is followed by RawInline with space" , "Reference link is followed by RawInline with space"
=: para ((link "/url" "" "link") <> rawInline "markdown" " [rawText]") =: para (link "/url" "" "link" <> rawInline "markdown" " [rawText]")
=?> unlines [ "[link][] [rawText]" =?> unlines [ "[link][] [rawText]"
, "" , ""
, " [link]: /url" , " [link]: /url"
] ]
, "Reference link is followed by citation" , "Reference link is followed by citation"
=: para ((link "/url" "" "link") <> cite [Citation "author" [] [] NormalCitation 0 0] (str "[@author]")) =: para (link "/url" "" "link" <> cite [Citation "author" [] [] NormalCitation 0 0] (str "[@author]"))
=?> unlines [ "[link][][@author]" =?> unlines [ "[link][][@author]"
, "" , ""
, " [link]: /url" , " [link]: /url"
] ]
, "Reference link is followed by space and citation" , "Reference link is followed by space and citation"
=: para ((link "/url" "" "link") <> space <> cite [Citation "author" [] [] NormalCitation 0 0] (str "[@author]")) =: para (link "/url" "" "link" <> space <> cite [Citation "author" [] [] NormalCitation 0 0] (str "[@author]"))
=?> unlines [ "[link][] [@author]" =?> unlines [ "[link][] [@author]"
, "" , ""
, " [link]: /url" , " [link]: /url"

View file

@ -175,6 +175,6 @@ tests = [ testGroup "rubrics"
, "--------"] , "--------"]
] ]
, testTemplate "$subtitle$\n" "subtitle" $ , testTemplate "$subtitle$\n" "subtitle" $
(setMeta "subtitle" ("subtitle" :: Inlines) $ doc $ plain "") =?> setMeta "subtitle" ("subtitle" :: Inlines) (doc $ plain "") =?>
("subtitle" :: String) ("subtitle" :: String)
] ]