aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README7
-rw-r--r--data/docx/word/styles.xml19
-rw-r--r--src/Text/Pandoc/Readers/Org.hs2
-rw-r--r--src/Text/Pandoc/Writers/Docx.hs51
-rw-r--r--tests/Tests/Readers/Org.hs4
5 files changed, 78 insertions, 5 deletions
diff --git a/README b/README
index 2d28155cd..db3d93ae1 100644
--- a/README
+++ b/README
@@ -319,7 +319,12 @@ Reader options
Those who would prefer to write filters in python can use the
module `pandocfilters`, installable from PyPI. See
<http://github.com/jgm/pandocfilters> for the module and several
- examples. Note that the *EXECUTABLE* will be sought in the user's
+ examples. There are also pandoc filter libraries in
+ [PHP](https://github.com/vinai/pandocfilters-php),
+ [perl](https://metacpan.org/pod/Pandoc::Filter), and
+ [javascript/node.js](https://github.com/mvhenderson/pandoc-filter-node).
+
+ Note that the *EXECUTABLE* will be sought in the user's
`PATH`, and not in the working directory, if no directory is
provided. If you want to run a script in the working directory,
preface the filename with `./`.
diff --git a/data/docx/word/styles.xml b/data/docx/word/styles.xml
index 0de21bd4c..01190ef5a 100644
--- a/data/docx/word/styles.xml
+++ b/data/docx/word/styles.xml
@@ -340,4 +340,23 @@
<w:color w:val="4F81BD" w:themeColor="accent1" />
</w:rPr>
</w:style>
+ <w:style w:type="paragraph" w:styleId="TOCHeading">
+ <w:name w:val="TOC Heading" />
+ <w:basedOn w:val="Heading1" />
+ <w:next w:val="BodyText" />
+ <w:uiPriority w:val="39" />
+ <w:unhideWhenUsed />
+ <w:qFormat />
+ <w:pPr>
+ <w:spacing w:before="240" w:line="259" w:lineRule="auto" />
+ <w:outlineLvl w:val="9" />
+ </w:pPr>
+ <w:rPr>
+ <w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
+ <w:b w:val="0" />
+ <w:bCs w:val="0" />
+ <w:color w:val="365F91" w:themeColor="accent1"
+ w:themeShade="BF" />
+ </w:rPr>
+ </w:style>
</w:styles>
diff --git a/src/Text/Pandoc/Readers/Org.hs b/src/Text/Pandoc/Readers/Org.hs
index 1dfbdd700..fc63cc11e 100644
--- a/src/Text/Pandoc/Readers/Org.hs
+++ b/src/Text/Pandoc/Readers/Org.hs
@@ -1093,7 +1093,7 @@ explicitOrImageLink = try $ do
char ']'
alt <- internalLink src title'
return $
- (if isImageFilename src && isImageFilename title
+ (if isImageFilename title
then B.link src "" $ B.image title mempty mempty
else fromMaybe alt (linkToInlines src title'))
diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs
index 5903e7689..8bb1d0ced 100644
--- a/src/Text/Pandoc/Writers/Docx.hs
+++ b/src/Text/Pandoc/Writers/Docx.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ScopedTypeVariables, PatternGuards #-}
+{-# LANGUAGE ScopedTypeVariables, PatternGuards, ViewPatterns #-}
{-
Copyright (C) 2012-2014 John MacFarlane <jgm@berkeley.edu>
@@ -66,6 +66,7 @@ import Text.Pandoc.MIME (MimeType, getMimeType, getMimeTypeDef,
extensionFromMimeType)
import Control.Applicative ((<$>), (<|>), (<*>))
import Data.Maybe (fromMaybe, mapMaybe, maybeToList)
+import Data.Char (ord)
data ListMarker = NoMarker
| BulletMarker
@@ -176,13 +177,29 @@ renumId f renumMap e
renumIds :: (QName -> Bool) -> (M.Map String String) -> [Element] -> [Element]
renumIds f renumMap = map (renumId f renumMap)
+-- | Certain characters are invalid in XML even if escaped.
+-- See #1992
+stripInvalidChars :: Pandoc -> Pandoc
+stripInvalidChars = bottomUp (filter isValidChar)
+
+-- | See XML reference
+isValidChar :: Char -> Bool
+isValidChar (ord -> c)
+ | c == 0x9 = True
+ | c == 0xA = True
+ | c == 0xD = True
+ | 0x20 <= c && c <= 0xD7FF = True
+ | 0xE000 <= c && c <= 0xFFFD = True
+ | 0x10000 <= c && c <= 0x10FFFF = True
+ | otherwise = False
+
-- | Produce an Docx file from a Pandoc document.
writeDocx :: WriterOptions -- ^ Writer options
-> Pandoc -- ^ Document to convert
-> IO BL.ByteString
writeDocx opts doc@(Pandoc meta _) = do
let datadir = writerUserDataDir opts
- let doc' = walk fixDisplayMath doc
+ let doc' = stripInvalidChars . walk fixDisplayMath $ doc
username <- lookup "USERNAME" <$> getEnvironment
utctime <- getCurrentTime
refArchive <- liftM (toArchive . toLazy) $
@@ -604,6 +621,33 @@ mkLvl marker lvl =
getNumId :: WS Int
getNumId = (((baseListId - 1) +) . length) `fmap` gets stLists
+makeTOC :: WriterOptions -> WS [Element]
+makeTOC opts | writerTableOfContents opts = do
+ let depth = "1-"++(show (writerTOCDepth opts))
+ let tocCmd = "TOC \\o \""++depth++"\" \\h \\z \\u"
+ title <- withParaPropM (pStyleM "TOC Heading") (blocksToOpenXML opts [Para [Str "Table of Contents"]])
+ return $
+ [mknode "w:sdt" [] ([
+ mknode "w:sdtPr" [] (
+ mknode "w:docPartObj" [] (
+ [mknode "w:docPartGallery" [("w:val","Table of Contents")] (),
+ mknode "w:docPartUnique" [] ()]
+ ) -- w:docPartObj
+ ), -- w:sdtPr
+ mknode "w:sdtContent" [] (title++[
+ mknode "w:p" [] (
+ mknode "w:r" [] ([
+ mknode "w:fldChar" [("w:fldCharType","begin"),("w:dirty","true")] (),
+ mknode "w:instrText" [("xml:space","preserve")] tocCmd,
+ mknode "w:fldChar" [("w:fldCharType","separate")] (),
+ mknode "w:fldChar" [("w:fldCharType","end")] ()
+ ]) -- w:r
+ ) -- w:p
+ ])
+ ])] -- w:sdt
+makeTOC _ = return []
+
+
-- | Convert Pandoc document to two lists of
-- OpenXML elements (the main document and footnotes).
writeOpenXML :: WriterOptions -> Pandoc -> WS ([Element], [Element])
@@ -636,7 +680,8 @@ writeOpenXML opts (Pandoc meta blocks) = do
let blocks' = bottomUp convertSpace blocks
doc' <- (setFirstPara >> blocksToOpenXML opts blocks')
notes' <- reverse `fmap` gets stFootnotes
- let meta' = title ++ subtitle ++ authors ++ date ++ abstract
+ toc <- makeTOC opts
+ let meta' = title ++ subtitle ++ authors ++ date ++ abstract ++ toc
return (meta' ++ doc', notes')
-- | Convert a list of Pandoc blocks to OpenXML.
diff --git a/tests/Tests/Readers/Org.hs b/tests/Tests/Readers/Org.hs
index f555447c7..4cec54a68 100644
--- a/tests/Tests/Readers/Org.hs
+++ b/tests/Tests/Readers/Org.hs
@@ -216,6 +216,10 @@ tests =
"[[sunset.png][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" "" ""))
+
, "Plain link" =:
"Posts on http://zeitlens.com/ can be funny at times." =?>
(para $ spcSep [ "Posts", "on"