summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Text/Pandoc/Writers/ZimWiki.hs78
-rw-r--r--test/tables.zimwiki46
-rw-r--r--test/writer.zimwiki12
3 files changed, 81 insertions, 55 deletions
diff --git a/src/Text/Pandoc/Writers/ZimWiki.hs b/src/Text/Pandoc/Writers/ZimWiki.hs
index 42b168418..d01ce0e8b 100644
--- a/src/Text/Pandoc/Writers/ZimWiki.hs
+++ b/src/Text/Pandoc/Writers/ZimWiki.hs
@@ -18,11 +18,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{- |
Module : Text.Pandoc.Writers.ZimWiki
- Copyright : Copyright (C) 2008-2015 John MacFarlane, 2016 Alex Ivkin
+ Copyright : Copyright (C) 2008-2015 John MacFarlane, 2017 Alex Ivkin
License : GNU GPL, version 2 or above
Maintainer : Alex Ivkin <alex@ivkin.net>
- Stability : alpha
+ Stability : beta
Portability : portable
Conversion of 'Pandoc' documents to ZimWiki markup.
@@ -44,20 +44,22 @@ import Data.Default (Default(..))
import Network.URI ( isURI )
import Control.Monad ( zipWithM )
import Control.Monad.State ( modify, State, get, evalState )
---import Control.Monad.Reader ( ReaderT, runReaderT, ask, local )
import Text.Pandoc.Class ( PandocMonad )
+import qualified Data.Map as Map
data WriterState = WriterState {
stItemNum :: Int,
- stIndent :: String -- Indent after the marker at the beginning of list items
+ stIndent :: String, -- Indent after the marker at the beginning of list items
+ stInTable :: Bool, -- Inside a table
+ stInLink :: Bool -- Inside a link description
}
instance Default WriterState where
- def = WriterState { stItemNum = 1, stIndent = "" }
+ def = WriterState { stItemNum = 1, stIndent = "", stInTable = False, stInLink = False }
-- | Convert Pandoc to ZimWiki.
writeZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> m String
-writeZimWiki opts document = return $ evalState (pandocToZimWiki opts document) (WriterState 1 "")
+writeZimWiki opts document = return $ evalState (pandocToZimWiki opts document) def
-- | Return ZimWiki representation of document.
pandocToZimWiki :: WriterOptions -> Pandoc -> State WriterState String
@@ -129,9 +131,15 @@ blockToZimWiki opts (Header level _ inlines) = do
return $ eqs ++ " " ++ contents ++ " " ++ eqs ++ "\n"
blockToZimWiki _ (CodeBlock (_,classes,_) str) = do
+ -- Remap languages into the gtksourceview2 convention that ZimWiki source code plugin is using
+ let langal = [("javascript", "js"), ("bash", "sh"), ("winbatch", "dosbatch")]
+ let langmap = Map.fromList langal
return $ case classes of
- [] -> "'''\n" ++ cleanupCode str ++ "\n'''\n" -- no lang block is a quote block
- (x:_) -> "{{{code: lang=\"" ++ x ++ "\" linenumbers=\"True\"\n" ++ str ++ "\n}}}\n" -- for zim's code plugin, go verbatim on the lang spec
+ [] -> "'''\n" ++ cleanupCode str ++ "\n'''\n" -- turn no lang block into a quote block
+ (x:_) -> "{{{code: lang=\"" ++
+ (case Map.lookup x langmap of
+ Nothing -> x
+ Just y -> y) ++ "\" linenumbers=\"True\"\n" ++ str ++ "\n}}}\n" -- for zim's code plugin, go verbatim on the lang spec
blockToZimWiki opts (BlockQuote blocks) = do
contents <- blockListToZimWiki opts blocks
@@ -145,7 +153,7 @@ blockToZimWiki opts (Table capt aligns _ headers rows) = do
return $ "" ++ c ++ "\n"
headers' <- if all null headers
then zipWithM (tableItemToZimWiki opts) aligns (rows !! 0)
- else zipWithM (tableItemToZimWiki opts) aligns headers
+ else mapM (inlineListToZimWiki opts) (map removeFormatting headers) -- emphasis, links etc. are not allowed in table headers
rows' <- mapM (zipWithM (tableItemToZimWiki opts) aligns) rows
let widths = map (maximum . map length) $ transpose (headers':rows')
let padTo (width, al) s =
@@ -167,10 +175,10 @@ blockToZimWiki opts (Table capt aligns _ headers rows) = do
then replicate (width-1) '-' ++ ":"
else ":" ++ replicate (width-2) '-' ++ ":"
let underheader = "|" ++ intercalate "|" (zipWith borderCell (zip widths aligns) headers') ++ "|"
- let renderRow sep cells = sep ++ intercalate sep (zipWith padTo (zip widths aligns) cells) ++ sep
+ let renderRow cells = "|" ++ intercalate "|" (zipWith padTo (zip widths aligns) cells) ++ "|"
return $ captionDoc ++
- (if null headers' then "" else renderRow "|" headers' ++ "\n") ++ underheader ++ "\n" ++
- unlines (map (renderRow "|") rows')
+ (if null headers' then "" else renderRow headers' ++ "\n") ++ underheader ++ "\n" ++
+ unlines (map renderRow rows')
blockToZimWiki opts (BulletList items) = do
indent <- stIndent <$> get
@@ -255,7 +263,9 @@ tableItemToZimWiki opts align' item = do
(if align' == AlignLeft || align' == AlignCenter
then " "
else "")
- contents <- blockListToZimWiki opts item -- local (\s -> s { stBackSlashLB = True }) $
+ modify $ \s -> s { stInTable = True }
+ contents <- blockListToZimWiki opts item
+ modify $ \s -> s { stInTable = False }
return $ mkcell contents
-- | Convert list of Pandoc block elements to ZimWiki.
@@ -305,7 +315,15 @@ inlineToZimWiki opts (Cite _ lst) = inlineListToZimWiki opts lst
inlineToZimWiki _ (Code _ str) = return $ "''" ++ str ++ "''"
-inlineToZimWiki _ (Str str) = return $ escapeString str
+inlineToZimWiki _ (Str str) = do
+ inTable <- stInTable <$> get
+ inLink <- stInLink <$> get
+ if inTable
+ then return $ substitute "|" "\\|" . escapeString $ str
+ else
+ if inLink
+ then return $ str
+ else return $ escapeString str
inlineToZimWiki _ (Math mathType str) = return $ delim ++ str ++ delim -- note: str should NOT be escaped
where delim = case mathType of
@@ -318,7 +336,11 @@ inlineToZimWiki opts (RawInline f str)
| f == Format "html" = do cont <- indentFromHTML opts str; return cont
| otherwise = return ""
-inlineToZimWiki _ LineBreak = return "\n" -- was \\\\
+inlineToZimWiki _ LineBreak = do
+ inTable <- stInTable <$> get
+ if inTable
+ then return "\\n"
+ else return "\n"
inlineToZimWiki opts SoftBreak =
case writerWrapText opts of
@@ -329,30 +351,38 @@ inlineToZimWiki opts SoftBreak =
inlineToZimWiki _ Space = return " "
inlineToZimWiki opts (Link _ txt (src, _)) = do
- label <- inlineListToZimWiki opts txt
+ inTable <- stInTable <$> get
+ modify $ \s -> s { stInLink = True }
+ label <- inlineListToZimWiki opts $ removeFormatting txt -- zim does not allow formatting in link text, it takes the text verbatim, no need to escape it
+ modify $ \s -> s { stInLink = False }
+ let label'= if inTable
+ then "" -- no label is allowed in a table
+ else "|"++label
case txt of
[Str s] | "mailto:" `isPrefixOf` src -> return $ "<" ++ s ++ ">"
| escapeURI s == src -> return src
_ -> if isURI src
- then return $ "[[" ++ src ++ "|" ++ label ++ "]]"
- else return $ "[[" ++ src' ++ "|" ++ label ++ "]]"
+ then return $ "[[" ++ src ++ label' ++ "]]"
+ else return $ "[[" ++ src' ++ label' ++ "]]"
where src' = case src of
'/':xs -> xs -- with leading / it's a
_ -> src -- link to a help page
inlineToZimWiki opts (Image attr alt (source, tit)) = do
alt' <- inlineListToZimWiki opts alt
- let txt = case (tit, alt) of
- ("", []) -> ""
- ("", _ ) -> "|" ++ alt'
- (_ , _ ) -> "|" ++ tit
+ inTable <- stInTable <$> get
+ let txt = case (tit, alt, inTable) of
+ ("",[], _) -> ""
+ ("", _, False ) -> "|" ++ alt'
+ (_ , _, False ) -> "|" ++ tit
+ (_ , _, True ) -> ""
-- Relative links fail isURI and receive a colon
prefix = if isURI source then "" else ":"
return $ "{{" ++ prefix ++ source ++ imageDims opts attr ++ txt ++ "}}"
inlineToZimWiki opts (Note contents) = do
+ -- no concept of notes in zim wiki, use a text block
contents' <- blockListToZimWiki opts contents
- return $ "((" ++ contents' ++ "))"
- -- note - may not work for notes with multiple blocks
+ return $ " **{Note:** " ++ trimr contents' ++ "**}**"
imageDims :: WriterOptions -> Attr -> String
imageDims opts attr = go (toPx $ dimension Width attr) (toPx $ dimension Height attr)
diff --git a/test/tables.zimwiki b/test/tables.zimwiki
index 6da1f7f2c..2757055f6 100644
--- a/test/tables.zimwiki
+++ b/test/tables.zimwiki
@@ -1,43 +1,43 @@
Simple table with caption:
Demonstration of simple table syntax.
-| Right|Left | Center |Default|
-|------:|:-----|:--------:|-------|
-| 12|12 | 12 |12 |
-| 123|123 | 123 |123 |
-| 1|1 | 1 |1 |
+|Right|Left |Center |Default|
+|----:|:----|:-----:|-------|
+| 12|12 | 12 |12 |
+| 123|123 | 123 |123 |
+| 1|1 | 1 |1 |
Simple table without caption:
-| Right|Left | Center |Default|
-|------:|:-----|:--------:|-------|
-| 12|12 | 12 |12 |
-| 123|123 | 123 |123 |
-| 1|1 | 1 |1 |
+|Right|Left |Center |Default|
+|----:|:----|:-----:|-------|
+| 12|12 | 12 |12 |
+| 123|123 | 123 |123 |
+| 1|1 | 1 |1 |
Simple table indented two spaces:
Demonstration of simple table syntax.
-| Right|Left | Center |Default|
-|------:|:-----|:--------:|-------|
-| 12|12 | 12 |12 |
-| 123|123 | 123 |123 |
-| 1|1 | 1 |1 |
+|Right|Left |Center |Default|
+|----:|:----|:-----:|-------|
+| 12|12 | 12 |12 |
+| 123|123 | 123 |123 |
+| 1|1 | 1 |1 |
Multiline table with caption:
Here’s the caption. It may span multiple lines.
-| Centered Header |Left Aligned | Right Aligned|Default aligned |
-|:-----------------:|:-------------|--------------:|:------------------------------------------------------|
-| First |row | 12.0|Example of a row that spans multiple lines. |
-| Second |row | 5.0|Here’s another one. Note the blank line between rows. |
+|Centered Header|Left Aligned|Right Aligned|Default aligned |
+|:-------------:|:-----------|------------:|:------------------------------------------------------|
+| First |row | 12.0|Example of a row that spans multiple lines. |
+| Second |row | 5.0|Here’s another one. Note the blank line between rows. |
Multiline table without caption:
-| Centered Header |Left Aligned | Right Aligned|Default aligned |
-|:-----------------:|:-------------|--------------:|:------------------------------------------------------|
-| First |row | 12.0|Example of a row that spans multiple lines. |
-| Second |row | 5.0|Here’s another one. Note the blank line between rows. |
+|Centered Header|Left Aligned|Right Aligned|Default aligned |
+|:-------------:|:-----------|------------:|:------------------------------------------------------|
+| First |row | 12.0|Example of a row that spans multiple lines. |
+| Second |row | 5.0|Here’s another one. Note the blank line between rows. |
Table without column headers:
diff --git a/test/writer.zimwiki b/test/writer.zimwiki
index 848ca955e..7a15bad9d 100644
--- a/test/writer.zimwiki
+++ b/test/writer.zimwiki
@@ -606,8 +606,7 @@ Here is a movie {{:movie.jpg|movie}} icon.
====== Footnotes ======
-Here is a footnote reference,((Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.
-)) and another.((Here’s the long note. This one contains multiple blocks.
+Here is a footnote reference, **{Note:** Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.**}** and another. **{Note:** Here’s the long note. This one contains multiple blocks.
Subsequent blocks are indented to show that they belong to the footnote (as with list items).
@@ -615,13 +614,10 @@ Subsequent blocks are indented to show that they belong to the footnote (as with
{ <code> }
'''
-If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.
-)) This should //not// be a footnote reference, because it contains a space.[^my note] Here is an inline note.((This is //easier// to type. Inline notes may contain [[http://google.com|links]] and '']'' verbatim characters, as well as [bracketed text].
-))
+If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.**}** This should //not// be a footnote reference, because it contains a space.[^my note] Here is an inline note. **{Note:** This is //easier// to type. Inline notes may contain [[http://google.com|links]] and '']'' verbatim characters, as well as [bracketed text].**}**
-> Notes can go in quotes.((In quote.
-> ))
+> Notes can go in quotes. **{Note:** In quote.**}**
- 1. And in list items.((In list.))
+ 1. And in list items. **{Note:** In list.**}**
This paragraph should not be part of the note, as it is not indented.