diff options
Diffstat (limited to 'src/Text/Pandoc/Shared.hs')
-rw-r--r-- | src/Text/Pandoc/Shared.hs | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/src/Text/Pandoc/Shared.hs b/src/Text/Pandoc/Shared.hs index a86e5da95..96dbec6f6 100644 --- a/src/Text/Pandoc/Shared.hs +++ b/src/Text/Pandoc/Shared.hs @@ -92,7 +92,9 @@ module Text.Pandoc.Shared ( -- * Safe read safeRead, -- * Temp directory - withTempDir + withTempDir, + -- * Version + pandocVersion ) where import Text.Pandoc.Definition @@ -106,35 +108,38 @@ import System.Exit (exitWith, ExitCode(..)) import Data.Char ( toLower, isLower, isUpper, isAlpha, isLetter, isDigit, isSpace ) import Data.List ( find, stripPrefix, intercalate ) +import Data.Version ( showVersion ) import qualified Data.Map as M import Network.URI ( escapeURIString, isURI, nonStrictRelativeTo, unEscapeString, parseURIReference, isAllowedInURI ) import qualified Data.Set as Set import System.Directory -import System.FilePath (joinPath, splitDirectories, pathSeparator, isPathSeparator) +import System.FilePath (splitDirectories, isPathSeparator) +import qualified System.FilePath.Posix as Posix import Text.Pandoc.MIME (MimeType, getMimeType) import System.FilePath ( (</>), takeExtension, dropExtension) import Data.Generics (Typeable, Data) import qualified Control.Monad.State as S import qualified Control.Exception as E -import Control.Applicative ((<$>)) import Control.Monad (msum, unless, MonadPlus(..)) import Text.Pandoc.Pretty (charWidth) -import Text.Pandoc.Compat.Locale (defaultTimeLocale) -import Data.Time +import Text.Pandoc.Compat.Time import Data.Time.Clock.POSIX import System.IO (stderr) import System.IO.Temp import Text.HTML.TagSoup (renderTagsOptions, RenderOptions(..), Tag(..), renderOptions) +import Text.Pandoc.Compat.Monoid ((<>)) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as B8 -import Text.Pandoc.Compat.Monoid import Data.ByteString.Base64 (decodeLenient) import Data.Sequence (ViewR(..), ViewL(..), viewl, viewr) import qualified Data.Text as T (toUpper, pack, unpack) import Data.ByteString.Lazy (toChunks, fromChunks) import qualified Data.ByteString.Lazy as BL +import Paths_pandoc (version) + +import Codec.Archive.Zip #ifdef EMBED_DATA_FILES import Text.Pandoc.Data (dataFiles) @@ -155,7 +160,6 @@ import Network.HTTP.Client.TLS (tlsManagerSettings) import System.Environment (getEnv) import Network.HTTP.Types.Header ( hContentType) import Network (withSocketsDo) -import Codec.Archive.Zip #else import Network.URI (parseURI) import Network.HTTP (findHeader, rspBody, @@ -163,6 +167,10 @@ import Network.HTTP (findHeader, rspBody, import Network.Browser (browse, setAllowRedirects, setOutHandler, request) #endif +-- | Version number of pandoc library. +pandocVersion :: String +pandocVersion = showVersion version + -- -- List processing -- @@ -278,9 +286,12 @@ toRomanNumeral x = _ | x >= 1 -> "I" ++ toRomanNumeral (x - 1) _ -> "" --- | Escape whitespace in URI. +-- | Escape whitespace and some punctuation characters in URI. escapeURI :: String -> String -escapeURI = escapeURIString (not . isSpace) +escapeURI = escapeURIString (not . needsEscaping) + where needsEscaping c = isSpace c || c `elem` + ['<','>','|','"','{','}','[',']','^', '`'] + -- | Convert tabs to spaces and filter out DOS line endings. -- Tabs will be preserved if tab stop is set to 0. @@ -310,7 +321,12 @@ tabFilter tabStop = normalizeDate :: String -> Maybe String normalizeDate s = fmap (formatTime defaultTimeLocale "%F") (msum $ map (\fs -> parsetimeWith fs s) formats :: Maybe Day) - where parsetimeWith = parseTime defaultTimeLocale + where parsetimeWith = +#if MIN_VERSION_time(1,5,0) + parseTimeM True defaultTimeLocale +#else + parseTime defaultTimeLocale +#endif formats = ["%x","%m/%d/%Y", "%D","%F", "%d %b %Y", "%d %B %Y", "%b. %d, %Y", "%B %d, %Y", "%Y"] @@ -539,6 +555,7 @@ stringify = query go . walk deNote go (Str x) = x go (Code _ x) = x go (Math _ x) = x + go (RawInline (Format "html") ('<':'b':'r':_)) = " " -- see #2105 go LineBreak = " " go _ = "" deNote (Note _) = Str "" @@ -830,7 +847,7 @@ readDefaultDataFile fname = case lookup (makeCanonical fname) dataFiles of Nothing -> err 97 $ "Could not find data file " ++ fname Just contents -> return contents - where makeCanonical = joinPath . transformPathParts . splitDirectories + where makeCanonical = Posix.joinPath . transformPathParts . splitDirectories transformPathParts = reverse . foldl go [] go as "." = as go (_:as) ".." = as @@ -838,7 +855,6 @@ readDefaultDataFile fname = #else getDataFileName fname' >>= checkExistence >>= BS.readFile where fname' = if fname == "README" then fname else "data" </> fname -#endif checkExistence :: FilePath -> IO FilePath checkExistence fn = do @@ -846,6 +862,7 @@ checkExistence fn = do if exists then return fn else err 97 ("Could not find data file " ++ fn) +#endif -- | Read file from specified user data directory or, if not found there, from -- Cabal data directory. @@ -897,9 +914,9 @@ fetchItem' media sourceURL s = do -- | Read from a URL and return raw data and maybe mime type. openURL :: String -> IO (Either E.SomeException (BS.ByteString, Maybe MimeType)) openURL u - | Just u' <- stripPrefix "data:" u = - let mime = takeWhile (/=',') u' - contents = B8.pack $ unEscapeString $ drop 1 $ dropWhile (/=',') u' + | Just u'' <- stripPrefix "data:" u = + let mime = takeWhile (/=',') u'' + contents = B8.pack $ unEscapeString $ drop 1 $ dropWhile (/=',') u'' in return $ Right (decodeLenient contents, Just mime) #ifdef HTTP_CLIENT | otherwise = withSocketsDo $ E.try $ do @@ -965,14 +982,14 @@ hush (Right x) = Just x -- > collapseFilePath "parent/foo/.." == "parent" -- > collapseFilePath "/parent/foo/../../bar" == "/bar" collapseFilePath :: FilePath -> FilePath -collapseFilePath = joinPath . reverse . foldl go [] . splitDirectories +collapseFilePath = Posix.joinPath . reverse . foldl go [] . splitDirectories where go rs "." = rs go r@(p:rs) ".." = case p of ".." -> ("..":r) (checkPathSeperator -> Just True) -> ("..":r) _ -> rs - go _ (checkPathSeperator -> Just True) = [[pathSeparator]] + go _ (checkPathSeperator -> Just True) = [[Posix.pathSeparator]] go rs x = x:rs isSingleton [] = Nothing isSingleton [x] = Just x |