git.iko.soy/typeable/pandoc
on master help sign in
Merge pull request #1486 from Aelve/minor
2de2842John MacFarlane
pandoc.hs+52−37
@@ -57,7 +57,8 @@ import System.IO.Error ( isDoesNotExistError )
57import qualified Control.Exception as E
57import qualified Control.Exception as E
58import Control.Exception.Extensible ( throwIO )
58import Control.Exception.Extensible ( throwIO )
59import qualified Text.Pandoc.UTF8 as UTF8
59import qualified Text.Pandoc.UTF8 as UTF8
60−import Control.Monad (when, unless, liftM, (>=>))
60+import Control.Monad (when, unless, (>=>))
61+import Data.Maybe (isJust)
61import Data.Foldable (foldrM)
62import Data.Foldable (foldrM)
62import Network.URI (parseURI, isURI, URI(..))
63import Network.URI (parseURI, isURI, URI(..))
63import qualified Data.ByteString.Lazy as B
64import qualified Data.ByteString.Lazy as B
@@ -74,10 +75,13 @@ import Data.Monoid
74type Transform = Pandoc -> Pandoc
75type Transform = Pandoc -> Pandoc
75
76
76copyrightMessage :: String
77copyrightMessage :: String
78+copyrightMessage = unlines [
79+ "",
77−copyrightMessage = "\nCopyright (C) 2006-2014 John MacFarlane\n" ++
80+ "Copyright (C) 2006-2014 John MacFarlane",
78− "Web: http://johnmacfarlane.net/pandoc\n" ++
81+ "Web: http://johnmacfarlane.net/pandoc",
79− "This is free software; see the source for copying conditions. There is no\n" ++
82+ "This is free software; see the source for copying conditions.",
80− "warranty, not even for merchantability or fitness for a particular purpose."
83+ "There is no warranty, not even for merchantability or fitness",
84+ "for a particular purpose." ]
81
85
82compileInfo :: String
86compileInfo :: String
83compileInfo =
87compileInfo =
@@ -91,15 +95,21 @@ compileInfo =
91-- comma separated words in lines with a maximum line length.
95-- comma separated words in lines with a maximum line length.
92wrapWords :: Int -> Int -> [String] -> String
96wrapWords :: Int -> Int -> [String] -> String
93wrapWords indent c = wrap' (c - indent) (c - indent)
97wrapWords indent c = wrap' (c - indent) (c - indent)
98+ where
94− where wrap' _ _ [] = ""
99+ wrap' _ _ [] = ""
95− wrap' cols remaining (x:xs) = if remaining == cols
100+ wrap' cols remaining (x:xs)
101+ | remaining == cols =
96− then x ++ wrap' cols (remaining - length x) xs
102+ x ++ wrap' cols (remaining - length x) xs
97− else if (length x + 1) > remaining
103+ | (length x + 1) > remaining =
104+ ",\n" ++ replicate indent ' ' ++ x ++
98− then ",\n" ++ replicate indent ' ' ++ x ++ wrap' cols (cols - length x) xs
105+ wrap' cols (cols - length x) xs
106+ | otherwise =
107+ ", " ++ x ++
99− else ", " ++ x ++ wrap' cols (remaining - (length x + 2)) xs
108+ wrap' cols (remaining - length x - 2) xs
100
109
101isTextFormat :: String -> Bool
110isTextFormat :: String -> Bool
102−isTextFormat s = takeWhile (`notElem` "+-") s `notElem` ["odt","docx","epub","epub3"]
111+isTextFormat s = takeWhile (`notElem` "+-") s `notElem` binaries
112+ where binaries = ["odt","docx","epub","epub3"]
103
113
104externalFilter :: FilePath -> [String] -> Pandoc -> IO Pandoc
114externalFilter :: FilePath -> [String] -> Pandoc -> IO Pandoc
105externalFilter f args' d = do
115externalFilter f args' d = do
@@ -938,7 +948,7 @@ defaultWriterName x =
938 ".fb2" -> "fb2"
948 ".fb2" -> "fb2"
939 ".opml" -> "opml"
949 ".opml" -> "opml"
940 ['.',y] | y `elem` ['1'..'9'] -> "man"
950 ['.',y] | y `elem` ['1'..'9'] -> "man"
941− _ -> "html"
951+ _ -> "html"
942
952
943-- Transformations of a Pandoc document post-parsing:
953-- Transformations of a Pandoc document post-parsing:
944
954
@@ -968,7 +978,7 @@ applyFilters filters args d =
968main :: IO ()
978main :: IO ()
969main = do
979main = do
970
980
971− rawArgs <- liftM (map UTF8.decodeArg) getArgs
981+ rawArgs <- map UTF8.decodeArg <$> getArgs
972 prg <- getProgName
982 prg <- getProgName
973 let compatMode = (prg == "hsmarkdown")
983 let compatMode = (prg == "hsmarkdown")
974
984
@@ -1003,7 +1013,7 @@ main = do
1003 , optTemplate = templatePath
1013 , optTemplate = templatePath
1004 , optOutputFile = outputFile
1014 , optOutputFile = outputFile
1005 , optNumberSections = numberSections
1015 , optNumberSections = numberSections
1006− , optNumberOffset = numberFrom
1016+ , optNumberOffset = numberFrom
1007 , optSectionDivs = sectionDivs
1017 , optSectionDivs = sectionDivs
1008 , optIncremental = incremental
1018 , optIncremental = incremental
1009 , optSelfContained = selfContained
1019 , optSelfContained = selfContained
@@ -1051,18 +1061,17 @@ main = do
1051 exitWith ExitSuccess
1061 exitWith ExitSuccess
1052
1062
1053 -- --bibliography implies -F pandoc-citeproc for backwards compatibility:
1063 -- --bibliography implies -F pandoc-citeproc for backwards compatibility:
1054− let filters' = case M.lookup "bibliography" metadata of
1064+ let needsCiteproc = isJust (M.lookup "bibliography" metadata) &&
1055− Just _ | optCiteMethod opts /= Natbib &&
1065+ optCiteMethod opts `notElem` [Natbib, Biblatex] &&
1056− optCiteMethod opts /= Biblatex &&
1066+ "pandoc-citeproc" `notElem` map takeBaseName filters
1057− all (\f -> takeBaseName f /= "pandoc-citeproc")
1058− filters -> "pandoc-citeproc" : filters
1067+ let filters' = if needsCiteproc then "pandoc-citeproc" : filters
1059− _ -> filters
1068+ else filters
1060
1069
1061 let sources = if ignoreArgs then [] else args
1070 let sources = if ignoreArgs then [] else args
1062
1071
1063 datadir <- case mbDataDir of
1072 datadir <- case mbDataDir of
1064 Nothing -> E.catch
1073 Nothing -> E.catch
1065− (liftM Just $ getAppUserDataDirectory "pandoc")
1074+ (Just <$> getAppUserDataDirectory "pandoc")
1066 (\e -> let _ = (e :: E.SomeException)
1075 (\e -> let _ = (e :: E.SomeException)
1067 in return Nothing)
1076 in return Nothing)
1068 Just _ -> return mbDataDir
1077 Just _ -> return mbDataDir
@@ -1093,7 +1102,8 @@ main = do
1093 else case getWriter writerName' of
1102 else case getWriter writerName' of
1094 Left e -> err 9 $
1103 Left e -> err 9 $
1095 if writerName' == "pdf"
1104 if writerName' == "pdf"
1105+ then e ++
1096− then e ++ "\nTo create a pdf with pandoc, use " ++
1106+ "\nTo create a pdf with pandoc, use " ++
1097 "the latex or beamer writer and specify\n" ++
1107 "the latex or beamer writer and specify\n" ++
1098 "an output file with .pdf extension " ++
1108 "an output file with .pdf extension " ++
1099 "(pandoc -t latex -o filename.pdf)."
1109 "(pandoc -t latex -o filename.pdf)."
@@ -1145,20 +1155,22 @@ main = do
1145 then do
1155 then do
1146 dztempl <- readDataFileUTF8 datadir
1156 dztempl <- readDataFileUTF8 datadir
1147 ("dzslides" </> "template.html")
1157 ("dzslides" </> "template.html")
1158+ let dzline = "<!-- {{{{ dzslides core"
1159+ let dzcore = unlines
1148− let dzcore = unlines $ dropWhile (not . isPrefixOf "<!-- {{{{ dzslides core")
1160+ $ dropWhile (not . (dzline `isPrefixOf`))
1149− $ lines dztempl
1161+ $ lines dztempl
1150 return $ ("dzslides-core", dzcore) : variables'
1162 return $ ("dzslides-core", dzcore) : variables'
1151 else return variables'
1163 else return variables'
1152
1164
1153 let sourceURL = case sources of
1165 let sourceURL = case sources of
1154− [] -> Nothing
1166+ [] -> Nothing
1155− (x:_) -> case parseURI x of
1167+ (x:_) -> case parseURI x of
1156− Just u
1168+ Just u
1157− | uriScheme u `elem` ["http:","https:"] ->
1169+ | uriScheme u `elem` ["http:","https:"] ->
1158− Just $ show u{ uriPath = "",
1170+ Just $ show u{ uriPath = "",
1159− uriQuery = "",
1171+ uriQuery = "",
1160− uriFragment = "" }
1172+ uriFragment = "" }
1161− _ -> Nothing
1173+ _ -> Nothing
1162
1174
1163 let readerOpts = def{ readerSmart = smart || (texLigatures &&
1175 let readerOpts = def{ readerSmart = smart || (texLigatures &&
1164 (laTeXOutput || "context" `isPrefixOf` writerName'))
1176 (laTeXOutput || "context" `isPrefixOf` writerName'))
@@ -1194,11 +1206,14 @@ main = do
1194 let readFiles [] = error "Cannot read archive from stdin"
1206 let readFiles [] = error "Cannot read archive from stdin"
1195 readFiles (x:_) = B.readFile x
1207 readFiles (x:_) = B.readFile x
1196
1208
1197− let convertTabs = tabFilter (if (preserveTabs || readerName' == "t2t") then 0 else tabStop)
1209+ let convertTabs = tabFilter (if preserveTabs || readerName' == "t2t"
1210+ then 0
1211+ else tabStop)
1198
1212
1199− let handleIncludes' = if readerName' == "latex" || readerName' == "latex+lhs"
1213+ let handleIncludes' = if readerName' == "latex" ||
1214+ readerName' == "latex+lhs"
1200− then handleIncludes
1215+ then handleIncludes
1201− else return
1216+ else return
1202
1217
1203 (doc, media) <-
1218 (doc, media) <-
1204 case reader of
1219 case reader of
src/Text/Pandoc/Readers/Docx.hs+7−7
@@ -86,7 +86,7 @@ import Text.Pandoc.Readers.Docx.TexChar
86import Text.Pandoc.Shared
86import Text.Pandoc.Shared
87import Text.Pandoc.MediaBag (insertMedia, MediaBag)
87import Text.Pandoc.MediaBag (insertMedia, MediaBag)
88import Data.Maybe (mapMaybe, fromMaybe)
88import Data.Maybe (mapMaybe, fromMaybe)
89−import Data.List (delete, isPrefixOf, (\\), intercalate, intersect)
89+import Data.List (delete, stripPrefix, (\\), intercalate, intersect)
90import Data.Monoid
90import Data.Monoid
91import qualified Data.ByteString.Lazy as B
91import qualified Data.ByteString.Lazy as B
92import qualified Data.Map as M
92import qualified Data.Map as M
@@ -455,8 +455,8 @@ oMathElemToTexString (LowerLimit base limElems) = do
455 -- we want to make sure to replace the `\rightarrow` with `\to`
455 -- we want to make sure to replace the `\rightarrow` with `\to`
456 let arrowToTo :: String -> String
456 let arrowToTo :: String -> String
457 arrowToTo "" = ""
457 arrowToTo "" = ""
458− arrowToTo s | "\\rightarrow" `isPrefixOf` s =
458+ arrowToTo s | Just s' <- stripPrefix "\\rightarrow" s =
459− "\\to" ++ (arrowToTo $ drop (length "\\rightarrow") s)
459+ "\\to" ++ arrowToTo s'
460 arrowToTo (c:cs) = c : arrowToTo cs
460 arrowToTo (c:cs) = c : arrowToTo cs
461 lim' = arrowToTo lim
461 lim' = arrowToTo lim
462 return $ case baseString of
462 return $ case baseString of
@@ -470,8 +470,8 @@ oMathElemToTexString (UpperLimit base limElems) = do
470 -- we want to make sure to replace the `\rightarrow` with `\to`
470 -- we want to make sure to replace the `\rightarrow` with `\to`
471 let arrowToTo :: String -> String
471 let arrowToTo :: String -> String
472 arrowToTo "" = ""
472 arrowToTo "" = ""
473− arrowToTo s | "\\rightarrow" `isPrefixOf` s =
473+ arrowToTo s | Just s' <- stripPrefix "\\rightarrow" s =
474− "\\to" ++ (arrowToTo $ drop (length "\\rightarrow") s)
474+ "\\to" ++ arrowToTo s'
475 arrowToTo (c:cs) = c : arrowToTo cs
475 arrowToTo (c:cs) = c : arrowToTo cs
476 lim' = arrowToTo lim
476 lim' = arrowToTo lim
477 return $ case baseString of
477 return $ case baseString of
@@ -698,8 +698,8 @@ ilToCode Space = " "
698ilToCode _ = ""
698ilToCode _ = ""
699
699
700isHeaderClass :: String -> Maybe Int
700isHeaderClass :: String -> Maybe Int
701−isHeaderClass s | "Heading" `isPrefixOf` s =
701+isHeaderClass s | Just s' <- stripPrefix "Heading" s =
702− case reads (drop (length "Heading") s) :: [(Int, String)] of
702+ case reads s' :: [(Int, String)] of
703 [] -> Nothing
703 [] -> Nothing
704 ((n, "") : []) -> Just n
704 ((n, "") : []) -> Just n
705 _ -> Nothing
705 _ -> Nothing
src/Text/Pandoc/Readers/Org.hs+1−1
@@ -274,7 +274,7 @@ optionalAttributes parser = try $
274parseBlockAttributes :: OrgParser ()
274parseBlockAttributes :: OrgParser ()
275parseBlockAttributes = do
275parseBlockAttributes = do
276 attrs <- many attribute
276 attrs <- many attribute
277− () <$ mapM (uncurry parseAndAddAttribute) attrs
277+ mapM_ (uncurry parseAndAddAttribute) attrs
278 where
278 where
279 attribute :: OrgParser (String, String)
279 attribute :: OrgParser (String, String)
280 attribute = try $ do
280 attribute = try $ do
src/Text/Pandoc/Readers/RST.hs+1−4
@@ -47,7 +47,7 @@ import Text.Pandoc.Builder (Inlines, Blocks, trimInlines, (<>))
47import qualified Text.Pandoc.Builder as B
47import qualified Text.Pandoc.Builder as B
48import Data.Monoid (mconcat, mempty)
48import Data.Monoid (mconcat, mempty)
49import Data.Sequence (viewr, ViewR(..))
49import Data.Sequence (viewr, ViewR(..))
50−import Data.Char (toLower)
50+import Data.Char (toLower, isHexDigit)
51
51
52-- | Parse reStructuredText string and return Pandoc document.
52-- | Parse reStructuredText string and return Pandoc document.
53readRST :: ReaderOptions -- ^ Reader options
53readRST :: ReaderOptions -- ^ Reader options
@@ -656,9 +656,6 @@ extractUnicodeChar s = maybe Nothing (\c -> Just (c,rest)) mbc
656 where (ds,rest) = span isHexDigit s
656 where (ds,rest) = span isHexDigit s
657 mbc = safeRead ('\'':'\\':'x':ds ++ "'")
657 mbc = safeRead ('\'':'\\':'x':ds ++ "'")
658
658
659−isHexDigit :: Char -> Bool
660−isHexDigit c = c `elem` "0123456789ABCDEFabcdef"
661−
662extractCaption :: RSTParser (Inlines, Blocks)
659extractCaption :: RSTParser (Inlines, Blocks)
663extractCaption = do
660extractCaption = do
664 capt <- trimInlines . mconcat <$> many inline
661 capt <- trimInlines . mconcat <$> many inline
src/Text/Pandoc/Shared.hs+8−8
@@ -1,5 +1,5 @@
1{-# LANGUAGE DeriveDataTypeable, CPP, MultiParamTypeClasses,
1{-# LANGUAGE DeriveDataTypeable, CPP, MultiParamTypeClasses,
2− FlexibleContexts, ScopedTypeVariables #-}
2+ FlexibleContexts, ScopedTypeVariables, PatternGuards #-}
3{-
3{-
4Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>
4Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>
5
5
@@ -99,7 +99,7 @@ import System.Environment (getProgName)
99import System.Exit (exitWith, ExitCode(..))
99import System.Exit (exitWith, ExitCode(..))
100import Data.Char ( toLower, isLower, isUpper, isAlpha,
100import Data.Char ( toLower, isLower, isUpper, isAlpha,
101 isLetter, isDigit, isSpace )
101 isLetter, isDigit, isSpace )
102−import Data.List ( find, isPrefixOf, intercalate )
102+import Data.List ( find, stripPrefix, intercalate )
103import qualified Data.Map as M
103import qualified Data.Map as M
104import Network.URI ( escapeURIString, isURI, nonStrictRelativeTo,
104import Network.URI ( escapeURIString, isURI, nonStrictRelativeTo,
105 unEscapeString, parseURIReference, isAllowedInURI )
105 unEscapeString, parseURIReference, isAllowedInURI )
@@ -183,9 +183,9 @@ substitute :: (Eq a) => [a] -> [a] -> [a] -> [a]
183substitute _ _ [] = []
183substitute _ _ [] = []
184substitute [] _ xs = xs
184substitute [] _ xs = xs
185substitute target replacement lst@(x:xs) =
185substitute target replacement lst@(x:xs) =
186− if target `isPrefixOf` lst
186+ case stripPrefix target lst of
187− then replacement ++ substitute target replacement (drop (length target) lst)
187+ Just lst' -> replacement ++ substitute target replacement lst'
188− else x : substitute target replacement xs
188+ Nothing -> x : substitute target replacement xs
189
189
190ordNub :: (Ord a) => [a] -> [a]
190ordNub :: (Ord a) => [a] -> [a]
191ordNub l = go Set.empty l
191ordNub l = go Set.empty l
@@ -808,9 +808,9 @@ fetchItem' media sourceURL s = do
808-- | Read from a URL and return raw data and maybe mime type.
808-- | Read from a URL and return raw data and maybe mime type.
809openURL :: String -> IO (Either E.SomeException (BS.ByteString, Maybe String))
809openURL :: String -> IO (Either E.SomeException (BS.ByteString, Maybe String))
810openURL u
810openURL u
811− | "data:" `isPrefixOf` u =
811+ | Just u' <- stripPrefix "data:" u =
812− let mime = takeWhile (/=',') $ drop 5 u
812+ let mime = takeWhile (/=',') u'
813− contents = B8.pack $ unEscapeString $ drop 1 $ dropWhile (/=',') u
813+ contents = B8.pack $ unEscapeString $ drop 1 $ dropWhile (/=',') u'
814 in return $ Right (decodeLenient contents, Just mime)
814 in return $ Right (decodeLenient contents, Just mime)
815#ifdef HTTP_CLIENT
815#ifdef HTTP_CLIENT
816 | otherwise = withSocketsDo $ E.try $ do
816 | otherwise = withSocketsDo $ E.try $ do
src/Text/Pandoc/Writers/AsciiDoc.hs+3−2
@@ -43,7 +43,8 @@ import Text.Pandoc.Shared
43import Text.Pandoc.Writers.Shared
43import Text.Pandoc.Writers.Shared
44import Text.Pandoc.Options
44import Text.Pandoc.Options
45import Text.Pandoc.Parsing hiding (blankline, space)
45import Text.Pandoc.Parsing hiding (blankline, space)
46+import Data.Maybe (fromMaybe)
46−import Data.List ( isPrefixOf, intersperse, intercalate )
47+import Data.List ( stripPrefix, intersperse, intercalate )
47import Text.Pandoc.Pretty
48import Text.Pandoc.Pretty
48import Control.Monad.State
49import Control.Monad.State
49import qualified Data.Map as M
50import qualified Data.Map as M
@@ -401,7 +402,7 @@ inlineToAsciiDoc opts (Link txt (src, _tit)) = do
401 let prefix = if isRelative
402 let prefix = if isRelative
402 then text "link:"
403 then text "link:"
403 else empty
404 else empty
404− let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src
405+ let srcSuffix = fromMaybe src (stripPrefix "mailto:" src)
405 let useAuto = case txt of
406 let useAuto = case txt of
406 [Str s] | escapeURI s == srcSuffix -> True
407 [Str s] | escapeURI s == srcSuffix -> True
407 _ -> False
408 _ -> False
src/Text/Pandoc/Writers/Docbook.hs+15−15
@@ -1,4 +1,4 @@
1−{-# LANGUAGE OverloadedStrings #-}
1+{-# LANGUAGE OverloadedStrings, PatternGuards #-}
2{-
2{-
3Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>
3Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>
4
4
@@ -37,7 +37,7 @@ import Text.Pandoc.Writers.Shared
37import Text.Pandoc.Options
37import Text.Pandoc.Options
38import Text.Pandoc.Templates (renderTemplate')
38import Text.Pandoc.Templates (renderTemplate')
39import Text.Pandoc.Readers.TeXMath
39import Text.Pandoc.Readers.TeXMath
40−import Data.List ( isPrefixOf, intercalate, isSuffixOf )
40+import Data.List ( stripPrefix, isPrefixOf, intercalate, isSuffixOf )
41import Data.Char ( toLower )
41import Data.Char ( toLower )
42import Control.Applicative ((<$>))
42import Control.Applicative ((<$>))
43import Data.Monoid ( Any(..) )
43import Data.Monoid ( Any(..) )
@@ -313,19 +313,19 @@ inlineToDocbook _ (RawInline f x) | f == "html" || f == "docbook" = text x
313 | otherwise = empty
313 | otherwise = empty
314inlineToDocbook _ LineBreak = text "\n"
314inlineToDocbook _ LineBreak = text "\n"
315inlineToDocbook _ Space = space
315inlineToDocbook _ Space = space
316−inlineToDocbook opts (Link txt (src, _)) =
316+inlineToDocbook opts (Link txt (src, _))
317− if isPrefixOf "mailto:" src
317+ | Just email <- stripPrefix "mailto:" src =
318− then let src' = drop 7 src
319− emailLink = inTagsSimple "email" $ text $
318+ let emailLink = inTagsSimple "email" $ text $
320− escapeStringForXML $ src'
319+ escapeStringForXML $ email
321− in case txt of
320+ in case txt of
322− [Str s] | escapeURI s == src' -> emailLink
321+ [Str s] | escapeURI s == email -> emailLink
323− _ -> inlinesToDocbook opts txt <+>
322+ _ -> inlinesToDocbook opts txt <+>
324− char '(' <> emailLink <> char ')'
323+ char '(' <> emailLink <> char ')'
324+ | otherwise =
325− else (if isPrefixOf "#" src
325+ (if isPrefixOf "#" src
326− then inTags False "link" [("linkend", drop 1 src)]
326+ then inTags False "link" [("linkend", drop 1 src)]
327− else inTags False "ulink" [("url", src)]) $
327+ else inTags False "ulink" [("url", src)]) $
328− inlinesToDocbook opts txt
328+ inlinesToDocbook opts txt
329inlineToDocbook _ (Image _ (src, tit)) =
329inlineToDocbook _ (Image _ (src, tit)) =
330 let titleDoc = if null tit
330 let titleDoc = if null tit
331 then empty
331 then empty
src/Text/Pandoc/Writers/EPUB.hs+6−6
@@ -32,7 +32,7 @@ module Text.Pandoc.Writers.EPUB ( writeEPUB ) where
32import Data.IORef
32import Data.IORef
33import qualified Data.Map as M
33import qualified Data.Map as M
34import Data.Maybe ( fromMaybe )
34import Data.Maybe ( fromMaybe )
35−import Data.List ( isInfixOf, intercalate )
35+import Data.List ( isPrefixOf, isInfixOf, intercalate )
36import System.Environment ( getEnv )
36import System.Environment ( getEnv )
37import Text.Printf (printf)
37import Text.Printf (printf)
38import System.FilePath ( (</>), takeExtension, takeFileName )
38import System.FilePath ( (</>), takeExtension, takeFileName )
@@ -825,11 +825,11 @@ ppTopElement = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ++) . unEntity .
825 unEntity (x:xs) = x : unEntity xs
825 unEntity (x:xs) = x : unEntity xs
826
826
827mediaTypeOf :: FilePath -> Maybe String
827mediaTypeOf :: FilePath -> Maybe String
828+mediaTypeOf x =
829+ let mediaPrefixes = ["image", "video", "audio"] in
828−mediaTypeOf x = case getMimeType x of
830+ case getMimeType x of
829− Just y@('i':'m':'a':'g':'e':_) -> Just y
831+ Just y | any (`isPrefixOf` y) mediaPrefixes -> Just y
830− Just y@('v':'i':'d':'e':'o':_) -> Just y
831− Just y@('a':'u':'d':'i':'o':_) -> Just y
832− _ -> Nothing
832+ _ -> Nothing
833
833
834data IdentState = IdentState{
834data IdentState = IdentState{
835 chapterNumber :: Int,
835 chapterNumber :: Int,
src/Text/Pandoc/Writers/FB2.hs+16−16
@@ -1,3 +1,5 @@
1+{-# LANGUAGE PatternGuards #-}
2+
1{-
3{-
2Copyright (c) 2011-2012, Sergey Astanin
4Copyright (c) 2011-2012, Sergey Astanin
3All rights reserved.
5All rights reserved.
@@ -29,7 +31,7 @@ import Control.Monad.State (StateT, evalStateT, get, modify)
29import Control.Monad.State (liftM, liftM2, liftIO)
31import Control.Monad.State (liftM, liftM2, liftIO)
30import Data.ByteString.Base64 (encode)
32import Data.ByteString.Base64 (encode)
31import Data.Char (toLower, isSpace, isAscii, isControl)
33import Data.Char (toLower, isSpace, isAscii, isControl)
32−import Data.List (intersperse, intercalate, isPrefixOf)
34+import Data.List (intersperse, intercalate, isPrefixOf, stripPrefix)
33import Data.Either (lefts, rights)
35import Data.Either (lefts, rights)
34import Network.Browser (browse, request, setAllowRedirects, setOutHandler)
36import Network.Browser (browse, request, setAllowRedirects, setOutHandler)
35import Network.HTTP (catchIO_, getRequest, getHeaders, getResponseBody)
37import Network.HTTP (catchIO_, getRequest, getHeaders, getResponseBody)
@@ -252,22 +254,21 @@ readDataURI :: String -- ^ URI
252 -> Maybe (String,String,Bool,String)
254 -> Maybe (String,String,Bool,String)
253 -- ^ Maybe (mime,charset,isBase64,data)
255 -- ^ Maybe (mime,charset,isBase64,data)
254readDataURI uri =
256readDataURI uri =
255− let prefix = "data:"
257+ case stripPrefix "data:" uri of
256− in if not (prefix `isPrefixOf` uri)
257− then Nothing
258+ Nothing -> Nothing
258− else
259+ Just rest ->
259− let rest = drop (length prefix) uri
260− meta = takeWhile (/= ',') rest -- without trailing ','
260+ let meta = takeWhile (/= ',') rest -- without trailing ','
261− uridata = drop (length meta + 1) rest
261+ uridata = drop (length meta + 1) rest
262− parts = split (== ';') meta
262+ parts = split (== ';') meta
263− (mime,cs,enc)=foldr upd ("text/plain","US-ASCII",False) parts
263+ (mime,cs,enc)=foldr upd ("text/plain","US-ASCII",False) parts
264− in Just (mime,cs,enc,uridata)
264+ in Just (mime,cs,enc,uridata)
265+
265 where
266 where
266 upd str m@(mime,cs,enc)
267 upd str m@(mime,cs,enc)
267− | isMimeType str = (str,cs,enc)
268+ | isMimeType str = (str,cs,enc)
268− | "charset=" `isPrefixOf` str = (mime,drop (length "charset=") str,enc)
269+ | Just str' <- stripPrefix "charset=" str = (mime,str',enc)
269− | str == "base64" = (mime,cs,True)
270+ | str == "base64" = (mime,cs,True)
270− | otherwise = m
271+ | otherwise = m
271
272
272-- Without parameters like ;charset=...; see RFC 2045, 5.1
273-- Without parameters like ;charset=...; see RFC 2045, 5.1
273isMimeType :: String -> Bool
274isMimeType :: String -> Bool
@@ -295,7 +296,6 @@ fetchURL url = do
295 let content_type = lookupHeader HdrContentType (getHeaders r)
296 let content_type = lookupHeader HdrContentType (getHeaders r)
296 content <- liftM (Just . toStr . encode . toBS) . getResponseBody $ Right r
297 content <- liftM (Just . toStr . encode . toBS) . getResponseBody $ Right r
297 return $ liftM2 (,) content_type content
298 return $ liftM2 (,) content_type content
298− where
299
299
300toBS :: String -> B.ByteString
300toBS :: String -> B.ByteString
301toBS = B.pack . map (toEnum . fromEnum)
301toBS = B.pack . map (toEnum . fromEnum)
src/Text/Pandoc/Writers/LaTeX.hs+5−4
@@ -1,4 +1,5 @@
1−{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
1+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables,
2+ PatternGuards #-}
2{-
3{-
3Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>
4Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>
4
5
@@ -37,7 +38,7 @@ import Text.Pandoc.Options
37import Text.Pandoc.Templates
38import Text.Pandoc.Templates
38import Text.Printf ( printf )
39import Text.Printf ( printf )
39import Network.URI ( isURI, unEscapeString )
40import Network.URI ( isURI, unEscapeString )
40−import Data.List ( (\\), isSuffixOf, isInfixOf,
41+import Data.List ( (\\), isSuffixOf, isInfixOf, stripPrefix,
41 isPrefixOf, intercalate, intersperse )
42 isPrefixOf, intercalate, intersperse )
42import Data.Char ( toLower, isPunctuation, isAscii, isLetter, isDigit, ord )
43import Data.Char ( toLower, isPunctuation, isAscii, isLetter, isDigit, ord )
43import Data.Maybe ( fromMaybe )
44import Data.Maybe ( fromMaybe )
@@ -761,8 +762,8 @@ inlineToLaTeX (Link txt (src, _)) =
761 do modify $ \s -> s{ stUrl = True }
762 do modify $ \s -> s{ stUrl = True }
762 src' <- stringToLaTeX URLString src
763 src' <- stringToLaTeX URLString src
763 return $ text $ "\\url{" ++ src' ++ "}"
764 return $ text $ "\\url{" ++ src' ++ "}"
764− [Str x] | "mailto:" `isPrefixOf` src &&
765+ [Str x] | Just rest <- stripPrefix "mailto:" src,
765− escapeURI x == drop 7 src -> -- email autolink
766+ escapeURI x == rest -> -- email autolink
766 do modify $ \s -> s{ stUrl = True }
767 do modify $ \s -> s{ stUrl = True }
767 src' <- stringToLaTeX URLString src
768 src' <- stringToLaTeX URLString src
768 contents <- inlineListToLaTeX txt
769 contents <- inlineListToLaTeX txt
src/Text/Pandoc/Writers/Man.hs+3−2
@@ -36,7 +36,8 @@ import Text.Pandoc.Writers.Shared
36import Text.Pandoc.Options
36import Text.Pandoc.Options
37import Text.Pandoc.Readers.TeXMath
37import Text.Pandoc.Readers.TeXMath
38import Text.Printf ( printf )
38import Text.Printf ( printf )
39−import Data.List ( isPrefixOf, intersperse, intercalate )
39+import Data.List ( stripPrefix, intersperse, intercalate )
40+import Data.Maybe (fromMaybe)
40import Text.Pandoc.Pretty
41import Text.Pandoc.Pretty
41import Text.Pandoc.Builder (deleteMeta)
42import Text.Pandoc.Builder (deleteMeta)
42import Control.Monad.State
43import Control.Monad.State
@@ -343,7 +344,7 @@ inlineToMan _ (LineBreak) = return $
343inlineToMan _ Space = return space
344inlineToMan _ Space = return space
344inlineToMan opts (Link txt (src, _)) = do
345inlineToMan opts (Link txt (src, _)) = do
345 linktext <- inlineListToMan opts txt
346 linktext <- inlineListToMan opts txt
346− let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src
347+ let srcSuffix = fromMaybe src (stripPrefix "mailto:" src)
347 return $ case txt of
348 return $ case txt of
348 [Str s]
349 [Str s]
349 | escapeURI s == srcSuffix ->
350 | escapeURI s == srcSuffix ->
src/Text/Pandoc/Writers/Markdown.hs+3−2
@@ -38,7 +38,8 @@ import Text.Pandoc.Shared
38import Text.Pandoc.Writers.Shared
38import Text.Pandoc.Writers.Shared
39import Text.Pandoc.Options
39import Text.Pandoc.Options
40import Text.Pandoc.Parsing hiding (blankline, blanklines, char, space)
40import Text.Pandoc.Parsing hiding (blankline, blanklines, char, space)
41+import Data.Maybe (fromMaybe)
41−import Data.List ( group, isPrefixOf, find, intersperse, transpose, sortBy )
42+import Data.List ( group, stripPrefix, find, intersperse, transpose, sortBy )
42import Data.Char ( isSpace, isPunctuation )
43import Data.Char ( isSpace, isPunctuation )
43import Data.Ord ( comparing )
44import Data.Ord ( comparing )
44import Text.Pandoc.Pretty
45import Text.Pandoc.Pretty
@@ -815,7 +816,7 @@ inlineToMarkdown opts (Link txt (src, tit)) = do
815 let linktitle = if null tit
816 let linktitle = if null tit
816 then empty
817 then empty
817 else text $ " \"" ++ tit ++ "\""
818 else text $ " \"" ++ tit ++ "\""
818− let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src
819+ let srcSuffix = fromMaybe src (stripPrefix "mailto:" src)
819 let useAuto = isURI src &&
820 let useAuto = isURI src &&
820 case txt of
821 case txt of
821 [Str s] | escapeURI s == srcSuffix -> True
822 [Str s] | escapeURI s == srcSuffix -> True
src/Text/Pandoc/Writers/RST.hs+3−2
@@ -37,7 +37,8 @@ import Text.Pandoc.Shared
37import Text.Pandoc.Writers.Shared
37import Text.Pandoc.Writers.Shared
38import Text.Pandoc.Templates (renderTemplate')
38import Text.Pandoc.Templates (renderTemplate')
39import Text.Pandoc.Builder (deleteMeta)
39import Text.Pandoc.Builder (deleteMeta)
40+import Data.Maybe (fromMaybe)
40−import Data.List ( isPrefixOf, intersperse, transpose )
41+import Data.List ( isPrefixOf, stripPrefix, intersperse, transpose )
41import Network.URI (isURI)
42import Network.URI (isURI)
42import Text.Pandoc.Pretty
43import Text.Pandoc.Pretty
43import Control.Monad.State
44import Control.Monad.State
@@ -401,7 +402,7 @@ inlineToRST (Link [Str str] (src, _))
401 if "mailto:" `isPrefixOf` src
402 if "mailto:" `isPrefixOf` src
402 then src == escapeURI ("mailto:" ++ str)
403 then src == escapeURI ("mailto:" ++ str)
403 else src == escapeURI str = do
404 else src == escapeURI str = do
404− let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src
405+ let srcSuffix = fromMaybe src (stripPrefix "mailto:" src)
405 return $ text srcSuffix
406 return $ text srcSuffix
406inlineToRST (Link [Image alt (imgsrc,imgtit)] (src, _tit)) = do
407inlineToRST (Link [Image alt (imgsrc,imgtit)] (src, _tit)) = do
407 label <- registerImage alt (imgsrc,imgtit) (Just src)
408 label <- registerImage alt (imgsrc,imgtit) (Just src)