aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJess Robinson <[email protected]>2012-02-19 01:32:45 +0000
committerJohn MacFarlane <[email protected]>2012-04-25 13:54:16 -0700
commit567d32c4b784722914fd1f220b2dbb96eeb8740e (patch)
treed2e1605efdd47fd594bc0fda29b8249e65d2588d
parent7f6f8f66609d86f962d925c227da0afc2990e484 (diff)
Bunch of updates
-rw-r--r--pandoc.cabal1
-rw-r--r--src/Tests/Writers/PseudoPod.hs34
-rw-r--r--src/Text/Pandoc/Writers/PseudoPod.hs127
3 files changed, 106 insertions, 56 deletions
diff --git a/pandoc.cabal b/pandoc.cabal
index 898e06069..8dda9d3d3 100644
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -419,6 +419,7 @@ Executable test-pandoc
Tests.Shared
Tests.Readers.LaTeX
Tests.Readers.Markdown
+ Tests.Readers.PseudoPod
Tests.Readers.RST
Tests.Writers.Native
Tests.Writers.ConTeXt
diff --git a/src/Tests/Writers/PseudoPod.hs b/src/Tests/Writers/PseudoPod.hs
new file mode 100644
index 000000000..6377a2d1f
--- /dev/null
+++ b/src/Tests/Writers/PseudoPod.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE OverloadedStrings, QuasiQuotes #-}
+module Tests.Writers.PseudoPod (tests) where
+
+import Test.Framework
+import Text.Pandoc.Builder
+import Text.Pandoc
+import Tests.Helpers
+import Tests.Arbitrary()
+
+pseudopod :: (ToString a, ToPandoc a) => a -> String
+pseudopod = writePseudoPod defaultWriterOptions . toPandoc
+
+{-
+ "my test" =: X =?> Y
+
+is shorthand for
+
+ test pseudopod "my test" $ X =?> Y
+
+which is in turn shorthand for
+
+ test pseudopod "my test" (X,Y)
+-}
+
+infix 4 =:
+(=:) :: (ToString a, ToPandoc a)
+ => String -> (a, String) -> Test
+(=:) = test pseudopod
+
+tests :: [Test]
+tests = [ "escaped > in string"
+ =: (para "string with > in it" )
+ =?> "string with E<gt> in it"
+ ]
diff --git a/src/Text/Pandoc/Writers/PseudoPod.hs b/src/Text/Pandoc/Writers/PseudoPod.hs
index 38dee2b5f..ce008d996 100644
--- a/src/Text/Pandoc/Writers/PseudoPod.hs
+++ b/src/Text/Pandoc/Writers/PseudoPod.hs
@@ -37,21 +37,18 @@ import Text.Pandoc.Templates (renderTemplate)
import Text.Pandoc.Shared
import Text.Pandoc.Parsing hiding (blankline)
import Text.ParserCombinators.Parsec ( runParser, GenParser )
-import Data.List ( group, intersperse, transpose )
+import Data.List ( intersperse, transpose )
import Text.Pandoc.Pretty
import Control.Monad.State
-type Notes = [[Block]]
type Refs = [([Inline], Target)]
-data WriterState = WriterState { stNotes :: Notes
- , stRefs :: Refs
+data WriterState = WriterState { stRefs :: Refs
, stPlain :: Bool }
-- | Convert Pandoc to PseudoPod.
writePseudoPod :: WriterOptions -> Pandoc -> String
writePseudoPod opts document =
- evalState (pandocToPseudoPod opts document) WriterState{ stNotes = []
- , stRefs = []
+ evalState (pandocToPseudoPod opts document) WriterState{stRefs = []
, stPlain = False }
-- | Return PseudoPod representation of document.
@@ -66,15 +63,12 @@ pandocToPseudoPod opts (Pandoc (Meta title authors date) blocks) = do
then tableOfContents opts headerBlocks
else empty
body <- blockListToPseudoPod opts blocks
- st <- get
- notes' <- notesToPseudoPod opts (reverse $ stNotes st)
st' <- get -- note that the notes may contain refs
refs' <- refsToPseudoPod opts (reverse $ stRefs st')
let colwidth = if writerWrapText opts
then Just $ writerColumns opts
else Nothing
let main = render colwidth $ body <>
- (if isEmpty notes' then empty else blankline <> notes') <>
(if isEmpty refs' then empty else blankline <> refs')
let context = writerVariables opts ++
[ ("toc", render colwidth toc)
@@ -104,36 +98,21 @@ keyToPseudoPod opts (label, (src, tit)) = do
return $ nest 2 $ hang 2
("[" <> label' <> "]:" <> space) (text src <> tit')
--- | Return PseudoPod representation of notes.
-notesToPseudoPod :: WriterOptions -> [[Block]] -> State WriterState Doc
-notesToPseudoPod opts notes =
- mapM (\(num, note) -> noteToPseudoPod opts num note) (zip [1..] notes) >>=
- return . vsep
-
--- | Return PseudoPod representation of a note.
-noteToPseudoPod :: WriterOptions -> Int -> [Block] -> State WriterState Doc
-noteToPseudoPod opts num blocks = do
- contents <- blockListToPseudoPod opts blocks
- let num' = text $ show num
- let marker = text "[^" <> num' <> text "]:"
- let markerSize = 4 + offset num'
- let spacer = case writerTabStop opts - markerSize of
- n | n > 0 -> text $ replicate n ' '
- _ -> text " "
- return $ hang (writerTabStop opts) (marker <> spacer) contents
-
-- | Escape special characters for PseudoPod.
escapeString :: String -> String
escapeString = escapeStringUsing pseudopodEscapes
- where pseudopodEscapes = backslashEscapes "\\`*_>#~^"
+ where pseudopodEscapes = entityEscapes
+
+-- | pod-ish entity escapes, E<>
+entityEscapes :: [(Char,String)]
+entityEscapes = [('>', "E<gt>")]
-- | Construct table of contents from list of header blocks.
tableOfContents :: WriterOptions -> [Block] -> Doc
tableOfContents opts headers =
let opts' = opts { writerIgnoreNotes = True }
contents = BulletList $ map elementToListItem $ hierarchicalize headers
- in evalState (blockToPseudoPod opts' contents) WriterState{ stNotes = []
- , stRefs = []
+ in evalState (blockToPseudoPod opts' contents) WriterState{ stRefs = []
, stPlain = False }
-- | Converts an Element to a list item for a table of contents,
@@ -184,6 +163,8 @@ blockToPseudoPod _ Null = return empty
blockToPseudoPod opts (Plain inlines) = do
contents <- inlineListToPseudoPod opts inlines
return $ contents <> cr
+
+
blockToPseudoPod opts (Para inlines) = do
contents <- inlineListToPseudoPod opts inlines
-- escape if para starts with ordered list marker
@@ -201,8 +182,10 @@ blockToPseudoPod _ (RawBlock f str)
then return empty
else return $ text str <> text "\n"
blockToPseudoPod _ (RawBlock _ _) = return empty
+
+-- | No horizontal rules, leave a space
blockToPseudoPod _ HorizontalRule =
- return $ blankline <> text "* * * * *" <> blankline
+ return $ blankline <> blankline <> blankline
-- | =headN <content> - DONE
blockToPseudoPod opts (Header level inlines) = do
@@ -283,9 +266,14 @@ blockToPseudoPod opts (Table caption aligns widths headers rows) = do
else border
return $ nest 2 $ head'' $$ underline $$ body $$
bottom $$ blankline $$ caption'' $$ blankline
+
+-- | =over / =item * / =back
blockToPseudoPod opts (BulletList items) = do
contents <- mapM (bulletListItemToPseudoPod opts) items
- return $ cat contents <> blankline
+ return $ "=over" <> blankline <> cat contents <> blankline <> "=back" <> blankline
+
+
+-- | =over / =item N. / =back
blockToPseudoPod opts (OrderedList attribs items) = do
let markers = orderedListMarkers attribs
let markers' = map (\m -> if length m < 3
@@ -293,18 +281,18 @@ blockToPseudoPod opts (OrderedList attribs items) = do
else m) markers
contents <- mapM (\(item, num) -> orderedListItemToPseudoPod opts item num) $
zip markers' items
- return $ cat contents <> blankline
+ return $ "=over" <> blankline <> cat contents <> blankline <> "=back" <> blankline
+-- return $ cat contents <> blankline
+
blockToPseudoPod opts (DefinitionList items) = do
contents <- mapM (definitionListItemToPseudoPod opts) items
- return $ cat contents <> blankline
+ return $ "=over" <> blankline <> cat contents <> blankline <> "=back" <> blankline
--- | Convert bullet list item (list of blocks) to PseudoPod.
+-- | bullet list -> =item *
bulletListItemToPseudoPod :: WriterOptions -> [Block] -> State WriterState Doc
bulletListItemToPseudoPod opts items = do
contents <- blockListToPseudoPod opts items
- let sps = replicate (writerTabStop opts - 2) ' '
- let start = text ('-' : ' ' : sps)
- return $ hang (writerTabStop opts) start $ contents <> cr
+ return $ "=item *" <> blankline <> contents <> blankline
-- | Convert ordered list item (a list of blocks) to PseudoPod.
orderedListItemToPseudoPod :: WriterOptions -- ^ options
@@ -313,13 +301,17 @@ orderedListItemToPseudoPod :: WriterOptions -- ^ options
-> State WriterState Doc
orderedListItemToPseudoPod opts marker items = do
contents <- blockListToPseudoPod opts items
+ return $ "=item " <> (text marker) <> blankline <> contents <> blankline
+
+{-
let sps = case length marker - writerTabStop opts of
n | n > 0 -> text $ replicate n ' '
_ -> text " "
let start = text marker <> sps
return $ hang (writerTabStop opts) start $ contents <> cr
+-}
--- | Convert definition list item (label, list of blocks) to PseudoPod.
+-- | Convert definition list item (label, list of blocks) to markdown.
definitionListItemToPseudoPod :: WriterOptions
-> ([Inline],[[Block]])
-> State WriterState Doc
@@ -335,6 +327,24 @@ definitionListItemToPseudoPod opts (label, defs) = do
let contents = vcat $ map (\d -> hang tabStop (leader <> sps) $ vcat d <> cr) defs'
return $ labelText <> cr <> contents <> cr
+{-
+-- | Convert definition list item (label, list of blocks) to PseudoPod.
+-- | =over / =item FOO / para / =back
+definitionListItemToPseudoPod :: WriterOptions
+ -> ([Inline],[[Block]])
+ -> State WriterState Doc
+definitionListItemToPseudoPod opts (label, defs) = do
+ labelText <- inlineListToPseudoPod opts label
+ -- each call to definitonListItemToPseudoPod is one label, which can have multiple defintions. (Each definition is a [Block].)
+
+ defs' <- mapM (mapM (blockToPseudoPod opts)) defs
+-- let contents = vcat $ map (\d -> "=item") $ vcat d <> cr) defs'
+ return $ "=item" <> labelText <> blankline <> vcat (vcat defs') <> blankline
+
+definitionListSubItemToPseudoPod :: WriterOptions -> ([Inline], [Block])
+definitionListSubItemToPseudoPod opts (label, def) = do
+-}
+
-- | Convert list of Pandoc block elements to PseudoPod.
blockListToPseudoPod :: WriterOptions -- ^ Options
-> [Block] -- ^ List of block elements
@@ -384,41 +394,46 @@ inlineToPseudoPod opts (Strikeout lst) = do
return $ "~~" <> contents <> "~~"
-}
+-- | G<>
inlineToPseudoPod opts (Superscript lst) = do
let lst' = bottomUp escapeSpaces lst
contents <- inlineListToPseudoPod opts lst'
- return $ "^" <> contents <> "^"
+ return $ "G<" <> contents <> ">"
+
+-- | H<>
inlineToPseudoPod opts (Subscript lst) = do
let lst' = bottomUp escapeSpaces lst
contents <- inlineListToPseudoPod opts lst'
- return $ "~" <> contents <> "~"
+ return $ "H<" <> contents <> ">"
+
+-- | FIXME - doesnt exist
inlineToPseudoPod opts (SmallCaps lst) = inlineListToPseudoPod opts lst
+
inlineToPseudoPod opts (Quoted SingleQuote lst) = do
contents <- inlineListToPseudoPod opts lst
return $ "‘" <> contents <> "’"
inlineToPseudoPod opts (Quoted DoubleQuote lst) = do
contents <- inlineListToPseudoPod opts lst
return $ "“" <> contents <> "”"
+
+-- | C<>
inlineToPseudoPod opts (Code attr str) =
- let tickGroups = filter (\s -> '`' `elem` s) $ group str
- longest = if null tickGroups
- then 0
- else maximum $ map length tickGroups
- marker = replicate (longest + 1) '`'
- spacer = if (longest == 0) then "" else " "
- attrs = if writerStrictMarkdown opts || attr == nullAttr
- then empty
- else attrsToPseudoPod attr
- in return $ text (marker ++ spacer ++ str ++ spacer ++ marker) <> attrs
+ return $ "C<< " <> text (escapeString str) <> " >>"
+
inlineToPseudoPod _ (Str str) = do
st <- get
if stPlain st
then return $ text str
else return $ text $ escapeString str
+
+-- | No Math
+-- inlineToPseudoPod opts (Math _ str) = inlineToPseudoPod opts Inline str
+
inlineToPseudoPod _ (Math InlineMath str) =
return $ "$" <> text str <> "$"
inlineToPseudoPod _ (Math DisplayMath str) =
return $ "$$" <> text str <> "$$"
+
inlineToPseudoPod _ (RawInline f str)
| f == "html" || f == "latex" || f == "tex" || f == "PseudoPod" =
return $ text str
@@ -469,8 +484,8 @@ inlineToPseudoPod opts (Image alternate (source, tit)) = do
else alternate
linkPart <- inlineToPseudoPod opts (Link txt (source, tit))
return $ "!" <> linkPart
-inlineToPseudoPod _ (Note contents) = do
- modify (\st -> st{ stNotes = contents : stNotes st })
- st <- get
- let ref = show $ (length $ stNotes st)
- return $ "[^" <> text ref <> "]"
+
+-- | N<>
+inlineToPseudoPod opts (Note blocks) = do
+ contents <- blockListToPseudoPod opts blocks
+ return $ "N<" <> contents <> ">"