aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL26
-rw-r--r--MANUAL.txt7
m---------data/templates14
-rw-r--r--src/Text/Pandoc/Error.hs12
-rw-r--r--src/Text/Pandoc/Readers/MediaWiki.hs22
-rw-r--r--src/Text/Pandoc/Readers/Org/Blocks.hs45
-rw-r--r--src/Text/Pandoc/Readers/Org/Inlines.hs33
-rw-r--r--src/Text/Pandoc/Readers/Org/Shared.hs25
-rw-r--r--src/Text/Pandoc/Readers/Textile.hs5
-rw-r--r--src/Text/Pandoc/Writers/LaTeX.hs4
-rw-r--r--tests/Tests/Readers/Org.hs26
11 files changed, 146 insertions, 73 deletions
diff --git a/INSTALL b/INSTALL
index 87be44eca..01747665d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -8,6 +8,32 @@ There are also binary installers for Windows and Mac OS X.
If you are installing the development version from github, see also:
https://github.com/jgm/pandoc/wiki/Installing-the-development-version-of-pandoc
+How to get the source
+---------------------
+
+Source tarballs can be found at
+<https://hackage.haskell.org/package/pandoc>. The tarball
+for a particular version `VERSION` can be found at
+
+ https://hackage.haskell.org/package/pandoc-VERSION/pandoc-VERSION.tar.gz
+
+**Do not use the automatically generated tarball that can be
+downloaded from pandoc's GitHub releases page.** It does not
+include some essential template files, which come from a GitHub
+submodule.
+
+If you want the latest development code, you can fetch it
+by cloning the repository:
+
+ git clone https://github.com/jgm/pandoc
+ cd pandoc
+ git submodule update --init # to fetch the templates
+
+Note: there may be times when the development code is broken
+or depends on other libraries which must be installed
+separately. Unless you really know what you're doing, install
+the last released version.
+
Quick install with stack
------------------------
diff --git a/MANUAL.txt b/MANUAL.txt
index 8d5be98f8..2177cf926 100644
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -1164,6 +1164,9 @@ including all [reveal.js configuration options].
`theme`, `colortheme`, `fonttheme`, `innertheme`, `outertheme`
: themes for LaTeX [`beamer`] documents
+`themeoptions`
+: options for LaTeX beamer themes (a list).
+
`navigation`
: controls navigation symbols in `beamer` documents
(default is `empty` for no navigation symbols; other valid values
@@ -1173,6 +1176,10 @@ including all [reveal.js configuration options].
: enables on "title pages" for new sections in `beamer`
documents (default = true).
+`beamerarticle`
+: when true, the `beamerarticle` package is loaded (for
+ producing an article from beamer slides).
+
[reveal.js configuration options]: https://github.com/hakimel/reveal.js#configuration
Variables for LaTeX
diff --git a/data/templates b/data/templates
-Subproject 8bed1acf2271c84ae564d6f0b9adcdc4d5c71d2
+Subproject 284279f61e493bf70a8375eb772d293b9fb5d6b
diff --git a/src/Text/Pandoc/Error.hs b/src/Text/Pandoc/Error.hs
index 792098b35..292396aee 100644
--- a/src/Text/Pandoc/Error.hs
+++ b/src/Text/Pandoc/Error.hs
@@ -62,8 +62,12 @@ handleError (Left err) =
let errPos = errorPos err'
errLine = sourceLine errPos
errColumn = sourceColumn errPos
- theline = (lines input ++ [""]) !! (errLine - 1)
- in error $ "\nError at " ++ show err' ++ "\n" ++
- theline ++ "\n" ++ replicate (errColumn - 1) ' ' ++
- "^"
+ ls = lines input ++ [""]
+ errorInFile = if length ls > errLine - 1
+ then concat ["\n", (ls !! (errLine - 1))
+ ,"\n", replicate (errColumn - 1) ' '
+ ,"^"]
+ else ""
+ in error $ "\nError at " ++ show err'
+ ++ errorInFile
diff --git a/src/Text/Pandoc/Readers/MediaWiki.hs b/src/Text/Pandoc/Readers/MediaWiki.hs
index d3cee08e2..dcf0c5f4a 100644
--- a/src/Text/Pandoc/Readers/MediaWiki.hs
+++ b/src/Text/Pandoc/Readers/MediaWiki.hs
@@ -253,7 +253,7 @@ parseAttr = try $ do
k <- many1 letter
char '='
v <- (char '"' >> many1Till (satisfy (/='\n')) (char '"'))
- <|> many1 nonspaceChar
+ <|> many1 (satisfy $ \c -> not (isSpace c) && c /= '|')
return (k,v)
tableStart :: MWParser ()
@@ -376,11 +376,17 @@ preformatted = try $ do
spacesStr _ = False
if F.all spacesStr contents
then return mempty
- else return $ B.para $ walk strToCode contents
-
-strToCode :: Inline -> Inline
-strToCode (Str s) = Code ("",[],[]) s
-strToCode x = x
+ else return $ B.para $ encode contents
+
+encode :: Inlines -> Inlines
+encode = B.fromList . normalizeCode . B.toList . walk strToCode
+ where strToCode (Str s) = Code ("",[],[]) s
+ strToCode Space = Code ("",[],[]) " "
+ strToCode x = x
+ normalizeCode [] = []
+ normalizeCode (Code a1 x : Code a2 y : zs) | a1 == a2 =
+ normalizeCode $ (Code a1 (x ++ y)) : zs
+ normalizeCode (x:xs) = x : normalizeCode xs
header :: MWParser Blocks
header = try $ do
@@ -545,8 +551,8 @@ inlineTag = do
TagOpen "del" _ -> B.strikeout <$> inlinesInTags "del"
TagOpen "sub" _ -> B.subscript <$> inlinesInTags "sub"
TagOpen "sup" _ -> B.superscript <$> inlinesInTags "sup"
- TagOpen "code" _ -> walk strToCode <$> inlinesInTags "code"
- TagOpen "tt" _ -> walk strToCode <$> inlinesInTags "tt"
+ TagOpen "code" _ -> encode <$> inlinesInTags "code"
+ TagOpen "tt" _ -> encode <$> inlinesInTags "tt"
TagOpen "hask" _ -> B.codeWith ("",["haskell"],[]) <$> charsInTags "hask"
_ -> B.rawInline "html" . snd <$> htmlTag (~== tag)
diff --git a/src/Text/Pandoc/Readers/Org/Blocks.hs b/src/Text/Pandoc/Readers/Org/Blocks.hs
index 0bd82ce2f..6a8bb8b28 100644
--- a/src/Text/Pandoc/Readers/Org/Blocks.hs
+++ b/src/Text/Pandoc/Readers/Org/Blocks.hs
@@ -39,8 +39,8 @@ import Text.Pandoc.Readers.Org.Inlines
import Text.Pandoc.Readers.Org.ParserState
import Text.Pandoc.Readers.Org.Parsing
import Text.Pandoc.Readers.Org.Shared
- ( isImageFilename, rundocBlockClass, toRundocAttrib
- , translateLang )
+ ( cleanLinkString, isImageFilename, rundocBlockClass
+ , toRundocAttrib, translateLang )
import qualified Text.Pandoc.Builder as B
import Text.Pandoc.Builder ( Inlines, Blocks )
@@ -422,7 +422,16 @@ verseBlock blockType = try $ do
ignHeaders
content <- rawBlockContent blockType
fmap B.para . mconcat . intersperse (pure B.linebreak)
- <$> mapM (parseFromString inlines) (map (++ "\n") . lines $ content)
+ <$> mapM parseVerseLine (lines content)
+ where
+ -- replace initial spaces with nonbreaking spaces to preserve
+ -- indentation, parse the rest as normal inline
+ parseVerseLine :: String -> OrgParser (F Inlines)
+ parseVerseLine cs = do
+ let (initialSpaces, indentedLine) = span isSpace cs
+ let nbspIndent = B.str $ map (const '\160') initialSpaces
+ line <- parseFromString inlines (indentedLine ++ "\n")
+ return (pure nbspIndent <> line)
-- | Read a code block and the associated results block if present. Which of
-- boths blocks is included in the output is determined using the "exports"
@@ -571,23 +580,33 @@ figure :: OrgParser (F Blocks)
figure = try $ do
figAttrs <- blockAttributes
src <- skipSpaces *> selfTarget <* skipSpaces <* newline
- guard . not . isNothing . blockAttrCaption $ figAttrs
- guard (isImageFilename src)
- let figName = fromMaybe mempty $ blockAttrName figAttrs
- let figLabel = fromMaybe mempty $ blockAttrLabel figAttrs
- let figCaption = fromMaybe mempty $ blockAttrCaption figAttrs
- let figKeyVals = blockAttrKeyValues figAttrs
- let attr = (figLabel, mempty, figKeyVals)
- return $ (B.para . B.imageWith attr src (withFigPrefix figName) <$> figCaption)
+ case cleanLinkString src of
+ Nothing -> mzero
+ Just imgSrc -> do
+ guard (not . isNothing . blockAttrCaption $ figAttrs)
+ guard (isImageFilename imgSrc)
+ return $ figureBlock figAttrs imgSrc
where
+ selfTarget :: OrgParser String
+ selfTarget = try $ char '[' *> linkTarget <* char ']'
+
+ figureBlock :: BlockAttributes -> String -> (F Blocks)
+ figureBlock figAttrs imgSrc =
+ let
+ figName = fromMaybe mempty $ blockAttrName figAttrs
+ figLabel = fromMaybe mempty $ blockAttrLabel figAttrs
+ figCaption = fromMaybe mempty $ blockAttrCaption figAttrs
+ figKeyVals = blockAttrKeyValues figAttrs
+ attr = (figLabel, mempty, figKeyVals)
+ in
+ B.para . B.imageWith attr imgSrc (withFigPrefix figName) <$> figCaption
+
withFigPrefix :: String -> String
withFigPrefix cs =
if "fig:" `isPrefixOf` cs
then cs
else "fig:" ++ cs
- selfTarget :: OrgParser String
- selfTarget = try $ char '[' *> linkTarget <* char ']'
--
-- Examples
diff --git a/src/Text/Pandoc/Readers/Org/Inlines.hs b/src/Text/Pandoc/Readers/Org/Inlines.hs
index e1a66a8c7..31f098d27 100644
--- a/src/Text/Pandoc/Readers/Org/Inlines.hs
+++ b/src/Text/Pandoc/Readers/Org/Inlines.hs
@@ -37,8 +37,8 @@ import Text.Pandoc.Readers.Org.BlockStarts
import Text.Pandoc.Readers.Org.ParserState
import Text.Pandoc.Readers.Org.Parsing
import Text.Pandoc.Readers.Org.Shared
- ( isImageFilename, rundocBlockClass, toRundocAttrib
- , translateLang )
+ ( cleanLinkString, isImageFilename, rundocBlockClass
+ , toRundocAttrib, translateLang )
import qualified Text.Pandoc.Builder as B
import Text.Pandoc.Builder ( Inlines )
@@ -52,7 +52,7 @@ import qualified Text.TeXMath.Readers.MathML.EntityMap as MathMLEntityMap
import Prelude hiding (sequence)
import Control.Monad ( guard, mplus, mzero, when, void )
import Data.Char ( isAlphaNum, isSpace )
-import Data.List ( intersperse, isPrefixOf )
+import Data.List ( intersperse )
import Data.Maybe ( fromMaybe )
import qualified Data.Map as M
import Data.Traversable (sequence)
@@ -435,9 +435,11 @@ explicitOrImageLink = try $ do
char ']'
return $ do
src <- srcF
- if isImageFilename title
- then pure $ B.link src "" $ B.image title mempty mempty
- else linkToInlinesF src =<< title'
+ case cleanLinkString title of
+ Just imgSrc | isImageFilename imgSrc ->
+ pure $ B.link src "" $ B.image imgSrc mempty mempty
+ _ ->
+ linkToInlinesF src =<< title'
selflinkOrImage :: OrgParser (F Inlines)
selflinkOrImage = try $ do
@@ -482,25 +484,6 @@ linkToInlinesF linkStr =
else pure . B.link cleanedLink ""
Nothing -> internalLink linkStr -- other internal link
--- | Cleanup and canonicalize a string describing a link. Return @Nothing@ if
--- the string does not appear to be a link.
-cleanLinkString :: String -> Maybe String
-cleanLinkString s =
- case s of
- '/':_ -> Just $ "file://" ++ s -- absolute path
- '.':'/':_ -> Just s -- relative path
- '.':'.':'/':_ -> Just s -- relative path
- -- Relative path or URL (file schema)
- 'f':'i':'l':'e':':':s' -> Just $ if ("//" `isPrefixOf` s') then s else s'
- _ | isUrl s -> Just s -- URL
- _ -> Nothing
- where
- isUrl :: String -> Bool
- isUrl cs =
- let (scheme, path) = break (== ':') cs
- in all (\c -> isAlphaNum c || c `elem` (".-"::String)) scheme
- && not (null path)
-
internalLink :: String -> Inlines -> F Inlines
internalLink link title = do
anchorB <- (link `elem`) <$> asksF orgStateAnchorIds
diff --git a/src/Text/Pandoc/Readers/Org/Shared.hs b/src/Text/Pandoc/Readers/Org/Shared.hs
index 3ba46b9e4..8c87cfa25 100644
--- a/src/Text/Pandoc/Readers/Org/Shared.hs
+++ b/src/Text/Pandoc/Readers/Org/Shared.hs
@@ -27,13 +27,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Utility functions used in other Pandoc Org modules.
-}
module Text.Pandoc.Readers.Org.Shared
- ( isImageFilename
+ ( cleanLinkString
+ , isImageFilename
, rundocBlockClass
, toRundocAttrib
, translateLang
) where
import Control.Arrow ( first )
+import Data.Char ( isAlphaNum )
import Data.List ( isPrefixOf, isSuffixOf )
@@ -41,12 +43,31 @@ import Data.List ( isPrefixOf, isSuffixOf )
isImageFilename :: String -> Bool
isImageFilename filename =
any (\x -> ('.':x) `isSuffixOf` filename) imageExtensions &&
- (any (\x -> (x++":") `isPrefixOf` filename) protocols ||
+ (any (\x -> (x ++ "://") `isPrefixOf` filename) protocols ||
':' `notElem` filename)
where
imageExtensions = [ "jpeg" , "jpg" , "png" , "gif" , "svg" ]
protocols = [ "file", "http", "https" ]
+-- | Cleanup and canonicalize a string describing a link. Return @Nothing@ if
+-- the string does not appear to be a link.
+cleanLinkString :: String -> Maybe String
+cleanLinkString s =
+ case s of
+ '/':_ -> Just $ "file://" ++ s -- absolute path
+ '.':'/':_ -> Just s -- relative path
+ '.':'.':'/':_ -> Just s -- relative path
+ -- Relative path or URL (file schema)
+ 'f':'i':'l':'e':':':s' -> Just $ if ("//" `isPrefixOf` s') then s else s'
+ _ | isUrl s -> Just s -- URL
+ _ -> Nothing
+ where
+ isUrl :: String -> Bool
+ isUrl cs =
+ let (scheme, path) = break (== ':') cs
+ in all (\c -> isAlphaNum c || c `elem` (".-"::String)) scheme
+ && not (null path)
+
-- | Prefix used for Rundoc classes and arguments.
rundocPrefix :: String
rundocPrefix = "rundoc-"
diff --git a/src/Text/Pandoc/Readers/Textile.hs b/src/Text/Pandoc/Readers/Textile.hs
index 4ab0243fe..a4de85dfb 100644
--- a/src/Text/Pandoc/Readers/Textile.hs
+++ b/src/Text/Pandoc/Readers/Textile.hs
@@ -60,7 +60,7 @@ import Text.Pandoc.Parsing
import Text.Pandoc.Readers.HTML ( htmlTag, isBlockTag, isInlineTag )
import Text.Pandoc.Shared (trim)
import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
-import Text.HTML.TagSoup (parseTags, innerText, fromAttrib, Tag(..))
+import Text.HTML.TagSoup (fromAttrib, Tag(..))
import Text.HTML.TagSoup.Match
import Data.List ( intercalate, transpose, intersperse )
import Data.Char ( digitToInt, isUpper )
@@ -182,8 +182,7 @@ trimTrailingNewlines = reverse . dropWhile (=='\n') . reverse
codeBlockPre :: Parser [Char] ParserState Blocks
codeBlockPre = try $ do
(t@(TagOpen _ attrs),_) <- htmlTag (tagOpen (=="pre") (const True))
- result' <- (innerText . parseTags) `fmap` -- remove internal tags
- manyTill anyChar (htmlTag (tagClose (=="pre")))
+ result' <- manyTill anyChar (htmlTag (tagClose (=="pre")))
optional blanklines
-- drop leading newline if any
let result'' = case result' of
diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs
index 5829bcd33..29e8c962c 100644
--- a/src/Text/Pandoc/Writers/LaTeX.hs
+++ b/src/Text/Pandoc/Writers/LaTeX.hs
@@ -732,7 +732,6 @@ sectionHeader unnumbered ident level lst = do
noNote x = x
let lstNoNotes = walk noNote lst
txtNoNotes <- inlineListToLaTeX lstNoNotes
- let star = if unnumbered then text "*" else empty
-- footnotes in sections don't work (except for starred variants)
-- unless you specify an optional argument:
-- \section[mysec]{mysec\footnote{blah}}
@@ -745,7 +744,6 @@ sectionHeader unnumbered ident level lst = do
else braces (text "\\texorpdfstring"
<> braces txt
<> braces (text plain))
- let stuffing = star <> optional <> contents
book <- gets stBook
opts <- gets stOptions
let level' = if book || writerChapters opts then level - 1 else level
@@ -765,6 +763,8 @@ sectionHeader unnumbered ident level lst = do
-- see http://tex.stackexchange.com/questions/169830/
else empty
lab <- labelFor ident
+ let star = if unnumbered && level < 4 then text "*" else empty
+ let stuffing = star <> optional <> contents
stuffing' <- hypertarget ident $ text ('\\':sectionType) <> stuffing <> lab
return $ if level' > 5
then txt
diff --git a/tests/Tests/Readers/Org.hs b/tests/Tests/Readers/Org.hs
index 1f8a8a01e..0a3f9c222 100644
--- a/tests/Tests/Readers/Org.hs
+++ b/tests/Tests/Readers/Org.hs
@@ -219,12 +219,12 @@ tests =
(para $ link "" "" "New Link")
, "Image link" =:
- "[[sunset.png][dusk.svg]]" =?>
+ "[[sunset.png][file:dusk.svg]]" =?>
(para $ link "sunset.png" "" (image "dusk.svg" "" ""))
, "Image link with non-image target" =:
- "[[http://example.com][logo.png]]" =?>
- (para $ link "http://example.com" "" (image "logo.png" "" ""))
+ "[[http://example.com][./logo.png]]" =?>
+ (para $ link "http://example.com" "" (image "./logo.png" "" ""))
, "Plain link" =:
"Posts on http://zeitlens.com/ can be funny at times." =?>
@@ -810,29 +810,29 @@ tests =
[ "Figure" =:
unlines [ "#+caption: A very courageous man."
, "#+name: goodguy"
- , "[[edward.jpg]]"
+ , "[[file:edward.jpg]]"
] =?>
para (image "edward.jpg" "fig:goodguy" "A very courageous man.")
, "Figure with no name" =:
unlines [ "#+caption: I've been through the desert on this"
- , "[[horse.png]]"
+ , "[[file:horse.png]]"
] =?>
para (image "horse.png" "fig:" "I've been through the desert on this")
, "Figure with `fig:` prefix in name" =:
unlines [ "#+caption: Used as a metapher in evolutionary biology."
, "#+name: fig:redqueen"
- , "[[the-red-queen.jpg]]"
+ , "[[./the-red-queen.jpg]]"
] =?>
- para (image "the-red-queen.jpg" "fig:redqueen"
+ para (image "./the-red-queen.jpg" "fig:redqueen"
"Used as a metapher in evolutionary biology.")
, "Figure with HTML attributes" =:
unlines [ "#+CAPTION: mah brain just explodid"
, "#+NAME: lambdacat"
, "#+ATTR_HTML: :style color: blue :role button"
- , "[[lambdacat.jpg]]"
+ , "[[file:lambdacat.jpg]]"
] =?>
let kv = [("style", "color: blue"), ("role", "button")]
name = "fig:lambdacat"
@@ -842,7 +842,7 @@ tests =
, "Labelled figure" =:
unlines [ "#+CAPTION: My figure"
, "#+LABEL: fig:myfig"
- , "[[blub.png]]"
+ , "[[file:blub.png]]"
] =?>
let attr = ("fig:myfig", mempty, mempty)
in para (imageWith attr "blub.png" "fig:" "My figure")
@@ -1440,6 +1440,14 @@ tests =
] =?>
para ("foo" <> linebreak <> linebreak <> "bar")
+ , "Verse block with varying indentation" =:
+ unlines [ "#+BEGIN_VERSE"
+ , " hello darkness"
+ , "my old friend"
+ , "#+END_VERSE"
+ ] =?>
+ para ("\160\160hello darkness" <> linebreak <> "my old friend")
+
, "Raw block LaTeX" =:
unlines [ "#+BEGIN_LaTeX"
, "The category $\\cat{Set}$ is adhesive."